Skip to main content

acex_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)]
14#[cfg_attr(feature = "defmt", derive(defmt::Format))]
15pub struct FaultConfig {
16    /// Probability a message is silently dropped.
17    pub message_loss: (u32, u32),
18
19    /// Probability two consecutive messages are reordered.
20    pub message_reorder: (u32, u32),
21
22    /// Probability a message is delayed. Delay duration is drawn uniformly from `0..max_delay_us`.
23    pub message_delay: (u32, u32),
24    pub max_delay: Duration,
25
26    /// Probability a message payload byte is corrupted. Applied per-byte independently.
27    pub corruption: (u32, u32),
28
29    /// Probability a respponse is replaced with a timeout (i.e suppressed entirely, forcing the
30    /// sender to timeout)
31    pub timeout: (u32, u32),
32}
33
34impl FaultConfig {
35    /// No faults - fully deterministic pass-through.
36    pub fn none() -> Self {
37        Self {
38            message_loss: (0, 1),
39            message_reorder: (0, 1),
40            message_delay: (0, 1),
41            max_delay: Duration::ZERO,
42            corruption: (0, 1),
43            timeout: (0, 1),
44        }
45    }
46
47    /// Light fault injection - suitable for initial CI runs.
48    pub fn light() -> Self {
49        Self {
50            message_loss: (1, 100),
51            message_reorder: (1, 50),
52            message_delay: (1, 20),
53            max_delay: Duration::from_millis(50),
54            corruption: (1, 500),
55            timeout: (1, 200),
56        }
57    }
58
59    /// Heavy fault injection - chaos mode for stress testing.
60    pub fn chaos() -> Self {
61        Self {
62            message_loss: (1, 10),
63            message_reorder: (1, 5),
64            message_delay: (1, 3),
65            max_delay: Duration::from_millis(500),
66            corruption: (1, 50),
67            timeout: (1, 20),
68        }
69    }
70}
71
72// endregion: Fault Config