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 { readFile, mkdir } from 'node:fs/promises';
|
||||
import { existsSync } from 'node:fs';
|
||||
import { join } from 'node:path';
|
||||
import { newFixture, type Fixture } from '../helpers/fixture.js';
|
||||
import { activateFiles } from '../helpers/staged-files.js';
|
||||
|
||||
let fixture: Fixture;
|
||||
|
||||
@@ -34,7 +35,7 @@ async function seedFleet(): Promise<void> {
|
||||
}
|
||||
|
||||
describe('config baseline + overlay flow', () => {
|
||||
it('composes baseline + overlay and writes dedicated_sp.cfg on beta open, restores pre-beta state on rollback', async () => {
|
||||
it('composes baseline + overlay for activation and queues restoration of the pre-beta state', async () => {
|
||||
await seedFleet();
|
||||
const { createScript, getLatestVersion } = await import('../../src/lib/server/fleet/scripts.js');
|
||||
const { openBeta, rollbackBeta } = await import('../../src/lib/server/fleet/beta.js');
|
||||
@@ -70,9 +71,10 @@ describe('config baseline + overlay flow', () => {
|
||||
waitForMatch: false
|
||||
});
|
||||
|
||||
// 4. Verify: composed cfg lands at configs/dedicated_sp.cfg (in place,
|
||||
// NO -beta suffix — the game reads the exact filename).
|
||||
// The live filename is untouched until activation.
|
||||
const cfgPath = join(fixture.t5, 't5_zombie_theater_1', 'configs', 'dedicated_sp.cfg');
|
||||
expect(existsSync(cfgPath)).toBe(false);
|
||||
await activateFiles('beta', betaId);
|
||||
expect(existsSync(cfgPath)).toBe(true);
|
||||
const composed = (await readFile(cfgPath)).toString('utf8');
|
||||
expect(composed).toContain('set g_inactivity "0"');
|
||||
@@ -82,7 +84,9 @@ describe('config baseline + overlay flow', () => {
|
||||
|
||||
// 5. Rollback restores the pre-beta state. There was no cfg on disk
|
||||
// beforehand, so rollback should just remove the beta-written file.
|
||||
await rollbackBeta(betaId);
|
||||
const rollback = await rollbackBeta(betaId);
|
||||
expect(await readFile(cfgPath, 'utf8')).toBe(composed);
|
||||
await activateFiles('campaign', rollback.deploymentId!);
|
||||
expect(existsSync(cfgPath)).toBe(false);
|
||||
});
|
||||
|
||||
@@ -110,6 +114,7 @@ describe('config baseline + overlay flow', () => {
|
||||
waitForHealth: false,
|
||||
waitForMatch: false
|
||||
});
|
||||
await activateFiles('beta', betaId);
|
||||
|
||||
const row = db()
|
||||
.prepare(`SELECT stage, error FROM beta_servers WHERE beta_id = ? AND server = ?`)
|
||||
@@ -146,6 +151,8 @@ describe('plugin kind writes to plugin destination', () => {
|
||||
});
|
||||
|
||||
const pluginPath = join(fixture.t5, 't5_zombie_theater_1', 'runtime/plutonium/plugins', 'demo.dll');
|
||||
expect(existsSync(pluginPath)).toBe(false);
|
||||
await activateFiles('beta', betaId);
|
||||
expect(existsSync(pluginPath)).toBe(true);
|
||||
const bytes = await readFile(pluginPath);
|
||||
expect(bytes.equals(Buffer.from([0x00, 0x01, 0x02, 0x03]))).toBe(true);
|
||||
|
||||
Reference in New Issue
Block a user