test(driver-turso): await the "remote was reached" latch instead of sampling a request counter (#17121) - #17282
Merged
Conversation
…ampling a request counter `turso-driver-timeout.test.ts` asserted "the remote really was reached" by reading a request COUNTER at the instant the 100 ms window closed, twice. The sample instant is chosen by the very timer under test, and libuv runs the TIMERS phase before the POLL phase: any stall that spans the window delivers the abort -- and every assertion that follows it -- before the server's already-arrived bytes are parsed into a `request` event. The counter then reads 0 for a request that is demonstrably on the wire, and the file fails as `expected 0 to be greater than 0` from a merge-queue runner, presenting as a behaviour regression when it is a load artefact. Measured on the fixture, freezing the loop 300 ms from the moment undici publishes `undici:client:sendHeaders`: 6/6 runs read the counter as 0 while `undici:client:sendHeaders` had fired, the server had accepted the connection, and the request handler dispatched ~2 ms AFTER the assertion would have run. The driver answered TIMEOUT / 504 in every one of them, so the competing hypothesis -- a 504 for a request that never left the process -- is excluded under this reproduction. The fixture now exposes a latching `firstRequest` promise the tests AWAIT, and the positive case proves reachability with an UNBOUNDED driver before the timed one runs. A window may legitimately close before its own request is issued, so "this timed request reached the remote" is not a promise the timed operation can be made to keep; "this fixture is a remote the transport reaches" is, off the timed path, and that is the anti-vacuity guard the case needs. Every product assertion is unchanged: the envelope (TIMEOUT / 504), the message, the elapsed bound, and the three negative controls all still pin what they pinned. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XTBcV7zZHmokdyQgXjbyEU
…essage A red from a sampled counter reads `expected 0 to be greater than 0`, which names no duration -- and merge-queue triage classifies a red by asking exactly that, so the flake this file produced was read as a behaviour regression. Both latch assertions now carry a message naming the bound they missed, so the red says in words that a duration went unmet. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XTBcV7zZHmokdyQgXjbyEU
Contributor
📓 Docs Drift CheckNothing in this diff resolved to a documentable surface (no symbol, route or SDK anchor derived from 0 changed package(s)), so this run has no opinion about the docs. What this run could not see
Coarse fallback — 0 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): |
os-sam
marked this pull request as ready for review
September 10, 2026 03:18
os-sam
enabled auto-merge
September 10, 2026 03:19
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #17121
turso-driver-timeout.test.tsejected PR #17101 from the merge queue onexpect(remote.requests()).toBeGreaterThan(0). The card asked for three things in order — reproduce under load, discriminate the two hypotheses mechanically, then fix accordingly. All three are below, with the measurements.1. The mechanism, measured
The counter increments only when Node dispatches a
requesthandler. The instant it is read is chosen by the very timer under test, and libuv runs the TIMERS phase before the POLL phase: any stall that spans the window delivers the abort — and every assertion that follows it — before the server's already-arrived bytes are parsed into arequestevent. The counter then reads0for a request that is demonstrably on the wire.Instrumented against the real fixture and the real driver, subscribing to undici's own
undici:client:sendHeaders/undici:client:beforeConnectchannels (client-side proof that bytes left the process) and sampling the counter both at the assertion instant and after a settle window:sendHeadersfiredsendHeaders, 6 runsIdle, the server dispatches the handler ~2.1 ms after the call — against a 100 ms window. Under six CPU hogs on four cores that stretched to a worst observed 38.3 ms, an 18x stretch that still never reddened the assertion: plain CPU pressure does not reproduce it, a stall that spans the deadline does. In the frozen runs the handler dispatched ~2 ms after the assertion would have run, every time.
2. Which hypothesis — discriminated, not argued
The card's competing hypothesis was a driver defect:
TIMEOUT/ 504 for a request that never left the process, making the 504 a lie. Under the reproduction that matches the CI signature it is excluded:undici:client:sendHeadershad fired in 6/6, the fixture had accepted the TCP connection in 6/6, and the request handler dispatched in 6/6 — only late. The bytes were on the wire; the observation lagged.A separate probe froze the loop before the connect instead, and there the request genuinely never leaves — but the process was stopped for 3x the whole budget, so no implementation could have issued it and the deadline is answering correctly. No driver change is required, and none is made — the declared
Clause-②: nostands andturso-driver.tsis untouched.3. The fix
The fixture's counter becomes a latching
firstRequestpromise the tests AWAIT, at both call sites —:122and the:138in the negative control that the duplicate card #17079 correctly pointed out would otherwise be left live.The positive case goes one step further. A window may legitimately close before its own request is issued, so "this timed request reached the remote" is not a promise the timed operation can be made to keep. "This fixture is a remote the transport reaches" is — off the timed path. The case now proves it with an unbounded driver against the same server before the timed one runs: nothing can preempt that request, so the condition is awaited rather than raced, and a fixture nothing ever reaches still fails, loudly.
Both latch assertions carry a failure message naming the bound they missed. Merge-queue triage classifies a red by asking whether the assertion names a duration;
expected 0 to be greater than 0answers no, which is precisely why this flake was first read as a behaviour regression.Nothing the test protects is weakened: the envelope (
TIMEOUT/ 504), the message content, the elapsed bound and all three negative controls are unchanged and still pin that a stalled remote fails within the configured window.4. Proof under the failure condition
Both legs run the real file through vitest with a setup that freezes the loop 300 ms from
undici:client:sendHeaders— the shipped file restored from the merge base for the first leg, byte-verified bygit hash-objectagainstorigin/main's blob and restored withgit checkout HEAD --afterwards (git diff HEADempty).Shipped assertion under that condition — the CI signature, reproduced exactly:
This branch under the same condition, five consecutive runs plus one at a 1500 ms freeze (15x the window):
Verification
At
246fff55ca, in a dedicated worktree offcf6e0a193b:Changeset
skip-changeset, measured rather than assumed.@objectstack/driver-tursoshipsfiles: ["dist", "README.md", "CHANGELOG.md"]. After a package build, every symbol this diff introduces has zero hits across all three —settlesWithin0,firstRequest0,REACH_BOUND_MS0,stalledHttpServer0 — while the positive control hits 6 files each (TursoDriver,TursoDriverConfig), anddist/contains no compiled test. Nothing published moves.Acceptance notes
turso-driver-timeout.test.tsraces its own 100 ms window against issuing the request — reddened the hourly full run on main, and the same assertion appears twice #17079 noted that a remedy applied only to:122would leave:138live;:138gets the same awaited latch, for the same reason.code/statusenvelope is exactly right and no implementation could have issued that request — so it is an observation, not a defect, and no card is opened for it.🤖 Generated with Claude Code
https://claude.ai/code/session_01XTBcV7zZHmokdyQgXjbyEU
Generated by Claude Code