| 1 | # cargo-nextest profile for contributors (`cargo nextest run --workspace`). |
| 2 | # |
| 3 | # Required GitHub CI and RC/release parity use nextest plus Cargo doctests. |
| 4 | # nextest runs each test in its own process; that does not establish a pass |
| 5 | # under libtest's shared-process globals. GH6698 separately requires two full |
| 6 | # `cargo test --workspace --all-features --locked -- --format=pretty` passes |
| 7 | # at one exact revision. CI's manual `shared-process-twice` mode records that |
| 8 | # evidence; adding the mode or passing nextest does not satisfy the issue. |
| 9 | # nextest also remains a faster local loop with named slow/hanging tests. |
| 10 | # |
| 11 | # Because tests no longer share a process, integration suites that serialize |
| 12 | # on in-process locks must be bounded here when they contend for mock-server |
| 13 | # ports or wall-clock timing budgets. |
| 14 | |
| 15 | [profile.default] |
| 16 | # Name tests that take longer than this so contributors see where the time goes. |
| 17 | slow-timeout = { period = "30s" } |
| 18 | # Keep failures visible in the final summary and never retry silently: |
| 19 | # a flaky test is a bug report, not something to paper over. |
| 20 | retries = 0 |
| 21 | fail-fast = false |
| 22 | final-status-level = "slow" |
| 23 | # RUST_MIN_STACK is not a nextest.toml key. CI and scripts/dev-test.sh |
| 24 | # export 16 MiB so local nextest matches the product thread stack. |
| 25 | |
| 26 | [test-groups] |
| 27 | # Integration tests that spawn the real `codewhale` binary and wait on |
| 28 | # service start-up deadlines; bounded so a fully parallel run on a busy |
| 29 | # machine cannot starve them past their 30 s budgets. |
| 30 | spawns-binaries = { max-threads = 3 } |
| 31 | # Telemetry contract tests also spawn the real binary, and their fixture's |
| 32 | # in-process mutex cannot serialize nextest's one-process-per-test workers. |
| 33 | # Keep one telemetry process alongside the other three integration workers. |
| 34 | telemetry-contract = { max-threads = 1 } |
| 35 | # Persistent-service exec tests wait on a pid file from a real child. Under |
| 36 | # parallel load the file never appears (#5355). Serialize them; do not drop |
| 37 | # the tests. |
| 38 | exec-persistent-service = { max-threads = 1 } |
| 39 | # Fleet manager lifecycle tests start real `/bin/sh` workers under setsid and |
| 40 | # wait 10-15 s for the child's first line. Under full macOS CI load that line |
| 41 | # never ran for three overlapping tests (#6424, #6428 runs), while each |
| 42 | # passed alone from the same binary in under 1.2 s. Serialize the module; do |
| 43 | # not lengthen its deadlines or drop tests. The product side of the load |
| 44 | # (a durable heartbeat and a `ps` sample on every scheduler tick) is now |
| 45 | # bounded to once a second per worker. |
| 46 | fleet-manager-lifecycle = { max-threads = 1 } |
| 47 | # Extension fixtures launch real Node hosts, and the production handshake |
| 48 | # deadline is 30 s (`HANDSHAKE_DEADLINE`, raised from 5 s: Windows full-suite |
| 49 | # runs on #6776/#6780 reported ordinary hosts missing the old one). Bound |
| 50 | # contention across nextest processes; keep production deadlines and the |
| 51 | # explicit hang-detection tests unchanged. |
| 52 | extension-host = { max-threads = 1 } |
| 53 | |
| 54 | # First matching test-group override wins. Keep these more-specific |
| 55 | # integration filters before binary(integration) so they are not stolen |
| 56 | # by the three-thread group. |
| 57 | [[profile.default.overrides]] |
| 58 | filter = 'binary(integration) & test(/^telemetry_contract::/)' |
| 59 | test-group = 'telemetry-contract' |
| 60 | |
| 61 | # Same hazard, different binary. `telemetry_kill_switch_dispatch` is a |
| 62 | # codewhale-cli integration binary, not `integration`, so none of the filters |
| 63 | # below ever matched it and it ran at full parallelism beside ~15.7k tests. |
| 64 | # Each of its cases spawns the real binary, which gives a detached writer |
| 65 | # thread only CLI_PERSIST_TIMEOUT (250 ms, crates/telemetry/src/lib.rs) to |
| 66 | # re-read config from disk and fsync its batch before the process exits. Under |
| 67 | # Ubuntu CI load that deadline is missed and the dry-run receipt never lands — |
| 68 | # observed at telemetry_kill_switch_dispatch.rs:180 on PR #6104 (2026-09-12) |
| 69 | # and again on PR #6267 (2026-09-16), both Ubuntu-only, both on changes that |
| 70 | # touch neither telemetry nor the CLI. |
| 71 | [[profile.default.overrides]] |
| 72 | filter = 'binary(telemetry_kill_switch_dispatch)' |
| 73 | test-group = 'telemetry-contract' |
| 74 | |
| 75 | [[profile.default.overrides]] |
| 76 | filter = 'package(codewhale-tui) & kind(lib) & test(/^fleet::manager::tests::/)' |
| 77 | test-group = 'fleet-manager-lifecycle' |
| 78 | |
| 79 | [[profile.default.overrides]] |
| 80 | filter = 'package(codewhale-tui) & kind(lib) & (test(/^extension_host::/) | test(/^core::engine::.*extension/))' |
| 81 | test-group = 'extension-host' |
| 82 | |
| 83 | [[profile.default.overrides]] |
| 84 | filter = 'binary(integration) & test(/^exec_persistent_service::/)' |
| 85 | test-group = 'exec-persistent-service' |
| 86 | slow-timeout = { period = "120s" } |
| 87 | |
| 88 | [[profile.default.overrides]] |
| 89 | filter = 'binary(integration)' |
| 90 | test-group = 'spawns-binaries' |
| 91 | |
| 92 | # CI (profiles inherit from default): the final summary lists every failure and |
| 93 | # slow test in full so the run log is enough to diagnose without rerunning. |
| 94 | [profile.ci] |
| 95 | retries = 0 |
| 96 | # A test that runs past ten minutes is a hang, not a slow test: terminate it |
| 97 | # and surface its captured output instead of letting the job die at the |
| 98 | # runner's 90-minute limit with no diagnostics (v0.9.12 Windows candidate). |
| 99 | slow-timeout = { period = "60s", terminate-after = 10 } |
| 100 | fail-fast = false |
| 101 | final-status-level = "slow" |
| 102 | failure-output = "immediate-final" |
| 103 | |
| 104 | # Exact compiled-image Native delivery receipt comes from this same full run. |
| 105 | # Only the fixed containment and memory marker/output is retained on success; the rest |
| 106 | # of the workspace keeps its existing output policy. |
| 107 | [profile.ci.junit] |
| 108 | path = "junit.xml" |
| 109 | report-name = "codewhale-native-host" |
| 110 | |
| 111 | [[profile.ci.overrides]] |
| 112 | filter = 'package(codewhale-tui) & kind(lib) & (test(/^extension_host::tests::compiled_native_host_cannot_read_secrets_or_write_outside_its_data_dir$/) | test(/^extension_host::tests::compiled_native_host_memory_cap_is_enforced$/))' |
| 113 | junit.store-success-output = true |
| 114 |