-
Notifications
You must be signed in to change notification settings - Fork 52
Adding Lcore 714 health endpoint #744
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
tisnik
merged 7 commits into
lightspeed-core:main
from
xmican10:LCORE_714_health_endpoint
Oct 31, 2025
Merged
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
d9ca6cb
Adding health endpoint integration tests.
xmican10 6d8bcc4
Removing liveness probe endpoint test when config is not loaded.
xmican10 8265459
Merge remote-tracking branch 'origin/main' into LCORE_714_health_endp…
xmican10 9e02f79
Removing unused imports.
xmican10 683a8f1
Adding test for provider health statuses.
xmican10 6adf5fc
Adding test for provider health statuses.
xmican10 64ce25a
Fixing pylinter imports order.
xmican10 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,183 @@ | ||
| """Integration tests for the /health endpoint.""" | ||
|
|
||
| from typing import Generator, Any | ||
| import pytest | ||
| from pytest_mock import MockerFixture, AsyncMockType | ||
| from llama_stack.providers.datatypes import HealthStatus | ||
|
|
||
| from fastapi import Response, status | ||
| from authentication.interface import AuthTuple | ||
|
|
||
| from configuration import AppConfig | ||
| from app.endpoints.health import ( | ||
| liveness_probe_get_method, | ||
| readiness_probe_get_method, | ||
| get_providers_health_statuses, | ||
| ) | ||
|
|
||
|
|
||
| @pytest.fixture(name="mock_llama_stack_client_health") | ||
| def mock_llama_stack_client_fixture( | ||
| mocker: MockerFixture, | ||
| ) -> Generator[Any, None, None]: | ||
| """Mock only the external Llama Stack client. | ||
|
|
||
| This is the only external dependency we mock for integration tests, | ||
| as it represents an external service call. | ||
| """ | ||
| mock_holder_class = mocker.patch("app.endpoints.health.AsyncLlamaStackClientHolder") | ||
|
|
||
| mock_client = mocker.AsyncMock() | ||
| # Mock the version endpoint to return a known version | ||
| mock_client.inspect.version.return_value = [] | ||
|
|
||
| # Create a mock holder instance | ||
| mock_holder_instance = mock_holder_class.return_value | ||
| mock_holder_instance.get_client.return_value = mock_client | ||
|
|
||
| yield mock_client | ||
|
|
||
|
|
||
| @pytest.mark.asyncio | ||
| async def test_health_liveness( | ||
| test_config: AppConfig, | ||
| test_auth: AuthTuple, | ||
| ) -> None: | ||
| """Test that liveness probe endpoint is alive | ||
|
|
||
| This integration test verifies: | ||
| - Endpoint handler integrates with configuration system | ||
| - Real noop authentication is used | ||
| - Response structure matches expected format | ||
|
|
||
| Args: | ||
| test_config: Loads test configuration | ||
| test_auth: noop authentication tuple | ||
| """ | ||
| _ = test_config | ||
|
|
||
| response = await liveness_probe_get_method(auth=test_auth) | ||
|
|
||
| # Verify that service is alive | ||
| assert response.alive is True | ||
|
|
||
|
|
||
| @pytest.mark.asyncio | ||
| async def test_health_readiness_provider_statuses( | ||
| mock_llama_stack_client_health: AsyncMockType, | ||
| mocker: MockerFixture, | ||
| ) -> None: | ||
| """Test that get_providers_health_statuses correctly retrieves and returns | ||
| provider health statuses. | ||
|
|
||
| This integration test verifies: | ||
| - Function correctly retrieves provider list from Llama Stack client | ||
| - Both healthy and unhealthy providers are properly processed | ||
| - Provider health status, ID, and error messages are correctly mapped | ||
| - Multiple providers with different health states are handled correctly | ||
|
|
||
| Args: | ||
| mock_llama_stack_client_health: Mocked Llama Stack client | ||
| mocker: pytest-mock fixture for creating mock objects | ||
| """ | ||
| # Arrange: Set up mock provider list with mixed health statuses | ||
| mock_llama_stack_client_health.providers.list.return_value = [ | ||
| mocker.Mock( | ||
| provider_id="unhealthy-provider-1", | ||
| health={ | ||
| "status": HealthStatus.ERROR.value, | ||
| "message": "Database connection failed", | ||
| }, | ||
| ), | ||
| mocker.Mock( | ||
| provider_id="unhealthy-provider-2", | ||
| health={ | ||
| "status": HealthStatus.ERROR.value, | ||
| "message": "Service unavailable", | ||
| }, | ||
| ), | ||
| mocker.Mock( | ||
| provider_id="healthy-provider", health={"status": "ok", "message": ""} | ||
| ), | ||
| ] | ||
|
|
||
| # Call the function to retrieve provider health statuses | ||
| result = await get_providers_health_statuses() | ||
|
|
||
| # Verify providers | ||
| assert result[0].provider_id == "unhealthy-provider-1" | ||
| assert result[0].status == "Error" | ||
| assert result[0].message == "Database connection failed" | ||
|
|
||
| assert result[1].provider_id == "unhealthy-provider-2" | ||
| assert result[1].status == "Error" | ||
| assert result[1].message == "Service unavailable" | ||
|
|
||
| assert result[2].provider_id == "healthy-provider" | ||
| assert result[2].status == "ok" | ||
| assert result[2].message == "" | ||
|
|
||
|
|
||
| @pytest.mark.asyncio | ||
| async def test_health_readiness_client_error( | ||
| test_response: Response, | ||
| test_auth: AuthTuple, | ||
| ) -> None: | ||
| """Test that readiness probe endpoint handles uninitialized client gracefully. | ||
|
|
||
| This integration test verifies: | ||
| - Endpoint handles missing client initialization gracefully | ||
| - Error is caught and returned as proper health status | ||
| - Service returns 503 status code for unhealthy state | ||
| - Error message includes details about initialization failure | ||
|
|
||
| Args: | ||
| test_response: FastAPI response object | ||
| test_auth: noop authentication tuple | ||
| """ | ||
| result = await readiness_probe_get_method(auth=test_auth, response=test_response) | ||
|
|
||
| # Verify HTTP status code is 503 (Service Unavailable) | ||
| assert test_response.status_code == status.HTTP_503_SERVICE_UNAVAILABLE | ||
|
|
||
| # Verify that service returns error response when client not initialized | ||
| assert result.ready is False | ||
| assert "Providers not healthy" in result.reason | ||
| assert "unknown" in result.reason | ||
|
|
||
| # Verify the response includes provider error details | ||
| assert len(result.providers) == 1 | ||
| assert result.providers[0].provider_id == "unknown" | ||
| assert result.providers[0].status == "Error" | ||
| assert ( | ||
| "AsyncLlamaStackClient has not been initialised" in result.providers[0].message | ||
| ) | ||
|
|
||
|
|
||
| @pytest.mark.asyncio | ||
| async def test_health_readiness( | ||
| mock_llama_stack_client_health: AsyncMockType, | ||
| test_response: Response, | ||
| test_auth: AuthTuple, | ||
| ) -> None: | ||
| """Test that readiness probe endpoint returns readiness status. | ||
|
|
||
| This integration test verifies: | ||
| - Endpoint handler integrates with configuration system | ||
| - Configuration values are correctly accessed | ||
| - Real noop authentication is used | ||
| - Response structure matches expected format | ||
|
|
||
| Args: | ||
| mock_llama_stack_client_health: Mocked Llama Stack client | ||
| test_response: FastAPI response object | ||
| test_auth: noop authentication tuple | ||
| """ | ||
| _ = mock_llama_stack_client_health | ||
|
|
||
| result = await readiness_probe_get_method(auth=test_auth, response=test_response) | ||
|
|
||
| # Verify that service returns readiness response | ||
| assert result.ready is True | ||
| assert result.reason == "All providers are healthy" | ||
| assert result.providers is not None | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Stub healthy providers before asserting readiness.
With no return value configured for
mock_llama_stack_client_health.providers.list,get_providers_health_statuses()hits the exception path, returns an"unknown"error entry, andreadiness_probe_get_method()keepsreadyfalse—so the assertions on Lines 181-183 fail. Set an explicit healthy provider list in this test.async def test_health_readiness( mock_llama_stack_client_health: AsyncMockType, + mocker: MockerFixture, test_response: Response, test_auth: AuthTuple, ) -> None: @@ - Args: - mock_llama_stack_client_health: Mocked Llama Stack client - test_response: FastAPI response object - test_auth: noop authentication tuple + Args: + mock_llama_stack_client_health: Mocked Llama Stack client + mocker: pytest-mock fixture for creating mock objects + test_response: FastAPI response object + test_auth: noop authentication tuple @@ - _ = mock_llama_stack_client_health + mock_llama_stack_client_health.providers.list.return_value = [ + mocker.Mock( + provider_id="healthy-provider", + health={"status": "ok", "message": ""}, + ) + ] result = await readiness_probe_get_method(auth=test_auth, response=test_response)🤖 Prompt for AI Agents