Skip to content

Commit 8a6abc0

Browse files
committed
Replace wall-clock margins in stdio cleanup tests with kernel-level signals
The stdio cleanup tests asserted upper bounds on elapsed wall-clock time (cleanup took < 6.0s, < 5.0s, < 3.0s, between 1.5s and 4.5s) and paced themselves with fixed sleeps ("let the process start"). Upper bounds on elapsed time fail on slow runners — spawning an interpreter on a loaded CI box can eat the whole margin — and the sleeps raced process startup. Every cleanup test now uses the socket-based liveness probe the process-tree tests already had: the child connects back to a listener owned by the test (deterministic readiness, replacing the sleeps; setup lines such as installing a signal handler are guaranteed to have run before the connect), and the kernel closing that socket when the process dies is the proof of termination (replacing the elapsed-time upper bounds). Time bounds that remain are generous fail_after hang guards, not performance claims, plus one deliberate lower bound: test_stdio_client_stdin_close_ignored still asserts cleanup takes at least PROCESS_TERMINATION_TIMEOUT, which pins the genuine time-based contract that escalation must wait out the stdin-close grace period. Lower bounds cannot fail from runner slowness. Details worth knowing: - test_stdio_client_sigint_only_process is renamed to test_stdio_client_sigterm_ignoring_process: the cleanup path never sends SIGINT (it escalates stdin-close -> SIGTERM -> SIGKILL), so the old child's SIGINT handler never fired and SIGKILL was what actually killed it. The test now states what it proves. Its whole-function "pragma: lax no cover" stays, with the real reason documented: coverage is enforced per CI job at 100% including on Windows runners, where the test is skipped and its body would count as uncovered. - test_stdio_client_graceful_stdin_exit now proves "no signal was needed" directly: the child sends a marker over the socket only on the stdin-EOF exit path before exiting on its own. The old upper bound (< 3.0s) could not distinguish a stdin-driven exit from a SIGTERM-driven one, which also completes in about 2.2s. - TestChildProcessCleanup's three tests become top-level functions per the no-test-classes rule; bodies unchanged. - The defensive except (TimeoutError, Exception) block and the pragma'd cancelled_caught/pytest.fail arms are gone: hang guards are plain anyio.fail_after, whose TimeoutError fails the test with no dead lines to exclude from coverage. - PROCESS_TERMINATION_TIMEOUT is intentionally not monkeypatched anywhere: the 2s grace period is the contract under test in the lower-bound test, and everywhere else the tests no longer measure time at all, so shrinking it would only save ~6s of real escalation waiting at the cost of testing a constant production never uses.
1 parent 19fe9fa commit 8a6abc0

1 file changed

Lines changed: 216 additions & 324 deletions

File tree

0 commit comments

Comments
 (0)