Add House Party Protocol for fleet-wide queued destruction
This commit is contained in:
@@ -41,6 +41,68 @@ afterEach(async () => {
|
||||
vi.unstubAllEnvs();
|
||||
});
|
||||
|
||||
describe('House Party Protocol', () => {
|
||||
it('includes registered and queued servers once and reuses destruction requests', async () => {
|
||||
const { createServer, queueCreateServer } = await import('../../src/lib/server/fleet/create.js');
|
||||
const { housePartyTargets, queueHouseParty } = await import('../../src/lib/server/fleet/house-party.js');
|
||||
expect(await createServer(input)).toMatchObject({ ok: true });
|
||||
expect(queueCreateServer(input)).toMatchObject({ ok: true });
|
||||
const names = housePartyTargets();
|
||||
expect(names).toEqual([serverName, 't5_zombie_cosmodrome_2']);
|
||||
const first = queueHouseParty(names);
|
||||
expect(first).toMatchObject({ ok: true, deployments: [{ server: serverName }, { server: names[1] }] });
|
||||
expect(queueHouseParty(names)).toEqual(first);
|
||||
});
|
||||
|
||||
it('rejects a changed fleet without queuing any destruction', async () => {
|
||||
const { queueCreateServer } = await import('../../src/lib/server/fleet/create.js');
|
||||
const { housePartyTargets, queueHouseParty } = await import('../../src/lib/server/fleet/house-party.js');
|
||||
const { db } = await import('../../src/lib/server/db/index.js');
|
||||
const names = housePartyTargets();
|
||||
expect(queueCreateServer(input).ok).toBe(true);
|
||||
expect(queueHouseParty(names).ok).toBe(false);
|
||||
expect(db().prepare("SELECT * FROM server_deployments WHERE action = 'destroy'").all()).toEqual([]);
|
||||
});
|
||||
|
||||
it('rolls back the entire bulk request when an insert fails', async () => {
|
||||
const { queueCreateServer } = await import('../../src/lib/server/fleet/create.js');
|
||||
const { housePartyTargets, queueHouseParty } = await import('../../src/lib/server/fleet/house-party.js');
|
||||
const { db } = await import('../../src/lib/server/db/index.js');
|
||||
expect(queueCreateServer(input).ok).toBe(true);
|
||||
expect(queueCreateServer(input).ok).toBe(true);
|
||||
db().exec(`CREATE TRIGGER reject_destroy BEFORE INSERT ON server_deployments
|
||||
WHEN NEW.action = 'destroy' AND NEW.server = 't5_zombie_cosmodrome_2'
|
||||
BEGIN SELECT RAISE(ABORT, 'test failure'); END`);
|
||||
expect(() => queueHouseParty(housePartyTargets())).toThrow('test failure');
|
||||
expect(db().prepare("SELECT * FROM server_deployments WHERE action = 'destroy'").all()).toEqual([]);
|
||||
});
|
||||
|
||||
it('waits for queued creations, then for verified emptiness, and preserves keys', async () => {
|
||||
const { queueCreateServer, processCreations, processDestructions } = await import('../../src/lib/server/fleet/create.js');
|
||||
const { housePartyTargets, queueHouseParty } = await import('../../src/lib/server/fleet/house-party.js');
|
||||
const { getServer } = await import('../../src/lib/server/fleet/servers.js');
|
||||
const { getServerKey } = await import('../../src/lib/server/fleet/server-keys.js');
|
||||
const { komodoDestroyDeployment, komodoInspectHealthy } = await import('../../src/lib/server/integrations/komodo.js');
|
||||
const { rconGetPlayerCount } = await import('../../src/lib/server/integrations/rcon.js');
|
||||
expect(queueCreateServer(input).ok).toBe(true);
|
||||
expect(queueHouseParty(housePartyTargets()).ok).toBe(true);
|
||||
await processDestructions();
|
||||
expect(komodoDestroyDeployment).not.toHaveBeenCalled();
|
||||
await processCreations();
|
||||
vi.mocked(rconGetPlayerCount).mockResolvedValueOnce(2);
|
||||
await processDestructions();
|
||||
vi.mocked(rconGetPlayerCount).mockResolvedValueOnce(null);
|
||||
await processDestructions();
|
||||
expect(komodoDestroyDeployment).not.toHaveBeenCalled();
|
||||
vi.mocked(rconGetPlayerCount).mockResolvedValueOnce(0);
|
||||
vi.mocked(komodoInspectHealthy).mockResolvedValue({ ok: false, kind: 'not-found', message: 'gone' } as never);
|
||||
await processDestructions();
|
||||
expect(komodoDestroyDeployment).toHaveBeenCalledWith(serverName);
|
||||
expect(getServer(serverName)).toBeUndefined();
|
||||
expect(getServerKey(serverName)).toBe('test-key');
|
||||
});
|
||||
});
|
||||
|
||||
async function promotedConfig() {
|
||||
const { createScript, getLatestVersion } = await import('../../src/lib/server/fleet/scripts.js');
|
||||
const { db } = await import('../../src/lib/server/db/index.js');
|
||||
|
||||
Reference in New Issue
Block a user