about summary refs log tree commit diff
path: root/compiler/rustc_codegen_gcc/build_system/src/test.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_codegen_gcc/build_system/src/test.rs')
-rw-r--r--compiler/rustc_codegen_gcc/build_system/src/test.rs173
1 files changed, 115 insertions, 58 deletions
diff --git a/compiler/rustc_codegen_gcc/build_system/src/test.rs b/compiler/rustc_codegen_gcc/build_system/src/test.rs
index df4ac85233b..bcaab0fb526 100644
--- a/compiler/rustc_codegen_gcc/build_system/src/test.rs
+++ b/compiler/rustc_codegen_gcc/build_system/src/test.rs
@@ -9,8 +9,8 @@ use crate::build;
 use crate::config::{Channel, ConfigInfo};
 use crate::utils::{
     create_dir, get_sysroot_dir, get_toolchain, git_clone, git_clone_root_dir, remove_file,
-    run_command, run_command_with_env, run_command_with_output_and_env, rustc_version_info,
-    split_args, walk_dir,
+    run_command, run_command_with_env, run_command_with_output, run_command_with_output_and_env,
+    rustc_version_info, split_args, walk_dir,
 };
 
 type Env = HashMap<String, String>;
@@ -42,7 +42,7 @@ fn get_runners() -> Runners {
     );
     runners.insert("--extended-regex-tests", ("Run extended regex tests", extended_regex_tests));
     runners.insert("--mini-tests", ("Run mini tests", mini_tests));
-
+    runners.insert("--cargo-tests", ("Run cargo tests", cargo_tests));
     runners
 }
 
@@ -53,9 +53,9 @@ fn get_number_after_arg(
     match args.next() {
         Some(nb) if !nb.is_empty() => match usize::from_str(&nb) {
             Ok(nb) => Ok(nb),
-            Err(_) => Err(format!("Expected a number after `{}`, found `{}`", option, nb)),
+            Err(_) => Err(format!("Expected a number after `{option}`, found `{nb}`")),
         },
-        _ => Err(format!("Expected a number after `{}`, found nothing", option)),
+        _ => Err(format!("Expected a number after `{option}`, found nothing")),
     }
 }
 
@@ -76,8 +76,8 @@ fn show_usage() {
     for (option, (doc, _)) in get_runners() {
         // FIXME: Instead of using the hard-coded `23` value, better to compute it instead.
         let needed_spaces = 23_usize.saturating_sub(option.len());
-        let spaces: String = std::iter::repeat(' ').take(needed_spaces).collect();
-        println!("    {}{}: {}", option, spaces, doc);
+        let spaces: String = std::iter::repeat_n(' ', needed_spaces).collect();
+        println!("    {option}{spaces}: {doc}");
     }
     println!("    --help                 : Show this help");
 }
@@ -88,6 +88,8 @@ struct TestArg {
     use_system_gcc: bool,
     runners: Vec<String>,
     flags: Vec<String>,
+    /// Additional arguments, to be passed to commands like `cargo test`.
+    test_args: Vec<String>,
     nb_parts: Option<usize>,
     current_part: Option<usize>,
     sysroot_panic_abort: bool,
@@ -137,13 +139,14 @@ impl TestArg {
                         test_arg.sysroot_features.push(feature);
                     }
                     _ => {
-                        return Err(format!("Expected an argument after `{}`, found nothing", arg));
+                        return Err(format!("Expected an argument after `{arg}`, found nothing"));
                     }
                 },
                 "--help" => {
                     show_usage();
                     return Ok(None);
                 }
+                "--" => test_arg.test_args.extend(&mut args),
                 x if runners.contains_key(x)
                     && !test_arg.runners.iter().any(|runner| runner == x) =>
                 {
@@ -151,7 +154,7 @@ impl TestArg {
                 }
                 arg => {
                     if !test_arg.config_info.parse_argument(arg, &mut args)? {
-                        return Err(format!("Unknown option {}", arg));
+                        return Err(format!("Unknown option {arg}"));
                     }
                 }
             }
