Repository navigation
#40 test: deterministic reclaim test; sweep of timing margins in tests/ - #41
Merged
Merged
Conversation
…sleep against 500 ms A slow step 1 (over 500 ms) let the second walk reclaim cmd-1 again: facts ['cmd-1', 'cmd-1', 'cmd-2'], reproduced with a 0.6 s extraction. Both entries now start 60 s idle (JUSTID: no delivery counted) against a 30 s threshold. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…5x margin 0.2 s delay against a real 0.3 s deadline: an overhead past 0.1 s failed the first call. A fake monotonic leaves the second call 0.1 s against a 0.5 s stall. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
It polled for the lock file, which flock(1) creates before it holds the lock: a deploy in that window took it. fcntl.flock in the test closes the window. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…25 s left match="Timeout" passed any short bound (a left / 2 mutation passed); 9.9 left 0.0999…, which no message can match exactly. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A start past 10 s issued the command before the group (created at `$`), and the test failed 20 s later on an unpack and a ProcessLookupError. Now 30 s bounds, an exited process named at once, and no SIGTERM to a process gone. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Oct 8, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #40. Test-only: no deploy (
tests/isn't a runtime path).The strand test: no wall clock
The hand-off's trace confirmed. With a 0.6 s in-process extraction, the old test fails with
['cmd-1', 'cmd-1', 'cmd-2']: step 1 took longer than 500 ms, so the second walk reclaimed cmd-1 again. It never failed in 30 runs under CPU load, so the flake is rare.Now
XCLAIM … IDLE 60000 JUSTID, run asadmin, gives both entries 60 s of idle time. They stay with the dead consumer, and JUSTID means no delivery is counted. The threshold isreclaim_min_idle_ms=30_000, and thesleep(0.6)is gone. Scratch Redis and CI are both 7.0.15, which acceptIDLE.count=1→count=2inConsumer.reclaim(claim both entries at once), it fails['cmd-1'] == ['cmd-1', 'cmd-2'].Sweep of
tests/Fixed:
test_drift.py::test_every_call_shares_one_deadlinemonotonicfor the deadline. The second call gets 0.1 s against a 0.5 s stall (5×), and the first call has no timing in it. Mutationtimeout=REQUEST_TIMEOUT_SECONDS(no shared deadline) → failstest_deploy.py::test_refuses_while_another_deploy_holds_the_lockflock(1)creates the file before it holds the lockfcntl.flock). Mutation: deploy.sh skipsflock -n→ failsListed, safe (≥ 2× or one-sided):
test_consumer.pytest_run_stops_promptly:sleep(0.5)test_consumer.pybroker-name retry: poll 10 ms,asyncio.timeout(10)test_consumer.pystop-during-reclaimreclaim_min_idle_ms=0: no clocktest_main.pye2e: two polls, 100 × 0.1 stest_child.pytest_timeout_kills_the_child:timeout_s=2,< 10test_child.pyterminal interrupt: 5 s pid poll, 1.5 s child sleeptest_contain.pyundumpable: 10 s ready polltest_checkin.pytest_a_stall_is_cut_off: 0.5 s stall against a 0.1 s timeouttest_deploy.pyCI wait:< 15s against a 30 s pollVerification
ruff check,ruff format --check: clean. Full suite: 554 passed, 4 skipped.co-processor, under 4 CPU-hog processes on 2 vCPU: the strand and deadline tests 50/50, thentests/test_consumer.py50/50. The hogs' 900 s timeout ran out near the end of that second loop, so its last few runs had no load.Review (CR --fix)
test_drift.py: the clock now reads 9.875, so the call has 0.125 s left, and the test matchesread timeout=0.125).match="Timeout"had let aleft / 2mutation pass; it fails nowtest_main.pye2e: both waits are now bounded at 30 s byasyncio.timeout, and aprocessor runthat exits is named at once. A failed start used to fail the test 21 s later with an unpacking error, then aProcessLookupErrorfrom the SIGTERM; now it fails in 1.7 s with "processor run exited before its loop was up"Gate after CR 2: ruff clean,
uv lock --lockedok, full suite 554 passed / 4 skipped, scratch Redis clean. Both touched tests passed 20/20 in a loop.🤖 Generated with Claude Code