1use dev_report::{CheckResult, Producer, Report, Severity};
8
9use crate::FuzzRun;
10
11pub struct FuzzProducer {
34 run: FuzzRun,
35}
36
37impl FuzzProducer {
38 pub fn new(run: FuzzRun) -> Self {
40 Self { run }
41 }
42}
43
44impl Producer for FuzzProducer {
45 fn produce(&self) -> Report {
46 let target = self.run.target_name().to_string();
47 let version = self.run.subject_version().to_string();
48 let mut report = Report::new(&target, &version).with_producer("dev-fuzz");
49 match self.run.execute() {
50 Ok(result) => {
51 let r = result.into_report();
52 return r;
56 }
57 Err(e) => {
58 let detail = e.to_string();
59 let check = CheckResult::fail(format!("fuzz::{target}"), Severity::Critical)
60 .with_detail(detail)
61 .with_tag("fuzz")
62 .with_tag("subprocess");
63 report.push(check);
64 }
65 }
66 report.finish();
67 report
68 }
69}
70
71#[cfg(test)]
72mod tests {
73 use super::*;
74 use dev_report::Verdict;
75
76 #[test]
77 fn produce_maps_run_failure_to_critical_fail() {
78 let dir = tempfile::tempdir().unwrap();
82 let producer =
83 FuzzProducer::new(FuzzRun::new("nonexistent_target", "0.0.0").in_dir(dir.path()));
84 let report = producer.produce();
85 assert_eq!(report.subject, "nonexistent_target");
86 assert_eq!(report.checks.len(), 1);
87 let check = &report.checks[0];
88 assert_eq!(check.name, "fuzz::nonexistent_target");
89 assert_eq!(check.verdict, Verdict::Fail);
90 assert_eq!(check.severity, Some(Severity::Critical));
91 assert!(check.has_tag("subprocess"));
92 }
93
94 #[test]
95 fn produce_maps_missing_workdir_to_critical_fail() {
96 let producer =
97 FuzzProducer::new(FuzzRun::new("parse", "0.0.0").in_dir("definitely/not/a/dir/7f3a"));
98 let report = producer.produce();
99 assert_eq!(report.checks.len(), 1);
100 assert_eq!(report.checks[0].verdict, Verdict::Fail);
101 assert!(report.checks[0]
102 .detail
103 .as_deref()
104 .unwrap_or("")
105 .contains("does not exist"));
106 }
107}