Quellcode durchsuchen

support/testing: new kvmtool runtime test

Signed-off-by: Julien Olivain <ju.o@free.fr>
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
Julien Olivain vor 3 Wochen
Ursprung
Commit
577a2a32af

+ 2 - 0
DEVELOPERS

@@ -1934,6 +1934,8 @@ F:	support/testing/tests/package/test_kmod.py
 F:	support/testing/tests/package/test_kmod/
 F:	support/testing/tests/package/test_kmscube.py
 F:	support/testing/tests/package/test_kmscube/
+F:	support/testing/tests/package/test_kvmtool.py
+F:	support/testing/tests/package/test_kvmtool/
 F:	support/testing/tests/package/test_lame.py
 F:	support/testing/tests/package/test_less.py
 F:	support/testing/tests/package/test_libcamera.py

+ 97 - 0
support/testing/tests/package/test_kvmtool.py

@@ -0,0 +1,97 @@
+import os
+
+import infra.basetest
+
+
+class TestKvmTool(infra.basetest.BRTest):
+    # This test passes the Buildroot image directory to the emulated
+    # guest using the 9p virtiofs. This guest enables the
+    # virtualization support. It will start a nested KVM virtual
+    # machine, using the same Kernel/initramfs images. For these
+    # reasons, we need a specific kernel configuration that enables
+    # KVM and 9P.
+    kern_frag = \
+        infra.filepath("tests/package/test_kvmtool/linux-kvm.fragment")
+    rootfs_overlay = \
+        infra.filepath("tests/package/test_kvmtool/rootfs-overlay")
+    config = \
+        f"""
+        BR2_aarch64=y
+        BR2_TOOLCHAIN_EXTERNAL=y
+        BR2_LINUX_KERNEL=y
+        BR2_LINUX_KERNEL_CUSTOM_VERSION=y
+        BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.18.1"
+        BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y
+        BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="board/qemu/aarch64-virt/linux.config"
+        BR2_LINUX_KERNEL_CONFIG_FRAGMENT_FILES="{kern_frag}"
+        BR2_LINUX_KERNEL_NEEDS_HOST_OPENSSL=y
+        BR2_PACKAGE_KVMTOOL=y
+        BR2_ROOTFS_OVERLAY="{rootfs_overlay}"
+        BR2_TARGET_ROOTFS_CPIO=y
+        # BR2_TARGET_ROOTFS_TAR is not set
+        """
+
+    def test_run(self):
+        img = os.path.join(self.builddir, "images", "rootfs.cpio")
+        kern = os.path.join(self.builddir, "images", "Image")
+        img_dir = os.path.join(self.builddir, "images")
+        virtfs_tag = "br-imgs"
+        virtfs_opts = [
+            f"local,path={img_dir}",
+            f"mount_tag={virtfs_tag}",
+            "security_model=mapped-xattr",
+            "readonly"
+        ]
+        qemu_opts = ["-M", "virt,gic-version=3,virtualization=on",
+                     "-cpu", "cortex-a57",
+                     "-smp", "4",
+                     "-m", "1G",
+                     "-virtfs", ','.join(virtfs_opts),
+                     "-initrd", img]
+        self.emulator.boot(arch="aarch64",
+                           kernel=kern,
+                           options=qemu_opts)
+        self.emulator.login()
+
+        # Test the program can execute.
+        self.assertRunOk("lkvm --version")
+
+        # We mount the virtfs to get the Kernel and initramfs from the
+        # test host.
+        self.assertRunOk(f"mount -t 9p {virtfs_tag} /mnt/")
+
+        # We define an arbitrary kernel command line argument that we
+        # will use to detect we are in our virtual machine.
+        kvm_karg = "br-kvm"
+
+        # The number of CPU of our virtual machine
+        kvm_nproc = 2
+
+        # We run the KVM virtual machine
+        cmd = "lkvm run"
+        cmd += " --kernel /mnt/Image"
+        cmd += " --initrd /mnt/rootfs.cpio"
+        cmd += f" --cpus {kvm_nproc}"
+        cmd += " --mem 320M"
+        cmd += " --console virtio"
+        cmd += " --irqchip gicv3"
+        cmd += f" --params {kvm_karg}"
+
+        # We use qemu.sendline() to run the command because the
+        # program will not return an exit code. The command "lkvm run"
+        # will spawn the new virtual machine console. The login is
+        # expected to be reached after the command is issued.
+        self.emulator.qemu.sendline(cmd)
+
+        # We login in the virtual machine.
+        self.emulator.login()
+
+        # We check we can see our kernel argument.
+        out, ret = self.emulator.run("cat /proc/cmdline")
+        self.assertEqual(ret, 0)
+        self.assertIn(kvm_karg, out[0])
+
+        # We check the virtual machine has the expected number of CPU.
+        out, ret = self.emulator.run("nproc")
+        self.assertEqual(ret, 0)
+        self.assertEqual(int(out[0]), kvm_nproc)

+ 6 - 0
support/testing/tests/package/test_kvmtool/linux-kvm.fragment

@@ -0,0 +1,6 @@
+CONFIG_VIRTUALIZATION=y
+CONFIG_KVM=y
+CONFIG_NET_9P=y
+CONFIG_NET_9P_VIRTIO=y
+CONFIG_9P_FS=y
+CONFIG_9P_FS_POSIX_ACL=y

+ 3 - 0
support/testing/tests/package/test_kvmtool/rootfs-overlay/etc/profile.d/stty-raw.sh

@@ -0,0 +1,3 @@
+# Avoid double-cooking the terminal, otherwise the test infrastructure
+# would not be able to retrieve return codes properly.
+grep -Fq br-kvm /proc/cmdline && stty raw