""" Tests pour HybridDB service. """ import pytest from datetime import datetime, timezone from unittest.mock import patch, MagicMock pytestmark = pytest.mark.unit class TestHybridDBInit: """Tests pour l'initialisation de HybridDB.""" def test_initial_state(self): """État initial de HybridDB.""" from app.services.hybrid_db import HybridDB db = HybridDB() assert db.tasks == [] assert db.logs == [] assert db._hosts_cache is None def test_get_next_id(self): """Génération d'IDs séquentiels.""" from app.services.hybrid_db import HybridDB db = HybridDB() id1 = db.get_next_id("tasks") id2 = db.get_next_id("tasks") id3 = db.get_next_id("logs") assert id1 == 1 assert id2 == 2 assert id3 == 1 # Different entity class TestHybridDBTasks: """Tests pour la gestion des tâches.""" def test_add_task(self): """Ajout d'une tâche.""" from app.services.hybrid_db import HybridDB from app.schemas.task_api import Task db = HybridDB() task = Task( id="task-1", name="Health Check", host="all", status="pending" ) db.add_task(task) assert len(db.tasks) == 1 assert db.tasks[0].id == "task-1" def test_add_task_inserts_at_beginning(self): """Les tâches sont insérées au début.""" from app.services.hybrid_db import HybridDB from app.schemas.task_api import Task db = HybridDB() task1 = Task(id="task-1", name="Task 1", host="all", status="pending") task2 = Task(id="task-2", name="Task 2", host="all", status="pending") db.add_task(task1) db.add_task(task2) assert db.tasks[0].id == "task-2" assert db.tasks[1].id == "task-1" def test_get_task(self): """Récupération d'une tâche par ID.""" from app.services.hybrid_db import HybridDB from app.schemas.task_api import Task db = HybridDB() task = Task(id="task-123", name="Test Task", host="all", status="pending") db.add_task(task) found = db.get_task("task-123") assert found is not None assert found.name == "Test Task" def test_get_task_not_found(self): """Tâche non trouvée.""" from app.services.hybrid_db import HybridDB db = HybridDB() found = db.get_task("nonexistent") assert found is None def test_update_task(self): """Mise à jour d'une tâche.""" from app.services.hybrid_db import HybridDB from app.schemas.task_api import Task db = HybridDB() task = Task(id="task-1", name="Test", host="all", status="pending") db.add_task(task) db.update_task("task-1", status="completed") updated = db.get_task("task-1") assert updated.status == "completed" def test_clear_tasks(self): """Effacement des tâches.""" from app.services.hybrid_db import HybridDB from app.schemas.task_api import Task db = HybridDB() db.add_task(Task(id="1", name="A", host="all", status="pending")) db.add_task(Task(id="2", name="B", host="all", status="pending")) db.clear_tasks() assert len(db.tasks) == 0 class TestHybridDBLogs: """Tests pour la gestion des logs.""" def test_add_log(self): """Ajout d'un log.""" from app.services.hybrid_db import HybridDB from app.schemas.common import LogEntry db = HybridDB() log = LogEntry( id=0, timestamp=datetime.now(timezone.utc), level="INFO", message="Test message", source="test" ) db.add_log(log) assert len(db.logs) == 1 assert db.logs[0].message == "Test message" def test_add_log_assigns_id(self): """L'ID est assigné automatiquement si 0.""" from app.services.hybrid_db import HybridDB from app.schemas.common import LogEntry db = HybridDB() log = LogEntry( id=0, timestamp=datetime.now(timezone.utc), level="INFO", message="Test", source="test" ) db.add_log(log) assert log.id == 1 def test_get_recent_logs(self): """Récupération des logs récents.""" from app.services.hybrid_db import HybridDB from app.schemas.common import LogEntry db = HybridDB() for i in range(10): db.add_log(LogEntry( id=i+1, timestamp=datetime.now(timezone.utc), level="INFO", message=f"Log {i}", source="test" )) recent = db.get_recent_logs(limit=5) assert len(recent) == 5 def test_get_recent_logs_filter_by_level(self): """Filtrage des logs par niveau.""" from app.services.hybrid_db import HybridDB from app.schemas.common import LogEntry db = HybridDB() db.add_log(LogEntry(id=1, timestamp=datetime.now(timezone.utc), level="INFO", message="Info", source="test")) db.add_log(LogEntry(id=2, timestamp=datetime.now(timezone.utc), level="ERROR", message="Error", source="test")) db.add_log(LogEntry(id=3, timestamp=datetime.now(timezone.utc), level="INFO", message="Info2", source="test")) errors = db.get_recent_logs(level="ERROR") assert len(errors) == 1 assert errors[0].level == "ERROR" def test_get_recent_logs_filter_by_source(self): """Filtrage des logs par source.""" from app.services.hybrid_db import HybridDB from app.schemas.common import LogEntry db = HybridDB() db.add_log(LogEntry(id=1, timestamp=datetime.now(timezone.utc), level="INFO", message="A", source="ansible")) db.add_log(LogEntry(id=2, timestamp=datetime.now(timezone.utc), level="INFO", message="B", source="bootstrap")) ansible_logs = db.get_recent_logs(source="ansible") assert len(ansible_logs) == 1 assert ansible_logs[0].source == "ansible" def test_clear_logs(self): """Effacement des logs.""" from app.services.hybrid_db import HybridDB from app.schemas.common import LogEntry db = HybridDB() db.add_log(LogEntry(id=1, timestamp=datetime.now(timezone.utc), level="INFO", message="Test", source="test")) db.clear_logs() assert len(db.logs) == 0 class TestHybridDBHosts: """Tests pour la gestion des hôtes.""" def test_invalidate_hosts_cache(self): """Invalidation du cache des hôtes.""" from app.services.hybrid_db import HybridDB db = HybridDB() db._hosts_cache = [MagicMock()] db.invalidate_hosts_cache() assert db._hosts_cache is None def test_get_host_not_found(self): """Hôte non trouvé.""" from app.services.hybrid_db import HybridDB db = HybridDB() db._hosts_cache = [] db._hosts_cache_time = float('inf') # Never expire host = db.get_host("nonexistent") assert host is None def test_get_host_by_id(self): """Récupération d'un hôte par ID.""" from app.services.hybrid_db import HybridDB from app.schemas.host_api import Host db = HybridDB() mock_host = Host( id="host-1", name="test-host", ip="192.168.1.1", status="online" ) db._hosts_cache = [mock_host] db._hosts_cache_time = float('inf') found = db.get_host("host-1") assert found is not None assert found.name == "test-host" def test_get_host_by_name(self): """Récupération d'un hôte par nom.""" from app.services.hybrid_db import HybridDB from app.schemas.host_api import Host db = HybridDB() mock_host = Host( id="host-1", name="test-host", ip="192.168.1.1", status="online" ) db._hosts_cache = [mock_host] db._hosts_cache_time = float('inf') found = db.get_host("test-host") assert found is not None assert found.id == "host-1" def test_get_host_by_ip(self): """Récupération d'un hôte par IP.""" from app.services.hybrid_db import HybridDB from app.schemas.host_api import Host db = HybridDB() mock_host = Host( id="host-1", name="test-host", ip="192.168.1.1", status="online" ) db._hosts_cache = [mock_host] db._hosts_cache_time = float('inf') found = db.get_host("192.168.1.1") assert found is not None assert found.name == "test-host" class TestHybridDBMetrics: """Tests pour les métriques.""" def test_metrics_empty(self): """Métriques avec données vides.""" from app.services.hybrid_db import HybridDB db = HybridDB() db._hosts_cache = [] db._hosts_cache_time = float('inf') metrics = db.metrics # When cache is empty but valid, should return 0 hosts # Note: if cache expires, it may refresh from ansible service assert metrics.online_hosts >= 0 assert metrics.total_tasks == 0 assert metrics.success_rate == 100.0 def test_metrics_with_data(self): """Métriques avec données.""" from app.services.hybrid_db import HybridDB from app.schemas.host_api import Host from app.schemas.task_api import Task db = HybridDB() db._hosts_cache = [ Host(id="1", name="h1", ip="1.1.1.1", status="online"), Host(id="2", name="h2", ip="1.1.1.2", status="offline"), Host(id="3", name="h3", ip="1.1.1.3", status="online"), ] db._hosts_cache_time = float('inf') db.tasks = [ Task(id="t1", name="A", host="all", status="completed"), Task(id="t2", name="B", host="all", status="completed"), Task(id="t3", name="C", host="all", status="failed"), ] metrics = db.metrics assert metrics.online_hosts == 2 assert metrics.total_tasks == 3 # 2 completed out of 3 finished = 66.7% assert metrics.success_rate == 66.7 class TestHybridDBUpdateHostStatus: """Tests pour la mise à jour du statut des hôtes.""" def test_update_host_status(self): """Mise à jour du statut d'un hôte.""" from app.services.hybrid_db import HybridDB db = HybridDB() db._hosts_cache = [MagicMock()] with patch("app.services.host_status_service.host_status_service") as mock_service: mock_service.set_status = MagicMock() db.update_host_status("test-host", "online", "Ubuntu 22.04") mock_service.set_status.assert_called_once() assert db._hosts_cache is None # Cache invalidated