Skip to content

Commit

Permalink
Fix: Orchestrator failed with `assert result["result"] == HTTPOk.stat…
Browse files Browse the repository at this point in the history
…us_code`

Problem:

The diagnostic VM returned HTTP 200 with {"result": False} when it could not connect to the internet.

Since this is an OK return code, `raise_for_status` did not raise an error and an assertion error was raised.

Solution:

Test that the returned status code also corresponds to HTTP OK.
  • Loading branch information
hoh committed Jun 12, 2024
1 parent b63d248 commit 0e656ba
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 3 deletions.
14 changes: 11 additions & 3 deletions src/aleph/vm/orchestrator/status.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,9 +118,17 @@ async def check_ipv6(session: ClientSession, vm_id: ItemHash) -> bool:
async def check_internet(session: ClientSession, vm_id: ItemHash) -> bool:
"""Check that the VM has internet connectivity. This requires DNS, IP, HTTP and TLS to work."""
try:
result: dict = await get_json_from_vm(session, vm_id, "/internet")
assert result["result"] == HTTPOk.status_code
assert "Server" in result["headers"]
response: dict = await get_json_from_vm(session, vm_id, "/internet")

# The HTTP Header "Server" must always be present in the result.
if "Server" not in response["headers"]:
raise ValueError("Server header not found in the result.")

# The diagnostic VM returns HTTP 200 with {"result": False} when cannot connect to the internet.
# else it forwards the return code if its own test endpoint.
if response.get("result") != HTTPOk.status_code:
return False

return True
except ClientResponseError:
return False
Expand Down
39 changes: 39 additions & 0 deletions tests/supervisor/test_status.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
from unittest.mock import AsyncMock, MagicMock, Mock

import pytest
from aleph_message.models import ItemHash

from aleph.vm.orchestrator.status import check_internet


@pytest.mark.asyncio
async def test_check_internet_no_server_header():
vm_id = ItemHash("cafecafecafecafecafecafecafecafecafecafecafecafecafecafecafecafe")

mock_session = Mock()
mock_session.get = MagicMock()
mock_session.get.__aenter__.return_value.json = AsyncMock(return_value={"result": 200})

# A "Server" header is always expected in the result from the VM.
# If it is not present, the diagnostic VM is not working correctly
# and an error must be raised.
with pytest.raises(ValueError):
await check_internet(mock_session, vm_id)


@pytest.mark.asyncio
async def test_check_internet_wrong_result_code():
vm_id = ItemHash("cafecafecafecafecafecafecafecafecafecafecafecafecafecafecafecafe")

mock_session = Mock()
mock_session.get = MagicMock()

mock_session.get.return_value.__aenter__.return_value.json = AsyncMock(
return_value={"result": 200, "headers": {"Server": "nginx"}}
)
assert await check_internet(mock_session, vm_id) is True

mock_session.get.return_value.__aenter__.return_value.json = AsyncMock(
return_value={"result": 400, "headers": {"Server": "nginx"}}
)
assert await check_internet(mock_session, vm_id) is False

0 comments on commit 0e656ba

Please sign in to comment.