""" Tests for the failover manager. """ from app.core.failover import FailoverManager def test_default_returns_primary(): """Without any events, primary is the recommended provider.""" fm = FailoverManager(primary="binance", backups=["bybit"]) assert fm.get_best_provider("BTCUSDT") == "binance" def test_gaps_cause_switch(): """Enough gaps should cause a switch to backup.""" fm = FailoverManager( primary="binance", backups=["bybit"], switch_threshold=0.3, ) # Record some events for bybit so it has health for _ in range(10): fm.record_event("bybit", "BTCUSDT") # Degrade binance heavily (5 gaps = -1.0) for _ in range(5): fm.record_gap("binance", "BTCUSDT") best = fm.get_best_provider("BTCUSDT") assert best == "bybit" def test_recovery_returns_to_primary(): """When primary recovers, switch back from backup.""" fm = FailoverManager( primary="binance", backups=["bybit"], switch_threshold=0.3, recovery_threshold=0.7, ) # Degrade primary and switch to backup for _ in range(10): fm.record_event("bybit", "BTCUSDT") for _ in range(5): fm.record_gap("binance", "BTCUSDT") assert fm.get_best_provider("BTCUSDT") == "bybit" # Now primary recovers (many events increase score) for _ in range(100): fm.record_event("binance", "BTCUSDT") assert fm.get_best_provider("BTCUSDT") == "binance" def test_status_report(): """Status report includes all provider/symbol pairs.""" fm = FailoverManager(primary="binance", backups=["bybit"]) fm.record_event("binance", "BTCUSDT") fm.record_event("bybit", "BTCUSDT") fm.record_gap("binance", "ETHUSDT") status = fm.get_status() assert "binance/BTCUSDT" in status assert "bybit/BTCUSDT" in status assert "binance/ETHUSDT" in status assert status["binance/BTCUSDT"]["events"] == 1 assert status["binance/ETHUSDT"]["gaps"] == 1 def test_no_backup_stays_on_primary(): """Without backups, always returns primary even when degraded.""" fm = FailoverManager(primary="binance", backups=[]) for _ in range(5): fm.record_gap("binance", "BTCUSDT") # No alternative, stays on binance assert fm.get_best_provider("BTCUSDT") == "binance"