Skip to content

test(api): ignore late logs of earlier requests in McpToolErrorTests - #1249

Merged
mforce merged 4 commits into
mainfrom
test/mcp-tool-error-handshake-race
Oct 11, 2026
Merged

mforce merged 4 commits into
mainfrom
test/mcp-tool-error-handshake-race

Conversation

@mforce

@mforce mforce commented Oct 11, 2026

Copy link
Copy Markdown
Owner

McpToolErrorTests failed intermittently in CI because of a race in the test. This PR changes only the test; product behaviour is unchanged.

Closes #1246

The race

The test clears its log sink so that only the call under test remains: once after connecting, and once between the two calls in ConstructionFault_LogsAtError_UnlessAnArgumentIsBad. A request that the client has already finished with can still be completing on the server. When it ends in a TaskCanceledException, request logging records HTTP POST /mcp responded 500 at Error after the clear. The test then counts that event against the call under test.

The CI logs show both kinds of earlier request:

The other failures listed in #1246 have the same signature: main at f18267fc (run 38171174745), PR #1245, and #1237 at f6db0535 (run 38174306632).

The fix

Every event of one request carries that request's trace id. The test sink now has a Clear() that records the trace of every event it has seen before emptying itself. The assertions read sink.Observed, which drops only later events carrying one of those recorded traces. An event with no trace, or with a trace the sink has not seen, still counts. So an Error of unknown origin still fails the test.

Proof

I could not force a real late abort without changing product code. So I injected the event CI logged into the sink, after the call under test: POST /mcp responded 500 at Error, with a TaskCanceledException. The table shows results for the 13 BadArgument cases and for ConstructionFault.

Test Injected Error's trace BadArgument (13) ConstructionFault (1)
before this PR any (it arrives after the clear) 13 of 13 fail fails
after this PR an earlier request's: server/discover, or the first call's 13 of 13 pass passes
after this PR none (no Activity) 13 of 13 fail fails
after this PR an independent trace 13 of 13 fail fails

Without injection, the class (20 cases) passed 25 runs out of 25 at 6d955537.

Open question

The server logs an MCP POST that the client abandons as a 500 at Error. In these runs, the handler had already completed, and the client already had its answer. That is request logging's ordinary behaviour, and this PR leaves it unchanged. Should an aborted /mcp POST be logged below Error?

McpToolErrorTests cleared its sink after connecting, but the handshake's
server/discover POST can finish logging after the client has returned. When
that POST ended in TaskCanceledException, request logging recorded a 500 at
Error after the clear, and "logs no Error" failed (main at f18267f, #1237 at
d9ff13e). The assertions now read only the latest tools/call request's
events, by trace id, and the clear is gone.
Reading only the call's trace also hid an Error logged with no Activity or
under another trace. The sink is again cleared after connecting, and the
assertions exclude only events carrying the trace of the server/discover
request seen during the connect. With no such trace, nothing is excluded.
Run 38174048915 failed ConstructionFault_LogsAtError_UnlessAnArgumentIsBad
on the same race as the handshake: the first call's POST logged its
cancelled 500 after the test's second clear. The sink's Clear now records
the trace of every request it has seen, and the assertions exclude only
later events of those traces. An event with no trace or a new trace still
counts.
@mforce
mforce merged commit 8796ab8 into main Oct 11, 2026
18 checks passed
@mforce
mforce deleted the test/mcp-tool-error-handshake-race branch October 11, 2026 22:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

test(api): McpToolErrorTests fails intermittently on a cancelled-request Error log

1 participant