test(clock): exercise suspended lifecycle actions
This commit is contained in:
@@ -306,11 +306,27 @@ export const buildTournamentRuntimeKeys = (profileName: string): string[] => [
|
||||
`sammo:${profileName}:tournament:source-revision`,
|
||||
];
|
||||
|
||||
export const buildGameClockRuntimeKeys = (profileName: string): string[] => [
|
||||
`sammo:${profileName}:clock:active-revision`,
|
||||
`sammo:${profileName}:clock:deadline-generation`,
|
||||
`sammo:${profileName}:clock:phase`,
|
||||
];
|
||||
|
||||
export const buildProfileResetRuntimeKeys = (profileName: string): string[] => [
|
||||
...buildTournamentRuntimeKeys(profileName),
|
||||
...buildGameClockRuntimeKeys(profileName),
|
||||
];
|
||||
|
||||
export const clearTournamentRuntimeKeys = async (
|
||||
redis: { del(keys: string[]): Promise<number> },
|
||||
profileName: string
|
||||
): Promise<number> => redis.del(buildTournamentRuntimeKeys(profileName));
|
||||
|
||||
export const clearProfileResetRuntimeKeys = async (
|
||||
redis: { del(keys: string[]): Promise<number> },
|
||||
profileName: string
|
||||
): Promise<number> => redis.del(buildProfileResetRuntimeKeys(profileName));
|
||||
|
||||
const buildServerId = (profileName: string, now: Date, installOperationId?: string): string => {
|
||||
const year = String(now.getFullYear()).slice(-2);
|
||||
const month = String(now.getMonth() + 1).padStart(2, '0');
|
||||
@@ -965,6 +981,7 @@ export class GatewayOrchestrator implements GatewayOrchestratorHandle {
|
||||
private readonly profileReadinessTimeoutMs: number;
|
||||
private readonly now: () => Date;
|
||||
private readonly fetchImpl: typeof fetch;
|
||||
/** Backwards-compatible injection name; the default clears all season-owned RESET keys. */
|
||||
private readonly clearTournamentRuntimeState: (profileName: string) => Promise<void>;
|
||||
private readonly cancelGame: typeof defaultCancelGame;
|
||||
private readonly transitionProfileClockOverride?: GatewayOrchestratorOptions['transitionProfileClock'];
|
||||
@@ -2779,7 +2796,7 @@ export class GatewayOrchestrator implements GatewayOrchestratorHandle {
|
||||
const connector = createRedisConnector(resolveRedisConfigFromEnv(this.processConfig.baseEnv ?? process.env));
|
||||
await connector.connect();
|
||||
try {
|
||||
await clearTournamentRuntimeKeys(connector.client, profileName);
|
||||
await clearProfileResetRuntimeKeys(connector.client, profileName);
|
||||
} finally {
|
||||
await connector.disconnect();
|
||||
}
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
|
||||
import {
|
||||
buildGameClockRuntimeKeys,
|
||||
buildProfileResetRuntimeKeys,
|
||||
buildTournamentRuntimeKeys,
|
||||
clearProfileResetRuntimeKeys,
|
||||
clearTournamentRuntimeKeys,
|
||||
} from '../src/orchestrator/gatewayOrchestrator.js';
|
||||
|
||||
@@ -32,4 +35,31 @@ describe('tournament reset state', () => {
|
||||
expect(deleted).toBe(5);
|
||||
expect(calls).toEqual([buildTournamentRuntimeKeys('che:1010')]);
|
||||
});
|
||||
|
||||
it('clears stale clock authority together with tournament projection on season reset', async () => {
|
||||
expect(buildGameClockRuntimeKeys('hwe:default')).toEqual([
|
||||
'sammo:hwe:default:clock:active-revision',
|
||||
'sammo:hwe:default:clock:deadline-generation',
|
||||
'sammo:hwe:default:clock:phase',
|
||||
]);
|
||||
expect(buildProfileResetRuntimeKeys('hwe:default')).toEqual([
|
||||
...buildTournamentRuntimeKeys('hwe:default'),
|
||||
...buildGameClockRuntimeKeys('hwe:default'),
|
||||
]);
|
||||
|
||||
const calls: string[][] = [];
|
||||
const deleted = await clearProfileResetRuntimeKeys(
|
||||
{
|
||||
del: async (keys) => {
|
||||
calls.push(keys);
|
||||
return keys.length;
|
||||
},
|
||||
},
|
||||
'hwe:default'
|
||||
);
|
||||
|
||||
expect(deleted).toBe(8);
|
||||
expect(calls).toEqual([buildProfileResetRuntimeKeys('hwe:default')]);
|
||||
expect(calls[0]).not.toContain('sammo:che:default:clock:phase');
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user