Skip to content

Commit 01f89b0

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 6ea17d4 + 6329cb2 commit 01f89b0

File tree

4 files changed

+27
-1
lines changed

4 files changed

+27
-1
lines changed

test/src/cli.rs

Lines changed: 5 additions & 0 deletions
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)

test/src/console.rs

Lines changed: 1 addition & 1 deletion
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
}

test/src/lib.rs

Lines changed: 20 additions & 0 deletions
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

test/src/tests.rs

Lines changed: 1 addition & 0 deletions
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
}

0 commit comments

Comments
 (0)