@@ -189,7 +192,7 @@ fn build_if_no_backend(env: &Env, args: &TestArg) -> Result<(), String> {
         command.push(&"--release");
         &tmp_env
     } else {
-        &env
+        env
     };
     for flag in args.flags.iter() {
         command.push(flag);
@@ -203,6 +206,33 @@ fn clean(_env: &Env, args: &TestArg) -> Result<(), String> {
     create_dir(&path)
 }
 
+fn cargo_tests(test_env: &Env, test_args: &TestArg) -> Result<(), String> {
+    // First, we call `mini_tests` to build minicore for us. This ensures we are testing with a working `minicore`,
+    // and that any changes we have made affect `minicore`(since it would get rebuilt).
+    mini_tests(test_env, test_args)?;
+    // Then, we copy some of the env vars from `test_env`
+    // We don't want to pass things like `RUSTFLAGS`, since they contain the -Zcodegen-backend flag.
+    // That would force `cg_gcc` to *rebuild itself* and only then run tests, which is undesirable.
+    let mut env = HashMap::new();
+    env.insert(
+        "LD_LIBRARY_PATH".into(),
+        test_env.get("LD_LIBRARY_PATH").expect("LD_LIBRARY_PATH missing!").to_string(),
+    );
+    env.insert(
+        "LIBRARY_PATH".into(),
+        test_env.get("LIBRARY_PATH").expect("LIBRARY_PATH missing!").to_string(),
+    );
+    env.insert(
+        "CG_RUSTFLAGS".into(),
+        test_env.get("CG_RUSTFLAGS").map(|s| s.as_str()).unwrap_or("").to_string(),
+    );
+    // Pass all the default args + the user-specified ones.
+    let mut args: Vec<&dyn AsRef<OsStr>> = vec![&"cargo", &"test"];
+    args.extend(test_args.test_args.iter().map(|s| s as &dyn AsRef<OsStr>));
+    run_command_with_output_and_env(&args, None, Some(&env))?;
+    Ok(())
+}
+
 fn mini_tests(env: &Env, args: &TestArg) -> Result<(), String> {
     // FIXME: create a function "display_if_not_quiet" or something along the line.
     println!("[BUILD] mini_core");
@@ -222,7 +252,7 @@ fn mini_tests(env: &Env, args: &TestArg) -> Result<(), String> {
         &"--target",
         &args.config_info.target_triple,
     ]);
-    run_command_with_output_and_env(&command, None, Some(&env))?;
+    run_command_with_output_and_env(&command, None, Some(env))?;
 
     // FIXME: create a function "display_if_not_quiet" or something along the line.
     println!("[BUILD] example");
@@ -234,7 +264,7 @@ fn mini_tests(env: &Env, args: &TestArg) -> Result<(), String> {
         &"--target",
         &args.config_info.target_triple,
     ]);
-    run_command_with_output_and_env(&command, None, Some(&env))?;
+    run_command_with_output_and_env(&command, None, Some(env))?;
 
     // FIXME: create a function "display_if_not_quiet" or something along the line.
     println!("[AOT] mini_core_hello_world");
@@ -249,14 +279,14 @@ fn mini_tests(env: &Env, args: &TestArg) -> Result<(), String> {
         &"--target",
         &args.config_info.target_triple,
     ]);
-    run_command_with_output_and_env(&command, None, Some(&env))?;
+    run_command_with_output_and_env(&command, None, Some(env))?;
 
     let command: &[&dyn AsRef<OsStr>] = &[
         &Path::new(&args.config_info.cargo_target_dir).join("mini_core_hello_world"),
         &"abc",
         &"bcd",
     ];
-    maybe_run_command_in_vm(&command, env, args)?;
+    maybe_run_command_in_vm(command, env, args)?;
     Ok(())
 }
 
@@ -454,22 +484,47 @@ fn setup_rustc(env: &mut Env, args: &TestArg) -> Result<PathBuf, String> {
     } else {
         run_command_with_output_and_env(&[&"git", &"checkout"], rust_dir, Some(env))?;
     }
