Skip to content

Commit 1b98ba7

Browse files
authored
Unrolled build for #146501
Rollup merge of #146501 - Enselic:x-test-filter, r=Mark-Simulacrum compiletest: Fix `--exact` test filtering This fix only changes the behavior when using `--exact` test filtering, which was quite broken. Before this fix, the following runs 0 tests: $ ./x test tests/run-make/crate-loading -- --exact running 0 tests test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 431 filtered out; finished in 24.95µs With the fix the desired test is run: $ ./x test tests/run-make/crate-loading -- --exact running 1 tests test [run-make] tests/run-make/crate-loading ... ok Without `--exact` the set of run tests is unchanged. This still runs "too many" (cc #134341) tests $ ./x test tests/run-make/crate-loading running 3 tests test [run-make] tests/run-make/crate-loading-crate-depends-on-itself ... ok test [run-make] tests/run-make/crate-loading-multiple-candidates ... ok test [run-make] tests/run-make/crate-loading ... ok This still runs the one and only right test $ ./x test tests/ui/lint/unused/unused-allocation.rs running 1 tests test [ui] tests/ui/lint/unused/unused-allocation.rs ... ok ### Notes - I have not verified this on Windows which treats paths differently (but I see no reason why it should not work since my code should be platform agnostic).
2 parents 52618eb + a48c8e3 commit 1b98ba7

File tree

4 files changed

+54
-11
lines changed

4 files changed

+54
-11
lines changed

src/tools/compiletest/src/directives.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1446,6 +1446,7 @@ pub(crate) fn make_test_description<R: Read>(
14461446
cache: &DirectivesCache,
14471447
name: String,
14481448
path: &Utf8Path,
1449+
filterable_path: &Utf8Path,
14491450
src: R,
14501451
test_revision: Option<&str>,
14511452
poisoned: &mut bool,
@@ -1520,7 +1521,13 @@ pub(crate) fn make_test_description<R: Read>(
15201521
_ => ShouldPanic::No,
15211522
};
15221523

1523-
CollectedTestDesc { name, ignore, ignore_message, should_panic }
1524+
CollectedTestDesc {
1525+
name,
1526+
filterable_path: filterable_path.to_owned(),
1527+
ignore,
1528+
ignore_message,
1529+
should_panic,
1530+
}
15241531
}
15251532

