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")]
60 pub samples: u32,
61}
62
63fn default_samples() -> u32 {
64 1
65}
66
67impl Scenario {
68 #[must_use]
70 pub fn new(name: impl Into<String>) -> Self {
71 Self {
72 name: name.into(),
73 description: String::new(),
74 tags: Vec::new(),
75 criticality: Criticality::Normal,
76 owner: None,
77 expected: ExpectedResult::Success,
78 budget: BudgetPolicy::default(),
79 samples: 1,
80 }
81 }
82
83 #[must_use]
85 pub fn has_tag(&self, tag: &str) -> bool {
86 self.tags.iter().any(|t| t == tag)
87 }
88}
89
90#[cfg(test)]
91mod tests {
92 use super::*;
93
94 #[test]
95 fn defaults_are_sane() {
96 let s = Scenario::new("swap/happy_path");
97 assert_eq!(s.samples, 1);
98 assert_eq!(s.expected, ExpectedResult::Success);
99 assert_eq!(s.criticality, Criticality::Normal);
100 }
101
102 #[test]
103 fn tag_filtering() {
104 let mut s = Scenario::new("swap/large_pool");
105 s.tags = vec!["swap".into(), "hot-path".into()];
106 assert!(s.has_tag("hot-path"));
107 assert!(!s.has_tag("admin"));
108 }
109}