Preserve server status when batch probes miss the deadline
This commit is contained in:
@@ -47,11 +47,14 @@ async function setup(count = 5, hostCount = 1) {
|
||||
describe('host status observations', () => {
|
||||
it('uses one batch per host for a fifteen-server pass and shares overlapping scans', async () => {
|
||||
const api = await setup(5, 3);
|
||||
const hosts = await import('../../src/lib/server/hosts/index.js');
|
||||
const wait = vi.spyOn(hosts, 'waitHostOperationStatus');
|
||||
const passes = [api.fanoutStatus(), api.fanoutStatus()];
|
||||
try {
|
||||
await vi.waitFor(() => expect(api.operations()).toHaveLength(3));
|
||||
for (const operation of api.operations()) {
|
||||
expect(operation.kind).toBe('rcon.status-batch');
|
||||
expect(wait).toHaveBeenCalledWith(operation.id, 25_000);
|
||||
expect(operation.payload.instances).toHaveLength(5);
|
||||
expect(api.pendingHostOperations(operation.hostId, 'health').map(op => op.id)).toEqual([operation.id]);
|
||||
expect(api.pendingHostOperations(operation.hostId, 'write')).toEqual([]);
|
||||
@@ -115,6 +118,32 @@ describe('host status observations', () => {
|
||||
expect(api.operations()).toHaveLength(1);
|
||||
});
|
||||
|
||||
it('preserves previous game evidence for deadline skips while recording actual timeouts', async () => {
|
||||
const api = await setup(3);
|
||||
const first = api.fanoutStatus();
|
||||
await vi.waitFor(() => expect(api.operations()).toHaveLength(1));
|
||||
api.complete(); await first;
|
||||
const previous = api.getServer('server-0-0')!;
|
||||
const previousGame = api.monitoringStatus('server-0-0')?.game;
|
||||
vi.setSystemTime(at + 31_000);
|
||||
const pass = api.fanoutStatus();
|
||||
try {
|
||||
await vi.waitFor(() => expect(api.operations()).toHaveLength(2));
|
||||
const operation = api.operations().find(op => op.state !== 'completed')!;
|
||||
api.reportHostOperation(operation.hostId, operation.id, { state: 'completed', result: { ok: false, results: [
|
||||
{ instanceId: 'instance-0-0', generation: 1, reply: { ok: false, reason: 'deadline', text: '' } },
|
||||
{ instanceId: 'instance-0-1', generation: 1, reply: { ok: false, reason: 'timeout', text: '' } },
|
||||
{ instanceId: 'instance-0-2', generation: 1, reply: { ok: true, text: 'map: mp_kino\nnum score ping guid name\n--- ----- ---- ---- ----\n' } }
|
||||
] } });
|
||||
} finally { api.complete(); await pass; }
|
||||
expect(api.getServer('server-0-0')).toMatchObject({ last_checked_at: previous.last_checked_at,
|
||||
last_seen_at: previous.last_seen_at, last_error: previous.last_error, last_players: previous.last_players,
|
||||
last_reply_snippet: previous.last_reply_snippet });
|
||||
expect(api.monitoringStatus('server-0-0')?.game).toEqual(previousGame);
|
||||
expect(api.getServer('server-0-1')?.last_error).toContain('timeout:');
|
||||
expect(Date.parse(api.getServer('server-0-2')!.last_seen_at!)).toBeGreaterThanOrEqual(at + 31_000);
|
||||
});
|
||||
|
||||
it('records each failed or omitted result without retrying the batch per server', async () => {
|
||||
const api = await setup();
|
||||
const pass = api.fanoutStatus();
|
||||
|
||||
Reference in New Issue
Block a user