1use super::types::FuzzResult;
4use std::collections::HashMap;
5
6#[derive(Debug, Clone)]
8pub struct FuzzTargetConfig {
9 pub name: String,
11 pub iterations: u64,
13 pub timeout_secs: u64,
15 pub seed: Option<u64>,
17 pub track_coverage: bool,
19}
20
21impl FuzzTargetConfig {
22 pub fn new(name: &str) -> Self {
24 Self {
25 name: name.to_string(),
26 iterations: 10000,
27 timeout_secs: 60,
28 seed: None,
29 track_coverage: true,
30 }
31 }
32
33 pub fn with_iterations(mut self, iterations: u64) -> Self {
35 self.iterations = iterations;
36 self
37 }
38
39 pub fn with_timeout(mut self, timeout_secs: u64) -> Self {
41 self.timeout_secs = timeout_secs;
42 self
43 }
44
45 pub fn with_seed(mut self, seed: u64) -> Self {
47 self.seed = Some(seed);
48 self
49 }
50}
51
52#[derive(Debug, Default)]
54pub struct FuzzSuite {
55 results: HashMap<String, FuzzResult>,
57 total_cases: u64,
59 total_failures: u64,
61}
62
63impl FuzzSuite {
64 pub fn new() -> Self {
66 Self::default()
67 }
68
69 pub fn add_result(&mut self, result: FuzzResult) {
71 self.total_cases += result.test_cases;
72 self.total_failures += result.failures;
73 self.results.insert(result.target.clone(), result);
74 }
75
76 pub fn get_result(&self, target: &str) -> Option<&FuzzResult> {
78 self.results.get(target)
79 }
80
81 pub fn all_passed(&self) -> bool {
83 self.total_failures == 0
84 }
85
86 pub fn total_cases(&self) -> u64 {
88 self.total_cases
89 }
90
91 pub fn total_failures(&self) -> u64 {
93 self.total_failures
94 }
95
96 pub fn results(&self) -> &HashMap<String, FuzzResult> {
98 &self.results
99 }
100
101 pub fn summary(&self) -> FuzzSummary {
103 let targets_passed = self.results.values().filter(|r| r.passed()).count();
104 let avg_coverage = if self.results.is_empty() {
105 0.0
106 } else {
107 self.results
108 .values()
109 .map(|r| r.coverage_percent)
110 .sum::<f64>()
111 / self.results.len() as f64
112 };
113
114 FuzzSummary {
115 total_targets: self.results.len(),
116 targets_passed,
117 total_cases: self.total_cases,
118 total_failures: self.total_failures,
119 avg_coverage,
120 overall_passed: self.all_passed(),
121 }
122 }
123}
124
125#[derive(Debug, Clone)]
127pub struct FuzzSummary {
128 pub total_targets: usize,
130 pub targets_passed: usize,
132 pub total_cases: u64,
134 pub total_failures: u64,
136 pub avg_coverage: f64,
138 pub overall_passed: bool,
140}
141
142impl FuzzSummary {
143 pub fn pass_rate(&self) -> f64 {
145 if self.total_targets == 0 {
146 100.0
147 } else {
148 (self.targets_passed as f64 / self.total_targets as f64) * 100.0
149 }
150 }
151}