Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 24 additions & 9 deletions .config/nextest.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,19 @@
# Local runs: no retries, so a flaky failure surfaces instead of being masked.
retries = 0

# Determinism backstop (WOR-1405). The deadlock this file guards against turns a
# starved child-spawning test into an indefinite hang, which freezes the whole
# local run with no output and no end. The concurrency bound below removes the
# starvation, but a backstop guarantees the run always terminates: any test
# still running after 180s (three 60s periods) is killed and reported failed
# rather than hanging forever. No default-feature test comes close to 60s, so a
# healthy run never trips this; it only fires on a genuine hang or regression.
# Profiles inherit unset settings from `default`, so ci gets the same guard.
slow-timeout = { period = "60s", terminate-after = 3 }

# Bounded concurrency for the process-spawning integration tests (WOR-1405).
# 80 of the 87 `mcptest` integration-test files fork a `/bin/sh` JSON-RPC
# fixture or spawn an `mcptest` child and assert on a round-trip. Each such test
# Most integration tests across the workspace fork a `/bin/sh` JSON-RPC fixture
# or spawn an `mcptest`/server child and assert on a round-trip. Each such test
# needs CPU for both itself and its child, so at nextest's default parallelism
# (one test per core, thousands queued) the cores get oversubscribed two-to-one,
# the children starve, and a blocking round-trip read hangs the whole local run
Expand Down Expand Up @@ -46,13 +56,18 @@ path = "junit.xml"
filter = 'test(repl_prints_notifications_and_fulfills_sampling) | test(graceful_shutdown_terminates_child)'
threads-required = 'num-cpus'

# Assign every `mcptest` integration test (the `tests/` dir, kind = test) to the
# Assign every workspace integration test (the `tests/` dir, kind = test) to the
# bounded `stdio-spawners` group so the swarm of child-spawning tests cannot
# co-saturate the CPU (WOR-1405). Nearly all of them spawn a child; scoping by
# `kind(test)` is both robust (no hand-maintained list to drift) and correct
# (unit tests stay fully parallel). The two tests above also match here, which
# composes cleanly: they reserve the whole pool when they run, which already
# satisfies this group's bound.
# co-saturate the CPU (WOR-1405). The child-spawners are not confined to one
# crate: the bulk live in `mcptest`, but `mcptest-core`
# (stdio_transport_integration, auto_discover_doctor_corpus) and `mcptest-agent`
# (the agent end-to-end suites) fork children too, and a `package(mcptest)`
# filter left those unbounded. Scoping by `kind(test)` alone is both robust (no
# per-crate or per-test list to drift as suites are added) and correct (unit
# tests, kind lib/bin, stay fully parallel). The genuinely pure-logic
# integration tests it also catches are fast, so bounding them costs little. The
# two tests above also match here, which composes cleanly: they reserve the
# whole pool when they run, which already satisfies this group's bound.
[[profile.default.overrides]]
filter = 'package(mcptest) & kind(test)'
filter = 'kind(test)'
test-group = 'stdio-spawners'
Loading