Skip to content

Commit

Permalink
libtest: allow multiple filters
Browse files Browse the repository at this point in the history
  • Loading branch information
ehuss committed Jan 24, 2021
1 parent 9a9477f commit 30891b8
Show file tree
Hide file tree
Showing 7 changed files with 63 additions and 27 deletions.
17 changes: 6 additions & 11 deletions library/test/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use super::time::TestTimeOptions;
#[derive(Debug)]
pub struct TestOpts {
pub list: bool,
pub filter: Option<String>,
pub filters: Vec<String>,
pub filter_exact: bool,
pub force_run_in_process: bool,
pub exclude_should_panic: bool,
Expand Down Expand Up @@ -148,12 +148,13 @@ fn optgroups() -> getopts::Options {
}

fn usage(binary: &str, options: &getopts::Options) {
let message = format!("Usage: {} [OPTIONS] [FILTER]", binary);
let message = format!("Usage: {} [OPTIONS] [FILTERS...]", binary);
println!(
r#"{usage}
The FILTER string is tested against the name of all tests, and only those
tests whose names contain the filter are run.
tests whose names contain the filter are run. Multiple filter strings may
be passed, which will run all tests matching any of the filters.
By default, all tests are run in parallel. This can be altered with the
--test-threads flag or the RUST_TEST_THREADS environment variable when running
Expand Down Expand Up @@ -243,7 +244,7 @@ fn parse_opts_impl(matches: getopts::Matches) -> OptRes {

let logfile = get_log_file(&matches)?;
let run_ignored = get_run_ignored(&matches, include_ignored)?;
let filter = get_filter(&matches)?;
let filters = matches.free.clone();
let nocapture = get_nocapture(&matches)?;
let test_threads = get_test_threads(&matches)?;
let color = get_color_config(&matches)?;
Expand All @@ -253,7 +254,7 @@ fn parse_opts_impl(matches: getopts::Matches) -> OptRes {

let test_opts = TestOpts {
list,
filter,
filters,
filter_exact: exact,
force_run_in_process,
exclude_should_panic,
Expand Down Expand Up @@ -397,12 +398,6 @@ fn get_run_ignored(matches: &getopts::Matches, include_ignored: bool) -> OptPart
Ok(run_ignored)
}

fn get_filter(matches: &getopts::Matches) -> OptPartRes<Option<String>> {
let filter = if !matches.free.is_empty() { Some(matches.free[0].clone()) } else { None };

Ok(filter)
}

fn get_allow_unstable(matches: &getopts::Matches) -> OptPartRes<bool> {
let mut allow_unstable = false;

Expand Down
4 changes: 2 additions & 2 deletions library/test/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -359,8 +359,8 @@ pub fn filter_tests(opts: &TestOpts, tests: Vec<TestDescAndFn>) -> Vec<TestDescA
};

// Remove tests that don't match the test filter
if let Some(ref filter) = opts.filter {
filtered.retain(|test| matches_filter(test, filter));
if !opts.filters.is_empty() {
filtered.retain(|test| opts.filters.iter().any(|filter| matches_filter(test, filter)));
}

// Skip tests that match any of the skip filters
Expand Down
35 changes: 26 additions & 9 deletions library/test/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ impl TestOpts {
fn new() -> TestOpts {
TestOpts {
list: false,
filter: None,
filters: vec![],
filter_exact: false,
force_run_in_process: false,
exclude_should_panic: false,
Expand Down Expand Up @@ -469,43 +469,60 @@ pub fn exact_filter_match() {
}

let substr =
filter_tests(&TestOpts { filter: Some("base".into()), ..TestOpts::new() }, tests());
filter_tests(&TestOpts { filters: vec!["base".into()], ..TestOpts::new() }, tests());
assert_eq!(substr.len(), 4);

let substr = filter_tests(&TestOpts { filter: Some("bas".into()), ..TestOpts::new() }, tests());
let substr =
filter_tests(&TestOpts { filters: vec!["bas".into()], ..TestOpts::new() }, tests());
assert_eq!(substr.len(), 4);

let substr =
filter_tests(&TestOpts { filter: Some("::test".into()), ..TestOpts::new() }, tests());
filter_tests(&TestOpts { filters: vec!["::test".into()], ..TestOpts::new() }, tests());
assert_eq!(substr.len(), 3);

let substr =
filter_tests(&TestOpts { filter: Some("base::test".into()), ..TestOpts::new() }, tests());
filter_tests(&TestOpts { filters: vec!["base::test".into()], ..TestOpts::new() }, tests());
assert_eq!(substr.len(), 3);

let substr = filter_tests(
&TestOpts { filters: vec!["test1".into(), "test2".into()], ..TestOpts::new() },
tests(),
);
assert_eq!(substr.len(), 2);

let exact = filter_tests(
&TestOpts { filter: Some("base".into()), filter_exact: true, ..TestOpts::new() },
&TestOpts { filters: vec!["base".into()], filter_exact: true, ..TestOpts::new() },
tests(),
);
assert_eq!(exact.len(), 1);

let exact = filter_tests(
&TestOpts { filter: Some("bas".into()), filter_exact: true, ..TestOpts::new() },
&TestOpts { filters: vec!["bas".into()], filter_exact: true, ..TestOpts::new() },
tests(),
);
assert_eq!(exact.len(), 0);

let exact = filter_tests(
&TestOpts { filter: Some("::test".into()), filter_exact: true, ..TestOpts::new() },
&TestOpts { filters: vec!["::test".into()], filter_exact: true, ..TestOpts::new() },
tests(),
);
assert_eq!(exact.len(), 0);

let exact = filter_tests(
&TestOpts { filter: Some("base::test".into()), filter_exact: true, ..TestOpts::new() },
&TestOpts { filters: vec!["base::test".into()], filter_exact: true, ..TestOpts::new() },
tests(),
);
assert_eq!(exact.len(), 1);

let exact = filter_tests(
&TestOpts {
filters: vec!["base".into(), "base::test".into()],
filter_exact: true,
..TestOpts::new()
},
tests(),
);
assert_eq!(exact.len(), 2);
}

#[test]
Expand Down
17 changes: 17 additions & 0 deletions src/test/ui/test-attrs/test-filter-multiple.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// run-pass
// compile-flags: --test
// run-flags: --test-threads=1 test1 test2
// check-run-results
// normalize-stdout-test "finished in \d+\.\d+s" -> "finished in $$TIME"
// ignore-emscripten no threads support

#[test]
fn test1() {}

#[test]
fn test2() {}

#[test]
fn test3() {
panic!("this should not run");
}
7 changes: 7 additions & 0 deletions src/test/ui/test-attrs/test-filter-multiple.run.stdout
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@

running 2 tests
test test1 ... ok
test test2 ... ok

test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 1 filtered out; finished in $TIME

4 changes: 2 additions & 2 deletions src/tools/compiletest/src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -240,8 +240,8 @@ pub struct Config {
/// Run ignored tests
pub run_ignored: bool,

/// Only run tests that match this filter
pub filter: Option<String>,
/// Only run tests that match these filters
pub filters: Vec<String>,

/// Exactly match the filter, rather than a substring
pub filter_exact: bool,
Expand Down
6 changes: 3 additions & 3 deletions src/tools/compiletest/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ pub fn parse_config(args: Vec<String>) -> Config {
suite: matches.opt_str("suite").unwrap(),
debugger: None,
run_ignored,
filter: matches.free.first().cloned(),
filters: matches.free.clone(),
filter_exact: matches.opt_present("exact"),
force_pass_mode: matches.opt_str("pass").map(|mode| {
mode.parse::<PassMode>()
Expand Down Expand Up @@ -280,7 +280,7 @@ pub fn log_config(config: &Config) {
logv(c, format!("stage_id: {}", config.stage_id));
logv(c, format!("mode: {}", config.mode));
logv(c, format!("run_ignored: {}", config.run_ignored));
logv(c, format!("filter: {}", opt_str(&config.filter)));
logv(c, format!("filters: {:?}", config.filters));
logv(c, format!("filter_exact: {}", config.filter_exact));
logv(
c,
Expand Down Expand Up @@ -465,7 +465,7 @@ fn configure_lldb(config: &Config) -> Option<Config> {
pub fn test_opts(config: &Config) -> test::TestOpts {
test::TestOpts {
exclude_should_panic: false,
filter: config.filter.clone(),
filters: config.filters.clone(),
filter_exact: config.filter_exact,
run_ignored: if config.run_ignored { test::RunIgnored::Yes } else { test::RunIgnored::No },
format: if config.quiet { test::OutputFormat::Terse } else { test::OutputFormat::Pretty },
Expand Down

0 comments on commit 30891b8

Please sign in to comment.