compiletest/runtest/
incremental.rs1use std::sync::LazyLock;
2
3use crate::runtest::{Emit, TestCx, WillExecute};
4use crate::util::string_enum;
5
6string_enum!(
7 #[derive(Clone, Copy, PartialEq, Eq)]
11 enum IncrRevKind {
12 CheckPass => "cpass",
13 BuildFail => "bfail",
14 BuildPass => "bpass",
15 RunPass => "rpass",
16 }
17);
18
19impl IncrRevKind {
20 fn for_revision_name(rev_name: &str) -> Result<Self, &'static str> {
21 static MESSAGE: LazyLock<String> = LazyLock::new(|| {
22 let values = IncrRevKind::STR_VARIANTS
23 .iter()
24 .map(|s| format!("`{s}`"))
25 .collect::<Vec<_>>()
26 .join(", ");
27 format!("incremental revision name must begin with one of: {values}")
28 });
29
30 IncrRevKind::VARIANTS
31 .iter()
32 .copied()
33 .find(|kind| rev_name.starts_with(kind.to_str()))
34 .ok_or_else(|| MESSAGE.as_str())
35 }
36}
37
38impl TestCx<'_> {
39 pub(super) fn run_incremental_test(&self) {
41 let revision = self.revision.expect("incremental tests require a list of revisions");
42
43 let incremental_dir = self.props.incremental_dir.as_ref().unwrap();
45 assert!(incremental_dir.exists(), "init_incremental_test failed to create incremental dir");
46
47 if self.config.verbose {
48 write!(self.stdout, "revision={:?} props={:#?}", revision, self.props);
49 }
50
51 let rev_kind = IncrRevKind::for_revision_name(revision).unwrap_or_else(|e| self.fatal(e));
54
55 let emit = match rev_kind {
57 IncrRevKind::CheckPass => Emit::Metadata, IncrRevKind::BuildFail | IncrRevKind::BuildPass | IncrRevKind::RunPass => Emit::None,
59 };
60 let will_execute = match rev_kind {
61 IncrRevKind::CheckPass | IncrRevKind::BuildFail | IncrRevKind::BuildPass => {
62 WillExecute::No
63 }
64 IncrRevKind::RunPass => {
65 self.run_if_enabled()
67 }
68 };
69 let proc_res = &self.compile_test(will_execute, emit);
70
71 match rev_kind {
73 IncrRevKind::CheckPass | IncrRevKind::BuildPass | IncrRevKind::RunPass => {
74 if !proc_res.status.success() {
76 self.fatal_proc_rec("test compilation failed although it shouldn't!", proc_res);
77 }
78 }
79
80 IncrRevKind::BuildFail => {
81 if proc_res.status.success() {
83 self.fatal_proc_rec("incremental test did not emit an error", proc_res);
84 }
85 if !self.props.dont_check_failure_status {
86 self.check_correct_failure_status(proc_res);
87 }
88 }
89 }
90
91 let output_to_check = self.get_output(proc_res);
93 self.check_expected_errors(&proc_res);
94 self.check_all_error_patterns(&output_to_check, proc_res);
95 self.check_forbid_output(&output_to_check, proc_res);
96
97 match rev_kind {
99 IncrRevKind::CheckPass | IncrRevKind::BuildFail | IncrRevKind::BuildPass => {}
100 IncrRevKind::RunPass => {
101 if self.config.run_enabled() {
102 let run_proc_res = self.exec_compiled_test();
103 if !run_proc_res.status.success() {
104 self.fatal_proc_rec("test run failed!", &run_proc_res);
105 }
106 }
107 }
108 }
109 }
110}