refactor: share readiness test harness

This commit is contained in:
Peter Steinberger
2026-03-13 17:31:29 +00:00
parent 06bdfc403e
commit db9c755045

View File

@@ -46,172 +46,188 @@ function createHealthyDiscordManager(startedAt: number, lastEventAt: number): Ch
);
}
function withReadinessClock(run: () => void) {
vi.useFakeTimers();
vi.setSystemTime(new Date("2026-03-06T12:00:00Z"));
try {
run();
} finally {
vi.useRealTimers();
}
}
function createReadinessHarness(params: {
startedAgoMs: number;
accounts: Record<string, Partial<ChannelAccountSnapshot>>;
cacheTtlMs?: number;
}) {
const startedAt = Date.now() - params.startedAgoMs;
const manager = createManager(snapshotWith(params.accounts));
return {
manager,
readiness: createReadinessChecker({
channelManager: manager,
startedAt,
cacheTtlMs: params.cacheTtlMs,
}),
};
}
describe("createReadinessChecker", () => {
it("reports ready when all managed channels are healthy", () => {
vi.useFakeTimers();
vi.setSystemTime(new Date("2026-03-06T12:00:00Z"));
const startedAt = Date.now() - 5 * 60_000;
const manager = createHealthyDiscordManager(startedAt, Date.now() - 1_000);
withReadinessClock(() => {
const startedAt = Date.now() - 5 * 60_000;
const manager = createHealthyDiscordManager(startedAt, Date.now() - 1_000);
const readiness = createReadinessChecker({ channelManager: manager, startedAt });
expect(readiness()).toEqual({ ready: true, failing: [], uptimeMs: 300_000 });
vi.useRealTimers();
const readiness = createReadinessChecker({ channelManager: manager, startedAt });
expect(readiness()).toEqual({ ready: true, failing: [], uptimeMs: 300_000 });
});
});
it("ignores disabled and unconfigured channels", () => {
vi.useFakeTimers();
vi.setSystemTime(new Date("2026-03-06T12:00:00Z"));
const startedAt = Date.now() - 5 * 60_000;
const manager = createManager(
snapshotWith({
discord: {
running: false,
enabled: false,
configured: true,
lastStartAt: startedAt,
withReadinessClock(() => {
const { readiness } = createReadinessHarness({
startedAgoMs: 5 * 60_000,
accounts: {
discord: {
running: false,
enabled: false,
configured: true,
lastStartAt: Date.now() - 5 * 60_000,
},
telegram: {
running: false,
enabled: true,
configured: false,
lastStartAt: Date.now() - 5 * 60_000,
},
},
telegram: {
running: false,
enabled: true,
configured: false,
lastStartAt: startedAt,
},
}),
);
const readiness = createReadinessChecker({ channelManager: manager, startedAt });
expect(readiness()).toEqual({ ready: true, failing: [], uptimeMs: 300_000 });
vi.useRealTimers();
});
expect(readiness()).toEqual({ ready: true, failing: [], uptimeMs: 300_000 });
});
});
it("uses startup grace before marking disconnected channels not ready", () => {
vi.useFakeTimers();
vi.setSystemTime(new Date("2026-03-06T12:00:00Z"));
const startedAt = Date.now() - 30_000;
const manager = createManager(
snapshotWith({
discord: {
running: true,
connected: false,
enabled: true,
configured: true,
lastStartAt: startedAt,
withReadinessClock(() => {
const { readiness } = createReadinessHarness({
startedAgoMs: 30_000,
accounts: {
discord: {
running: true,
connected: false,
enabled: true,
configured: true,
lastStartAt: Date.now() - 30_000,
},
},
}),
);
const readiness = createReadinessChecker({ channelManager: manager, startedAt });
expect(readiness()).toEqual({ ready: true, failing: [], uptimeMs: 30_000 });
vi.useRealTimers();
});
expect(readiness()).toEqual({ ready: true, failing: [], uptimeMs: 30_000 });
});
});
it("reports disconnected managed channels after startup grace", () => {
vi.useFakeTimers();
vi.setSystemTime(new Date("2026-03-06T12:00:00Z"));
const startedAt = Date.now() - 5 * 60_000;
const manager = createManager(
snapshotWith({
discord: {
running: true,
connected: false,
enabled: true,
configured: true,
lastStartAt: startedAt,
withReadinessClock(() => {
const { readiness } = createReadinessHarness({
startedAgoMs: 5 * 60_000,
accounts: {
discord: {
running: true,
connected: false,
enabled: true,
configured: true,
lastStartAt: Date.now() - 5 * 60_000,
},
},
}),
);
const readiness = createReadinessChecker({ channelManager: manager, startedAt });
expect(readiness()).toEqual({ ready: false, failing: ["discord"], uptimeMs: 300_000 });
vi.useRealTimers();
});
expect(readiness()).toEqual({ ready: false, failing: ["discord"], uptimeMs: 300_000 });
});
});
it("keeps restart-pending channels ready during reconnect backoff", () => {
vi.useFakeTimers();
vi.setSystemTime(new Date("2026-03-06T12:00:00Z"));
const startedAt = Date.now() - 5 * 60_000;
const manager = createManager(
snapshotWith({
discord: {
running: false,
restartPending: true,
reconnectAttempts: 3,
enabled: true,
configured: true,
lastStartAt: startedAt - 30_000,
lastStopAt: Date.now() - 5_000,
withReadinessClock(() => {
const startedAt = Date.now() - 5 * 60_000;
const { readiness } = createReadinessHarness({
startedAgoMs: 5 * 60_000,
accounts: {
discord: {
running: false,
restartPending: true,
reconnectAttempts: 3,
enabled: true,
configured: true,
lastStartAt: startedAt - 30_000,
lastStopAt: Date.now() - 5_000,
},
},
}),
);
const readiness = createReadinessChecker({ channelManager: manager, startedAt });
expect(readiness()).toEqual({ ready: true, failing: [], uptimeMs: 300_000 });
vi.useRealTimers();
});
expect(readiness()).toEqual({ ready: true, failing: [], uptimeMs: 300_000 });
});
});
it("treats stale-socket channels as ready to avoid pulling healthy idle pods", () => {
vi.useFakeTimers();
vi.setSystemTime(new Date("2026-03-06T12:00:00Z"));
const startedAt = Date.now() - 31 * 60_000;
const manager = createManager(
snapshotWith({
discord: {
running: true,
connected: true,
enabled: true,
configured: true,
lastStartAt: startedAt,
lastEventAt: Date.now() - 31 * 60_000,
withReadinessClock(() => {
const startedAt = Date.now() - 31 * 60_000;
const { readiness } = createReadinessHarness({
startedAgoMs: 31 * 60_000,
accounts: {
discord: {
running: true,
connected: true,
enabled: true,
configured: true,
lastStartAt: startedAt,
lastEventAt: Date.now() - 31 * 60_000,
},
},
}),
);
const readiness = createReadinessChecker({ channelManager: manager, startedAt });
expect(readiness()).toEqual({ ready: true, failing: [], uptimeMs: 1_860_000 });
vi.useRealTimers();
});
expect(readiness()).toEqual({ ready: true, failing: [], uptimeMs: 1_860_000 });
});
});
it("keeps telegram long-polling channels ready without stale-socket classification", () => {
vi.useFakeTimers();
vi.setSystemTime(new Date("2026-03-06T12:00:00Z"));
const startedAt = Date.now() - 31 * 60_000;
const manager = createManager(
snapshotWith({
telegram: {
running: true,
connected: true,
enabled: true,
configured: true,
lastStartAt: startedAt,
lastEventAt: null,
withReadinessClock(() => {
const startedAt = Date.now() - 31 * 60_000;
const { readiness } = createReadinessHarness({
startedAgoMs: 31 * 60_000,
accounts: {
telegram: {
running: true,
connected: true,
enabled: true,
configured: true,
lastStartAt: startedAt,
lastEventAt: null,
},
},
}),
);
const readiness = createReadinessChecker({ channelManager: manager, startedAt });
expect(readiness()).toEqual({ ready: true, failing: [], uptimeMs: 1_860_000 });
vi.useRealTimers();
});
expect(readiness()).toEqual({ ready: true, failing: [], uptimeMs: 1_860_000 });
});
});
it("caches readiness snapshots briefly to keep repeated probes cheap", () => {
vi.useFakeTimers();
vi.setSystemTime(new Date("2026-03-06T12:00:00Z"));
const startedAt = Date.now() - 5 * 60_000;
const manager = createHealthyDiscordManager(startedAt, Date.now() - 1_000);
withReadinessClock(() => {
const { manager, readiness } = createReadinessHarness({
startedAgoMs: 5 * 60_000,
accounts: {
discord: {
running: true,
connected: true,
enabled: true,
configured: true,
lastStartAt: Date.now() - 5 * 60_000,
lastEventAt: Date.now() - 1_000,
},
},
cacheTtlMs: 1_000,
});
expect(readiness()).toEqual({ ready: true, failing: [], uptimeMs: 300_000 });
vi.advanceTimersByTime(500);
expect(readiness()).toEqual({ ready: true, failing: [], uptimeMs: 300_500 });
expect(manager.getRuntimeSnapshot).toHaveBeenCalledTimes(1);
const readiness = createReadinessChecker({
channelManager: manager,
startedAt,
cacheTtlMs: 1_000,
vi.advanceTimersByTime(600);
expect(readiness()).toEqual({ ready: true, failing: [], uptimeMs: 301_100 });
expect(manager.getRuntimeSnapshot).toHaveBeenCalledTimes(2);
});
expect(readiness()).toEqual({ ready: true, failing: [], uptimeMs: 300_000 });
vi.advanceTimersByTime(500);
expect(readiness()).toEqual({ ready: true, failing: [], uptimeMs: 300_500 });
expect(manager.getRuntimeSnapshot).toHaveBeenCalledTimes(1);
vi.advanceTimersByTime(600);
expect(readiness()).toEqual({ ready: true, failing: [], uptimeMs: 301_100 });
expect(manager.getRuntimeSnapshot).toHaveBeenCalledTimes(2);
vi.useRealTimers();
});
});