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
+51 -12
View File
@@ -6,6 +6,7 @@ import { promisify } from 'node:util';
import { seedScenarioToDatabase } from '@sammo-ts/game-engine';
import {
activateReadModelRevisionCoverage,
createGamePostgresConnector,
createRedisConnector,
GamePrisma,
@@ -264,7 +265,10 @@ const resizeSeededGenerals = async (db: GamePrismaClient, config: LoadConfig): P
where: { id: world.id },
data: {
tickSeconds: Math.trunc(config.capacity.turnIntervalMs / 1_000),
meta: { ...(world.meta as Record<string, unknown>), lastGeneralId: rows.length } as GamePrisma.InputJsonValue,
meta: {
...(world.meta as Record<string, unknown>),
lastGeneralId: rows.length,
} as GamePrisma.InputJsonValue,
config: {
...(world.config as Record<string, unknown>),
maxUserCnt: expectedHuman,
@@ -335,8 +339,9 @@ export const seedCapacityFixture = async (options: {
await deleteMatchingRedisKeys(redis.client, `${accessKeyPrefix(options.config)}ga_*`);
const issuedAt = new Date().toISOString();
const expiresAt = new Date(Date.now() + 24 * 60 * 60 * 1_000).toISOString();
const tokens = Array.from({ length: options.config.capacity.authenticatedViewers }, () =>
`ga_${randomUUID()}`
const tokens = Array.from(
{ length: options.config.capacity.authenticatedViewers },
() => `ga_${randomUUID()}`
);
await Promise.all(
tokens.map((token, index) => {
@@ -401,9 +406,16 @@ export const verifyCapacityFixture = async (config: LoadConfig, env: NodeJS.Proc
const redis = createRedisConnector({ url: environment.redisUrl });
await postgres.connect();
try {
const [state, postgresRows] = await Promise.all([
const [state, postgresRows, revisionMeta, revisionHeads, pendingOutbox] = await Promise.all([
projectFixtureState(postgres.prisma),
postgres.prisma.$queryRaw<Array<{ version: string }>>(GamePrisma.sql`SELECT version()`),
postgres.prisma.readModelRevisionMeta.findUnique({ where: { id: 1 } }),
postgres.prisma.readModelRevision.findMany({
where: { domain: { in: ['dashboard.global', 'map.world'] }, entityId: 0 },
orderBy: { domain: 'asc' },
select: { domain: true, revision: true },
}),
postgres.prisma.readModelOutbox.count({ where: { deliveredAt: null } }),
]);
const fixtureSha256 = `sha256:${sha256(canonicalJson(state))}`;
await redis.connect();
@@ -413,8 +425,7 @@ export const verifyCapacityFixture = async (config: LoadConfig, env: NodeJS.Proc
if (rawManifest) {
try {
const parsed = JSON.parse(rawManifest) as Record<string, unknown>;
manifestFixtureSha256 =
typeof parsed.fixtureSha256 === 'string' ? parsed.fixtureSha256 : null;
manifestFixtureSha256 = typeof parsed.fixtureSha256 === 'string' ? parsed.fixtureSha256 : null;
} catch {
manifestFixtureSha256 = null;
}
@@ -423,9 +434,7 @@ export const verifyCapacityFixture = async (config: LoadConfig, env: NodeJS.Proc
const redisInfo = await redis.client.info('server');
const redisVersion = /^redis_version:(.+)$/mu.exec(redisInfo)?.[1]?.trim() ?? 'unknown';
const npcGenerals = state.generals.filter((general) => general.npcState >= 2).length;
const humanGenerals = state.generals.filter(
(general) => general.npcState === 0 && general.userId
).length;
const humanGenerals = state.generals.filter((general) => general.npcState === 0 && general.userId).length;
const valid =
state.generals.length === config.capacity.npcGenerals + config.capacity.humanGenerals &&
npcGenerals === config.capacity.npcGenerals &&
@@ -443,6 +452,12 @@ export const verifyCapacityFixture = async (config: LoadConfig, env: NodeJS.Proc
redisManifestMatches: manifestFixtureSha256 === fixtureSha256,
postgresVersion: postgresRows[0]?.version ?? 'unknown',
redisVersion,
coverageVersion: revisionMeta?.coverageVersion ?? null,
revisionHeads: revisionHeads.map((head) => ({
domain: head.domain,
revision: head.revision.toString(),
})),
pendingOutbox,
};
} finally {
await redis.disconnect();
@@ -452,6 +467,32 @@ export const verifyCapacityFixture = async (config: LoadConfig, env: NodeJS.Proc
}
};
export const activateCapacityCoverage = async (
config: LoadConfig,
confirmation: string,
env: NodeJS.ProcessEnv = process.env
) => {
if (confirmation !== config.isolation.postgresSchema) {
throw new Error('coverage activation confirmation must exactly equal isolation.postgresSchema');
}
const environment = requireEnvironment(env);
assertFixtureIsolation(config, environment);
const fixture = await verifyCapacityFixture(config, env);
if (!fixture.valid) {
throw new Error('fixture verification failed; refusing coverage activation');
}
const postgres = createGamePostgresConnector({ url: environment.databaseUrl });
await postgres.connect();
try {
const result = await postgres.prisma.$transaction((transaction) =>
activateReadModelRevisionCoverage(transaction, 0)
);
return { activated: true, ...result };
} finally {
await postgres.disconnect();
}
};
export const materializeCalibrationConfig = async (options: {
config: LoadConfig;
outputPath: string;
@@ -473,9 +514,7 @@ export const materializeCalibrationConfig = async (options: {
}
const verified = await verifyCapacityFixture(options.config, env);
if (!verified.valid) throw new Error('fixture verification failed; refusing to materialize calibration config');
const gitCommit = (
await execFileAsync('git', ['rev-parse', 'HEAD'], { cwd: options.workspaceRoot })
).stdout.trim();
const gitCommit = (await execFileAsync('git', ['rev-parse', 'HEAD'], { cwd: options.workspaceRoot })).stdout.trim();
const runtimeConfig: LoadConfig = {
...options.config,
name: `${options.config.name}-calibration`,