Skip to content

Commit

Permalink
Simplify exponential backoff test cases
Browse files Browse the repository at this point in the history
  • Loading branch information
justuswilhelm committed Apr 20, 2024
1 parent 56b6096 commit 568b9de
Showing 1 changed file with 32 additions and 29 deletions.
61 changes: 32 additions & 29 deletions __tests__/index/retryConnectionDelay.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,71 +68,74 @@ describe("Exponential backoff delay", () => {
describe("with rate 2, backoffLimit 8000 ms", () => {
// The initial delay shall be 1 s
const initialDelay = 1000;
const exponentialBackoffParams: ExponentialBackoffParams = {
const exponentialBackoff: ExponentialBackoffParams = {
backoffRate: 2,
// We put the ceiling at exactly 8000 ms
backoffLimit: 8000,
};
const attempts: [number, number][] = [
[1000, 0],
[2000, 1],
[4000, 2],
[8000, 3],
[8000, 4],
];
it("will never be more than 8000 ms with rate set to 2", () => {
expect(
calculateRetryDelayFactor(exponentialBackoffParams, initialDelay, 0),
).toBe(1000);
expect(
calculateRetryDelayFactor(exponentialBackoffParams, initialDelay, 1),
).toBe(2000);
expect(
calculateRetryDelayFactor(exponentialBackoffParams, initialDelay, 2),
).toBe(4000);
expect(
calculateRetryDelayFactor(exponentialBackoffParams, initialDelay, 3),
).toBe(8000);
expect(
calculateRetryDelayFactor(exponentialBackoffParams, initialDelay, 4),
).toBe(8000);
attempts.forEach(([delay, failedAttempts]) => {
expect(
calculateRetryDelayFactor(
exponentialBackoff,
initialDelay,
failedAttempts,
),
).toBe(delay);
});
});

it("should delay reconnection attempts exponentially", async () => {
// Somehow we need to convincen typescript here that "WebSocket" is
// totally valid. Could be because it doesn't assume WebSocket is part of
// global / the index key is missing
const webSocketSpy = jest.spyOn(global, "WebSocket" as any);
webSocketSpy.mockImplementation(() => {});
const setTimeoutSpy = jest.spyOn(global, "setTimeout");
const sarus = new Sarus({
url,
exponentialBackoff: exponentialBackoffParams,
});
const sarus = new Sarus({ url, exponentialBackoff });
expect(sarus.state).toStrictEqual({
kind: "connecting",
failedConnectionAttempts: 0,
});
let instance: WebSocket;
// Get the first WebSocket instance, and ...
[instance] = webSocketSpy.mock.instances;
if (!instance.onopen) {
throw new Error();
}
// tell the sarus instance that it is open, and ...
instance.onopen(new Event("open"));
if (!instance.onclose) {
throw new Error();
}
// close it immediately
instance.onclose(new CloseEvent("close"));
expect(sarus.state).toStrictEqual({
kind: "closed",
failedConnectionAttempts: 0,
});

let cb: Sarus["connect"];
// We iteratively call sarus.connect() and let it fail, seeing
// if it reaches 8000 as a delay and stays there
const attempts: [number, number][] = [
[1000, 1],
[2000, 2],
[4000, 3],
[8000, 4],
[8000, 5],
];
attempts.forEach(([delay, failedAttempts]: [number, number]) => {
attempts.forEach(([delay, failedAttempts]) => {
const call =
setTimeoutSpy.mock.calls[setTimeoutSpy.mock.calls.length - 1];
if (!call) {
throw new Error();
}
// Make sure that setTimeout was called with the correct delay
expect(call[1]).toBe(delay);
cb = call[0];
cb();
// Get the most recent WebSocket instance
instance =
webSocketSpy.mock.instances[webSocketSpy.mock.instances.length - 1];
if (!instance.onclose) {
Expand All @@ -141,7 +144,7 @@ describe("Exponential backoff delay", () => {
instance.onclose(new CloseEvent("close"));
expect(sarus.state).toStrictEqual({
kind: "connecting",
failedConnectionAttempts: failedAttempts,
failedConnectionAttempts: failedAttempts + 1,
});
});
});
Expand Down

0 comments on commit 568b9de

Please sign in to comment.