From 9b47e2c345d46ca4bb1878ce8f4d7429d470f756 Mon Sep 17 00:00:00 2001 From: Marius Ciepluch <11855163+norandom@users.noreply.github.com> Date: Wed, 23 Sep 2026 14:03:48 +0200 Subject: [PATCH] test(cpg): read /proc state without a check-then-read race `test_hanging_process_group_killed_inside_shared_allowance` failed about one run in thirty under load with FileNotFoundError: it checked that /proc//stat existed, the killed process was reaped, and the read then failed. A reaped process is the outcome the test wants, so it now reads and treats a missing entry as gone. The engine-stage test had the same race. 150 of 150 runs pass under engine load. Co-Authored-By: Claude Opus 5.5 (1M context) Claude-Session: https://claude.ai/code/session_01EmM1j46qgKMh3zqD1QMwEo --- tests/test_cpg_budget.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/tests/test_cpg_budget.py b/tests/test_cpg_budget.py index ed5b06a..25b1fd8 100644 --- a/tests/test_cpg_budget.py +++ b/tests/test_cpg_budget.py @@ -67,7 +67,12 @@ while True: time.sleep(1) for pid in map(int, pids.read_text().split()): status = Path(f"/proc/{pid}/stat") for _ in range(30): - if not status.exists() or status.read_text().split()[2] == "Z": + # Read, never check-then-read: a killed process can be reaped between the two, and its + # disappearing is exactly the outcome this test wants, not an error. + try: + if status.read_text().split()[2] == "Z": + break + except FileNotFoundError: break time.sleep(0.005) else: @@ -147,7 +152,10 @@ print({END!r}) for pid in map(int, pid_log.read_text().split()): status = Path(f"/proc/{pid}/stat") for _ in range(30): - if not status.exists() or status.read_text().split()[2] == "Z": + try: # read, never check-then-read: a reaped process is the outcome wanted + if status.read_text().split()[2] == "Z": + break + except FileNotFoundError: break time.sleep(0.005) else: