Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion src/tools/compiletest/src/directives.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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 {
Expand Down
8 changes: 5 additions & 3 deletions src/tools/compiletest/src/directives/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -24,6 +25,7 @@ fn make_test_description<R: Read>(
&cache,
name,
path,
filterable_path,
src,
revision,
&mut poisoned,
Expand Down Expand Up @@ -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
}

Expand All @@ -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);
}

Expand Down
11 changes: 9 additions & 2 deletions src/tools/compiletest/src/executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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,
Expand Down
37 changes: 32 additions & 5 deletions src/tools/compiletest/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -317,18 +317,30 @@ 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()
}
})
.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| {
Expand Down Expand Up @@ -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.
Expand All @@ -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,
Expand Down Expand Up @@ -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 {
Expand All @@ -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
Expand Down
Loading