| Brad Bishop | d7bf8c1 | 2018-02-25 22:55:05 -0500 | [diff] [blame] | 1 | # | 
|  | 2 | # Copyright (c) 2017 Wind River Systems, Inc. | 
|  | 3 | # | 
|  | 4 |  | 
|  | 5 | import re | 
| Brad Bishop | 316dfdd | 2018-06-25 12:45:53 -0400 | [diff] [blame] | 6 | import tempfile | 
|  | 7 | import time | 
| Brad Bishop | d7bf8c1 | 2018-02-25 22:55:05 -0500 | [diff] [blame] | 8 | from oeqa.selftest.case import OESelftestTestCase | 
| Brad Bishop | 316dfdd | 2018-06-25 12:45:53 -0400 | [diff] [blame] | 9 | from oeqa.utils.commands import bitbake, runqemu, get_bb_var, runCmd | 
| Brad Bishop | d7bf8c1 | 2018-02-25 22:55:05 -0500 | [diff] [blame] | 10 | from oeqa.core.decorator.oeid import OETestID | 
|  | 11 |  | 
|  | 12 | class RunqemuTests(OESelftestTestCase): | 
|  | 13 | """Runqemu test class""" | 
|  | 14 |  | 
|  | 15 | image_is_ready = False | 
|  | 16 | deploy_dir_image = '' | 
|  | 17 | # We only want to print runqemu stdout/stderr if there is a test case failure | 
|  | 18 | buffer = True | 
|  | 19 |  | 
|  | 20 | def setUpLocal(self): | 
|  | 21 | super(RunqemuTests, self).setUpLocal() | 
|  | 22 | self.recipe = 'core-image-minimal' | 
|  | 23 | self.machine =  'qemux86-64' | 
|  | 24 | self.fstypes = "ext4 iso hddimg wic.vmdk wic.qcow2 wic.vdi" | 
|  | 25 | self.cmd_common = "runqemu nographic" | 
|  | 26 |  | 
|  | 27 | self.write_config( | 
|  | 28 | """ | 
|  | 29 | MACHINE = "%s" | 
|  | 30 | IMAGE_FSTYPES = "%s" | 
|  | 31 | # 10 means 1 second | 
|  | 32 | SYSLINUX_TIMEOUT = "10" | 
|  | 33 | """ | 
|  | 34 | % (self.machine, self.fstypes) | 
|  | 35 | ) | 
|  | 36 |  | 
|  | 37 | if not RunqemuTests.image_is_ready: | 
|  | 38 | RunqemuTests.deploy_dir_image = get_bb_var('DEPLOY_DIR_IMAGE') | 
|  | 39 | bitbake(self.recipe) | 
|  | 40 | RunqemuTests.image_is_ready = True | 
|  | 41 |  | 
|  | 42 | @OETestID(2001) | 
|  | 43 | def test_boot_machine(self): | 
|  | 44 | """Test runqemu machine""" | 
|  | 45 | cmd = "%s %s" % (self.cmd_common, self.machine) | 
|  | 46 | with runqemu(self.recipe, ssh=False, launch_cmd=cmd) as qemu: | 
|  | 47 | self.assertTrue(qemu.runner.logged, "Failed: %s" % cmd) | 
|  | 48 |  | 
|  | 49 | @OETestID(2002) | 
|  | 50 | def test_boot_machine_ext4(self): | 
|  | 51 | """Test runqemu machine ext4""" | 
|  | 52 | cmd = "%s %s ext4" % (self.cmd_common, self.machine) | 
|  | 53 | with runqemu(self.recipe, ssh=False, launch_cmd=cmd) as qemu: | 
|  | 54 | with open(qemu.qemurunnerlog) as f: | 
|  | 55 | self.assertTrue('rootfs.ext4' in f.read(), "Failed: %s" % cmd) | 
|  | 56 |  | 
|  | 57 | @OETestID(2003) | 
|  | 58 | def test_boot_machine_iso(self): | 
|  | 59 | """Test runqemu machine iso""" | 
|  | 60 | cmd = "%s %s iso" % (self.cmd_common, self.machine) | 
|  | 61 | with runqemu(self.recipe, ssh=False, launch_cmd=cmd) as qemu: | 
|  | 62 | with open(qemu.qemurunnerlog) as f: | 
|  | 63 | self.assertTrue('media=cdrom' in f.read(), "Failed: %s" % cmd) | 
|  | 64 |  | 
|  | 65 | @OETestID(2004) | 
|  | 66 | def test_boot_recipe_image(self): | 
|  | 67 | """Test runqemu recipe-image""" | 
|  | 68 | cmd = "%s %s" % (self.cmd_common, self.recipe) | 
|  | 69 | with runqemu(self.recipe, ssh=False, launch_cmd=cmd) as qemu: | 
|  | 70 | self.assertTrue(qemu.runner.logged, "Failed: %s" % cmd) | 
|  | 71 |  | 
|  | 72 | @OETestID(2005) | 
|  | 73 | def test_boot_recipe_image_vmdk(self): | 
|  | 74 | """Test runqemu recipe-image vmdk""" | 
|  | 75 | cmd = "%s %s wic.vmdk" % (self.cmd_common, self.recipe) | 
|  | 76 | with runqemu(self.recipe, ssh=False, launch_cmd=cmd) as qemu: | 
|  | 77 | with open(qemu.qemurunnerlog) as f: | 
|  | 78 | self.assertTrue('format=vmdk' in f.read(), "Failed: %s" % cmd) | 
|  | 79 |  | 
|  | 80 | @OETestID(2006) | 
|  | 81 | def test_boot_recipe_image_vdi(self): | 
|  | 82 | """Test runqemu recipe-image vdi""" | 
|  | 83 | cmd = "%s %s wic.vdi" % (self.cmd_common, self.recipe) | 
|  | 84 | with runqemu(self.recipe, ssh=False, launch_cmd=cmd) as qemu: | 
|  | 85 | with open(qemu.qemurunnerlog) as f: | 
|  | 86 | self.assertTrue('format=vdi' in f.read(), "Failed: %s" % cmd) | 
|  | 87 |  | 
|  | 88 | @OETestID(2007) | 
|  | 89 | def test_boot_deploy(self): | 
|  | 90 | """Test runqemu deploy_dir_image""" | 
|  | 91 | cmd = "%s %s" % (self.cmd_common, self.deploy_dir_image) | 
|  | 92 | with runqemu(self.recipe, ssh=False, launch_cmd=cmd) as qemu: | 
|  | 93 | self.assertTrue(qemu.runner.logged, "Failed: %s" % cmd) | 
|  | 94 |  | 
|  | 95 | @OETestID(2008) | 
|  | 96 | def test_boot_deploy_hddimg(self): | 
|  | 97 | """Test runqemu deploy_dir_image hddimg""" | 
|  | 98 | cmd = "%s %s hddimg" % (self.cmd_common, self.deploy_dir_image) | 
|  | 99 | with runqemu(self.recipe, ssh=False, launch_cmd=cmd) as qemu: | 
|  | 100 | with open(qemu.qemurunnerlog) as f: | 
|  | 101 | self.assertTrue(re.search('file=.*.hddimg', f.read()), "Failed: %s" % cmd) | 
|  | 102 |  | 
|  | 103 | @OETestID(2009) | 
|  | 104 | def test_boot_machine_slirp(self): | 
|  | 105 | """Test runqemu machine slirp""" | 
|  | 106 | cmd = "%s slirp %s" % (self.cmd_common, self.machine) | 
|  | 107 | with runqemu(self.recipe, ssh=False, launch_cmd=cmd) as qemu: | 
|  | 108 | with open(qemu.qemurunnerlog) as f: | 
|  | 109 | self.assertTrue(' -netdev user' in f.read(), "Failed: %s" % cmd) | 
|  | 110 |  | 
|  | 111 | @OETestID(2009) | 
|  | 112 | def test_boot_machine_slirp_qcow2(self): | 
|  | 113 | """Test runqemu machine slirp qcow2""" | 
|  | 114 | cmd = "%s slirp wic.qcow2 %s" % (self.cmd_common, self.machine) | 
|  | 115 | with runqemu(self.recipe, ssh=False, launch_cmd=cmd) as qemu: | 
|  | 116 | with open(qemu.qemurunnerlog) as f: | 
|  | 117 | self.assertTrue('format=qcow2' in f.read(), "Failed: %s" % cmd) | 
|  | 118 |  | 
|  | 119 | @OETestID(2010) | 
|  | 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 | self.assertTrue(qemu.runner.logged, "Failed: %s" % cmd) | 
|  | 129 |  | 
|  | 130 | @OETestID(2011) | 
|  | 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 | self.assertTrue(qemu.runner.logged, "Failed: %s" % cmd) | 
| Brad Bishop | 316dfdd | 2018-06-25 12:45:53 -0400 | [diff] [blame] | 140 |  | 
|  | 141 | # This test was designed as a separate class to test that shutdown | 
|  | 142 | # command will shutdown qemu as expected on each qemu architecture | 
|  | 143 | # based on the MACHINE configuration inside the config file | 
|  | 144 | # (eg. local.conf). | 
|  | 145 | # | 
|  | 146 | # This was different compared to RunqemuTests, where RunqemuTests was | 
|  | 147 | # dedicated for MACHINE=qemux86-64 where it test that qemux86-64 will | 
|  | 148 | # bootup various filesystem types, including live image(iso and hddimg) | 
|  | 149 | # where live image was not supported on all qemu architecture. | 
|  | 150 | class QemuTest(OESelftestTestCase): | 
|  | 151 |  | 
|  | 152 | @classmethod | 
|  | 153 | def setUpClass(cls): | 
|  | 154 | super(QemuTest, cls).setUpClass() | 
|  | 155 | cls.recipe = 'core-image-minimal' | 
|  | 156 | cls.machine =  get_bb_var('MACHINE') | 
|  | 157 | cls.deploy_dir_image =  get_bb_var('DEPLOY_DIR_IMAGE') | 
|  | 158 | cls.cmd_common = "runqemu nographic" | 
|  | 159 | cls.qemuboot_conf = "%s-%s.qemuboot.conf" % (cls.recipe, cls.machine) | 
|  | 160 | cls.qemuboot_conf = os.path.join(cls.deploy_dir_image, cls.qemuboot_conf) | 
|  | 161 | bitbake(cls.recipe) | 
|  | 162 |  | 
|  | 163 | def _start_qemu_shutdown_check_if_shutdown_succeeded(self, qemu, timeout): | 
|  | 164 | qemu.run_serial("shutdown -h now") | 
|  | 165 | # Stop thread will stop the LoggingThread instance used for logging | 
|  | 166 | # qemu through serial console, stop thread will prevent this code | 
|  | 167 | # from facing exception (Console connection closed unexpectedly) | 
|  | 168 | # when qemu was shutdown by the above shutdown command | 
|  | 169 | qemu.runner.stop_thread() | 
|  | 170 | time_track = 0 | 
|  | 171 | while True: | 
|  | 172 | is_alive = qemu.check() | 
|  | 173 | if not is_alive: | 
|  | 174 | return True | 
|  | 175 | if time_track > timeout: | 
|  | 176 | return False | 
|  | 177 | time.sleep(1) | 
|  | 178 | time_track += 1 | 
|  | 179 |  | 
|  | 180 | def test_qemu_can_shutdown(self): | 
|  | 181 | self.assertExists(self.qemuboot_conf) | 
|  | 182 | cmd = "%s %s" % (self.cmd_common, self.qemuboot_conf) | 
|  | 183 | shutdown_timeout = 120 | 
|  | 184 | with runqemu(self.recipe, ssh=False, launch_cmd=cmd) as qemu: | 
|  | 185 | qemu_shutdown_succeeded = self._start_qemu_shutdown_check_if_shutdown_succeeded(qemu, shutdown_timeout) | 
|  | 186 | self.assertTrue(qemu_shutdown_succeeded, 'Failed: %s does not shutdown within timeout(%s)' % (self.machine, shutdown_timeout)) | 
|  | 187 |  | 
|  | 188 | # Need to have portmap/rpcbind running to allow this test to work and | 
|  | 189 | # current autobuilder setup does not have this. | 
|  | 190 | def disabled_test_qemu_can_boot_nfs_and_shutdown(self): | 
|  | 191 | self.assertExists(self.qemuboot_conf) | 
|  | 192 | bitbake('meta-ide-support') | 
|  | 193 | rootfs_tar = "%s-%s.tar.bz2" % (self.recipe, self.machine) | 
|  | 194 | rootfs_tar = os.path.join(self.deploy_dir_image, rootfs_tar) | 
|  | 195 | self.assertExists(rootfs_tar) | 
|  | 196 | tmpdir = tempfile.mkdtemp(prefix='qemu_nfs') | 
|  | 197 | tmpdir_nfs = os.path.join(tmpdir, 'nfs') | 
|  | 198 | cmd_extract_nfs = 'runqemu-extract-sdk %s %s' % (rootfs_tar, tmpdir_nfs) | 
|  | 199 | result = runCmd(cmd_extract_nfs) | 
|  | 200 | self.assertEqual(0, result.status, "runqemu-extract-sdk didn't run as expected. %s" % result.output) | 
|  | 201 | cmd = "%s nfs %s %s" % (self.cmd_common, self.qemuboot_conf, tmpdir_nfs) | 
|  | 202 | shutdown_timeout = 120 | 
|  | 203 | with runqemu(self.recipe, ssh=False, launch_cmd=cmd) as qemu: | 
|  | 204 | qemu_shutdown_succeeded = self._start_qemu_shutdown_check_if_shutdown_succeeded(qemu, shutdown_timeout) | 
|  | 205 | self.assertTrue(qemu_shutdown_succeeded, 'Failed: %s does not shutdown within timeout(%s)' % (self.machine, shutdown_timeout)) | 
|  | 206 | runCmd('rm -rf %s' % tmpdir) |