Skip to content

test(vt-server): make the dead-client test deterministic - #682

Open
wan9chi wants to merge 1 commit into
mainfrom
claude/sharp-wozniak-de0ae9
Open

test(vt-server): make the dead-client test deterministic#682
wan9chi wants to merge 1 commit into
mainfrom
claude/sharp-wozniak-de0ae9

Conversation

@wan9chi

@wan9chi wan9chi commented Aug 17, 2026

Copy link
Copy Markdown
Member

Motivation

vt_server::integration client_gone_before_reading_response_is_not_an_error failed now and then on Windows CI (example run, on a PR that touched nothing in vt_server or socket_ipc), and a re-run of the same commit passed. CLAUDE.md says the suite has no flaky tests, so this should be made certain instead of left to luck.

The two frames were not racing each other — the connection was never taken. On Windows the operating system attaches a client to the waiting pipe immediately, before the server's accept sees it. This test's client waited for nothing, so it could finish while its connection was still unclaimed, and the test helper then told the server to stop accepting. The server's loop now had two things ready at once, the stop signal and the waiting connection, and it picks one of them at random. When the stop won, the server dropped that pipe with both frames unread, so the flag the test checked was never recorded. Unix cannot land here, because a client there cannot finish connecting until the server has taken it.

What changed

The test is rebuilt around what the server promises — a client that dies while being answered ends only its own stream — with every step forced instead of timed:

  • The dying client marks its request tracked, so the records prove the server handled it even though the answer never arrived.
  • It reads the four bytes of length in front of the answer and nothing else. Those bytes arrive only once the server has read the request, looked every env up and begun writing, and the body behind them is far bigger than any pipe buffer (checked), so dropping the stream there always leaves that write with no reader.
  • A second client, open across the death, is served both while the first is stuck mid-answer and after it dies, and its value must show up in the records.
  • Renamed to client_gone_mid_response_only_ends_its_own_stream.

The DisableCache frame this test used to lean on is gone. It rode on a connection about to die, which the server promises nothing about, and raw_disable_cache_request_disables_cache already covers that frame on a healthy connection. connect_raw now spells out the rule it broke: a raw client must wait for the server before its work ends.

No production code changed.

🤖 Generated with Claude Code

`client_gone_before_reading_response_is_not_an_error` failed intermittently
on Windows CI. On Windows a client reaches a pipe instance before the
server's `accept` sees it, and this test's client waited for nothing before
its work ended, so the connection could still be unaccepted when the harness
signalled the server to stop accepting. The accept loop then had both the
stop signal and the pending accept ready, and `tokio::select!` picks among
ready branches at random; when the stop won, the server dropped that pipe
instance with both frames unread, so the flag the test asserted was never
recorded.

Rebuild the test around what the server promises. The dying client's request
is tracked, so the reports prove the handler ran. It reads only the answer's
length prefix, which arrives only once the server has started writing a body
far larger than any pipe buffer, so dropping the stream there always leaves
that write with no reader. A second client, open across the death, is served
both while the first is stuck and after it dies.

The `DisableCache` frame this test used to piggyback on is gone: it rode on a
connection about to die, which the server makes no promise about, and
`raw_disable_cache_request_disables_cache` already covers that frame.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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.

1 participant