Clear known env vars for tests (#14080)
Currently, it's possible to break our test suite by having an env var set that influences uv, either a `UV_*` var, or something more generic such as the XDG env vars. We previously fixed them env-var-by-env-var as we discovered. By clearing uv-specific env var for subcommands, we can invert this. We intentionally avoid clearing all env vars as some of them, especially on Windows, are system env vars required for basic operations. Notable limitations are that this only affects tests that use `TestContext::add_shared_env` (default, can be opted-out). Fixed #9873
This commit is contained in:
@@ -143,6 +143,21 @@ pub fn attribute_env_vars_metadata(_attr: TokenStream, input: TokenStream) -> To
|
||||
return quote! { #ast #(#added_in_errors)* }.into();
|
||||
}
|
||||
|
||||
let env_var_names = ast.items.iter().filter_map(|item| {
|
||||
if let ImplItem::Const(item) = item {
|
||||
let syn::Expr::Lit(syn::ExprLit {
|
||||
lit: syn::Lit::Str(lit),
|
||||
..
|
||||
}) = &item.expr
|
||||
else {
|
||||
return None;
|
||||
};
|
||||
Some(lit.value())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
});
|
||||
|
||||
let struct_name = &ast.self_ty;
|
||||
let pairs = constants.iter().map(|(name, doc, added_in, _span)| {
|
||||
if let Some(added_in) = added_in {
|
||||
@@ -160,6 +175,11 @@ pub fn attribute_env_vars_metadata(_attr: TokenStream, input: TokenStream) -> To
|
||||
pub fn metadata<'a>() -> &'a [(&'static str, &'static str, Option<&'static str>)] {
|
||||
&[#(#pairs),*]
|
||||
}
|
||||
|
||||
/// Returns all environment variable names defined as constants (including hidden ones).
|
||||
pub fn all_names() -> &'static [&'static str] {
|
||||
&[#(#env_var_names),*]
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1444,6 +1444,9 @@ impl TestContext {
|
||||
command
|
||||
}
|
||||
|
||||
/// The path to the Python interpreter in the venv.
|
||||
///
|
||||
/// Don't use this for `Command::new`, use `Self::python_command` instead.
|
||||
pub fn interpreter(&self) -> PathBuf {
|
||||
let venv = &self.venv;
|
||||
if cfg!(unix) {
|
||||
@@ -1726,8 +1729,39 @@ impl TestContext {
|
||||
|
||||
/// Creates a new `Command` that is intended to be suitable for use in
|
||||
/// all tests, but with the given binary.
|
||||
///
|
||||
/// Clears environment variables defined in [`EnvVars`] to avoid reading
|
||||
/// test host settings.
|
||||
fn new_command_with(bin: &Path) -> Command {
|
||||
Command::new(bin)
|
||||
let mut command = Command::new(bin);
|
||||
|
||||
let passthrough = [
|
||||
// For debugging tests.
|
||||
EnvVars::RUST_LOG,
|
||||
EnvVars::RUST_BACKTRACE,
|
||||
// Windows System configuration.
|
||||
EnvVars::SYSTEMDRIVE,
|
||||
// Work around small default stack sizes and large futures in debug builds.
|
||||
EnvVars::RUST_MIN_STACK,
|
||||
EnvVars::UV_STACK_SIZE,
|
||||
// Allow running tests with custom network settings.
|
||||
EnvVars::ALL_PROXY,
|
||||
EnvVars::HTTPS_PROXY,
|
||||
EnvVars::HTTP_PROXY,
|
||||
EnvVars::NO_PROXY,
|
||||
EnvVars::SSL_CERT_DIR,
|
||||
EnvVars::SSL_CERT_FILE,
|
||||
EnvVars::UV_NATIVE_TLS,
|
||||
];
|
||||
|
||||
for env_var in EnvVars::all_names()
|
||||
.iter()
|
||||
.filter(|name| !passthrough.contains(name))
|
||||
{
|
||||
command.env_remove(env_var);
|
||||
}
|
||||
|
||||
command
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1790,7 +1824,7 @@ pub fn get_python(version: &PythonVersion) -> PathBuf {
|
||||
|
||||
/// Create a virtual environment at the given path.
|
||||
pub fn create_venv_from_executable<P: AsRef<Path>>(path: P, cache_dir: &ChildPath, python: &Path) {
|
||||
assert_cmd::Command::new(get_bin())
|
||||
TestContext::new_command_with(&get_bin())
|
||||
.arg("venv")
|
||||
.arg(path.as_ref().as_os_str())
|
||||
.arg("--clear")
|
||||
|
||||
Reference in New Issue
Block a user