From 2da2ade0f7b289cd2d670fa6c77f50b3559ede2b Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Wed, 22 Mar 2023 21:12:40 -0700 Subject: [PATCH 1/2] Rename tests to ensure they don't have overlapping names. Some tests will delete their output directory before starting. The output directory is based on the test names. If one test is the prefix of another test, then when that test starts, it could try to delete the output directory of the other test with the longer path. --- tests/rustdoc/{ => primitive}/primitive.rs | 0 .../ui/impl-trait/{ => multiple-lifetimes}/multiple-lifetimes.rs | 0 .../mod_file_disambig_aux/compiletest-ignore-dir | 0 .../non_modrs_mods_and_inline_mods/x/y/z/compiletest-ignore-dir | 0 tests/ui/use/{ => use-mod}/use-mod.rs | 0 tests/ui/use/{ => use-mod}/use-mod.stderr | 0 tests/ui/{ => use}/use.rs | 0 7 files changed, 0 insertions(+), 0 deletions(-) rename tests/rustdoc/{ => primitive}/primitive.rs (100%) rename tests/ui/impl-trait/{ => multiple-lifetimes}/multiple-lifetimes.rs (100%) create mode 100644 tests/ui/modules_and_files_visibility/mod_file_disambig_aux/compiletest-ignore-dir create mode 100644 tests/ui/non_modrs_mods_and_inline_mods/x/y/z/compiletest-ignore-dir rename tests/ui/use/{ => use-mod}/use-mod.rs (100%) rename tests/ui/use/{ => use-mod}/use-mod.stderr (100%) rename tests/ui/{ => use}/use.rs (100%) diff --git a/tests/rustdoc/primitive.rs b/tests/rustdoc/primitive/primitive.rs similarity index 100% rename from tests/rustdoc/primitive.rs rename to tests/rustdoc/primitive/primitive.rs diff --git a/tests/ui/impl-trait/multiple-lifetimes.rs b/tests/ui/impl-trait/multiple-lifetimes/multiple-lifetimes.rs similarity index 100% rename from tests/ui/impl-trait/multiple-lifetimes.rs rename to tests/ui/impl-trait/multiple-lifetimes/multiple-lifetimes.rs diff --git a/tests/ui/modules_and_files_visibility/mod_file_disambig_aux/compiletest-ignore-dir b/tests/ui/modules_and_files_visibility/mod_file_disambig_aux/compiletest-ignore-dir new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/ui/non_modrs_mods_and_inline_mods/x/y/z/compiletest-ignore-dir b/tests/ui/non_modrs_mods_and_inline_mods/x/y/z/compiletest-ignore-dir new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/ui/use/use-mod.rs b/tests/ui/use/use-mod/use-mod.rs similarity index 100% rename from tests/ui/use/use-mod.rs rename to tests/ui/use/use-mod/use-mod.rs diff --git a/tests/ui/use/use-mod.stderr b/tests/ui/use/use-mod/use-mod.stderr similarity index 100% rename from tests/ui/use/use-mod.stderr rename to tests/ui/use/use-mod/use-mod.stderr diff --git a/tests/ui/use.rs b/tests/ui/use/use.rs similarity index 100% rename from tests/ui/use.rs rename to tests/ui/use/use.rs From 1692d0c142985a01a2770da8654912dc40342412 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Wed, 22 Mar 2023 21:13:27 -0700 Subject: [PATCH 2/2] Add a check to ensure tests with overlapping prefixes aren't added. Some tests will delete their output directory before starting. The output directory is based on the test names. If one test is the prefix of another test, then when that test starts, it could try to delete the output directory of the other test with the longer path. --- src/tools/compiletest/src/main.rs | 37 +++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs index cbaa599f793..c4d9bb6cec6 100644 --- a/src/tools/compiletest/src/main.rs +++ b/src/tools/compiletest/src/main.rs @@ -12,6 +12,7 @@ use build_helper::git::{get_git_modified_files, get_git_untracked_files}; use core::panic; use getopts::Options; use lazycell::LazyCell; +use std::collections::BTreeSet; use std::ffi::OsString; use std::fs; use std::io::{self, ErrorKind}; @@ -406,7 +407,9 @@ pub fn run_tests(config: Config) { let mut tests = Vec::new(); for c in &configs { - make_tests(c, &mut tests); + let mut found_paths = BTreeSet::new(); + make_tests(c, &mut tests, &mut found_paths); + check_overlapping_tests(&found_paths); } tests.sort_by(|a, b| a.desc.name.as_slice().cmp(&b.desc.name.as_slice())); @@ -528,7 +531,11 @@ pub fn test_opts(config: &Config) -> test::TestOpts { } } -pub fn make_tests(config: &Config, tests: &mut Vec) { +pub fn make_tests( + config: &Config, + tests: &mut Vec, + found_paths: &mut BTreeSet, +) { debug!("making tests from {:?}", config.src_base.display()); let inputs = common_inputs_stamp(config); let modified_tests = modified_tests(config, &config.src_base).unwrap_or_else(|err| { @@ -540,6 +547,7 @@ pub fn make_tests(config: &Config, tests: &mut Vec) { &PathBuf::new(), &inputs, tests, + found_paths, &modified_tests, ) .unwrap_or_else(|_| panic!("Could not read tests from {}", config.src_base.display())); @@ -610,6 +618,7 @@ fn collect_tests_from_dir( relative_dir_path: &Path, inputs: &Stamp, tests: &mut Vec, + found_paths: &mut BTreeSet, modified_tests: &Vec, ) -> io::Result<()> { // Ignore directories that contain a file named `compiletest-ignore-dir`. @@ -643,6 +652,8 @@ fn collect_tests_from_dir( let file_name = file.file_name(); if is_test(&file_name) && (!config.only_modified || modified_tests.contains(&file_path)) { debug!("found test file: {:?}", file_path.display()); + let rel_test_path = relative_dir_path.join(file_path.file_stem().unwrap()); + found_paths.insert(rel_test_path); let paths = TestPaths { file: file_path, relative_dir: relative_dir_path.to_path_buf() }; @@ -657,6 +668,7 @@ fn collect_tests_from_dir( &relative_file_path, inputs, tests, + found_paths, modified_tests, )?; } @@ -1072,3 +1084,24 @@ fn extract_lldb_version(full_version_line: &str) -> Option<(u32, bool)> { fn not_a_digit(c: char) -> bool { !c.is_digit(10) } + +fn check_overlapping_tests(found_paths: &BTreeSet) { + let mut collisions = Vec::new(); + for path in found_paths { + for ancestor in path.ancestors().skip(1) { + if found_paths.contains(ancestor) { + collisions.push((path, ancestor.clone())); + } + } + } + if !collisions.is_empty() { + let collisions: String = collisions + .into_iter() + .map(|(path, check_parent)| format!("test {path:?} clashes with {check_parent:?}\n")) + .collect(); + panic!( + "{collisions}\n\ + Tests cannot have overlapping names. Make sure they use unique prefixes." + ); + } +}