Skip to content

Commit

Permalink
test: add boot test on arm64 as well
Browse files Browse the repository at this point in the history
This commit enables arm64 boot tests for the generated image.
  • Loading branch information
mvo5 committed Jan 15, 2024
1 parent 7b37cde commit 5244759
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 14 deletions.
1 change: 0 additions & 1 deletion test/test_smoke.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,6 @@ def test_image_is_generated(image_type):
f"content: {os.listdir(os.fspath(image_type.img_path))}"


@pytest.mark.skipif(platform.system() != "Linux", reason="boot test only runs on linux right now")
@pytest.mark.parametrize("image_type", SUPPORTED_IMAGE_TYPES, indirect=["image_type"])
def test_image_boots(image_type):
with QEMU(image_type.img_path) as test_vm:
Expand Down
58 changes: 45 additions & 13 deletions test/vm.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import abc
import glob
import pathlib
import platform
import subprocess
import sys
import uuid
Expand Down Expand Up @@ -85,32 +87,62 @@ class QEMU(VM):
# TODO: support qemu-system-aarch64 too :)
QEMU = "qemu-system-x86_64"

def __init__(self, img, snapshot=True):
def __init__(self, img, arch="", snapshot=True):
super().__init__()
self._img = pathlib.Path(img)
if arch in ("", "native"):
arch = platform.machine()
self._arch = arch
self._qemu_p = None
self._snapshot = snapshot

def start(self):
if self.running():
return
log_path = self._img.with_suffix(".serial-log")
self._ssh_port = get_free_port()
self._address = "localhost"
qemu_cmdline = [
self.QEMU, "-enable-kvm",
"-m", self.MEM,
# get "illegal instruction" inside the VM otherwise
def _find_ovmf_bios(self):
match self._arch:
case "arm64", "aarch64":
p = "/opt/homebrew/Cellar/qemu/*/share/qemu/edk2-aarch64-code.fd"
m = glob.glob(p)
if len(m) != 1:
raise ValueError("cannot find edk2 bios in {p}: {m}")
return m[0]
case _:
raise ValueError("ovmf bios only supported on arm64 right now")

def _gen_qemu_cmdline(self):
qemu_cmdline_common = [
"-cpu", "host",
"-nographic",
"-serial", "stdio",
"-monitor", "none",
"-netdev", f"user,id=net.0,hostfwd=tcp::{self._ssh_port}-:22",
"-device", "rtl8139,netdev=net.0",
"-m", self.MEM,
]
if self._snapshot:
qemu_cmdline.append("-snapshot")
qemu_cmdline.append(self._img)
qemu_cmdline_common.append("-snapshot")
qemu_cmdline_common.append(self._img)
match self._arch:
case "arm64", "aarch64":
return [
"qemu-system-aarch64",
"-M", "accel=hvf",
"-machine", "virt",
"-bios", self._find_ovmf_bios(),
]
case "amd64", "x86_64":
return [
"qemu-system-x86_64",
"-M", "accel=kvm",
] + qemu_cmdline_common
case _:
raise ValueError(f"unsupported architecture {self._arch}")

def start(self):
if self.running():
return
log_path = self._img.with_suffix(".serial-log")
self._ssh_port = get_free_port()
self._address = "localhost"
qemu_cmdline = self._gen_qemu_cmdline()
self._log(f"vm starting, log available at {log_path}")

# XXX: use systemd-run to ensure cleanup?
Expand Down

0 comments on commit 5244759

Please sign in to comment.