Skip to main content

ace_sim/
fault.rs

1// region: Imports
2
3use crate::clock::Duration;
4
5// endregion: Imports
6
7// region: Fault Config
8
9/// Controls which faults the simulation bus may inject and at what rates.
10///
11/// All probabilities are expressed as `(numerator, denominator)` pairs. For example `(1, 100)`
12/// means a 1% chance per eligible event.
13#[derive(Debug, Clone)]
14pub struct FaultConfig {
15    /// Probability a message is silently dropped.
16    pub message_loss: (u32, u32),
17
18    /// Probability two consecutive messages are reordered.
19    pub message_reorder: (u32, u32),
20
21    /// Probability a message is delayed. Delay duration is drawn uniformly from `0..max_delay_us`.
22    pub message_delay: (u32, u32),
23    pub max_delay: Duration,
24
25    /// Probability a message payload byte is corrupted. Applied per-byte independently.
26    pub corruption: (u32, u32),
27
28    /// Probability a respponse is replaced with a timeout (i.e suppressed entirely, forcing the
29    /// sender to timeout)
30    pub timeout: (u32, u32),
31}
32
33impl FaultConfig {
34    /// No faults - fully deterministic pass-through.
35    pub fn none() -> Self {
36        Self {
37            message_loss: (0, 1),
38            message_reorder: (0, 1),
39            message_delay: (0, 1),
40            max_delay: Duration::ZERO,
41            corruption: (0, 1),
42            timeout: (0, 1),
43        }
44    }
45
46    /// Light fault injection - suitable for initial CI runs.
47    pub fn light() -> Self {
48        Self {
49            message_loss: (1, 100),
50            message_reorder: (1, 50),
51            message_delay: (1, 20),
52            max_delay: Duration::from_millis(50),
53            corruption: (1, 500),
54            timeout: (1, 200),
55        }
56    }
57
58    /// Heavy fault injection - chaos mode for stress testing.
59    pub fn chaos() -> Self {
60        Self {
61            message_loss: (1, 10),
62            message_reorder: (1, 5),
63            message_delay: (1, 3),
64            max_delay: Duration::from_millis(500),
65            corruption: (1, 50),
66            timeout: (1, 20),
67        }
68    }
69}
70
71// endregion: Fault Config