Files
core2026/app/game-api/test/tournamentStoreRevision.integration.test.ts
T
Hide_D e4ac2a60b1 perf: 공유 지도와 토너먼트 revision을 원자화
지도 캐시는 coverage가 확인된 PostgreSQL map.world head만 사용하고 실패 시 전체 계산으로 복구한다. 토너먼트 Redis payload와 source revision은 Lua 한 번으로 갱신한다.
2026-08-16 18:37:48 +00:00

48 lines
1.7 KiB
TypeScript

import { randomUUID } from 'node:crypto';
import { afterAll, beforeAll, describe, expect, it } from 'vitest';
import { createRedisConnector, resolveRedisConfigFromEnv, type RedisConnector } from '@sammo-ts/infra';
import { buildTournamentKeys } from '../src/tournament/keys.js';
import { TournamentStore } from '../src/tournament/store.js';
const integration = describe.skipIf(!process.env.REDIS_URL);
integration('TournamentStore Redis source revision', () => {
let connector: RedisConnector;
const profile = `test:tournament-revision:${randomUUID()}`;
const keys = buildTournamentKeys(profile);
beforeAll(async () => {
connector = createRedisConnector(resolveRedisConfigFromEnv());
await connector.connect();
});
afterAll(async () => {
if (!connector) return;
await connector.client.del([
keys.stateKey,
keys.participantsKey,
keys.matchesKey,
keys.bettingKey,
keys.sourceRevisionKey,
]);
await connector.disconnect();
});
it('commits concurrent payload writes with unique monotonic revisions', async () => {
const store = new TournamentStore(connector.client, keys);
const revisions = await Promise.all(
Array.from({ length: 20 }, (_, index) =>
store.setMatches([
{ id: index + 1, stage: 7, roundIndex: index, attackerId: 1, defenderId: 2 },
])
)
);
expect(new Set(revisions).size).toBe(20);
await expect(store.getSourceRevision()).resolves.toBe('20');
await expect(store.getMatches()).resolves.toHaveLength(1);
});
});