test_xen.py 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. import os
  2. import pexpect
  3. import infra.basetest
  4. class TestXenBase(infra.basetest.BRTest):
  5. """A class to test Xen for multiple architectures."""
  6. # We run only in the initramfs; this allows to use a single ramdisk image
  7. # for both the host and the guest.
  8. base_config = \
  9. """
  10. BR2_TOOLCHAIN_EXTERNAL=y
  11. BR2_ROOTFS_POST_BUILD_SCRIPT="support/testing/tests/package/test_xen/common/post-build.sh"
  12. BR2_LINUX_KERNEL=y
  13. BR2_LINUX_KERNEL_CUSTOM_VERSION=y
  14. BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="6.12.9"
  15. BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y
  16. BR2_LINUX_KERNEL_NEEDS_HOST_OPENSSL=y
  17. BR2_PACKAGE_XEN=y
  18. BR2_PACKAGE_XEN_HYPERVISOR=y
  19. BR2_PACKAGE_XEN_TOOLS=y
  20. BR2_TARGET_ROOTFS_CPIO=y
  21. # BR2_TARGET_ROOTFS_TAR is not set
  22. BR2_TARGET_UBOOT=y
  23. BR2_TARGET_UBOOT_BUILD_SYSTEM_KCONFIG=y
  24. BR2_TARGET_UBOOT_CUSTOM_VERSION=y
  25. BR2_TARGET_UBOOT_CUSTOM_VERSION_VALUE="2025.01"
  26. BR2_TARGET_UBOOT_NEEDS_OPENSSL=y
  27. BR2_TARGET_UBOOT_NEEDS_GNUTLS=y
  28. BR2_PACKAGE_HOST_DOSFSTOOLS=y
  29. BR2_PACKAGE_HOST_GENIMAGE=y
  30. BR2_PACKAGE_HOST_MTOOLS=y
  31. """
  32. def get_dom_uuid(self) -> str:
  33. out, rc = self.emulator.run("cat /sys/hypervisor/uuid")
  34. self.assertEqual(rc, 0, "Failed to get domain UUID")
  35. return out[0]
  36. def assertNumVM(self, x: int) -> None:
  37. out, rc = self.emulator.run("xl vm-list")
  38. self.assertEqual(rc, 0, "Failed to get VM list")
  39. num_vm = len(out) - 1
  40. self.assertEqual(num_vm, x, f"Expected {x} VM(s) but found {num_vm}")
  41. def run_xen_test(self, arch: str, options: list[str]) -> None:
  42. """This functions tests Xen for multiple architectures.
  43. The arch and options parameters are passed to the emulator.
  44. """
  45. # Boot the emulator.
  46. # The system should automatically boot Xen and a Dom0.
  47. self.emulator.boot(arch=arch, options=options)
  48. self.emulator.login()
  49. # Verify that we are indeed running under Xen.
  50. self.assertRunOk("xl info")
  51. # Check that we are dom0.
  52. uuid = self.get_dom_uuid()
  53. dom0_uuid = "00000000-0000-0000-0000-000000000000"
  54. self.assertEqual(uuid, dom0_uuid, f"Unexpected dom UUID {uuid}")
  55. # Check that we have one VM running.
  56. self.assertNumVM(1)
  57. # Create dom1 with console attached and login.
  58. self.emulator.qemu.sendline("xl create -c /etc/xen/dom1.cfg")
  59. self.emulator.login()
  60. # Check that we are not talking to dom0 anymore.
  61. uuid = self.get_dom_uuid()
  62. self.assertNotEqual(uuid, dom0_uuid, "Unexpected dom0 UUID")
  63. # Detach from dom1's console with CTRL-].
  64. # dom1 is still running in the background after that.
  65. self.emulator.qemu.send(chr(0x1d))
  66. mult = self.emulator.timeout_multiplier
  67. index = self.emulator.qemu.expect(["#", pexpect.TIMEOUT],
  68. timeout=2 * mult)
  69. self.assertEqual(index, 0, "Timeout exiting guest")
  70. # Check that we are talking to dom0 again.
  71. uuid = self.get_dom_uuid()
  72. self.assertEqual(uuid, dom0_uuid, f"Unexpected dom UUID {uuid}")
  73. # Check that we have two VMs running.
  74. self.assertNumVM(2)
  75. class TestXenAarch64(TestXenBase):
  76. # Test Xen on 64b Arm.
  77. # Boot flow: Qemu Devicetree -> U-Boot -> Xen UEFI -> Linux
  78. # We need to boot Xen in UEFI to read xen.cfg.
  79. # We use U-Boot as our UEFI firmware.
  80. # We have a custom kernel config to reduce build time.
  81. # Our genimage.cfg is inspired from qemu_aarch64_ebbr_defconfig as we boot
  82. # Xen with UEFI.
  83. config = TestXenBase.base_config + \
  84. """
  85. BR2_aarch64=y
  86. BR2_ROOTFS_OVERLAY="support/testing/tests/package/test_xen/common/overlay \
  87. support/testing/tests/package/test_xen/aarch64/overlay"
  88. BR2_ROOTFS_POST_IMAGE_SCRIPT="support/testing/tests/package/test_xen/aarch64/post-image.sh support/scripts/genimage.sh"
  89. BR2_ROOTFS_POST_SCRIPT_ARGS="-c support/testing/tests/package/test_xen/aarch64/genimage.cfg"
  90. BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="support/testing/tests/package/test_xen/aarch64/linux.config"
  91. BR2_TARGET_UBOOT_BOARD_DEFCONFIG="qemu_arm64"
  92. """
  93. def test_run(self):
  94. uboot_bin = os.path.join(self.builddir, "images", "u-boot.bin")
  95. disk_img = os.path.join(self.builddir, "images", "disk.img")
  96. # We need to run Qemu with virtualization to run Xen.
  97. qemu_opts = [
  98. "-bios", uboot_bin,
  99. "-cpu", "cortex-a53",
  100. "-device", "virtio-blk-device,drive=hd0",
  101. "-drive", f"file={disk_img},if=none,format=raw,id=hd0",
  102. "-m", "1G",
  103. "-machine", "virt,gic-version=3,virtualization=on,acpi=off",
  104. "-smp", "2"
  105. ]
  106. # Run Xen test.
  107. self.run_xen_test(arch="aarch64", options=qemu_opts)
  108. class TestXenArmv7(TestXenBase):
  109. # Test Xen on 32b Arm v7.
  110. # Boot flow: Qemu Devicetree -> U-Boot -> Xen -> Linux
  111. # Xen does not boot with UEFI on 32-bit Arm v7.
  112. # We use U-Boot and a script to load the Dom0 images and amend the
  113. # Devicetree for Xen dynamically.
  114. # We have a custom kernel config to reduce build time.
  115. config = TestXenBase.base_config + \
  116. """
  117. BR2_arm=y
  118. BR2_cortex_a15=y
  119. BR2_ROOTFS_OVERLAY="support/testing/tests/package/test_xen/common/overlay \
  120. support/testing/tests/package/test_xen/arm/overlay"
  121. BR2_ROOTFS_POST_IMAGE_SCRIPT="support/scripts/genimage.sh"
  122. BR2_ROOTFS_POST_SCRIPT_ARGS="-c support/testing/tests/package/test_xen/arm/genimage.cfg"
  123. BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="support/testing/tests/package/test_xen/arm/linux.config"
  124. BR2_TARGET_UBOOT_BOARD_DEFCONFIG="qemu_arm"
  125. BR2_PACKAGE_HOST_UBOOT_TOOLS=y
  126. BR2_PACKAGE_HOST_UBOOT_TOOLS_BOOT_SCRIPT=y
  127. BR2_PACKAGE_HOST_UBOOT_TOOLS_BOOT_SCRIPT_SOURCE="support/testing/tests/package/test_xen/arm/boot.cmd"
  128. """
  129. def test_run(self):
  130. uboot_bin = os.path.join(self.builddir, "images", "u-boot.bin")
  131. disk_img = os.path.join(self.builddir, "images", "disk.img")
  132. # We need to run Qemu with virtualization to run Xen.
  133. qemu_opts = [
  134. "-bios", uboot_bin,
  135. "-cpu", "cortex-a15",
  136. "-device", "virtio-blk-device,drive=hd0",
  137. "-drive", f"file={disk_img},if=none,format=raw,id=hd0",
  138. "-m", "1G",
  139. "-machine", "virt,virtualization=on,acpi=off",
  140. "-smp", "2"
  141. ]
  142. # Run Xen test.
  143. self.run_xen_test(arch="armv7", options=qemu_opts)