quantrs2_anneal/comprehensive_integration_testing/
validation.rs1use std::collections::HashMap;
4use std::time::Duration;
5
6use super::results::{IntegrationValidationResult, ValidationStatus};
7use super::scenarios::{IntegrationTestCase, ValidationMethod};
8
9pub struct IntegrationVerification {
11 pub verification_rules: Vec<VerificationRule>,
13 pub validation_history: Vec<ValidationHistoryEntry>,
15 pub statistics: VerificationStatistics,
17}
18
19impl IntegrationVerification {
20 #[must_use]
21 pub fn new() -> Self {
22 Self {
23 verification_rules: vec![],
24 validation_history: vec![],
25 statistics: VerificationStatistics::default(),
26 }
27 }
28
29 pub fn verify_test_case(
31 &self,
32 test_case: &IntegrationTestCase,
33 ) -> Result<IntegrationValidationResult, String> {
34 let start_time = std::time::SystemTime::now();
35 let mut violations = Vec::new();
36
37 for rule in &self.verification_rules {
39 if let Some(violation) = self.check_rule(rule, test_case) {
40 violations.push(violation);
41 }
42 }
43
44 let duration = start_time.elapsed().unwrap_or(Duration::from_secs(0));
45
46 let status = if violations.is_empty() {
47 ValidationStatus::Passed
48 } else if violations
49 .iter()
50 .any(|v| matches!(v.severity, RuleSeverity::Critical | RuleSeverity::Error))
51 {
52 ValidationStatus::Failed
53 } else {
54 ValidationStatus::Partial
55 };
56
57 Ok(IntegrationValidationResult {
59 component_results: super::results::ComponentIntegrationResults {
60 components: HashMap::new(),
61 integration_matrix: vec![],
62 },
63 system_results: super::results::SystemIntegrationResults {
64 end_to_end_results: vec![],
65 system_health: super::results::SystemHealthMetrics {
66 health_score: if status == ValidationStatus::Passed {
67 1.0
68 } else {
69 0.5
70 },
71 component_health: HashMap::new(),
72 resource_utilization: super::results::ResourceUtilization {
73 cpu: 0.0,
74 memory: 0.0,
75 disk: 0.0,
76 network: 0.0,
77 },
78 },
79 },
80 performance_results: super::results::PerformanceIntegrationResults {
81 benchmarks: HashMap::new(),
82 trends: super::results::PerformanceTrends {
83 execution_time_trend: vec![],
84 memory_trend: vec![],
85 success_rate_trend: vec![],
86 },
87 regressions: vec![],
88 },
89 overall_status: status,
90 })
91 }
92
93 const fn check_rule(
95 &self,
96 rule: &VerificationRule,
97 _test_case: &IntegrationTestCase,
98 ) -> Option<RuleViolation> {
99 match &rule.condition {
101 VerificationCondition::Custom(_) => None,
102 _ => None, }
104 }
105
106 pub fn add_rule(&mut self, rule: VerificationRule) {
108 self.verification_rules.push(rule);
109 }
110
111 pub fn remove_rule(&mut self, rule_name: &str) {
113 self.verification_rules.retain(|r| r.name != rule_name);
114 }
115
116 #[must_use]
118 pub const fn get_statistics(&self) -> &VerificationStatistics {
119 &self.statistics
120 }
121
122 pub fn clear_history(&mut self) {
124 self.validation_history.clear();
125 }
126
127 #[must_use]
129 pub fn get_history(&self) -> &[ValidationHistoryEntry] {
130 &self.validation_history
131 }
132
133 pub fn update_statistics(&mut self, status: ValidationStatus, duration: Duration) {
135 self.statistics.total_verifications += 1;
136 match status {
137 ValidationStatus::Passed => self.statistics.successful_verifications += 1,
138 ValidationStatus::Failed => self.statistics.failed_verifications += 1,
139 _ => {}
140 }
141
142 let total_time = self.statistics.avg_verification_time.as_secs_f64().mul_add(
144 (self.statistics.total_verifications - 1) as f64,
145 duration.as_secs_f64(),
146 );
147 self.statistics.avg_verification_time =
148 Duration::from_secs_f64(total_time / self.statistics.total_verifications as f64);
149 }
150}
151
152#[derive(Debug, Clone)]
154pub struct VerificationRule {
155 pub name: String,
157 pub description: String,
159 pub rule_type: VerificationRuleType,
161 pub condition: VerificationCondition,
163 pub severity: RuleSeverity,
165}
166
167#[derive(Debug, Clone, PartialEq, Eq)]
169pub enum VerificationRuleType {
170 ComponentCompatibility,
172 PerformanceRequirement,
174 ResourceConstraint,
176 SecurityRequirement,
178 Custom(String),
180}
181
182#[derive(Debug, Clone)]
184pub enum VerificationCondition {
185 ValueComparison {
187 field: String,
188 operator: ComparisonOperator,
189 value: VerificationValue,
190 },
191 RangeCheck { field: String, min: f64, max: f64 },
193 PatternMatch { field: String, pattern: String },
195 Custom(String),
197}
198
199#[derive(Debug, Clone, PartialEq, Eq)]
201pub enum ComparisonOperator {
202 Equal,
203 NotEqual,
204 GreaterThan,
205 GreaterThanOrEqual,
206 LessThan,
207 LessThanOrEqual,
208 Contains,
209 StartsWith,
210 EndsWith,
211}
212
213#[derive(Debug, Clone)]
215pub enum VerificationValue {
216 String(String),
217 Number(f64),
218 Boolean(bool),
219 Duration(Duration),
220 Array(Vec<Self>),
221}
222
223#[derive(Debug, Clone, PartialEq, Eq)]
225pub enum RuleSeverity {
226 Info,
227 Warning,
228 Error,
229 Critical,
230}
231
232#[derive(Debug, Clone)]
234pub struct ValidationHistoryEntry {
235 pub timestamp: std::time::SystemTime,
237 pub test_case_id: String,
239 pub result: ValidationStatus,
241 pub duration: Duration,
243 pub violations: Vec<RuleViolation>,
245}
246
247#[derive(Debug, Clone)]
249pub struct RuleViolation {
250 pub rule_name: String,
252 pub message: String,
254 pub severity: RuleSeverity,
256 pub context: HashMap<String, String>,
258}
259
260#[derive(Debug, Clone)]
262pub struct VerificationStatistics {
263 pub total_verifications: usize,
265 pub successful_verifications: usize,
267 pub failed_verifications: usize,
269 pub avg_verification_time: Duration,
271 pub rule_violations: HashMap<String, usize>,
273}
274
275impl Default for VerificationStatistics {
276 fn default() -> Self {
277 Self {
278 total_verifications: 0,
279 successful_verifications: 0,
280 failed_verifications: 0,
281 avg_verification_time: Duration::from_secs(0),
282 rule_violations: HashMap::new(),
283 }
284 }
285}
286
287#[derive(Debug, Clone)]
289pub struct ValidationContext {
290 pub test_case: IntegrationTestCase,
292 pub parameters: HashMap<String, String>,
294 pub environment: ValidationEnvironment,
296}
297
298#[derive(Debug, Clone)]
300pub struct ValidationEnvironment {
301 pub name: String,
303 pub variables: HashMap<String, String>,
305 pub constraints: ResourceConstraints,
307}
308
309#[derive(Debug, Clone)]
311pub struct ResourceConstraints {
312 pub max_execution_time: Duration,
314 pub max_memory_usage: usize,
316 pub max_cpu_usage: f64,
318 pub max_disk_usage: usize,
320}
321
322pub struct ValidationExecutor {
324 pub rules: Vec<VerificationRule>,
326 pub context: ValidationContext,
328 pub methods: HashMap<ValidationMethod, Box<dyn Fn(&ValidationContext) -> ValidationStatus>>,
330}
331
332impl ValidationExecutor {
333 #[must_use]
334 pub fn new(context: ValidationContext) -> Self {
335 Self {
336 rules: vec![],
337 context,
338 methods: HashMap::new(),
339 }
340 }
341
342 pub fn execute(&self) -> Result<ValidationStatus, String> {
344 let mut has_errors = false;
345 let mut has_warnings = false;
346
347 for rule in &self.rules {
349 match self.validate_rule(rule) {
350 Ok(status) => match status {
351 ValidationStatus::Failed => has_errors = true,
352 ValidationStatus::Partial => has_warnings = true,
353 _ => {}
354 },
355 Err(_) => has_errors = true,
356 }
357 }
358
359 Ok(if has_errors {
360 ValidationStatus::Failed
361 } else if has_warnings {
362 ValidationStatus::Partial
363 } else {
364 ValidationStatus::Passed
365 })
366 }
367
368 const fn validate_rule(&self, rule: &VerificationRule) -> Result<ValidationStatus, String> {
370 match &rule.condition {
371 VerificationCondition::ValueComparison { .. } => Ok(ValidationStatus::Passed),
372 VerificationCondition::RangeCheck { .. } => Ok(ValidationStatus::Passed),
373 VerificationCondition::PatternMatch { .. } => Ok(ValidationStatus::Passed),
374 VerificationCondition::Custom(_) => Ok(ValidationStatus::Passed),
375 }
376 }
377
378 pub fn add_rule(&mut self, rule: VerificationRule) {
380 self.rules.push(rule);
381 }
382
383 pub fn clear_rules(&mut self) {
385 self.rules.clear();
386 }
387
388 #[must_use]
390 pub fn rule_count(&self) -> usize {
391 self.rules.len()
392 }
393}