Skip to content

Commit 85b884b

Browse files
committed
Auto merge of #122997 - matthiaskrgr:compiletest_ices, r=oli-obk
compiletest ice tracking see https://rust-lang.zulipchat.com/#narrow/stream/131828-t-compiler/topic/where.20to.20mass-add.20known.20ices.20.2F.20merging.20glacier.20into.20rust/near/429082963 This will allow us to sunset most of https://github.com/rust-lang/glacier The rustc ices will be tracked directly inside the rust testsuite There are a couple of .sh tests remaining that I have not ported over yet. This adds `tests/crashes`, a file inside this directory MUST ice, otherwise it is considered test-fail. This will be used to track ICEs from glacier and the bugtracker. When someones pr accidentally fixes one of these ICEs, they can move the test from `crashes` into `ui` for example. I also added a new tidy lint that warns when a test inside `tests/crashes` does not have a `//@ known-bug: ` line the env var `COMPILETEST_VERBOSE_CRASHES` can be set to get exit code, stderr and stdout of a crash-test to aid debugging/adding tests.
2 parents 9db7a74 + 2ce487c commit 85b884b

172 files changed

Lines changed: 3362 additions & 7 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎src/bootstrap/src/core/build_steps/test.rs‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1400,6 +1400,8 @@ impl Step for RunMakeSupport {
14001400

14011401
default_test!(Ui{ path:"tests/ui", mode:"ui", suite:"ui"});
14021402

1403+
default_test!(Crashes{ path:"tests/crashes", mode:"crashes", suite:"crashes"});
1404+
14031405
default_test!(RunPassValgrind{
14041406
path:"tests/run-pass-valgrind",
14051407
mode:"run-pass-valgrind",

‎src/bootstrap/src/core/builder.rs‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -745,6 +745,7 @@ impl<'a> Builder<'a> {
745745
test::ExpandYamlAnchors,
746746
test::Tidy,
747747
test::Ui,
748+
test::Crashes,
748749
test::RunPassValgrind,
749750
test::Coverage,
750751
test::CoverageMap,

‎src/tools/compiletest/src/common.rs‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ string_enum! {
6969
Assembly => "assembly",
7070
CoverageMap => "coverage-map",
7171
CoverageRun => "coverage-run",
72+
Crashes => "crashes",
7273
}
7374
}
7475

‎src/tools/compiletest/src/header.rs‎

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -581,6 +581,16 @@ impl TestProps {
581581
self.incremental = true;
582582
}
583583

584+
if config.mode == Mode::Crashes{
585+
// we don't want to pollute anything with backtrace-files
586+
// also turn off backtraces in order to save some execution
587+
// time on the tests; we only need to know IF it crashes
588+
self.rustc_env = vec![
589+
("RUST_BACKTRACE".to_string(),"0".to_string()),
590+
("RUSTC_ICE".to_string(),"0".to_string()),
591+
];
592+
}
593+
584594
for key in&["RUST_TEST_NOCAPTURE","RUST_TEST_THREADS"]{
585595
ifletOk(val) = env::var(key){
586596
ifself.exec_env.iter().find(|&&(ref x, _)| x == key).is_none(){
@@ -596,7 +606,8 @@ impl TestProps {
596606

597607
fnupdate_fail_mode(&mutself,ln:&str,config:&Config){
598608
let check_ui = |mode:&str| {
599-
if config.mode != Mode::Ui{
609+
// Mode::Crashes may need build-fail in order to trigger llvm errors or stack overflows
610+
if config.mode != Mode::Ui && config.mode != Mode::Crashes{
600611
panic!("`{}-fail` header is only supported in UI tests", mode);
601612
}
602613
};
@@ -625,6 +636,7 @@ impl TestProps {
625636
fnupdate_pass_mode(&mutself,ln:&str,revision:Option<&str>,config:&Config){
626637
let check_no_run = |s| match(config.mode, s){
627638
(Mode::Ui, _) => (),
639+
(Mode::Crashes, _) => (),
628640
(Mode::Codegen,"build-pass") => (),
629641
(Mode::Incremental, _) => {
630642
if revision.is_some() && !self.revisions.iter().all(|r| r.starts_with("cfail")){
@@ -757,6 +769,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[
757769
"ignore-mode-codegen-units",
758770
"ignore-mode-coverage-map",
759771
"ignore-mode-coverage-run",
772+
"ignore-mode-crashes",
760773
"ignore-mode-debuginfo",
761774
"ignore-mode-incremental",
762775
"ignore-mode-js-doc-test",

‎src/tools/compiletest/src/lib.rs‎

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,8 @@ pub fn parse_config(args: Vec<String>) -> Config {
6565
"mode",
6666
"which sort of compile tests to run",
6767
"run-pass-valgrind | pretty | debug-info | codegen | rustdoc \
68-
| rustdoc-json | codegen-units | incremental | run-make | ui | js-doc-test | mir-opt | assembly",
68+
| rustdoc-json | codegen-units | incremental | run-make | ui \
69+
| js-doc-test | mir-opt | assembly | crashes",
6970
)
7071
.reqopt(
7172
"",
@@ -82,7 +83,12 @@ pub fn parse_config(args: Vec<String>) -> Config {
8283
.optopt("","run","whether to execute run-* tests","auto | always | never")
8384
.optflag("","ignored","run tests marked as ignored")
8485
.optflag("","with-debug-assertions","whether to run tests with `ignore-debug` header")
85-
.optmulti("","skip","skip tests matching SUBSTRING. Can be passed multiple times","SUBSTRING")
86+
.optmulti(
87+
"",
88+
"skip",
89+
"skip tests matching SUBSTRING. Can be passed multiple times",
90+
"SUBSTRING",
91+
)
8692
.optflag("","exact","filters match exactly")
8793
.optopt(
8894
"",
@@ -145,7 +151,11 @@ pub fn parse_config(args: Vec<String>) -> Config {
145151
.optflag("","profiler-support","is the profiler runtime enabled for this target")
146152
.optflag("h","help","show this message")
147153
.reqopt("","channel","current Rust channel","CHANNEL")
148-
.optflag("","git-hash","run tests which rely on commit version being compiled into the binaries")
154+
.optflag(
155+
"",
156+
"git-hash",
157+
"run tests which rely on commit version being compiled into the binaries",
158+
)
149159
.optopt("","edition","default Rust edition","EDITION")
150160
.reqopt("","git-repository","name of the git repository","ORG/REPO")
151161
.reqopt("","nightly-branch","name of the git branch for nightly","BRANCH");

‎src/tools/compiletest/src/runtest.rs‎

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use crate::common::{
44
expected_output_path,UI_EXTENSIONS,UI_FIXED,UI_STDERR,UI_STDOUT,UI_SVG,UI_WINDOWS_SVG,
55
};
66
usecrate::common::{incremental_dir, output_base_dir, output_base_name, output_testname_unique};
7-
usecrate::common::{Assembly,Incremental,JsDocTest,MirOpt,RunMake,RustdocJson,Ui};
7+
usecrate::common::{Assembly,Crashes,Incremental,JsDocTest,MirOpt,RunMake,RustdocJson,Ui};
88
usecrate::common::{Codegen,CodegenUnits,DebugInfo,Debugger,Rustdoc};
99
usecrate::common::{CompareMode,FailMode,PassMode};
1010
usecrate::common::{Config,TestPaths};
@@ -244,7 +244,7 @@ impl<'test> TestCx<'test> {
244244
/// Code executed for each revision in turn (or, if there are no
245245
/// revisions, exactly once, with revision == None).
246246
fnrun_revision(&self){
247-
ifself.props.should_ice && self.config.mode != Incremental{
247+
ifself.props.should_ice && self.config.mode != Incremental&& self.config.mode != Crashes{
248248
self.fatal("cannot use should-ice in a test that is not cfail");
249249
}
250250
matchself.config.mode{
@@ -263,6 +263,7 @@ impl<'test> TestCx<'test> {
263263
JsDocTest => self.run_js_doc_test(),
264264
CoverageMap => self.run_coverage_map_test(),
265265
CoverageRun => self.run_coverage_run_test(),
266+
Crashes => self.run_crash_test(),
266267
}
267268
}
268269

@@ -295,6 +296,7 @@ impl<'test> TestCx<'test> {
295296
matchself.config.mode{
296297
JsDocTest => true,
297298
Ui => pm.is_some() || self.props.fail_mode > Some(FailMode::Build),
299+
Crashes => false,
298300
Incremental => {
299301
let revision =
300302
self.revision.expect("incremental tests require a list of revisions");
@@ -359,6 +361,27 @@ impl<'test> TestCx<'test> {
359361
self.check_forbid_output(&output_to_check,&proc_res);
360362
}
361363

364+
fnrun_crash_test(&self){
365+
let pm = self.pass_mode();
366+
let proc_res = self.compile_test(WillExecute::No,self.should_emit_metadata(pm));
367+
368+
if std::env::var("COMPILETEST_VERBOSE_CRASHES").is_ok(){
369+
eprintln!("{}", proc_res.status);
370+
eprintln!("{}", proc_res.stdout);
371+
eprintln!("{}", proc_res.stderr);
372+
eprintln!("{}", proc_res.cmdline);
373+
}
374+
375+
// if a test does not crash, consider it an error
376+
if proc_res.status.success() || matches!(proc_res.status.code(),Some(1 | 0)){
377+
self.fatal(&format!(
378+
"test no longer crashes/triggers ICE! Please give it a mearningful name, \
379+
add a doc-comment to the start of the test explaining why it exists and \
380+
move it to tests/ui or wherever you see fit."
381+
));
382+
}
383+
}
384+
362385
fnrun_rfail_test(&self){
363386
let pm = self.pass_mode();
364387
let should_run = self.run_if_enabled();
@@ -2517,7 +2540,7 @@ impl<'test> TestCx<'test> {
25172540
rustc.arg("-Cdebug-assertions=no");
25182541
}
25192542
RunPassValgrind | Pretty | DebugInfo | Rustdoc | RustdocJson | RunMake
2520-
| CodegenUnits | JsDocTest => {
2543+
| CodegenUnits | JsDocTest| Crashes=> {
25212544
// do not use JSON output
25222545
}
25232546
}

‎src/tools/opt-dist/src/tests.rs‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ llvm-config = "{llvm_config}"
9696
"tests/pretty",
9797
"tests/run-pass-valgrind",
9898
"tests/ui",
99+
"tests/crashes",
99100
];
100101
for test_path in env.skipped_tests(){
101102
args.extend(["--skip", test_path]);

‎src/tools/tidy/src/known_bug.rs‎

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
//! Tidy check to ensure that tests inside 'tests/crashes' have a '@known-bug' directive.
2+
3+
usecrate::walk::*;
4+
use std::path::Path;
5+
6+
pubfncheck(filepath:&Path,bad:&mutbool){
7+
walk(filepath, |path, _is_dir| filter_not_rust(path),&mut |entry, contents| {
8+
let file = entry.path();
9+
if !contents.lines().any(|line| line.starts_with("//@ known-bug: ")){
10+
tidy_error!(
11+
bad,
12+
"{} crash/ice test does not have a \"//@ known-bug: \" directive",
13+
file.display()
14+
);
15+
}
16+
});
17+
}

‎src/tools/tidy/src/lib.rs‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ pub mod features;
6767
pubmod fluent_alphabetical;
6868
mod fluent_used;
6969
pub(crate)mod iter_header;
70+
pubmod known_bug;
7071
pubmod mir_opt_tests;
7172
pubmod pal;
7273
pubmod run_make_tests;

‎src/tools/tidy/src/main.rs‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ fn main() {
3535
let library_path = root_path.join("library");
3636
let compiler_path = root_path.join("compiler");
3737
let librustdoc_path = src_path.join("librustdoc");
38+
let crashes_path = tests_path.join("crashes");
3839

3940
let args:Vec<String> = env::args().skip(1).collect();
4041
let(cfg_args, pos_args) = match args.iter().position(|arg| arg == "--"){
@@ -108,6 +109,7 @@ fn main() {
108109
check!(mir_opt_tests,&tests_path, bless);
109110
check!(rustdoc_gui_tests,&tests_path);
110111
check!(rustdoc_css_themes,&librustdoc_path);
112+
check!(known_bug,&crashes_path);
111113

112114
// Checks that only make sense for the compiler.
113115
check!(error_codes,&root_path,&[&compiler_path,&librustdoc_path], verbose);

0 commit comments

Comments
 (0)