Skip to content

fix(tests): serialize all env-touching tests on the crate-wide mutex - #12

Merged
paveq merged 1 commit into
mainfrom
fix/env-mutex
Sep 22, 2026
Merged

paveq merged 1 commit into
mainfrom
fix/env-mutex

Conversation

@paveq

@paveq paveq commented Sep 22, 2026

Copy link
Copy Markdown
Contributor

cargo test --lib failed reliably on a 14-core machine: 20 of 352 tests failed, all cascading from a single race. Three modules opted out of the crate-wide lock in lib.rs.

client and secrets each declared their own module-private ENV_MUTEX, so their guards serialized only against tests in the same module. The 17 client tests that set HOME therefore ran concurrently with the config, run and sandbox tests that the crate-wide mutex serializes; config::tests::agent_filesystem_paths_resolved read another test's HOME, panicked while holding the crate-wide mutex, and poisoned it for the 19 further tests that unwrap() that lock.

Four exec tests took no lock at all. They compare build_env()'s snapshot of the environment against a second std::env::var read of the same variable, and ESSENTIAL_VARS covers HOME, LANG, LC_ALL and TZ — all mutated by run tests, so the value could change between the two reads.

With every env-touching test on one mutex, 40 consecutive parallel runs pass, so the Nix package no longer needs dontUseCargoParallelTests.

Claude-Session: https://claude.ai/code/session_01E3R8fS7y8zYjoEzjorYTBJ

`cargo test --lib` failed reliably on a 14-core machine: 20 of 352 tests
failed, all cascading from a single race. Three modules opted out of the
crate-wide lock in [lib.rs](src/lib.rs#L21).

`client` and `secrets` each declared their own module-private
`ENV_MUTEX`, so their guards serialized only against tests in the same
module. The 17 `client` tests that set `HOME` therefore ran concurrently
with the `config`, `run` and `sandbox` tests that the crate-wide mutex
serializes; `config::tests::agent_filesystem_paths_resolved` read another
test's `HOME`, panicked while holding the crate-wide mutex, and poisoned
it for the 19 further tests that `unwrap()` that lock.

Four `exec` tests took no lock at all. They compare `build_env()`'s
snapshot of the environment against a second `std::env::var` read of the
same variable, and `ESSENTIAL_VARS` covers `HOME`, `LANG`, `LC_ALL` and
`TZ` — all mutated by `run` tests, so the value could change between the
two reads.

With every env-touching test on one mutex, 40 consecutive parallel runs
pass, so the Nix package no longer needs `dontUseCargoParallelTests`.

Claude-Session: https://claude.ai/code/session_01E3R8fS7y8zYjoEzjorYTBJ
@paveq paveq self-assigned this Sep 22, 2026
@paveq
paveq merged commit c844a8a into main Sep 22, 2026
2 checks passed
@paveq
paveq deleted the fix/env-mutex branch September 22, 2026 08:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant