Skip to content

Commit

Permalink
ui pattern failure tests (#524)
Browse files Browse the repository at this point in the history
  • Loading branch information
lordshashank authored Jun 10, 2024
1 parent eccab8b commit a63b83e
Show file tree
Hide file tree
Showing 6 changed files with 170 additions and 67 deletions.
9 changes: 9 additions & 0 deletions .github/workflows/failures.yml
Original file line number Diff line number Diff line change
Expand Up @@ -98,3 +98,12 @@ jobs:
run: |
${{ matrix.libgccjit_version.env_extra }} ./y.sh test --release --clean --build-sysroot --test-failing-rustc ${{ matrix.libgccjit_version.extra }} | tee output_log
rg --text "test result" output_log >> $GITHUB_STEP_SUMMARY
- name: Run failing ui pattern tests for ICE
id: ui-tests
run: |
${{ matrix.libgccjit_version.env_extra }} ./y.sh test --release --test-failing-ui-pattern-tests ${{ matrix.libgccjit_version.extra }} | tee output_log_ui
if grep -q "the compiler unexpectedly panicked" output_log_ui; then
echo "Error: 'the compiler unexpectedly panicked' found in output logs. CI Error!!"
exit 1
fi
17 changes: 10 additions & 7 deletions build_system/src/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ fn cleanup_sysroot_previous_build(start_dir: &Path) {
// Clean target dir except for build scripts and incremental cache
let _ = walk_dir(
start_dir.join("target"),
|dir: &Path| {
&mut |dir: &Path| {
for top in &["debug", "release"] {
let _ = fs::remove_dir_all(dir.join(top).join("build"));
let _ = fs::remove_dir_all(dir.join(top).join("deps"));
Expand All @@ -77,7 +77,7 @@ fn cleanup_sysroot_previous_build(start_dir: &Path) {

let _ = walk_dir(
dir.join(top),
|sub_dir: &Path| {
&mut |sub_dir: &Path| {
if sub_dir
.file_name()
.map(|filename| filename.to_str().unwrap().starts_with("libsysroot"))
Expand All @@ -87,7 +87,7 @@ fn cleanup_sysroot_previous_build(start_dir: &Path) {
}
Ok(())
},
|file: &Path| {
&mut |file: &Path| {
if file
.file_name()
.map(|filename| filename.to_str().unwrap().starts_with("libsysroot"))
Expand All @@ -97,11 +97,13 @@ fn cleanup_sysroot_previous_build(start_dir: &Path) {
}
Ok(())
},
false,
);
}
Ok(())
},
|_| Ok(()),
&mut |_| Ok(()),
false,
);

let _ = fs::remove_file(start_dir.join("Cargo.lock"));
Expand Down Expand Up @@ -166,14 +168,15 @@ pub fn build_sysroot(env: &HashMap<String, String>, config: &ConfigInfo) -> Resu
// Copy files to sysroot
let sysroot_path = start_dir.join(format!("sysroot/lib/rustlib/{}/lib/", config.target_triple));
create_dir(&sysroot_path)?;
let copier = |dir_to_copy: &Path| {
let mut copier = |dir_to_copy: &Path| {
// FIXME: should not use shell command!
run_command(&[&"cp", &"-r", &dir_to_copy, &sysroot_path], None).map(|_| ())
};
walk_dir(
start_dir.join(&format!("target/{}/{}/deps", config.target_triple, channel)),
copier,
copier,
&mut copier.clone(),
&mut copier,
false,
)?;

// Copy the source files to the sysroot (Rust for Linux needs this).
Expand Down
15 changes: 9 additions & 6 deletions build_system/src/prepare.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,30 +72,33 @@ fn prepare_libcore(
let mut patches = Vec::new();
walk_dir(
"patches",
|_| Ok(()),
|file_path: &Path| {
&mut |_| Ok(()),
&mut |file_path: &Path| {
patches.push(file_path.to_path_buf());
Ok(())
},
false,
)?;
if cross_compile {
walk_dir(
"patches/cross_patches",
|_| Ok(()),
|file_path: &Path| {
&mut |_| Ok(()),
&mut |file_path: &Path| {
patches.push(file_path.to_path_buf());
Ok(())
},
false,
)?;
}
if libgccjit12_patches {
walk_dir(
"patches/libgccjit12",
|_| Ok(()),
|file_path: &Path| {
&mut |_| Ok(()),
&mut |file_path: &Path| {
patches.push(file_path.to_path_buf());
Ok(())
},
false,
)?;
}
patches.sort();
Expand Down
150 changes: 97 additions & 53 deletions build_system/src/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ fn get_runners() -> Runners {
runners.insert("--test-rustc", ("Run all rustc tests", test_rustc as Runner));
runners
.insert("--test-successful-rustc", ("Run successful rustc tests", test_successful_rustc));
runners.insert(
"--test-failing-ui-pattern-tests",
("Run failing ui pattern tests", test_failing_ui_pattern_tests),
);
runners.insert("--test-failing-rustc", ("Run failing rustc tests", test_failing_rustc));
runners.insert("--projects", ("Run the tests of popular crates", test_projects));
runners.insert("--test-libcore", ("Run libcore tests", test_libcore));
Expand Down Expand Up @@ -808,7 +812,7 @@ fn extended_sysroot_tests(env: &Env, args: &TestArg) -> Result<(), String> {
Ok(())
}

fn should_not_remove_test(file: &str) -> bool {
fn valid_ui_error_pattern_test(file: &str) -> bool {
// contains //~ERROR, but shouldn't be removed
[
"issues/auxiliary/issue-3136-a.rs",
Expand All @@ -824,7 +828,7 @@ fn should_not_remove_test(file: &str) -> bool {
}

#[rustfmt::skip]
fn should_remove_test(file_path: &Path) -> Result<bool, String> {
fn contains_ui_error_patterns(file_path: &Path) -> Result<bool, String> {
// Tests generating errors.
let file = File::open(file_path)
.map_err(|error| format!("Failed to read `{}`: {:?}", file_path.display(), error))?;
Expand Down Expand Up @@ -856,10 +860,19 @@ fn should_remove_test(file_path: &Path) -> Result<bool, String> {
Ok(false)
}

// # Parameters
//
// * `env`: An environment variable that provides context for the function.
// * `args`: The arguments passed to the test. This could include things like the flags, config etc.
// * `prepare_files_callback`: A callback function that prepares the files needed for the test. Its used to remove/retain tests giving Error to run various rust test suits.
// * `run_error_pattern_test`: A boolean that determines whether to run only error pattern tests.
// * `test_type`: A string that indicates the type of the test being run.
//
fn test_rustc_inner<F>(
env: &Env,
args: &TestArg,
prepare_files_callback: F,
run_error_pattern_test: bool,
test_type: &str,
) -> Result<(), String>
where
Expand All @@ -876,54 +889,71 @@ where
}

if test_type == "ui" {
walk_dir(
rust_path.join("tests/ui"),
|dir| {
let dir_name = dir.file_name().and_then(|name| name.to_str()).unwrap_or("");
if [
"abi",
"extern",
"unsized-locals",
"proc-macro",
"threads-sendsync",
"borrowck",
"test-attrs",
]
.iter()
.any(|name| *name == dir_name)
{
std::fs::remove_dir_all(dir).map_err(|error| {
format!("Failed to remove folder `{}`: {:?}", dir.display(), error)
})?;
if run_error_pattern_test {
// After we removed the error tests that are known to panic with rustc_codegen_gcc, we now remove the passing tests since this runs the error tests.
walk_dir(
rust_path.join("tests/ui"),
&mut |_dir| Ok(()),
&mut |file_path| {
if contains_ui_error_patterns(file_path)? {
Ok(())
} else {
remove_file(file_path).map_err(|e| e.to_string())
}
},
true,
)?;
} else {
walk_dir(
rust_path.join("tests/ui"),
&mut |dir| {
let dir_name = dir.file_name().and_then(|name| name.to_str()).unwrap_or("");
if [
"abi",
"extern",
"unsized-locals",
"proc-macro",
"threads-sendsync",
"borrowck",
"test-attrs",
]
.iter()
.any(|name| *name == dir_name)
{
std::fs::remove_dir_all(dir).map_err(|error| {
format!("Failed to remove folder `{}`: {:?}", dir.display(), error)
})?;
}
Ok(())
},
&mut |_| Ok(()),
false,
)?;

// These two functions are used to remove files that are known to not be working currently
// with the GCC backend to reduce noise.
fn dir_handling(dir: &Path) -> Result<(), String> {
if dir.file_name().map(|name| name == "auxiliary").unwrap_or(true) {
return Ok(());
}
Ok(())
},
|_| Ok(()),
)?;

// These two functions are used to remove files that are known to not be working currently
// with the GCC backend to reduce noise.
fn dir_handling(dir: &Path) -> Result<(), String> {
if dir.file_name().map(|name| name == "auxiliary").unwrap_or(true) {
return Ok(());
walk_dir(dir, &mut dir_handling, &mut file_handling, false)
}
walk_dir(dir, dir_handling, file_handling)
}
fn file_handling(file_path: &Path) -> Result<(), String> {
if !file_path.extension().map(|extension| extension == "rs").unwrap_or(false) {
return Ok(());
}
let path_str = file_path.display().to_string().replace("\\", "/");
if should_not_remove_test(&path_str) {
return Ok(());
} else if should_remove_test(file_path)? {
return remove_file(&file_path);
fn file_handling(file_path: &Path) -> Result<(), String> {
if !file_path.extension().map(|extension| extension == "rs").unwrap_or(false) {
return Ok(());
}
let path_str = file_path.display().to_string().replace("\\", "/");
if valid_ui_error_pattern_test(&path_str) {
return Ok(());
} else if contains_ui_error_patterns(file_path)? {
return remove_file(&file_path);
}
Ok(())
}
Ok(())
}

walk_dir(rust_path.join("tests/ui"), dir_handling, file_handling)?;

walk_dir(rust_path.join("tests/ui"), &mut dir_handling, &mut file_handling, false)?;
}
let nb_parts = args.nb_parts.unwrap_or(0);
if nb_parts > 0 {
let current_part = args.current_part.unwrap();
Expand Down Expand Up @@ -1004,22 +1034,24 @@ where
}

fn test_rustc(env: &Env, args: &TestArg) -> Result<(), String> {
test_rustc_inner(env, args, |_| Ok(false), "run-make")?;
test_rustc_inner(env, args, |_| Ok(false), "ui")
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 = test_rustc_inner(
env,
args,
prepare_files_callback_failing("tests/failing-run-make-tests.txt", "run-make"),
retain_files_callback("tests/failing-run-make-tests.txt", "run-make"),
false,
"run-make",
);

let result2 = test_rustc_inner(
env,
args,
prepare_files_callback_failing("tests/failing-ui-tests.txt", "ui"),
retain_files_callback("tests/failing-ui-tests.txt", "ui"),
false,
"ui",
);

Expand All @@ -1030,18 +1062,30 @@ fn test_successful_rustc(env: &Env, args: &TestArg) -> Result<(), String> {
test_rustc_inner(
env,
args,
prepare_files_callback_success("tests/failing-ui-tests.txt", "ui"),
remove_files_callback("tests/failing-ui-tests.txt", "ui"),
false,
"ui",
)?;
test_rustc_inner(
env,
args,
prepare_files_callback_success("tests/failing-run-make-tests.txt", "run-make"),
remove_files_callback("tests/failing-run-make-tests.txt", "run-make"),
false,
"run-make",
)
}

fn prepare_files_callback_failing<'a>(
fn test_failing_ui_pattern_tests(env: &Env, args: &TestArg) -> Result<(), String> {
test_rustc_inner(
env,
args,
remove_files_callback("tests/failing-ice-tests.txt", "ui"),
true,
"ui",
)
}

fn retain_files_callback<'a>(
file_path: &'a str,
test_type: &'a str,
) -> impl Fn(&Path) -> Result<bool, String> + 'a {
Expand Down Expand Up @@ -1104,7 +1148,7 @@ fn prepare_files_callback_failing<'a>(
}
}

fn prepare_files_callback_success<'a>(
fn remove_files_callback<'a>(
file_path: &'a str,
test_type: &'a str,
) -> impl Fn(&Path) -> Result<bool, String> + 'a {
Expand Down
10 changes: 9 additions & 1 deletion build_system/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,12 @@ pub fn git_clone_root_dir(
git_clone_inner(to_clone, &dest_parent_dir.join(&repo_name), shallow_clone, repo_name)
}

pub fn walk_dir<P, D, F>(dir: P, mut dir_cb: D, mut file_cb: F) -> Result<(), String>
pub fn walk_dir<P, D, F>(
dir: P,
dir_cb: &mut D,
file_cb: &mut F,
recursive: bool,
) -> Result<(), String>
where
P: AsRef<Path>,
D: FnMut(&Path) -> Result<(), String>,
Expand All @@ -358,6 +363,9 @@ where
let entry_path = entry.path();
if entry_path.is_dir() {
dir_cb(&entry_path)?;
if recursive {
walk_dir(entry_path, dir_cb, file_cb, recursive)?; // Recursive call
}
} else {
file_cb(&entry_path)?;
}
Expand Down
Loading

0 comments on commit a63b83e

Please sign in to comment.