Skip to main content

compiletest/runtest/
incremental.rs

1use super::{FailMode, 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("bpass") {
35            self.run_bpass_test();
36        } else if revision.starts_with("rpass") {
37            self.run_rpass_test();
38        } else if revision.starts_with("bfail") {
39            self.run_bfail_test();
40        } else {
41            self.fatal("revision name must begin with `bfail`, `bpass`, or `rpass`");
42        }
43    }
44
45    fn run_bpass_test(&self) {
46        let emit_metadata = self.should_emit_metadata(self.pass_mode());
47        let proc_res = self.compile_test(WillExecute::No, emit_metadata);
48
49        if !proc_res.status.success() {
50            self.fatal_proc_rec("compilation failed!", &proc_res);
51        }
52
53        self.check_compiler_output_for_incr(&proc_res);
54    }
55
56    fn run_rpass_test(&self) {
57        let emit_metadata = self.should_emit_metadata(self.pass_mode());
58        let should_run = self.run_if_enabled();
59        let proc_res = self.compile_test(should_run, emit_metadata);
60
61        if !proc_res.status.success() {
62            self.fatal_proc_rec("compilation failed!", &proc_res);
63        }
64
65        self.check_compiler_output_for_incr(&proc_res);
66
67        if let WillExecute::Disabled = should_run {
68            return;
69        }
70
71        let proc_res = self.exec_compiled_test();
72        if !proc_res.status.success() {
73            self.fatal_proc_rec("test run failed!", &proc_res);
74        }
75    }
76
77    fn run_bfail_test(&self) {
78        let pm = self.pass_mode();
79        let proc_res = self.compile_test(WillExecute::No, self.should_emit_metadata(pm));
80        self.check_if_test_should_compile(Some(FailMode::Build), pm, &proc_res);
81        self.check_compiler_output_for_incr(&proc_res);
82    }
83
84    fn check_compiler_output_for_incr(&self, proc_res: &ProcRes) {
85        let output_to_check = self.get_output(proc_res);
86        self.check_expected_errors(&proc_res);
87        self.check_all_error_patterns(&output_to_check, proc_res);
88        self.check_forbid_output(&output_to_check, proc_res);
89    }
90}