feat: add Watchdog recovery and drift rebuild workflows
This commit is contained in:
@@ -54,6 +54,19 @@ async function tick(seconds = 15, players = 4, healthy = true) {
|
||||
const scriptPath = (name: string) => join(fixture.t5, name, 'runtime/plutonium/storage/t5/raw/scripts/sp/test.gsc');
|
||||
|
||||
describe('durable beta test plans', () => {
|
||||
it('waits for occupied telemetry to clear before restarting a beta despite an empty RCON response', async () => {
|
||||
const id = await openPlan(defaultPlan());
|
||||
const { listBetaServers } = await import('../../src/lib/server/fleet/beta.js');
|
||||
const { komodoRestart } = await import('../../src/lib/server/integrations/komodo.js');
|
||||
await postTelemetry(gameEvent('heartbeat', 4, 2));
|
||||
await tick();
|
||||
expect(komodoRestart).not.toHaveBeenCalled();
|
||||
expect(listBetaServers(id)[0].stage).toBe('awaiting-empty');
|
||||
await postTelemetry(gameEvent('heartbeat', 4, 0));
|
||||
await tick();
|
||||
expect(komodoRestart).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('holds file deployment until each wave passes, and rollback leaves undeployed files alone', async () => {
|
||||
await writeFile(scriptPath(names[1]), 'original untracked file');
|
||||
const id = await openPlan({ ...defaultPlan(), waveSize: 1 }, names);
|
||||
@@ -81,7 +94,7 @@ describe('durable beta test plans', () => {
|
||||
it('uses script events instead of logs and keeps match progress across app restarts', async () => {
|
||||
await postTelemetry(gameEvent('game_end'));
|
||||
const id = await openPlan({ ...defaultPlan(), requirements: [requirement('matches', 'matches')] });
|
||||
await tick(); await tick();
|
||||
await tick(46); await tick();
|
||||
const { testView } = await import('../../src/lib/server/fleet/beta-tests.js');
|
||||
await appendFile(join(fixture.t5, names[0], 'logs/games_sp.log'), 'InitGame:\n 0:00 J;new;1;Josh\nExitLevel: executed\n');
|
||||
await tick();
|
||||
@@ -98,7 +111,7 @@ describe('durable beta test plans', () => {
|
||||
it('automatically credits ordinary rounds only to active deployed beta servers', async () => {
|
||||
const id = await openPlan({ ...defaultPlan(), waveSize: 1, requirements: [requirement('round', 'round')] }, names);
|
||||
await postTelemetry(gameEvent('round_change'));
|
||||
await tick(); await tick();
|
||||
await tick(46); await tick();
|
||||
const { testView } = await import('../../src/lib/server/fleet/beta-tests.js');
|
||||
expect(testView(id)?.servers[0].progress[0].current).toBe(0);
|
||||
await postTelemetry(gameEvent('round_change', 99, 4, names[1]));
|
||||
@@ -117,7 +130,7 @@ describe('durable beta test plans', () => {
|
||||
const first = currentRun(id, names[0])!;
|
||||
expect(testView(id)?.servers[0].progress[0].current).toBe(0);
|
||||
await postTelemetry(gameEvent('game_start'));
|
||||
await tick(); await tick();
|
||||
await tick(46); await tick();
|
||||
expect(currentRun(id, names[0])?.id).not.toBe(first.id);
|
||||
expect(currentRun(id, names[0])?.phase).toBe(1);
|
||||
expect(testView(id)?.servers[0].progress[0].current).toBe(0);
|
||||
@@ -212,7 +225,7 @@ describe('durable beta test plans', () => {
|
||||
expect(retry.status).toBe(200);
|
||||
await postTelemetry(gameEvent('round_change'));
|
||||
expect(testView(id)?.servers).toHaveLength(0);
|
||||
await tick(); await tick();
|
||||
await tick(46); await tick();
|
||||
expect(testView(id)?.servers[0].progress[0].current).toBe(0);
|
||||
await postTelemetry(gameEvent('round_change'));
|
||||
expect(testView(id)?.servers[0].progress[0].current).toBe(25);
|
||||
|
||||
Reference in New Issue
Block a user