Files
nest/tests/test_firecracker_config.py
T
kstyagi fb80ce7c8a feat: Add storage management for VM creation and resizing
- Introduced storage parameter in VmCreateRequest and VmResizeRequest models.
- Implemented storage validation to ensure minimum and maximum limits.
- Enhanced CLI to support storage options during VM creation and resizing.
- Updated lifecycle management to handle pending resize operations for VM resources.
- Added methods for resizing VM disks and validating storage capacity.
- Updated API endpoints to accommodate new storage functionality.
- Refactored related validation and configuration logic to support storage management.
2026-09-21 19:16:33 +05:30

134 lines
4.5 KiB
Python

from __future__ import annotations
import unittest
from ipaddress import IPv4Address, IPv4Network
from pathlib import Path
from uvm.config import Settings
from uvm.domain import VmRecord
from uvm.firecracker.api import FirecrackerClient
from uvm.firecracker.config import build_config, vcpu_count
class RecordingFirecrackerClient(FirecrackerClient):
def __init__(self) -> None:
self.calls: list[tuple[str, str, object]] = []
def _request(self, method: str, path: str, body: object) -> None:
self.calls.append((method, path, body))
class FirecrackerConfigTests(unittest.TestCase):
def test_uses_arm_boot_console_arguments_only_on_arm64(self) -> None:
vm = VmRecord(
id="vm-test",
cpu=1,
ram_mib=512,
guest_ip="10.42.0.2",
gateway="10.42.0.1",
tap="uvm-test",
mac="02:fc:00:00:00:01",
socket="/tmp/firecracker.sock",
config="/tmp/config.json",
log="/tmp/firecracker.log",
)
for architecture in ("x86_64", "aarch64", "arm64"):
with self.subTest(architecture=architecture):
config = build_config(
Settings(architecture=architecture),
vm,
Path("/images/vmlinux"),
Path("/vm/rootfs.ext4"),
)
arguments = config["boot-source"]["boot_args"].split()
self.assertEqual("keep_bootcon" in arguments, architecture != "x86_64")
self.assertIn("console=ttyS0", arguments)
self.assertIn("ip=10.42.0.2::10.42.0.1:255.255.255.0::eth0:off", arguments)
def test_builds_a_writable_vm_disk_configuration(self) -> None:
vm = VmRecord(
id="vm-test",
cpu=0.5,
ram_mib=512,
guest_ip="10.42.0.2",
gateway="10.42.0.1",
tap="uvm-test",
mac="02:fc:00:00:00:01",
socket="/tmp/firecracker.sock",
config="/tmp/config.json",
log="/tmp/firecracker.log",
disk="/vm/rootfs.ext4",
)
config = build_config(
Settings(),
vm,
Path("/images/vmlinux"),
Path("/vm/rootfs.ext4"),
)
self.assertEqual(vcpu_count(0.5), 1)
self.assertEqual(config["machine-config"]["mem_size_mib"], 512)
self.assertEqual(config["drives"][0]["path_on_host"], "/vm/rootfs.ext4")
self.assertIn("ip=10.42.0.2::10.42.0.1", config["boot-source"]["boot_args"])
self.assertNotIn("password", str(config))
def test_configures_firecracker_in_required_order_before_start(self) -> None:
vm = VmRecord(
id="vm-test",
cpu=1,
ram_mib=512,
guest_ip="10.42.0.2",
gateway="10.42.0.1",
tap="uvm-test",
mac="02:fc:00:00:00:01",
socket="/tmp/firecracker.sock",
config="/tmp/config.json",
log="/tmp/firecracker.log",
disk="/vm/rootfs.ext4",
)
config = build_config(
Settings(), vm, Path("/images/vmlinux"), Path("/vm/rootfs.ext4")
)
client = RecordingFirecrackerClient()
client.configure_and_start(config)
self.assertEqual(
[path for _method, path, _body in client.calls],
[
"/machine-config",
"/boot-source",
"/drives/rootfs",
"/network-interfaces/eth0",
"/actions",
],
)
self.assertEqual(
client.calls[0][2],
{"vcpu_count": 1, "mem_size_mib": 512, "smt": False},
)
self.assertEqual(client.calls[-1][2], {"action_type": "InstanceStart"})
def test_uses_the_configured_network_netmask_in_guest_boot_arguments(self) -> None:
settings = Settings(
network=IPv4Network("10.50.0.0/16"),
gateway=IPv4Address("10.50.0.1"),
)
vm = VmRecord(
id="vm-test",
cpu=1,
ram_mib=512,
guest_ip="10.50.0.2",
gateway="10.50.0.1",
tap="uvm-test",
mac="02:fc:00:00:00:01",
socket="/tmp/firecracker.sock",
config="/tmp/config.json",
log="/tmp/firecracker.log",
)
config = build_config(settings, vm, Path("/images/vmlinux"), Path("/vm/rootfs.ext4"))
self.assertIn("ip=10.50.0.2::10.50.0.1:255.255.0.0", config["boot-source"]["boot_args"])