bcf1eb9100
CI / push-validation (pull_request) Successful in 25s
CI / build (pull_request) Successful in 41s
CI / lint (pull_request) Successful in 48s
CI / quality (pull_request) Successful in 47s
CI / helm (pull_request) Successful in 46s
CI / typecheck (pull_request) Successful in 58s
CI / security (pull_request) Successful in 1m33s
CI / unit_tests (pull_request) Successful in 6m44s
CI / integration_tests (pull_request) Successful in 10m30s
CI / docker (pull_request) Successful in 1m45s
CI / coverage (pull_request) Successful in 10m23s
CI / status-check (pull_request) Successful in 4s
- Move MockMCPTransport import to module level in counting_mcp_transport.py, removing the noqa: PLC0415 suppression that caused RUF100 (unused noqa) - Remove dead `if TYPE_CHECKING: pass` block and unused TYPE_CHECKING import - Remove unused `from typing import Any` in race condition step definitions (F401) - Fix excess blank lines (3 → 2) between imports and first section in step file - Remove @tdd_expected_fail tag from tdd_mcp_client_start_race.feature; the bug is fixed so the scenario now passes, and the file's own comment states the tag must be removed when #10438 is resolved ISSUES CLOSED: #10438
28 lines
1.5 KiB
Gherkin
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_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
|