Skip to content

Keep ruby unit tests off the host Bundler env - #2066

Open
Mikola Lysenko (mikolalysenko) wants to merge 1 commit into
mainfrom
ci-janitor/bundle-env-scrub
Open

Mikola Lysenko (mikolalysenko) wants to merge 1 commit into
mainfrom
ci-janitor/bundle-env-scrub

Conversation

@mikolalysenko

@mikolalysenko Mikola Lysenko (mikolalysenko) commented Nov 13, 2026 •

Copy link
Copy Markdown
Collaborator

Problem

CI was healthy this run: the merge queue was empty, all merge_group runs since 11-12 18:56 UTC passed, main's latest push run (43324491043) and today's nightly (43373720347) are green, and nothing was queued. The two recent red nightlies (11-10, 11-12, Windows) were already fixed by #2049 and #2061. So this run takes a priority-4 robustness target from #1919, the same class as #2054–#2057 and #2063–#2065: core unit tests that pass only because CI's env is clean.

The hostile-env probe on #1919 found BUNDLE_GEMFILE and BUNDLE_APP_CONFIG still leak into the core lib tests. Measured on origin/main (de81f1b), cargo test -p socket-patch-core --lib:

host env main this PR
clean 7720/7720 7721/7721 (1 new test)
BUNDLE_GEMFILE=<other dir>/Gemfile 156 failed all pass
BUNDLE_APP_CONFIG=<dir with config> 5 failed all pass
HOME with .bundle/config setting BUNDLE_PATH__SYSTEM + BUNDLE_GEMFILE 154 failed (not in the earlier probe) all pass
all of the above + BUNDLE_PATH__SYSTEM=true BUNDLE_IGNORE_CONFIG=1 157 failed all pass

Failing modules on main: vendor::gem, vex::discover::gem, vendor::lock_inventory, vex::discover, upstream::gem.

Root cause

crawlers/ruby_crawler.rs reads every BUNDLE_* var (31 call sites) with std::env::var_os and the user's global Bundler config through ambient_home() → home_dir(), with no test seam. BundlerEnv/*_with_env seams exist, but the vendor and vex paths reach the ambient wrappers.

Fix

Under cfg(test) only, two small seams in ruby_crawler.rs, same pattern as utils::go_env::process_env (#2057):

  • bundle_env(key) replaces the 31 std::env::var_os("BUNDLE_*") reads; in tests it returns only values a live EnvGuard holds (test_env::guarded_var).
  • ambient_home() in tests resolves HOME/USERPROFILE through home_from_env over guarded values only, so a developer's ~/.bundle/config is never read.

Non-test builds are byte-for-byte the old code path (std::env::var_os, home_dir()), including the CLI integration tests, which link the non-test core. New test bundler_env_sees_only_guarded_variables (#[serial]) pins both halves: an unguarded export is not seen, guarded values are.

This is deliberately the minimal seam; it doesn't touch the Bundler-settings parsing that #1935 plans to move, so it shouldn't conflict with that refactor.

Proof

  • Table above (main measured with the same binary built from de81f1b, then from this branch).
  • New test looped 50x: 50/50.
  • cargo clippy --locked -p socket-patch-core --all-features -- -D warnings (CI invocation) is clean; rustfmt --check clean on the touched file. --all-targets only shows a pre-existing cloned_ref_to_slice_refs lint in test code this PR doesn't touch.
  • No test removed or moved; nothing changes in CI config.

Generated by Claude Code

The core unit tests read BUNDLE_* vars and the user's ~/.bundle/config
straight from the process env. A developer with BUNDLE_GEMFILE exported
saw 156 core lib tests fail on a clean checkout, BUNDLE_APP_CONFIG 5,
and a ~/.bundle/config with path.system/gemfile 154 (#1919).

Under cfg(test) only, ruby_crawler's BUNDLE_* reads and its home
lookup now see only values a live EnvGuard holds, the seam go_env
(#2057) uses. Non-test builds are unchanged.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011f9aeNvBQRDzpbqHAEjNAY
@mikolalysenko Mikola Lysenko (mikolalysenko) added the ci-janitor Opened by the CI janitor routine (flakes, redundant tests, CI perf) label Nov 13, 2026
@mikolalysenko

Copy link
Copy Markdown
Collaborator Author

bugbot run


Generated by Claude Code

@cursor

cursor Bot commented Nov 13, 2026 •

Copy link
Copy Markdown

PR Summary

Low Risk
Test-only behavior changes behind cfg(test); production Bundler discovery paths are unchanged.

Overview
Adds cfg(test) seams in the Ruby crawler so unit tests no longer inherit the host BUNDLE_* exports or HOME-backed Bundler config. All ambient BUNDLE_* reads go through bundle_env, and ambient_home() only resolves home from EnvGuard-held vars in tests; release builds still use std::env::var_os and home_dir() unchanged.

A serial unit test bundler_env_sees_only_guarded_variables asserts unguarded shell exports are invisible and guarded values are visible—fixing the ~156 failures when BUNDLE_GEMFILE (and related env) leak into socket-patch-core lib tests (#1919).

Reviewed by Cursor Bugbot for commit 75b2596. Configure here.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 75b2596. Configure here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci-janitor Opened by the CI janitor routine (flakes, redundant tests, CI perf)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants