Allow revising active betas with fresh tests and history
This commit is contained in:
@@ -1276,6 +1276,41 @@ describe('native provisioning cancellation and rollback', () => {
|
||||
});
|
||||
|
||||
describe('cancelled native mutation bookkeeping', () => {
|
||||
it.each([null, 'before beta'])('keeps the original host receipt across beta revisions (original=%s)', async original => {
|
||||
const job = await queue(); await advance(); await acknowledge(job.deploymentId);
|
||||
const { db } = await import('../../src/lib/server/db/index.js');
|
||||
const { createScript } = await import('../../src/lib/server/fleet/scripts.js');
|
||||
const { openBeta, reviseBeta, rollbackBeta } = await import('../../src/lib/server/fleet/beta.js');
|
||||
const { requestRestart } = await import('../../src/lib/server/provisioning/requests.js');
|
||||
const { reportHostOperation, getHostOperation } = await import('../../src/lib/server/hosts/index.js');
|
||||
const { script, version } = createScript({ name: 'Revised beta', kind: 'script', targetRelPath: 'revision.gsc',
|
||||
content: Buffer.from('revision one'), scopeType: 'game', scopeValue: 't5' });
|
||||
const { betaId } = await openBeta({ scripts: [{ scriptId: script.id, scriptVersionId: version.id }],
|
||||
servers: [job.name], waitForHealth: true, waitForMatch: false });
|
||||
async function activate(before: string | null) {
|
||||
const restart = requestRestart(job.name, { kind: 'beta', id: String(betaId) });
|
||||
await advance();
|
||||
const staged = db().prepare('SELECT stage_operation_id FROM native_provisioning WHERE deployment_id = ?').get(restart.id) as { stage_operation_id: string };
|
||||
const files = getHostOperation(staged.stage_operation_id)!.payload.files as Array<{ id: number; path: string }>;
|
||||
reportHostOperation(hostId, staged.stage_operation_id, { state: 'completed' });
|
||||
await advance();
|
||||
// A dispatched activation must settle before revision submission.
|
||||
await expect(reviseBeta(betaId, 1, [{ scriptId: script.id, content: Buffer.from('premature update') }])).rejects.toThrow();
|
||||
const activation = (await operationFor(restart.id))!;
|
||||
reportHostOperation(hostId, activation.id, { state: 'completed', result: {
|
||||
before: files.map(file => ({ ...file, contentBase64: before === null ? null : Buffer.from(before).toString('base64') }))
|
||||
} });
|
||||
await advance();
|
||||
expect((await detail(restart.id)).state).toBe('done');
|
||||
}
|
||||
await activate(original);
|
||||
await reviseBeta(betaId, 1, [{ scriptId: script.id, content: Buffer.from('revision two') }]);
|
||||
await activate('revision one');
|
||||
const rollback = await rollbackBeta(betaId);
|
||||
expect(db().prepare("SELECT content FROM staged_file_changes WHERE source_kind = 'campaign' AND source_id = ?").get(rollback.deploymentId))
|
||||
.toEqual({ content: original === null ? null : Buffer.from(original) });
|
||||
});
|
||||
|
||||
it('keeps explicit cleanup available after cancelling an unsubmitted creation', async () => {
|
||||
const job = await queue();
|
||||
const { cancelProvisioningJob } = await import('../../src/lib/server/provisioning/cancellation.js');
|
||||
|
||||
Reference in New Issue
Block a user