runqemu.py 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. #
  2. # Copyright (c) 2017 Wind River Systems, Inc.
  3. #
  4. import re
  5. import tempfile
  6. import time
  7. import oe.types
  8. from oeqa.selftest.case import OESelftestTestCase
  9. from oeqa.utils.commands import bitbake, runqemu, get_bb_var, runCmd
  10. class RunqemuTests(OESelftestTestCase):
  11. """Runqemu test class"""
  12. image_is_ready = False
  13. deploy_dir_image = ''
  14. def setUpLocal(self):
  15. super(RunqemuTests, self).setUpLocal()
  16. self.recipe = 'core-image-minimal'
  17. self.machine = 'qemux86-64'
  18. self.fstypes = "ext4 iso hddimg wic.vmdk wic.qcow2 wic.vdi"
  19. self.cmd_common = "runqemu nographic"
  20. kvm = oe.types.qemu_use_kvm(get_bb_var('QEMU_USE_KVM'), 'x86_64')
  21. if kvm:
  22. self.cmd_common += " kvm"
  23. self.write_config(
  24. """
  25. MACHINE = "%s"
  26. IMAGE_FSTYPES = "%s"
  27. # 10 means 1 second
  28. SYSLINUX_TIMEOUT = "10"
  29. """
  30. % (self.machine, self.fstypes)
  31. )
  32. if not RunqemuTests.image_is_ready:
  33. RunqemuTests.deploy_dir_image = get_bb_var('DEPLOY_DIR_IMAGE')
  34. bitbake(self.recipe)
  35. RunqemuTests.image_is_ready = True
  36. def test_boot_machine(self):
  37. """Test runqemu machine"""
  38. cmd = "%s %s" % (self.cmd_common, self.machine)
  39. with runqemu(self.recipe, ssh=False, launch_cmd=cmd) as qemu:
  40. with open(qemu.qemurunnerlog) as f:
  41. self.assertTrue(qemu.runner.logged, "Failed: %s, %s" % (cmd, f.read()))
  42. def test_boot_machine_ext4(self):
  43. """Test runqemu machine ext4"""
  44. cmd = "%s %s ext4" % (self.cmd_common, self.machine)
  45. with runqemu(self.recipe, ssh=False, launch_cmd=cmd) as qemu:
  46. with open(qemu.qemurunnerlog) as f:
  47. self.assertIn('rootfs.ext4', f.read(), "Failed: %s" % cmd)
  48. def test_boot_machine_iso(self):
  49. """Test runqemu machine iso"""
  50. cmd = "%s %s iso" % (self.cmd_common, self.machine)
  51. with runqemu(self.recipe, ssh=False, launch_cmd=cmd) as qemu:
  52. with open(qemu.qemurunnerlog) as f:
  53. self.assertIn('media=cdrom', f.read(), "Failed: %s" % cmd)
  54. def test_boot_recipe_image(self):
  55. """Test runqemu recipe-image"""
  56. cmd = "%s %s" % (self.cmd_common, self.recipe)
  57. with runqemu(self.recipe, ssh=False, launch_cmd=cmd) as qemu:
  58. with open(qemu.qemurunnerlog) as f:
  59. self.assertTrue(qemu.runner.logged, "Failed: %s, %s" % (cmd, f.read()))
  60. def test_boot_recipe_image_vmdk(self):
  61. """Test runqemu recipe-image vmdk"""
  62. cmd = "%s %s wic.vmdk" % (self.cmd_common, self.recipe)
  63. with runqemu(self.recipe, ssh=False, launch_cmd=cmd) as qemu:
  64. with open(qemu.qemurunnerlog) as f:
  65. self.assertIn('format=vmdk', f.read(), "Failed: %s" % cmd)
  66. def test_boot_recipe_image_vdi(self):
  67. """Test runqemu recipe-image vdi"""
  68. cmd = "%s %s wic.vdi" % (self.cmd_common, self.recipe)
  69. with runqemu(self.recipe, ssh=False, launch_cmd=cmd) as qemu:
  70. with open(qemu.qemurunnerlog) as f:
  71. self.assertIn('format=vdi', f.read(), "Failed: %s" % cmd)
  72. def test_boot_deploy(self):
  73. """Test runqemu deploy_dir_image"""
  74. cmd = "%s %s" % (self.cmd_common, self.deploy_dir_image)
  75. with runqemu(self.recipe, ssh=False, launch_cmd=cmd) as qemu:
  76. with open(qemu.qemurunnerlog) as f:
  77. self.assertTrue(qemu.runner.logged, "Failed: %s, %s" % (cmd, f.read()))
  78. def test_boot_deploy_hddimg(self):
  79. """Test runqemu deploy_dir_image hddimg"""
  80. cmd = "%s %s hddimg" % (self.cmd_common, self.deploy_dir_image)
  81. with runqemu(self.recipe, ssh=False, launch_cmd=cmd) as qemu:
  82. with open(qemu.qemurunnerlog) as f:
  83. self.assertTrue(re.search('file=.*.hddimg', f.read()), "Failed: %s, %s" % (cmd, f.read()))
  84. def test_boot_machine_slirp(self):
  85. """Test runqemu machine slirp"""
  86. cmd = "%s slirp %s" % (self.cmd_common, self.machine)
  87. with runqemu(self.recipe, ssh=False, launch_cmd=cmd) as qemu:
  88. with open(qemu.qemurunnerlog) as f:
  89. self.assertIn(' -netdev user', f.read(), "Failed: %s" % cmd)
  90. def test_boot_machine_slirp_qcow2(self):
  91. """Test runqemu machine slirp qcow2"""
  92. cmd = "%s slirp wic.qcow2 %s" % (self.cmd_common, self.machine)
  93. with runqemu(self.recipe, ssh=False, launch_cmd=cmd) as qemu:
  94. with open(qemu.qemurunnerlog) as f:
  95. self.assertIn('format=qcow2', f.read(), "Failed: %s" % cmd)
  96. def test_boot_qemu_boot(self):
  97. """Test runqemu /path/to/image.qemuboot.conf"""
  98. qemuboot_conf = "%s-%s.qemuboot.conf" % (self.recipe, self.machine)
  99. qemuboot_conf = os.path.join(self.deploy_dir_image, qemuboot_conf)
  100. if not os.path.exists(qemuboot_conf):
  101. self.skipTest("%s not found" % qemuboot_conf)
  102. cmd = "%s %s" % (self.cmd_common, qemuboot_conf)
  103. with runqemu(self.recipe, ssh=False, launch_cmd=cmd) as qemu:
  104. with open(qemu.qemurunnerlog) as f:
  105. self.assertTrue(qemu.runner.logged, "Failed: %s, %s" % (cmd, f.read()))
  106. def test_boot_rootfs(self):
  107. """Test runqemu /path/to/rootfs.ext4"""
  108. rootfs = "%s-%s.ext4" % (self.recipe, self.machine)
  109. rootfs = os.path.join(self.deploy_dir_image, rootfs)
  110. if not os.path.exists(rootfs):
  111. self.skipTest("%s not found" % rootfs)
  112. cmd = "%s %s" % (self.cmd_common, rootfs)
  113. with runqemu(self.recipe, ssh=False, launch_cmd=cmd) as qemu:
  114. with open(qemu.qemurunnerlog) as f:
  115. self.assertTrue(qemu.runner.logged, "Failed: %s, %s" % (cmd, f.read()))
  116. # This test was designed as a separate class to test that shutdown
  117. # command will shutdown qemu as expected on each qemu architecture
  118. # based on the MACHINE configuration inside the config file
  119. # (eg. local.conf).
  120. #
  121. # This was different compared to RunqemuTests, where RunqemuTests was
  122. # dedicated for MACHINE=qemux86-64 where it test that qemux86-64 will
  123. # bootup various filesystem types, including live image(iso and hddimg)
  124. # where live image was not supported on all qemu architecture.
  125. class QemuTest(OESelftestTestCase):
  126. @classmethod
  127. def setUpClass(cls):
  128. super(QemuTest, cls).setUpClass()
  129. cls.recipe = 'core-image-minimal'
  130. cls.machine = get_bb_var('MACHINE')
  131. cls.deploy_dir_image = get_bb_var('DEPLOY_DIR_IMAGE')
  132. cls.cmd_common = "runqemu nographic"
  133. cls.qemuboot_conf = "%s-%s.qemuboot.conf" % (cls.recipe, cls.machine)
  134. cls.qemuboot_conf = os.path.join(cls.deploy_dir_image, cls.qemuboot_conf)
  135. bitbake(cls.recipe)
  136. def _start_qemu_shutdown_check_if_shutdown_succeeded(self, qemu, timeout):
  137. qemu.run_serial("shutdown -h now")
  138. # Stop thread will stop the LoggingThread instance used for logging
  139. # qemu through serial console, stop thread will prevent this code
  140. # from facing exception (Console connection closed unexpectedly)
  141. # when qemu was shutdown by the above shutdown command
  142. qemu.runner.stop_thread()
  143. time_track = 0
  144. try:
  145. while True:
  146. is_alive = qemu.check()
  147. if not is_alive:
  148. return True
  149. if time_track > timeout:
  150. return False
  151. time.sleep(1)
  152. time_track += 1
  153. except SystemExit:
  154. return True
  155. def test_qemu_can_shutdown(self):
  156. self.assertExists(self.qemuboot_conf)
  157. cmd = "%s %s" % (self.cmd_common, self.qemuboot_conf)
  158. shutdown_timeout = 120
  159. with runqemu(self.recipe, ssh=False, launch_cmd=cmd) as qemu:
  160. qemu_shutdown_succeeded = self._start_qemu_shutdown_check_if_shutdown_succeeded(qemu, shutdown_timeout)
  161. self.assertTrue(qemu_shutdown_succeeded, 'Failed: %s does not shutdown within timeout(%s)' % (self.machine, shutdown_timeout))
  162. # Need to have portmap/rpcbind running to allow this test to work and
  163. # current autobuilder setup does not have this.
  164. def disabled_test_qemu_can_boot_nfs_and_shutdown(self):
  165. self.assertExists(self.qemuboot_conf)
  166. bitbake('meta-ide-support')
  167. rootfs_tar = "%s-%s.tar.bz2" % (self.recipe, self.machine)
  168. rootfs_tar = os.path.join(self.deploy_dir_image, rootfs_tar)
  169. self.assertExists(rootfs_tar)
  170. tmpdir = tempfile.mkdtemp(prefix='qemu_nfs')
  171. tmpdir_nfs = os.path.join(tmpdir, 'nfs')
  172. cmd_extract_nfs = 'runqemu-extract-sdk %s %s' % (rootfs_tar, tmpdir_nfs)
  173. result = runCmd(cmd_extract_nfs)
  174. self.assertEqual(0, result.status, "runqemu-extract-sdk didn't run as expected. %s" % result.output)
  175. cmd = "%s nfs %s %s" % (self.cmd_common, self.qemuboot_conf, tmpdir_nfs)
  176. shutdown_timeout = 120
  177. with runqemu(self.recipe, ssh=False, launch_cmd=cmd) as qemu:
  178. qemu_shutdown_succeeded = self._start_qemu_shutdown_check_if_shutdown_succeeded(qemu, shutdown_timeout)
  179. self.assertTrue(qemu_shutdown_succeeded, 'Failed: %s does not shutdown within timeout(%s)' % (self.machine, shutdown_timeout))
  180. runCmd('rm -rf %s' % tmpdir)