Skip to content

Commit 4ba85a7

Browse files
committed
api: add health endpoint for availability checks
The root endpoint now serves the HTML landing page, so it should not be documented or tested as the machine-readable API availability check. Add GET /health for a stable JSON health response, update the root handler tests to assert the HTML contract, add health endpoint coverage, and point the local-instance docs at /latest/health. Fixes: #632 Signed-off-by: Denys Fedoryshchenko <denys.f@collabora.com>
1 parent cb4f5bd commit 4ba85a7

4 files changed

Lines changed: 41 additions & 6 deletions

File tree

api/main.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,13 @@ async def root():
298298
return HTMLResponse(file.read())
299299

300300

301+
@app.get("/health")
302+
async def health():
303+
"""Health endpoint handler"""
304+
metrics.add("http_requests_total", 1)
305+
return {"status": "ok", "service": "KernelCI API"}
306+
307+
301308
# -----------------------------------------------------------------------------
302309
# Users
303310

doc/local-instance.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,8 @@ It can take a few minutes to build the images from scratch the first time.
8989
Then the services should be up and running. To confirm the API is available:
9090

9191
```
92-
$ curl http://localhost:8001/latest/
93-
{"message":"KernelCI API"}
92+
$ curl http://localhost:8001/latest/health
93+
{"status":"ok","service":"KernelCI API"}
9494
```
9595

9696
> **Port numbers** for the services exposed by `docker-compose` can be
@@ -101,7 +101,7 @@ $ curl http://localhost:8001/latest/
101101
Following the `curl` command from the example above, the container log should
102102
show:
103103
```
104-
kernelci-api | INFO: 172.20.0.1:49228 - "GET / HTTP/1.1" 200 OK
104+
kernelci-api | INFO: 172.20.0.1:49228 - "GET /latest/health HTTP/1.1" 200 OK
105105
```
106106

107107
### Bootstrap the initial admin user

tests/e2e_tests/test_root_handler.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,16 @@ async def test_root_endpoint(test_async_client):
1313
"""Test root handler"""
1414
response = await test_async_client.get("/")
1515
assert response.status_code == 200
16-
assert response.json() == {"message": "KernelCI API"}
16+
assert response.headers["content-type"].startswith("text/html")
17+
assert "KernelCI API Server" in response.text
18+
19+
20+
@pytest.mark.asyncio
21+
async def test_health_endpoint(test_async_client):
22+
"""Test health handler"""
23+
response = await test_async_client.get("health")
24+
assert response.status_code == 200
25+
assert response.json() == {
26+
"status": "ok",
27+
"service": "KernelCI API",
28+
}

tests/unit_tests/test_root_handler.py

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,24 @@ def test_root_endpoint(test_client):
1111
Test Case : Test KernelCI API root endpoint
1212
Expected Result :
1313
HTTP Response Code 200 OK
14-
JSON with 'message' key
14+
HTML landing page
1515
"""
1616
response = test_client.get("/")
1717
assert response.status_code == 200
18-
assert response.json() == {"message": "KernelCI API"}
18+
assert response.headers["content-type"].startswith("text/html")
19+
assert "KernelCI API Server" in response.text
20+
21+
22+
def test_health_endpoint(test_client):
23+
"""
24+
Test Case : Test KernelCI API health endpoint
25+
Expected Result :
26+
HTTP Response Code 200 OK
27+
JSON with health status
28+
"""
29+
response = test_client.get("health")
30+
assert response.status_code == 200
31+
assert response.json() == {
32+
"status": "ok",
33+
"service": "KernelCI API",
34+
}

0 commit comments

Comments
 (0)