use std::collections::HashMap;
use std::time::{Duration, SystemTime};
pub struct TestRegistry {
pub test_cases: HashMap<String, IntegrationTestCase>,
pub test_suites: HashMap<String, TestSuite>,
pub dependencies: HashMap<String, Vec<String>>,
pub categories: HashMap<TestCategory, Vec<String>>,
}
impl TestRegistry {
#[must_use]
pub fn new() -> Self {
Self {
test_cases: HashMap::new(),
test_suites: HashMap::new(),
dependencies: HashMap::new(),
categories: HashMap::new(),
}
}
pub fn register_test_case(&mut self, test_case: IntegrationTestCase) -> Result<(), String> {
let id = test_case.id.clone();
let category = test_case.category.clone();
self.test_cases.insert(id.clone(), test_case);
self.categories
.entry(category)
.or_insert_with(Vec::new)
.push(id);
Ok(())
}
pub fn register_test_suite(&mut self, test_suite: TestSuite) -> Result<(), String> {
let id = test_suite.id.clone();
self.test_suites.insert(id, test_suite);
Ok(())
}
pub fn unregister_test_case(&mut self, test_case_id: &str) -> Result<(), String> {
self.test_cases
.remove(test_case_id)
.ok_or_else(|| format!("Test case {test_case_id} not found"))?;
self.dependencies.remove(test_case_id);
Ok(())
}
#[must_use]
pub fn get_test_case(&self, test_case_id: &str) -> Option<&IntegrationTestCase> {
self.test_cases.get(test_case_id)
}
#[must_use]
pub fn get_test_suite(&self, test_suite_id: &str) -> Option<&TestSuite> {
self.test_suites.get(test_suite_id)
}
#[must_use]
pub fn get_test_cases_by_category(&self, category: &TestCategory) -> Vec<&IntegrationTestCase> {
if let Some(ids) = self.categories.get(category) {
ids.iter()
.filter_map(|id| self.test_cases.get(id))
.collect()
} else {
Vec::new()
}
}
pub fn add_dependency(&mut self, test_case_id: String, dependency_id: String) {
self.dependencies
.entry(test_case_id)
.or_insert_with(Vec::new)
.push(dependency_id);
}
#[must_use]
pub fn get_dependencies(&self, test_case_id: &str) -> Vec<&str> {
self.dependencies
.get(test_case_id)
.map(|deps| deps.iter().map(std::string::String::as_str).collect())
.unwrap_or_default()
}
#[must_use]
pub fn list_test_cases(&self) -> Vec<&IntegrationTestCase> {
self.test_cases.values().collect()
}
#[must_use]
pub fn list_test_suites(&self) -> Vec<&TestSuite> {
self.test_suites.values().collect()
}
#[must_use]
pub fn test_case_count(&self) -> usize {
self.test_cases.len()
}
#[must_use]
pub fn test_suite_count(&self) -> usize {
self.test_suites.len()
}
pub fn clear_all(&mut self) {
self.test_cases.clear();
self.test_suites.clear();
self.dependencies.clear();
self.categories.clear();
}
#[must_use]
pub fn find_test_cases(&self, pattern: &str) -> Vec<&IntegrationTestCase> {
self.test_cases
.values()
.filter(|tc| tc.name.contains(pattern) || tc.description.contains(pattern))
.collect()
}
}
#[derive(Debug, Clone)]
pub struct IntegrationTestCase {
pub id: String,
pub name: String,
pub description: String,
pub category: TestCategory,
pub priority: TestPriority,
pub timeout: Duration,
pub prerequisites: Vec<String>,
pub parameters: HashMap<String, TestParameter>,
pub expected_results: ExpectedResults,
pub test_steps: Vec<TestStep>,
pub metadata: TestMetadata,
}
#[derive(Debug, Clone)]
pub struct TestSuite {
pub id: String,
pub name: String,
pub description: String,
pub test_cases: Vec<String>,
pub configuration: TestSuiteConfig,
pub metadata: TestMetadata,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum TestCategory {
Unit,
Component,
System,
EndToEnd,
Performance,
Stress,
Security,
Compatibility,
Custom(String),
}
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd)]
pub enum TestPriority {
Low = 1,
Normal = 2,
High = 3,
Critical = 4,
}
#[derive(Debug, Clone)]
pub struct TestParameter {
pub name: String,
pub parameter_type: ParameterType,
pub default_value: Option<ParameterValue>,
pub description: String,
pub validation: ParameterValidation,
}
#[derive(Debug, Clone, PartialEq)]
pub enum ParameterType {
Boolean,
Integer,
Float,
String,
Array(Box<Self>),
Object(HashMap<String, Self>),
}
#[derive(Debug, Clone)]
pub enum ParameterValue {
Boolean(bool),
Integer(i64),
Float(f64),
String(String),
Array(Vec<Self>),
Object(HashMap<String, Self>),
}
#[derive(Debug, Clone)]
pub struct ParameterValidation {
pub required: bool,
pub min_value: Option<f64>,
pub max_value: Option<f64>,
pub allowed_values: Option<Vec<ParameterValue>>,
pub custom_validator: Option<String>,
}
#[derive(Debug, Clone)]
pub struct ExpectedResults {
pub outcome: ExpectedOutcome,
pub validation: ResultValidation,
pub performance_metrics: Option<ExpectedPerformanceMetrics>,
pub side_effects: Vec<ExpectedSideEffect>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ExpectedOutcome {
Pass,
Fail,
Skip,
Custom(String),
}
#[derive(Debug, Clone)]
pub struct ResultValidation {
pub method: ValidationMethod,
pub tolerance: Option<f64>,
pub confidence_level: f64,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ValidationMethod {
Exact,
Approximate,
Range,
Statistical,
Custom(String),
}
#[derive(Debug, Clone)]
pub struct ExpectedPerformanceMetrics {
pub execution_time: Option<Duration>,
pub memory_usage: Option<usize>,
pub throughput: Option<f64>,
pub error_rate: Option<f64>,
pub custom_metrics: HashMap<String, f64>,
}
#[derive(Debug, Clone)]
pub struct ExpectedSideEffect {
pub name: String,
pub effect_type: SideEffectType,
pub description: String,
pub acceptance_criteria: AcceptanceCriteria,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum SideEffectType {
StateChange,
ResourceConsumption,
PerformanceImpact,
DataModification,
Custom(String),
}
#[derive(Debug, Clone)]
pub struct AcceptanceCriteria {
pub acceptable_impact: ImpactLevel,
pub max_duration: Option<Duration>,
pub recovery_requirements: Vec<String>,
}
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd)]
pub enum ImpactLevel {
None = 0,
Minimal = 1,
Low = 2,
Medium = 3,
High = 4,
Critical = 5,
}
#[derive(Debug, Clone)]
pub struct TestStep {
pub id: String,
pub name: String,
pub description: String,
pub step_type: StepType,
pub parameters: HashMap<String, ParameterValue>,
pub timeout: Option<Duration>,
pub retry_config: Option<RetryConfig>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum StepType {
Setup,
Execution,
Validation,
Cleanup,
Custom(String),
}
#[derive(Debug, Clone)]
pub struct RetryConfig {
pub max_attempts: usize,
pub retry_delay: Duration,
pub exponential_backoff: bool,
pub retry_conditions: Vec<String>,
}
#[derive(Debug, Clone)]
pub struct TestSuiteConfig {
pub execution_order: ExecutionOrder,
pub parallel_execution: ParallelExecutionConfig,
pub timeout: Duration,
pub failure_handling: FailureHandling,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ExecutionOrder {
Sequential,
Parallel,
DependencyBased,
PriorityBased,
Custom(Vec<String>),
}
#[derive(Debug, Clone)]
pub struct ParallelExecutionConfig {
pub enable_parallel: bool,
pub max_threads: usize,
pub thread_pool_config: ThreadPoolConfig,
}
#[derive(Debug, Clone)]
pub struct ThreadPoolConfig {
pub core_size: usize,
pub max_size: usize,
pub keepalive_time: Duration,
pub queue_capacity: usize,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum FailureHandling {
StopOnFirstFailure,
ContinueOnFailure,
RetryFailedTests,
Custom(String),
}
#[derive(Debug, Clone)]
pub struct TestMetadata {
pub author: String,
pub created: SystemTime,
pub modified: SystemTime,
pub version: String,
pub tags: Vec<String>,
pub custom: HashMap<String, String>,
}