Skip to content

Commit 6f0a2ad

Browse files
authored
Rollup merge of #105153 - oli-obk:fail_faster, r=compiler-errors
Create a hacky fail-fast mode that stops tests at the first failure This is useful for not having to wait until all 10k+ ui tests have finished running and then having to crawl through hundreds of failure reports. You now only get the first report when you turn on that env var and no new tests are run at all This works like a charm, but is obviously welded on very crudely
2 parents 1a2f79b + e590258 commit 6f0a2ad

File tree

5 files changed

+28
-1
lines changed

5 files changed

+28
-1
lines changed

library/test/src/cli.rs

+5
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ pub struct TestOpts {
2626
pub test_threads: Option<usize>,
2727
pub skip: Vec<String>,
2828
pub time_options: Option<TestTimeOptions>,
29+
/// Stop at first failing test.
30+
/// May run a few more tests due to threading, but will
31+
/// abort as soon as possible.
32+
pub fail_fast: bool,
2933
pub options: Options,
3034
}
3135

@@ -296,6 +300,7 @@ fn parse_opts_impl(matches: getopts::Matches) -> OptRes {
296300
skip,
297301
time_options,
298302
options,
303+
fail_fast: false,
299304
};
300305

301306
Ok(test_opts)

library/test/src/console.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@ pub fn run_tests_console(opts: &TestOpts, tests: Vec<TestDescAndFn>) -> io::Resu
293293
run_tests(opts, tests, |x| on_test_event(&x, &mut st, &mut *out))?;
294294
st.exec_time = start_time.map(|t| TestSuiteExecTime(t.elapsed()));
295295

296-
assert!(st.current_test_count() == st.total);
296+
assert!(opts.fail_fast || st.current_test_count() == st.total);
297297

298298
out.write_run_finish(&st)
299299
}

library/test/src/lib.rs

+20
Original file line numberDiff line numberDiff line change
@@ -384,8 +384,17 @@ where
384384
let mut completed_test = rx.recv().unwrap();
385385
RunningTest { join_handle }.join(&mut completed_test);
386386

387+
let fail_fast = match completed_test.result {
388+
TrIgnored | TrOk | TrBench(_) => false,
389+
TrFailed | TrFailedMsg(_) | TrTimedFail => opts.fail_fast,
390+
};
391+
387392
let event = TestEvent::TeResult(completed_test);
388393
notify_about_test_event(event)?;
394+
395+
if fail_fast {
396+
return Ok(());
397+
}
389398
}
390399
} else {
391400
while pending > 0 || !remaining.is_empty() {
@@ -431,9 +440,20 @@ where
431440
let running_test = running_tests.remove(&completed_test.id).unwrap();
432441
running_test.join(&mut completed_test);
433442

443+
let fail_fast = match completed_test.result {
444+
TrIgnored | TrOk | TrBench(_) => false,
445+
TrFailed | TrFailedMsg(_) | TrTimedFail => opts.fail_fast,
446+
};
447+
434448
let event = TestEvent::TeResult(completed_test);
435449
notify_about_test_event(event)?;
436450
pending -= 1;
451+
452+
if fail_fast {
453+
// Prevent remaining test threads from panicking
454+
std::mem::forget(rx);
455+
return Ok(());
456+
}
437457
}
438458
}
439459

library/test/src/tests.rs

+1
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ impl TestOpts {
5151
skip: vec![],
5252
time_options: None,
5353
options: Options::new(),
54+
fail_fast: false,
5455
}
5556
}
5657
}

src/tools/compiletest/src/main.rs

+1
Original file line numberDiff line numberDiff line change
@@ -514,6 +514,7 @@ pub fn test_opts(config: &Config) -> test::TestOpts {
514514
options: test::Options::new(),
515515
time_options: None,
516516
force_run_in_process: false,
517+
fail_fast: std::env::var_os("RUSTC_TEST_FAIL_FAST").is_some(),
517518
}
518519
}
519520

0 commit comments

Comments
 (0)