use std::collections::HashMap;
use std::sync::{Arc, Mutex, RwLock};
use super::config::IntegrationTestConfig;
use super::execution::TestExecutionEngine;
use super::monitoring::TestPerformanceMonitor;
use super::reporting::TestReportGenerator;
use super::results::TestResultStorage;
use super::scenarios::{IntegrationTestCase, TestRegistry};
pub struct ComprehensiveIntegrationTesting {
pub config: IntegrationTestConfig,
pub test_registry: Arc<RwLock<TestRegistry>>,
pub execution_engine: Arc<Mutex<TestExecutionEngine>>,
pub result_storage: Arc<Mutex<TestResultStorage>>,
pub performance_monitor: Arc<Mutex<TestPerformanceMonitor>>,
pub report_generator: Arc<Mutex<TestReportGenerator>>,
pub environment_manager: Arc<Mutex<TestEnvironmentManager>>,
}
impl ComprehensiveIntegrationTesting {
#[must_use]
pub fn new(config: IntegrationTestConfig) -> Self {
Self {
config: config.clone(),
test_registry: Arc::new(RwLock::new(TestRegistry::new())),
execution_engine: Arc::new(Mutex::new(TestExecutionEngine::new())),
result_storage: Arc::new(Mutex::new(TestResultStorage::new(
config.storage_config.clone(),
))),
performance_monitor: Arc::new(Mutex::new(TestPerformanceMonitor::new())),
report_generator: Arc::new(Mutex::new(TestReportGenerator::new())),
environment_manager: Arc::new(Mutex::new(TestEnvironmentManager::new(
config.environment_config,
))),
}
}
pub fn register_test_case(&self, test_case: IntegrationTestCase) -> Result<(), String> {
let mut registry = self
.test_registry
.write()
.map_err(|e| format!("failed to acquire write lock on test registry: {}", e))?;
registry.register_test_case(test_case)
}
pub async fn execute_all_tests(
&self,
) -> Result<Vec<super::results::IntegrationTestResult>, String> {
let registry = self
.test_registry
.read()
.map_err(|e| format!("failed to acquire read lock on test registry: {}", e))?;
let test_cases: Vec<_> = registry.test_cases.values().cloned().collect();
drop(registry);
let mut results = Vec::new();
let mut engine = self
.execution_engine
.lock()
.map_err(|e| format!("failed to acquire lock on execution engine: {}", e))?;
for test_case in test_cases {
let request = super::execution::TestExecutionRequest {
id: format!("exec_{}", test_case.id),
test_case,
priority: super::scenarios::TestPriority::Normal,
requested_time: std::time::SystemTime::now(),
context: super::execution::ExecutionContext {
parameters: std::collections::HashMap::new(),
environment: std::collections::HashMap::new(),
resources: super::execution::ResourceAllocation {
cpu_cores: 1,
memory_bytes: 1024 * 1024 * 1024, disk_bytes: 1024 * 1024 * 1024, network_bandwidth: None,
},
metadata: std::collections::HashMap::new(),
},
};
match engine.execute_test(request) {
Ok(exec_result) => {
results.push(exec_result.result);
}
Err(e) => {
return Err(format!("Failed to execute test: {e}"));
}
}
}
Ok(results)
}
pub async fn execute_test_suite(
&self,
suite_name: &str,
) -> Result<super::results::IntegrationTestResult, String> {
let registry = self
.test_registry
.read()
.map_err(|e| format!("failed to acquire read lock on test registry: {}", e))?;
let suite = registry
.test_suites
.get(suite_name)
.ok_or_else(|| format!("Test suite '{suite_name}' not found"))?
.clone();
drop(registry);
let mut engine = self
.execution_engine
.lock()
.map_err(|e| format!("failed to acquire lock on execution engine: {}", e))?;
let registry = self
.test_registry
.read()
.map_err(|e| format!("failed to acquire read lock on test registry: {}", e))?;
for test_case_id in &suite.test_cases {
if let Some(test_case) = registry.test_cases.get(test_case_id) {
let request = super::execution::TestExecutionRequest {
id: format!("exec_{suite_name}_{test_case_id}"),
test_case: test_case.clone(),
priority: super::scenarios::TestPriority::Normal,
requested_time: std::time::SystemTime::now(),
context: super::execution::ExecutionContext {
parameters: std::collections::HashMap::new(),
environment: std::collections::HashMap::new(),
resources: super::execution::ResourceAllocation {
cpu_cores: 1,
memory_bytes: 1024 * 1024 * 1024,
disk_bytes: 1024 * 1024 * 1024,
network_bandwidth: None,
},
metadata: std::collections::HashMap::new(),
},
};
engine.execute_test(request)?;
}
}
Ok(super::results::IntegrationTestResult {
test_case_id: suite_name.to_string(),
timestamp: std::time::SystemTime::now(),
outcome: super::results::TestOutcome::Passed,
performance_metrics: super::results::PerformanceMetrics {
execution_duration: std::time::Duration::from_secs(0),
setup_duration: std::time::Duration::from_secs(0),
cleanup_duration: std::time::Duration::from_secs(0),
peak_memory_usage: 0,
avg_cpu_usage: 0.0,
custom_metrics: std::collections::HashMap::new(),
},
validation_results: super::results::ValidationResults {
status: super::results::ValidationStatus::Passed,
validations: Vec::new(),
summary: super::results::ValidationSummary {
total: suite.test_cases.len(),
passed: suite.test_cases.len(),
failed: 0,
skipped: 0,
},
},
error_info: None,
artifacts: Vec::new(),
})
}
pub fn generate_report(&self) -> Result<String, String> {
let storage = self
.result_storage
.lock()
.map_err(|e| format!("failed to acquire lock on result storage: {}", e))?;
let stats = storage.get_statistics();
let report = format!(
"Comprehensive Integration Test Report\n\
=====================================\n\
\n\
Total Results: {}\n\
Storage Size: {} bytes\n\
Last Cleanup: {:?}\n\
Compression Ratio: {:.2}\n\
\n\
Recent Test Results:\n",
stats.total_results, stats.storage_size, stats.last_cleanup, stats.compression_ratio
);
Ok(report)
}
}
pub struct TestEnvironmentManager {
pub config: super::config::TestEnvironmentConfig,
pub active_environments: HashMap<String, TestEnvironment>,
}
impl TestEnvironmentManager {
#[must_use]
pub fn new(config: super::config::TestEnvironmentConfig) -> Self {
Self {
config,
active_environments: HashMap::new(),
}
}
pub fn create_environment(&mut self, id: String) -> Result<(), String> {
if self.active_environments.contains_key(&id) {
return Err(format!("Environment {id} already exists"));
}
let environment = TestEnvironment {
id: id.clone(),
status: EnvironmentStatus::Initializing,
resources: self.config.resource_allocation.clone(),
};
self.active_environments.insert(id, environment);
Ok(())
}
#[must_use]
pub fn get_environment(&self, id: &str) -> Option<&TestEnvironment> {
self.active_environments.get(id)
}
pub fn destroy_environment(&mut self, id: &str) -> Result<(), String> {
self.active_environments
.remove(id)
.ok_or_else(|| format!("Environment {id} not found"))?;
Ok(())
}
#[must_use]
pub fn list_environments(&self) -> Vec<&TestEnvironment> {
self.active_environments.values().collect()
}
pub fn update_environment_status(
&mut self,
id: &str,
status: EnvironmentStatus,
) -> Result<(), String> {
let env = self
.active_environments
.get_mut(id)
.ok_or_else(|| format!("Environment {id} not found"))?;
env.status = status;
Ok(())
}
#[must_use]
pub fn active_count(&self) -> usize {
self.active_environments.len()
}
pub fn clear_all(&mut self) {
self.active_environments.clear();
}
}
#[derive(Debug, Clone)]
pub struct TestEnvironment {
pub id: String,
pub status: EnvironmentStatus,
pub resources: super::config::ResourceAllocationConfig,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum EnvironmentStatus {
Initializing,
Ready,
Running,
Cleaning,
Stopped,
Error(String),
}