test(signature): serialize registry-auth env tests to end cross-test env bleed (JEF-412)#234
Merged
thejefflarson merged 1 commit intoJul 12, 2026
Conversation
…env bleed (JEF-412) RegistryAuth::from_env reads three process-global env vars (PROTECTOR_REGISTRY_USERNAME / PROTECTOR_REGISTRY_PASSWORD / PROTECTOR_REGISTRY_AUTH_FILE). Rust's default harness runs tests as parallel threads in one process, so one case's set_var/remove_var was observed by a sibling mid-flight — making docker_io_variants_match_the_index_v1_config_key (and its whole env-touching family) flaky under `cargo test`. CI stays green only because it runs nextest, which isolates each test in its own process. Fix (test-hermeticity only; no production change): route every env-mutating test through an RAII EnvGuard that takes a shared static Mutex, snapshots the three vars, clears them to a known state, and restores the snapshot on drop — even on panic — so no test can see another's mutation. The lock recovers from poisoning so one legitimate assertion failure can't cascade. Verified deterministic: 30/30 green under `cargo test -p protector --lib policies::signature::auth::tests -- --test-threads=8` (was ~40% flaky before). Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VtjoJttCvBY4dzCoE4f9vP
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.
Closes JEF-412
Problem
policies::signature::auth::tests::docker_io_variants_match_the_index_v1_config_key(and its whole env-touching sibling family) passed in isolation but flaked under full-suitecargo testparallelism (reproduced ~40% failure rate over 25 runs).Shared global + siblings that bled it:
RegistryAuth::from_envreads three process-global env vars —PROTECTOR_REGISTRY_USERNAME,PROTECTOR_REGISTRY_PASSWORD, andPROTECTOR_REGISTRY_AUTH_FILE. Rust's default test harness runs tests as parallel threads in one process, so aset_var/remove_varin one test was observed by another mid-flight. The bleeding was mutual acrossresolves_per_image_across_multiple_registries,docker_io_variants_match_the_index_v1_config_key,ghcr_private_image_still_resolves_basic_from_the_auth_file, and especiallyenv_override_applies_across_all_registries(it setsPROTECTOR_REGISTRY_USERNAME/PROTECTOR_REGISTRY_PASSWORD, which any concurrent test then saw as a global override).CI stayed green only because it runs
cargo nextest, which isolates each test in its own process — the stale test-file header even claimed nextest isolation, butcargo testgives none.Fix (chosen: serialize + restore — option 2)
Test-hermeticity only; no production behavior change.
from_env()is the exact API the webhook and the sweep call, and the tests must keep exercising its real env-reading — so rather than refactor the env read out of the production hot path (option 1), every env-mutating test now routes through an RAIIEnvGuard:static ENV_LOCK: Mutex<()>so only one env-mutating test runs at a time;Drop— even on panic — so a failing assertion can never leak creds into a sibling;The var list lives in one
CRED_ENV_VARSarray that drives both the clear and the restore. This folds away the old repeatedclear_cred_env()+unsafe { set_var }boilerplate at each test site. No new dependency (noserial_test).Verification
Deterministic under parallel execution — 30/30 green:
Full signature policy area also green (
109 passed).cargo fmt --checkclean,cargo clippy --lib --tests -- -D warningsclean. Test file is 242 lines (well under the 1000-line cap).🤖 Generated with Claude Code
https://claude.ai/code/session_01VtjoJttCvBY4dzCoE4f9vP