Repository navigation
Description
New race on main since #2064 (7c5240e, merged 2026-11-13 15:13 UTC). It already failed one coverage shard.
Evidence
- PR Keep coverage's instrumented binary under the update cap #2071 (a CI-only change, unrelated to composer),
coverage (1), run https://github.com/SocketDev/socket-patch/actions/runs/43499592420/job/132141704760:
crawlers::composer_crawler::tests::equivalence::randomized_vendor_trees_match_the_async_oraclepanicked atcrates/socket-patch-core/src/crawlers/composer_crawler.rs:2504:
seed 3: crawl_all left: [("b", "3.5.0", …"/proj/web/plugins/p0"), ("plugin", "3.5.0", …"/proj/vendor/wp/plugin")] right: []
The fixture is deterministic (seeded), so one of the two crawlers saw a different vendor dir partway through the test.
Root cause
Under cfg(test), the composer crawler reads COMPOSER_VENDOR_DIR through test_env::guarded_var_os, which returns the real value whenever any live EnvGuard holds the key. #2064 added vendor_dir_lookups_ignore_the_hosts_composer_env, which ends with EnvGuard::set("COMPOSER_VENDOR_DIR", "held"). That test is #[serial], but the readers (randomized_vendor_trees_match_the_async_oracle and the other composer crawl tests) are not. serial only excludes other serial tests, so a parallel reader can see vendor-dir = held (a directory that doesn't exist) for the guard's lifetime. The new crawler resolved before the guard and the legacy one during it, or the other way round, and the results diverged.
The same pattern can hit any env that guarded_var gates (ruby_crawler's Bundler vars, utils::go_env) wherever a guard-holding test runs beside non-serial readers.
Fix options
- Test the "a held value is honoured" half through the injected-
varresolver (thevar("COMPOSER_VENDOR_DIR")closure path at ~L723) instead of a process-wide guard, and keep only the "host value hidden" half on the real env. This is the smallest fix. - Or mark the env readers in that module
#[serial_test::parallel], which excludes them from running beside#[serial]tests, and document the rule intest_env.rs("every user must also be serial" covers writers but not readers).
Frequency: 1 hit so far (needs the two tests to overlap). It's in the gating coverage leg, so in the merge queue one hit evicts an entry.
Filed by the hourly CI janitor.
Generated by Claude Code
Activity