The module docstring at lines 8-9 claimed the scenario was tagged
``@tdd_expected_fail`` so CI would invert a failing result while the
bug existed. Both claims are false: the implementation already holds
``_registry_lock`` around all reads and writes (src/cleveragents/
providers/registry.py:800,817), so the scenario passes normally, and
the feature file deliberately does not carry ``@tdd_expected_fail``.
Rewrite the module docstring to describe the current behaviour — the
lock is present, the scenario passes, the tag is intentionally omitted,
and the test now functions as a regression guard against the lock
being removed. Update the two inner step docstrings in the same way so
"this assertion fires when the bug exists" no longer contradicts the
fixed implementation.
No runtime behaviour changes. The lint gate passes.
ISSUES CLOSED: #10409
The PR contained duplicate step definitions and feature files that caused
behave AmbiguousStep errors crashing the unit_tests gate. The underlying
thread-safety fix for get_provider_registry() already landed on master in
commit e1cd306f6, so the scenario now passes as a regression test.
- Delete scripts/fix_registry_steps_tmp.py: temporary debugging script with
hardcoded /tmp paths that produced 6 ruff errors (F401, UP015, E501 x4).
- Delete features/tdd_registry_thread_safety.feature and
features/steps/tdd_registry_thread_safety_steps.py: weaker duplicates of
the canonical files under features/providers/ and features/steps/. Their
step decorators collided with the elaborate barrier-based steps in
registry_thread_safety_steps.py, causing AmbiguousStep across the suite.
- Remove @tdd_expected_fail tag from the canonical scenario per the
CONTRIBUTING.md bug fix workflow: behave's TDD harness explicitly
instructs removing the tag once the bug appears fixed, so the scenario
now functions as a normal regression test.
- Apply ruff format to features/steps/registry_thread_safety_steps.py.
ISSUES CLOSED: #10409
Removed the accidentally committed temporary fix script (scripts/fix_registry_steps_tmp.py) that was causing lint failures. The actual test implementation in features/providers/test_registry_thread_safety.feature and features/steps/registry_thread_safety_steps.py is clean and properly formatted.
This PR demonstrates the thread-safety race condition in get_provider_registry() using TDD methodology with @tdd_expected_fail tag.
Replace try-except-pass blocks with contextlib.suppress() and combine
nested with statements into a single parenthesized context manager.
ISSUES CLOSED: #10409
Implemented a Behave BDD test to prove the thread-safety race in get_provider_registry():
- Added features/providers/test_registry_thread_safety.feature with a two-thread scenario using a Barrier to trigger an actual race and asserting both threads obtain the same singleton instance. The scenario is tagged @tdd_issue, @tdd_issue_10409, and @tdd_expected_fail.
- Added features/steps/registry_thread_safety_steps.py implementing Given/When/Then steps to coordinate threads and verify singleton identity.
- The scenario currently fails against the unfixed code due to non-thread-safe singleton; the @tdd_expected_fail tag inverts the result so CI passes.
ISSUES CLOSED: #10409