1use crate::receipt::Receipt;
6use std::path::Path;
7use std::process::Command;
8use time::format_description::well_known::Rfc3339;
9use time::OffsetDateTime;
10
11pub fn run_check(
15 repo: &Path,
16 reference: &str,
17 platform: &str,
18 green_exit_code: i32,
19) -> Result<Receipt, String> {
20 let commit = crate::capture::resolve_sha(repo, &None)?;
21 let ran_at = OffsetDateTime::now_utc()
22 .format(&Rfc3339)
23 .map_err(|e| format!("timestamp: {e}"))?;
24 let status = Command::new("sh")
25 .arg("-c")
26 .arg(reference)
27 .current_dir(repo)
28 .status()
29 .map_err(|e| format!("cannot run {reference:?}: {e}"))?;
30 let result = if status.code() == Some(green_exit_code) {
32 "green"
33 } else {
34 "red"
35 };
36 Ok(Receipt {
37 test: reference.to_string(),
38 platform: platform.to_string(),
39 commit,
40 ran_at,
41 result: result.to_string(),
42 falsifiable: None,
43 })
44}
45
46#[cfg(test)]
47mod tests {
48 use super::*;
49
50 fn git_repo() -> std::path::PathBuf {
52 use std::sync::atomic::{AtomicU64, Ordering};
53 static N: AtomicU64 = AtomicU64::new(0);
54 let p = std::env::temp_dir().join(format!(
55 "ev-runner-{}-{}",
56 std::process::id(),
57 N.fetch_add(1, Ordering::Relaxed)
58 ));
59 let _ = std::fs::remove_dir_all(&p);
60 std::fs::create_dir_all(&p).unwrap();
61 for args in [
62 ["init"].as_slice(),
63 ["config", "user.email", "t@e.st"].as_slice(),
64 ["config", "user.name", "Tester"].as_slice(),
65 ["commit", "--allow-empty", "-m", "init"].as_slice(),
66 ] {
67 Command::new("git")
68 .args(args)
69 .current_dir(&p)
70 .output()
71 .unwrap();
72 }
73 p
74 }
75
76 #[test]
77 fn run_check_should_record_green_when_the_command_exits_zero() {
78 let repo = git_repo();
80
81 let r = run_check(&repo, "true", "local", 0).expect("ok");
83
84 assert_eq!(r.result, "green");
86 assert_eq!(r.platform, "local");
87 assert_eq!(r.test, "true");
88 assert_eq!(r.commit.len(), 40);
89 }
90
91 #[test]
92 fn run_check_should_record_red_when_the_command_exits_nonzero() {
93 let repo = git_repo();
95
96 let r = run_check(&repo, "false", "local", 0).expect("ok");
98
99 assert_eq!(r.result, "red");
101 }
102}