"""Tests for health check endpoint."""
from unittest.mock import MagicMock, patch
import pytest
class TestHealthCheck:
"""Test health_check endpoint."""
@patch("preloop.services.mcp_client_pool.get_mcp_client_pool")
@patch("preloop.services.mcp_http.get_mcp_lifespan_manager")
def test_health_check_all_healthy(
self, mock_get_mcp_lifespan, mock_get_client_pool, mock_db_session
):
"""Test health check when all systems are healthy."""
from preloop.api.endpoints.health import health_check
# Mock database session
mock_db_session.execute.return_value = None
# Mock MCP lifespan manager
mock_lifespan = MagicMock()
mock_get_mcp_lifespan.return_value = mock_lifespan
# Mock MCP client pool
mock_pool = MagicMock()
mock_pool.get_active_servers.return_value = ["server1", "server2"]
mock_get_client_pool.return_value = mock_pool
result = health_check(db=mock_db_session)
assert result["status"] == "healthy"
assert result["database"] == "connected"
assert result["mcp_server"] == "available"
assert result["upstream_connections"] == 2
assert result["upstream_servers"] == ["server1", "server2"]
assert "timestamp" in result
@patch("preloop.services.mcp_client_pool.get_mcp_client_pool")
@patch("preloop.services.mcp_http.get_mcp_lifespan_manager")
def test_health_check_database_error(
self, mock_get_mcp_lifespan, mock_get_client_pool, mock_db_session
):
"""Test health check when database connection fails."""
from preloop.api.endpoints.health import health_check
# Mock database error
mock_db_session.execute.side_effect = Exception("Database connection failed")
# Mock MCP services (healthy)
mock_lifespan = MagicMock()
mock_get_mcp_lifespan.return_value = mock_lifespan
mock_pool = MagicMock()
mock_pool.get_active_servers.return_value = []
mock_get_client_pool.return_value = mock_pool
result = health_check(db=mock_db_session)
assert result["status"] == "unhealthy"
assert "error: Database connection failed" in result["database"]
assert result["mcp_server"] == "available"
assert result["upstream_connections"] == 0
@patch("preloop.services.mcp_client_pool.get_mcp_client_pool")
@patch("preloop.services.mcp_http.get_mcp_lifespan_manager")
def test_health_check_mcp_server_not_initialized(
self, mock_get_mcp_lifespan, mock_get_client_pool, mock_db_session
):
"""Test health check when MCP server is not initialized."""
from preloop.api.endpoints.health import health_check
# Mock database (healthy)
mock_db_session.execute.return_value = None
# Mock MCP lifespan manager returning None
mock_get_mcp_lifespan.return_value = None
# Mock MCP client pool
mock_pool = MagicMock()
mock_pool.get_active_servers.return_value = []
mock_get_client_pool.return_value = mock_pool
result = health_check(db=mock_db_session)
assert result["status"] == "healthy"
assert result["database"] == "connected"
assert result["mcp_server"] == "not_initialized"
assert result["upstream_connections"] == 0
@patch("preloop.services.mcp_client_pool.get_mcp_client_pool")
@patch("preloop.services.mcp_http.get_mcp_lifespan_manager")
def test_health_check_mcp_server_error(
self, mock_get_mcp_lifespan, mock_get_client_pool, mock_db_session
):
"""Test health check when MCP server check raises an error."""
from preloop.api.endpoints.health import health_check
# Mock database (healthy)
mock_db_session.execute.return_value = None
# Mock MCP lifespan manager error
mock_get_mcp_lifespan.side_effect = Exception("MCP initialization error")
# Mock MCP client pool
mock_pool = MagicMock()
mock_pool.get_active_servers.return_value = []
mock_get_client_pool.return_value = mock_pool
result = health_check(db=mock_db_session)
assert result["status"] == "healthy"
assert result["database"] == "connected"
assert "error: MCP initialization error" in result["mcp_server"]
assert result["upstream_connections"] == 0
@patch("preloop.services.mcp_client_pool.get_mcp_client_pool")
@patch("preloop.services.mcp_http.get_mcp_lifespan_manager")
def test_health_check_upstream_connections_error(
self, mock_get_mcp_lifespan, mock_get_client_pool, mock_db_session
):
"""Test health check when upstream connections check raises an error."""
from preloop.api.endpoints.health import health_check
# Mock database (healthy)
mock_db_session.execute.return_value = None
# Mock MCP lifespan manager (healthy)
mock_lifespan = MagicMock()
mock_get_mcp_lifespan.return_value = mock_lifespan
# Mock MCP client pool error
mock_get_client_pool.side_effect = Exception("Client pool unavailable")
result = health_check(db=mock_db_session)
assert result["status"] == "healthy"
assert result["database"] == "connected"
assert result["mcp_server"] == "available"
assert "error: Client pool unavailable" in str(result["upstream_connections"])
@patch("preloop.services.mcp_client_pool.get_mcp_client_pool")
@patch("preloop.services.mcp_http.get_mcp_lifespan_manager")
def test_health_check_no_upstream_servers(
self, mock_get_mcp_lifespan, mock_get_client_pool, mock_db_session
):
"""Test health check when no upstream servers are active."""
from preloop.api.endpoints.health import health_check
# Mock database (healthy)
mock_db_session.execute.return_value = None
# Mock MCP lifespan manager (healthy)
mock_lifespan = MagicMock()
mock_get_mcp_lifespan.return_value = mock_lifespan
# Mock MCP client pool with no active servers
mock_pool = MagicMock()
mock_pool.get_active_servers.return_value = []
mock_get_client_pool.return_value = mock_pool
result = health_check(db=mock_db_session)
assert result["status"] == "healthy"
assert result["database"] == "connected"
assert result["mcp_server"] == "available"
assert result["upstream_connections"] == 0
assert "upstream_servers" not in result
@pytest.fixture
def mock_db_session():
"""Create a mock database session."""
return MagicMock()