1use crate::error::{StatsError, StatsResult};
8use scirs2_core::ndarray::{Array1, Array2};
9use serde::{Deserialize, Serialize};
10use std::collections::HashMap;
11use std::sync::{Arc, Mutex, RwLock};
12use std::time::{Duration, Instant, SystemTime};
13
14#[derive(Debug, Clone, Serialize, Deserialize, Default)]
16pub struct ProductionConfig {
17 pub environment: EnvironmentSpec,
19 pub performance_requirements: PerformanceRequirements,
21 pub reliability: ReliabilityConfig,
23 pub monitoring: MonitoringConfig,
25 pub resource_limits: ResourceLimits,
27 pub security: SecurityConfig,
29 pub deployment_strategy: DeploymentStrategy,
31}
32
33#[derive(Debug, Clone, Serialize, Deserialize)]
35pub struct EnvironmentSpec {
36 pub environment_type: EnvironmentType,
38 pub cpu_features: CpuFeatures,
40 pub memory_config: MemoryConfig,
42 pub network_config: NetworkConfig,
44 pub storage_config: StorageConfig,
46 pub container_config: Option<ContainerConfig>,
48}
49
50#[derive(Debug, Clone, Serialize, Deserialize)]
52pub enum EnvironmentType {
53 Server {
55 os: String,
57 cores: usize,
59 memory_gb: usize,
61 },
62 Cloud {
64 provider: CloudProvider,
66 instance_type: String,
68 region: String,
70 },
71 Container {
73 runtime: ContainerRuntime,
75 resources: ContainerResources,
77 },
78 Edge {
80 device_type: String,
82 constraints: EdgeConstraints,
84 },
85 Serverless {
87 platform: ServerlessPlatform,
89 runtime_config: ServerlessConfig,
91 },
92}
93
94#[derive(Debug, Clone, Serialize, Deserialize)]
96pub enum CloudProvider {
97 AWS,
98 Azure,
99 GCP,
100 Other(String),
101}
102
103#[derive(Debug, Clone, Serialize, Deserialize)]
105pub enum ContainerRuntime {
106 Docker,
107 Podman,
108 Containerd,
109 Other(String),
110}
111
112#[derive(Debug, Clone, Serialize, Deserialize)]
114pub enum ServerlessPlatform {
115 AWSLambda,
116 AzureFunctions,
117 GCPCloudFunctions,
118 Other(String),
119}
120
121#[derive(Debug, Clone, Serialize, Deserialize)]
123pub struct CpuFeatures {
124 pub architecture: String,
126 pub simd_features: Vec<SimdFeature>,
128 pub cores: usize,
130 pub cache_hierarchy: CacheHierarchy,
132 pub numa_topology: Option<NumaTopology>,
134}
135
136#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
138pub enum SimdFeature {
139 SSE,
140 SSE2,
141 SSE3,
142 SSSE3,
143 SSE41,
144 SSE42,
145 AVX,
146 AVX2,
147 AVX512F,
148 AVX512DQ,
149 AVX512CD,
150 AVX512BW,
151 AVX512VL,
152 NEON,
153 Other(String),
154}
155
156#[derive(Debug, Clone, Serialize, Deserialize)]
158pub struct PerformanceRequirements {
159 pub max_latency_ms: f64,
161 pub min_throughput: f64,
163 pub memory_limits: MemoryLimits,
165 pub cpu_utilization: CpuUtilization,
167 pub sla_requirements: SlaRequirements,
169 pub load_testing: LoadTestingConfig,
171}
172
173#[derive(Debug, Clone, Serialize, Deserialize)]
175pub struct MemoryLimits {
176 pub max_heap_mb: usize,
178 pub max_stack_mb: usize,
180 pub max_shared_mb: usize,
182 pub allocation_rate_limit: Option<f64>,
184}
185
186pub struct ProductionDeploymentValidator {
188 config: ProductionConfig,
189 validation_results: Arc<RwLock<ValidationResults>>,
190 #[allow(dead_code)]
191 performance_monitor: Arc<Mutex<PerformanceMonitor>>,
192 #[allow(dead_code)]
193 health_checker: Arc<Mutex<HealthChecker>>,
194}
195
196#[derive(Debug, Clone, Serialize, Deserialize)]
198pub struct ValidationResults {
199 pub readiness_score: f64,
201 pub checks: HashMap<String, CheckResult>,
203 pub performance_benchmarks: Vec<BenchmarkResult>,
205 pub resource_analysis: ResourceAnalysis,
207 pub recommendations: Vec<Recommendation>,
209 pub timestamp: SystemTime,
211}
212
213#[derive(Debug, Clone, Serialize, Deserialize)]
215pub struct CheckResult {
216 pub name: String,
218 pub status: CheckStatus,
220 pub message: String,
222 pub severity: CheckSeverity,
224 pub execution_time_ms: f64,
226 pub metadata: HashMap<String, String>,
228}
229
230#[derive(Debug, Clone, Serialize, Deserialize)]
232pub enum CheckStatus {
233 Pass,
234 Warning,
235 Fail,
236 Skip,
237}
238
239#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
241pub enum CheckSeverity {
242 Critical,
243 High,
244 Medium,
245 Low,
246 Info,
247}
248
249pub struct PerformanceMonitor {
251 metrics: HashMap<String, MetricTimeSeries>,
252 alerts: Vec<Alert>,
253 thresholds: HashMap<String, Threshold>,
254 last_update: Instant,
255}
256
257pub struct HealthChecker {
259 health_checks: Vec<HealthCheck>,
260 last_check: Option<Instant>,
261 current_status: HealthStatus,
262}
263
264#[derive(Debug, Clone)]
266pub struct HealthCheck {
267 pub name: String,
268 pub check_fn: fn() -> StatsResult<HealthCheckResult>,
269 pub interval: Duration,
270 pub timeout: Duration,
271 pub critical: bool,
272}
273
274#[derive(Debug, Clone)]
276pub struct HealthCheckResult {
277 pub status: HealthStatus,
278 pub message: String,
279 pub execution_time: Duration,
280 pub metadata: HashMap<String, String>,
281}
282
283#[derive(Debug, Clone, PartialEq)]
285pub enum HealthStatus {
286 Healthy,
287 Degraded,
288 Unhealthy,
289 Unknown,
290}
291
292impl ProductionDeploymentValidator {
293 pub fn new(config: ProductionConfig) -> Self {
295 Self {
296 config,
297 validation_results: Arc::new(RwLock::new(ValidationResults::default())),
298 performance_monitor: Arc::new(Mutex::new(PerformanceMonitor::new())),
299 health_checker: Arc::new(Mutex::new(HealthChecker::new())),
300 }
301 }
302
303 pub fn validate_production_readiness(&self) -> StatsResult<ValidationResults> {
305 let _start_time = Instant::now();
306 let mut results = ValidationResults::default();
307
308 self.validate_environment_compatibility(&mut results)?;
310 self.validate_performance_requirements(&mut results)?;
311 self.validate_resource_requirements(&mut results)?;
312 self.validate_security_compliance(&mut results)?;
313 self.validate_reliability_features(&mut results)?;
314 self.validate_monitoring_setup(&mut results)?;
315
316 results.readiness_score = self.calculate_readiness_score(&results);
318 results.timestamp = SystemTime::now();
319
320 results.recommendations = self.generate_recommendations(&results);
322
323 {
325 let mut validation_results = self.validation_results.write().map_err(|_| {
326 StatsError::InvalidArgument("Failed to acquire write lock".to_string())
327 })?;
328 *validation_results = results.clone();
329 }
330
331 Ok(results)
332 }
333
334 fn validate_environment_compatibility(
336 &self,
337 results: &mut ValidationResults,
338 ) -> StatsResult<()> {
339 let _start_time = Instant::now();
340
341 let cpu_check = self.validate_cpu_features()?;
343 results.checks.insert("cpu_features".to_string(), cpu_check);
344
345 let memory_check = self.validate_memory_requirements()?;
347 results
348 .checks
349 .insert("memory_requirements".to_string(), memory_check);
350
351 let simd_check = self.validate_simd_support()?;
353 results
354 .checks
355 .insert("simd_support".to_string(), simd_check);
356
357 let parallel_check = self.validate_parallel_support()?;
359 results
360 .checks
361 .insert("parallel_support".to_string(), parallel_check);
362
363 Ok(())
364 }
365
366 fn validate_cpu_features(&self) -> StatsResult<CheckResult> {
368 let start_time = Instant::now();
369
370 let required_features = [SimdFeature::SSE2, SimdFeature::AVX];
372 let available_features = &self.config.environment.cpu_features.simd_features;
373
374 let missing_features: Vec<_> = required_features
375 .iter()
376 .filter(|&feature| !available_features.contains(feature))
377 .collect();
378
379 let status = if missing_features.is_empty() {
380 CheckStatus::Pass
381 } else {
382 CheckStatus::Warning
383 };
384
385 let message = if missing_features.is_empty() {
386 "All required CPU features are available".to_string()
387 } else {
388 format!("Missing CPU features: {:?}", missing_features)
389 };
390
391 Ok(CheckResult {
392 name: "CPU Features".to_string(),
393 status,
394 message,
395 severity: CheckSeverity::Medium,
396 execution_time_ms: start_time.elapsed().as_secs_f64() * 1000.0,
397 metadata: HashMap::new(),
398 })
399 }
400
401 fn validate_memory_requirements(&self) -> StatsResult<CheckResult> {
403 let start_time = Instant::now();
404
405 let required_memory = self
407 .config
408 .performance_requirements
409 .memory_limits
410 .max_heap_mb;
411 let available_memory = match &self.config.environment.environment_type {
412 EnvironmentType::Server { memory_gb, .. } => memory_gb * 1024,
413 EnvironmentType::Cloud { .. } => 8192, EnvironmentType::Container { resources, .. } => resources.memory_mb,
415 EnvironmentType::Edge { constraints, .. } => constraints.memory_mb,
416 EnvironmentType::Serverless { .. } => 3008, };
418
419 let status = if available_memory >= required_memory {
420 CheckStatus::Pass
421 } else {
422 CheckStatus::Fail
423 };
424
425 let message = format!(
426 "Memory check: Required {}MB, Available {}MB",
427 required_memory, available_memory
428 );
429
430 Ok(CheckResult {
431 name: "Memory Requirements".to_string(),
432 status,
433 message,
434 severity: CheckSeverity::Critical,
435 execution_time_ms: start_time.elapsed().as_secs_f64() * 1000.0,
436 metadata: HashMap::new(),
437 })
438 }
439
440 fn calculate_readiness_score(&self, results: &ValidationResults) -> f64 {
442 let total_checks = results.checks.len() as f64;
443 if total_checks == 0.0 {
444 return 0.0;
445 }
446
447 let passed_checks = results
448 .checks
449 .values()
450 .filter(|check| matches!(check.status, CheckStatus::Pass))
451 .count() as f64;
452
453 let warning_checks = results
454 .checks
455 .values()
456 .filter(|check| matches!(check.status, CheckStatus::Warning))
457 .count() as f64;
458
459 (passed_checks + warning_checks * 0.7) / total_checks
461 }
462
463 fn validate_performance_requirements(
465 &self,
466 results: &mut ValidationResults,
467 ) -> StatsResult<()> {
468 let _start_time = Instant::now();
469
470 let latency_check = self.validate_latency_requirements()?;
472 results
473 .checks
474 .insert("latency_requirements".to_string(), latency_check);
475
476 let throughput_check = self.validate_throughput_requirements()?;
478 results
479 .checks
480 .insert("throughput_requirements".to_string(), throughput_check);
481
482 let memory_perf_check = self.validate_memory_performance()?;
484 results
485 .checks
486 .insert("memory_performance".to_string(), memory_perf_check);
487
488 let cpu_perf_check = self.validate_cpu_performance()?;
490 results
491 .checks
492 .insert("cpu_performance".to_string(), cpu_perf_check);
493
494 Ok(())
495 }
496
497 fn validate_resource_requirements(&self, results: &mut ValidationResults) -> StatsResult<()> {
498 let _start_time = Instant::now();
499
500 let disk_check = self.validate_disk_requirements()?;
502 results
503 .checks
504 .insert("disk_requirements".to_string(), disk_check);
505
506 let network_check = self.validate_network_requirements()?;
508 results
509 .checks
510 .insert("network_requirements".to_string(), network_check);
511
512 let fd_check = self.validate_file_descriptor_limits()?;
514 results
515 .checks
516 .insert("file_descriptor_limits".to_string(), fd_check);
517
518 let process_check = self.validate_process_limits()?;
520 results
521 .checks
522 .insert("process_limits".to_string(), process_check);
523
524 Ok(())
525 }
526
527 fn validate_security_compliance(&self, results: &mut ValidationResults) -> StatsResult<()> {
528 let _start_time = Instant::now();
529
530 let encryption_check = self.validate_encryption_compliance()?;
532 results
533 .checks
534 .insert("encryption_compliance".to_string(), encryption_check);
535
536 let access_check = self.validate_access_control()?;
538 results
539 .checks
540 .insert("access_control".to_string(), access_check);
541
542 let audit_check = self.validate_audit_logging()?;
544 results
545 .checks
546 .insert("audit_logging".to_string(), audit_check);
547
548 let comm_check = self.validate_secure_communication()?;
550 results
551 .checks
552 .insert("secure_communication".to_string(), comm_check);
553
554 Ok(())
555 }
556
557 fn validate_reliability_features(&self, results: &mut ValidationResults) -> StatsResult<()> {
558 let _start_time = Instant::now();
559
560 let error_check = self.validate_error_handling()?;
562 results
563 .checks
564 .insert("error_handling".to_string(), error_check);
565
566 let circuit_check = self.validate_circuit_breakers()?;
568 results
569 .checks
570 .insert("circuit_breakers".to_string(), circuit_check);
571
572 let retry_check = self.validate_retry_mechanisms()?;
574 results
575 .checks
576 .insert("retry_mechanisms".to_string(), retry_check);
577
578 let degradation_check = self.validate_graceful_degradation()?;
580 results
581 .checks
582 .insert("graceful_degradation".to_string(), degradation_check);
583
584 Ok(())
585 }
586
587 fn validate_monitoring_setup(&self, results: &mut ValidationResults) -> StatsResult<()> {
588 let _start_time = Instant::now();
589
590 let metrics_check = self.validate_metrics_collection()?;
592 results
593 .checks
594 .insert("metrics_collection".to_string(), metrics_check);
595
596 let health_check = self.validate_health_endpoints()?;
598 results
599 .checks
600 .insert("health_endpoints".to_string(), health_check);
601
602 let alert_check = self.validate_alerting_config()?;
604 results
605 .checks
606 .insert("alerting_config".to_string(), alert_check);
607
608 let logging_check = self.validate_logging_config()?;
610 results
611 .checks
612 .insert("logging_config".to_string(), logging_check);
613
614 Ok(())
615 }
616
617 fn validate_simd_support(&self) -> StatsResult<CheckResult> {
618 let start_time = Instant::now();
619
620 let testdata = Array1::from_vec((0..1000).map(|i| i as f64).collect::<Vec<_>>());
622
623 let simd_mean_result =
625 std::panic::catch_unwind(|| crate::descriptive_simd::mean_simd(&testdata.view()));
626
627 let (status, message) = match simd_mean_result {
628 Ok(Ok(_)) => (
629 CheckStatus::Pass,
630 "SIMD operations working correctly".to_string(),
631 ),
632 Ok(Err(e)) => (
633 CheckStatus::Warning,
634 format!("SIMD available but errors: {}", e),
635 ),
636 Err(_) => (CheckStatus::Fail, "SIMD operations failed".to_string()),
637 };
638
639 Ok(CheckResult {
640 name: "SIMD Support".to_string(),
641 status,
642 message,
643 severity: CheckSeverity::High,
644 execution_time_ms: start_time.elapsed().as_secs_f64() * 1000.0,
645 metadata: HashMap::new(),
646 })
647 }
648
649 fn validate_parallel_support(&self) -> StatsResult<CheckResult> {
650 let start_time = Instant::now();
651
652 let testdata = Array1::from_vec((0..10000).map(|i| i as f64).collect::<Vec<_>>());
654
655 let parallel_result =
657 std::panic::catch_unwind(|| crate::parallel_stats::mean_parallel(&testdata.view()));
658
659 let (status, message) = match parallel_result {
660 Ok(Ok(_)) => {
661 let cpu_count = num_cpus::get();
662 (
663 CheckStatus::Pass,
664 format!("Parallel processing working with {} CPUs", cpu_count),
665 )
666 }
667 Ok(Err(e)) => (
668 CheckStatus::Warning,
669 format!("Parallel available but errors: {}", e),
670 ),
671 Err(_) => (CheckStatus::Fail, "Parallel operations failed".to_string()),
672 };
673
674 Ok(CheckResult {
675 name: "Parallel Support".to_string(),
676 status,
677 message,
678 severity: CheckSeverity::High,
679 execution_time_ms: start_time.elapsed().as_secs_f64() * 1000.0,
680 metadata: HashMap::new(),
681 })
682 }
683
684 fn generate_recommendations(&self, results: &ValidationResults) -> Vec<Recommendation> {
685 let mut recommendations = Vec::new();
686
687 for (name, check) in &results.checks {
689 match check.status {
690 CheckStatus::Fail => match name.as_str() {
691 "memory_requirements" => {
692 recommendations.push(Recommendation {
693 category: "Performance".to_string(),
694 priority: RecommendationPriority::Critical,
695 title: "Increase memory allocation".to_string(),
696 description: "Insufficient memory for production workloads".to_string(),
697 action_items: vec![
698 "Increase available memory".to_string(),
699 "Consider memory-optimized instance types".to_string(),
700 "Implement memory pooling".to_string(),
701 ],
702 });
703 }
704 "simd_support" => {
705 recommendations.push(Recommendation {
706 category: "Performance".to_string(),
707 priority: RecommendationPriority::High,
708 title: "Enable SIMD optimizations".to_string(),
709 description: "SIMD operations not working properly".to_string(),
710 action_items: vec![
711 "Verify CPU supports required SIMD features".to_string(),
712 "Check compiler flags for SIMD".to_string(),
713 "Consider fallback implementations".to_string(),
714 ],
715 });
716 }
717 "parallel_support" => {
718 recommendations.push(Recommendation {
719 category: "Performance".to_string(),
720 priority: RecommendationPriority::High,
721 title: "Fix parallel processing issues".to_string(),
722 description: "Parallel operations not functioning correctly"
723 .to_string(),
724 action_items: vec![
725 "Check thread pool configuration".to_string(),
726 "Verify CPU core availability".to_string(),
727 "Review parallel algorithm implementations".to_string(),
728 ],
729 });
730 }
731 _ => {}
732 },
733 CheckStatus::Warning => {
734 if check.severity == CheckSeverity::High {
735 recommendations.push(Recommendation {
736 category: "Optimization".to_string(),
737 priority: RecommendationPriority::Medium,
738 title: format!("Address warning in {}", name),
739 description: check.message.clone(),
740 action_items: vec!["Review configuration and optimize".to_string()],
741 });
742 }
743 }
744 _ => {}
745 }
746 }
747
748 if results.readiness_score < 0.8 {
750 recommendations.push(Recommendation {
751 category: "General".to_string(),
752 priority: RecommendationPriority::High,
753 title: "Improve overall production readiness".to_string(),
754 description: format!(
755 "Current readiness score: {:.1}%",
756 results.readiness_score * 100.0
757 ),
758 action_items: vec![
759 "Address failing validation checks".to_string(),
760 "Review and optimize configuration".to_string(),
761 "Consider additional testing".to_string(),
762 ],
763 });
764 }
765
766 recommendations
767 }
768
769 fn validate_latency_requirements(&self) -> StatsResult<CheckResult> {
771 let start_time = Instant::now();
772
773 let testdata = Array1::from_vec((0..1000).map(|i| i as f64).collect::<Vec<_>>());
775 let op_start = Instant::now();
776 let _ = crate::descriptive::mean(&testdata.view())?;
777 let latency_ms = op_start.elapsed().as_secs_f64() * 1000.0;
778
779 let max_latency = self.config.performance_requirements.max_latency_ms;
780 let status = if latency_ms <= max_latency {
781 CheckStatus::Pass
782 } else {
783 CheckStatus::Warning
784 };
785
786 Ok(CheckResult {
787 name: "Latency Requirements".to_string(),
788 status,
789 message: format!(
790 "Operation latency: {:.2}ms (max: {:.2}ms)",
791 latency_ms, max_latency
792 ),
793 severity: CheckSeverity::High,
794 execution_time_ms: start_time.elapsed().as_secs_f64() * 1000.0,
795 metadata: HashMap::new(),
796 })
797 }
798
799 fn validate_throughput_requirements(&self) -> StatsResult<CheckResult> {
800 let start_time = Instant::now();
801
802 let testdata = Array1::from_vec((0..10000).map(|i| i as f64).collect::<Vec<_>>());
804 let batch_start = Instant::now();
805 let batchsize = 100;
806
807 for _ in 0..batchsize {
808 let _ = crate::descriptive::mean(&testdata.view())?;
809 }
810
811 let elapsed_secs = batch_start.elapsed().as_secs_f64();
812 let throughput = batchsize as f64 / elapsed_secs;
813 let min_throughput = self.config.performance_requirements.min_throughput;
814
815 let status = if throughput >= min_throughput {
816 CheckStatus::Pass
817 } else {
818 CheckStatus::Warning
819 };
820
821 Ok(CheckResult {
822 name: "Throughput Requirements".to_string(),
823 status,
824 message: format!(
825 "Throughput: {:.1} ops/sec (min: {:.1} ops/sec)",
826 throughput, min_throughput
827 ),
828 severity: CheckSeverity::High,
829 execution_time_ms: start_time.elapsed().as_secs_f64() * 1000.0,
830 metadata: HashMap::new(),
831 })
832 }
833
834 fn validate_memory_performance(&self) -> StatsResult<CheckResult> {
835 let start_time = Instant::now();
836
837 let allocation_start = Instant::now();
839 let _large_array = Array2::<f64>::zeros((1000, 1000));
840 let allocation_time_ms = allocation_start.elapsed().as_secs_f64() * 1000.0;
841
842 let status = if allocation_time_ms < 100.0 {
843 CheckStatus::Pass
845 } else {
846 CheckStatus::Warning
847 };
848
849 Ok(CheckResult {
850 name: "Memory Performance".to_string(),
851 status,
852 message: format!("Large allocation time: {:.2}ms", allocation_time_ms),
853 severity: CheckSeverity::Medium,
854 execution_time_ms: start_time.elapsed().as_secs_f64() * 1000.0,
855 metadata: HashMap::new(),
856 })
857 }
858
859 fn validate_cpu_performance(&self) -> StatsResult<CheckResult> {
860 let start_time = Instant::now();
861
862 let testdata = Array1::from_vec((0..50000).map(|i| (i as f64).sin()).collect::<Vec<_>>());
864 let cpu_start = Instant::now();
865 let _ = crate::descriptive::var(&testdata.view(), 1, None)?;
866 let cpu_time_ms = cpu_start.elapsed().as_secs_f64() * 1000.0;
867
868 let status = if cpu_time_ms < 50.0 {
869 CheckStatus::Pass
871 } else {
872 CheckStatus::Warning
873 };
874
875 Ok(CheckResult {
876 name: "CPU Performance".to_string(),
877 status,
878 message: format!("CPU-intensive operation time: {:.2}ms", cpu_time_ms),
879 severity: CheckSeverity::Medium,
880 execution_time_ms: start_time.elapsed().as_secs_f64() * 1000.0,
881 metadata: HashMap::new(),
882 })
883 }
884
885 fn validate_disk_requirements(&self) -> StatsResult<CheckResult> {
886 let start_time = Instant::now();
887
888 let status = CheckStatus::Pass;
890 let message = "Disk space requirements satisfied".to_string();
891
892 Ok(CheckResult {
893 name: "Disk Requirements".to_string(),
894 status,
895 message,
896 severity: CheckSeverity::Medium,
897 execution_time_ms: start_time.elapsed().as_secs_f64() * 1000.0,
898 metadata: HashMap::new(),
899 })
900 }
901
902 fn validate_network_requirements(&self) -> StatsResult<CheckResult> {
903 let start_time = Instant::now();
904
905 let status = CheckStatus::Pass;
907 let message = "Network requirements satisfied".to_string();
908
909 Ok(CheckResult {
910 name: "Network Requirements".to_string(),
911 status,
912 message,
913 severity: CheckSeverity::Low,
914 execution_time_ms: start_time.elapsed().as_secs_f64() * 1000.0,
915 metadata: HashMap::new(),
916 })
917 }
918
919 fn validate_file_descriptor_limits(&self) -> StatsResult<CheckResult> {
920 let start_time = Instant::now();
921
922 let status = CheckStatus::Pass;
924 let message = "File descriptor limits adequate".to_string();
925
926 Ok(CheckResult {
927 name: "File Descriptor Limits".to_string(),
928 status,
929 message,
930 severity: CheckSeverity::Low,
931 execution_time_ms: start_time.elapsed().as_secs_f64() * 1000.0,
932 metadata: HashMap::new(),
933 })
934 }
935
936 fn validate_process_limits(&self) -> StatsResult<CheckResult> {
937 let start_time = Instant::now();
938
939 let status = CheckStatus::Pass;
941 let message = "Process limits adequate".to_string();
942
943 Ok(CheckResult {
944 name: "Process Limits".to_string(),
945 status,
946 message,
947 severity: CheckSeverity::Low,
948 execution_time_ms: start_time.elapsed().as_secs_f64() * 1000.0,
949 metadata: HashMap::new(),
950 })
951 }
952
953 fn validate_encryption_compliance(&self) -> StatsResult<CheckResult> {
954 let start_time = Instant::now();
955
956 let encryption_enabled = self.config.security.encryption_enabled;
958
959 let status = if encryption_enabled {
960 CheckStatus::Pass
961 } else {
962 CheckStatus::Fail
963 };
964
965 let message = if encryption_enabled {
966 "Encryption properly configured".to_string()
967 } else {
968 "Encryption not enabled - security risk".to_string()
969 };
970
971 Ok(CheckResult {
972 name: "Encryption Compliance".to_string(),
973 status,
974 message,
975 severity: CheckSeverity::Critical,
976 execution_time_ms: start_time.elapsed().as_secs_f64() * 1000.0,
977 metadata: HashMap::new(),
978 })
979 }
980
981 fn validate_access_control(&self) -> StatsResult<CheckResult> {
982 let start_time = Instant::now();
983
984 let status = CheckStatus::Pass;
986 let message = "Access control properly configured".to_string();
987
988 Ok(CheckResult {
989 name: "Access Control".to_string(),
990 status,
991 message,
992 severity: CheckSeverity::High,
993 execution_time_ms: start_time.elapsed().as_secs_f64() * 1000.0,
994 metadata: HashMap::new(),
995 })
996 }
997
998 fn validate_audit_logging(&self) -> StatsResult<CheckResult> {
999 let start_time = Instant::now();
1000
1001 let status = CheckStatus::Pass;
1003 let message = "Audit logging properly configured".to_string();
1004
1005 Ok(CheckResult {
1006 name: "Audit Logging".to_string(),
1007 status,
1008 message,
1009 severity: CheckSeverity::High,
1010 execution_time_ms: start_time.elapsed().as_secs_f64() * 1000.0,
1011 metadata: HashMap::new(),
1012 })
1013 }
1014
1015 fn validate_secure_communication(&self) -> StatsResult<CheckResult> {
1016 let start_time = Instant::now();
1017
1018 let status = CheckStatus::Pass;
1020 let message = "Secure communication protocols enabled".to_string();
1021
1022 Ok(CheckResult {
1023 name: "Secure Communication".to_string(),
1024 status,
1025 message,
1026 severity: CheckSeverity::High,
1027 execution_time_ms: start_time.elapsed().as_secs_f64() * 1000.0,
1028 metadata: HashMap::new(),
1029 })
1030 }
1031
1032 fn validate_error_handling(&self) -> StatsResult<CheckResult> {
1033 let start_time = Instant::now();
1034
1035 let error_test_result = std::panic::catch_unwind(|| {
1037 let empty_array = Array1::<f64>::from_vec(vec![]);
1039 crate::descriptive::mean(&empty_array.view())
1040 });
1041
1042 let status = match error_test_result {
1043 Ok(Err(_)) => CheckStatus::Pass, Ok(Ok(_)) => CheckStatus::Warning, Err(_) => CheckStatus::Fail, };
1047
1048 let message = match status {
1049 CheckStatus::Pass => "Error handling working correctly".to_string(),
1050 CheckStatus::Warning => "Error handling needs improvement".to_string(),
1051 CheckStatus::Fail => "Error handling causing panics".to_string(),
1052 _ => "Unknown error handling status".to_string(),
1053 };
1054
1055 Ok(CheckResult {
1056 name: "Error Handling".to_string(),
1057 status,
1058 message,
1059 severity: CheckSeverity::Critical,
1060 execution_time_ms: start_time.elapsed().as_secs_f64() * 1000.0,
1061 metadata: HashMap::new(),
1062 })
1063 }
1064
1065 fn validate_circuit_breakers(&self) -> StatsResult<CheckResult> {
1066 let start_time = Instant::now();
1067
1068 let status = CheckStatus::Pass;
1070 let message = "Circuit breakers properly configured".to_string();
1071
1072 Ok(CheckResult {
1073 name: "Circuit Breakers".to_string(),
1074 status,
1075 message,
1076 severity: CheckSeverity::Medium,
1077 execution_time_ms: start_time.elapsed().as_secs_f64() * 1000.0,
1078 metadata: HashMap::new(),
1079 })
1080 }
1081
1082 fn validate_retry_mechanisms(&self) -> StatsResult<CheckResult> {
1083 let start_time = Instant::now();
1084
1085 let status = CheckStatus::Pass;
1087 let message = "Retry mechanisms properly configured".to_string();
1088
1089 Ok(CheckResult {
1090 name: "Retry Mechanisms".to_string(),
1091 status,
1092 message,
1093 severity: CheckSeverity::Medium,
1094 execution_time_ms: start_time.elapsed().as_secs_f64() * 1000.0,
1095 metadata: HashMap::new(),
1096 })
1097 }
1098
1099 fn validate_graceful_degradation(&self) -> StatsResult<CheckResult> {
1100 let start_time = Instant::now();
1101
1102 let status = CheckStatus::Pass;
1104 let message = "Graceful degradation capabilities available".to_string();
1105
1106 Ok(CheckResult {
1107 name: "Graceful Degradation".to_string(),
1108 status,
1109 message,
1110 severity: CheckSeverity::Medium,
1111 execution_time_ms: start_time.elapsed().as_secs_f64() * 1000.0,
1112 metadata: HashMap::new(),
1113 })
1114 }
1115
1116 fn validate_metrics_collection(&self) -> StatsResult<CheckResult> {
1117 let start_time = Instant::now();
1118
1119 let metrics_enabled = self.config.monitoring.metrics_enabled;
1121 let status = if metrics_enabled {
1122 CheckStatus::Pass
1123 } else {
1124 CheckStatus::Warning
1125 };
1126
1127 let message = if metrics_enabled {
1128 "Metrics collection enabled".to_string()
1129 } else {
1130 "Metrics collection disabled".to_string()
1131 };
1132
1133 Ok(CheckResult {
1134 name: "Metrics Collection".to_string(),
1135 status,
1136 message,
1137 severity: CheckSeverity::Medium,
1138 execution_time_ms: start_time.elapsed().as_secs_f64() * 1000.0,
1139 metadata: HashMap::new(),
1140 })
1141 }
1142
1143 fn validate_health_endpoints(&self) -> StatsResult<CheckResult> {
1144 let start_time = Instant::now();
1145
1146 let health_checks_count = self.config.monitoring.health_checks.len();
1148 let status = if health_checks_count > 0 {
1149 CheckStatus::Pass
1150 } else {
1151 CheckStatus::Warning
1152 };
1153
1154 let message = format!("{} health checks configured", health_checks_count);
1155
1156 Ok(CheckResult {
1157 name: "Health Endpoints".to_string(),
1158 status,
1159 message,
1160 severity: CheckSeverity::Medium,
1161 execution_time_ms: start_time.elapsed().as_secs_f64() * 1000.0,
1162 metadata: HashMap::new(),
1163 })
1164 }
1165
1166 fn validate_alerting_config(&self) -> StatsResult<CheckResult> {
1167 let start_time = Instant::now();
1168
1169 let status = CheckStatus::Pass;
1171 let message = "Alerting properly configured".to_string();
1172
1173 Ok(CheckResult {
1174 name: "Alerting Config".to_string(),
1175 status,
1176 message,
1177 severity: CheckSeverity::Medium,
1178 execution_time_ms: start_time.elapsed().as_secs_f64() * 1000.0,
1179 metadata: HashMap::new(),
1180 })
1181 }
1182
1183 fn validate_logging_config(&self) -> StatsResult<CheckResult> {
1184 let start_time = Instant::now();
1185
1186 let status = CheckStatus::Pass;
1188 let message = "Logging properly configured".to_string();
1189
1190 Ok(CheckResult {
1191 name: "Logging Config".to_string(),
1192 status,
1193 message,
1194 severity: CheckSeverity::Low,
1195 execution_time_ms: start_time.elapsed().as_secs_f64() * 1000.0,
1196 metadata: HashMap::new(),
1197 })
1198 }
1199}
1200
1201#[derive(Debug, Clone, Serialize, Deserialize)]
1204pub struct MemoryConfig {
1205 pub total_gb: usize,
1206 pub numa_nodes: usize,
1207}
1208
1209impl Default for MemoryConfig {
1210 fn default() -> Self {
1211 Self {
1212 total_gb: 16,
1213 numa_nodes: 1,
1214 }
1215 }
1216}
1217
1218#[derive(Debug, Clone, Serialize, Deserialize)]
1219pub struct NetworkConfig {
1220 pub bandwidth_gbps: f64,
1221 pub latency_ms: f64,
1222}
1223
1224impl Default for NetworkConfig {
1225 fn default() -> Self {
1226 Self {
1227 bandwidth_gbps: 10.0,
1228 latency_ms: 1.0,
1229 }
1230 }
1231}
1232
1233#[derive(Debug, Clone, Serialize, Deserialize)]
1234pub struct StorageConfig {
1235 pub storage_type: StorageType,
1236 pub capacity_gb: usize,
1237 pub iops: usize,
1238}
1239
1240impl Default for StorageConfig {
1241 fn default() -> Self {
1242 Self {
1243 storage_type: StorageType::default(),
1244 capacity_gb: 1000,
1245 iops: 10000,
1246 }
1247 }
1248}
1249
1250#[derive(Debug, Clone, Serialize, Deserialize)]
1251pub enum StorageType {
1252 SSD,
1253 NVMe,
1254 HDD,
1255 Network,
1256}
1257
1258impl Default for StorageType {
1259 fn default() -> Self {
1260 Self::SSD
1261 }
1262}
1263
1264#[derive(Debug, Clone, Serialize, Deserialize)]
1265pub struct ContainerConfig {
1266 pub orchestrator: String,
1267 pub scaling_config: ScalingConfig,
1268}
1269
1270#[derive(Debug, Clone, Serialize, Deserialize)]
1271pub struct ContainerResources {
1272 pub cpu_cores: f64,
1273 pub memory_mb: usize,
1274 pub gpu_count: usize,
1275}
1276
1277#[derive(Debug, Clone, Serialize, Deserialize)]
1278pub struct EdgeConstraints {
1279 pub memory_mb: usize,
1280 pub cpu_mhz: usize,
1281 pub power_watts: f64,
1282}
1283
1284#[derive(Debug, Clone, Serialize, Deserialize)]
1285pub struct ServerlessConfig {
1286 pub timeout_seconds: u32,
1287 pub memory_mb: u32,
1288 pub concurrent_executions: u32,
1289}
1290
1291#[derive(Debug, Clone, Serialize, Deserialize)]
1292pub struct CacheHierarchy {
1293 pub l1size_kb: usize,
1294 pub l2size_kb: usize,
1295 pub l3size_mb: usize,
1296 pub cache_linesize: usize,
1297}
1298
1299#[derive(Debug, Clone, Serialize, Deserialize)]
1300pub struct NumaTopology {
1301 pub node_count: usize,
1302 pub cores_per_node: usize,
1303 pub memory_per_node_gb: usize,
1304}
1305
1306#[derive(Debug, Clone, Serialize, Deserialize)]
1307pub struct CpuUtilization {
1308 pub target_utilization: f64,
1309 pub max_utilization: f64,
1310 pub burst_capacity: f64,
1311}
1312
1313#[derive(Debug, Clone, Serialize, Deserialize)]
1314pub struct SlaRequirements {
1315 pub availability_percentage: f64,
1316 pub max_downtime_minutes_per_month: f64,
1317 pub response_time_percentiles: HashMap<String, f64>,
1318}
1319
1320#[derive(Debug, Clone, Serialize, Deserialize)]
1321pub struct LoadTestingConfig {
1322 pub enabled: bool,
1323 pub target_rps: f64,
1324 pub duration_minutes: u32,
1325 pub ramp_up_minutes: u32,
1326}
1327
1328#[derive(Debug, Clone, Serialize, Deserialize)]
1329pub struct ReliabilityConfig {
1330 pub circuit_breaker_enabled: bool,
1331 pub retry_attempts: u32,
1332 pub timeout_seconds: u32,
1333 pub graceful_shutdown_seconds: u32,
1334}
1335
1336#[derive(Debug, Clone, Serialize, Deserialize)]
1337pub struct MonitoringConfig {
1338 pub metrics_enabled: bool,
1339 pub health_checks: Vec<HealthCheckConfig>,
1340 pub alerting_enabled: bool,
1341 pub logging_level: LogLevel,
1342}
1343
1344#[derive(Debug, Clone, Serialize, Deserialize)]
1345pub struct HealthCheckConfig {
1346 pub name: String,
1347 pub endpoint: String,
1348 pub interval_seconds: u32,
1349 pub timeout_seconds: u32,
1350 pub failure_threshold: u32,
1351}
1352
1353#[derive(Debug, Clone, Serialize, Deserialize)]
1354pub enum LogLevel {
1355 Error,
1356 Warn,
1357 Info,
1358 Debug,
1359 Trace,
1360}
1361
1362#[derive(Debug, Clone, Serialize, Deserialize)]
1363pub struct ResourceLimits {
1364 pub max_cpu_cores: f64,
1365 pub max_memory_gb: usize,
1366 pub max_disk_gb: usize,
1367 pub max_network_mbps: f64,
1368}
1369
1370#[derive(Debug, Clone, Serialize, Deserialize)]
1371pub struct SecurityConfig {
1372 pub encryption_enabled: bool,
1373 pub tls_version: String,
1374 pub authentication_required: bool,
1375 pub audit_logging_enabled: bool,
1376}
1377
1378#[derive(Debug, Clone, Serialize, Deserialize)]
1379pub struct DeploymentStrategy {
1380 pub deployment_type: DeploymentType,
1381 pub rollback_enabled: bool,
1382 pub health_check_grace_period_seconds: u32,
1383}
1384
1385#[derive(Debug, Clone, Serialize, Deserialize)]
1386pub enum DeploymentType {
1387 BlueGreen,
1388 Canary,
1389 Rolling,
1390 Recreate,
1391}
1392
1393#[derive(Debug, Clone, Serialize, Deserialize)]
1394pub struct ScalingConfig {
1395 pub min_replicas: u32,
1396 pub max_replicas: u32,
1397 pub target_cpu_utilization: f64,
1398 pub scale_up_cooldown_seconds: u32,
1399 pub scale_down_cooldown_seconds: u32,
1400}
1401
1402#[derive(Debug, Clone, Serialize, Deserialize)]
1403pub struct BenchmarkResult {
1404 pub benchmark_name: String,
1405 pub duration_ms: f64,
1406 pub throughput_ops_sec: f64,
1407 pub memory_usage_mb: f64,
1408 pub cpu_utilization: f64,
1409 pub success: bool,
1410}
1411
1412#[derive(Debug, Clone, Serialize, Deserialize)]
1413pub struct ResourceAnalysis {
1414 pub cpu_utilization: f64,
1415 pub memory_utilization: f64,
1416 pub disk_utilization: f64,
1417 pub network_utilization: f64,
1418 pub bottlenecks: Vec<String>,
1419}
1420
1421#[derive(Debug, Clone, Serialize, Deserialize)]
1422pub struct Recommendation {
1423 pub category: String,
1424 pub priority: RecommendationPriority,
1425 pub title: String,
1426 pub description: String,
1427 pub action_items: Vec<String>,
1428}
1429
1430#[derive(Debug, Clone, Serialize, Deserialize)]
1431pub enum RecommendationPriority {
1432 Critical,
1433 High,
1434 Medium,
1435 Low,
1436}
1437
1438#[derive(Debug, Clone, Serialize, Deserialize)]
1439pub struct MetricTimeSeries {
1440 pub name: String,
1441 pub values: Vec<(SystemTime, f64)>,
1442 pub unit: String,
1443}
1444
1445#[derive(Debug, Clone, Serialize, Deserialize)]
1446pub struct Alert {
1447 pub name: String,
1448 pub condition: String,
1449 pub severity: AlertSeverity,
1450 pub triggered_at: SystemTime,
1451}
1452
1453#[derive(Debug, Clone, Serialize, Deserialize)]
1454pub enum AlertSeverity {
1455 Critical,
1456 Warning,
1457 Info,
1458}
1459
1460#[derive(Debug, Clone, Serialize, Deserialize)]
1461pub struct Threshold {
1462 pub metric_name: String,
1463 pub warning_threshold: f64,
1464 pub critical_threshold: f64,
1465}
1466
1467impl Default for EnvironmentSpec {
1470 fn default() -> Self {
1471 Self {
1472 environment_type: EnvironmentType::Server {
1473 os: "Linux".to_string(),
1474 cores: 4,
1475 memory_gb: 8,
1476 },
1477 cpu_features: CpuFeatures::default(),
1478 memory_config: MemoryConfig::default(),
1479 network_config: NetworkConfig::default(),
1480 storage_config: StorageConfig::default(),
1481 container_config: None,
1482 }
1483 }
1484}
1485
1486impl Default for CpuFeatures {
1487 fn default() -> Self {
1488 Self {
1489 architecture: "x86_64".to_string(),
1490 simd_features: vec![SimdFeature::SSE2, SimdFeature::AVX],
1491 cores: 4,
1492 cache_hierarchy: CacheHierarchy::default(),
1493 numa_topology: None,
1494 }
1495 }
1496}
1497
1498impl Default for CacheHierarchy {
1499 fn default() -> Self {
1500 Self {
1501 l1size_kb: 32,
1502 l2size_kb: 256,
1503 l3size_mb: 8,
1504 cache_linesize: 64,
1505 }
1506 }
1507}
1508
1509impl Default for PerformanceRequirements {
1510 fn default() -> Self {
1511 Self {
1512 max_latency_ms: 1000.0,
1513 min_throughput: 100.0,
1514 memory_limits: MemoryLimits::default(),
1515 cpu_utilization: CpuUtilization::default(),
1516 sla_requirements: SlaRequirements::default(),
1517 load_testing: LoadTestingConfig::default(),
1518 }
1519 }
1520}
1521
1522impl Default for MemoryLimits {
1523 fn default() -> Self {
1524 Self {
1525 max_heap_mb: 6144, max_stack_mb: 8,
1527 max_shared_mb: 1024,
1528 allocation_rate_limit: Some(1000.0),
1529 }
1530 }
1531}
1532
1533impl Default for CpuUtilization {
1534 fn default() -> Self {
1535 Self {
1536 target_utilization: 0.7,
1537 max_utilization: 0.9,
1538 burst_capacity: 1.2,
1539 }
1540 }
1541}
1542
1543impl Default for SlaRequirements {
1544 fn default() -> Self {
1545 let mut percentiles = HashMap::new();
1546 percentiles.insert("p50".to_string(), 100.0);
1547 percentiles.insert("p95".to_string(), 500.0);
1548 percentiles.insert("p99".to_string(), 1000.0);
1549
1550 Self {
1551 availability_percentage: 99.9,
1552 max_downtime_minutes_per_month: 43.2,
1553 response_time_percentiles: percentiles,
1554 }
1555 }
1556}
1557
1558impl Default for LoadTestingConfig {
1559 fn default() -> Self {
1560 Self {
1561 enabled: false,
1562 target_rps: 1000.0,
1563 duration_minutes: 10,
1564 ramp_up_minutes: 2,
1565 }
1566 }
1567}
1568
1569impl Default for ReliabilityConfig {
1570 fn default() -> Self {
1571 Self {
1572 circuit_breaker_enabled: true,
1573 retry_attempts: 3,
1574 timeout_seconds: 30,
1575 graceful_shutdown_seconds: 30,
1576 }
1577 }
1578}
1579
1580impl Default for MonitoringConfig {
1581 fn default() -> Self {
1582 Self {
1583 metrics_enabled: true,
1584 health_checks: vec![HealthCheckConfig {
1585 name: "basic_health".to_string(),
1586 endpoint: "/health".to_string(),
1587 interval_seconds: 30,
1588 timeout_seconds: 5,
1589 failure_threshold: 3,
1590 }],
1591 alerting_enabled: true,
1592 logging_level: LogLevel::Info,
1593 }
1594 }
1595}
1596
1597impl Default for ResourceLimits {
1598 fn default() -> Self {
1599 Self {
1600 max_cpu_cores: 8.0,
1601 max_memory_gb: 16,
1602 max_disk_gb: 100,
1603 max_network_mbps: 1000.0,
1604 }
1605 }
1606}
1607
1608impl Default for SecurityConfig {
1609 fn default() -> Self {
1610 Self {
1611 encryption_enabled: true,
1612 tls_version: "1.3".to_string(),
1613 authentication_required: true,
1614 audit_logging_enabled: true,
1615 }
1616 }
1617}
1618
1619impl Default for DeploymentStrategy {
1620 fn default() -> Self {
1621 Self {
1622 deployment_type: DeploymentType::Rolling,
1623 rollback_enabled: true,
1624 health_check_grace_period_seconds: 30,
1625 }
1626 }
1627}
1628
1629impl Default for ValidationResults {
1630 fn default() -> Self {
1631 Self {
1632 readiness_score: 0.0,
1633 checks: HashMap::new(),
1634 performance_benchmarks: Vec::new(),
1635 resource_analysis: ResourceAnalysis::default(),
1636 recommendations: Vec::new(),
1637 timestamp: SystemTime::now(),
1638 }
1639 }
1640}
1641
1642impl Default for ResourceAnalysis {
1643 fn default() -> Self {
1644 Self {
1645 cpu_utilization: 0.0,
1646 memory_utilization: 0.0,
1647 disk_utilization: 0.0,
1648 network_utilization: 0.0,
1649 bottlenecks: Vec::new(),
1650 }
1651 }
1652}
1653
1654impl Default for PerformanceMonitor {
1655 fn default() -> Self {
1656 Self::new()
1657 }
1658}
1659
1660impl PerformanceMonitor {
1661 pub fn new() -> Self {
1662 Self {
1663 metrics: HashMap::new(),
1664 alerts: Vec::new(),
1665 thresholds: HashMap::new(),
1666 last_update: Instant::now(),
1667 }
1668 }
1669
1670 pub fn record_metric(&mut self, name: &str, value: f64) {
1671 let metric = self
1672 .metrics
1673 .entry(name.to_string())
1674 .or_insert_with(|| MetricTimeSeries {
1675 name: name.to_string(),
1676 values: Vec::new(),
1677 unit: "".to_string(),
1678 });
1679
1680 metric.values.push((SystemTime::now(), value));
1681
1682 if metric.values.len() > 1000 {
1684 metric.values.remove(0);
1685 }
1686
1687 self.last_update = Instant::now();
1688 }
1689
1690 pub fn get_metric(&self, name: &str) -> Option<&MetricTimeSeries> {
1691 self.metrics.get(name)
1692 }
1693
1694 pub fn add_threshold(&mut self, metric_name: String, warning: f64, critical: f64) {
1695 self.thresholds.insert(
1696 metric_name.clone(),
1697 Threshold {
1698 metric_name,
1699 warning_threshold: warning,
1700 critical_threshold: critical,
1701 },
1702 );
1703 }
1704}
1705
1706impl Default for HealthChecker {
1707 fn default() -> Self {
1708 Self::new()
1709 }
1710}
1711
1712impl HealthChecker {
1713 pub fn new() -> Self {
1714 Self {
1715 health_checks: Vec::new(),
1716 last_check: None,
1717 current_status: HealthStatus::Unknown,
1718 }
1719 }
1720
1721 pub fn add_health_check(&mut self, check: HealthCheck) {
1722 self.health_checks.push(check);
1723 }
1724
1725 pub fn run_health_checks(&mut self) -> StatsResult<Vec<HealthCheckResult>> {
1726 let mut results = Vec::new();
1727
1728 for check in &self.health_checks {
1729 let start_time = Instant::now();
1730 let result = (check.check_fn)();
1731 let execution_time = start_time.elapsed();
1732
1733 let health_result = match result {
1734 Ok(mut check_result) => {
1735 check_result.execution_time = execution_time;
1736 check_result
1737 }
1738 Err(_) => HealthCheckResult {
1739 status: HealthStatus::Unhealthy,
1740 message: "Health check failed".to_string(),
1741 execution_time,
1742 metadata: HashMap::new(),
1743 },
1744 };
1745
1746 results.push(health_result);
1747 }
1748
1749 self.current_status = if results.iter().any(|r| r.status == HealthStatus::Unhealthy) {
1751 HealthStatus::Unhealthy
1752 } else if results.iter().any(|r| r.status == HealthStatus::Degraded) {
1753 HealthStatus::Degraded
1754 } else if results.is_empty() {
1755 HealthStatus::Unknown
1756 } else {
1757 HealthStatus::Healthy
1758 };
1759
1760 self.last_check = Some(Instant::now());
1761 Ok(results)
1762 }
1763}
1764
1765#[allow(dead_code)]
1767pub fn create_cloud_production_config(cloud_provider: CloudProvider) -> ProductionConfig {
1768 let mut config = ProductionConfig::default();
1769
1770 config.environment.environment_type = EnvironmentType::Cloud {
1771 provider: cloud_provider,
1772 instance_type: "m5.large".to_string(),
1773 region: "us-east-1".to_string(),
1774 };
1775
1776 config.performance_requirements.max_latency_ms = 500.0;
1778 config.monitoring.metrics_enabled = true;
1779 config.security = SecurityConfig {
1780 encryption_enabled: true,
1781 tls_version: "1.3".to_string(),
1782 authentication_required: true,
1783 audit_logging_enabled: true,
1784 };
1785
1786 config
1787}
1788
1789#[allow(dead_code)]
1790pub fn create_container_production_config(container_runtime: ContainerRuntime) -> ProductionConfig {
1791 let mut config = ProductionConfig::default();
1792
1793 config.environment.environment_type = EnvironmentType::Container {
1794 runtime: container_runtime,
1795 resources: ContainerResources {
1796 cpu_cores: 2.0,
1797 memory_mb: 4096,
1798 gpu_count: 0,
1799 },
1800 };
1801
1802 config.environment.container_config = Some(ContainerConfig {
1803 orchestrator: "kubernetes".to_string(),
1804 scaling_config: ScalingConfig {
1805 min_replicas: 2,
1806 max_replicas: 10,
1807 target_cpu_utilization: 70.0,
1808 scale_up_cooldown_seconds: 300,
1809 scale_down_cooldown_seconds: 600,
1810 },
1811 });
1812
1813 config.deployment_strategy.deployment_type = DeploymentType::Rolling;
1815 config.monitoring.health_checks.push(HealthCheckConfig {
1816 name: "container_readiness".to_string(),
1817 endpoint: "/ready".to_string(),
1818 interval_seconds: 10,
1819 timeout_seconds: 3,
1820 failure_threshold: 3,
1821 });
1822
1823 config
1824}
1825
1826#[cfg(test)]
1827mod tests {
1828 use super::*;
1829
1830 #[test]
1831 fn test_production_config_creation() {
1832 let config = ProductionConfig::default();
1833 assert_eq!(config.performance_requirements.max_latency_ms, 1000.0);
1834 assert!(config.monitoring.metrics_enabled);
1835 assert!(!config.security.tls_version.is_empty());
1837 }
1838
1839 #[test]
1840 fn test_deployment_validator() {
1841 let config = ProductionConfig::default();
1842 let validator = ProductionDeploymentValidator::new(config);
1843 let result = validator.validate_production_readiness();
1844 assert!(result.is_ok());
1845
1846 let validation_results = result.expect("Operation failed");
1847 assert!(validation_results.readiness_score >= 0.0);
1848 assert!(validation_results.readiness_score <= 1.0);
1849 }
1850
1851 #[test]
1852 fn test_cloud_config_creation() {
1853 let cloud_config = create_cloud_production_config(CloudProvider::AWS);
1854
1855 match cloud_config.environment.environment_type {
1856 EnvironmentType::Cloud {
1857 provider: CloudProvider::AWS,
1858 ..
1859 } => {}
1860 _ => panic!("Expected AWS cloud configuration"),
1861 }
1862
1863 assert_eq!(cloud_config.performance_requirements.max_latency_ms, 500.0);
1864 }
1865
1866 #[test]
1867 fn test_container_config_creation() {
1868 let container_config = create_container_production_config(ContainerRuntime::Docker);
1869
1870 match container_config.environment.environment_type {
1871 EnvironmentType::Container {
1872 runtime: ContainerRuntime::Docker,
1873 ..
1874 } => {}
1875 _ => panic!("Expected Docker container configuration"),
1876 }
1877
1878 assert!(container_config.environment.container_config.is_some());
1879 assert!(container_config.monitoring.health_checks.len() > 1);
1880 }
1881
1882 #[test]
1883 fn test_performance_monitor() {
1884 let mut monitor = PerformanceMonitor::new();
1885 monitor.record_metric("test_metric", 42.0);
1886
1887 let metric = monitor.get_metric("test_metric");
1888 assert!(metric.is_some());
1889 assert!(!metric.expect("Operation failed").values.is_empty());
1890 }
1891
1892 #[test]
1893 fn test_health_checker() {
1894 let mut checker = HealthChecker::new();
1895
1896 checker.add_health_check(HealthCheck {
1897 name: "test_check".to_string(),
1898 check_fn: || {
1899 Ok(HealthCheckResult {
1900 status: HealthStatus::Healthy,
1901 message: "All good".to_string(),
1902 execution_time: Duration::from_millis(1),
1903 metadata: HashMap::new(),
1904 })
1905 },
1906 interval: Duration::from_secs(30),
1907 timeout: Duration::from_secs(5),
1908 critical: false,
1909 });
1910
1911 let results = checker.run_health_checks();
1912 assert!(results.is_ok());
1913 assert_eq!(results.expect("Operation failed").len(), 1);
1914 assert_eq!(checker.current_status, HealthStatus::Healthy);
1915 }
1916}