homelab_automation/tests/backend/test_services_hybrid_db.py
Bruno Charest ecefbc8611
Some checks failed
Tests / Backend Tests (Python) (3.10) (push) Has been cancelled
Tests / Backend Tests (Python) (3.11) (push) Has been cancelled
Tests / Backend Tests (Python) (3.12) (push) Has been cancelled
Tests / Frontend Tests (JS) (push) Has been cancelled
Tests / Integration Tests (push) Has been cancelled
Tests / All Tests Passed (push) Has been cancelled
Clean up test files and debug artifacts, add node_modules to gitignore, export DashboardManager for testing, and enhance pytest configuration with comprehensive test markers and settings
2025-12-15 08:15:49 -05:00

379 lines
11 KiB
Python

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