bootstrap/compiletest: implement "crashes" tests that fail if no ice is reproduced

This commit is contained in:
Matthias Krüger 2024-03-24 12:57:54 +01:00
parent 65ca71815a
commit 7b05360a1e
8 changed files with 36 additions and 6 deletions

View File

@ -1400,6 +1400,8 @@ fn run(self, builder: &Builder<'_>) -> PathBuf {
default_test!(Ui { path: "tests/ui", mode: "ui", suite: "ui" }); default_test!(Ui { path: "tests/ui", mode: "ui", suite: "ui" });
default_test!(Crashes { path: "tests/crashes", mode: "crashes", suite: "crashes" });
default_test!(RunPassValgrind { default_test!(RunPassValgrind {
path: "tests/run-pass-valgrind", path: "tests/run-pass-valgrind",
mode: "run-pass-valgrind", mode: "run-pass-valgrind",

View File

@ -745,6 +745,7 @@ macro_rules! describe {
test::ExpandYamlAnchors, test::ExpandYamlAnchors,
test::Tidy, test::Tidy,
test::Ui, test::Ui,
test::Crashes,
test::RunPassValgrind, test::RunPassValgrind,
test::Coverage, test::Coverage,
test::CoverageMap, test::CoverageMap,

View File

@ -69,6 +69,7 @@ pub enum Mode {
Assembly => "assembly", Assembly => "assembly",
CoverageMap => "coverage-map", CoverageMap => "coverage-map",
CoverageRun => "coverage-run", CoverageRun => "coverage-run",
Crashes => "crashes",
} }
} }

View File

@ -625,6 +625,7 @@ fn update_fail_mode(&mut self, ln: &str, config: &Config) {
fn update_pass_mode(&mut self, ln: &str, revision: Option<&str>, config: &Config) { fn update_pass_mode(&mut self, ln: &str, revision: Option<&str>, config: &Config) {
let check_no_run = |s| match (config.mode, s) { let check_no_run = |s| match (config.mode, s) {
(Mode::Ui, _) => (), (Mode::Ui, _) => (),
(Mode::Crashes, "should-ice") => (),
(Mode::Codegen, "build-pass") => (), (Mode::Codegen, "build-pass") => (),
(Mode::Incremental, _) => { (Mode::Incremental, _) => {
if revision.is_some() && !self.revisions.iter().all(|r| r.starts_with("cfail")) { if revision.is_some() && !self.revisions.iter().all(|r| r.starts_with("cfail")) {

View File

@ -65,7 +65,8 @@ pub fn parse_config(args: Vec<String>) -> Config {
"mode", "mode",
"which sort of compile tests to run", "which sort of compile tests to run",
"run-pass-valgrind | pretty | debug-info | codegen | rustdoc \ "run-pass-valgrind | pretty | debug-info | codegen | rustdoc \
| rustdoc-json | codegen-units | incremental | run-make | ui | js-doc-test | mir-opt | assembly", | rustdoc-json | codegen-units | incremental | run-make | ui \
| js-doc-test | mir-opt | assembly | crashes",
) )
.reqopt( .reqopt(
"", "",
@ -82,7 +83,12 @@ pub fn parse_config(args: Vec<String>) -> Config {
.optopt("", "run", "whether to execute run-* tests", "auto | always | never") .optopt("", "run", "whether to execute run-* tests", "auto | always | never")
.optflag("", "ignored", "run tests marked as ignored") .optflag("", "ignored", "run tests marked as ignored")
.optflag("", "with-debug-assertions", "whether to run tests with `ignore-debug` header") .optflag("", "with-debug-assertions", "whether to run tests with `ignore-debug` header")
.optmulti("", "skip", "skip tests matching SUBSTRING. Can be passed multiple times", "SUBSTRING") .optmulti(
"",
"skip",
"skip tests matching SUBSTRING. Can be passed multiple times",
"SUBSTRING",
)
.optflag("", "exact", "filters match exactly") .optflag("", "exact", "filters match exactly")
.optopt( .optopt(
"", "",
@ -145,7 +151,11 @@ pub fn parse_config(args: Vec<String>) -> Config {
.optflag("", "profiler-support", "is the profiler runtime enabled for this target") .optflag("", "profiler-support", "is the profiler runtime enabled for this target")
.optflag("h", "help", "show this message") .optflag("h", "help", "show this message")
.reqopt("", "channel", "current Rust channel", "CHANNEL") .reqopt("", "channel", "current Rust channel", "CHANNEL")
.optflag("", "git-hash", "run tests which rely on commit version being compiled into the binaries") .optflag(
"",
"git-hash",
"run tests which rely on commit version being compiled into the binaries",
)
.optopt("", "edition", "default Rust edition", "EDITION") .optopt("", "edition", "default Rust edition", "EDITION")
.reqopt("", "git-repository", "name of the git repository", "ORG/REPO") .reqopt("", "git-repository", "name of the git repository", "ORG/REPO")
.reqopt("", "nightly-branch", "name of the git branch for nightly", "BRANCH"); .reqopt("", "nightly-branch", "name of the git branch for nightly", "BRANCH");

View File

@ -4,7 +4,7 @@
expected_output_path, UI_EXTENSIONS, UI_FIXED, UI_STDERR, UI_STDOUT, UI_SVG, UI_WINDOWS_SVG, expected_output_path, UI_EXTENSIONS, UI_FIXED, UI_STDERR, UI_STDOUT, UI_SVG, UI_WINDOWS_SVG,
}; };
use crate::common::{incremental_dir, output_base_dir, output_base_name, output_testname_unique}; use crate::common::{incremental_dir, output_base_dir, output_base_name, output_testname_unique};
use crate::common::{Assembly, Incremental, JsDocTest, MirOpt, RunMake, RustdocJson, Ui}; use crate::common::{Assembly, Crashes, Incremental, JsDocTest, MirOpt, RunMake, RustdocJson, Ui};
use crate::common::{Codegen, CodegenUnits, DebugInfo, Debugger, Rustdoc}; use crate::common::{Codegen, CodegenUnits, DebugInfo, Debugger, Rustdoc};
use crate::common::{CompareMode, FailMode, PassMode}; use crate::common::{CompareMode, FailMode, PassMode};
use crate::common::{Config, TestPaths}; use crate::common::{Config, TestPaths};
@ -244,7 +244,7 @@ impl<'test> TestCx<'test> {
/// Code executed for each revision in turn (or, if there are no /// Code executed for each revision in turn (or, if there are no
/// revisions, exactly once, with revision == None). /// revisions, exactly once, with revision == None).
fn run_revision(&self) { fn run_revision(&self) {
if self.props.should_ice && self.config.mode != Incremental { if self.props.should_ice && self.config.mode != Incremental && self.config.mode != Crashes {
self.fatal("cannot use should-ice in a test that is not cfail"); self.fatal("cannot use should-ice in a test that is not cfail");
} }
match self.config.mode { match self.config.mode {
@ -263,6 +263,7 @@ fn run_revision(&self) {
JsDocTest => self.run_js_doc_test(), JsDocTest => self.run_js_doc_test(),
CoverageMap => self.run_coverage_map_test(), CoverageMap => self.run_coverage_map_test(),
CoverageRun => self.run_coverage_run_test(), CoverageRun => self.run_coverage_run_test(),
Crashes => self.run_crash_test(),
} }
} }
@ -295,6 +296,7 @@ fn should_compile_successfully(&self, pm: Option<PassMode>) -> bool {
match self.config.mode { match self.config.mode {
JsDocTest => true, JsDocTest => true,
Ui => pm.is_some() || self.props.fail_mode > Some(FailMode::Build), Ui => pm.is_some() || self.props.fail_mode > Some(FailMode::Build),
Crashes => false,
Incremental => { Incremental => {
let revision = let revision =
self.revision.expect("incremental tests require a list of revisions"); self.revision.expect("incremental tests require a list of revisions");
@ -359,6 +361,17 @@ fn run_cfail_test(&self) {
self.check_forbid_output(&output_to_check, &proc_res); self.check_forbid_output(&output_to_check, &proc_res);
} }
fn run_crash_test(&self) {
let pm = self.pass_mode();
let proc_res = self.compile_test(WillExecute::No, self.should_emit_metadata(pm));
// if a test does not crash, consider it an error
match proc_res.status.code() {
Some(101) => (),
_ => self.fatal("expected ICE"),
}
}
fn run_rfail_test(&self) { fn run_rfail_test(&self) {
let pm = self.pass_mode(); let pm = self.pass_mode();
let should_run = self.run_if_enabled(); let should_run = self.run_if_enabled();
@ -2517,7 +2530,7 @@ fn make_compile_args(
rustc.arg("-Cdebug-assertions=no"); rustc.arg("-Cdebug-assertions=no");
} }
RunPassValgrind | Pretty | DebugInfo | Rustdoc | RustdocJson | RunMake RunPassValgrind | Pretty | DebugInfo | Rustdoc | RustdocJson | RunMake
| CodegenUnits | JsDocTest => { | CodegenUnits | JsDocTest | Crashes => {
// do not use JSON output // do not use JSON output
} }
} }

View File

@ -96,6 +96,7 @@ pub fn run_tests(env: &Environment) -> anyhow::Result<()> {
"tests/pretty", "tests/pretty",
"tests/run-pass-valgrind", "tests/run-pass-valgrind",
"tests/ui", "tests/ui",
"tests/crases",
]; ];
for test_path in env.skipped_tests() { for test_path in env.skipped_tests() {
args.extend(["--skip", test_path]); args.extend(["--skip", test_path]);

1
tests/crashes/no-ice.rs Normal file
View File

@ -0,0 +1 @@
pub fn main() {}