From d4f464c57e9749eb0af05a964cc6af1a0552eb51 Mon Sep 17 00:00:00 2001 From: Yichao Liang Date: Sat, 26 Sep 2026 17:48:28 -0400 Subject: [PATCH] Wait for the fast rollout before timing gather's partial return test_gather_timeout_returns_partial raced a trivial forked child against a 2 s gather timeout. Under pytest-cov every forked child starts its own coverage tracer, and in a CI shard with thousands of modules imported on a busy node that start-up alone can pass 2 s, so the fast rollout was still pending and the test failed. Measured on a quicktest node with 5,600 modules imported: launch to result took 0.06 s without coverage, 0.3 s with it, and 1.0 to 2.9 s with coverage under CPU contention. The test now waits for the fast child first, then checks that a short gather timeout returns it as done and the slow child as pending without blocking. --- tests/agent_sdk/test_async_rollouts.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/tests/agent_sdk/test_async_rollouts.py b/tests/agent_sdk/test_async_rollouts.py index f1d37ee6ce..1dc27608cf 100644 --- a/tests/agent_sdk/test_async_rollouts.py +++ b/tests/agent_sdk/test_async_rollouts.py @@ -119,10 +119,17 @@ def test_gather_timeout_returns_partial(): reg = AsyncRolloutRegistry(max_workers=2) try: fast = reg.launch(lambda: "fast") - slow = reg.launch(lambda: time.sleep(10) or "slow") - done, pending = reg.gather([fast, slow], timeout=2) - assert fast in done - assert slow in pending + slow = reg.launch(lambda: time.sleep(60) or "slow") + # Wait for the fast child on its own first: forking a large test + # process can take seconds on a loaded node, and racing that + # against the short timeout below tested the node, not gather. + first, _ = reg.gather([fast], timeout=30) + assert first == [fast] + start = time.monotonic() + done, pending = reg.gather([fast, slow], timeout=0.5) + assert time.monotonic() - start < 10 + assert done == [fast] + assert pending == [slow] finally: reg.shutdown()