Skip to content

Commit

Permalink
Fix the test
Browse files Browse the repository at this point in the history
  • Loading branch information
Will committed Oct 8, 2024
1 parent ba78d35 commit 4a34f0f
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 12 deletions.
5 changes: 3 additions & 2 deletions jest.setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ declare global {
): R;
}
interface Expect {
matchesPredicate(predicate: (actual: any) => boolean): any
matchesPredicate(predicate: (actual: any) => boolean): any;
}
interface ExpectExtendMap {
matchesPredicate: MatcherFunction<[predicate: (actual: any) => boolean]>
matchesPredicate: MatcherFunction<[predicate: (actual: any) => boolean]>;
}
}
}
Expand Down Expand Up @@ -67,6 +67,7 @@ But instead it was:
message: () => "Expected function to throw but it did not",
};
},

matchesPredicate(actual: any, predicate: (actual: any) => boolean) {
return {
pass: predicate(actual),
Expand Down
13 changes: 10 additions & 3 deletions src/domain/release-archive.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import fs, { WriteStream } from "node:fs";
import os from "node:os";
import path from "node:path";
import tar from "tar";
import "../../jest.setup";
import { fakeModuleFile } from "../test/mock-template-files";
import { expectThrownError } from "../test/util";
import {
Expand Down Expand Up @@ -66,16 +67,22 @@ describe("fetch", () => {
});

test("retries the request if it fails", async () => {
// Restore the original behavior of exponentialDelay.
mocked(axiosRetry.exponentialDelay).mockImplementation(
jest.requireActual("axios-retry").exponentialDelay
);

await ReleaseArchive.fetch(RELEASE_ARCHIVE_URL, STRIP_PREFIX);

expect(axiosRetry).toHaveBeenCalledWith(axios, {
retries: 3,
retryDelay: expect.matchesPredicate((retryDelayFn: Function) => {
// Make sure the retry delays follow exponential backoff
// and the final retry happens after at least 1 minute total.
let firstRetryDelay = retryDelayFn(0);
let secondRetryDelay = retryDelayFn(1);
let thirdRetryDelay = retryDelayFn(2);
// Axios also randomly adds up to 20% to each delay, so test the upper bounds as well.
let firstRetryDelay = retryDelayFn.call(this, 0);
let secondRetryDelay = retryDelayFn.call(this, 1);
let thirdRetryDelay = retryDelayFn.call(this, 2);
return 10000 <= firstRetryDelay && firstRetryDelay <= 12000
&& 20000 <= secondRetryDelay && secondRetryDelay <= 24000
&& 40000 <= thirdRetryDelay && thirdRetryDelay <= 48000;
Expand Down
17 changes: 10 additions & 7 deletions src/domain/release-archive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,11 +108,12 @@ export class ReleaseArchive {
}
}

function exponentialDelay(retryCount: number, error: AxiosError = undefined): number {
// Using exponential backoff with 3 retries and a delay factor of 10 seconds
// gives you at least 70 seconds to publish a release archive.
const tenSeconds = 10000;
return axiosRetry.exponentialDelay(retryCount, error, tenSeconds);
function tenSecondExponentialDelay(
retryCount: number,
error: AxiosError | undefined
): number {
const tenSeconds = 10000;
return axiosRetry.exponentialDelay(retryCount, error, tenSeconds);
}

async function download(url: string, dest: string): Promise<void> {
Expand All @@ -131,10 +132,12 @@ async function download(url: string, dest: string): Promise<void> {

const writer = fs.createWriteStream(dest, { flags: "w" });

// Retry the request in case the artifact is still being uploaded
// Retry the request in case the artifact is still being uploaded.
// Exponential backoff with 3 retries and a delay factor of 10 seconds
// gives you at least 70 seconds to upload a release archive.
axiosRetry(axios, {
retries: 3,
retryDelay: exponentialDelay,
retryDelay: tenSecondExponentialDelay,
shouldResetTimeout: true,
});

Expand Down

0 comments on commit 4a34f0f

Please sign in to comment.