fix(test): stabilize retry_with_timeout scenario
CI / benchmark-publish (pull_request) Has been skipped
CI / lint (pull_request) Successful in 15s
CI / build (pull_request) Successful in 15s
CI / quality (pull_request) Successful in 27s
CI / typecheck (pull_request) Has been cancelled
CI / security (pull_request) Has been cancelled
CI / unit_tests (pull_request) Has been cancelled
CI / integration_tests (pull_request) Has been cancelled
CI / coverage (pull_request) Has been cancelled
CI / benchmark-regression (pull_request) Has been cancelled
CI / docker (pull_request) Has been cancelled

Patch time.monotonic alongside time.sleep in the retry timeout step
so stop_after_delay cannot elapse due to wall-clock overhead on
busy CI runners. The fake monotonic clock advances by 1µs per call,
keeping elapsed time well under the 0.01s timeout while preserving
retry semantics.

Closes #200
This commit is contained in:
2026-02-28 03:31:34 +00:00
parent e3a93bf32c
commit 465683fb6b
+12 -1
View File
@@ -572,13 +572,24 @@ def step_verify_async_execute_attempts(context, attempts):
@when("I apply retry with timeout of {max_attempts:d} attempts and {timeout} seconds")
def step_apply_retry_with_timeout(context, max_attempts, timeout):
"""Apply retry_with_timeout while stubbing out sleep delays."""
"""Apply retry_with_timeout while stubbing out sleep and monotonic clock."""
timeout_seconds = float(timeout)
original_sleep = time.sleep
original_monotonic = time.monotonic
_fake_base = original_monotonic()
_call_counter = [0]
def _fake_monotonic():
_call_counter[0] += 1
return _fake_base + _call_counter[0] * 1e-6
time.sleep = lambda _seconds: None
time.monotonic = _fake_monotonic
def restore_sleep():
time.sleep = original_sleep
time.monotonic = original_monotonic
# Register cleanup first so it runs even if the step body fails.
context.add_cleanup(restore_sleep)