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