|
11 | 11 | from pytest_mock import MockerFixture
|
12 | 12 |
|
13 | 13 | from aleph.vm.conf import settings
|
| 14 | +from aleph.vm.models import VmExecution |
14 | 15 | from aleph.vm.orchestrator.supervisor import setup_webapp
|
15 | 16 | from aleph.vm.pool import VmPool
|
16 | 17 | from aleph.vm.sevclient import SevClient
|
17 | 18 |
|
18 | 19 |
|
| 20 | +@pytest.fixture() |
| 21 | +def mock_instance_content(): |
| 22 | + fake = { |
| 23 | + "address": "0x101d8D16372dBf5f1614adaE95Ee5CCE61998Fc9", |
| 24 | + "time": 1713874241.800818, |
| 25 | + "allow_amend": False, |
| 26 | + "metadata": None, |
| 27 | + "authorized_keys": None, |
| 28 | + "variables": None, |
| 29 | + "environment": {"reproducible": False, "internet": True, "aleph_api": True, "shared_cache": False}, |
| 30 | + "resources": {"vcpus": 1, "memory": 256, "seconds": 30, "published_ports": None}, |
| 31 | + "payment": {"type": "superfluid", "chain": "BASE"}, |
| 32 | + "requirements": None, |
| 33 | + "replaces": None, |
| 34 | + "rootfs": { |
| 35 | + "parent": {"ref": "63f07193e6ee9d207b7d1fcf8286f9aee34e6f12f101d2ec77c1229f92964696"}, |
| 36 | + "ref": "63f07193e6ee9d207b7d1fcf8286f9aee34e6f12f101d2ec77c1229f92964696", |
| 37 | + "use_latest": True, |
| 38 | + "comment": "", |
| 39 | + "persistence": "host", |
| 40 | + "size_mib": 1000, |
| 41 | + }, |
| 42 | + } |
| 43 | + |
| 44 | + return fake |
| 45 | + |
| 46 | + |
19 | 47 | @pytest.mark.asyncio
|
20 | 48 | async def test_allocation_fails_on_invalid_item_hash(aiohttp_client):
|
21 | 49 | """Test that the allocation endpoint fails when an invalid item_hash is provided."""
|
@@ -137,6 +165,124 @@ def get_persistent_executions(self):
|
137 | 165 | assert await response.json() == {"success": True, "successful": [], "failing": [], "errors": {}}
|
138 | 166 |
|
139 | 167 |
|
| 168 | +@pytest.mark.asyncio |
| 169 | +async def test_v2_executions_list_one_vm(aiohttp_client, mock_app_with_pool, mock_instance_content): |
| 170 | + web_app = await mock_app_with_pool |
| 171 | + pool = web_app["vm_pool"] |
| 172 | + message = InstanceContent.model_validate(mock_instance_content) |
| 173 | + |
| 174 | + hash = "decadecadecadecadecadecadecadecadecadecadecadecadecadecadecadeca" |
| 175 | + |
| 176 | + execution = VmExecution( |
| 177 | + vm_hash=hash, |
| 178 | + message=message, |
| 179 | + original=message, |
| 180 | + persistent=False, |
| 181 | + snapshot_manager=None, |
| 182 | + systemd_manager=None, |
| 183 | + ) |
| 184 | + pool.executions = {hash: execution} |
| 185 | + client = await aiohttp_client(web_app) |
| 186 | + response: web.Response = await client.get( |
| 187 | + "/v2/about/executions/list", |
| 188 | + ) |
| 189 | + assert response.status == 200 |
| 190 | + assert await response.json() == { |
| 191 | + "decadecadecadecadecadecadecadecadecadecadecadecadecadecadecadeca": { |
| 192 | + "networking": {}, |
| 193 | + "status": { |
| 194 | + "defined_at": str(execution.times.defined_at), |
| 195 | + "preparing_at": None, |
| 196 | + "prepared_at": None, |
| 197 | + "starting_at": None, |
| 198 | + "started_at": None, |
| 199 | + "stopping_at": None, |
| 200 | + "stopped_at": None, |
| 201 | + }, |
| 202 | + "running": None, |
| 203 | + } |
| 204 | + } |
| 205 | + |
| 206 | + |
| 207 | +@pytest.mark.asyncio |
| 208 | +async def test_v2_executions_list_vm_network(aiohttp_client, mocker, mock_app_with_pool, mock_instance_content): |
| 209 | + "Test locally but do not create" |
| 210 | + web_app = await mock_app_with_pool |
| 211 | + pool = web_app["vm_pool"] |
| 212 | + message = InstanceContent.model_validate(mock_instance_content) |
| 213 | + |
| 214 | + vm_hash = "decadecadecadecadecadecadecadecadecadecadecadecadecadecadecadeca" |
| 215 | + |
| 216 | + execution = VmExecution( |
| 217 | + vm_hash=hash, |
| 218 | + message=message, |
| 219 | + original=message, |
| 220 | + persistent=False, |
| 221 | + snapshot_manager=None, |
| 222 | + systemd_manager=None, |
| 223 | + ) |
| 224 | + vm_id = 3 |
| 225 | + from aleph.vm.network.hostnetwork import Network, make_ipv6_allocator |
| 226 | + |
| 227 | + network = Network( |
| 228 | + vm_ipv4_address_pool_range=settings.IPV4_ADDRESS_POOL, |
| 229 | + vm_network_size=settings.IPV4_NETWORK_PREFIX_LENGTH, |
| 230 | + external_interface=settings.NETWORK_INTERFACE, |
| 231 | + ipv6_allocator=make_ipv6_allocator( |
| 232 | + allocation_policy=settings.IPV6_ALLOCATION_POLICY, |
| 233 | + address_pool=settings.IPV6_ADDRESS_POOL, |
| 234 | + subnet_prefix=settings.IPV6_SUBNET_PREFIX, |
| 235 | + ), |
| 236 | + use_ndp_proxy=False, |
| 237 | + ipv6_forwarding_enabled=False, |
| 238 | + ) |
| 239 | + network.setup() |
| 240 | + |
| 241 | + from aleph.vm.vm_type import VmType |
| 242 | + |
| 243 | + vm_type = VmType.from_message_content(message) |
| 244 | + tap_interface = await network.prepare_tap(vm_id, vm_hash, vm_type) |
| 245 | + # await network.create_tap(vm_id, tap_interface) |
| 246 | + execution.vm = mocker.Mock() |
| 247 | + execution.vm.tap_interface = tap_interface |
| 248 | + |
| 249 | + pool.executions = {vm_hash: execution} |
| 250 | + client = await aiohttp_client(web_app) |
| 251 | + response: web.Response = await client.get( |
| 252 | + "/v2/about/executions/list", |
| 253 | + ) |
| 254 | + assert response.status == 200 |
| 255 | + assert await response.json() == { |
| 256 | + "decadecadecadecadecadecadecadecadecadecadecadecadecadecadecadeca": { |
| 257 | + "networking": { |
| 258 | + "ipv4_network": "172.16.3.0/24", |
| 259 | + "ipv6_network": "fc00:1:2:3:3:deca:deca:dec0/124", |
| 260 | + "ipv6_ip": "fc00:1:2:3:3:deca:deca:dec1", |
| 261 | + }, |
| 262 | + "status": { |
| 263 | + "defined_at": str(execution.times.defined_at), |
| 264 | + "preparing_at": None, |
| 265 | + "prepared_at": None, |
| 266 | + "starting_at": None, |
| 267 | + "started_at": None, |
| 268 | + "stopping_at": None, |
| 269 | + "stopped_at": None, |
| 270 | + }, |
| 271 | + "running": None, |
| 272 | + } |
| 273 | + } |
| 274 | + |
| 275 | + |
| 276 | +@pytest.mark.asyncio |
| 277 | +async def test_v2_executions_list_empty(aiohttp_client, mock_app_with_pool): |
| 278 | + client = await aiohttp_client(await mock_app_with_pool) |
| 279 | + response: web.Response = await client.get( |
| 280 | + "/v2/about/executions/list", |
| 281 | + ) |
| 282 | + assert response.status == 200 |
| 283 | + assert await response.json() == {} |
| 284 | + |
| 285 | + |
140 | 286 | @pytest.mark.asyncio
|
141 | 287 | async def test_about_certificates_missing_setting(aiohttp_client):
|
142 | 288 | """Test that the certificates system endpoint returns an error if the setting isn't enabled"""
|
@@ -268,7 +414,6 @@ def mock_is_kernel_enabled_gpu(pci_host: str) -> bool:
|
268 | 414 | )
|
269 | 415 |
|
270 | 416 | mocker.patch.object(settings, "ENABLE_GPU_SUPPORT", True)
|
271 |
| - loop = asyncio.new_event_loop() |
272 | 417 | pool = VmPool()
|
273 | 418 | await pool.setup()
|
274 | 419 | app = setup_webapp(pool=pool)
|
|
0 commit comments