From 08be92b6fa537646264f4aab9203055f6bef8f80 Mon Sep 17 00:00:00 2001 From: hided62 Date: Wed, 23 Sep 2026 16:21:52 +0000 Subject: [PATCH] =?UTF-8?q?=EC=A1=B0=EA=B1=B4=EB=B6=80=20=ED=86=B5?= =?UTF-8?q?=ED=95=A9=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EB=93=B1=EB=A1=9D?= =?UTF-8?q?=EA=B3=BC=20=EC=8B=9C=EA=B3=84=20fixture=EB=A5=BC=20=EB=B0=94?= =?UTF-8?q?=EB=A1=9C=EC=9E=A1=EB=8A=94=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../test/auctionWorker.integration.test.ts | 7 +++++++ .../test/createGeneral.integration.test.ts | 4 ++-- .../accountIconPersistence.integration.test.ts | 16 ++++++++++++++++ ...atalogBoundaryPersistence.integration.test.ts | 8 ++++++++ .../check-conditional-integration-files.test.mjs | 4 ++-- tools/conditional-integration-registry.tsv | 2 ++ 6 files changed, 37 insertions(+), 4 deletions(-) diff --git a/app/game-api/test/auctionWorker.integration.test.ts b/app/game-api/test/auctionWorker.integration.test.ts index ec0ad77f..64dfe50f 100644 --- a/app/game-api/test/auctionWorker.integration.test.ts +++ b/app/game-api/test/auctionWorker.integration.test.ts @@ -5,6 +5,7 @@ import { SystemClock } from '@sammo-ts/common'; import { createDatabaseTurnHooks, DatabaseTurnDaemonCommandQueue, + DatabaseTurnDaemonLease, EngineStateManager, InMemoryTurnStateStore, InMemoryTurnWorld, @@ -695,6 +696,10 @@ liveDescribe('auction worker durable recovery', () => { const redisConnector = createRedisConnector(resolveRedisConfigFromEnv()); await redisConnector.connect(); + // 독립 worker는 활성 daemon의 clock_ready fence가 있을 때만 GAME_TIME을 진행한다. + const lease = await DatabaseTurnDaemonLease.connect(databaseUrl!, { profile: profileName }); + await lease.acquire(); + await lease.markClockReady(); const keys = buildAuctionTimerKeys(profileName); const abortController = new AbortController(); const worker = runAuctionWorker({ signal: abortController.signal }); @@ -725,6 +730,8 @@ liveDescribe('auction worker durable recovery', () => { } finally { abortController.abort(); await worker; + await lease.close(); + await connector.prisma.turnDaemonLease.delete({ where: { profile: profileName } }); await redisConnector.client.del([keys.timerKey, keys.historyKey]); await redisConnector.disconnect(); await connector.prisma.errorLog.deleteMany({ diff --git a/app/game-api/test/createGeneral.integration.test.ts b/app/game-api/test/createGeneral.integration.test.ts index 2b9f74dc..23eec64a 100644 --- a/app/game-api/test/createGeneral.integration.test.ts +++ b/app/game-api/test/createGeneral.integration.test.ts @@ -384,8 +384,8 @@ integration('generic general creation through the durable turn daemon', () => { actorUserId: userId, }); expect(access.lastRefresh?.getTime()).toBe(event.createdAt.getTime()); - const turnGridOffsetSeconds = - ((created.turnTime.getTime() - runtime!.world.getState().lastTurnTime.getTime()) / 1000 + 300) % 300; + // 상속 턴 시간대는 daemon cursor가 아닌 5분 격자의 위상을 보존한다. + const turnGridOffsetSeconds = ((created.turnTime.getTime() / 1000) % 300 + 300) % 300; expect(turnGridOffsetSeconds).toBeGreaterThanOrEqual(35); expect(turnGridOffsetSeconds).toBeLessThan(40); diff --git a/app/game-engine/test/accountIconPersistence.integration.test.ts b/app/game-engine/test/accountIconPersistence.integration.test.ts index 25eb7149..61f07e09 100644 --- a/app/game-engine/test/accountIconPersistence.integration.test.ts +++ b/app/game-engine/test/accountIconPersistence.integration.test.ts @@ -72,6 +72,14 @@ const state: TurnWorldState = { currentMonth: 1, tickSeconds: 600, lastTurnTime: new Date('2026-07-31T09:00:00.000Z'), + clockBaseTime: new Date('2026-07-31T09:00:00.000Z'), + clockTick: 0, + lastTurnTick: 0, + clockMode: 'manual', + clockPhase: 'MANUAL', + clockWallAnchor: new Date('2026-07-31T09:00:00.000Z'), + clockRevision: 1, + deadlineGeneration: 1, meta: { killturn: 24, lastTurnTime: '2026-07-31T09:00:00.000Z', @@ -209,6 +217,14 @@ integration('adjustGeneralIcon PostgreSQL persistence', () => { currentYear: state.currentYear, currentMonth: state.currentMonth, tickSeconds: state.tickSeconds, + clockBaseTime: state.clockBaseTime, + clockTick: BigInt(state.clockTick ?? 0), + lastTurnTick: BigInt(state.lastTurnTick ?? 0), + clockMode: state.clockMode, + clockPhase: state.clockPhase, + clockWallAnchor: state.clockWallAnchor, + clockRevision: BigInt(state.clockRevision ?? 1), + deadlineGeneration: BigInt(state.deadlineGeneration ?? 1), config: JSON.parse(JSON.stringify(scenarioConfig)) as GamePrisma.InputJsonValue, meta: state.meta as GamePrisma.InputJsonValue, }, diff --git a/app/game-engine/test/monthlyCatalogBoundaryPersistence.integration.test.ts b/app/game-engine/test/monthlyCatalogBoundaryPersistence.integration.test.ts index ef97d1e3..c290ebb3 100644 --- a/app/game-engine/test/monthlyCatalogBoundaryPersistence.integration.test.ts +++ b/app/game-engine/test/monthlyCatalogBoundaryPersistence.integration.test.ts @@ -224,6 +224,14 @@ integration('monthly catalog boundary persistence', () => { currentYear: 190, currentMonth: 12, tickSeconds: 600, + clockBaseTime: new Date('2026-07-25T01:50:00.000Z'), + clockTick: 0n, + lastTurnTick: 0n, + clockMode: 'manual', + clockPhase: 'MANUAL', + clockWallAnchor: new Date('2026-07-25T01:50:00.000Z'), + clockRevision: 1n, + deadlineGeneration: 1n, config: scenarioConfig, meta: { hiddenSeed: 'monthly-boundary-core-catalog', diff --git a/tools/check-conditional-integration-files.test.mjs b/tools/check-conditional-integration-files.test.mjs index 91c3619e..2ea985d5 100644 --- a/tools/check-conditional-integration-files.test.mjs +++ b/tools/check-conditional-integration-files.test.mjs @@ -16,7 +16,7 @@ test('keeps every non-database conditional Ref suite in one requirement group', ); assert.deepEqual(counts, { - reference_command: 5, + reference_command: 3, reference_full_lifecycle: 1, reference_instant_diplomacy: 1, reference_monthly: 1, @@ -49,7 +49,7 @@ test('enables Ref suites only with the Ref runtime and saved traces only as a pa }); assert.equal( selectEnabledConditionalIntegrationFiles(entries, { TURN_DIFFERENTIAL_REFERENCE: '1' }).referenceFiles.length, - 9 + 7 ); assert.deepEqual( selectEnabledConditionalIntegrationFiles(entries, { diff --git a/tools/conditional-integration-registry.tsv b/tools/conditional-integration-registry.tsv index 33f6c7af..29727f7e 100644 --- a/tools/conditional-integration-registry.tsv +++ b/tools/conditional-integration-registry.tsv @@ -8,6 +8,8 @@ GATEWAY_RELEASE_DATABASE_URL gateway_runtime GENERAL_LIFECYCLE_DATABASE_URL core IMMEDIATE_ACTION_DATABASE_URL immediate_action INPUT_EVENT_DATABASE_URL core +PLAY_AUDIT_COST_DATABASE_URL external_fixture +PLAY_AUDIT_DECISION_DATABASE_URL external_fixture PLAY_AUDIT_RETENTION_DATABASE_URL external_fixture PLAY_AUDIT_STARTUP_DATABASE_URL external_fixture LIVE_SORTIE_PERSISTENCE_DATABASE_URL reference_live_sortie