Skip to content

Commit 66558c8

Browse files
committed
Fix tests and parsing
1 parent 04b4101 commit 66558c8

File tree

3 files changed

+47
-20
lines changed

3 files changed

+47
-20
lines changed

src/aleph/vm/orchestrator/machine.py

+9-7
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
11
import asyncio
22
import json
33
import re
4+
import shutil
45

56
import psutil
67

8+
from aleph.vm.utils import run_in_subprocess
79

8-
async def get_hardware_info():
9-
lshw = await asyncio.create_subprocess_shell(
10-
"lshw -sanitize -json", stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE
11-
)
1210

13-
output, _ = await lshw.communicate()
14-
data = json.loads(output)
11+
async def get_hardware_info():
12+
lshw_path = shutil.which("lshw")
13+
assert lshw_path, "lshw not found in PATH. apt install lshw."
14+
lshw_output = await run_in_subprocess([lshw_path, "-sanitize", "-json"])
15+
data = json.loads(lshw_output)
1516

1617
hw_info = {"cpu": None, "memory": None}
1718

@@ -26,12 +27,13 @@ async def get_hardware_info():
2627

2728
def get_cpu_info(hw):
2829
cpu_info = hw["cpu"]
29-
architecture = cpu_info["width"]
3030

3131
if "x86_64" in cpu_info["capabilities"] or "x86-64" in cpu_info["capabilities"]:
3232
architecture = "x86_64"
3333
elif "arm64" in cpu_info["capabilities"] or "arm-64" in cpu_info["capabilities"]:
3434
architecture = "arm64"
35+
else:
36+
architecture = None
3537

3638
vendor = cpu_info["vendor"]
3739
# lshw vendor implementation => https://github.com/lyonel/lshw/blob/15e4ca64647ad119b69be63274e5de2696d3934f/src/core/cpuinfo.cc#L308

src/aleph/vm/orchestrator/resources.py

+6-6
Original file line numberDiff line numberDiff line change
@@ -99,17 +99,17 @@ class ExtendedCpuProperties(CpuProperties):
9999
"""CPU properties."""
100100

101101
model: Optional[str] = Field(default=None, description="CPU model")
102-
frequency: Optional[str] = Field(default=None, description="CPU frequency")
103-
count: Optional[str] = Field(default=None, description="CPU count")
102+
frequency: Optional[int] = Field(default=None, description="CPU frequency")
103+
count: Optional[int] = Field(default=None, description="CPU count")
104104

105105

106106
class MemoryProperties(BaseModel):
107107
"""MEMORY properties."""
108108

109-
size: Optional[str] = Field(default=None, description="Memory size")
109+
size: Optional[int] = Field(default=None, description="Memory size")
110110
units: Optional[str] = Field(default=None, description="Memory size units")
111111
type: Optional[str] = Field(default=None, description="Memory type")
112-
clock: Optional[str] = Field(default=None, description="Memory clock")
112+
clock: Optional[int] = Field(default=None, description="Memory clock")
113113
clock_units: Optional[str] = Field(default=None, description="Memory clock units")
114114

115115

