"""Unit tests for health monitor.""" import pytest from datetime import datetime, timedelta from src.data.health_monitor import HealthMonitor, HealthMetrics, HealthStatus class TestHealthMetrics: """Tests for HealthMetrics.""" def test_record_success(self): """Test recording successful operation.""" metrics = HealthMetrics() metrics.record_success(0.5) assert metrics.status == HealthStatus.HEALTHY assert metrics.success_count == 1 assert metrics.consecutive_failures == 0 assert len(metrics.response_times) == 1 def test_record_failure(self): """Test recording failed operation.""" metrics = HealthMetrics() metrics.record_failure() assert metrics.failure_count == 1 assert metrics.consecutive_failures == 1 def test_circuit_breaker(self): """Test circuit breaker opening.""" metrics = HealthMetrics() # Record 5 failures for _ in range(5): metrics.record_failure() assert metrics.circuit_breaker_open is True assert metrics.consecutive_failures == 5 def test_should_attempt(self): """Test should_attempt logic.""" metrics = HealthMetrics() # Should attempt if circuit breaker not open assert metrics.should_attempt() is True # Open circuit breaker for _ in range(5): metrics.record_failure() # Should not attempt immediately assert metrics.should_attempt(circuit_breaker_timeout=60) is False def test_get_avg_response_time(self): """Test average response time calculation.""" metrics = HealthMetrics() metrics.response_times.extend([0.1, 0.2, 0.3]) avg = metrics.get_avg_response_time() assert avg == 0.2 class TestHealthMonitor: """Tests for HealthMonitor.""" @pytest.fixture def monitor(self): """Create a health monitor instance.""" return HealthMonitor() def test_record_success(self, monitor): """Test recording success.""" monitor.record_success("provider1", 0.5) metrics = monitor.get_metrics("provider1") assert metrics is not None assert metrics.status == HealthStatus.HEALTHY assert metrics.success_count == 1 def test_record_failure(self, monitor): """Test recording failure.""" monitor.record_failure("provider1") metrics = monitor.get_metrics("provider1") assert metrics is not None assert metrics.failure_count == 1 assert metrics.consecutive_failures == 1 def test_is_healthy(self, monitor): """Test health checking.""" # No metrics yet - assume healthy assert monitor.is_healthy("provider1") is True # Record success monitor.record_success("provider1", 0.5) assert monitor.is_healthy("provider1") is True # Record many failures for _ in range(10): monitor.record_failure("provider1") assert monitor.is_healthy("provider1") is False def test_get_health_status(self, monitor): """Test getting health status.""" monitor.record_success("provider1", 0.5) status = monitor.get_health_status("provider1") assert status == HealthStatus.HEALTHY def test_select_healthiest(self, monitor): """Test selecting healthiest provider.""" # Make provider1 healthy monitor.record_success("provider1", 0.1) monitor.record_success("provider1", 0.2) # Make provider2 unhealthy monitor.record_failure("provider2") monitor.record_failure("provider2") monitor.record_failure("provider2") healthiest = monitor.select_healthiest(["provider1", "provider2"]) assert healthiest == "provider1" def test_reset_circuit_breaker(self, monitor): """Test resetting circuit breaker.""" # Open circuit breaker for _ in range(5): monitor.record_failure("provider1") assert monitor.get_metrics("provider1").circuit_breaker_open is True monitor.reset_circuit_breaker("provider1") metrics = monitor.get_metrics("provider1") assert metrics.circuit_breaker_open is False assert metrics.consecutive_failures == 0 def test_reset_metrics(self, monitor): """Test resetting metrics.""" monitor.record_success("provider1", 0.5) assert monitor.get_metrics("provider1") is not None monitor.reset_metrics("provider1") assert monitor.get_metrics("provider1") is None