mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-10-30 17:27:09 +00:00
test: two flaky queue tests no longer race real time or the first copy's start (#6283)
This commit is contained in:
@@ -40,15 +40,14 @@ async function runFixture(onConnection: (socket: Socket) => void) {
|
||||
});
|
||||
let stderr = "";
|
||||
child.stderr.on("data", (chunk) => (stderr += chunk));
|
||||
const startedAt = Date.now();
|
||||
const code = await new Promise<number | null>((resolve) => {
|
||||
const giveUp = setTimeout(() => resolve(null), 20_000);
|
||||
const giveUp = setTimeout(() => resolve(null), 110_000);
|
||||
child.once("exit", (exitCode) => {
|
||||
clearTimeout(giveUp);
|
||||
resolve(exitCode);
|
||||
});
|
||||
});
|
||||
return { code, stderr, port, home, elapsedMs: Date.now() - startedAt };
|
||||
return { code, stderr, port, home };
|
||||
}
|
||||
|
||||
it("exits with code 1 when the download host accepts the connection and never answers", async () => {
|
||||
@@ -58,21 +57,4 @@ it("exits with code 1 when the download host accepts the connection and never an
|
||||
expect(run.stderr).toContain(`The Chrome download from 127.0.0.1:${run.port} stalled`);
|
||||
expect(run.stderr).toContain("Retrying (2/2)");
|
||||
expect(existsSync(join(run.home, ".cache", "hyperframes", ".chrome.install.lock"))).toBe(false);
|
||||
}, 30_000);
|
||||
|
||||
it("does not call a download that keeps sending bytes a stall", async () => {
|
||||
const run = await runFixture((socket) => {
|
||||
socket.once("data", () => {
|
||||
socket.write("HTTP/1.1 200 OK\r\ncontent-length: 100000\r\n\r\n");
|
||||
const trickle = setInterval(() => socket.write("x"), 80);
|
||||
setTimeout(() => {
|
||||
clearInterval(trickle);
|
||||
socket.destroy();
|
||||
}, 1_200);
|
||||
});
|
||||
});
|
||||
|
||||
expect(run.code).toBe(1);
|
||||
expect(run.stderr).not.toContain("no data for");
|
||||
expect(run.elapsedMs).toBeGreaterThan(1_000);
|
||||
}, 30_000);
|
||||
}, 120_000);
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { installProgressLine } from "./installProtocol.js";
|
||||
|
||||
const worker = vi.hoisted(() => ({
|
||||
options: undefined as { signal: AbortSignal; onStdout: (chunk: string) => void } | undefined,
|
||||
finish: undefined as ((paths: string) => void) | undefined,
|
||||
}));
|
||||
|
||||
vi.mock("../utils/cancellableProcess.js", () => ({
|
||||
runRenderSetupWorker: (_mode: string, _input: unknown, options: typeof worker.options) => {
|
||||
worker.options = options;
|
||||
return new Promise<string>((resolve, reject) => {
|
||||
worker.finish = resolve;
|
||||
options!.signal.addEventListener("abort", () => reject(options!.signal.reason));
|
||||
});
|
||||
},
|
||||
}));
|
||||
|
||||
const { BrowserDownloadStalledError, installInChild } = await import("./installInChild.js");
|
||||
|
||||
const STALL_MS = 200;
|
||||
const input = {
|
||||
browser: "chrome-headless-shell",
|
||||
buildId: "1",
|
||||
cacheDir: "/x",
|
||||
unpack: false,
|
||||
} as const;
|
||||
|
||||
beforeEach(() => vi.useFakeTimers());
|
||||
afterEach(() => vi.useRealTimers());
|
||||
|
||||
describe("installInChild stall watchdog", () => {
|
||||
it("does not call a download that keeps reporting progress a stall", async () => {
|
||||
const result = installInChild(input as never, {
|
||||
stallMs: STALL_MS,
|
||||
host: "h",
|
||||
onLog: () => {},
|
||||
});
|
||||
for (let downloaded = 1; downloaded <= 100; downloaded++) {
|
||||
await vi.advanceTimersByTimeAsync(STALL_MS - 1);
|
||||
worker.options!.onStdout(installProgressLine(downloaded, 1000));
|
||||
}
|
||||
expect(worker.options!.signal.aborted).toBe(false);
|
||||
worker.finish!("done");
|
||||
await expect(result).resolves.toBe("done");
|
||||
});
|
||||
|
||||
it("aborts with the host and window once no progress arrives for the stall window", async () => {
|
||||
const result = installInChild(input as never, {
|
||||
stallMs: STALL_MS,
|
||||
host: "h",
|
||||
onLog: () => {},
|
||||
});
|
||||
const rejected = expect(result).rejects.toThrow(BrowserDownloadStalledError);
|
||||
worker.options!.onStdout(installProgressLine(1, 100));
|
||||
await vi.advanceTimersByTimeAsync(STALL_MS);
|
||||
await rejected;
|
||||
await expect(result).rejects.toThrow("The Chrome download from h stalled: no data for 0.2s.");
|
||||
});
|
||||
});
|
||||
@@ -36,6 +36,7 @@ import { openBlobStore } from "./blobStore";
|
||||
// A test can hold a media copy, and run work after its blob is stored but before history records it.
|
||||
const mediaCopy = vi.hoisted(() => ({
|
||||
held: null as Promise<void> | null,
|
||||
entered: null as (() => void) | null,
|
||||
stored: null as (() => Promise<unknown>) | null,
|
||||
copies: [] as string[],
|
||||
fails: null as ((copy: number) => boolean) | null,
|
||||
@@ -50,6 +51,7 @@ vi.mock("./blobStore", async (importOriginal) => {
|
||||
...store,
|
||||
put: async (path: string) => {
|
||||
if (path.endsWith(".bin")) {
|
||||
mediaCopy.entered?.();
|
||||
await mediaCopy.held;
|
||||
mediaCopy.copies.push(basename(path));
|
||||
if (mediaCopy.fails?.(mediaCopy.copies.length)) throw new Error("The disk is full.");
|
||||
@@ -70,7 +72,7 @@ const cleanup: Array<() => unknown> = [];
|
||||
|
||||
afterEach(async () => {
|
||||
for (const step of cleanup.splice(0).reverse()) await step();
|
||||
Object.assign(mediaCopy, { held: null, stored: null, copies: [], fails: null });
|
||||
Object.assign(mediaCopy, { held: null, entered: null, stored: null, copies: [], fails: null });
|
||||
});
|
||||
|
||||
const inside = (dir: string, path: string) => readFileSync(join(dir, path), "utf-8");
|
||||
@@ -366,11 +368,13 @@ describe("openProjectHistory", () => {
|
||||
it("never copies the media of a folder that replaced the project", async () => {
|
||||
let release = () => {};
|
||||
mediaCopy.held = new Promise<void>((resolve) => (release = resolve));
|
||||
const firstCopyRunning = new Promise<void>((resolve) => (mediaCopy.entered = resolve));
|
||||
const media = {
|
||||
"a.bin": Buffer.alloc(2 * 1024 ** 2, 1),
|
||||
"b.bin": Buffer.alloc(2 * 1024 ** 2, 2),
|
||||
};
|
||||
const { history, write, projectDir } = await project({ "index.html": "A", ...media });
|
||||
await firstCopyRunning;
|
||||
renameSync(projectDir, `${projectDir}-moved`);
|
||||
cleanup.push(() => rmSync(`${projectDir}-moved`, { recursive: true, force: true }));
|
||||
mkdirSync(projectDir);
|
||||
|
||||
Reference in New Issue
Block a user