diff --git a/changelog.d/10985-parity-fixture-timeouts.md b/changelog.d/10985-parity-fixture-timeouts.md new file mode 100644 index 0000000000..e7c59e06c0 --- /dev/null +++ b/changelog.d/10985-parity-fixture-timeouts.md @@ -0,0 +1 @@ +Report stalled thread-release and stdin-backpressure gap fixtures as timeouts instead of parity mismatches caused by local deadlines. diff --git a/test-files/test_gap_9493_child_stdin_backpressure.ts b/test-files/test_gap_9493_child_stdin_backpressure.ts index 0098613d7d..48fbd9101d 100644 --- a/test-files/test_gap_9493_child_stdin_backpressure.ts +++ b/test-files/test_gap_9493_child_stdin_backpressure.ts @@ -20,7 +20,6 @@ import { spawn } from "node:child_process"; const ROLE_ENV = "PERRY_9493_STDIN_ROLE"; const FILE_ENV = "PERRY_9493_STDIN_FILE"; -const WATCHDOG_MS = 8000; const BIG = 4 * 1024 * 1024; const role = process.env[ROLE_ENV] ?? ""; @@ -85,11 +84,9 @@ if (role === "stdin-small-exit") { const childArgs = [...process.execArgv, ...process.argv.slice(1)]; const waitForMarker = (marker: string) => - new Promise((resolve) => { - const deadline = Date.now() + WATCHDOG_MS; + new Promise((resolve) => { const poll = () => { - if (fs.existsSync(marker)) return resolve(true); - if (Date.now() > deadline) return resolve(false); + if (fs.existsSync(marker)) return resolve(); setTimeout(poll, 20); }; poll(); @@ -103,12 +100,12 @@ if (role === "stdin-small-exit") { env: { ...process.env, [ROLE_ENV]: name, [FILE_ENV]: file }, stdio: ["ignore", "inherit", "inherit"], }); - let settled = false; - const report = async (code: number | null | string) => { + const report = async (code: number | null) => { if (silent) { - const landed = (await waitForMarker(file + ".done")) && fs.existsSync(file) - ? fs.statSync(file).size - : -1; + // If the marker never appears, let the parity harness report a + // timeout instead of printing a clock-dependent `no-marker` result. + await waitForMarker(file + ".done"); + const landed = fs.existsSync(file) ? fs.statSync(file).size : -1; const total = name === "stdin-small-exit" ? 6 : BIG; const kind = landed < 0 ? "no-marker" : landed === 0 ? "none" : landed >= total ? "full" : "partial"; console.log(name + " exit=" + code + " landed=" + kind); @@ -117,16 +114,7 @@ if (role === "stdin-small-exit") { } resolve(); }; - const watchdog = setTimeout(() => { - if (settled) return; - settled = true; - child.kill("SIGKILL"); - void report("WATCHDOG"); - }, WATCHDOG_MS); child.on("exit", (code) => { - if (settled) return; - settled = true; - clearTimeout(watchdog); void report(code); }); }); diff --git a/test-files/test_gap_9592_child_timeout_threads.ts b/test-files/test_gap_9592_child_timeout_threads.ts index 3ef205cf43..7c7c4e694a 100644 --- a/test-files/test_gap_9592_child_timeout_threads.ts +++ b/test-files/test_gap_9592_child_timeout_threads.ts @@ -34,15 +34,12 @@ await Promise.all(quickChildren); if (process.platform !== "linux") { console.log("timeout threads released: skipped (no /proc task census)"); } else { - let timeoutThreadsReleased = false; - const releaseDeadline = Date.now() + 1_000; - while (!timeoutThreadsReleased && Date.now() < releaseDeadline) { - timeoutThreadsReleased = threadCount() <= baseline + 5; - if (!timeoutThreadsReleased) { - await new Promise((resolve) => setTimeout(resolve, 20)); - } + // Let the parity harness report a timeout if the threads never drain. + // A fixture-local deadline would print `false` as a parity mismatch. + while (threadCount() > baseline + 5) { + await new Promise((resolve) => setTimeout(resolve, 20)); } - console.log("timeout threads released:", timeoutThreadsReleased); + console.log("timeout threads released: true"); } const started = Date.now();