Files
openchamber/packages/ui/src/lib/browser/crashRecovery.test.ts
T

56 lines
2.2 KiB
TypeScript
Raw Normal View History

import { describe, expect, test } from 'bun:test';
import {
CRASH_RECOVERY_BASE_DELAY_MS,
CRASH_RECOVERY_MAX_ATTEMPTS,
CRASH_RECOVERY_WINDOW_MS,
INITIAL_CRASH_RECOVERY_STATE,
planCrashRecovery,
} from './crashRecovery';
describe('crash recovery', () => {
test('recovers from the first crash immediately enough to feel automatic', () => {
const plan = planCrashRecovery(INITIAL_CRASH_RECOVERY_STATE, 1_000);
expect(plan?.delayMs).toBe(CRASH_RECOVERY_BASE_DELAY_MS);
expect(plan?.state).toEqual({ attempts: 1, windowStartedAt: 1_000 });
});
test('waits longer after each attempt instead of reloading in a tight loop', () => {
let state = INITIAL_CRASH_RECOVERY_STATE;
const delays: number[] = [];
for (let index = 0; index < CRASH_RECOVERY_MAX_ATTEMPTS; index += 1) {
const plan = planCrashRecovery(state, 1_000 + index);
expect(plan === null).toBe(false);
delays.push(plan!.delayMs);
state = plan!.state;
}
expect(delays).toEqual([250, 500, 1000]);
});
test('gives up once the attempts in this window are spent', () => {
let state = INITIAL_CRASH_RECOVERY_STATE;
for (let index = 0; index < CRASH_RECOVERY_MAX_ATTEMPTS; index += 1) {
state = planCrashRecovery(state, 1_000)!.state;
}
expect(planCrashRecovery(state, 1_000)).toBeNull();
});
test('a crash long after the last one starts over rather than staying given up', () => {
let state = INITIAL_CRASH_RECOVERY_STATE;
for (let index = 0; index < CRASH_RECOVERY_MAX_ATTEMPTS; index += 1) {
state = planCrashRecovery(state, 1_000)!.state;
}
const later = 1_000 + CRASH_RECOVERY_WINDOW_MS;
const plan = planCrashRecovery(state, later);
expect(plan?.delayMs).toBe(CRASH_RECOVERY_BASE_DELAY_MS);
expect(plan?.state).toEqual({ attempts: 1, windowStartedAt: later });
});
test('crashes inside the window keep counting against the same window', () => {
const first = planCrashRecovery(INITIAL_CRASH_RECOVERY_STATE, 1_000)!;
const second = planCrashRecovery(first.state, 1_000 + CRASH_RECOVERY_WINDOW_MS - 1)!;
expect(second.state.windowStartedAt).toBe(1_000);
expect(second.state.attempts).toBe(2);
});
});