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 =
42 self.variant.revision().expect("incremental tests require a list of revisions");
43
44 let incremental_dir = self.props.incremental_dir.as_ref().unwrap();
46 assert!(incremental_dir.exists(), "init_incremental_test failed to create incremental dir");
47
48 if self.config.verbose {
49 write!(self.stdout, "revision={:?} props={:#?}", revision, self.props);
50 }
51
52 let rev_kind = IncrRevKind::for_revision_name(revision).unwrap_or_else(|e| self.fatal(e));
55
56 let emit = match rev_kind {
58 IncrRevKind::CheckPass => Emit::Metadata, IncrRevKind::BuildFail | IncrRevKind::BuildPass | IncrRevKind::RunPass => Emit::None,
60 };
61 let will_execute = match rev_kind {
62 IncrRevKind::CheckPass | IncrRevKind::BuildFail | IncrRevKind::BuildPass => {
63 WillExecute::No
64 }
65 IncrRevKind::RunPass => {
66 self.run_if_enabled()
68 }
69 };
70 let proc_res = &self.compile_test(will_execute, emit);
71
72 match rev_kind {
74 IncrRevKind::CheckPass | IncrRevKind::BuildPass | IncrRevKind::RunPass => {
75 if !proc_res.status.success() {
77 self.fatal_proc_rec("test compilation failed although it shouldn't!", proc_res);
78 }
79 }
80
81 IncrRevKind::BuildFail => {
82 if proc_res.status.success() {
84 self.fatal_proc_rec("incremental test did not emit an error", proc_res);
85 }
86 if !self.props.dont_check_failure_status {
87 self.check_correct_failure_status(proc_res);
88 }
89 }
90 }
91
92 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 match rev_kind {
100 IncrRevKind::CheckPass | IncrRevKind::BuildFail | IncrRevKind::BuildPass => {}
101 IncrRevKind::RunPass => {
102 if self.config.run_enabled() {
103 let run_proc_res = self.exec_compiled_test();
104 if !run_proc_res.status.success() {
105 self.fatal_proc_rec("test run failed!", &run_proc_res);
106 }
107 }
108 }
109 }
110 }
111}