Skip to main content

oxirs_embed/
monitoring_tests.rs

1//! Tests for monitoring metrics, health checks, and alerting.
2
3#[cfg(test)]
4mod tests {
5    use std::collections::HashMap;
6    use std::sync::Arc;
7
8    use chrono::Utc;
9
10    use crate::monitoring::{MonitoringConfig, PerformanceMonitor};
11    use crate::monitoring_health::{
12        Alert, AlertHandler, AlertSeverity, AlertType, ConsoleAlertHandler, HealthChecker,
13        HealthStatus,
14    };
15    use crate::monitoring_metrics::{
16        ErrorEvent, ErrorSeverity, MetricsCollector, PerformanceMetrics,
17    };
18
19    #[tokio::test]
20    async fn test_performance_monitor_creation() {
21        let config = MonitoringConfig::default();
22        let monitor = PerformanceMonitor::new(config);
23
24        let metrics = monitor.get_metrics();
25        assert_eq!(metrics.latency.total_measurements, 0);
26        assert_eq!(metrics.throughput.total_requests, 0);
27    }
28
29    #[tokio::test]
30    async fn test_latency_recording() {
31        let config = MonitoringConfig::default();
32        let monitor = PerformanceMonitor::new(config);
33
34        monitor.record_latency(100.0).await;
35        monitor.record_latency(150.0).await;
36        monitor.record_latency(120.0).await;
37
38        let metrics = monitor.get_metrics();
39        assert_eq!(metrics.latency.total_measurements, 3);
40        assert_eq!(metrics.latency.max_latency_ms, 150.0);
41        assert_eq!(metrics.latency.min_latency_ms, 100.0);
42    }
43
44    #[tokio::test]
45    async fn test_error_recording() {
46        let config = MonitoringConfig::default();
47        let monitor = PerformanceMonitor::new(config);
48
49        let error_event = ErrorEvent {
50            timestamp: Utc::now(),
51            error_type: "timeout".to_string(),
52            error_message: "Request timeout".to_string(),
53            severity: ErrorSeverity::Medium,
54            context: HashMap::new(),
55        };
56
57        monitor.record_error(error_event).await;
58
59        let metrics = monitor.get_metrics();
60        assert_eq!(metrics.errors.total_errors, 1);
61        assert_eq!(metrics.errors.timeout_errors, 1);
62    }
63
64    #[test]
65    fn test_alert_thresholds_default() {
66        use crate::monitoring_health::AlertThresholds;
67
68        let thresholds = AlertThresholds::default();
69        assert_eq!(thresholds.max_p95_latency_ms, 500.0);
70        assert_eq!(thresholds.min_throughput_rps, 100.0);
71        assert_eq!(thresholds.max_error_rate, 0.05);
72    }
73
74    #[test]
75    fn test_console_alert_handler() {
76        let handler = ConsoleAlertHandler;
77        let alert = Alert {
78            alert_type: AlertType::HighLatency,
79            message: "Test alert".to_string(),
80            severity: AlertSeverity::Warning,
81            timestamp: Utc::now(),
82            metrics: HashMap::new(),
83        };
84
85        assert!(handler.handle_alert(alert).is_ok());
86    }
87
88    #[test]
89    fn test_metrics_collector_creation() {
90        let collector = MetricsCollector::new();
91        // Just verify it was created successfully
92        assert_eq!(collector.requests_total.get(), 0);
93    }
94
95    #[test]
96    fn test_metrics_collector_counters() {
97        let collector = MetricsCollector::new();
98
99        collector.record_request_start();
100        collector.record_request_complete(50.0);
101
102        assert_eq!(collector.requests_total.get(), 1);
103    }
104
105    #[test]
106    fn test_metrics_collector_cache_hit_rate() {
107        let collector = MetricsCollector::new();
108
109        collector.record_cache_hit();
110        collector.record_cache_hit();
111        collector.record_cache_miss();
112
113        let hit_rate = collector.get_cache_hit_rate();
114        assert!((hit_rate - 0.666).abs() < 0.01); // ~66.6%
115    }
116
117    #[test]
118    fn test_metrics_collector_resource_update() {
119        let collector = MetricsCollector::new();
120
121        collector.update_resource_metrics(0.75, 2048.0, 0.5, 4096.0);
122
123        assert_eq!(collector.cpu_utilization.get(), 0.75);
124        assert_eq!(collector.memory_usage_bytes.get(), 2048.0 * 1024.0 * 1024.0);
125        assert_eq!(collector.gpu_utilization.get(), 0.5);
126        assert_eq!(collector.gpu_memory_bytes.get(), 4096.0 * 1024.0 * 1024.0);
127    }
128
129    #[test]
130    fn test_health_checker_liveness() {
131        let metrics = Arc::new(MetricsCollector::new());
132        let checker = HealthChecker::new(metrics);
133
134        let result = checker.check_liveness();
135        assert_eq!(result.status, HealthStatus::Healthy);
136        assert!(result.components.contains_key("service"));
137    }
138
139    #[test]
140    fn test_health_checker_readiness_no_models() {
141        let metrics = Arc::new(MetricsCollector::new());
142        let checker = HealthChecker::new(metrics);
143
144        let result = checker.check_readiness();
145        assert_eq!(result.status, HealthStatus::Unhealthy);
146        assert!(result.components.contains_key("models"));
147    }
148
149    #[test]
150    fn test_health_checker_readiness_with_models() {
151        let metrics = Arc::new(MetricsCollector::new());
152        let checker = HealthChecker::new(metrics);
153
154        checker
155            .set_models_loaded(true)
156            .expect("Failed to set models loaded");
157
158        let result = checker.check_readiness();
159        assert_eq!(result.status, HealthStatus::Healthy);
160    }
161
162    #[test]
163    fn test_health_checker_comprehensive() {
164        let metrics = Arc::new(MetricsCollector::new());
165        let checker = HealthChecker::new(metrics);
166
167        checker
168            .set_models_loaded(true)
169            .expect("Failed to set models loaded");
170
171        let perf_metrics = PerformanceMetrics::default();
172
173        let result = checker.check_health(&perf_metrics);
174        assert_eq!(result.status, HealthStatus::Healthy);
175        assert!(result.components.contains_key("models"));
176        assert!(result.components.contains_key("latency"));
177        assert!(result.components.contains_key("errors"));
178        assert!(result.components.contains_key("memory"));
179    }
180
181    #[test]
182    fn test_health_checker_degraded_latency() {
183        let metrics = Arc::new(MetricsCollector::new());
184        let checker = HealthChecker::new(metrics);
185
186        checker
187            .set_models_loaded(true)
188            .expect("Failed to set models loaded");
189
190        let mut perf_metrics = PerformanceMetrics::default();
191        perf_metrics.latency.p95_latency_ms = 2000.0; // Above threshold
192
193        let result = checker.check_health(&perf_metrics);
194        assert_eq!(result.status, HealthStatus::Degraded);
195    }
196
197    #[test]
198    fn test_prometheus_export() {
199        let collector = MetricsCollector::new();
200
201        collector.record_request_start();
202        collector.record_embeddings(5, 25.0);
203
204        let prometheus_output = collector.export_prometheus();
205        assert!(prometheus_output.is_ok());
206
207        let _output = prometheus_output.unwrap_or_default();
208        // Check that metrics were recorded (may not always be in prometheus output depending on implementation)
209        assert_eq!(collector.requests_total.get(), 1);
210        assert_eq!(collector.embeddings_generated_total.get(), 5);
211    }
212}