Skip to main content

compiletest/runtest/
incremental.rs

1use super::{Emit, FailMode, PassMode, ProcRes, TestCx, WillExecute};
2
3impl TestCx<'_> {
4    pub(super) fn run_incremental_test(&self) {
5        // Basic plan for a test incremental/foo/bar.rs:
6        // - load list of revisions rpass1, bfail2, rpass3
7        //   - each should begin with `bfail`, `bpass`, or `rpass`
8        //   - if `bfail`, expect compilation to fail
9        //   - if `bpass`, expect compilation to succeed, don't execute
10        //   - if `rpass`, expect compilation and execution to succeed
11        // - create a directory build/foo/bar.incremental
12        // - compile foo/bar.rs with -C incremental=.../foo/bar.incremental and -C rpass1
13        //   - because name of revision starts with "rpass", expect success
14        // - compile foo/bar.rs with -C incremental=.../foo/bar.incremental and -C bfail2
15        //   - because name of revision starts with "bfail", expect an error
16        //   - load expected errors as usual, but filter for those with `[bfail2]`
17        // - compile foo/bar.rs with -C incremental=.../foo/bar.incremental and -C rpass3
18        //   - because name of revision starts with "rpass", expect success
19        // - execute build/foo/bar.exe and save output
20        //
21        // FIXME -- use non-incremental mode as an oracle? That doesn't apply
22        // to #[rustc_clean] tests I guess
23
24        let revision = self.revision.expect("incremental tests require a list of revisions");
25
26        // Incremental workproduct directory should have already been created.
27        let incremental_dir = self.props.incremental_dir.as_ref().unwrap();
28        assert!(incremental_dir.exists(), "init_incremental_test failed to create incremental dir");
29
30        if self.config.verbose {
31            write!(self.stdout, "revision={:?} props={:#?}", revision, self.props);
32        }
33
34        if revision.starts_with("cpass") {
35            self.run_cpass_test();
36        } else if revision.starts_with("bpass") {
37            self.run_bpass_test();
38        } else if revision.starts_with("rpass") {
39            self.run_rpass_test();
40        } else if revision.starts_with("bfail") {
41            self.run_bfail_test();
42        } else {
43            self.fatal("revision name must begin with `bfail`, `bpass`, or `rpass`");
44        }
45    }
46
47    fn run_cpass_test(&self) {
48        let proc_res = self.compile_test(WillExecute::No, Emit::Metadata);
49        self.check_if_test_should_compile(None, Some(PassMode::Check), &proc_res);
50        self.check_compiler_output_for_incr(&proc_res);
51    }
52
53    fn run_bpass_test(&self) {
54        let emit_metadata = self.should_emit_metadata(self.pass_mode());
55        let proc_res = self.compile_test(WillExecute::No, emit_metadata);
56
57        if !proc_res.status.success() {
58            self.fatal_proc_rec("compilation failed!", &proc_res);
59        }
60
61        self.check_compiler_output_for_incr(&proc_res);
62    }
63
64    fn run_rpass_test(&self) {
65        let emit_metadata = self.should_emit_metadata(self.pass_mode());
66        let should_run = self.run_if_enabled();
67        let proc_res = self.compile_test(should_run, emit_metadata);
68
69        if !proc_res.status.success() {
70            self.fatal_proc_rec("compilation failed!", &proc_res);
71        }
72
73        self.check_compiler_output_for_incr(&proc_res);
74
75        if let WillExecute::Disabled = should_run {
76            return;
77        }
78
79        let proc_res = self.exec_compiled_test();
80        if !proc_res.status.success() {
81            self.fatal_proc_rec("test run failed!", &proc_res);
82        }
83    }
84
85    fn run_bfail_test(&self) {
86        let pm = self.pass_mode();
87        let proc_res = self.compile_test(WillExecute::No, self.should_emit_metadata(pm));
88        self.check_if_test_should_compile(Some(FailMode::Build), pm, &proc_res);
89        self.check_compiler_output_for_incr(&proc_res);
90    }
91
92    fn check_compiler_output_for_incr(&self, proc_res: &ProcRes) {
93        let output_to_check = self.get_output(proc_res);
94        self.check_expected_errors(&proc_res);
95        self.check_all_error_patterns(&output_to_check, proc_res);
96        self.check_forbid_output(&output_to_check, proc_res);
97    }
98}