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" 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
This commit is contained in:
parent
7ad23f43a2
commit
a48c8e337d
4 changed files with 54 additions and 11 deletions
|
|
@ -1446,6 +1446,7 @@ pub(crate) fn make_test_description<R: Read>(
|
|||
cache: &DirectivesCache,
|
||||
name: String,
|
||||
path: &Utf8Path,
|
||||
filterable_path: &Utf8Path,
|
||||
src: R,
|
||||
test_revision: Option<&str>,
|
||||
poisoned: &mut bool,
|
||||
|
|
@ -1520,7 +1521,13 @@ pub(crate) fn make_test_description<R: Read>(
|
|||
_ => ShouldPanic::No,
|
||||
};
|
||||
|
||||
CollectedTestDesc { name, ignore, ignore_message, should_panic }
|
||||
CollectedTestDesc {
|
||||
name,
|
||||
filterable_path: filterable_path.to_owned(),
|
||||
ignore,
|
||||
ignore_message,
|
||||
should_panic,
|
||||
}
|
||||
}
|
||||
|
||||
fn ignore_cdb(config: &Config, line: &str) -> IgnoreDecision {
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ fn make_test_description<R: Read>(
|
|||
config: &Config,
|
||||
name: String,
|
||||
path: &Utf8Path,
|
||||
filterable_path: &Utf8Path,
|
||||
src: R,
|
||||
revision: Option<&str>,
|
||||
) -> CollectedTestDesc {
|
||||
|
|
@ -24,6 +25,7 @@ fn make_test_description<R: Read>(
|
|||
&cache,
|
||||
name,
|
||||
path,
|
||||
filterable_path,
|
||||
src,
|
||||
revision,
|
||||
&mut poisoned,
|
||||
|
|
@ -221,7 +223,7 @@ fn parse_rs(config: &Config, contents: &str) -> EarlyProps {
|
|||
fn check_ignore(config: &Config, contents: &str) -> bool {
|
||||
let tn = String::new();
|
||||
let p = Utf8Path::new("a.rs");
|
||||
let d = make_test_description(&config, tn, p, std::io::Cursor::new(contents), None);
|
||||
let d = make_test_description(&config, tn, p, p, std::io::Cursor::new(contents), None);
|
||||
d.ignore
|
||||
}
|
||||
|
||||
|
|
@ -231,9 +233,9 @@ fn should_fail() {
|
|||
let tn = String::new();
|
||||
let p = Utf8Path::new("a.rs");
|
||||
|
||||
let d = make_test_description(&config, tn.clone(), p, std::io::Cursor::new(""), None);
|
||||
let d = make_test_description(&config, tn.clone(), p, p, std::io::Cursor::new(""), None);
|
||||
assert_eq!(d.should_panic, ShouldPanic::No);
|
||||
let d = make_test_description(&config, tn, p, std::io::Cursor::new("//@ should-fail"), None);
|
||||
let d = make_test_description(&config, tn, p, p, std::io::Cursor::new("//@ should-fail"), None);
|
||||
assert_eq!(d.should_panic, ShouldPanic::Yes);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@ use std::num::NonZero;
|
|||
use std::sync::{Arc, Mutex, mpsc};
|
||||
use std::{env, hint, io, mem, panic, thread};
|
||||
|
||||
use camino::Utf8PathBuf;
|
||||
|
||||
use crate::common::{Config, TestPaths};
|
||||
use crate::output_capture::{self, ConsoleOut};
|
||||
use crate::panic_hook;
|
||||
|
|
@ -293,8 +295,12 @@ fn filter_tests(opts: &Config, tests: Vec<CollectedTest>) -> Vec<CollectedTest>
|
|||
let mut filtered = tests;
|
||||
|
||||
let matches_filter = |test: &CollectedTest, filter_str: &str| {
|
||||
let test_name = &test.desc.name;
|
||||
if opts.filter_exact { test_name == filter_str } else { test_name.contains(filter_str) }
|
||||
let filterable_path = test.desc.filterable_path.as_str();
|
||||
if opts.filter_exact {
|
||||
filterable_path == filter_str
|
||||
} else {
|
||||
filterable_path.contains(filter_str)
|
||||
}
|
||||
};
|
||||
|
||||
// Remove tests that don't match the test filter
|
||||
|
|
@ -339,6 +345,7 @@ pub(crate) struct CollectedTest {
|
|||
/// Information that was historically needed to create a libtest `TestDesc`.
|
||||
pub(crate) struct CollectedTestDesc {
|
||||
pub(crate) name: String,
|
||||
pub(crate) filterable_path: Utf8PathBuf,
|
||||
pub(crate) ignore: bool,
|
||||
pub(crate) ignore_message: Option<Cow<'static, str>>,
|
||||
pub(crate) should_panic: ShouldPanic,
|
||||
|
|
|
|||
|
|
@ -317,11 +317,17 @@ pub fn parse_config(args: Vec<String>) -> Config {
|
|||
.free
|
||||
.iter()
|
||||
.map(|f| {
|
||||
// Here `f` is relative to `./tests/run-make`. So if you run
|
||||
//
|
||||
// ./x test tests/run-make/crate-loading
|
||||
//
|
||||
// then `f` is "crate-loading".
|
||||
let path = Utf8Path::new(f);
|
||||
let mut iter = path.iter().skip(1);
|
||||
|
||||
// We skip the test folder and check if the user passed `rmake.rs`.
|
||||
if iter.next().is_some_and(|s| s == "rmake.rs") && iter.next().is_none() {
|
||||
// Strip the "rmake.rs" suffix. For example, if `f` is
|
||||
// "crate-loading/rmake.rs" then this gives us "crate-loading".
|
||||
path.parent().unwrap().to_string()
|
||||
} else {
|
||||
f.to_string()
|
||||
|
|
@ -329,6 +335,12 @@ pub fn parse_config(args: Vec<String>) -> Config {
|
|||
})
|
||||
.collect::<Vec<_>>()
|
||||
} else {
|
||||
// Note that the filters are relative to the root dir of the different test
|
||||
// suites. For example, with:
|
||||
//
|
||||
// ./x test tests/ui/lint/unused
|
||||
//
|
||||
// the filter is "lint/unused".
|
||||
matches.free.clone()
|
||||
};
|
||||
let compare_mode = matches.opt_str("compare-mode").map(|s| {
|
||||
|
|
@ -911,7 +923,8 @@ fn make_test(cx: &TestCollectorCx, collector: &mut TestCollector, testpaths: &Te
|
|||
collector.tests.extend(revisions.into_iter().map(|revision| {
|
||||
// Create a test name and description to hand over to the executor.
|
||||
let src_file = fs::File::open(&test_path).expect("open test file to parse ignores");
|
||||
let test_name = make_test_name(&cx.config, testpaths, revision);
|
||||
let (test_name, filterable_path) =
|
||||
make_test_name_and_filterable_path(&cx.config, testpaths, revision);
|
||||
// Create a description struct for the test/revision.
|
||||
// This is where `ignore-*`/`only-*`/`needs-*` directives are handled,
|
||||
// because they historically needed to set the libtest ignored flag.
|
||||
|
|
@ -920,6 +933,7 @@ fn make_test(cx: &TestCollectorCx, collector: &mut TestCollector, testpaths: &Te
|
|||
&cx.cache,
|
||||
test_name,
|
||||
&test_path,
|
||||
&filterable_path,
|
||||
src_file,
|
||||
revision,
|
||||
&mut collector.poisoned,
|
||||
|
|
@ -1072,7 +1086,11 @@ impl Stamp {
|
|||
}
|
||||
|
||||
/// Creates a name for this test/revision that can be handed over to the executor.
|
||||
fn make_test_name(config: &Config, testpaths: &TestPaths, revision: Option<&str>) -> String {
|
||||
fn make_test_name_and_filterable_path(
|
||||
config: &Config,
|
||||
testpaths: &TestPaths,
|
||||
revision: Option<&str>,
|
||||
) -> (String, Utf8PathBuf) {
|
||||
// Print the name of the file, relative to the sources root.
|
||||
let path = testpaths.file.strip_prefix(&config.src_root).unwrap();
|
||||
let debugger = match config.debugger {
|
||||
|
|
@ -1084,14 +1102,23 @@ fn make_test_name(config: &Config, testpaths: &TestPaths, revision: Option<&str>
|
|||
None => String::new(),
|
||||
};
|
||||
|
||||
format!(
|
||||
let name = format!(
|
||||
"[{}{}{}] {}{}",
|
||||
config.mode,
|
||||
debugger,
|
||||
mode_suffix,
|
||||
path,
|
||||
revision.map_or("".to_string(), |rev| format!("#{}", rev))
|
||||
)
|
||||
);
|
||||
|
||||
// `path` is the full path from the repo root like, `tests/ui/foo/bar.rs`.
|
||||
// Filtering is applied without the `tests/ui/` part, so strip that off.
|
||||
// First strip off "tests" to make sure we don't have some unexpected path.
|
||||
let mut filterable_path = path.strip_prefix("tests").unwrap().to_owned();
|
||||
// Now strip off e.g. "ui" or "run-make" component.
|
||||
filterable_path = filterable_path.components().skip(1).collect();
|
||||
|
||||
(name, filterable_path)
|
||||
}
|
||||
|
||||
/// Checks that test discovery didn't find any tests whose name stem is a prefix
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue