Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion nanokvm/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
GetHardwareRsp,
GetHdmiStateRsp,
GetHidModeRsp,
GetImagesRsp,
GetInfoRsp,
GetMdnsStateRsp,
GetMemoryLimitRsp,
Expand Down Expand Up @@ -194,7 +195,7 @@ async def _api_request_json(
raw_response = await response.json(content_type=None)
_LOGGER.debug("Raw JSON response data: %s", raw_response)
# Parse the outer ApiResponse structure
api_response = ApiResponse[response_model].parse_obj(raw_response) # type: ignore
api_response = ApiResponse[response_model].model_validate(raw_response) # type: ignore
except (json.JSONDecodeError, ValidationError) as err:
raise NanoKVMInvalidResponseError(
f"Invalid JSON response received: {err}"
Expand Down Expand Up @@ -397,6 +398,14 @@ async def get_tailscale_status(self) -> GetTailscaleStatusRsp:
response_model=GetTailscaleStatusRsp,
)

async def get_images(self) -> GetImagesRsp:
"""Get the list of available image files."""
return await self._api_request_json(
hdrs.METH_GET,
"/storage/image",
response_model=GetImagesRsp,
)

async def get_mounted_image(self) -> GetMountedImageRsp:
"""Get the currently mounted image file."""
return await self._api_request_json(
Expand Down
74 changes: 73 additions & 1 deletion tests/test_client.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,82 @@
from aiohttp import ClientSession
from aioresponses import aioresponses

from nanokvm.client import NanoKVMClient
from nanokvm.client import NanoKVMApiError, NanoKVMClient
from nanokvm.models import ApiResponseCode


async def test_client() -> None:
"""Test the NanoKVMClient."""
async with ClientSession() as session:
client = NanoKVMClient("http://localhost:8888/api/", session)
assert client is not None


async def test_get_images_success() -> None:
"""Test get_images with a successful response."""
async with ClientSession() as session:
client = NanoKVMClient(
"http://localhost:8888/api/", session, token="test-token"
)

with aioresponses() as m:
m.get(
"http://localhost:8888/api/storage/image",
payload={
"code": 0,
"msg": "success",
"data": {
"files": [
"/data/alpine-standard-3.23.2-x86_64.iso",
"/data/cs10-js.iso",
]
},
},
)

response = await client.get_images()

assert response is not None
assert len(response.files) == 2
assert "/data/alpine-standard-3.23.2-x86_64.iso" in response.files
assert "/data/cs10-js.iso" in response.files


async def test_get_images_empty() -> None:
"""Test get_images with an empty list."""
async with ClientSession() as session:
client = NanoKVMClient(
"http://localhost:8888/api/", session, token="test-token"
)

with aioresponses() as m:
m.get(
"http://localhost:8888/api/storage/image",
payload={"code": 0, "msg": "success", "data": {"files": []}},
)

response = await client.get_images()

assert response is not None
assert len(response.files) == 0


async def test_get_images_api_error() -> None:
"""Test get_images with an API error response."""
async with ClientSession() as session:
client = NanoKVMClient(
"http://localhost:8888/api/", session, token="test-token"
)

with aioresponses() as m:
m.get(
"http://localhost:8888/api/storage/image",
payload={"code": -1, "msg": "failed to list images", "data": None},
)

try:
await client.get_images()
raise AssertionError("Expected NanoKVMApiError to be raised")
except NanoKVMApiError as e:
assert e.code == ApiResponseCode.FAILURE
assert "failed to list images" in e.msg
Loading