Skip to content

Commit e8dc453

Browse files
committed
Auto merge of #146595 - Shourya742:make-cargo-test-work-for-self-test, r=Kobzol
Make cargo test work for bootstrap self test This PR enables the bootstrap self-test to run via cargo test. I have removed the detect_src_and_out test for now, but it will be reintroduced in a follow-up PR where all bootstrap tests will be migrated to use testCtx. r? `@Kobzol`
2 parents caccb4d + aaa82ae commit e8dc453

File tree

6 files changed

+328
-388
lines changed

6 files changed

+328
-388
lines changed

src/bootstrap/src/core/builder/tests.rs

Lines changed: 18 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,7 @@ fn configure(cmd: &str, host: &[&str], target: &[&str]) -> Config {
2222
}
2323

2424
fn configure_with_args(cmd: &[&str], host: &[&str], target: &[&str]) -> Config {
25-
TestCtx::new()
26-
.config(cmd[0])
27-
.args(&cmd[1..])
28-
.hosts(host)
29-
.targets(target)
30-
.args(&["--build", TEST_TRIPLE_1])
31-
.create_config()
25+
TestCtx::new().config(cmd[0]).args(&cmd[1..]).hosts(host).targets(target).create_config()
3226
}
3327

3428
fn first<A, B>(v: Vec<(A, B)>) -> Vec<A> {
@@ -218,25 +212,25 @@ fn prepare_rustc_checkout(ctx: &mut GitCtx) {
218212

219213
/// Parses a Config directory from `path`, with the given value of `download_rustc`.
220214
fn parse_config_download_rustc_at(path: &Path, download_rustc: &str, ci: bool) -> Config {
221-
Config::parse_inner(
222-
Flags::parse(&[
223-
"build".to_owned(),
224-
"--dry-run".to_owned(),
225-
"--ci".to_owned(),
226-
if ci { "true" } else { "false" }.to_owned(),
227-
format!("--set=rust.download-rustc='{download_rustc}'"),
228-
"--src".to_owned(),
229-
path.to_str().unwrap().to_owned(),
230-
]),
231-
|&_| Ok(Default::default()),
232-
)
215+
TestCtx::new()
216+
.config("build")
217+
.args(&[
218+
"--ci",
219+
if ci { "true" } else { "false" },
220+
format!("--set=rust.download-rustc='{download_rustc}'").as_str(),
221+
"--src",
222+
path.to_str().unwrap(),
223+
])
224+
.no_override_download_ci_llvm()
225+
.create_config()
233226
}
234227

235228
mod dist {
236229
use pretty_assertions::assert_eq;
237230

238231
use super::{Config, TEST_TRIPLE_1, TEST_TRIPLE_2, TEST_TRIPLE_3, first, run_build};
239232
use crate::Flags;
233+
use crate::core::builder::tests::host_target;
240234
use crate::core::builder::*;
241235

242236
fn configure(host: &[&str], target: &[&str]) -> Config {
@@ -245,11 +239,11 @@ mod dist {
245239

246240
#[test]
247241
fn llvm_out_behaviour() {
248-
let mut config = configure(&[TEST_TRIPLE_1], &[TEST_TRIPLE_2]);
242+
let mut config = configure(&[], &[TEST_TRIPLE_2]);
249243
config.llvm_from_ci = true;
250244
let build = Build::new(config.clone());
251245

252-
let target = TargetSelection::from_user(TEST_TRIPLE_1);
246+
let target = TargetSelection::from_user(&host_target());
253247
assert!(build.llvm_out(target).ends_with("ci-llvm"));
254248
let target = TargetSelection::from_user(TEST_TRIPLE_2);
255249
assert!(build.llvm_out(target).ends_with("llvm"));
@@ -314,7 +308,7 @@ mod sysroot_target_dirs {
314308
/// cg_gcc tests instead.
315309
#[test]
316310
fn test_test_compiler() {
317-
let config = configure_with_args(&["test", "compiler"], &[TEST_TRIPLE_1], &[TEST_TRIPLE_1]);
311+
let config = configure_with_args(&["test", "compiler"], &[&host_target()], &[TEST_TRIPLE_1]);
318312
let cache = run_build(&config.paths.clone(), config);
319313

320314
let compiler = cache.contains::<test::CrateLibrustc>();
@@ -347,7 +341,7 @@ fn test_test_coverage() {
347341
// Print each test case so that if one fails, the most recently printed
348342
// case is the one that failed.
349343
println!("Testing case: {cmd:?}");
350-
let config = configure_with_args(cmd, &[TEST_TRIPLE_1], &[TEST_TRIPLE_1]);
344+
let config = configure_with_args(cmd, &[], &[TEST_TRIPLE_1]);
351345
let mut cache = run_build(&config.paths.clone(), config);
352346

353347
let modes =
@@ -359,14 +353,7 @@ fn test_test_coverage() {
359353
#[test]
360354
fn test_prebuilt_llvm_config_path_resolution() {
361355
fn configure(config: &str) -> Config {
362-
Config::parse_inner(
363-
Flags::parse(&[
364-
"build".to_string(),
365-
"--dry-run".to_string(),
366-
"--config=/does/not/exist".to_string(),
367-
]),
368-
|&_| toml::from_str(&config),
369-
)
356+
TestCtx::new().config("build").with_default_toml_config(config).create_config()
370357
}
371358

372359
// Removes Windows disk prefix if present

src/bootstrap/src/core/config/config.rs

Lines changed: 38 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -424,6 +424,18 @@ impl Config {
424424
src = src_;
425425
}
426426

427+
#[cfg(test)]
428+
{
429+
if let Some(config_path) = flags_config.as_ref() {
430+
assert!(
431+
!config_path.starts_with(&src),
432+
"Path {config_path:?} should not be inside or equal to src dir {src:?}"
433+
);
434+
} else {
435+
panic!("During test the config should be explicitly added");
436+
}
437+
}
438+
427439
// Now load the TOML config, as soon as possible
428440
let (mut toml, toml_path) = load_toml_config(&src, flags_config, &get_toml);
429441

@@ -630,19 +642,13 @@ impl Config {
630642
let llvm_assertions = llvm_assertions.unwrap_or(false);
631643
let mut target_config = HashMap::new();
632644
let mut channel = "dev".to_string();
633-
let out = flags_build_dir.or(build_build_dir.map(PathBuf::from)).unwrap_or_else(|| {
634-
if cfg!(test) {
635-
// Use the build directory of the original x.py invocation, so that we can set `initial_rustc` properly.
636-
Path::new(
637-
&env::var_os("CARGO_TARGET_DIR").expect("cargo test directly is not supported"),
638-
)
639-
.parent()
640-
.unwrap()
641-
.to_path_buf()
642-
} else {
643-
PathBuf::from("build")
644-
}
645-
});
645+
let out = if cfg!(test) {
646+
test_build_dir()
647+
} else {
648+
flags_build_dir
649+
.or_else(|| build_build_dir.map(PathBuf::from))
650+
.unwrap_or_else(|| PathBuf::from("build"))
651+
};
646652

647653
// NOTE: Bootstrap spawns various commands with different working directories.
648654
// To avoid writing to random places on the file system, `config.out` needs to be an absolute path.
@@ -2484,3 +2490,22 @@ fn find_correct_section_for_field(field_name: &str) -> Vec<WouldBeValidFor> {
24842490
})
24852491
.collect()
24862492
}
2493+
2494+
/// Resolve the build directory used for tests.
2495+
///
2496+
/// - When tests are run through bootstrap (`x.py test`), the build system
2497+
/// sets `CARGO_TARGET_DIR`, so we can trust and use it here.
2498+
/// - When tests are run directly with cargo test, `CARGO_TARGET_DIR` will
2499+
/// not be set. In that case we fall back to resolving relative to
2500+
/// `CARGO_MANIFEST_DIR`, by walking two parents up and appending `build`.
2501+
fn test_build_dir() -> PathBuf {
2502+
env::var_os("CARGO_TARGET_DIR")
2503+
.map(|value| Path::new(&value).parent().unwrap().to_path_buf())
2504+
.unwrap_or_else(|| {
2505+
let base = option_env!("CARGO_MANIFEST_DIR")
2506+
.map(PathBuf::from)
2507+
.unwrap_or_else(|| std::env::current_dir().expect("failed to get current dir"));
2508+
2509+
base.ancestors().nth(2).unwrap_or_else(|| Path::new(".")).join("build")
2510+
})
2511+
}

0 commit comments

Comments
 (0)