Automatically deploy the lowest available lobby with exact ID preview

This commit is contained in:
2026-09-17 15:59:29 -04:00
parent ae173517b6
commit e8e7332365
5 changed files with 39 additions and 47 deletions
+19 -14
View File
@@ -127,15 +127,16 @@ describe('persistent server keys', () => {
const { komodoCreateDeployment, komodoInspectHealthy } = await import('../../src/lib/server/integrations/komodo.js');
vi.mocked(komodoInspectHealthy).mockResolvedValue({ ok: false, kind: 'not-found', message: 'gone' } as never);
const name = 't5_zombie_cosmodrome_2';
expect(await createServer({ ...input, lobby: 2 })).toMatchObject({ ok: true, name });
expect(await createServer(input)).toMatchObject({ ok: true, name: serverName });
expect(await createServer(input)).toMatchObject({ ok: true, name });
expect(getServerKey(name)).toBe('test-key');
expect(await destroyServer(name)).toMatchObject({ ok: true });
expect(listServerKeys()).toEqual([expect.objectContaining({ server_id: name, deployed: 0 })]);
expect(listServerKeys()).toContainEqual(expect.objectContaining({ server_id: name, deployed: 0 }));
expect(JSON.stringify(listServerKeys())).not.toContain('test-key');
expect(await createServer({ gameMode: 'zombie', mapSlug: 'cosmodrome', lobby: 2 })).toMatchObject({ ok: true, name });
expect(await createServer({ gameMode: 'zombie', mapSlug: 'cosmodrome', expectedName: name })).toMatchObject({ ok: true, name });
const spec = vi.mocked(komodoCreateDeployment).mock.calls.at(-1)![0];
expect(spec.environment).toContainEqual({ variable: 'PLUTO_SERVER_KEY', value: 'test-key' });
expect(await createServer({ gameMode: 'zombie', mapSlug: 'cosmodrome', lobby: 1 })).toMatchObject({ ok: false, kind: 'bad-request' });
expect(await createServer({ gameMode: 'zombie', mapSlug: 'cosmodrome' })).toMatchObject({ ok: false, kind: 'bad-request' });
});
it('updates and removes keys independently of deployments and survives reopening the database', async () => {
@@ -153,15 +154,19 @@ describe('persistent server keys', () => {
expect(() => saveServerKey(serverName, 'two words')).toThrow();
});
it('rejects invalid or occupied lobbies before external operations', async () => {
const { createServer } = await import('../../src/lib/server/fleet/create.js');
const { komodoCreateDeployment } = await import('../../src/lib/server/integrations/komodo.js');
for (const lobby of [0, 21, 1.5]) {
expect(await createServer({ ...input, lobby })).toMatchObject({ ok: false, kind: 'bad-request' });
}
expect(komodoCreateDeployment).not.toHaveBeenCalled();
expect(await createServer({ ...input, lobby: 2 })).toMatchObject({ ok: true });
expect(await createServer({ ...input, lobby: 2 })).toMatchObject({ ok: false, kind: 'no-slot' });
expect(komodoCreateDeployment).toHaveBeenCalledTimes(1);
it('fills the lowest gap and rejects stale previews before saving a key or deploying', async () => {
const { createServer, destroyServer } = await import('../../src/lib/server/fleet/create.js');
const { getServerKey } = await import('../../src/lib/server/fleet/server-keys.js');
const { komodoCreateDeployment, komodoInspectHealthy } = await import('../../src/lib/server/integrations/komodo.js');
vi.mocked(komodoInspectHealthy).mockResolvedValue({ ok: false } as never);
expect(await createServer(input)).toMatchObject({ ok: true, name: serverName });
expect(await createServer(input)).toMatchObject({ ok: true, name: 't5_zombie_cosmodrome_2' });
await destroyServer(serverName);
expect(await createServer({ ...input, plutoKey: 'wrong-key', expectedName: 't5_zombie_cosmodrome_3' }))
.toMatchObject({ ok: false, kind: 'no-slot' });
expect(getServerKey(serverName)).toBe('test-key');
expect(komodoCreateDeployment).toHaveBeenCalledTimes(2);
expect(await createServer({ gameMode: 'zombie', mapSlug: 'cosmodrome', expectedName: serverName }))
.toMatchObject({ ok: true, name: serverName });
});
});