Files
crypto_trader/tests/unit/data/test_health_monitor.py

146 lines
4.7 KiB
Python

"""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