Skip to content

Commit 1692d0c

Browse files
committed
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.
1 parent 2da2ade commit 1692d0c

File tree

1 file changed

+35
-2
lines changed

1 file changed

+35
-2
lines changed

src/tools/compiletest/src/main.rs

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use build_helper::git::{get_git_modified_files, get_git_untracked_files};
1212
use core::panic;
1313
use getopts::Options;
1414
use lazycell::LazyCell;
15+
use std::collections::BTreeSet;
1516
use std::ffi::OsString;
1617
use std::fs;
1718
use std::io::{self, ErrorKind};
@@ -406,7 +407,9 @@ pub fn run_tests(config: Config) {
406407

407408
let mut tests = Vec::new();
408409
for c in &configs {
409-
make_tests(c, &mut tests);
410+
let mut found_paths = BTreeSet::new();
411+
make_tests(c, &mut tests, &mut found_paths);
412+
check_overlapping_tests(&found_paths);
410413
}
411414

412415
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 {
528531
}
529532
}
530533

531-
pub fn make_tests(config: &Config, tests: &mut Vec<test::TestDescAndFn>) {
534+
pub fn make_tests(
535+
config: &Config,
536+
tests: &mut Vec<test::TestDescAndFn>,
537+
found_paths: &mut BTreeSet<PathBuf>,
538+
) {
532539
debug!("making tests from {:?}", config.src_base.display());
533540
let inputs = common_inputs_stamp(config);
534541
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<test::TestDescAndFn>) {
540547
&PathBuf::new(),
541548
&inputs,
542549
tests,
550+
found_paths,
543551
&modified_tests,
544552
)
545553
.unwrap_or_else(|_| panic!("Could not read tests from {}", config.src_base.display()));
@@ -610,6 +618,7 @@ fn collect_tests_from_dir(
610618
relative_dir_path: &Path,
611619
inputs: &Stamp,
612620
tests: &mut Vec<test::TestDescAndFn>,
621+
found_paths: &mut BTreeSet<PathBuf>,
613622
modified_tests: &Vec<PathBuf>,
614623
) -> io::Result<()> {
615624
// Ignore directories that contain a file named `compiletest-ignore-dir`.
@@ -643,6 +652,8 @@ fn collect_tests_from_dir(
643652
let file_name = file.file_name();
644653
if is_test(&file_name) && (!config.only_modified || modified_tests.contains(&file_path)) {
645654
debug!("found test file: {:?}", file_path.display());
655+
let rel_test_path = relative_dir_path.join(file_path.file_stem().unwrap());
656+
found_paths.insert(rel_test_path);
646657
let paths =
647658
TestPaths { file: file_path, relative_dir: relative_dir_path.to_path_buf() };
648659

@@ -657,6 +668,7 @@ fn collect_tests_from_dir(
657668
&relative_file_path,
658669
inputs,
659670
tests,
671+
found_paths,
660672
modified_tests,
661673
)?;
662674
}
@@ -1072,3 +1084,24 @@ fn extract_lldb_version(full_version_line: &str) -> Option<(u32, bool)> {
10721084
fn not_a_digit(c: char) -> bool {
10731085
!c.is_digit(10)
10741086
}
1087+
1088+
fn check_overlapping_tests(found_paths: &BTreeSet<PathBuf>) {
1089+
let mut collisions = Vec::new();
1090+
for path in found_paths {
1091+
for ancestor in path.ancestors().skip(1) {
1092+
if found_paths.contains(ancestor) {
1093+
collisions.push((path, ancestor.clone()));
1094+
}
1095+
}
1096+
}
1097+
if !collisions.is_empty() {
1098+
let collisions: String = collisions
1099+
.into_iter()
1100+
.map(|(path, check_parent)| format!("test {path:?} clashes with {check_parent:?}\n"))
1101+
.collect();
1102+
panic!(
1103+
"{collisions}\n\
1104+
Tests cannot have overlapping names. Make sure they use unique prefixes."
1105+
);
1106+
}
1107+
}

0 commit comments

Comments
 (0)