diff --git a/backend/app/main.py b/backend/app/main.py index 13fdaed..0faaf88 100644 --- a/backend/app/main.py +++ b/backend/app/main.py @@ -228,9 +228,15 @@ def db_health(): except Exception: chroma_status = "down" - overall_status = "ok" if db_status == "up" and chroma_status == "up" else "degraded" - return{ - "status": db_status, + if db_status == "up" and chroma_status == "up": + overall_status = "healthy" + elif db_status == "down" and chroma_status == "down": + overall_status = "unhealthy" + else: + overall_status = "degraded" + + return { + "status": overall_status, "chroma": chroma_status, "db": db_status } diff --git a/backend/tests/test_api.py b/backend/tests/test_api.py index 2a2a409..68d769e 100644 --- a/backend/tests/test_api.py +++ b/backend/tests/test_api.py @@ -13,3 +13,74 @@ async def test_health_check_route(): assert response.status_code == 200 # Add more assertions based on expected JSON response + + +async def test_health_check_db_healthy_chroma_healthy(monkeypatch): + # Case 1: DB healthy, Chroma healthy -> status = healthy + # Both are healthy by default in test env (get_db yields test db, get_chroma_client works) + async with AsyncClient(transport=ASGITransport(app=app), base_url="http://testserver") as ac: + response = await ac.get("/health") + assert response.status_code == 200 + data = response.json() + assert data["status"] == "healthy" + assert data["db"] == "up" + assert data["chroma"] == "up" + + +async def test_health_check_db_healthy_chroma_unhealthy(monkeypatch): + # Case 2: DB healthy, Chroma unhealthy -> status = degraded + def mock_get_chroma_client_down(): + raise Exception("Chroma connection refused") + + monkeypatch.setattr("app.main.get_chroma_client", mock_get_chroma_client_down) + + async with AsyncClient(transport=ASGITransport(app=app), base_url="http://testserver") as ac: + response = await ac.get("/health") + assert response.status_code == 200 + data = response.json() + assert data["status"] == "degraded" + assert data["db"] == "up" + assert data["chroma"] == "down" + + +async def test_health_check_db_unhealthy_chroma_healthy(monkeypatch): + # Case 3: DB unhealthy, Chroma healthy -> status = degraded + from sqlalchemy.exc import SQLAlchemyError + + def mock_get_db_down(): + raise SQLAlchemyError("DB Connection refused") + yield + + monkeypatch.setattr("app.main.get_db", mock_get_db_down) + + async with AsyncClient(transport=ASGITransport(app=app), base_url="http://testserver") as ac: + response = await ac.get("/health") + assert response.status_code == 200 + data = response.json() + assert data["status"] == "degraded" + assert data["db"] == "down" + assert data["chroma"] == "up" + + +async def test_health_check_db_unhealthy_chroma_unhealthy(monkeypatch): + # Case 4: DB unhealthy, Chroma unhealthy -> status = unhealthy + from sqlalchemy.exc import SQLAlchemyError + + def mock_get_db_down(): + raise SQLAlchemyError("DB Connection refused") + yield + + def mock_get_chroma_client_down(): + raise Exception("Chroma connection refused") + + monkeypatch.setattr("app.main.get_db", mock_get_db_down) + monkeypatch.setattr("app.main.get_chroma_client", mock_get_chroma_client_down) + + async with AsyncClient(transport=ASGITransport(app=app), base_url="http://testserver") as ac: + response = await ac.get("/health") + assert response.status_code == 200 + data = response.json() + assert data["status"] == "unhealthy" + assert data["db"] == "down" + assert data["chroma"] == "down" +