From 42f5da531f324425c18a89c503433c8c3854017d Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 13 Oct 2026 17:52:37 +0000 Subject: [PATCH 1/3] Start fix for #823 slice 11 Assisted-by: Claude Code:claude-opus-5-5 From 8ecbd897d4e08dc3473f2055ecb06a88f71c2804 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 13 Oct 2026 18:14:05 +0000 Subject: [PATCH 2/3] Spawn Go test CLIs through hermetic builder The four Go suites started socket-patch with a bare Command::new and their own SOCKET_* handling, which had drifted from the shared tests/common/hermetic.rs: e2e_golang and the vendor redirect suite removed only a hand-picked list of vars, so any other ambient SOCKET_* (dry run, manifest path) reached the child, and none forced the update notifier off. A developer's shell could silently change what these tests exercise. They now start from hermetic::command and keep only their Go env (GOMODCACHE, GOPATH, GOFLAGS, plus VIRTUAL_ENV via Extra::Venv). The files leave PENDING_RAW_SPAWNS (26 -> 22) so the ratchet keeps them hermetic. Refs #823 Assisted-by: Claude Code:claude-opus-5-5 --- crates/socket-patch-cli/tests/e2e_golang.rs | 44 +++---------------- .../tests/e2e_golang_build.rs | 17 +++---- .../tests/e2e_golang_workspace_build.rs | 18 +++----- .../tests/spawn_env_hygiene.rs | 4 -- .../tests/vendor/e2e_golang_redirect.rs | 35 +++++---------- 5 files changed, 27 insertions(+), 91 deletions(-) diff --git a/crates/socket-patch-cli/tests/e2e_golang.rs b/crates/socket-patch-cli/tests/e2e_golang.rs index e2d49c309..3c3c1a467 100644 --- a/crates/socket-patch-cli/tests/e2e_golang.rs +++ b/crates/socket-patch-cli/tests/e2e_golang.rs @@ -53,11 +53,11 @@ async fn mount_batch(server: &MockServer) { /// Run the binary as a blocking subprocess (off the async runtime so the /// wiremock server can service the request concurrently). /// -/// The environment is pinned hard: `GOMODCACHE` fixes the crawl root, the -/// token/url/org steer the API at the in-test server, and every variable that -/// could redirect the API elsewhere or disable it (`GOPATH`, `SOCKET_OFFLINE`, -/// the proxy URLs) is scrubbed so an ambient value in the test environment -/// can't quietly change what the crawler discovers or whether it calls home. +/// The environment is pinned hard: `hermetic::command` scrubs every ambient +/// `SOCKET_*` (so `SOCKET_OFFLINE`, `SOCKET_ECOSYSTEMS`, `SOCKET_GLOBAL*` and +/// the output-mode trio can't change what the crawler discovers or whether it +/// calls home), `GOMODCACHE` fixes the crawl root with `GOPATH` removed, and +/// the token/url/org steer the API at the in-test server. async fn run(args: &[&str], cwd: &Path, gomodcache: &Path, api_url: &str) -> Output { let args: Vec = args.iter().map(|s| s.to_string()).collect(); let cwd = cwd.to_path_buf(); @@ -65,38 +65,14 @@ async fn run(args: &[&str], cwd: &Path, gomodcache: &Path, api_url: &str) -> Out let api_url = api_url.to_string(); tokio::task::spawn_blocking(move || { let arg_refs: Vec<&str> = args.iter().map(String::as_str).collect(); - std::process::Command::new(binary()) + common::hermetic::command(&binary()) .args(&arg_refs) .current_dir(&cwd) .env("GOMODCACHE", &gomodcache) .env("SOCKET_API_URL", &api_url) .env("SOCKET_API_TOKEN", "sktsec_dummy_e2e_golang_token_api") .env("SOCKET_ORG_SLUG", ORG) - // Ambient-pollution regression guard: seed a hostile value for - // each scan-affecting variable, then scrub it below. `env_remove` - // clears explicitly-set values too, so the child never sees the - // seeds — but if a scrub line is ever dropped, the seed (rather - // than a developer's ambient shell, which this suite can't rely - // on) turns the tests red immediately. Each seed was verified to - // break the suite when inherited: `SOCKET_ECOSYSTEMS` filters the - // go crawler out entirely, `SOCKET_GLOBAL` / `SOCKET_GLOBAL_PREFIX` - // redirect the crawl away from the pinned `GOMODCACHE`, and - // `SOCKET_JSON` / `SOCKET_SILENT` replace or suppress the human - // output the tests assert on. - .env("SOCKET_ECOSYSTEMS", "npm") - .env("SOCKET_GLOBAL", "true") - .env("SOCKET_GLOBAL_PREFIX", "/nonexistent") - .env("SOCKET_JSON", "true") - .env("SOCKET_SILENT", "true") - .env_remove("SOCKET_ECOSYSTEMS") - .env_remove("SOCKET_GLOBAL") - .env_remove("SOCKET_GLOBAL_PREFIX") - .env_remove("SOCKET_JSON") - .env_remove("SOCKET_SILENT") .env_remove("GOPATH") - .env_remove("SOCKET_OFFLINE") - .env_remove("SOCKET_PROXY_URL") - .env_remove("SOCKET_BATCH_SIZE") .output() .expect("Failed to run socket-patch binary") }) @@ -328,14 +304,6 @@ async fn scan_finds_the_cache_named_by_the_go_env_file() { .env("SOCKET_ORG_SLUG", ORG) .env_remove("GOMODCACHE") .env_remove("GOPATH") - .env_remove("SOCKET_ECOSYSTEMS") - .env_remove("SOCKET_GLOBAL") - .env_remove("SOCKET_GLOBAL_PREFIX") - .env_remove("SOCKET_JSON") - .env_remove("SOCKET_SILENT") - .env_remove("SOCKET_OFFLINE") - .env_remove("SOCKET_PROXY_URL") - .env_remove("SOCKET_BATCH_SIZE") .output() .expect("Failed to run socket-patch binary") }) diff --git a/crates/socket-patch-cli/tests/e2e_golang_build.rs b/crates/socket-patch-cli/tests/e2e_golang_build.rs index 2369e65e3..adef5a58c 100644 --- a/crates/socket-patch-cli/tests/e2e_golang_build.rs +++ b/crates/socket-patch-cli/tests/e2e_golang_build.rs @@ -60,19 +60,14 @@ fn go_env<'a>(modcache: &'a str, proxy_url: &'a str) -> Vec<(&'a str, &'a str)> ] } -/// Run socket-patch with ambient `SOCKET_*` scrubbed + the fixture GOMODCACHE -/// (the go crawler resolves installed modules through it). Every global flag -/// is env-backed (`SOCKET_DRY_RUN`, `SOCKET_GLOBAL`, `SOCKET_MANIFEST_PATH`, -/// …), so an unscrubbed ambient value would silently reconfigure `apply` / -/// `--check` out from under the assertions. +/// Run socket-patch with the hermetic `SOCKET_*` environment + the fixture +/// GOMODCACHE (the go crawler resolves installed modules through it). Every +/// global flag is env-backed (`SOCKET_DRY_RUN`, `SOCKET_GLOBAL`, +/// `SOCKET_MANIFEST_PATH`, …), so an unscrubbed ambient value would silently +/// reconfigure `apply` / `--check` out from under the assertions. fn run_socket(cwd: &Path, args: &[&str], modcache: &Path) -> (i32, String, String) { - let mut cmd = Command::new(binary()); + let mut cmd = common::hermetic::command(&binary()); cmd.args(args).current_dir(cwd); - for (k, _) in std::env::vars_os() { - if k.to_string_lossy().starts_with("SOCKET_") && k.to_string_lossy() != "SOCKET_NO_CONFIG" { - cmd.env_remove(&k); - } - } cmd.env("GOMODCACHE", modcache); let out = cmd.output().expect("failed to run socket-patch binary"); ( diff --git a/crates/socket-patch-cli/tests/e2e_golang_workspace_build.rs b/crates/socket-patch-cli/tests/e2e_golang_workspace_build.rs index fed6d3392..73122218a 100644 --- a/crates/socket-patch-cli/tests/e2e_golang_workspace_build.rs +++ b/crates/socket-patch-cli/tests/e2e_golang_workspace_build.rs @@ -38,7 +38,7 @@ mod golang_e2e_matrix; mod vex_e2e_common; use golang_e2e_matrix::{manifestless_vex, ManifestlessGo}; -use vex_e2e_common::{binary, git_sha256, patch_view, Marker, VexVia}; +use vex_e2e_common::{binary, git_sha256, hermetic, patch_view, Marker, VexVia}; const ORG: &str = "test-org"; const UMOD: &str = "example.com/upstream"; @@ -292,20 +292,12 @@ fn move_replace_to_go_work(root: &Path, sums_of: Option<&str>) -> String { line } -/// Run socket-patch (SOCKET_* scrubbed, hermetic config) in `cwd`. +/// Run socket-patch (hermetic `SOCKET_*` environment) in `cwd`. fn socket(cwd: &Path, args: &[&str], modcache: &Path) -> (i32, serde_json::Value, String) { - let mut cmd = Command::new(binary()); + let mut cmd = hermetic::command(&binary()); + hermetic::scrub_extra(&mut cmd, &[hermetic::Extra::Venv]); cmd.current_dir(cwd); - for (k, _) in std::env::vars_os() { - if k.to_string_lossy().starts_with("SOCKET_") { - cmd.env_remove(&k); - } - } - cmd.env("SOCKET_NO_CONFIG", "1") - .env("SOCKET_TELEMETRY_DISABLED", "1") - .env("GOMODCACHE", modcache) - .env("GOFLAGS", "") - .env_remove("VIRTUAL_ENV"); + cmd.env("GOMODCACHE", modcache).env("GOFLAGS", ""); let _fixture = prebuilt_common::prepare_command( &mut cmd, cwd, diff --git a/crates/socket-patch-cli/tests/spawn_env_hygiene.rs b/crates/socket-patch-cli/tests/spawn_env_hygiene.rs index 713a490b5..10a9f1981 100644 --- a/crates/socket-patch-cli/tests/spawn_env_hygiene.rs +++ b/crates/socket-patch-cli/tests/spawn_env_hygiene.rs @@ -34,9 +34,6 @@ const PENDING_RAW_SPAWNS: &[&str] = &[ "e2e_composer.rs", "e2e_composer_version_identity.rs", "e2e_gem.rs", - "e2e_golang.rs", - "e2e_golang_build.rs", - "e2e_golang_workspace_build.rs", "e2e_hosted_production.rs", "e2e_maven.rs", "e2e_npm.rs", @@ -51,7 +48,6 @@ const PENDING_RAW_SPAWNS: &[&str] = &[ "e2e_vendored_production.rs", "e2e_vex_vendor.rs", "rollback/rollback_multicopy_blob_gate.rs", - "vendor/e2e_golang_redirect.rs", "vendor/in_process_vendor_bun.rs", "vendor/vendor_gem_lockfile_only_e2e.rs", "vendor/vendor_rerun_no_network_e2e.rs", diff --git a/crates/socket-patch-cli/tests/vendor/e2e_golang_redirect.rs b/crates/socket-patch-cli/tests/vendor/e2e_golang_redirect.rs index 12c8ada3e..8c3e6d326 100644 --- a/crates/socket-patch-cli/tests/vendor/e2e_golang_redirect.rs +++ b/crates/socket-patch-cli/tests/vendor/e2e_golang_redirect.rs @@ -64,35 +64,20 @@ fn stage(root: &Path) -> (std::path::PathBuf, std::path::PathBuf) { (gomodcache, cache_dir) } -/// Run the CLI binary with the environment pinned hard (mirrors the -/// seed-then-scrub runner in `e2e_golang.rs`). Each variable below was -/// verified to break this suite when inherited from the ambient shell, so it -/// is seeded with a hostile value and then scrubbed — `env_remove` clears the -/// seed too, so the child never sees it, but if a scrub line is ever dropped -/// the seed (rather than a developer's ambient shell, which this suite can't -/// rely on) turns the tests red immediately. `SOCKET_GLOBAL` / -/// `SOCKET_GLOBAL_PREFIX` take the redirect backend out of local scope -/// (apply patches the fake module cache IN PLACE and `--check` exits 0 -/// having checked nothing), `SOCKET_DRY_RUN` makes every apply a no-op, and -/// `SOCKET_MANIFEST_PATH` points apply/check at a manifest that isn't there. -/// `--offline`, `--ecosystems`, and `--cwd` are passed as flags, which -/// outrank env, so their env twins can't bite; `GOMODCACHE` pins the crawl -/// root (so `GOPATH` is never consulted). +/// Run the CLI binary with the hermetic `SOCKET_*` environment. Its hostile +/// seeds cover the vars verified to break this suite when inherited: +/// `SOCKET_GLOBAL` / `SOCKET_GLOBAL_PREFIX` take the redirect backend out of +/// local scope (apply patches the fake module cache IN PLACE and `--check` +/// exits 0 having checked nothing), `SOCKET_DRY_RUN` makes every apply a +/// no-op, and `SOCKET_MANIFEST_PATH` points apply/check at a manifest that +/// isn't there. `--offline`, `--ecosystems`, and `--cwd` are passed as flags, +/// which outrank env, so their env twins can't bite; `GOMODCACHE` pins the +/// crawl root (so `GOPATH` is never consulted). fn run_cli(root: &Path, gomodcache: &Path, args: &[&str]) -> (i32, String, String) { - let out = std::process::Command::new(binary()) + let out = common::hermetic::command(&binary()) .args(args) .current_dir(root) .env("GOMODCACHE", gomodcache) - .env("SOCKET_GLOBAL", "true") - .env("SOCKET_GLOBAL_PREFIX", "/nonexistent") - .env("SOCKET_DRY_RUN", "true") - .env("SOCKET_MANIFEST_PATH", "/nonexistent/manifest.json") - .env_remove("SOCKET_GLOBAL") - .env_remove("SOCKET_GLOBAL_PREFIX") - .env_remove("SOCKET_DRY_RUN") - .env_remove("SOCKET_MANIFEST_PATH") - .env_remove("SOCKET_API_TOKEN") - .env_remove("SOCKET_CLI_API_TOKEN") .output() .expect("failed to execute socket-patch binary"); ( From b73ca1a3e9a6a6cd4231b028f3a7a6c9ba23a4e4 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 13 Oct 2026 18:20:25 +0000 Subject: [PATCH 3/3] Close peer-token and venv gaps in Go test spawns From /code-review high on the Go hermetic migration: - hermetic::command now removes the SOCKET_CLI_* peer aliases by name, like the flag-bound vars. The binary promotes a peer token onto SOCKET_API_TOKEN, so one set after the command was built put the child on the authenticated path. - e2e_golang's scans are unscoped, so an activated VIRTUAL_ENV added the venv's packages to the batch and broke the exact-PURL checks. Both spawn sites now share one builder that scrubs it. - e2e_golang_build and the vendor redirect suite use the shared common::run_with_env runner instead of private copies, and the redundant SOCKET_DRY_RUN set_var guard is gone (the builder seeds and scrubs it itself). Refs #823 Assisted-by: Claude Code:claude-opus-5-5 --- .../socket-patch-cli/tests/common/hermetic.rs | 6 +++ crates/socket-patch-cli/tests/e2e_golang.rs | 41 ++++++++++--------- .../tests/e2e_golang_build.rs | 29 ++++--------- .../tests/spawn_env_hygiene.rs | 9 ++++ .../tests/vendor/e2e_golang_redirect.rs | 16 ++------ 5 files changed, 48 insertions(+), 53 deletions(-) diff --git a/crates/socket-patch-cli/tests/common/hermetic.rs b/crates/socket-patch-cli/tests/common/hermetic.rs index c54cf49b6..8f5e78057 100644 --- a/crates/socket-patch-cli/tests/common/hermetic.rs +++ b/crates/socket-patch-cli/tests/common/hermetic.rs @@ -89,6 +89,12 @@ pub fn command(bin: &Path) -> Command { cmd.env_remove(k); } cmd.env_remove("SOCKET_API_TOKEN"); + // The `SOCKET_CLI_*` peer names too: the binary promotes each onto its + // canonical `SOCKET_*` name, so a peer token set mid-run would put the + // child on the authenticated path. + for (_, peer) in socket_patch_core::utils::env_compat::PEER_ENV_ALIASES { + cmd.env_remove(peer); + } scrub_socket_vars(&mut cmd); // Belt-and-braces on top of the `.cargo/config.toml` `[env]` defaults // (see `FORCED_OPT_OUTS`): a developer's real `socket login` would flip diff --git a/crates/socket-patch-cli/tests/e2e_golang.rs b/crates/socket-patch-cli/tests/e2e_golang.rs index 3c3c1a467..017815f55 100644 --- a/crates/socket-patch-cli/tests/e2e_golang.rs +++ b/crates/socket-patch-cli/tests/e2e_golang.rs @@ -50,14 +50,27 @@ async fn mount_batch(server: &MockServer) { .await; } +/// The binary with the environment pinned hard: `hermetic::command` scrubs +/// every ambient `SOCKET_*` (so `SOCKET_OFFLINE`, `SOCKET_ECOSYSTEMS`, +/// `SOCKET_GLOBAL*` and the output-mode trio can't change what the crawler +/// discovers or whether it calls home), `VIRTUAL_ENV` is removed (the scans +/// are unscoped, so an activated venv would add its packages to the batch), +/// `GOPATH` is removed, and the token/url/org steer the API at the in-test +/// server. Callers pin the module cache. +fn golang_command(cwd: &Path, api_url: &str) -> std::process::Command { + let mut cmd = common::hermetic::command(&binary()); + common::hermetic::scrub_extra(&mut cmd, &[common::hermetic::Extra::Venv]); + cmd.current_dir(cwd) + .env("SOCKET_API_URL", api_url) + .env("SOCKET_API_TOKEN", "sktsec_dummy_e2e_golang_token_api") + .env("SOCKET_ORG_SLUG", ORG) + .env_remove("GOPATH"); + cmd +} + /// Run the binary as a blocking subprocess (off the async runtime so the -/// wiremock server can service the request concurrently). -/// -/// The environment is pinned hard: `hermetic::command` scrubs every ambient -/// `SOCKET_*` (so `SOCKET_OFFLINE`, `SOCKET_ECOSYSTEMS`, `SOCKET_GLOBAL*` and -/// the output-mode trio can't change what the crawler discovers or whether it -/// calls home), `GOMODCACHE` fixes the crawl root with `GOPATH` removed, and -/// the token/url/org steer the API at the in-test server. +/// wiremock server can service the request concurrently), with +/// [`golang_command`]'s env and `GOMODCACHE` fixing the crawl root. async fn run(args: &[&str], cwd: &Path, gomodcache: &Path, api_url: &str) -> Output { let args: Vec = args.iter().map(|s| s.to_string()).collect(); let cwd = cwd.to_path_buf(); @@ -65,14 +78,9 @@ async fn run(args: &[&str], cwd: &Path, gomodcache: &Path, api_url: &str) -> Out let api_url = api_url.to_string(); tokio::task::spawn_blocking(move || { let arg_refs: Vec<&str> = args.iter().map(String::as_str).collect(); - common::hermetic::command(&binary()) + golang_command(&cwd, &api_url) .args(&arg_refs) - .current_dir(&cwd) .env("GOMODCACHE", &gomodcache) - .env("SOCKET_API_URL", &api_url) - .env("SOCKET_API_TOKEN", "sktsec_dummy_e2e_golang_token_api") - .env("SOCKET_ORG_SLUG", ORG) - .env_remove("GOPATH") .output() .expect("Failed to run socket-patch binary") }) @@ -293,17 +301,12 @@ async fn scan_finds_the_cache_named_by_the_go_env_file() { let (project2, api) = (project.clone(), api_url.clone()); let output = tokio::task::spawn_blocking(move || { - common::hermetic::command(&binary()) + golang_command(&project2, &api) .args(["scan", "--json", "--cwd", project2.to_str().unwrap()]) - .current_dir(&project2) .env("GOENV", &goenv) .env("HOME", &home) .env("USERPROFILE", &home) - .env("SOCKET_API_URL", &api) - .env("SOCKET_API_TOKEN", "sktsec_dummy_e2e_golang_token_api") - .env("SOCKET_ORG_SLUG", ORG) .env_remove("GOMODCACHE") - .env_remove("GOPATH") .output() .expect("Failed to run socket-patch binary") }) diff --git a/crates/socket-patch-cli/tests/e2e_golang_build.rs b/crates/socket-patch-cli/tests/e2e_golang_build.rs index adef5a58c..92a861bd8 100644 --- a/crates/socket-patch-cli/tests/e2e_golang_build.rs +++ b/crates/socket-patch-cli/tests/e2e_golang_build.rs @@ -60,21 +60,10 @@ fn go_env<'a>(modcache: &'a str, proxy_url: &'a str) -> Vec<(&'a str, &'a str)> ] } -/// Run socket-patch with the hermetic `SOCKET_*` environment + the fixture -/// GOMODCACHE (the go crawler resolves installed modules through it). Every -/// global flag is env-backed (`SOCKET_DRY_RUN`, `SOCKET_GLOBAL`, -/// `SOCKET_MANIFEST_PATH`, …), so an unscrubbed ambient value would silently -/// reconfigure `apply` / `--check` out from under the assertions. +/// Run socket-patch through the shared hermetic runner with the fixture +/// GOMODCACHE (the go crawler resolves installed modules through it). fn run_socket(cwd: &Path, args: &[&str], modcache: &Path) -> (i32, String, String) { - let mut cmd = common::hermetic::command(&binary()); - cmd.args(args).current_dir(cwd); - cmd.env("GOMODCACHE", modcache); - let out = cmd.output().expect("failed to run socket-patch binary"); - ( - out.status.code().unwrap_or(-1), - String::from_utf8_lossy(&out.stdout).into_owned(), - String::from_utf8_lossy(&out.stderr).into_owned(), - ) + common::run_with_env(cwd, args, &[("GOMODCACHE", modcache.to_str().unwrap())]) } /// Run `go` with its caches sandboxed, then the fixture's own env on top. @@ -201,14 +190,12 @@ fn go_build_links_patch_via_replace_redirect() { if !golang_e2e_matrix::toolchain_ready("e2e_golang_build") { return; } - // RED guards for the hermeticity pins: bake the hostile ambient values in - // so this suite fails deterministically if either leak returns. - // `GOTOOLCHAIN` must lose to go_env's `local` pin (or every `go` command - // chases a nonexistent toolchain through the file proxy); `SOCKET_DRY_RUN` - // must be scrubbed by `run_socket` (or every apply is a no-op that still - // exits 0 and the patched-symbol assert sees PRISTINE). + // RED guard for the toolchain pin: bake the hostile ambient value in so + // this suite fails deterministically if the leak returns. `GOTOOLCHAIN` + // must lose to go_env's `local` pin (or every `go` command chases a + // nonexistent toolchain through the file proxy). `SOCKET_DRY_RUN` needs + // no guard here: `hermetic::command` seeds and scrubs it itself. std::env::set_var("GOTOOLCHAIN", "go1.99.99"); - std::env::set_var("SOCKET_DRY_RUN", "true"); let tmp = tempfile::tempdir().unwrap(); let (consumer, modcache, proxy_url) = stage(tmp.path()); let cs = consumer.to_str().unwrap(); diff --git a/crates/socket-patch-cli/tests/spawn_env_hygiene.rs b/crates/socket-patch-cli/tests/spawn_env_hygiene.rs index 10a9f1981..55f4bbb1b 100644 --- a/crates/socket-patch-cli/tests/spawn_env_hygiene.rs +++ b/crates/socket-patch-cli/tests/spawn_env_hygiene.rs @@ -301,6 +301,11 @@ fn command_drops_flag_bound_vars_set_after_it_is_built() { ("SOCKET_DEBUG", "1"), ("SOCKET_PROXY_URL", "http://ambient.invalid"), ("SOCKET_SKIP_ROLLBACK", "true"), + // Peer aliases the binary promotes onto `SOCKET_API_TOKEN` & co. + ("SOCKET_CLI_API_TOKEN", "late-token"), + ("SOCKET_CLI_ORG_SLUG", "late-org"), + ("SOCKET_CLI_API_BASE_URL", "http://ambient.invalid"), + ("SOCKET_CLI_NO_API_TOKEN", "1"), ], || { let env = effective_env(&cmd); @@ -309,6 +314,10 @@ fn command_drops_flag_bound_vars_set_after_it_is_built() { "SOCKET_DEBUG", "SOCKET_PROXY_URL", "SOCKET_SKIP_ROLLBACK", + "SOCKET_CLI_API_TOKEN", + "SOCKET_CLI_ORG_SLUG", + "SOCKET_CLI_API_BASE_URL", + "SOCKET_CLI_NO_API_TOKEN", ] { assert_eq!(get(&env, key), None, "{key} set after build leaked"); } diff --git a/crates/socket-patch-cli/tests/vendor/e2e_golang_redirect.rs b/crates/socket-patch-cli/tests/vendor/e2e_golang_redirect.rs index 8c3e6d326..f257cc636 100644 --- a/crates/socket-patch-cli/tests/vendor/e2e_golang_redirect.rs +++ b/crates/socket-patch-cli/tests/vendor/e2e_golang_redirect.rs @@ -64,8 +64,8 @@ fn stage(root: &Path) -> (std::path::PathBuf, std::path::PathBuf) { (gomodcache, cache_dir) } -/// Run the CLI binary with the hermetic `SOCKET_*` environment. Its hostile -/// seeds cover the vars verified to break this suite when inherited: +/// Run the CLI binary through the shared hermetic runner. Its hostile seeds +/// cover the vars verified to break this suite when inherited: /// `SOCKET_GLOBAL` / `SOCKET_GLOBAL_PREFIX` take the redirect backend out of /// local scope (apply patches the fake module cache IN PLACE and `--check` /// exits 0 having checked nothing), `SOCKET_DRY_RUN` makes every apply a @@ -74,17 +74,7 @@ fn stage(root: &Path) -> (std::path::PathBuf, std::path::PathBuf) { /// which outrank env, so their env twins can't bite; `GOMODCACHE` pins the /// crawl root (so `GOPATH` is never consulted). fn run_cli(root: &Path, gomodcache: &Path, args: &[&str]) -> (i32, String, String) { - let out = common::hermetic::command(&binary()) - .args(args) - .current_dir(root) - .env("GOMODCACHE", gomodcache) - .output() - .expect("failed to execute socket-patch binary"); - ( - out.status.code().unwrap_or(-1), - String::from_utf8_lossy(&out.stdout).to_string(), - String::from_utf8_lossy(&out.stderr).to_string(), - ) + common::run_with_env(root, args, &[("GOMODCACHE", gomodcache.to_str().unwrap())]) } fn apply(root: &Path, gomodcache: &Path) -> (i32, String, String) {