From 2b7b8fbd2f3f0bd8a4f8fdc79149174cad65ec52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sujii=20=F0=9F=92=AB?= <24pa1a05c9@vishnu.edu.in> Date: Tue, 23 Jun 2026 11:04:19 +0530 Subject: [PATCH] fix: return overall health status in health endpoint --- backend/app/main.py | 12 +++++-- backend/tests/test_api.py | 71 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+), 3 deletions(-) diff --git a/backend/app/main.py b/backend/app/main.py index 13fdaed7..0faaf885 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 2a2a4090..68d769ea 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" +