cu_profiler_core/
scenario.rs1use serde::{Deserialize, Serialize};
7
8use crate::budget::BudgetPolicy;
9
10#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
12#[serde(rename_all = "lowercase")]
13pub enum Criticality {
14 Critical,
16 #[default]
18 Normal,
19 Low,
21}
22
23#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
26#[serde(rename_all = "lowercase")]
27pub enum ExpectedResult {
28 #[default]
30 Success,
31 Failure,
33}
34
35#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
37pub struct Scenario {
38 pub name: String,
40 #[serde(default)]
42 pub description: String,
43 #[serde(default)]
45 pub tags: Vec<String>,
46 #[serde(default)]
48 pub criticality: Criticality,
49 #[serde(default, skip_serializing_if = "Option::is_none")]
51 pub owner: Option<String>,
52 #[serde(default)]
54 pub expected: ExpectedResult,
55 #[serde(default)]
57 pub budget: BudgetPolicy,
58 #[serde(default = "default_samples")]
62 pub samples: u32,
63}
64
65fn default_samples() -> u32 {
66 1
67}
68
69impl Scenario {
70 #[must_use]
72 pub fn new(name: impl Into<String>) -> Self {
73 Self {
74 name: name.into(),
75 description: String::new(),
76 tags: Vec::new(),
77 criticality: Criticality::Normal,
78 owner: None,
79 expected: ExpectedResult::Success,
80 budget: BudgetPolicy::default(),
81 samples: 1,
82 }
83 }
84
85 #[must_use]
87 pub fn has_tag(&self, tag: &str) -> bool {
88 self.tags.iter().any(|t| t == tag)
89 }
90}
91
92#[cfg(test)]
93mod tests {
94 use super::*;
95
96 #[test]
97 fn defaults_are_sane() {
98 let s = Scenario::new("swap/happy_path");
99 assert_eq!(s.samples, 1);
100 assert_eq!(s.expected, ExpectedResult::Success);
101 assert_eq!(s.criticality, Criticality::Normal);
102 }
103
104 #[test]
105 fn tag_filtering() {
106 let mut s = Scenario::new("swap/large_pool");
107 s.tags = vec!["swap".into(), "hot-path".into()];
108 assert!(s.has_tag("hot-path"));
109 assert!(!s.has_tag("admin"));
110 }
111}