Skip to content
Open
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ ENHANCEMENTS:
* Exclude recovery service vaults from e2e tests ([#4920](https://github.com/microsoft/AzureTRE/issues/4920))

BUG FIXES:
* Fix Health check can falsely return OK even if Cosmos is down or inaccessible. ([#4926](https://github.com/microsoft/AzureTRE/issues/4926))
* Fix API timeout and name collision failures on workspace creation by checking storage account name availability and improved logging. ([#4946](https://github.com/microsoft/AzureTRE/pull/4946))
* Fix error handling in airlock processor ([#4929](https://github.com/microsoft/AzureTRE/pull/4929))

Expand Down
2 changes: 1 addition & 1 deletion api_app/_version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "0.25.25"
__version__ = "0.25.26"
3 changes: 2 additions & 1 deletion api_app/services/health_checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ async def create_state_store_status() -> Tuple[StatusEnum, str]:
message = ""
try:
container: ContainerProxy = await Database().get_container_proxy(STATE_STORE_RESOURCES_CONTAINER)
container.query_items("SELECT TOP 1 * FROM c")
async for _ in container.query_items("SELECT TOP 1 * FROM c", max_item_count=1):
break
except exceptions.ServiceRequestError:
status = StatusEnum.not_ok
message = strings.STATE_STORE_ENDPOINT_NOT_RESPONDING
Expand Down
41 changes: 39 additions & 2 deletions api_app/tests_ma/test_services/test_health_checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from unittest.mock import AsyncMock, MagicMock
import pytest
from azure.core.exceptions import ServiceRequestError
from azure.cosmos.exceptions import CosmosHttpResponseError
from azure.servicebus.exceptions import ServiceBusConnectionError
from mock import patch
Comment thread
JC-wk marked this conversation as resolved.
from models.schemas.status import StatusEnum
Expand All @@ -11,8 +12,11 @@
pytestmark = pytest.mark.asyncio


@patch("azure.cosmos.aio.ContainerProxy.query_items", return_value=AsyncMock())
async def test_get_state_store_status_responding(_) -> None:
@patch("api.dependencies.database.Database.get_container_proxy")
async def test_get_state_store_status_responding(get_container_proxy_mock) -> None:
container_mock = MagicMock()
container_mock.query_items.return_value = AsyncIterator([{"id": "item"}])
get_container_proxy_mock.return_value = container_mock
status, message = await health_checker.create_state_store_status()

assert status == StatusEnum.ok
Expand All @@ -39,6 +43,39 @@ async def test_get_state_store_status_other_exception(container_proxy_mock) -> N
assert message == strings.UNSPECIFIED_ERROR


class AsyncIteratorWithError:
def __init__(self, exception):
self.exception = exception

def __aiter__(self):
return self

async def __anext__(self):
raise self.exception


@patch("api.dependencies.database.Database.get_container_proxy")
async def test_get_state_store_status_cosmos_http_error(get_container_proxy_mock) -> None:
container_mock = MagicMock()
container_mock.query_items.return_value = AsyncIteratorWithError(CosmosHttpResponseError(message="some message"))
get_container_proxy_mock.return_value = container_mock
status, message = await health_checker.create_state_store_status()

assert status == StatusEnum.not_ok
assert message == strings.STATE_STORE_ENDPOINT_NOT_ACCESSIBLE


@patch("api.dependencies.database.Database.get_container_proxy")
async def test_get_state_store_status_service_request_error(get_container_proxy_mock) -> None:
container_mock = MagicMock()
container_mock.query_items.return_value = AsyncIteratorWithError(ServiceRequestError(message="some message"))
get_container_proxy_mock.return_value = container_mock
status, message = await health_checker.create_state_store_status()

assert status == StatusEnum.not_ok
assert message == strings.STATE_STORE_ENDPOINT_NOT_RESPONDING


@patch("core.credentials.get_credential_async_context")
@patch("services.health_checker.ServiceBusClient")
async def test_get_service_bus_status_responding(service_bus_client_mock, get_credential_async_context) -> None:
Expand Down
Loading