forked from HAL9000/cleveragents-core
8843872ce0
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
41 lines
1.5 KiB
Python
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
|