test: source revision capacity 계측을 추가

This commit is contained in:
2026-08-16 19:03:54 +00:00
parent cfcf57c877
commit a4274c64b6
10 changed files with 252 additions and 53 deletions
+9 -6
View File
@@ -5,7 +5,7 @@ import path from 'node:path';
import test from 'node:test';
import { validateLoadConfig } from '../src/config.js';
import { assertFixtureIsolation, prepareCapacitySecrets } from '../src/fixture.js';
import { activateCapacityCoverage, assertFixtureIsolation, prepareCapacitySecrets } from '../src/fixture.js';
const samplePath = new URL('../config/300-users-900-npcs-5m.json', import.meta.url);
@@ -40,13 +40,19 @@ void test('fixture refuses a shared schema, shared Redis database, and public ho
assert.throws(
() =>
assertFixtureIsolation(config, {
databaseUrl: 'postgresql://fixture:secret@database.example.com:5432/sammo?schema=load_capacity_300_900_5m',
databaseUrl:
'postgresql://fixture:secret@database.example.com:5432/sammo?schema=load_capacity_300_900_5m',
redisUrl: 'redis://127.0.0.1:16379/15',
}),
/loopback or private/u
);
});
void test('coverage activation requires the exact dedicated schema confirmation before connecting', async () => {
const config = validateLoadConfig(JSON.parse(await readFile(samplePath, 'utf8')));
await assert.rejects(activateCapacityCoverage(config, 'load_wrong_schema', {}), /confirmation must exactly equal/u);
});
void test('prepare creates only three 0600 ignored-secret inputs without returning their values', async () => {
const workspaceRoot = await mkdtemp(path.join(tmpdir(), 'sammo-capacity-prepare-'));
try {
@@ -63,10 +69,7 @@ void test('prepare creates only three 0600 ignored-secret inputs without returni
const info = await stat(path.join(workspaceRoot, 'tools/load-tests/secrets', name));
assert.equal(info.mode & 0o777, 0o600);
}
const envText = await readFile(
path.join(workspaceRoot, 'tools/load-tests/secrets/capacity.env'),
'utf8'
);
const envText = await readFile(path.join(workspaceRoot, 'tools/load-tests/secrets/capacity.env'), 'utf8');
assert.match(envText, /127\.0\.0\.1:25442/u);
assert.match(envText, /127\.0\.0\.1:26379\/15/u);
assert.equal(JSON.stringify(result).includes('postgresql://'), false);
+4
View File
@@ -26,6 +26,9 @@ void test('phase aggregation separates success, error, latency, and event counte
metrics.recordSseEvent('ready');
metrics.recordSseEvent('ready');
metrics.recordHttpResult('own', 'unchanged');
metrics.httpSourceRevisionObserved = 6;
metrics.httpSourceRevisionKnownSent = 3;
metrics.httpSourceRevisionMatchedUnchanged = 3;
metrics.processRssBytes.push(100, 200);
metrics.sseActiveConnections.push(0, 2);
const summary = summarizePhaseMetrics(metrics, {
@@ -36,6 +39,7 @@ void test('phase aggregation separates success, error, latency, and event counte
assert.deepEqual(summary.http.success, { own: 1 });
assert.deepEqual(summary.http.errors, { 'own:http-500': 1 });
assert.deepEqual(summary.http.results, { 'own:unchanged': 1 });
assert.deepEqual(summary.http.sourceRevision, { observed: 6, knownSent: 3, matchedUnchanged: 3 });
assert.equal(summary.http.latencyMs.own?.p50, 10);
assert.deepEqual(summary.sse.events, { ready: 2 });
assert.equal(summary.sse.activeConnections.max, 2);
+14 -3
View File
@@ -8,7 +8,13 @@ void test('tRPC query uses bearer auth without putting the token in the URL', ()
const request = buildTrpcQuery(
'http://127.0.0.1:15001',
'/api/trpc',
{ name: 'own', procedure: 'dashboard.getContextBundleDelta', type: 'query', weight: 1, input: { include: { context: true } } },
{
name: 'own',
procedure: 'dashboard.getContextBundleDelta',
type: 'query',
weight: 1,
input: { include: { context: true } },
},
token
);
assert.equal(new Headers(request.init.headers).get('authorization'), `Bearer ${token}`);
@@ -25,11 +31,16 @@ void test('dashboard observations retain only opaque revisions and aggregate-saf
data: {
json: {
context: { kind: 'unchanged', revision, data: { general: { id: 123 } } },
commandTable: { kind: 'snapshot', revision },
commandTable: { kind: 'snapshot', revision, sourceRevision: revision },
},
},
},
}),
{ revisions: { context: revision, commandTable: revision }, resultKinds: ['unchanged', 'snapshot'] }
{
revisions: { context: revision, commandTable: revision },
sourceRevisions: { commandTable: revision },
resultKinds: ['unchanged', 'snapshot'],
resultKindsBySlice: { context: 'unchanged', commandTable: 'snapshot' },
}
);
});