@@ -170,8 +170,8 @@ async def get_machine_capability() -> MachineCapability:
170170
architecture=cpu_info["architecture"],
171171
vendor=cpu_info["vendor"],
172172
model=cpu_info["model"],
173-
frequency=cpu_info["frequency"],
174-
count=cpu_info["count"],
173+
frequency=(cpu_info["frequency"]),
174+
count=(cpu_info["count"]),
175175
features=list(
176176
filter(
177177
None,

tests/supervisor/test_views.py

+32-7
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import asyncio
2+
import os
23
import tempfile
34
from copy import deepcopy
45
from pathlib import Path
@@ -11,7 +12,6 @@
1112
from pytest_mock import MockerFixture
1213

1314
from aleph.vm.conf import settings
14-
from aleph.vm.orchestrator.machine import get_hardware_info
1515
from aleph.vm.orchestrator.supervisor import setup_webapp
1616
from aleph.vm.pool import VmPool
1717
from aleph.vm.sevclient import SevClient
@@ -55,7 +55,7 @@ async def test_system_usage(aiohttp_client, mocker, mock_app_with_pool):
5555
assert resp["cpu"]["count"] > 0
5656

5757

58-
FAKE_SYSTEM_INFO = {
58+
MOCK_SYSTEM_INFO = {
5959
"cpu": {
6060
"id": "cpu",
6161
"class": "processor",
@@ -74,6 +74,7 @@ async def test_system_usage(aiohttp_client, mocker, mock_app_with_pool):
7474
"width": 64,
7575
"configuration": {"cores": "8", "enabledcores": "8", "microcode": "167776681", "threads": "1"},
7676
"capabilities": {
77+
"x86-64": "64bits extensions (x86-64)",
7778
"fpu": "mathematical co-processor",
7879
"fpu_exception": "FPU exceptions reporting",
7980
"wp": True,
@@ -209,7 +210,7 @@ async def test_system_usage(aiohttp_client, mocker, mock_app_with_pool):
209210
async def test_system_usage_mock(aiohttp_client, mocker, mock_app_with_pool):
210211
"""Test that the usage system endpoints response value. No auth needed"""
211212

212-
mocker.patch("aleph.vm.orchestrator.machine.get_hardware_info", FAKE_SYSTEM_INFO)
213+
mocker.patch("aleph.vm.orchestrator.resources.get_hardware_info", return_value=MOCK_SYSTEM_INFO)
213214
mocker.patch(
214215
"psutil.getloadavg",
215216
lambda: [1, 2, 3],
@@ -233,7 +234,10 @@ async def test_system_usage_mock(aiohttp_client, mocker, mock_app_with_pool):
233234
@pytest.mark.asyncio
234235
async def test_system_capability_mock(aiohttp_client, mocker):
235236
"""Test that the capability system endpoints response value. No auth needed"""
236-
mocker.patch("aleph.vm.orchestrator.machine.get_hardware_info", FAKE_SYSTEM_INFO)
237+
mocker.patch("aleph.vm.orchestrator.resources.get_hardware_info", return_value=MOCK_SYSTEM_INFO)
238+
mocker.patch("aleph.vm.orchestrator.resources.check_amd_sev_supported", return_value=True)
239+
mocker.patch("aleph.vm.orchestrator.resources.check_amd_sev_es_supported", return_value=True)
240+
mocker.patch("aleph.vm.orchestrator.resources.check_amd_sev_snp_supported", return_value=False)
237241
mocker.patch(
238242
"psutil.getloadavg",
239243
lambda: [1, 2, 3],
@@ -252,14 +256,34 @@ async def test_system_capability_mock(aiohttp_client, mocker):
252256
"cpu": {
253257
"architecture": "x86_64",
254258
"vendor": "AuthenticAMD",
259+
"features": ["sev", "sev_es"],
255260
"model": "AMD EPYC 7763 64-Core Processor",
256-
"frequency": "2000000000",
257-
"count": "200",
261+
"frequency": 2000000000,
262+
"count": 200,
258263
},
259-
"memory": {"size": "17179869184", "units": "bytes", "type": "", "clock": None, "clock_units": ""},
264+
"memory": {"size": 17179869184, "units": "bytes", "type": "", "clock": None, "clock_units": None},
260265
}
261266

262267

268+
@pytest.mark.asyncio
269+
async def test_system_capability_real(aiohttp_client, mocker):
270+
"""Test that the capability system endpoints response value
271+
with real system value, no mock so we don't know the definive value but want ot see that it works"""
272+
if os.environ.get("GITHUB_JOB"):
273+
pytest.xfail("Test fail inside GITHUB CI because of invalid lshw return inside worker")
274+
275+
app = setup_webapp()
276+
client = await aiohttp_client(app)
277+
response: web.Response = await client.get("/about/capability")
278+
assert response.status == 200
279+
# check if it is valid json
280+
resp = await response.json()
281+
assert resp.get("cpu"), resp
282+
assert resp["cpu"].get("architecture")
283+
assert resp.get("memory")
284+
assert resp["memory"].get("size")
285+
286+
263287
@pytest.mark.asyncio
264288
async def test_allocation_invalid_auth_token(aiohttp_client):
265289
"""Test that the allocation endpoint fails when an invalid auth token is provided."""
@@ -456,6 +480,7 @@ def mock_is_kernel_enabled_gpu(pci_host: str) -> bool:
456480
async def test_system_usage_gpu_ressources(aiohttp_client, mocker, mock_app_with_pool):
457481
"""Test gpu are properly listed"""
458482
client = await aiohttp_client(await mock_app_with_pool)
483+
mocker.patch("aleph.vm.orchestrator.resources.get_hardware_info", return_value=MOCK_SYSTEM_INFO)
459484

460485
response: web.Response = await client.get("/about/usage/system")
461486
assert response.status == 200

0 commit comments

Comments
 (0)