1use std::collections::HashMap;
4use std::time::{Duration, SystemTime};
5
6pub struct TestRegistry {
8 pub test_cases: HashMap<String, IntegrationTestCase>,
10 pub test_suites: HashMap<String, TestSuite>,
12 pub dependencies: HashMap<String, Vec<String>>,
14 pub categories: HashMap<TestCategory, Vec<String>>,
16}
17
18impl TestRegistry {
19 #[must_use]
20 pub fn new() -> Self {
21 Self {
22 test_cases: HashMap::new(),
23 test_suites: HashMap::new(),
24 dependencies: HashMap::new(),
25 categories: HashMap::new(),
26 }
27 }
28
29 pub fn register_test_case(&mut self, test_case: IntegrationTestCase) -> Result<(), String> {
30 let id = test_case.id.clone();
31 let category = test_case.category.clone();
32
33 self.test_cases.insert(id.clone(), test_case);
34
35 self.categories
37 .entry(category)
38 .or_insert_with(Vec::new)
39 .push(id);
40
41 Ok(())
42 }
43
44 pub fn register_test_suite(&mut self, test_suite: TestSuite) -> Result<(), String> {
46 let id = test_suite.id.clone();
47 self.test_suites.insert(id, test_suite);
48 Ok(())
49 }
50
51 pub fn unregister_test_case(&mut self, test_case_id: &str) -> Result<(), String> {
53 self.test_cases
54 .remove(test_case_id)
55 .ok_or_else(|| format!("Test case {test_case_id} not found"))?;
56
57 self.dependencies.remove(test_case_id);
59
60 Ok(())
61 }
62
63 #[must_use]
65 pub fn get_test_case(&self, test_case_id: &str) -> Option<&IntegrationTestCase> {
66 self.test_cases.get(test_case_id)
67 }
68
69 #[must_use]
71 pub fn get_test_suite(&self, test_suite_id: &str) -> Option<&TestSuite> {
72 self.test_suites.get(test_suite_id)
73 }
74
75 #[must_use]
77 pub fn get_test_cases_by_category(&self, category: &TestCategory) -> Vec<&IntegrationTestCase> {
78 if let Some(ids) = self.categories.get(category) {
79 ids.iter()
80 .filter_map(|id| self.test_cases.get(id))
81 .collect()
82 } else {
83 Vec::new()
84 }
85 }
86
87 pub fn add_dependency(&mut self, test_case_id: String, dependency_id: String) {
89 self.dependencies
90 .entry(test_case_id)
91 .or_insert_with(Vec::new)
92 .push(dependency_id);
93 }
94
95 #[must_use]
97 pub fn get_dependencies(&self, test_case_id: &str) -> Vec<&str> {
98 self.dependencies
99 .get(test_case_id)
100 .map(|deps| deps.iter().map(std::string::String::as_str).collect())
101 .unwrap_or_default()
102 }
103
104 #[must_use]
106 pub fn list_test_cases(&self) -> Vec<&IntegrationTestCase> {
107 self.test_cases.values().collect()
108 }
109
110 #[must_use]
112 pub fn list_test_suites(&self) -> Vec<&TestSuite> {
113 self.test_suites.values().collect()
114 }
115
116 #[must_use]
118 pub fn test_case_count(&self) -> usize {
119 self.test_cases.len()
120 }
121
122 #[must_use]
124 pub fn test_suite_count(&self) -> usize {
125 self.test_suites.len()
126 }
127
128 pub fn clear_all(&mut self) {
130 self.test_cases.clear();
131 self.test_suites.clear();
132 self.dependencies.clear();
133 self.categories.clear();
134 }
135
136 #[must_use]
138 pub fn find_test_cases(&self, pattern: &str) -> Vec<&IntegrationTestCase> {
139 self.test_cases
140 .values()
141 .filter(|tc| tc.name.contains(pattern) || tc.description.contains(pattern))
142 .collect()
143 }
144}
145
146#[derive(Debug, Clone)]
148pub struct IntegrationTestCase {
149 pub id: String,
151 pub name: String,
153 pub description: String,
155 pub category: TestCategory,
157 pub priority: TestPriority,
159 pub timeout: Duration,
161 pub prerequisites: Vec<String>,
163 pub parameters: HashMap<String, TestParameter>,
165 pub expected_results: ExpectedResults,
167 pub test_steps: Vec<TestStep>,
169 pub metadata: TestMetadata,
171}
172
173#[derive(Debug, Clone)]
175pub struct TestSuite {
176 pub id: String,
178 pub name: String,
180 pub description: String,
182 pub test_cases: Vec<String>,
184 pub configuration: TestSuiteConfig,
186 pub metadata: TestMetadata,
188}
189
190#[derive(Debug, Clone, PartialEq, Eq, Hash)]
192pub enum TestCategory {
193 Unit,
195 Component,
197 System,
199 EndToEnd,
201 Performance,
203 Stress,
205 Security,
207 Compatibility,
209 Custom(String),
211}
212
213#[derive(Debug, Clone, PartialEq, Eq, PartialOrd)]
215pub enum TestPriority {
216 Low = 1,
217 Normal = 2,
218 High = 3,
219 Critical = 4,
220}
221
222#[derive(Debug, Clone)]
224pub struct TestParameter {
225 pub name: String,
227 pub parameter_type: ParameterType,
229 pub default_value: Option<ParameterValue>,
231 pub description: String,
233 pub validation: ParameterValidation,
235}
236
237#[derive(Debug, Clone, PartialEq)]
239pub enum ParameterType {
240 Boolean,
242 Integer,
244 Float,
246 String,
248 Array(Box<Self>),
250 Object(HashMap<String, Self>),
252}
253
254#[derive(Debug, Clone)]
256pub enum ParameterValue {
257 Boolean(bool),
259 Integer(i64),
261 Float(f64),
263 String(String),
265 Array(Vec<Self>),
267 Object(HashMap<String, Self>),
269}
270
271#[derive(Debug, Clone)]
273pub struct ParameterValidation {
274 pub required: bool,
276 pub min_value: Option<f64>,
278 pub max_value: Option<f64>,
280 pub allowed_values: Option<Vec<ParameterValue>>,
282 pub custom_validator: Option<String>,
284}
285
286#[derive(Debug, Clone)]
288pub struct ExpectedResults {
289 pub outcome: ExpectedOutcome,
291 pub validation: ResultValidation,
293 pub performance_metrics: Option<ExpectedPerformanceMetrics>,
295 pub side_effects: Vec<ExpectedSideEffect>,
297}
298
299#[derive(Debug, Clone, PartialEq, Eq)]
301pub enum ExpectedOutcome {
302 Pass,
304 Fail,
306 Skip,
308 Custom(String),
310}
311
312#[derive(Debug, Clone)]
314pub struct ResultValidation {
315 pub method: ValidationMethod,
317 pub tolerance: Option<f64>,
319 pub confidence_level: f64,
321}
322
323#[derive(Debug, Clone, PartialEq, Eq)]
325pub enum ValidationMethod {
326 Exact,
328 Approximate,
330 Range,
332 Statistical,
334 Custom(String),
336}
337
338#[derive(Debug, Clone)]
340pub struct ExpectedPerformanceMetrics {
341 pub execution_time: Option<Duration>,
343 pub memory_usage: Option<usize>,
345 pub throughput: Option<f64>,
347 pub error_rate: Option<f64>,
349 pub custom_metrics: HashMap<String, f64>,
351}
352
353#[derive(Debug, Clone)]
355pub struct ExpectedSideEffect {
356 pub name: String,
358 pub effect_type: SideEffectType,
360 pub description: String,
362 pub acceptance_criteria: AcceptanceCriteria,
364}
365
366#[derive(Debug, Clone, PartialEq, Eq)]
368pub enum SideEffectType {
369 StateChange,
371 ResourceConsumption,
373 PerformanceImpact,
375 DataModification,
377 Custom(String),
379}
380
381#[derive(Debug, Clone)]
383pub struct AcceptanceCriteria {
384 pub acceptable_impact: ImpactLevel,
386 pub max_duration: Option<Duration>,
388 pub recovery_requirements: Vec<String>,
390}
391
392#[derive(Debug, Clone, PartialEq, Eq, PartialOrd)]
394pub enum ImpactLevel {
395 None = 0,
396 Minimal = 1,
397 Low = 2,
398 Medium = 3,
399 High = 4,
400 Critical = 5,
401}
402
403#[derive(Debug, Clone)]
405pub struct TestStep {
406 pub id: String,
408 pub name: String,
410 pub description: String,
412 pub step_type: StepType,
414 pub parameters: HashMap<String, ParameterValue>,
416 pub timeout: Option<Duration>,
418 pub retry_config: Option<RetryConfig>,
420}
421
422#[derive(Debug, Clone, PartialEq, Eq)]
424pub enum StepType {
425 Setup,
427 Execution,
429 Validation,
431 Cleanup,
433 Custom(String),
435}
436
437#[derive(Debug, Clone)]
439pub struct RetryConfig {
440 pub max_attempts: usize,
442 pub retry_delay: Duration,
444 pub exponential_backoff: bool,
446 pub retry_conditions: Vec<String>,
448}
449
450#[derive(Debug, Clone)]
452pub struct TestSuiteConfig {
453 pub execution_order: ExecutionOrder,
455 pub parallel_execution: ParallelExecutionConfig,
457 pub timeout: Duration,
459 pub failure_handling: FailureHandling,
461}
462
463#[derive(Debug, Clone, PartialEq, Eq)]
465pub enum ExecutionOrder {
466 Sequential,
468 Parallel,
470 DependencyBased,
472 PriorityBased,
474 Custom(Vec<String>),
476}
477
478#[derive(Debug, Clone)]
480pub struct ParallelExecutionConfig {
481 pub enable_parallel: bool,
483 pub max_threads: usize,
485 pub thread_pool_config: ThreadPoolConfig,
487}
488
489#[derive(Debug, Clone)]
491pub struct ThreadPoolConfig {
492 pub core_size: usize,
494 pub max_size: usize,
496 pub keepalive_time: Duration,
498 pub queue_capacity: usize,
500}
501
502#[derive(Debug, Clone, PartialEq, Eq)]
504pub enum FailureHandling {
505 StopOnFirstFailure,
507 ContinueOnFailure,
509 RetryFailedTests,
511 Custom(String),
513}
514
515#[derive(Debug, Clone)]
517pub struct TestMetadata {
518 pub author: String,
520 pub created: SystemTime,
522 pub modified: SystemTime,
524 pub version: String,
526 pub tags: Vec<String>,
528 pub custom: HashMap<String, String>,
530}