moonpool_sim/runner/
report.rs1use std::collections::HashMap;
6use std::fmt;
7use std::time::Duration;
8
9use crate::SimulationResult;
10use crate::chaos::AssertionStats;
11
12#[derive(Debug, Clone, PartialEq)]
14pub struct SimulationMetrics {
15 pub wall_time: Duration,
17 pub simulated_time: Duration,
19 pub events_processed: u64,
21}
22
23impl Default for SimulationMetrics {
24 fn default() -> Self {
25 Self {
26 wall_time: Duration::ZERO,
27 simulated_time: Duration::ZERO,
28 events_processed: 0,
29 }
30 }
31}
32
33#[derive(Debug, Clone)]
35pub struct SimulationReport {
36 pub iterations: usize,
38 pub successful_runs: usize,
40 pub failed_runs: usize,
42 pub metrics: SimulationMetrics,
44 pub individual_metrics: Vec<SimulationResult<SimulationMetrics>>,
46 pub seeds_used: Vec<u64>,
48 pub seeds_failing: Vec<u64>,
50 pub assertion_results: HashMap<String, AssertionStats>,
52 pub assertion_violations: Vec<String>,
54}
55
56impl SimulationReport {
57 pub fn success_rate(&self) -> f64 {
59 if self.iterations == 0 {
60 0.0
61 } else {
62 (self.successful_runs as f64 / self.iterations as f64) * 100.0
63 }
64 }
65
66 pub fn average_wall_time(&self) -> Duration {
68 if self.successful_runs == 0 {
69 Duration::ZERO
70 } else {
71 self.metrics.wall_time / self.successful_runs as u32
72 }
73 }
74
75 pub fn average_simulated_time(&self) -> Duration {
77 if self.successful_runs == 0 {
78 Duration::ZERO
79 } else {
80 self.metrics.simulated_time / self.successful_runs as u32
81 }
82 }
83
84 pub fn average_events_processed(&self) -> f64 {
86 if self.successful_runs == 0 {
87 0.0
88 } else {
89 self.metrics.events_processed as f64 / self.successful_runs as f64
90 }
91 }
92}
93
94impl fmt::Display for SimulationReport {
95 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
96 writeln!(f, "=== Simulation Report ===")?;
97 writeln!(f, "Iterations: {}", self.iterations)?;
98 writeln!(f, "Successful: {}", self.successful_runs)?;
99 writeln!(f, "Failed: {}", self.failed_runs)?;
100 writeln!(f, "Success Rate: {:.2}%", self.success_rate())?;
101 writeln!(f)?;
102 writeln!(f, "Average Wall Time: {:?}", self.average_wall_time())?;
103 writeln!(
104 f,
105 "Average Simulated Time: {:?}",
106 self.average_simulated_time()
107 )?;
108 writeln!(
109 f,
110 "Average Events Processed: {:.1}",
111 self.average_events_processed()
112 )?;
113
114 if !self.seeds_failing.is_empty() {
115 writeln!(f)?;
116 writeln!(f, "Faulty seeds: {:?}", self.seeds_failing)?;
117 }
118
119 writeln!(f)?;
120
121 Ok(())
122 }
123}