Simplify game files to automatic T5 and T6 uploads

This commit is contained in:
2026-10-04 12:23:36 -04:00
parent 482e27e735
commit 68323c0baa
19 changed files with 588 additions and 232 deletions
+34 -1
View File
@@ -33,7 +33,7 @@ afterEach(async () => { await fixture.cleanup(); vi.unstubAllEnvs(); });
async function prepareLibrary(game: 't5' | 't6' = 't5') {
const libs = await import('../../src/lib/server/game-files/index.js');
const version = libs.createLibraryImport({ hostId, game, name: game, version: '1' });
const version = libs.createLibraryImport({ hostId, game });
const bytes = Buffer.from('verified base game');
const file = { path: 'zone/base.ff', size: bytes.length, sha256: createHash('sha256').update(bytes).digest('hex') };
libs.setImportManifest(hostId, version.id, [file]);
@@ -73,6 +73,39 @@ async function detail(id: string) {
}
describe('native instance provisioning', () => {
it('selects the latest game files automatically and rejects stale explicit selections', async () => {
const { nativeSelection } = await import('../../src/lib/server/provisioning/native.js');
expect(() => nativeSelection({ hostId, image }, 't5')).toThrow('Upload T5 game files');
const old = await prepareLibrary('t5');
expect(nativeSelection({ hostId, image }, 't5').libraryId).toBe(old.id);
const latest = await prepareLibrary('t5');
expect(nativeSelection({ hostId, image }, 't5').libraryId).toBe(latest.id);
expect(() => nativeSelection({ hostId, image, libraryId: old.id }, 't5')).toThrow('Refresh the launch preview');
});
it('rejects a launch preview made before newer game files were published without reserving a server', async () => {
await prepareLibrary('t5');
const { previewNativeCreation, queueNativeCreation } = await import('../../src/lib/server/provisioning/native.js');
const preview = previewNativeCreation({ hostId, image, game: 't5', mapSlug: 'theater' });
await prepareLibrary('t5');
const result = queueNativeCreation({ game: 't5', gameMode: 'zombie', mapSlug: 'theater', previewId: preview.id, plutoKey: 'new-key' });
expect(result).toMatchObject({ ok: false, message: expect.stringContaining('Refresh the launch preview') });
const { db } = await import('../../src/lib/server/db/index.js');
expect(db().prepare('SELECT COUNT(*) AS count FROM native_instances').get()).toEqual({ count: 0 });
expect(db().prepare('SELECT COUNT(*) AS count FROM ec_host_ports').get()).toEqual({ count: 0 });
});
it('keeps a queued server pinned to its accepted files when newer game files arrive', async () => {
const job = await queue();
const acceptedId = libraryId;
const latest = await prepareLibrary('t5');
expect(latest.id).not.toBe(acceptedId);
await advance();
expect((await operationFor(job.deploymentId))?.payload.libraryId).toBe(acceptedId);
const { nativeInstance } = await import('../../src/lib/server/backends/native.js');
expect(nativeInstance(job.name)?.library_id).toBe(acceptedId);
});
it.each(['t5', 't6'] as const)('queues and verifies a %s deployment without Komodo', async game => {
const job = await queue(game); await advance();
const operation = await operationFor(job.deploymentId);