




























11// Parallels Update Job Timeout tests cover parallels update job timeout script behavior.
2+import { spawnSync } from "node:child_process";
3+import path from "node:path";
4+import { pathToFileURL } from "node:url";
25import { afterEach, describe, expect, it, vi } from "vitest";
36import { runTimedUpdateJob } from "../../scripts/e2e/parallels/update-job-timeout.ts";
47@@ -76,6 +79,7 @@ describe("Parallels update job timeout", () => {
7679const writeLog = vi.fn(async () => undefined);
77807881const result = runTimedUpdateJob({
82+abortSettleMs: 1,
7983append: (chunk) => chunks.push(chunk),
8084label: "Windows",
8185run: () => new Promise(() => {}),
@@ -84,7 +88,7 @@ describe("Parallels update job timeout", () => {
8488 writeLog,
8589});
869087-await vi.advanceTimersByTimeAsync(1000);
91+await vi.advanceTimersByTimeAsync(1001);
8892await expect(result).resolves.toBe(1);
8993expect(chunks).toEqual(["Windows update timed out after 1s\n"]);
9094expect(writeLog).toHaveBeenCalledTimes(1);
@@ -121,4 +125,80 @@ describe("Parallels update job timeout", () => {
121125expect(chunks).toEqual(["Linux update timed out after 1s plus cleanup backstop\n"]);
122126expect(writeLog).toHaveBeenCalledTimes(1);
123127});
128+129+it("waits for abort-aware cleanup before writing the job log", async () => {
130+vi.useFakeTimers();
131+const events: string[] = [];
132+133+const result = runTimedUpdateJob({
134+abortSettleMs: 250,
135+append: (chunk) => events.push(chunk.trim()),
136+label: "macOS",
137+run: ({ signal }) =>
138+new Promise<void>((resolve) => {
139+signal.addEventListener(
140+"abort",
141+() => {
142+events.push("abort");
143+setTimeout(() => {
144+events.push("cleanup");
145+resolve();
146+}, 25);
147+},
148+{ once: true },
149+);
150+}),
151+timeoutDescription: "1s plus cleanup backstop",
152+timeoutMs: 1000,
153+writeLog: async () => {
154+events.push("writeLog");
155+},
156+});
157+158+await vi.advanceTimersByTimeAsync(1025);
159+await expect(result).resolves.toBe(1);
160+expect(events).toEqual([
161+"macOS update timed out after 1s plus cleanup backstop",
162+"abort",
163+"cleanup",
164+"writeLog",
165+]);
166+});
167+168+it("keeps the process alive long enough to write logs for hung runners", () => {
169+const moduleUrl = pathToFileURL(
170+path.resolve("scripts/e2e/parallels/update-job-timeout.ts"),
171+).href;
172+const probe = `
173+import { runTimedUpdateJob } from ${JSON.stringify(moduleUrl)};
174+const events = [];
175+const result = await runTimedUpdateJob({
176+ abortSettleMs: 25,
177+ append: (chunk) => events.push(chunk.trim()),
178+ label: "Linux",
179+ run: () => new Promise(() => {}),
180+ timeoutDescription: "10ms",
181+ timeoutMs: 10,
182+ writeLog: async () => events.push("writeLog"),
183+});
184+console.log(JSON.stringify({ events, result }));
185+`;
186+187+const child = spawnSync(
188+process.execPath,
189+["--import", "tsx", "--input-type=module", "--eval", probe],
190+{
191+cwd: process.cwd(),
192+encoding: "utf8",
193+timeout: 5_000,
194+},
195+);
196+197+expect(child.stderr).toBe("");
198+expect(child.status).toBe(0);
199+expect(JSON.parse(child.stdout)).toEqual({
200+events: ["Linux update timed out after 10ms", "writeLog"],
201+result: 1,
202+});
203+});
124204});
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。