test(ci): make mattermost reconnect deterministic

This commit is contained in:
Peter Steinberger 2026-04-03 23:28:50 +01:00
parent 2af05ac558
commit 1322aa2ba2
No known key found for this signature in database
1 changed files with 19 additions and 7 deletions

View File

@ -3,7 +3,8 @@ import { runWithReconnect } from "./reconnect.js";
beforeEach(() => {
vi.restoreAllMocks();
vi.useRealTimers();
vi.useFakeTimers();
vi.clearAllMocks();
});
afterEach(() => {
@ -11,6 +12,11 @@ afterEach(() => {
vi.useRealTimers();
});
async function resolveReconnectRun(promise: Promise<void>): Promise<void> {
await vi.runAllTimersAsync();
await promise;
}
describe("runWithReconnect", () => {
it("retries after connectFn resolves (normal close)", async () => {
let callCount = 0;
@ -22,10 +28,11 @@ describe("runWithReconnect", () => {
}
});
await runWithReconnect(connectFn, {
const run = runWithReconnect(connectFn, {
abortSignal: abort.signal,
initialDelayMs: 1,
});
await resolveReconnectRun(run);
expect(connectFn).toHaveBeenCalledTimes(3);
});
@ -42,11 +49,12 @@ describe("runWithReconnect", () => {
abort.abort();
});
await runWithReconnect(connectFn, {
const run = runWithReconnect(connectFn, {
abortSignal: abort.signal,
onError,
initialDelayMs: 1,
});
await resolveReconnectRun(run);
expect(connectFn).toHaveBeenCalledTimes(3);
expect(onError).toHaveBeenCalledTimes(2);
@ -66,13 +74,14 @@ describe("runWithReconnect", () => {
throw new Error("connection refused");
});
await runWithReconnect(connectFn, {
const run = runWithReconnect(connectFn, {
abortSignal: abort.signal,
onReconnect: (delayMs) => delays.push(delayMs),
// Keep this test fast: validate the exponential pattern, not real-time waiting.
initialDelayMs: 1,
maxDelayMs: 10,
});
await resolveReconnectRun(run);
expect(connectFn).toHaveBeenCalledTimes(6);
// 5 errors produce delays: 1, 2, 4, 8, 10(cap)
@ -99,12 +108,13 @@ describe("runWithReconnect", () => {
abort.abort();
});
await runWithReconnect(connectFn, {
const run = runWithReconnect(connectFn, {
abortSignal: abort.signal,
onReconnect: (delayMs) => delays.push(delayMs),
initialDelayMs: 1,
maxDelayMs: 60_000,
});
await resolveReconnectRun(run);
expect(connectFn).toHaveBeenCalledTimes(4);
// call 1: fail -> delay 1
@ -146,10 +156,11 @@ describe("runWithReconnect", () => {
});
const start = Date.now();
await runWithReconnect(connectFn, {
const run = runWithReconnect(connectFn, {
abortSignal: abort.signal,
initialDelayMs: 60_000,
});
await resolveReconnectRun(run);
const elapsed = Date.now() - start;
expect(connectFn).toHaveBeenCalledTimes(1);
@ -168,13 +179,14 @@ describe("runWithReconnect", () => {
abort.abort();
});
await runWithReconnect(connectFn, {
const run = runWithReconnect(connectFn, {
abortSignal: abort.signal,
onReconnect: (delayMs) => delays.push(delayMs),
initialDelayMs: 10,
jitterRatio: 0.5,
random: () => 1,
});
await resolveReconnectRun(run);
expect(connectFn).toHaveBeenCalledTimes(2);
expect(delays).toEqual([15]);