Skip to content

harden(tests): share GLOBAL_ENV_LOCK across env-mutating integration suites (#48) - #68

Merged
thehoff merged 1 commit into
developfrom
harden/test-global-env-lock-48
May 18, 2026
Merged

thehoff merged 1 commit into
developfrom
harden/test-global-env-lock-48

Conversation

@thehoff

@thehoff thehoff commented May 18, 2026

Copy link
Copy Markdown
Owner

Summary

Closes #48 (test-suite layer). Consolidates env-mutating integration tests onto a single shared GLOBAL_ENV_LOCK so parallel test execution can't race on env mutation. Defense-in-depth — the current integration tests all use Command::env(...) which only affects child env, not parent. The lock prevents a future test that mutates parent env from racing with the existing suite.

Real-race follow-up (not in this PR)

Agent A's report flagged that the actual parent-env race lives in src/core/utils.rs unit tests (which use std::env::set_var/remove_var) — those mutate the parent process env and CAN race. A pre-existing GLOBAL_ENV_LOCK at src/core/utils.rs:1525 covers one block; other env-mutating unit tests in the same file don't grab it. Filing separately.

Design

  • New tests/common/mod.rs exposes pub static GLOBAL_ENV_LOCK: Mutex<()> + a poisoning-tolerant env_lock() helper
  • Helper-based suites (runtime/cloud/gh_glab_gt/proxy_nudge) acquire the lock INSIDE their shared spawn helper — minimum serialization, no leakage
  • Inline-spawn suites (cargo, node, git) acquire at the top of each env-mutating #[test] body
  • Tests that don't pass custom env are intentionally left untouched
  • Mutex::new is const since Rust 1.63 — no lazy_static ceremony

Verified

  • All 9 integration suites pass on this branch
  • No Cargo.toml changes
  • git diff --stat:
    tests/common/mod.rs           | 52 +++++++++++++++++++++++++++++++++++++++++++
    tests/cargo_hardening.rs      |  6 +++++
    tests/cloud_hardening.rs      |  4 ++++
    tests/gh_glab_gt_hardening.rs |  3 +++
    tests/git_hardening.rs        |  8 +++++++
    tests/node_hardening.rs       |  7 ++++++
    tests/proxy_nudge.rs          |  5 +++++
    tests/runtime_hardening.rs    |  7 +++++-
    

Partially closes #48 — full closure waits on the src/core/utils.rs unit-test race follow-up.

…suites (#48)

Adds tests/common/mod.rs with a single `pub static GLOBAL_ENV_LOCK:
Mutex<()>` plus an `env_lock()` helper that recovers from poisoning.
Every integration test that spawns the binary with mutated env now
acquires the shared lock across the spawn, so parallel `cargo test`
runs (the default) cannot race on env state.

Touched suites: runtime_hardening, cloud_hardening, cargo_hardening,
node_hardening, git_hardening, gh_glab_gt_hardening, proxy_nudge.
For helper-based suites (runtime/cloud/gh-glab-gt/proxy_nudge) the
guard is taken inside the shared `run_with_env`/`run_cc`/
`run_capture_stderr` helper; for the others it is added at the top
of each env-mutating `#[test]`. Tests that don't mutate env are
untouched, so the lock only serializes the suite-internal env path.

Why a single per-binary `static Mutex<()>`: every test binary in
Rust is its own process, so cross-binary races are impossible —
the lock only needs to serialize within a binary. `Mutex::new` is
const since 1.63 so no `lazy_static` / `OnceLock` ceremony is
required.

Note: the original issue also cites unit tests under
`src/core/utils.rs` (secure_git_tests, secure_cargo_tests) that
mutate env via `std::env::set_var`. Those use a per-module
`GLOBAL_ENV_LOCK` already and live outside this branch's contract
(src/ untouched). Consolidating them with the integration-side
lock would require a shared crate-level lock and is left for a
follow-up.

Refs #48.
@thehoff
thehoff merged commit b793c3f into develop May 18, 2026
3 checks passed
@thehoff
thehoff deleted the harden/test-global-env-lock-48 branch May 18, 2026 14:00
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.

harden(tests): share GLOBAL_ENV_LOCK across env-mutating tests in secure_*_tests mods

1 participant