+
+    let mut patches = Vec::new();
+    walk_dir(
+        "patches/tests",
+        &mut |_| Ok(()),
+        &mut |file_path: &Path| {
+            patches.push(file_path.to_path_buf());
+            Ok(())
+        },
+        false,
+    )?;
+    patches.sort();
+    // TODO: remove duplication with prepare.rs by creating a apply_patch function in the utils
+    // module.
+    for file_path in patches {
+        println!("[GIT] apply `{}`", file_path.display());
+        let path = Path::new("../..").join(file_path);
+        run_command_with_output(&[&"git", &"apply", &path], rust_dir)?;
+        run_command_with_output(&[&"git", &"add", &"-A"], rust_dir)?;
+        run_command_with_output(
+            &[&"git", &"commit", &"--no-gpg-sign", &"-m", &format!("Patch {}", path.display())],
+            rust_dir,
+        )?;
+    }
+
     let cargo = String::from_utf8(
         run_command_with_env(&[&"rustup", &"which", &"cargo"], rust_dir, Some(env))?.stdout,
     )
-    .map_err(|error| format!("Failed to retrieve cargo path: {:?}", error))
+    .map_err(|error| format!("Failed to retrieve cargo path: {error:?}"))
     .and_then(|cargo| {
         let cargo = cargo.trim().to_owned();
-        if cargo.is_empty() { Err(format!("`cargo` path is empty")) } else { Ok(cargo) }
+        if cargo.is_empty() { Err("`cargo` path is empty".to_string()) } else { Ok(cargo) }
     })?;
     let rustc = String::from_utf8(
         run_command_with_env(&[&"rustup", &toolchain, &"which", &"rustc"], rust_dir, Some(env))?
             .stdout,
     )
