1pub mod attacks;
2pub mod corpus;
3pub mod differential;
4pub mod mutators;
5pub mod report;
6pub mod subprocess;
7pub mod suite;
8
9pub use report::{AttackResult, AttackStatus, SimReport};
10pub use suite::{run_suite, tier_default_limits, SuiteConfig, SuiteTier, TimeBudget};
11
12#[cfg(test)]
13mod tests {
14 use super::*;
15 use std::path::PathBuf;
16
17 #[test]
18 fn test_quick_suite() {
19 let cfg = SuiteConfig {
20 tier: SuiteTier::Quick,
21 target_bundle: PathBuf::from("placeholder"),
22 seed: 42,
23 verify_limits: None,
24 time_budget_secs: 60,
25 };
26
27 let report = run_suite(cfg).expect("Suite failed to run");
28
29 if report.summary.bypassed > 0 {
31 println!("{}", serde_json::to_string_pretty(&report).unwrap());
32 }
33
34 assert_eq!(
37 report.summary.bypassed, 0,
38 "SECURITY: {} attacks bypassed verification",
39 report.summary.bypassed
40 );
41 assert!(
43 report.summary.blocked >= 1,
44 "SANITY: no attacks were blocked — suite may not have run"
45 );
46 let differential_ran = report
48 .results
49 .iter()
50 .any(|r| r.name == "differential.invariants");
51 assert!(
52 report.summary.passed >= 1 || differential_ran,
53 "SANITY: no checks passed and differential did not run — suite may not have run"
54 );
55 for r in &report.results {
60 let is_chaos_io = r.name.starts_with("chaos.io_fault.");
61 match r.status {
62 AttackStatus::Blocked | AttackStatus::Passed => {} AttackStatus::Error if is_chaos_io => {} _ => panic!(
65 "Unexpected status {:?} for '{}': {:?}",
66 r.status, r.name, r.message
67 ),
68 }
69 }
70 }
71}