From c9e82ec1970b023d0289adaab95e41d67566271f Mon Sep 17 00:00:00 2001 From: Ed Page Date: Tue, 19 Apr 2022 11:18:38 -0500 Subject: [PATCH] feat(test-support): Expose test-env setup --- crates/cargo-test-support/src/lib.rs | 168 ++++++++++++++++----------- tests/testsuite/cargo_add.rs | 48 +------- 2 files changed, 102 insertions(+), 114 deletions(-) diff --git a/crates/cargo-test-support/src/lib.rs b/crates/cargo-test-support/src/lib.rs index fccb1fc1f..18ff64de4 100644 --- a/crates/cargo-test-support/src/lib.rs +++ b/crates/cargo-test-support/src/lib.rs @@ -61,6 +61,7 @@ pub mod tools; pub mod prelude { pub use crate::ChannelChanger; + pub use crate::TestEnv; } /* @@ -1101,75 +1102,7 @@ pub fn process>(t: T) -> ProcessBuilder { fn _process(t: &OsStr) -> ProcessBuilder { let mut p = ProcessBuilder::new(t); - - // In general just clear out all cargo-specific configuration already in the - // environment. Our tests all assume a "default configuration" unless - // specified otherwise. - for (k, _v) in env::vars() { - if k.starts_with("CARGO_") { - p.env_remove(&k); - } - } - if env::var_os("RUSTUP_TOOLCHAIN").is_some() { - // Override the PATH to avoid executing the rustup wrapper thousands - // of times. This makes the testsuite run substantially faster. - lazy_static::lazy_static! { - static ref RUSTC_DIR: PathBuf = { - match ProcessBuilder::new("rustup") - .args(&["which", "rustc"]) - .exec_with_output() - { - Ok(output) => { - let s = str::from_utf8(&output.stdout).expect("utf8").trim(); - let mut p = PathBuf::from(s); - p.pop(); - p - } - Err(e) => { - panic!("RUSTUP_TOOLCHAIN was set, but could not run rustup: {}", e); - } - } - }; - } - let path = env::var_os("PATH").unwrap_or_default(); - let paths = env::split_paths(&path); - let new_path = env::join_paths(std::iter::once(RUSTC_DIR.clone()).chain(paths)).unwrap(); - p.env("PATH", new_path); - } - - p.cwd(&paths::root()) - .env("HOME", paths::home()) - .env("CARGO_HOME", paths::home().join(".cargo")) - .env("__CARGO_TEST_ROOT", paths::root()) - // Force Cargo to think it's on the stable channel for all tests, this - // should hopefully not surprise us as we add cargo features over time and - // cargo rides the trains. - .env("__CARGO_TEST_CHANNEL_OVERRIDE_DO_NOT_USE_THIS", "stable") - // For now disable incremental by default as support hasn't ridden to the - // stable channel yet. Once incremental support hits the stable compiler we - // can switch this to one and then fix the tests. - .env("CARGO_INCREMENTAL", "0") - .env_remove("__CARGO_DEFAULT_LIB_METADATA") - .env_remove("RUSTC") - .env_remove("RUSTDOC") - .env_remove("RUSTC_WRAPPER") - .env_remove("RUSTFLAGS") - .env_remove("RUSTDOCFLAGS") - .env_remove("XDG_CONFIG_HOME") // see #2345 - .env("GIT_CONFIG_NOSYSTEM", "1") // keep trying to sandbox ourselves - .env_remove("EMAIL") - .env_remove("USER") // not set on some rust-lang docker images - .env_remove("MFLAGS") - .env_remove("MAKEFLAGS") - .env_remove("GIT_AUTHOR_NAME") - .env_remove("GIT_AUTHOR_EMAIL") - .env_remove("GIT_COMMITTER_NAME") - .env_remove("GIT_COMMITTER_EMAIL") - .env_remove("MSYSTEM"); // assume cmd.exe everywhere on windows - if cfg!(target_os = "macos") { - // Work-around a bug in macOS 10.15, see `link_or_copy` for details. - p.env("__CARGO_COPY_DONT_LINK_DO_NOT_USE_THIS", "1"); - } + p.cwd(&paths::root()).test_env(); p } @@ -1190,6 +1123,103 @@ impl ChannelChanger for snapbox::cmd::Command { } } +/// Establish a process's test environment +pub trait TestEnv: Sized { + fn test_env(mut self) -> Self { + // In general just clear out all cargo-specific configuration already in the + // environment. Our tests all assume a "default configuration" unless + // specified otherwise. + for (k, _v) in env::vars() { + if k.starts_with("CARGO_") { + self = self.env_remove(&k); + } + } + if env::var_os("RUSTUP_TOOLCHAIN").is_some() { + // Override the PATH to avoid executing the rustup wrapper thousands + // of times. This makes the testsuite run substantially faster. + lazy_static::lazy_static! { + static ref RUSTC_DIR: PathBuf = { + match ProcessBuilder::new("rustup") + .args(&["which", "rustc"]) + .exec_with_output() + { + Ok(output) => { + let s = str::from_utf8(&output.stdout).expect("utf8").trim(); + let mut p = PathBuf::from(s); + p.pop(); + p + } + Err(e) => { + panic!("RUSTUP_TOOLCHAIN was set, but could not run rustup: {}", e); + } + } + }; + } + let path = env::var_os("PATH").unwrap_or_default(); + let paths = env::split_paths(&path); + let new_path = + env::join_paths(std::iter::once(RUSTC_DIR.clone()).chain(paths)).unwrap(); + self = self.env("PATH", new_path); + } + + self = self + .env("HOME", paths::home()) + .env("CARGO_HOME", paths::home().join(".cargo")) + .env("__CARGO_TEST_ROOT", paths::root()) + // Force Cargo to think it's on the stable channel for all tests, this + // should hopefully not surprise us as we add cargo features over time and + // cargo rides the trains. + .env("__CARGO_TEST_CHANNEL_OVERRIDE_DO_NOT_USE_THIS", "stable") + // For now disable incremental by default as support hasn't ridden to the + // stable channel yet. Once incremental support hits the stable compiler we + // can switch this to one and then fix the tests. + .env("CARGO_INCREMENTAL", "0") + .env_remove("__CARGO_DEFAULT_LIB_METADATA") + .env_remove("RUSTC") + .env_remove("RUSTDOC") + .env_remove("RUSTC_WRAPPER") + .env_remove("RUSTFLAGS") + .env_remove("RUSTDOCFLAGS") + .env_remove("XDG_CONFIG_HOME") // see #2345 + .env("GIT_CONFIG_NOSYSTEM", "1") // keep trying to sandbox ourselves + .env_remove("EMAIL") + .env_remove("USER") // not set on some rust-lang docker images + .env_remove("MFLAGS") + .env_remove("MAKEFLAGS") + .env_remove("GIT_AUTHOR_NAME") + .env_remove("GIT_AUTHOR_EMAIL") + .env_remove("GIT_COMMITTER_NAME") + .env_remove("GIT_COMMITTER_EMAIL") + .env_remove("MSYSTEM"); // assume cmd.exe everywhere on windows + if cfg!(target_os = "macos") { + // Work-around a bug in macOS 10.15, see `link_or_copy` for details. + self = self.env("__CARGO_COPY_DONT_LINK_DO_NOT_USE_THIS", "1"); + } + self + } + + fn env>(self, key: &str, value: S) -> Self; + fn env_remove(self, key: &str) -> Self; +} + +impl TestEnv for &mut ProcessBuilder { + fn env>(self, key: &str, value: S) -> Self { + self.env(key, value) + } + fn env_remove(self, key: &str) -> Self { + self.env_remove(key) + } +} + +impl TestEnv for snapbox::cmd::Command { + fn env>(self, key: &str, value: S) -> Self { + self.env(key, value) + } + fn env_remove(self, key: &str) -> Self { + self.env_remove(key) + } +} + fn split_and_add_args(p: &mut ProcessBuilder, s: &str) { for mut arg in s.split_whitespace() { if (arg.starts_with('"') && arg.ends_with('"')) diff --git a/tests/testsuite/cargo_add.rs b/tests/testsuite/cargo_add.rs index b8fec23e5..20f7ac6e2 100644 --- a/tests/testsuite/cargo_add.rs +++ b/tests/testsuite/cargo_add.rs @@ -4,51 +4,9 @@ use cargo_test_support::prelude::*; use cargo_test_support::Project; pub fn cargo_command() -> snapbox::cmd::Command { - let mut cmd = snapbox::cmd::Command::new(cargo_exe()).with_assert(assert()); - - // In general just clear out all cargo-specific configuration already in the - // environment. Our tests all assume a "default configuration" unless - // specified otherwise. - for (k, _v) in std::env::vars() { - if k.starts_with("CARGO_") { - cmd = cmd.env_remove(&k); - } - } - - cmd = cmd - .env("HOME", cargo_test_support::paths::home()) - .env( - "CARGO_HOME", - cargo_test_support::paths::home().join(".cargo"), - ) - .env("__CARGO_TEST_ROOT", cargo_test_support::paths::root()) - // Force Cargo to think it's on the stable channel for all tests, this - // should hopefully not surprise us as we add cargo features over time and - // cargo rides the trains. - .env("__CARGO_TEST_CHANNEL_OVERRIDE_DO_NOT_USE_THIS", "stable") - // For now disable incremental by default as support hasn't ridden to the - // stable channel yet. Once incremental support hits the stable compiler we - // can switch this to one and then fix the tests. - .env("CARGO_INCREMENTAL", "0") - .env_remove("__CARGO_DEFAULT_LIB_METADATA") - .env_remove("RUSTC") - .env_remove("RUSTDOC") - .env_remove("RUSTC_WRAPPER") - .env_remove("RUSTFLAGS") - .env_remove("RUSTDOCFLAGS") - .env_remove("XDG_CONFIG_HOME") // see #2345 - .env("GIT_CONFIG_NOSYSTEM", "1") // keep trying to sandbox ourselves - .env_remove("EMAIL") - .env_remove("USER") // not set on some rust-lang docker images - .env_remove("MFLAGS") - .env_remove("MAKEFLAGS") - .env_remove("GIT_AUTHOR_NAME") - .env_remove("GIT_AUTHOR_EMAIL") - .env_remove("GIT_COMMITTER_NAME") - .env_remove("GIT_COMMITTER_EMAIL") - .env_remove("MSYSTEM"); // assume cmd.exe everywhere on windows - - cmd + snapbox::cmd::Command::new(cargo_exe()) + .with_assert(assert()) + .test_env() } fn init_registry() {