From 9bbc2b9fd2f1ae8e426f486952a9f482eb1a8357 Mon Sep 17 00:00:00 2001 From: James Butters Date: Wed, 16 Sep 2026 20:36:21 -0600 Subject: [PATCH] test: assert parallelism, not wall-clock, in concurrent workers test_passing_suite spawned 5 workers over 5 two-second spec files and asserted the run finished in under 5 seconds. That conflates "the work overlapped" with "the runner was fast": booting five rubies on a loaded CI box eats the margin even when parallelism worked. It failed two of five matrix legs on its first CI run, at 5.02s and 5.19s. Compare wall clock against the summed job time the queue already records instead. A serialized run takes at least as long as the sum, so the bound scales with runner speed rather than assuming it. Verified both ways: parallel passes with ~2x headroom (5s vs 10s), and forcing a single worker still fails it (10.65s vs 10.03s). Raising the constant to 10 was the alternative, but 10s is the serial time, so it would have passed a fully serialized run. refs DE-1818 Co-Authored-By: Claude Opus 5 --- test/test_concurrent_workers.rb | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/test/test_concurrent_workers.rb b/test/test_concurrent_workers.rb index c07a88e..cbc64a6 100644 --- a/test/test_concurrent_workers.rb +++ b/test/test_concurrent_workers.rb @@ -2,9 +2,8 @@ class TestConcurrentWorkers < RSpecQTest # The 'passing_concurrent' suite contains 5 spec files each containing a - # single example taking 2". We spawn that many workers so we expect roughly - # 2 second total execution time. We some more to account for fork and - # rspec boot and other setup overheads + # single example taking 2". We spawn that many workers, so the work should + # overlap rather than run back to back. def test_passing_suite build_id = rand_id pids = [] @@ -20,10 +19,14 @@ def test_passing_suite elapsed = Process.clock_gettime(Process::CLOCK_MONOTONIC) - start - assert_operator elapsed, :<, 5 - queue = RSpecQ::Queue.new(build_id, "foo", REDIS_OPTS, 60) + # Parallelism, not runner speed: wall clock has to beat the summed job + # time, since a serialized run takes at least as long as the sum. A fixed + # threshold flakes instead on a loaded CI box, where booting five rubies + # eats the margin even though the work did overlap. + assert_operator elapsed, :<, queue.total_execution_time_ms / 1000.0 + assert_queue_well_formed(queue) assert queue.build_successful? assert_equal job_count, queue.example_count