Files
Aniworld/tests/unit/test_provider_failover.py
Lukas 5526ab884a refactor: restructure core→server, split large entity files into database module
- Move src/core/ → src/server/
- Split SerieList.py (531 lines) and series.py (414 lines) into src/server/database/
- Add database/models.py for SQLAlchemy models
- Update all test imports to reflect new structure
- Remove deprecated test files (test_serie_class.py, test_serie_folder_with_year.py)
2026-06-04 21:11:53 +02:00

208 lines
6.3 KiB
Python

"""Unit tests for provider failover system."""
import pytest
from src.server.providers.failover import (
ProviderFailover,
configure_failover,
get_failover,
)
class TestProviderFailover:
"""Test ProviderFailover class."""
def test_failover_initialization(self):
"""Test failover initialization."""
providers = ["provider1", "provider2", "provider3"]
failover = ProviderFailover(
providers=providers,
max_retries=5,
retry_delay=2.0,
)
assert failover._providers == providers
assert failover._max_retries == 5
assert failover._retry_delay == 2.0
def test_get_current_provider(self):
"""Test getting current provider."""
providers = ["provider1", "provider2"]
failover = ProviderFailover(
providers=providers,
enable_health_monitoring=False,
)
current = failover.get_current_provider()
assert current in providers
def test_get_next_provider(self):
"""Test getting next provider."""
providers = ["provider1", "provider2", "provider3"]
failover = ProviderFailover(
providers=providers,
enable_health_monitoring=False,
)
first = failover.get_current_provider()
next_provider = failover.get_next_provider()
assert next_provider in providers
assert next_provider != first
@pytest.mark.asyncio
async def test_execute_with_failover_success(self):
"""Test successful execution with failover."""
async def mock_operation(provider: str) -> str:
return f"Success with {provider}"
failover = ProviderFailover(
providers=["provider1"],
enable_health_monitoring=False,
)
result = await failover.execute_with_failover(
operation=mock_operation,
operation_name="test_op",
)
assert "Success" in result
@pytest.mark.asyncio
async def test_execute_with_failover_retry(self):
"""Test failover with retry on first failure."""
call_count = 0
async def mock_operation(provider: str) -> str:
nonlocal call_count
call_count += 1
if call_count == 1:
raise Exception("First attempt failed")
return f"Success with {provider}"
failover = ProviderFailover(
providers=["provider1"],
max_retries=2,
retry_delay=0.1,
enable_health_monitoring=False,
)
result = await failover.execute_with_failover(
operation=mock_operation,
operation_name="test_op",
)
assert "Success" in result
assert call_count == 2
@pytest.mark.asyncio
async def test_execute_with_failover_all_fail(self):
"""Test failover when all providers fail."""
async def mock_operation(provider: str) -> str:
raise Exception(f"Failed with {provider}")
failover = ProviderFailover(
providers=["provider1", "provider2"],
max_retries=1,
retry_delay=0.1,
enable_health_monitoring=False,
)
with pytest.raises(Exception) as exc_info:
await failover.execute_with_failover(
operation=mock_operation,
operation_name="test_op",
)
assert "failed with all providers" in str(exc_info.value)
def test_add_provider(self):
"""Test adding provider to failover chain."""
failover = ProviderFailover(providers=["provider1"])
failover.add_provider("provider2")
assert "provider2" in failover.get_providers()
assert len(failover.get_providers()) == 2
def test_remove_provider(self):
"""Test removing provider from failover chain."""
failover = ProviderFailover(providers=["provider1", "provider2"])
success = failover.remove_provider("provider1")
assert success is True
assert "provider1" not in failover.get_providers()
assert len(failover.get_providers()) == 1
def test_remove_nonexistent_provider(self):
"""Test removing provider that doesn't exist."""
failover = ProviderFailover(providers=["provider1"])
success = failover.remove_provider("nonexistent")
assert success is False
def test_set_provider_priority(self):
"""Test setting provider priority."""
failover = ProviderFailover(
providers=["provider1", "provider2", "provider3"]
)
success = failover.set_provider_priority("provider3", 0)
assert success is True
providers = failover.get_providers()
assert providers[0] == "provider3"
def test_set_priority_nonexistent_provider(self):
"""Test setting priority for nonexistent provider."""
failover = ProviderFailover(providers=["provider1"])
success = failover.set_provider_priority("nonexistent", 0)
assert success is False
def test_get_failover_stats(self):
"""Test getting failover statistics."""
providers = ["provider1", "provider2"]
failover = ProviderFailover(
providers=providers,
max_retries=3,
retry_delay=1.5,
enable_health_monitoring=False,
)
stats = failover.get_failover_stats()
assert stats["total_providers"] == 2
assert stats["providers"] == providers
assert stats["max_retries"] == 3
assert stats["retry_delay"] == 1.5
assert stats["health_monitoring_enabled"] is False
class TestFailoverSingleton:
"""Test global failover singleton."""
def test_get_failover_singleton(self):
"""Test that get_failover returns singleton."""
failover1 = get_failover()
failover2 = get_failover()
assert failover1 is failover2
def test_configure_failover(self):
"""Test configuring global failover instance."""
providers = ["custom1", "custom2"]
failover = configure_failover(
providers=providers,
max_retries=10,
retry_delay=3.0,
)
assert failover._providers == providers
assert failover._max_retries == 10
assert failover._retry_delay == 3.0