Repository navigation
test: time out on CPU time, not wall time - #631
Merged
Merged
Conversation
Quest-Claim: 7aadcb6392d9c155
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…eout # Conflicts: # quest/m0/macos-gate.md
The test's wall bound catches a wait that never ends; waits for a file use created's watcher instead of a poll. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…und catches Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
kixelated
marked this pull request as ready for review
November 11, 2026 19:24
Pre-merge checks:
|
…eout # Conflicts: # quest/m0/gate-test-races.md # quest/m0/test-cpu-timeout.md
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.
Finishes quest/m0/test-cpu-timeout.md.
Summary
The merge-group build kept dropping PRs for
Test timed out in 5000ms(or a 20 s / 30 s override) on the shared self-hosted runner: a wall-clock limit measured the host's load, not the tests.test/budget.ts, a vitest setup file, fails a test that spends more than 10 s of CPU, counting its hooks and every child process it waited for. On Linux it reads the worker'sutime + stime + cutime + cstimefrom/proc/self/statbefore and after each test.vitest.config.tsraisestestTimeoutandhookTimeoutto 5 minutes, which only catches a hang (a hung test waiting on a child or IO spends no CPU). The live suite keeps its own limits and no CPU budget.vi.setConfig({ testTimeout }),{ timeout }on describes and tests, trailing}, 60_000)), each of which existed only to survive load or slow Windows process creation.untilintest/gate.test.ts(200 x 25 ms, seen failing at 48-way load in moq-dev/quest#629), the matching loop intest/worktree.run.test.ts, and the 5 s loops intest/land-fixer-diagnostics.test.ts. A wait for a file now uses the fixture'screatedwatcher; a wait for a process to stop still polls, bounded by the test's wall limit.Measurements
Full suite on the maintainer's host (24 CPUs, load average about 40), 2026-11-11: 1222 tests, 128.6 s of CPU in total; the most any single test spent was 1.9 s (
review.test.ts"the PR's Models record sizes the review..."), then 1.6 s and 1.5 s inland.test.ts. The 10 s budget is about five times that peak, leaving room for slower CI cores and contention.A throwaway probe confirmed the behavior: a test spinning an 11 s child and one spinning itself for 11 s both failed with
test spent 10990 ms of CPU, over its 10000 ms budget, while a test waiting 6 s without CPU (past the old 5 s default) passed.Choices made without asking
afterEach, so a CPU-bound test fails once it finishes; one that never finishes fails at the 5-minute wall bound. Vitest offers no way to fail a running test from outside.test/gate.test.tslost its{ timeout: 30_000 }options, and prettier refolded the multi-linetest(...)calls they had forced.Decisions
/proc/self/stat(rejected: delegated per-worker cgroups). The gate's scope wraps the wholejust _test, so itscpu.statcannot attribute CPU to one test, and a per-worker cgroup would miss the commands the gate and worktree tests move into their own systemd scopes, whichcutimestill counts. The CPU budget applies in addition to a wall-clock bound that catches hangs (the 5-minute limit here); that bound also covers a descendant the test never waits for, which/proc/self/statdoes not count. This replaces the quest's earlier "cgroupcpu.stat" plan.until's fixed 200 x 25 ms deadline intest/gate.test.ts, so polled waits carry no deadline of their own: a wait that never completes fails its test at the 5-minute bound. A regression that hangs many waits in one file can therefore take the queue build to its 60-minute job limit before the file reports; a run of that file locally names the stalled tests.Public API
None. Test configuration only; no CLI, wire, or on-disk change.
Caused by
No single PR caused this; vitest's wall-clock default is as old as the suite.
Validation
just check: passed.just test(vitest, install and lifecycle checks, underquest gate): passed, 1239 tests, after merging main (with moq-dev/quest#629).Follow-ups
None.
Models
Size: M
Implementer: Claude Code, claude-opus-5-5, medium effort
Implementer: Claude Code, claude-opus-5-5, medium effort (iterate, M)
(Written by Claude Opus 5.5 with medium)
Review
Rewritten by
quest reviewafter each round.Head: 4d4e7d8
Base: origin/main at 9bcfd22
Reviewer: Codex, gpt-6.1-sol, medium effort
Session:
01a1cbdc-a8e6-7121-86bd-c29506759a8c, round 4Score: 10/10,
The incremental changes merge the updated base without introducing new branch-specific code or review findings.Findings: none
Reviewer: opencode, opencode-go/deepseek-v4.1-flash, high effort
Session:
ses_e34235094ffel7VB11tUcB2AIn, round 4Score: 10/10,
The merge with origin/main is clean: both conflicted quest files end deleted with no dangling references, and the branch's budget, config, and test edits survive intact, so nothing new holds at this head.Findings: none