diff --git a/src/test.rs b/src/test.rs index 90909262ec..19115a5d1e 100644 --- a/src/test.rs +++ b/src/test.rs @@ -19,11 +19,11 @@ use std::{ use sha2::{Digest, Sha256}; -use crate::{dist::TargetTuple, process::TestProcess}; +use crate::{dist::TargetTuple, process::TestProcess, utils::raw}; #[cfg(all(windows, any(test, feature = "test")))] pub(crate) fn test_id() -> String { - crate::utils::raw::random_string(8) + raw::random_string(8) } #[cfg(windows)] @@ -75,12 +75,51 @@ impl Env for HashMap { /// The path to a dir for this test binaries state fn exe_test_dir() -> io::Result { - let current_exe_path = env::current_exe().unwrap(); - let mut exe_dir = current_exe_path.parent().unwrap(); - if exe_dir.ends_with("deps") { - exe_dir = exe_dir.parent().unwrap(); + let curr_exe = env::current_exe().unwrap(); + let curr_exe_dir = curr_exe.parent().unwrap(); + + // Make an empty dir and try to rename it to under the OS' tmp dir to check if they are on the + // same device. If they are, we can conveniently use the renamed dir as the base for our test + // directories. If not, we try to put the base dir in `./target/` as before. + let probe_dir = curr_exe_dir.join(format!("rustup-test-{}", raw::random_string(8))); + raw::ensure_dir_exists(&probe_dir, |_| ())?; + let tmp_test_dir = env::temp_dir().join("rustup-test"); + + let Err(e) = fs::rename(&probe_dir, &tmp_test_dir) else { + return Ok(tmp_test_dir); + }; + + fs::remove_dir(&probe_dir)?; + match e.kind() { + io::ErrorKind::DirectoryNotEmpty => return Ok(tmp_test_dir), + io::ErrorKind::CrossesDevices => (), + _ => return Err(e), } - Ok(exe_dir.parent().unwrap().to_owned()) + + let mut comps = curr_exe_dir.components().collect::>(); + let retained_comps = match &comps[..] { + // New `cargo` output directory layout since Rust v1.100.0: + // /(debug|release)/build/rustup//out/ + [base @ .., _profile, build, rustup, _hash, out] + if build.as_os_str() == "build" + && rustup.as_os_str() == "rustup" + && out.as_os_str() == "out" => + { + base.len() + } + // Legacy layout before Rust v1.100.0: + // /(debug|release)/deps/ + [base @ .., _profile, deps] if deps.as_os_str() == "deps" => base.len(), + _ => { + return Err(io::Error::other(format!( + "unexpected current exe path format: {}", + curr_exe.display() + ))); + } + }; + + comps.truncate(retained_comps); + Ok(PathBuf::from_iter(comps)) } /// Returns a tempdir for running tests in diff --git a/tests/suite/cli_rustup.rs b/tests/suite/cli_rustup.rs index a8bba8cecf..fa9ce8fcfb 100644 --- a/tests/suite/cli_rustup.rs +++ b/tests/suite/cli_rustup.rs @@ -4315,10 +4315,9 @@ async fn only_toml_in_rust_toolchain_toml() { cx.config .expect(["rustc", "--version"]) .await - .extend_redactions([("[CWD]", &cwd)]) .with_stderr(snapbox::str![[r#" ... -error: could not parse override file: '[CWD]/rust-toolchain.toml'[..] +error: could not parse override file: '[..]/rust-toolchain.toml'[..] ... "#]]) .is_err();