15261533
fn ignore_cdb(config: &Config, line: &str) -> IgnoreDecision {

src/tools/compiletest/src/directives/tests.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ fn make_test_description<R: Read>(
1414
config: &Config,
1515
name: String,
1616
path: &Utf8Path,
17+
filterable_path: &Utf8Path,
1718
src: R,
1819
revision: Option<&str>,
1920
) -> CollectedTestDesc {
@@ -24,6 +25,7 @@ fn make_test_description<R: Read>(
2425
&cache,
2526
name,
2627
path,
28+
filterable_path,
2729
src,
2830
revision,
2931
&mut poisoned,
@@ -221,7 +223,7 @@ fn parse_rs(config: &Config, contents: &str) -> EarlyProps {
221223
fn check_ignore(config: &Config, contents: &str) -> bool {
222224
let tn = String::new();
223225
let p = Utf8Path::new("a.rs");
224-
let d = make_test_description(&config, tn, p, std::io::Cursor::new(contents), None);
226+
let d = make_test_description(&config, tn, p, p, std::io::Cursor::new(contents), None);
225227
d.ignore
226228
}
227229

@@ -231,9 +233,9 @@ fn should_fail() {
231233
let tn = String::new();
232234
let p = Utf8Path::new("a.rs");
233235

234-
let d = make_test_description(&config, tn.clone(), p, std::io::Cursor::new(""), None);
236+
let d = make_test_description(&config, tn.clone(), p, p, std::io::Cursor::new(""), None);
235237
assert_eq!(d.should_panic, ShouldPanic::No);
236-
let d = make_test_description(&config, tn, p, std::io::Cursor::new("//@ should-fail"), None);
238+
let d = make_test_description(&config, tn, p, p, std::io::Cursor::new("//@ should-fail"), None);
237239
assert_eq!(d.should_panic, ShouldPanic::Yes);
238240
}
239241

src/tools/compiletest/src/executor.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ use std::num::NonZero;
1212
use std::sync::{Arc, Mutex, mpsc};
1313
use std::{env, hint, io, mem, panic, thread};
1414

15+
use camino::Utf8PathBuf;
16+
1517
use crate::common::{Config, TestPaths};
1618
use crate::output_capture::{self, ConsoleOut};
1719
use crate::panic_hook;
@@ -293,8 +295,12 @@ fn filter_tests(opts: &Config, tests: Vec<CollectedTest>) -> Vec<CollectedTest>
293295
let mut filtered = tests;
294296

295297
let matches_filter = |test: &CollectedTest, filter_str: &str| {
296-
let test_name = &test.desc.name;
297-
if opts.filter_exact { test_name == filter_str } else { test_name.contains(filter_str) }
298+
let filterable_path = test.desc.filterable_path.as_str();
299+
if opts.filter_exact {
300+
filterable_path == filter_str
301+
} else {
302+
filterable_path.contains(filter_str)
303+
}
298304
};
299305

300306
// Remove tests that don't match the test filter
@@ -339,6 +345,7 @@ pub(crate) struct CollectedTest {
339345
/// Information that was historically needed to create a libtest `TestDesc`.
340346
pub(crate) struct CollectedTestDesc {
341347
pub(crate) name: String,
348+
pub(crate) filterable_path: Utf8PathBuf,
342349
pub(crate) ignore: bool,
343350
pub(crate) ignore_message: Option<Cow<'static, str>>,
344351
pub(crate) should_panic: ShouldPanic,

src/tools/compiletest/src/lib.rs

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -317,18 +317,30 @@ pub fn parse_config(args: Vec<String>) -> Config {
317317
.free
318318
.iter()
319319
.map(|f| {
320+
// Here `f` is relative to `./tests/run-make`. So if you run
321+
//
322+
// ./x test tests/run-make/crate-loading
323+
//
324+
// then `f` is "crate-loading".
320325
let path = Utf8Path::new(f);
321326
let mut iter = path.iter().skip(1);
322327

323-
// We skip the test folder and check if the user passed `rmake.rs`.
324328
if iter.next().is_some_and(|s| s == "rmake.rs") && iter.next().is_none() {
329+
// Strip the "rmake.rs" suffix. For example, if `f` is
330+
// "crate-loading/rmake.rs" then this gives us "crate-loading".
325331
path.parent().unwrap().to_string()
326332
} else {
327333
f.to_string()
328334
}
329335
})
330336
.collect::<Vec<_>>()
331337
} else {
338+
// Note that the filters are relative to the root dir of the different test
339+
// suites. For example, with:
340+
//
341+
// ./x test tests/ui/lint/unused
342+
//
343+
// the filter is "lint/unused".
332344
matches.free.clone()
333345
};
334346
let compare_mode = matches.opt_str("compare-mode").map(|s| {
@@ -911,7 +923,8 @@ fn make_test(cx: &TestCollectorCx, collector: &mut TestCollector, testpaths: &Te
911923
collector.tests.extend(revisions.into_iter().map(|revision| {
912924
// Create a test name and description to hand over to the executor.
913925
let src_file = fs::File::open(&test_path).expect("open test file to parse ignores");
914-
let test_name = make_test_name(&cx.config, testpaths, revision);
926+
let (test_name, filterable_path) =
927+
make_test_name_and_filterable_path(&cx.config, testpaths, revision);
915928
// Create a description struct for the test/revision.
916929
// This is where `ignore-*`/`only-*`/`needs-*` directives are handled,
917930
// because they historically needed to set the libtest ignored flag.
@@ -920,6 +933,7 @@ fn make_test(cx: &TestCollectorCx, collector: &mut TestCollector, testpaths: &Te
920933
&cx.cache,
921934
test_name,
922935
&test_path,
936+
&filterable_path,
923937
src_file,
924938
revision,
925939
&mut collector.poisoned,
@@ -1072,7 +1086,11 @@ impl Stamp {
10721086
}
10731087

10741088
/// Creates a name for this test/revision that can be handed over to the executor.
1075-
fn make_test_name(config: &Config, testpaths: &TestPaths, revision: Option<&str>) -> String {
1089+
fn make_test_name_and_filterable_path(
1090+
config: &Config,
1091+
testpaths: &TestPaths,
1092+
revision: Option<&str>,
1093+
) -> (String, Utf8PathBuf) {
10761094
// Print the name of the file, relative to the sources root.
10771095
let path = testpaths.file.strip_prefix(&config.src_root).unwrap();
10781096
let debugger = match config.debugger {
@@ -1084,14 +1102,23 @@ fn make_test_name(config: &Config, testpaths: &TestPaths, revision: Option<&str>
10841102
None => String::new(),
10851103
};
10861104

1087-
format!(
1105+
let name = format!(
10881106
"[{}{}{}] {}{}",
10891107
config.mode,
10901108
debugger,
10911109
mode_suffix,
10921110
path,
10931111
revision.map_or("".to_string(), |rev| format!("#{}", rev))
1094-
)
1112+
);
1113+
1114+
// `path` is the full path from the repo root like, `tests/ui/foo/bar.rs`.
1115+
// Filtering is applied without the `tests/ui/` part, so strip that off.
1116+
// First strip off "tests" to make sure we don't have some unexpected path.
1117+
let mut filterable_path = path.strip_prefix("tests").unwrap().to_owned();
1118+
// Now strip off e.g. "ui" or "run-make" component.
1119+
filterable_path = filterable_path.components().skip(1).collect();
1120+
1121+
(name, filterable_path)
10951122
}
10961123

10971124
/// Checks that test discovery didn't find any tests whose name stem is a prefix

0 commit comments

Comments
 (0)