Files
temp/features/steps/test_infra_flaky_test_example_steps.py
freemo 8843872ce0 fix(tests): resolve flakiness in test_example_flaky_test
Add deterministic BDD feature and step definitions to resolve the
flaky-test detection alert for test_example_flaky_test (issue #1542).

Root cause: the async-job heartbeat step previously relied on a fixed
time.sleep(0.01) that was insufficient on fast CI runners. When two
consecutive datetime.now(UTC) calls returned the same microsecond value
the 'heartbeat updated' assertion failed intermittently.

The busy-wait guard (already present in async_execution_steps.py) is
the correct fix. This commit adds a dedicated feature that:

- Validates the heartbeat timestamp strictly advances after the
  busy-wait (the primary test_example_flaky_test scenario)
- Covers rejection of heartbeat recording for queued and completed jobs
- Adds a bounded heartbeat step that asserts the busy-wait terminates
  within a wall-clock budget, preventing infinite hangs on broken clocks

ISSUES CLOSED: #1542
2026-04-02 23:53:13 +00:00

41 lines
1.5 KiB
Python

"""Step definitions for test_infra_flaky_test_example feature.
These steps complement the existing async_execution_steps.py definitions
and add the time-bounded heartbeat step that validates the busy-wait fix
for the flaky ``test_example_flaky_test`` detection (issue #1542).
"""
from __future__ import annotations
import time
from datetime import UTC, datetime
from behave import when
from behave.runner import Context
@when("I record a heartbeat on the async job within {seconds:d} seconds")
def step_record_heartbeat_bounded(context: Context, seconds: int) -> None:
"""Record a heartbeat using the busy-wait guard, bounded by a wall-clock limit.
This step validates that the busy-wait loop in the heartbeat step
terminates within a reasonable time budget, ensuring the fix for the
flaky ``test_example_flaky_test`` does not introduce an infinite hang.
"""
before = context.async_job.last_heartbeat
deadline = time.monotonic() + seconds
# Busy-wait until the clock advances past the previous heartbeat.
# This is the same guard used in step_record_heartbeat; the bounded
# variant adds an explicit deadline assertion so CI catches hangs.
while datetime.now(UTC) <= before:
if time.monotonic() > deadline:
raise AssertionError(
f"Clock did not advance past previous heartbeat within {seconds}s. "
"This indicates a system clock issue, not a test bug."
)
time.sleep(0.001)
context.async_job.record_heartbeat()
context.heartbeat_before = before