trueno_gpu/monitor/stress_test/
config.rs1use std::time::Duration;
6
7use super::super::device::DeviceId;
8
9#[derive(Debug, Clone)]
15pub struct StressTestConfig {
16 pub target: StressTarget,
18 pub duration: Duration,
20 pub intensity: f64,
22 pub ramp_up: Duration,
24 pub chaos_preset: Option<ChaosPreset>,
26 pub collect_metrics: bool,
28 pub export_report: bool,
30}
31
32impl Default for StressTestConfig {
33 fn default() -> Self {
34 Self {
35 target: StressTarget::All,
36 duration: Duration::from_secs(60),
37 intensity: 1.0,
38 ramp_up: Duration::from_secs(5),
39 chaos_preset: None,
40 collect_metrics: true,
41 export_report: true,
42 }
43 }
44}
45
46impl StressTestConfig {
47 #[must_use]
49 pub fn new() -> Self {
50 Self::default()
51 }
52
53 #[must_use]
55 pub fn with_target(mut self, target: StressTarget) -> Self {
56 self.target = target;
57 self
58 }
59
60 #[must_use]
62 pub fn with_duration(mut self, duration: Duration) -> Self {
63 self.duration = duration;
64 self
65 }
66
67 #[must_use]
69 pub fn with_intensity(mut self, intensity: f64) -> Self {
70 self.intensity = intensity.clamp(0.0, 1.0);
71 self
72 }
73
74 #[must_use]
76 pub fn with_ramp_up(mut self, ramp_up: Duration) -> Self {
77 self.ramp_up = ramp_up;
78 self
79 }
80
81 #[must_use]
83 pub fn with_chaos(mut self, preset: ChaosPreset) -> Self {
84 self.chaos_preset = Some(preset);
85 self
86 }
87
88 #[must_use]
90 pub fn parse_duration(s: &str) -> Option<Duration> {
91 let s = s.trim();
92 if s.is_empty() {
93 return None;
94 }
95
96 let (num, unit) = s.split_at(s.len() - 1);
97 let value: u64 = num.parse().ok()?;
98
99 match unit {
100 "s" => Some(Duration::from_secs(value)),
101 "m" => Some(Duration::from_secs(value * 60)),
102 "h" => Some(Duration::from_secs(value * 3600)),
103 _ => None,
104 }
105 }
106}
107
108#[derive(Debug, Clone, PartialEq)]
110pub enum StressTarget {
111 All,
113 Cpu,
115 Gpu(Option<DeviceId>),
117 Memory,
119 Pcie,
121 Custom(Vec<StressTarget>),
123}
124
125impl StressTarget {
126 #[must_use]
128 pub fn parse(s: &str) -> Option<Self> {
129 let s = s.trim().to_lowercase();
130
131 if s == "all" {
132 return Some(Self::All);
133 }
134 if s == "cpu" {
135 return Some(Self::Cpu);
136 }
137 if s == "memory" {
138 return Some(Self::Memory);
139 }
140 if s == "pcie" {
141 return Some(Self::Pcie);
142 }
143 if s == "gpu" {
144 return Some(Self::Gpu(None));
145 }
146 if let Some(idx_str) = s.strip_prefix("gpu:") {
147 let idx: u32 = idx_str.parse().ok()?;
148 return Some(Self::Gpu(Some(DeviceId::nvidia(idx))));
149 }
150
151 None
152 }
153
154 #[must_use]
156 pub fn includes_cpu(&self) -> bool {
157 match self {
158 Self::All | Self::Cpu => true,
159 Self::Custom(targets) => targets.iter().any(|t| t.includes_cpu()),
160 _ => false,
161 }
162 }
163
164 #[must_use]
166 pub fn includes_gpu(&self) -> bool {
167 match self {
168 Self::All | Self::Gpu(_) => true,
169 Self::Custom(targets) => targets.iter().any(|t| t.includes_gpu()),
170 _ => false,
171 }
172 }
173
174 #[must_use]
176 pub fn includes_memory(&self) -> bool {
177 match self {
178 Self::All | Self::Memory => true,
179 Self::Custom(targets) => targets.iter().any(|t| t.includes_memory()),
180 _ => false,
181 }
182 }
183
184 #[must_use]
186 pub fn includes_pcie(&self) -> bool {
187 match self {
188 Self::All | Self::Pcie => true,
189 Self::Custom(targets) => targets.iter().any(|t| t.includes_pcie()),
190 _ => false,
191 }
192 }
193}
194
195#[derive(Debug, Clone, Copy, PartialEq, Eq)]
201pub enum ChaosPreset {
202 Gentle,
204 Moderate,
206 Aggressive,
208 Extreme,
210}
211
212impl ChaosPreset {
213 #[must_use]
215 pub fn parse(s: &str) -> Option<Self> {
216 match s.trim().to_lowercase().as_str() {
217 "gentle" => Some(Self::Gentle),
218 "moderate" => Some(Self::Moderate),
219 "aggressive" => Some(Self::Aggressive),
220 "extreme" => Some(Self::Extreme),
221 _ => None,
222 }
223 }
224
225 #[must_use]
227 pub fn memory_limit_factor(&self) -> f64 {
228 match self {
229 Self::Gentle => 0.9, Self::Moderate => 0.75, Self::Aggressive => 0.5, Self::Extreme => 0.25, }
234 }
235
236 #[must_use]
238 pub fn cpu_throttle_factor(&self) -> f64 {
239 match self {
240 Self::Gentle => 1.0, Self::Moderate => 0.9, Self::Aggressive => 0.7, Self::Extreme => 0.5, }
245 }
246
247 #[must_use]
249 pub fn network_latency_ms(&self) -> u32 {
250 match self {
251 Self::Gentle => 0,
252 Self::Moderate => 10,
253 Self::Aggressive => 50,
254 Self::Extreme => 200,
255 }
256 }
257
258 #[must_use]
260 pub fn failure_rate(&self) -> f64 {
261 match self {
262 Self::Gentle => 0.0,
263 Self::Moderate => 0.01,
264 Self::Aggressive => 0.05,
265 Self::Extreme => 0.10,
266 }
267 }
268}