Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/10985-parity-fixture-timeouts.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Report stalled thread-release and stdin-backpressure gap fixtures as timeouts instead of parity mismatches caused by local deadlines.
26 changes: 7 additions & 19 deletions test-files/test_gap_9493_child_stdin_backpressure.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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] ?? "";
Expand Down Expand Up @@ -85,11 +84,9 @@ if (role === "stdin-small-exit") {
const childArgs = [...process.execArgv, ...process.argv.slice(1)];

const waitForMarker = (marker: string) =>
new Promise<boolean>((resolve) => {
const deadline = Date.now() + WATCHDOG_MS;
new Promise<void>((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();
Expand All @@ -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);
Expand All @@ -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);
});
});
Expand Down
13 changes: 5 additions & 8 deletions test-files/test_gap_9592_child_timeout_threads.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<void>((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<void>((resolve) => setTimeout(resolve, 20));
}
console.log("timeout threads released:", timeoutThreadsReleased);
console.log("timeout threads released: true");
}

const started = Date.now();
Expand Down
Loading