Files
cleveragents-core/features/tdd_mcp_client_start_race.feature
T
HAL9000 6ce3385217
CI / lint (push) Successful in 1m29s
CI / typecheck (push) Successful in 1m19s
CI / quality (push) Successful in 1m5s
CI / build (push) Successful in 47s
CI / security (push) Successful in 1m35s
CI / helm (push) Successful in 45s
CI / push-validation (push) Successful in 26s
CI / benchmark-regression (push) Has been skipped
CI / integration_tests (push) Successful in 4m15s
CI / unit_tests (push) Successful in 9m58s
CI / docker (push) Successful in 1m33s
CI / e2e_tests (push) Failing after 15m15s
CI / coverage (push) Successful in 12m27s
CI / status-check (push) Failing after 3s
CI / benchmark-publish (push) Successful in 1h30m14s
CI / benchmark-publish (pull_request) Has been skipped
CI / benchmark-regression (pull_request) Failing after 47s
CI / coverage (pull_request) Successful in 14m32s
CI / lint (pull_request) Successful in 1m8s
CI / quality (pull_request) Successful in 1m28s
CI / security (pull_request) Successful in 1m49s
CI / build (pull_request) Successful in 28s
CI / typecheck (pull_request) Successful in 2m24s
CI / helm (pull_request) Successful in 46s
CI / push-validation (pull_request) Successful in 22s
CI / unit_tests (pull_request) Successful in 6m26s
CI / integration_tests (pull_request) Successful in 4m40s
CI / e2e_tests (pull_request) Successful in 4m47s
CI / docker (pull_request) Successful in 1m31s
CI / status-check (pull_request) Successful in 4s
TDD: Add test for race condition in McpClient.start() double initialization
Adds a Behave TDD issue-capture test for bug #10438: McpClient.start()
releases the threading.RLock after setting _state to STARTING but before
calling connect() and discover_tools(). Concurrent callers can both pass
the _started idempotency check and call discover_tools() multiple times.

The test uses @tdd_expected_fail so CI passes while the bug is unfixed.
A counting mock transport records connect() and discover_tools() calls.
Five threads call start() concurrently through a threading.Barrier to
maximise the chance of the race manifesting.

ISSUES CLOSED: #10402
2026-05-02 21:57:54 +00:00

28 lines
1.5 KiB
Gherkin

# This test captures bug #10438 — McpClient.start() race condition.
#
# The @tdd_expected_fail tag inverts the test result: the underlying assertion
# fails (proving the bug exists) but CI reports the scenario as passed.
# When #10438 is fixed, the @tdd_expected_fail tag must be removed.
#
# See: https://git.cleverthis.com/cleveragents/cleveragents-core/issues/10438
@tdd_expected_fail @tdd_issue @tdd_issue_10438
Feature: TDD Issue #10438 — McpClient.start() race condition allows concurrent double initialization
McpClient.start() releases the threading.RLock after setting _state to STARTING
but before calling connect() and discover_tools(). If two threads call start()
concurrently, both can pass the _started idempotency check (which is still False)
and both proceed to call connect() and discover_tools() simultaneously.
This test proves the race exists by launching multiple threads that call start()
simultaneously via a threading.Barrier and verifying that connect() is called
exactly once (the correct, thread-safe behavior). Without the bug present,
connect() is called exactly once. With the bug, connect() is called multiple times.
Scenario: Concurrent start() calls must invoke connect() exactly once
Given an McpClient with a counting mock transport
When 5 threads call start() concurrently through a barrier
Then connect() should have been called exactly once
And discover_tools() should have been called exactly once
And the client state should be "running"
And all 5 threads should have completed without hanging