Skip to content

Commit b102ea4

Browse files
authored
Rollup merge of #81356 - ehuss:libtest-filters, r=m-ou-se
libtest: allow multiple filters Libtest ignores any filters after the first. This changes it so that if multiple filters are passed, it will test against all of them. This also affects compiletest to do the same. Closes #30422
2 parents 35ebbe3 + 30891b8 commit b102ea4

File tree

7 files changed

+63
-27
lines changed

7 files changed

+63
-27
lines changed

library/test/src/cli.rs

+6-11
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use super::time::TestTimeOptions;
1010
#[derive(Debug)]
1111
pub struct TestOpts {
1212
pub list: bool,
13-
pub filter: Option<String>,
13+
pub filters: Vec<String>,
1414
pub filter_exact: bool,
1515
pub force_run_in_process: bool,
1616
pub exclude_should_panic: bool,
@@ -148,12 +148,13 @@ fn optgroups() -> getopts::Options {
148148
}
149149

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

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

254255
let test_opts = TestOpts {
255256
list,
256-
filter,
257+
filters,
257258
filter_exact: exact,
258259
force_run_in_process,
259260
exclude_should_panic,
@@ -397,12 +398,6 @@ fn get_run_ignored(matches: &getopts::Matches, include_ignored: bool) -> OptPart
397398
Ok(run_ignored)
398399
}
399400

400-
fn get_filter(matches: &getopts::Matches) -> OptPartRes<Option<String>> {
401-
let filter = if !matches.free.is_empty() { Some(matches.free[0].clone()) } else { None };
402-
403-
Ok(filter)
404-
}
405-
406401
fn get_allow_unstable(matches: &getopts::Matches) -> OptPartRes<bool> {
407402
let mut allow_unstable = false;
408403

library/test/src/lib.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -396,8 +396,8 @@ pub fn filter_tests(opts: &TestOpts, tests: Vec<TestDescAndFn>) -> Vec<TestDescA
396396
};
397397

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

403403
// Skip tests that match any of the skip filters

library/test/src/tests.rs

+26-9
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ impl TestOpts {
3434
fn new() -> TestOpts {
3535
TestOpts {
3636
list: false,
37-
filter: None,
37+
filters: vec![],
3838
filter_exact: false,
3939
force_run_in_process: false,
4040
exclude_should_panic: false,
@@ -473,43 +473,60 @@ pub fn exact_filter_match() {
473473
}
474474

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

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

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

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

491+
let substr = filter_tests(
492+
&TestOpts { filters: vec!["test1".into(), "test2".into()], ..TestOpts::new() },
493+
tests(),
494+
);
495+
assert_eq!(substr.len(), 2);
496+
490497
let exact = filter_tests(
491-
&TestOpts { filter: Some("base".into()), filter_exact: true, ..TestOpts::new() },
498+
&TestOpts { filters: vec!["base".into()], filter_exact: true, ..TestOpts::new() },
492499
tests(),
493500
);
494501
assert_eq!(exact.len(), 1);
495502

496503
let exact = filter_tests(
497-
&TestOpts { filter: Some("bas".into()), filter_exact: true, ..TestOpts::new() },
504+
&TestOpts { filters: vec!["bas".into()], filter_exact: true, ..TestOpts::new() },
498505
tests(),
499506
);
500507
assert_eq!(exact.len(), 0);
501508

502509
let exact = filter_tests(
503-
&TestOpts { filter: Some("::test".into()), filter_exact: true, ..TestOpts::new() },
510+
&TestOpts { filters: vec!["::test".into()], filter_exact: true, ..TestOpts::new() },
504511
tests(),
505512
);
506513
assert_eq!(exact.len(), 0);
507514

508515
let exact = filter_tests(
509-
&TestOpts { filter: Some("base::test".into()), filter_exact: true, ..TestOpts::new() },
516+
&TestOpts { filters: vec!["base::test".into()], filter_exact: true, ..TestOpts::new() },
510517
tests(),
511518
);
512519
assert_eq!(exact.len(), 1);
520+
521+
let exact = filter_tests(
522+
&TestOpts {
523+
filters: vec!["base".into(), "base::test".into()],
524+
filter_exact: true,
525+
..TestOpts::new()
526+
},
527+
tests(),
528+
);
529+
assert_eq!(exact.len(), 2);
513530
}
514531

515532
#[test]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// run-pass
2+
// compile-flags: --test
3+
// run-flags: --test-threads=1 test1 test2
4+
// check-run-results
5+
// normalize-stdout-test "finished in \d+\.\d+s" -> "finished in $$TIME"
6+
// ignore-emscripten no threads support
7+
8+
#[test]
9+
fn test1() {}
10+
11+
#[test]
12+
fn test2() {}
13+
14+
#[test]
15+
fn test3() {
16+
panic!("this should not run");
17+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
2+
running 2 tests
3+
test test1 ... ok
4+
test test2 ... ok
5+
6+
test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 1 filtered out; finished in $TIME
7+

src/tools/compiletest/src/common.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -240,8 +240,8 @@ pub struct Config {
240240
/// Run ignored tests
241241
pub run_ignored: bool,
242242

243-
/// Only run tests that match this filter
244-
pub filter: Option<String>,
243+
/// Only run tests that match these filters
244+
pub filters: Vec<String>,
245245

246246
/// Exactly match the filter, rather than a substring
247247
pub filter_exact: bool,

src/tools/compiletest/src/main.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ pub fn parse_config(args: Vec<String>) -> Config {
221221
suite: matches.opt_str("suite").unwrap(),
222222
debugger: None,
223223
run_ignored,
224-
filter: matches.free.first().cloned(),
224+
filters: matches.free.clone(),
225225
filter_exact: matches.opt_present("exact"),
226226
force_pass_mode: matches.opt_str("pass").map(|mode| {
227227
mode.parse::<PassMode>()
@@ -280,7 +280,7 @@ pub fn log_config(config: &Config) {
280280
logv(c, format!("stage_id: {}", config.stage_id));
281281
logv(c, format!("mode: {}", config.mode));
282282
logv(c, format!("run_ignored: {}", config.run_ignored));
283-
logv(c, format!("filter: {}", opt_str(&config.filter)));
283+
logv(c, format!("filters: {:?}", config.filters));
284284
logv(c, format!("filter_exact: {}", config.filter_exact));
285285
logv(
286286
c,
@@ -465,7 +465,7 @@ fn configure_lldb(config: &Config) -> Option<Config> {
465465
pub fn test_opts(config: &Config) -> test::TestOpts {
466466
test::TestOpts {
467467
exclude_should_panic: false,
468-
filter: config.filter.clone(),
468+
filters: config.filters.clone(),
469469
filter_exact: config.filter_exact,
470470
run_ignored: if config.run_ignored { test::RunIgnored::Yes } else { test::RunIgnored::No },
471471
format: if config.quiet { test::OutputFormat::Terse } else { test::OutputFormat::Pretty },

0 commit comments

Comments
 (0)