-    .map_err(|error| format!("Failed to retrieve rustc path: {:?}", error))
+    .map_err(|error| format!("Failed to retrieve rustc path: {error:?}"))
     .and_then(|rustc| {
         let rustc = rustc.trim().to_owned();
-        if rustc.is_empty() { Err(format!("`rustc` path is empty")) } else { Ok(rustc) }
+        if rustc.is_empty() { Err("`rustc` path is empty".to_string()) } else { Ok(rustc) }
     })?;
     let llvm_filecheck = match run_command_with_env(
         &[
@@ -479,7 +534,8 @@ fn setup_rustc(env: &mut Env, args: &TestArg) -> Result<PathBuf, String> {
           which FileCheck-11 || \
           which FileCheck-12 || \
           which FileCheck-13 || \
-          which FileCheck-14",
+          which FileCheck-14 || \
+          which FileCheck",
         ],
         rust_dir,
         Some(env),
@@ -487,13 +543,15 @@ fn setup_rustc(env: &mut Env, args: &TestArg) -> Result<PathBuf, String> {
         Ok(cmd) => String::from_utf8_lossy(&cmd.stdout).to_string(),
         Err(_) => {
             eprintln!("Failed to retrieve LLVM FileCheck, ignoring...");
+            // FIXME: the test tests/run-make/no-builtins-attribute will fail if we cannot find
+            // FileCheck.
             String::new()
         }
     };
     let file_path = rust_dir_path.join("config.toml");
     std::fs::write(
         &file_path,
-        &format!(
+        format!(
             r#"change-id = 115898
 
 [rust]
@@ -532,7 +590,7 @@ fn asm_tests(env: &Env, args: &TestArg) -> Result<(), String> {
     let codegen_backend_path = format!(
         "{pwd}/target/{channel}/librustc_codegen_gcc.{dylib_ext}",
         pwd = std::env::current_dir()
-            .map_err(|error| format!("`current_dir` failed: {:?}", error))?
+            .map_err(|error| format!("`current_dir` failed: {error:?}"))?
             .display(),
         channel = args.config_info.channel.as_str(),
         dylib_ext = args.config_info.dylib_ext,
@@ -587,11 +645,11 @@ where
     F: Fn(&[&dyn AsRef<OsStr>], Option<&Path>, &Env) -> Result<(), String>,
 {
     let toolchain = get_toolchain()?;
-    let toolchain_arg = format!("+{}", toolchain);
+    let toolchain_arg = format!("+{toolchain}");
     let rustc_version = String::from_utf8(
         run_command_with_env(&[&args.config_info.rustc_command[0], &"-V"], cwd, Some(env))?.stdout,
     )
-    .map_err(|error| format!("Failed to retrieve rustc version: {:?}", error))?;
+    .map_err(|error| format!("Failed to retrieve rustc version: {error:?}"))?;
     let rustc_toolchain_version = String::from_utf8(
         run_command_with_env(
             &[&args.config_info.rustc_command[0], &toolchain_arg, &"-V"],
@@ -600,20 +658,19 @@ where
         )?
         .stdout,
     )
-    .map_err(|error| format!("Failed to retrieve rustc +toolchain version: {:?}", error))?;
+    .map_err(|error| format!("Failed to retrieve rustc +toolchain version: {error:?}"))?;
 
     if rustc_version != rustc_toolchain_version {
         eprintln!(
-            "rustc_codegen_gcc is built for `{}` but the default rustc version is `{}`.",
-            rustc_toolchain_version, rustc_version,
+            "rustc_codegen_gcc is built for `{rustc_toolchain_version}` but the default rustc version is `{rustc_version}`.",
         );
-        eprintln!("Using `{}`.", rustc_toolchain_version);
+        eprintln!("Using `{rustc_toolchain_version}`.");
     }
     let mut env = env.clone();
     let rustflags = env.get("RUSTFLAGS").cloned().unwrap_or_default();
     env.insert("RUSTDOCFLAGS".to_string(), rustflags);
     let mut cargo_command: Vec<&dyn AsRef<OsStr>> = vec![&"cargo", &toolchain_arg];
-    cargo_command.extend_from_slice(&command);
+    cargo_command.extend_from_slice(command);
     callback(&cargo_command, cwd, &env)
 }
 
@@ -680,7 +737,15 @@ fn test_libcore(env: &Env, args: &TestArg) -> Result<(), String> {
     println!("[TEST] libcore");
     let path = get_sysroot_dir().join("sysroot_src/library/coretests");
     let _ = remove_dir_all(path.join("target"));
-    run_cargo_command(&[&"test"], Some(&path), env, args)?;
+    // TODO(antoyo): run in release mode when we fix the failures.
+    // TODO(antoyo): remove the --skip f16::test_total_cmp when this issue is fixed:
+    // https://github.com/rust-lang/rust/issues/141503
+    run_cargo_command(
+        &[&"test", &"--", &"--skip", &"f16::test_total_cmp"],
+        Some(&path),
+        env,
+        args,
+    )?;
     Ok(())
 }
 
@@ -818,7 +883,7 @@ fn contains_ui_error_patterns(file_path: &Path, keep_lto_tests: bool) -> Result<
     // Tests generating errors.
     let file = File::open(file_path)
         .map_err(|error| format!("Failed to read `{}`: {:?}", file_path.display(), error))?;
-    for line in BufReader::new(file).lines().filter_map(|line| line.ok()) {
+    for line in BufReader::new(file).lines().map_while(Result::ok) {
         let line = line.trim();
         if line.is_empty() {
             continue;
@@ -887,7 +952,7 @@ where
 
     if !prepare_files_callback(&rust_path)? {
         // FIXME: create a function "display_if_not_quiet" or something along the line.
-        println!("Keeping all {} tests", test_type);
+        println!("Keeping all {test_type} tests");
     }
 
     if test_type == "ui" {
@@ -919,8 +984,7 @@ where
                         "borrowck",
                         "test-attrs",
                     ]
-                    .iter()
-                    .any(|name| *name == dir_name)
+                    .contains(&dir_name)
                     {
                         remove_dir_all(dir).map_err(|error| {
                             format!("Failed to remove folder `{}`: {:?}", dir.display(), error)
@@ -975,10 +1039,7 @@ where
         if nb_parts > 0 {
             let current_part = args.current_part.unwrap();
             // FIXME: create a function "display_if_not_quiet" or something along the line.
-            println!(
-                "Splitting ui_test into {} parts (and running part {})",
-                nb_parts, current_part
-            );
+            println!("Splitting ui_test into {nb_parts} parts (and running part {current_part})");
             let out = String::from_utf8(
                 run_command(
                     &[
@@ -996,7 +1057,7 @@ where
                 )?
                 .stdout,
             )
-            .map_err(|error| format!("Failed to retrieve output of find command: {:?}", error))?;
+            .map_err(|error| format!("Failed to retrieve output of find command: {error:?}"))?;
             let mut files = out
                 .split('\n')
                 .map(|line| line.trim())
@@ -1016,7 +1077,7 @@ where
     }
 
     // FIXME: create a function "display_if_not_quiet" or something along the line.
-    println!("[TEST] rustc {} test suite", test_type);
+    println!("[TEST] rustc {test_type} test suite");
     env.insert("COMPILETEST_FORCE_STAGE0".to_string(), "1".to_string());
 
     let extra =
@@ -1040,7 +1101,7 @@ where
             &"always",
             &"--stage",
             &"0",
-            &format!("tests/{}", test_type),
+            &format!("tests/{test_type}"),
             &"--compiletest-rustc-args",
             &rustc_args,
         ],
@@ -1051,19 +1112,18 @@ where
 }
 
 fn test_rustc(env: &Env, args: &TestArg) -> Result<(), String> {
-    //test_rustc_inner(env, args, |_| Ok(false), false, "run-make")?;
+    test_rustc_inner(env, args, |_| Ok(false), false, "run-make")?;
     test_rustc_inner(env, args, |_| Ok(false), false, "ui")
 }
 
 fn test_failing_rustc(env: &Env, args: &TestArg) -> Result<(), String> {
-    let result1 = Ok(());
-    /*test_rustc_inner(
+    let result1 = test_rustc_inner(
         env,
         args,
         retain_files_callback("tests/failing-run-make-tests.txt", "run-make"),
         false,
         "run-make",
-    )*/
+    );
 
     let result2 = test_rustc_inner(
         env,
@@ -1084,14 +1144,13 @@ fn test_successful_rustc(env: &Env, args: &TestArg) -> Result<(), String> {
         false,
         "ui",
     )?;
-    Ok(())
-    /*test_rustc_inner(
+    test_rustc_inner(
         env,
         args,
         remove_files_callback("tests/failing-run-make-tests.txt", "run-make"),
         false,
         "run-make",
-    )*/
+    )
 }
 
 fn test_failing_ui_pattern_tests(env: &Env, args: &TestArg) -> Result<(), String> {
@@ -1118,7 +1177,7 @@ fn retain_files_callback<'a>(
             run_command(
                 &[
                     &"find",
-                    &format!("tests/{}", test_type),
+                    &format!("tests/{test_type}"),
                     &"-mindepth",
                     &"1",
                     &"-type",
@@ -1137,7 +1196,7 @@ fn retain_files_callback<'a>(
             run_command(
                 &[
                     &"find",
-                    &format!("tests/{}", test_type),
+                    &format!("tests/{test_type}"),
                     &"-type",
                     &"f",
                     &"-name",
@@ -1152,15 +1211,12 @@ fn retain_files_callback<'a>(
         }
 
         // Putting back only the failing ones.
-        if let Ok(files) = std::fs::read_to_string(&file_path) {
+        if let Ok(files) = std::fs::read_to_string(file_path) {
             for file in files.split('\n').map(|line| line.trim()).filter(|line| !line.is_empty()) {
-                run_command(&[&"git", &"checkout", &"--", &file], Some(&rust_path))?;
+                run_command(&[&"git", &"checkout", &"--", &file], Some(rust_path))?;
             }
         } else {
-            println!(
-                "Failed to read `{}`, not putting back failing {} tests",
-                file_path, test_type
-            );
+            println!("Failed to read `{file_path}`, not putting back failing {test_type} tests");
         }
 
         Ok(true)
@@ -1188,8 +1244,7 @@ fn remove_files_callback<'a>(
                 }
             } else {
                 println!(
-                    "Failed to read `{}`, not putting back failing {} tests",
-                    file_path, test_type
+                    "Failed to read `{file_path}`, not putting back failing {test_type} tests"
                 );
             }
         } else {
@@ -1202,7 +1257,7 @@ fn remove_files_callback<'a>(
                     remove_file(&path)?;
                 }
             } else {
-                println!("Failed to read `{}`, not putting back failing ui tests", file_path);
+                println!("Failed to read `{file_path}`, not putting back failing ui tests");
             }
         }
         Ok(true)
@@ -1217,7 +1272,9 @@ fn run_all(env: &Env, args: &TestArg) -> Result<(), String> {
     // asm_tests(env, args)?;
     test_libcore(env, args)?;
     extended_sysroot_tests(env, args)?;
+    cargo_tests(env, args)?;
     test_rustc(env, args)?;
+
     Ok(())
 }