Fix non-running rustc ui tests

This commit is contained in:
Guillaume Gomez 2023-12-05 21:09:13 +01:00
parent ebb7aa0b85
commit 867ea12488
4 changed files with 109 additions and 104 deletions

View File

@ -128,9 +128,9 @@ pub fn build_sysroot(env: &HashMap<String, String>, config: &ConfigInfo) -> Resu
&[ &[
&"cargo", &"cargo",
&"build", &"build",
&"--release",
&"--target", &"--target",
&config.target_triple, &config.target_triple,
&"--release",
], ],
Some(start_dir), Some(start_dir),
Some(&env), Some(&env),

View File

@ -13,6 +13,8 @@ pub struct ConfigInfo {
pub dylib_ext: String, pub dylib_ext: String,
pub sysroot_release_channel: bool, pub sysroot_release_channel: bool,
pub sysroot_panic_abort: bool, pub sysroot_panic_abort: bool,
pub cg_backend_path: String,
pub sysroot_path: String,
} }
impl ConfigInfo { impl ConfigInfo {
@ -118,13 +120,12 @@ impl ConfigInfo {
.get("BUILTIN_BACKEND") .get("BUILTIN_BACKEND")
.map(|backend| !backend.is_empty()) .map(|backend| !backend.is_empty())
.unwrap_or(false); .unwrap_or(false);
let cg_backend_path;
let mut rustflags = Vec::new(); let mut rustflags = Vec::new();
if has_builtin_backend { if has_builtin_backend {
// It means we're building inside the rustc testsuite, so some options need to be handled // It means we're building inside the rustc testsuite, so some options need to be handled
// a bit differently. // a bit differently.
cg_backend_path = "gcc".to_string(); self.cg_backend_path = "gcc".to_string();
match env.get("RUSTC_SYSROOT") { match env.get("RUSTC_SYSROOT") {
Some(rustc_sysroot) if !rustc_sysroot.is_empty() => { Some(rustc_sysroot) if !rustc_sysroot.is_empty() => {
@ -134,15 +135,17 @@ impl ConfigInfo {
} }
rustflags.push("-Cpanic=abort".to_string()); rustflags.push("-Cpanic=abort".to_string());
} else { } else {
cg_backend_path = current_dir self.cg_backend_path = current_dir
.join("target") .join("target")
.join(channel) .join(channel)
.join(&format!("librustc_codegen_gcc.{}", self.dylib_ext)) .join(&format!("librustc_codegen_gcc.{}", self.dylib_ext))
.display() .display()
.to_string(); .to_string();
let sysroot_path = current_dir.join("build_sysroot/sysroot"); self.sysroot_path = current_dir
rustflags .join("build_sysroot/sysroot")
.extend_from_slice(&["--sysroot".to_string(), sysroot_path.display().to_string()]); .display()
.to_string();
rustflags.extend_from_slice(&["--sysroot".to_string(), self.sysroot_path.clone()]);
}; };
// This environment variable is useful in case we want to change options of rustc commands. // This environment variable is useful in case we want to change options of rustc commands.
@ -156,7 +159,7 @@ impl ConfigInfo {
rustflags.extend_from_slice(&[ rustflags.extend_from_slice(&[
"-Csymbol-mangling-version=v0".to_string(), "-Csymbol-mangling-version=v0".to_string(),
"-Cdebuginfo=2".to_string(), "-Cdebuginfo=2".to_string(),
format!("-Zcodegen-backend={}", cg_backend_path), format!("-Zcodegen-backend={}", self.cg_backend_path),
]); ]);
// Since we don't support ThinLTO, disable LTO completely when not trying to do LTO. // Since we don't support ThinLTO, disable LTO completely when not trying to do LTO.

View File

@ -1,14 +1,13 @@
use crate::build; use crate::build;
use crate::config::ConfigInfo; use crate::config::ConfigInfo;
use crate::utils::{ use crate::utils::{
get_gcc_path, get_toolchain, run_command, run_command_with_env, get_gcc_path, get_toolchain, remove_file, run_command, run_command_with_env,
run_command_with_output_and_env, rustc_version_info, split_args, walk_dir, run_command_with_output_and_env, rustc_version_info, split_args, walk_dir,
remove_file,
}; };
use std::collections::{BTreeSet, HashMap}; use std::collections::{BTreeSet, HashMap};
use std::ffi::OsStr; use std::ffi::OsStr;
use std::fs::{File, remove_dir_all}; use std::fs::{remove_dir_all, File};
use std::io::{BufRead, BufReader}; use std::io::{BufRead, BufReader};
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::str::FromStr; use std::str::FromStr;
@ -213,8 +212,11 @@ impl TestArg {
match (test_arg.current_part, test_arg.nb_parts) { match (test_arg.current_part, test_arg.nb_parts) {
(Some(_), Some(_)) | (None, None) => {} (Some(_), Some(_)) | (None, None) => {}
_ => { _ => {
return Err("If either `--current-part` or `--nb-parts` is specified, the other one \ return Err(
needs to be specified as well!".to_string()); "If either `--current-part` or `--nb-parts` is specified, the other one \
needs to be specified as well!"
.to_string(),
);
} }
} }
Ok(Some(test_arg)) Ok(Some(test_arg))
@ -230,20 +232,19 @@ fn build_if_no_backend(env: &Env, args: &TestArg) -> Result<(), String> {
return Ok(()); return Ok(());
} }
let mut command: Vec<&dyn AsRef<OsStr>> = vec![&"cargo", &"rustc"]; let mut command: Vec<&dyn AsRef<OsStr>> = vec![&"cargo", &"rustc"];
if args.channel == Channel::Release { let mut tmp_env;
let mut env = env.clone(); let env = if args.channel == Channel::Release {
env.insert("CARGO_INCREMENTAL".to_string(), "1".to_string()); tmp_env = env.clone();
tmp_env.insert("CARGO_INCREMENTAL".to_string(), "1".to_string());
command.push(&"--release"); command.push(&"--release");
for flag in args.flags.iter() { &tmp_env
command.push(flag);
}
run_command_with_output_and_env(&command, None, Some(&env))
} else { } else {
for flag in args.flags.iter() { &env
command.push(flag); };
} for flag in args.flags.iter() {
run_command_with_output_and_env(&command, None, Some(&env)) command.push(flag);
} }
run_command_with_output_and_env(&command, None, Some(env))
} }
fn clean(_env: &Env, args: &TestArg) -> Result<(), String> { fn clean(_env: &Env, args: &TestArg) -> Result<(), String> {
@ -403,11 +404,7 @@ fn std_tests(env: &Env, args: &TestArg) -> Result<(), String> {
&args.config_info.target_triple, &args.config_info.target_triple,
]); ]);
run_command_with_env(&command, None, Some(env))?; run_command_with_env(&command, None, Some(env))?;
maybe_run_command_in_vm( maybe_run_command_in_vm(&[&cargo_target_dir.join("alloc_example")], env, args)?;
&[&cargo_target_dir.join("alloc_example")],
env,
args,
)?;
} }
// FIXME: create a function "display_if_not_quiet" or something along the line. // FIXME: create a function "display_if_not_quiet" or something along the line.
@ -424,11 +421,7 @@ fn std_tests(env: &Env, args: &TestArg) -> Result<(), String> {
&args.config_info.target_triple, &args.config_info.target_triple,
]); ]);
run_command_with_env(&command, None, Some(env))?; run_command_with_env(&command, None, Some(env))?;
maybe_run_command_in_vm( maybe_run_command_in_vm(&[&cargo_target_dir.join("dst_field_align")], env, args)?;
&[&cargo_target_dir.join("dst_field_align")],
env,
args,
)?;
// FIXME: create a function "display_if_not_quiet" or something along the line. // FIXME: create a function "display_if_not_quiet" or something along the line.
println!("[AOT] std_example"); println!("[AOT] std_example");
@ -525,6 +518,7 @@ fn setup_rustc(env: &mut Env, args: &TestArg) -> Result<(), String> {
None, None,
Some(env), Some(env),
); );
run_command(&[&"git", &"checkout", &"--", &"tests/"], rust_dir)?;
run_command_with_output_and_env(&[&"git", &"fetch"], rust_dir, Some(env))?; run_command_with_output_and_env(&[&"git", &"fetch"], rust_dir, Some(env))?;
let rustc_commit = match rustc_version_info(env.get("RUSTC").map(|s| s.as_str()))?.commit_hash { let rustc_commit = match rustc_version_info(env.get("RUSTC").map(|s| s.as_str()))?.commit_hash {
Some(commit_hash) => commit_hash, Some(commit_hash) => commit_hash,
@ -532,7 +526,7 @@ fn setup_rustc(env: &mut Env, args: &TestArg) -> Result<(), String> {
}; };
run_command_with_output_and_env(&[&"git", &"checkout", &rustc_commit], rust_dir, Some(env))?; run_command_with_output_and_env(&[&"git", &"checkout", &rustc_commit], rust_dir, Some(env))?;
// FIXME: Is it really needed to empty `RUSTFLAGS` here? // FIXME: Is it really needed to empty `RUSTFLAGS` here?
env.insert("RUSTFLAGS".to_string(), String::new()); // env.insert("RUSTFLAGS".to_string(), String::new());
let cargo = String::from_utf8( let cargo = String::from_utf8(
run_command_with_env(&[&"rustup", &"which", &"cargo"], rust_dir, Some(env))?.stdout, run_command_with_env(&[&"rustup", &"which", &"cargo"], rust_dir, Some(env))?.stdout,
) )
@ -591,15 +585,6 @@ download-ci-llvm = false
), ),
) )
.map_err(|error| format!("Failed to write into `rust/config.toml`: {:?}", error))?; .map_err(|error| format!("Failed to write into `rust/config.toml`: {:?}", error))?;
let rustc_commit = match rustc_version_info(env.get("RUSTC").map(|s| s.as_str()))?.commit_hash {
Some(commit_hash) => commit_hash,
None => return Err("Couldn't retrieve rustc commit hash".to_string()),
};
// FIXME: create a function "display_if_not_quiet" or something along the line.
println!("commit: {:?}", rustc_commit);
let command: &[&dyn AsRef<OsStr>] = &[&"git", &"checkout", &rustc_commit, &"tests"];
run_command_with_output_and_env(command, rust_dir, Some(env))?;
Ok(()) Ok(())
} }
@ -834,27 +819,6 @@ fn extended_sysroot_tests(env: &Env, args: &TestArg) -> Result<(), String> {
Ok(()) Ok(())
} }
fn should_remove_ui_test(file: File) -> bool {
for line in BufReader::new(file).lines() {
if let Ok(line) = line {
if [
"// error-pattern:",
"// build-fail",
"// run-fail",
"-Cllvm-args",
"//~",
"// ~",
]
.iter()
.any(|check| line.contains(check))
{
return true;
}
}
}
false
}
fn should_not_remove_test(file: &str) -> bool { fn should_not_remove_test(file: &str) -> bool {
// contains //~ERROR, but shouldn't be removed // contains //~ERROR, but shouldn't be removed
[ [
@ -870,21 +834,40 @@ fn should_not_remove_test(file: &str) -> bool {
.any(|to_ignore| file.ends_with(to_ignore)) .any(|to_ignore| file.ends_with(to_ignore))
} }
fn should_remove_test(path: &Path, path_str: &str) -> bool { fn should_remove_test(file_path: &Path) -> Result<bool, String> {
// Tests generating errors. // Tests generating errors.
path.file_name() let file = File::open(file_path)
.and_then(|name| name.to_str()) .map_err(|error| format!("Failed to read `{}`: {:?}", file_path.display(), error))?;
.map(|name| name.contains("thread")) for line in BufReader::new(file).lines().filter_map(|line| line.ok()) {
.unwrap_or(false) let line = line.trim();
|| [ if line.is_empty() {
"consts/issue-miri-1910.rs", continue;
// Tests generating errors. }
"consts/issue-94675.rs", if [
// this test is oom-killed in the CI. "// error-pattern:",
"mir/mir_heavy/issue-miri-1910.rs", "// build-fail",
"// run-fail",
"-Cllvm-args",
"//~",
"thread",
] ]
.iter() .iter()
.any(|to_ignore| path_str.ends_with(to_ignore)) .any(|check| line.contains(check))
{
return Ok(true);
}
if line.contains("//[") && line.contains("]~") {
return Ok(true);
}
}
if file_path
.display()
.to_string()
.contains("ambiguous-4-extern.rs")
{
eprintln!("nothing found for {file_path:?}");
}
Ok(false)
} }
fn test_rustc_inner<F>(env: &Env, args: &TestArg, prepare_files_callback: F) -> Result<(), String> fn test_rustc_inner<F>(env: &Env, args: &TestArg, prepare_files_callback: F) -> Result<(), String>
@ -896,6 +879,8 @@ where
let mut env = env.clone(); let mut env = env.clone();
setup_rustc(&mut env, args)?; setup_rustc(&mut env, args)?;
let rust_path = Path::new("rust");
walk_dir( walk_dir(
"rust/tests/ui", "rust/tests/ui",
|dir| { |dir| {
@ -924,32 +909,41 @@ where
// These two functions are used to remove files that are known to not be working currently // These two functions are used to remove files that are known to not be working currently
// with the GCC backend to reduce noise. // with the GCC backend to reduce noise.
fn dir_handling(dir: &Path) -> Result<(), String> { fn dir_handling(dir: &Path) -> Result<(), String> {
if dir
.file_name()
.map(|name| name == "auxiliary")
.unwrap_or(true)
{
return Ok(());
}
walk_dir(dir, dir_handling, file_handling) walk_dir(dir, dir_handling, file_handling)
} }
fn file_handling(file_path: &Path) -> Result<(), String> { fn file_handling(file_path: &Path) -> Result<(), String> {
let path_str = file_path.display().to_string().replace("\\", "/"); if !file_path
if !path_str.ends_with(".rs") { .extension()
.map(|extension| extension == "rs")
.unwrap_or(false)
{
return Ok(()); return Ok(());
} else if should_not_remove_test(&path_str) {
return Ok(());
} else if should_remove_test(file_path, &path_str) {
return remove_file(&file_path);
} }
let file = File::open(file_path) let path_str = file_path.display().to_string().replace("\\", "/");
.map_err(|error| format!("Failed to read `{}`: {:?}", file_path.display(), error))?; if should_not_remove_test(&path_str) {
if should_remove_ui_test(file) { return Ok(());
remove_file(&file_path)?; } else if should_remove_test(file_path)? {
return remove_file(&file_path);
} }
Ok(()) Ok(())
} }
let rust_path = Path::new("rust"); remove_file(&rust_path.join("tests/ui/consts/const_cmp_type_id.rs"))?;
remove_file(&rust_path.join("tests/ui/consts/issue-73976-monomorphic.rs"))?;
// this test is oom-killed in the CI.
remove_file(&rust_path.join("tests/ui/consts/issue-miri-1910.rs"))?;
// Tests generating errors.
remove_file(&rust_path.join("tests/ui/consts/issue-94675.rs"))?;
remove_file(&rust_path.join("tests/ui/mir/mir_heavy_promoted.rs"))?;
walk_dir(rust_path.join("tests/ui"), dir_handling, file_handling)?; walk_dir(rust_path.join("tests/ui"), dir_handling, file_handling)?;
let file = rust_path.join("tests/ui/consts/const_cmp_type_id.rs");
remove_file(&file)?;
let file = rust_path.join("tests/ui/consts/issue-73976-monomorphic.rs");
remove_file(&file)?;
if !prepare_files_callback()? { if !prepare_files_callback()? {
// FIXME: create a function "display_if_not_quiet" or something along the line. // FIXME: create a function "display_if_not_quiet" or something along the line.
@ -992,14 +986,16 @@ where
// We increment the number of tests by one because if this is an odd number, we would skip // We increment the number of tests by one because if this is an odd number, we would skip
// one test. // one test.
let count = files.len() / nb_parts + 1; let count = files.len() / nb_parts + 1;
let start = nb_parts * count; let start = current_part * count;
let end = start + count; let end = current_part * count + count;
for (pos, path) in files.iter().enumerate() { // We remove the files we don't want to test.
if pos >= start && pos <= end { for path in files
continue; .iter()
} .enumerate()
let test_path = rust_path.join(path); .filter(|(pos, _)| *pos < start || *pos >= end)
remove_file(&test_path)?; .map(|(_, path)| path)
{
remove_file(&rust_path.join(path))?;
} }
} }
@ -1007,11 +1003,13 @@ where
println!("[TEST] rustc test suite"); println!("[TEST] rustc test suite");
env.insert("COMPILETEST_FORCE_STAGE0".to_string(), "1".to_string()); env.insert("COMPILETEST_FORCE_STAGE0".to_string(), "1".to_string());
let rustc_args = format!( let rustc_args = format!(
"{} {}", "{} -Csymbol-mangling-version=v0 -Zcodegen-backend={} --sysroot {}",
env.get("RUSTFLAGS")
.expect("RUSTFLAGS should not be empty at this stage"),
env.get("TEST_FLAGS").unwrap_or(&String::new()), env.get("TEST_FLAGS").unwrap_or(&String::new()),
args.config_info.cg_backend_path,
args.config_info.sysroot_path,
); );
env.get_mut("RUSTFLAGS").unwrap().clear();
run_command_with_output_and_env( run_command_with_output_and_env(
&[ &[
&"./x.py", &"./x.py",

View File

@ -336,7 +336,11 @@ pub fn split_args(args: &str) -> Result<Vec<String>, String> {
} }
} }
if !found_end { if !found_end {
return Err(format!("Didn't find `{}` at the end of `{}`", end, &args[start..])); return Err(format!(
"Didn't find `{}` at the end of `{}`",
end,
&args[start..]
));
} }
} else if c == '\\' { } else if c == '\\' {
// We skip the escaped character. // We skip the escaped character.