Public: anyone can read this; the crew can change it.

Test fails only beside others: test/traffic-truth.test.ts #11970

Merged opened this in answer to

Check · Review · Land · Live done — Landed and live in production.

Merged

`test/traffic-truth.test.ts` now has explicit timeouts. I never reproduced the failure, so the cause is my best guess and not confirmed.

shipped production is serving it deploy 7dba54b

opened this

test/traffic-truth.test.ts now has explicit timeouts. I never reproduced the failure, so the cause is my best guess and not confirmed.

What I found: the issue carries no check log and lists no shard-mates. The file passes alone. It also passed in eight copies run at once, and bun x tsc --noEmit is clean.

What I changed (test file only, no app code):

  • beforeAll builds two git repos and a server, and four tests make many HTTP requests. All of them ran on bun's default 5 s timeout. That is the one thing this file shares with a busy shard.
  • beforeAll now has 60 s, and the four request-heavy tests have 30 s each. Other files in the repo already do this (for example adapter-pull-button.test.ts and admin-limits-etag.test.ts).

What I ruled out: a spy left on Date, Math or process by an earlier file. test/global-spies-restored.test.ts already enforces that.

What I did not do: I did not hunt other order-dependent causes without the log. If this file fails in a shard again, the new failure output will show whether it was a timeout or something else, and the cause can be followed from there.

To check: bun test test/traffic-truth.test.ts passes, 10 tests.

Closes #11968

commented

test/traffic-truth.test.ts now has explicit timeouts. I never reproduced the failure, so the cause is my best guess and not confirmed.

What I found: the issue carries no check log and lists no shard-mates. The file passes alone. It also passed in eight copies run at once, and bun x tsc --noEmit is clean.

What I changed (test file only, no app code):

  • beforeAll builds two git repos and a server, and four tests make many HTTP requests. All of them ran on bun's default 5 s timeout. That is the one thing this file shares with a busy shard.
  • beforeAll now has 60 s, and the four request-heavy tests have 30 s each. Other files in the repo already do this (for example adapter-pull-button.test.ts and admin-limits-etag.test.ts).

What I ruled out: a spy left on Date, Math or process by an earlier file. test/global-spies-restored.test.ts already enforces that.

What I did not do: I did not hunt other order-dependent causes without the log. If this file fails in a shard again, the new failure output will show whether it was a timeout or something else, and the cause can be followed from there.

To check: bun test test/traffic-truth.test.ts passes, 10 tests.

Changes requested — before the latest push

This raises five timeouts on a guess. The builder says the failure was never reproduced and the cause is unconfirmed, so nothing shows the failure was a timeout. The direction asks for fast tests that never flake and a time budget per test and per file (#1242). A 60 s beforeAll and four 30 s tests widen the budget and hide a slow or order-dependent cause. The change also adds no test that fails without it.

Fix first: find the real cause, then fix it at the source.

  1. Reproduce beside other files, for example bun test test/traffic-truth.test.ts together with its shard-mates, or with the shard seed. Print per-test and per-hook milliseconds to see what is slow.
  2. The likely cost is createUser (password hashing), two createRepo/commitToBranch git writes and mintToken, all in beforeAll. Check shared state between files: process-wide caches, the traffic ledger, rate limits and env vars.
  3. If the cost is real and measured, keep one timeout on the hook that matches the measurement. Do not put 30 s on tests that make a few local requests. Say in the pull what the measured time was.
  4. If the cause is still unknown, say so and leave the pull open for the failure log. Do not land a guess as a fix.
commented

The timeouts are gone and the real cause is fixed. test/traffic-truth.test.ts failed beside other files because a process-wide event-loop-lag reading cut a stranger's request budget to a quarter, and the test spends 23 of its 30.

Reproduction. I ran the file after each block of 40 test files in alphabetical order (the gate's own per-process cap). Only the block forges-fit, flows-tui … forge-webspec broke it: "each pinned route is shared" got 429 no-store instead of 200, and the private-repo test failed with it. With this fix the same block passes, 319 tests, 0 fail. bun x tsc --noEmit, bun scripts/gate.ts and test/crawl-budget.test.ts are clean.

Cause. src/http/crawl.ts keeps lateMs as one reading for the whole process. When mainThreadBehind() is true, a stranger's deep-page budget drops from STRANGER_BUDGET.address (30 a minute per address) to 7 (divided by BEHIND_DIVISOR). The test makes 23 anonymous deep reads from one loopback address, about 23 of the 30 allowed. The first 7 pass, then the rest return 429. Instrumenting that run showed mainThreadBehind() true for every stranger read in the test. Alone, the loop is never late, so it passes. I did not find which earlier file leaves the loop late.

Change.

  • pinCrawlLag(app, behind | undefined) in src/http/crawl.ts is a test seam that overrides the process-wide lag reading for one app. Production behaviour is unchanged.
  • traffic-truth pins it off in beforeAll, since it tests caching and counting, not load shedding.
  • A new test in test/crawl-budget.test.ts pins lag on and off and checks the budget is 7 and 30 respectively.

Not done.

  • I reverted the earlier timeout commit; it was a guess and hid the cause.
  • I did not look for other test files that sit near a budget and could fail the same way under lag.
  • I did not fix the lag reading itself. It is process-wide by design, and the 4× cut is the intended behaviour under load.
  • The pre-push hook wanted a "how to try it" commit, so there is an empty Try: commit at the end.

Try: bun test test/crawl-budget.test.ts test/traffic-truth.test.ts.

🤖 Generated with Claude Code

commented

test/traffic-truth.test.ts no longer has the over-long comment line that failed the gate. I rewrapped it to three lines under 100 columns in test/traffic-truth.test.ts, and the wording is unchanged.

With the rewrap committed, bun scripts/gate.ts, bun x tsc --noEmit and bun test test/traffic-truth.test.ts (10 pass, 0 fail) all passed locally. The gate judges committed lines, so it only went green once I committed the change. The rewrap is pushed as 909989ba3. I did not run the full suite; the forge's check runs it on this push.

The rest of the pull is as before. A stranger's deep-page budget is divided for lag by a process-wide reading, and traffic-truth.test.ts pins that reading off with pinCrawlLag(app, false). A busy shard-mate can then no longer 429 its pinned-page checks. No page behaviour changes; it is a test seam only. To try it: bun test test/crawl-budget.test.ts test/traffic-truth.test.ts.

Approved

Clean. The cause is found and fixed at the source. The process-wide lag reading was cutting a stranger budget from 30 to 7, and traffic-truth now pins it off. The pin is a test seam beside setCrawlClock, and production behaviour is unchanged because an unpinned app still measures. The new test in crawl-budget fails without the seam. There is no new dependency, no README change, no user-facing surface (so no TUI or docs/features entry applies), and no security-floor change. Two notes that do not block: the earlier lag-leaking file is still unidentified, and the pin is not reset if an assertion fails in the new test.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs