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
This commit is contained in:
Matthias Krüger 2022-12-03 17:37:42 +01:00 committed by GitHub
commit 6f0a2adf6e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 28 additions and 1 deletions

View File

@ -26,6 +26,10 @@ pub struct TestOpts {
pub test_threads: Option<usize>,
pub skip: Vec<String>,
pub time_options: Option<TestTimeOptions>,
/// Stop at first failing test.
/// May run a few more tests due to threading, but will
/// abort as soon as possible.
pub fail_fast: bool,
pub options: Options,
}
@ -296,6 +300,7 @@ fn parse_opts_impl(matches: getopts::Matches) -> OptRes {
skip,
time_options,
options,
fail_fast: false,
};
Ok(test_opts)

View File

@ -293,7 +293,7 @@ pub fn run_tests_console(opts: &TestOpts, tests: Vec<TestDescAndFn>) -> io::Resu
run_tests(opts, tests, |x| on_test_event(&x, &mut st, &mut *out))?;
st.exec_time = start_time.map(|t| TestSuiteExecTime(t.elapsed()));
assert!(st.current_test_count() == st.total);
assert!(opts.fail_fast || st.current_test_count() == st.total);
out.write_run_finish(&st)
}

View File

@ -384,8 +384,17 @@ where
let mut completed_test = rx.recv().unwrap();
RunningTest { join_handle }.join(&mut completed_test);
let fail_fast = match completed_test.result {
TrIgnored | TrOk | TrBench(_) => false,
TrFailed | TrFailedMsg(_) | TrTimedFail => opts.fail_fast,
};
let event = TestEvent::TeResult(completed_test);
notify_about_test_event(event)?;
if fail_fast {
return Ok(());
}
}
} else {
while pending > 0 || !remaining.is_empty() {
@ -431,9 +440,20 @@ where
let running_test = running_tests.remove(&completed_test.id).unwrap();
running_test.join(&mut completed_test);
let fail_fast = match completed_test.result {
TrIgnored | TrOk | TrBench(_) => false,
TrFailed | TrFailedMsg(_) | TrTimedFail => opts.fail_fast,
};
let event = TestEvent::TeResult(completed_test);
notify_about_test_event(event)?;
pending -= 1;
if fail_fast {
// Prevent remaining test threads from panicking
std::mem::forget(rx);
return Ok(());
}
}
}

View File

@ -51,6 +51,7 @@ impl TestOpts {
skip: vec![],
time_options: None,
options: Options::new(),
fail_fast: false,
}
}
}

View File

@ -514,6 +514,7 @@ pub fn test_opts(config: &Config) -> test::TestOpts {
options: test::Options::new(),
time_options: None,
force_run_in_process: false,
fail_fast: std::env::var_os("RUSTC_TEST_FAIL_FAST").is_some(),
}
}