Defer server file changes until guarded restart activation
Persist beta, promotion, drift, and rollback payloads until occupancy and restart-capacity checks pass. Preserve rollback snapshots and campaign ordering, and allow held rollback campaigns to resume safely. Fixes #28 Validation: 805 tests passed, Svelte checks clean, production build passed.
This commit is contained in:
@@ -3,6 +3,7 @@ import { existsSync } from 'node:fs';
|
||||
import { mkdir, readFile, rm, writeFile } from 'node:fs/promises';
|
||||
import { join, resolve } from 'node:path';
|
||||
import { newFixture, type Fixture } from '../helpers/fixture.js';
|
||||
import { activateFiles } from '../helpers/staged-files.js';
|
||||
|
||||
let fixture: Fixture;
|
||||
const town = 't6_zombie_town_1';
|
||||
@@ -39,20 +40,29 @@ describe('T6 config lifecycle in a mixed fleet', () => {
|
||||
expect(script.target_rel_path).toBe('dedicated_zm.cfg');
|
||||
const { betaId } = await openBeta({ scripts: [{ scriptId: script.id, scriptVersionId: version.id }],
|
||||
servers: [town], waitForHealth: false, waitForMatch: false });
|
||||
expect(await readFile(cfgPath(town), 'utf8')).toBe(previous);
|
||||
await activateFiles('beta', betaId);
|
||||
expect(await readFile(cfgPath(town), 'utf8')).toContain('execgts zm_standard_town.cfg map zm_transit');
|
||||
db().prepare("UPDATE beta_servers SET stage = 'ready', restarted_at = ? WHERE beta_id = ?").run(new Date().toISOString(), betaId);
|
||||
db().prepare("UPDATE betas SET state = 'ready-promote' WHERE id = ?").run(betaId);
|
||||
const promoted = await promoteBeta(betaId);
|
||||
expect(new Set(promoted.landed)).toEqual(new Set([town, farm]));
|
||||
expect(existsSync(cfgPath(farm))).toBe(false);
|
||||
await activateFiles('campaign', promoted.deploymentId);
|
||||
const farmConfig = await readFile(cfgPath(farm), 'utf8');
|
||||
expect(farmConfig).toContain('execgts zm_standard_farm.cfg map zm_transit');
|
||||
expect(existsSync(join(fixture.t5, t5, 'configs/dedicated_sp.cfg'))).toBe(false);
|
||||
expect(existsSync(join(fixture.t6, farm, 'configs/dedicated_sp.cfg'))).toBe(false);
|
||||
expect(await scanServerDrift(farm)).toEqual([]);
|
||||
await rm(cfgPath(farm));
|
||||
expect((await runDriftDeployment({ servers: [farm] })).totalRestored).toBe(1);
|
||||
const drift = await runDriftDeployment({ servers: [farm] });
|
||||
expect(drift.totalRestored).toBe(1);
|
||||
expect(existsSync(cfgPath(farm))).toBe(false);
|
||||
await activateFiles('campaign', drift.deploymentId!);
|
||||
expect(await readFile(cfgPath(farm), 'utf8')).toBe(farmConfig);
|
||||
await rollbackPromoteDeployment(promoted.deploymentId);
|
||||
const rollback = await rollbackPromoteDeployment(promoted.deploymentId);
|
||||
expect(await readFile(cfgPath(farm), 'utf8')).toBe(farmConfig);
|
||||
await activateFiles('campaign', rollback.deploymentId);
|
||||
expect(await readFile(cfgPath(town), 'utf8')).toBe(previous);
|
||||
expect(existsSync(cfgPath(farm))).toBe(false);
|
||||
});
|
||||
@@ -71,7 +81,9 @@ describe('T6 config lifecycle in a mixed fleet', () => {
|
||||
content: Buffer.from('sv_voice 0\n') });
|
||||
const { betaId } = await openBeta({ scripts: [{ scriptId: script.id, scriptVersionId: version.id }],
|
||||
servers: [town], waitForHealth: false, waitForMatch: false });
|
||||
await rollbackBeta(betaId);
|
||||
await activateFiles('beta', betaId);
|
||||
const rollback = await rollbackBeta(betaId);
|
||||
await activateFiles('campaign', rollback.deploymentId!);
|
||||
expect(await readFile(cfgPath(town), 'utf8')).toBe(previous);
|
||||
expect(await scanServerDrift(town)).toEqual([]);
|
||||
await runDriftDeployment({ servers: [town] });
|
||||
|
||||
Reference in New Issue
Block a user