| # |
| # Copyright (c) 2017 Wind River Systems, Inc. |
| # |
| # SPDX-License-Identifier: MIT |
| # |
| |
| import os |
| import re |
| import time |
| import oe.types |
| from oeqa.core.decorator import OETestTag |
| from oeqa.core.decorator.data import skipIfNotArch, skipIfNotMachine |
| from oeqa.selftest.case import OESelftestTestCase |
| from oeqa.utils.commands import bitbake, runqemu, get_bb_var |
| |
| |
| @OETestTag("runqemu") |
| class RunqemuTests(OESelftestTestCase): |
| """Runqemu test class""" |
| |
| image_is_ready = False |
| deploy_dir_image = '' |
| |
| def setUpLocal(self): |
| super(RunqemuTests, self).setUpLocal() |
| self.recipe = 'core-image-minimal' |
| self.machine = self.td['MACHINE'] |
| self.image_link_name = get_bb_var('IMAGE_LINK_NAME', self.recipe) |
| |
| self.fstypes = "ext4" |
| if self.td["HOST_ARCH"] in ('i586', 'i686', 'x86_64'): |
| self.fstypes += " iso hddimg" |
| if self.machine == "qemux86-64": |
| self.fstypes += " wic.vmdk wic.qcow2 wic.vdi" |
| |
| self.cmd_common = "runqemu nographic" |
| kvm = oe.types.qemu_use_kvm(get_bb_var('QEMU_USE_KVM'), self.td["TARGET_ARCH"]) |
| if kvm: |
| self.cmd_common += " kvm" |
| |
| self.write_config( |
| """ |
| IMAGE_FSTYPES = "%s" |
| # 10 means 1 second |
| SYSLINUX_TIMEOUT = "10" |
| """ % self.fstypes) |
| |
| if not RunqemuTests.image_is_ready: |
| RunqemuTests.deploy_dir_image = get_bb_var('DEPLOY_DIR_IMAGE') |
| bitbake(self.recipe) |
| RunqemuTests.image_is_ready = True |
| |
| def test_boot_machine(self): |
| """Test runqemu machine""" |
| cmd = "%s %s" % (self.cmd_common, self.machine) |
| with runqemu(self.recipe, ssh=False, launch_cmd=cmd) as qemu: |
| with open(qemu.qemurunnerlog) as f: |
| self.assertTrue(qemu.runner.logged, "Failed: %s, %s" % (cmd, f.read())) |
| |
| def test_boot_machine_ext4(self): |
| """Test runqemu machine ext4""" |
| cmd = "%s %s ext4" % (self.cmd_common, self.machine) |
| with runqemu(self.recipe, ssh=False, launch_cmd=cmd) as qemu: |
| with open(qemu.qemurunnerlog) as f: |
| regexp = r'\nROOTFS: .*\.ext4]\n' |
| self.assertRegex(f.read(), regexp, "Failed to find '%s' in '%s' after running '%s'" % (regexp, qemu.qemurunnerlog, cmd)) |
| |
| @skipIfNotArch(['i586', 'i686', 'x86_64']) |
| def test_boot_machine_iso(self): |
| """Test runqemu machine iso""" |
| cmd = "%s %s iso" % (self.cmd_common, self.machine) |
| with runqemu(self.recipe, ssh=False, launch_cmd=cmd) as qemu: |
| with open(qemu.qemurunnerlog) as f: |
| text_in = 'media=cdrom' |
| self.assertIn(text_in, f.read(), "Failed to find '%s' in '%s' after running '%s'" % (text_in, qemu.qemurunnerlog, cmd)) |
| |
| def test_boot_recipe_image(self): |
| """Test runqemu recipe-image""" |
| cmd = "%s %s" % (self.cmd_common, self.recipe) |
| with runqemu(self.recipe, ssh=False, launch_cmd=cmd) as qemu: |
| with open(qemu.qemurunnerlog) as f: |
| self.assertTrue(qemu.runner.logged, "Failed: %s, %s" % (cmd, f.read())) |
| |
| # https://bugzilla.yoctoproject.org/show_bug.cgi?id=14963 |
| @skipIfNotMachine("qemux86-64", "tests are qemux86-64 specific currently") |
| def test_boot_recipe_image_vmdk(self): |
| """Test runqemu recipe-image vmdk""" |
| cmd = "%s %s wic.vmdk" % (self.cmd_common, self.recipe) |
| with runqemu(self.recipe, ssh=False, launch_cmd=cmd) as qemu: |
| with open(qemu.qemurunnerlog) as f: |
| text_in = 'format=vmdk' |
| self.assertIn(text_in, f.read(), "Failed to find '%s' in '%s' after running '%s'" % (text_in, qemu.qemurunnerlog, cmd)) |
| |
| @skipIfNotMachine("qemux86-64", "tests are qemux86-64 specific currently") |
| def test_boot_recipe_image_vdi(self): |
| """Test runqemu recipe-image vdi""" |
| cmd = "%s %s wic.vdi" % (self.cmd_common, self.recipe) |
| with runqemu(self.recipe, ssh=False, launch_cmd=cmd) as qemu: |
| with open(qemu.qemurunnerlog) as f: |
| text_in = 'format=vdi' |
| self.assertIn(text_in, f.read(), "Failed to find '%s' in '%s' after running '%s'" % (text_in, qemu.qemurunnerlog, cmd)) |
| |
| def test_boot_deploy(self): |
| """Test runqemu deploy_dir_image""" |
| cmd = "%s %s" % (self.cmd_common, self.deploy_dir_image) |
| with runqemu(self.recipe, ssh=False, launch_cmd=cmd) as qemu: |
| with open(qemu.qemurunnerlog) as f: |
| self.assertTrue(qemu.runner.logged, "Failed: %s, %s" % (cmd, f.read())) |
| |
| @skipIfNotArch(['i586', 'i686', 'x86_64']) |
| def test_boot_deploy_hddimg(self): |
| """Test runqemu deploy_dir_image hddimg""" |
| cmd = "%s %s hddimg" % (self.cmd_common, self.deploy_dir_image) |
| with runqemu(self.recipe, ssh=False, launch_cmd=cmd) as qemu: |
| with open(qemu.qemurunnerlog) as f: |
| self.assertTrue(re.search('file=.*.hddimg', f.read()), "Failed: %s, %s" % (cmd, f.read())) |
| |
| def test_boot_machine_slirp(self): |
| """Test runqemu machine slirp""" |
| cmd = "%s slirp %s" % (self.cmd_common, self.machine) |
| with runqemu(self.recipe, ssh=False, launch_cmd=cmd) as qemu: |
| with open(qemu.qemurunnerlog) as f: |
| self.assertIn(' -netdev user', f.read(), "Failed: %s" % cmd) |
| |
| @skipIfNotMachine("qemux86-64", "tests are qemux86-64 specific currently") |
| def test_boot_machine_slirp_qcow2(self): |
| """Test runqemu machine slirp qcow2""" |
| cmd = "%s slirp wic.qcow2 %s" % (self.cmd_common, self.machine) |
| with runqemu(self.recipe, ssh=False, launch_cmd=cmd) as qemu: |
| with open(qemu.qemurunnerlog) as f: |
| self.assertIn('format=qcow2', f.read(), "Failed: %s" % cmd) |
| |
| def test_boot_qemu_boot(self): |
| """Test runqemu /path/to/image.qemuboot.conf""" |
| qemuboot_conf = "%s.qemuboot.conf" % (self.image_link_name) |
| qemuboot_conf = os.path.join(self.deploy_dir_image, qemuboot_conf) |
| if not os.path.exists(qemuboot_conf): |
| self.skipTest("%s not found" % qemuboot_conf) |
| cmd = "%s %s" % (self.cmd_common, qemuboot_conf) |
| with runqemu(self.recipe, ssh=False, launch_cmd=cmd) as qemu: |
| with open(qemu.qemurunnerlog) as f: |
| self.assertTrue(qemu.runner.logged, "Failed: %s, %s" % (cmd, f.read())) |
| |
| def test_boot_rootfs(self): |
| """Test runqemu /path/to/rootfs.ext4""" |
| rootfs = "%s.ext4" % (self.image_link_name) |
| rootfs = os.path.join(self.deploy_dir_image, rootfs) |
| if not os.path.exists(rootfs): |
| self.skipTest("%s not found" % rootfs) |
| cmd = "%s %s" % (self.cmd_common, rootfs) |
| with runqemu(self.recipe, ssh=False, launch_cmd=cmd) as qemu: |
| with open(qemu.qemurunnerlog) as f: |
| self.assertTrue(qemu.runner.logged, "Failed: %s, %s" % (cmd, f.read())) |
| |
| |
| # This test was designed as a separate class to test that shutdown |
| # command will shutdown qemu as expected on each qemu architecture |
| # based on the MACHINE configuration inside the config file |
| # (eg. local.conf). |
| # |
| # This was different compared to RunqemuTests, where RunqemuTests was |
| # dedicated for MACHINE=qemux86-64 where it test that qemux86-64 will |
| # bootup various filesystem types, including live image(iso and hddimg) |
| # where live image was not supported on all qemu architecture. |
| @OETestTag("machine") |
| @OETestTag("runqemu") |
| class QemuTest(OESelftestTestCase): |
| |
| @classmethod |
| def setUpClass(cls): |
| super(QemuTest, cls).setUpClass() |
| cls.recipe = 'core-image-minimal' |
| cls.machine = get_bb_var('MACHINE') |
| cls.deploy_dir_image = get_bb_var('DEPLOY_DIR_IMAGE') |
| cls.image_link_name = get_bb_var('IMAGE_LINK_NAME', cls.recipe) |
| cls.cmd_common = "runqemu nographic" |
| cls.qemuboot_conf = "%s.qemuboot.conf" % (cls.image_link_name) |
| cls.qemuboot_conf = os.path.join(cls.deploy_dir_image, cls.qemuboot_conf) |
| bitbake(cls.recipe) |
| |
| def _start_qemu_shutdown_check_if_shutdown_succeeded(self, qemu, timeout): |
| # Allow the runner's LoggingThread instance to exit without errors |
| # (such as the exception "Console connection closed unexpectedly") |
| # as qemu will disappear when we shut it down |
| qemu.runner.allowexit() |
| qemu.run_serial("shutdown -h now") |
| time_track = 0 |
| try: |
| while True: |
| is_alive = qemu.check() |
| if not is_alive: |
| return True |
| if time_track > timeout: |
| return False |
| time.sleep(1) |
| time_track += 1 |
| except SystemExit: |
| return True |
| |
| def test_qemu_can_shutdown(self): |
| self.assertExists(self.qemuboot_conf) |
| cmd = "%s %s" % (self.cmd_common, self.qemuboot_conf) |
| shutdown_timeout = 120 |
| with runqemu(self.recipe, ssh=False, launch_cmd=cmd) as qemu: |
| qemu_shutdown_succeeded = self._start_qemu_shutdown_check_if_shutdown_succeeded(qemu, shutdown_timeout) |
| self.assertTrue(qemu_shutdown_succeeded, 'Failed: %s does not shutdown within timeout(%s)' % (self.machine, shutdown_timeout)) |
| |
| def test_qemu_can_boot_nfs_and_shutdown(self): |
| rootfs_tar = "%s.tar.bz2" % (self.image_link_name) |
| rootfs_tar = os.path.join(self.deploy_dir_image, rootfs_tar) |
| self.assertExists(rootfs_tar) |
| cmd = "%s %s" % (self.cmd_common, rootfs_tar) |
| shutdown_timeout = 120 |
| with runqemu(self.recipe, ssh=False, launch_cmd=cmd) as qemu: |
| qemu_shutdown_succeeded = self._start_qemu_shutdown_check_if_shutdown_succeeded(qemu, shutdown_timeout) |
| self.assertTrue(qemu_shutdown_succeeded, 'Failed: %s does not shutdown within timeout(%s)' % (self.machine, shutdown_timeout)) |