def run_sbin_init(self, origInit): """ Summary: Confirm we can replace original init and mount overlay on top of /etc Expected: Image is created successfully and /etc is mounted as an overlay Author: Vyacheslav Yurkov <*****@*****.**> """ config = """ DISTRO_FEATURES += "systemd" # Use systemd as init manager VIRTUAL-RUNTIME_init_manager = "systemd" # enable overlayfs in the kernel KERNEL_EXTRA_FEATURES:append = " features/overlayfs/overlayfs.scc" IMAGE_FSTYPES += "wic" OVERLAYFS_INIT_OPTION = "{OVERLAYFS_INIT_OPTION}" WKS_FILE = "overlayfs_etc.wks.in" EXTRA_IMAGE_FEATURES += "read-only-rootfs" # Image configuration for overlayfs-etc EXTRA_IMAGE_FEATURES += "overlayfs-etc" IMAGE_FEATURES:remove = "package-management" OVERLAYFS_ETC_MOUNT_POINT = "/data" OVERLAYFS_ETC_FSTYPE = "ext4" OVERLAYFS_ETC_DEVICE = "/dev/sda3" OVERLAYFS_ETC_USE_ORIG_INIT_NAME = "{OVERLAYFS_ETC_USE_ORIG_INIT_NAME}" """ args = { 'OVERLAYFS_INIT_OPTION': "" if origInit else "init=/sbin/preinit", 'OVERLAYFS_ETC_USE_ORIG_INIT_NAME': int(origInit == True) } self.write_config(config.format(**args)) bitbake('core-image-minimal') testFile = "/etc/my-test-data" with runqemu('core-image-minimal', image_fstype='wic', discard_writes=False) as qemu: status, output = qemu.run_serial("/bin/mount") line = getline_qemu(output, "/dev/sda3") self.assertTrue("/data" in output, msg=output) line = getline_qemu(output, "upperdir=/data/overlay-etc/upper") self.assertTrue(line and line.startswith("/data/overlay-etc/upper on /etc type overlay"), msg=output) status, output = qemu.run_serial("touch " + testFile) status, output = qemu.run_serial("sync") status, output = qemu.run_serial("ls -1 " + testFile) line = getline_qemu(output, testFile) self.assertTrue(line and line.startswith(testFile), msg=output) # Check that file exists in /etc after reboot with runqemu('core-image-minimal', image_fstype='wic') as qemu: status, output = qemu.run_serial("ls -1 " + testFile) line = getline_qemu(output, testFile) self.assertTrue(line and line.startswith(testFile), msg=output)
def test_postinst_rootfs_and_boot(self): """ Summary: The purpose of this test case is to verify Post-installation scripts are called when rootfs is created and also test that script can be delayed to run at first boot. Dependencies: NA Steps: 1. Add proper configuration to local.conf file 2. Build a "core-image-minimal" image 3. Verify that file created by postinst_rootfs recipe is present on rootfs dir. 4. Boot the image created on qemu and verify that the file created by postinst_boot recipe is present on image. Expected: The files are successfully created during rootfs and boot time for 3 different package managers: rpm,ipk,deb and for initialization managers: sysvinit and systemd. """ import oe.path vars = get_bb_vars(("IMAGE_ROOTFS", "sysconfdir"), "core-image-minimal") rootfs = vars["IMAGE_ROOTFS"] self.assertIsNotNone(rootfs) sysconfdir = vars["sysconfdir"] self.assertIsNotNone(sysconfdir) # Need to use oe.path here as sysconfdir starts with / hosttestdir = oe.path.join(rootfs, sysconfdir, "postinst-test") targettestdir = os.path.join(sysconfdir, "postinst-test") for init_manager in ("sysvinit", "systemd"): for classes in ("package_rpm", "package_deb", "package_ipk"): with self.subTest(init_manager=init_manager, package_class=classes): features = 'CORE_IMAGE_EXTRA_INSTALL = "postinst-delayed-b"\n' features += 'IMAGE_FEATURES += "package-management empty-root-password"\n' features += 'PACKAGE_CLASSES = "%s"\n' % classes if init_manager == "systemd": features += 'DISTRO_FEATURES_append = " systemd"\n' features += 'VIRTUAL-RUNTIME_init_manager = "systemd"\n' features += 'DISTRO_FEATURES_BACKFILL_CONSIDERED = "sysvinit"\n' features += 'VIRTUAL-RUNTIME_initscripts = ""\n' self.write_config(features) bitbake('core-image-minimal') self.assertTrue( os.path.isfile(os.path.join(hosttestdir, "rootfs")), "rootfs state file was not created") with runqemu('core-image-minimal') as qemu: # Make the test echo a string and search for that as # run_serial()'s status code is useless.' for filename in ("rootfs", "delayed-a", "delayed-b"): status, output = qemu.run_serial( "test -f %s && echo found" % os.path.join(targettestdir, filename)) self.assertEqual( output, "found", "%s was not present on boot" % filename)
def test_non_root_user_can_connect_via_ssh_without_password(self): """ Summary: Check if non root user can connect via ssh without password Expected: 1. Connection to the image via ssh using root user without providing a password should be allowed. 2. Connection to the image via ssh using tester user without providing a password should be allowed. Product: oe-core Author: Ionut Chisanovici <*****@*****.**> AutomatedBy: Daniel Istrate <*****@*****.**> """ features = 'EXTRA_IMAGE_FEATURES = "ssh-server-openssh empty-root-password allow-empty-password"\n' features += 'INHERIT += "extrausers"\n' features += "EXTRA_USERS_PARAMS = \"useradd -p '' {}; usermod -s /bin/sh {};\"".format( self.test_user, self.test_user ) # Append 'features' to local.conf self.append_config(features) # Build a core-image-minimal bitbake("core-image-minimal") with runqemu("core-image-minimal", self) as qemu: # Attempt to ssh with each user into qemu with empty password for user in [self.root_user, self.test_user]: ssh = SSHControl(ip=qemu.ip, logfile=qemu.sshlog, user=user) status, output = ssh.run("true") self.assertEqual(status, 0, "ssh to user %s failed with %s" % (user, output))
def test_biosplusefi_plugin_qemu(self): """Test biosplusefi plugin in qemu""" config = 'IMAGE_FSTYPES = "wic"\nWKS_FILE = "test_biosplusefi_plugin.wks"\nMACHINE_FEATURES_append = " efi"\n' self.append_config(config) self.assertEqual(0, bitbake('core-image-minimal').status) self.remove_config(config) with runqemu('core-image-minimal', ssh=False, image_fstype='wic') as qemu: # Check that we have ONLY two /dev/sda* partitions (/boot and /) cmd = "grep sda. /proc/partitions | wc -l" status, output = qemu.run_serial(cmd) self.assertEqual(1, status, 'Failed to run command "%s": %s' % (cmd, output)) self.assertEqual(output, '2') # Check that /dev/sda1 is /boot and that either /dev/root OR /dev/sda2 is / cmd = "mount | grep '^/dev/' | cut -f1,3 -d ' ' | egrep -c -e '/dev/sda1 /boot' -e '/dev/root /|/dev/sda2 /'" status, output = qemu.run_serial(cmd) self.assertEqual(1, status, 'Failed to run command "%s": %s' % (cmd, output)) self.assertEqual(output, '2') # Check that /boot has EFI bootx64.efi (required for EFI) cmd = "ls /boot/EFI/BOOT/bootx64.efi | wc -l" status, output = qemu.run_serial(cmd) self.assertEqual(1, status, 'Failed to run command "%s": %s' % (cmd, output)) self.assertEqual(output, '1') # Check that "BOOTABLE" flag is set on boot partition (required for PC-Bios) # Trailing "cat" seems to be required; otherwise run_serial() sends back echo of the input command cmd = "fdisk -l /dev/sda | grep /dev/sda1 | awk {print'$2'} | cat" status, output = qemu.run_serial(cmd) self.assertEqual(1, status, 'Failed to run command "%s": %s' % (cmd, output)) self.assertEqual(output, '*')
def test_postinst_roofs_and_boot(self): """ Summary: The purpose of this test case is to verify Post-installation scripts are called when roofs is created and also test that script can be delayed to run at first boot. Dependencies: NA Steps: 1. Add proper configuration to local.conf file 2. Build a "core-image-minimal" image 3. Verify that file created by postinst_rootfs recipe is present on rootfs dir. 4. Boot the image created on qemu and verify that the file created by postinst_boot recipe is present on image. 5. Clean the packages and image created to test with different package managers Expected: The files are successfully created during rootfs and boot time for 3 different package managers: rpm,ipk,deb and for initialization managers: sysvinit and systemd. """ file_rootfs_name = "this-was-created-at-rootfstime" fileboot_name = "this-was-created-at-first-boot" rootfs_pkg = 'postinst-at-rootfs' boot_pkg = 'postinst-delayed-a' #Step 1 features = 'MACHINE = "qemux86"\n' features += 'CORE_IMAGE_EXTRA_INSTALL += "%s %s "\n'% (rootfs_pkg, boot_pkg) features += 'IMAGE_FEATURES += "ssh-server-openssh"\n' for init_manager in ("sysvinit", "systemd"): #for sysvinit no extra configuration is needed, if (init_manager is "systemd"): features += 'DISTRO_FEATURES_append = " systemd"\n' features += 'VIRTUAL-RUNTIME_init_manager = "systemd"\n' features += 'DISTRO_FEATURES_BACKFILL_CONSIDERED = "sysvinit"\n' features += 'VIRTUAL-RUNTIME_initscripts = ""\n' for classes in ("package_rpm package_deb package_ipk", "package_deb package_rpm package_ipk", "package_ipk package_deb package_rpm"): features += 'PACKAGE_CLASSES = "%s"\n' % classes self.write_config(features) #Step 2 bitbake('core-image-minimal') #Step 3 file_rootfs_created = os.path.join(get_bb_var('IMAGE_ROOTFS',"core-image-minimal"), file_rootfs_name) found = os.path.isfile(file_rootfs_created) self.assertTrue(found, "File %s was not created at rootfs time by %s" % \ (file_rootfs_name, rootfs_pkg)) #Step 4 testcommand = 'ls /etc/'+fileboot_name with runqemu('core-image-minimal') as qemu: sshargs = '-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no' result = runCmd('ssh %s root@%s %s' % (sshargs, qemu.ip, testcommand)) self.assertEqual(result.status, 0, 'File %s was not created at firts boot'% fileboot_name) #Step 5 bitbake(' %s %s -c cleanall' % (rootfs_pkg, boot_pkg)) bitbake('core-image-minimal -c cleanall')
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.assertTrue(' -netdev user' in f.read(), "Failed: %s" % cmd)
def boot_image(self, overrides): # We don't know the final port yet, so instead we create a placeholder script # for qemu to use and rewrite that script once we are ready. The kernel refuses # to execute a shell script while we have it open, so here we close it # and clean up ourselves. # # The helper script also keeps command line handling a bit simpler (no whitespace # in -netdev parameter), which may or may not be relevant. self.ostree_netcat = tempfile.NamedTemporaryFile( mode='w', prefix='ostree-netcat-', dir=os.getcwd(), delete=False) self.ostree_netcat.close() os.chmod(self.ostree_netcat.name, stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR) self.track_for_cleanup(self.ostree_netcat.name) qemuboot_conf = os.path.join( self.image_dir_test, '%s-%s.qemuboot.conf' % (self.IMAGE_PN, get_bb_var('MACHINE'))) with open(qemuboot_conf) as f: conf = f.read() with open(qemuboot_conf, 'w') as f: f.write('\n'.join([ x for x in conf.splitlines() if not x.startswith('qb_slirp_opt') ])) f.write('\nqb_slirp_opt = -netdev user,id=net0,guestfwd=tcp:%s-cmd:%s\n' % \ (self.OSTREE_SERVER, self.ostree_netcat.name)) return runqemu(self.IMAGE_PN, discard_writes=False, ssh=False, overrides=overrides, runqemuparams='ovmf slirp nographic', image_fstype='wic')
def test_gdb_hardlink_debug(self): features = 'IMAGE_INSTALL_append = " selftest-hardlink"\n' features += 'IMAGE_INSTALL_append = " selftest-hardlink-dbg"\n' features += 'IMAGE_INSTALL_append = " selftest-hardlink-gdb"\n' self.write_config(features) bitbake("core-image-minimal") def gdbtest(qemu, binary): """ Check that gdb ``binary`` to read symbols from separated debug file """ self.logger.info("gdbtest %s" % binary) status, output = qemu.run_serial('/usr/bin/gdb.sh %s' % binary, timeout=60) for l in output.split('\n'): # Check debugging symbols exists if '(no debugging symbols found)' in l: self.logger.error("No debugging symbols found. GDB result:\n%s" % output) return False # Check debugging symbols works correctly elif "Breakpoint 1, main () at hello.c:4" in l: return True self.logger.error("GDB result:\n%d: %s", status, output) return False with runqemu('core-image-minimal') as qemu: for binary in ['/usr/bin/hello1', '/usr/bin/hello2', '/usr/libexec/hello3', '/usr/libexec/hello4']: if not gdbtest(qemu, binary): self.fail('GDB %s failed' % binary)
def test_gdb_hardlink_debug(self): features = 'IMAGE_INSTALL_append = " selftest-hardlink"\n' features += 'IMAGE_INSTALL_append = " selftest-hardlink-dbg"\n' features += 'IMAGE_INSTALL_append = " selftest-hardlink-gdb"\n' self.write_config(features) bitbake("core-image-minimal") def gdbtest(qemu, binary): """ Check that gdb ``binary`` to read symbols from separated debug file """ self.logger.info("gdbtest %s" % binary) status, output = qemu.run_serial('/usr/bin/gdb.sh %s' % binary, timeout=60) for l in output.split('\n'): # Check debugging symbols exists if '(no debugging symbols found)' in l: self.logger.error( "No debugging symbols found. GDB result:\n%s" % output) return False # Check debugging symbols works correctly elif re.match(r"Breakpoint 1.*hello\.c.*4", l): return True self.logger.error("GDB result:\n%d: %s", status, output) return False with runqemu('core-image-minimal') as qemu: for binary in [ '/usr/bin/hello1', '/usr/bin/hello2', '/usr/libexec/hello3', '/usr/libexec/hello4' ]: if not gdbtest(qemu, binary): self.fail('GDB %s failed' % binary)
def test_all_users_can_connect_via_ssh_without_password(self): """ Summary: Check if all users can connect via ssh without password Expected: 1. Connection to the image via ssh using root user without providing a password should NOT be allowed. 2. Connection to the image via ssh using tester user without providing a password should be allowed. Product: oe-core Author: Ionut Chisanovici <*****@*****.**> AutomatedBy: Daniel Istrate <*****@*****.**> """ features = 'EXTRA_IMAGE_FEATURES = "ssh-server-openssh allow-empty-password allow-root-login"\n' features += 'INHERIT += "extrausers"\n' features += 'EXTRA_USERS_PARAMS = "useradd -p \'\' {}; usermod -s /bin/sh {};"'.format(self.test_user, self.test_user) self.write_config(features) # Build a core-image-minimal bitbake('core-image-minimal') with runqemu("core-image-minimal") as qemu: # Attempt to ssh with each user into qemu with empty password for user in [self.root_user, self.test_user]: ssh = SSHControl(ip=qemu.ip, logfile=qemu.sshlog, user=user) status, output = ssh.run("true") if user == 'root': self.assertNotEqual(status, 0, 'ssh to user root was allowed when it should not have been') else: self.assertEqual(status, 0, 'ssh to user tester failed with %s' % output)
def test_all_users_can_connect_via_ssh_without_password(self): """ Summary: Check if all users can connect via ssh without password Expected: 1. Connection to the image via ssh using root user without providing a password should NOT be allowed. 2. Connection to the image via ssh using tester user without providing a password should be allowed. Product: oe-core Author: Ionut Chisanovici <*****@*****.**> AutomatedBy: Daniel Istrate <*****@*****.**> """ features = 'EXTRA_IMAGE_FEATURES = "ssh-server-openssh allow-empty-password allow-root-login"\n' features += 'INHERIT += "extrausers"\n' features += 'EXTRA_USERS_PARAMS = "useradd -p \'\' {}; usermod -s /bin/sh {};"'.format( self.test_user, self.test_user) self.write_config(features) # Build a core-image-minimal bitbake('core-image-minimal') with runqemu("core-image-minimal") as qemu: # Attempt to ssh with each user into qemu with empty password for user in [self.root_user, self.test_user]: ssh = SSHControl(ip=qemu.ip, logfile=qemu.sshlog, user=user) status, output = ssh.run("true") if user == 'root': self.assertNotEqual( status, 0, 'ssh to user root was allowed when it should not have been' ) else: self.assertEqual( status, 0, 'ssh to user tester failed with %s' % output)
def disabled_test_qemu_can_boot_nfs_and_shutdown(self): self.assertExists(self.qemuboot_conf) bitbake('meta-ide-support') rootfs_tar = "%s-%s.tar.bz2" % (self.recipe, self.machine) rootfs_tar = os.path.join(self.deploy_dir_image, rootfs_tar) self.assertExists(rootfs_tar) tmpdir = tempfile.mkdtemp(prefix='qemu_nfs') tmpdir_nfs = os.path.join(tmpdir, 'nfs') cmd_extract_nfs = 'runqemu-extract-sdk %s %s' % (rootfs_tar, tmpdir_nfs) result = runCmd(cmd_extract_nfs) self.assertEqual( 0, result.status, "runqemu-extract-sdk didn't run as expected. %s" % result.output) cmd = "%s nfs %s %s" % (self.cmd_common, self.qemuboot_conf, tmpdir_nfs) 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)) runCmd('rm -rf %s' % tmpdir)
def test_common_poky_config(self): """ A full image build test of the common image, without the refkit-config.inc. We cannot guarantee that content from other layers than OE-core and meta-refkit-core actually builds in such a configuration (additional layers might not be compatible with OE-core master yet), so we limit testing to OE-core and our own additional content. Poky uses sysvinit. Actually building an image runs also postinst and various rootfs manipulation code, and some of that might assume that systemd is used. """ self.add_refkit_layers(filter=['meta-refkit-core']) # We need an image that we can log into, so zap the root password. self.append_config(''' REFKIT_IMAGE_EXTRA_FEATURES_append = " empty-root-password" ''') bitbake('refkit-image-common', output_log=self.logger) with runqemu('refkit-image-common', ssh=False, image_fstype='wic', runqemuparams='ovmf slirp') as qemu: cmd = 'id' status, output = qemu.run_serial(cmd) self.assertTrue(status, 'Failed to log in:\n%s' % output) self.assertTrue(output.startswith('uid=0(root)'))
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()))
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 init_manager_loop(self, init_manager): import oe.path vars = get_bb_vars(("IMAGE_ROOTFS", "sysconfdir"), "core-image-minimal") rootfs = vars["IMAGE_ROOTFS"] self.assertIsNotNone(rootfs) sysconfdir = vars["sysconfdir"] self.assertIsNotNone(sysconfdir) # Need to use oe.path here as sysconfdir starts with / hosttestdir = oe.path.join(rootfs, sysconfdir, "postinst-test") targettestdir = os.path.join(sysconfdir, "postinst-test") for classes in ("package_rpm", "package_deb", "package_ipk"): with self.subTest(init_manager=init_manager, package_class=classes): features = 'CORE_IMAGE_EXTRA_INSTALL = "postinst-delayed-b"\n' features += 'IMAGE_FEATURES += "package-management empty-root-password"\n' features += 'PACKAGE_CLASSES = "%s"\n' % classes if init_manager == "systemd": features += 'DISTRO_FEATURES:append = " systemd"\n' features += 'VIRTUAL-RUNTIME_init_manager = "systemd"\n' features += 'DISTRO_FEATURES_BACKFILL_CONSIDERED = "sysvinit"\n' features += 'VIRTUAL-RUNTIME_initscripts = ""\n' self.write_config(features) bitbake('core-image-minimal') self.assertTrue(os.path.isfile(os.path.join(hosttestdir, "rootfs")), "rootfs state file was not created") with runqemu('core-image-minimal') as qemu: # Make the test echo a string and search for that as # run_serial()'s status code is useless.' for filename in ("rootfs", "delayed-a", "delayed-b"): status, output = qemu.run_serial("test -f %s && echo found" % os.path.join(targettestdir, filename)) self.assertIn("found", output, "%s was not present on boot" % filename)
def test_preserve_ownership(self): import os, stat, oe.cachedpath features = 'IMAGE_INSTALL_append = " selftest-chown"\n' self.write_config(features) bitbake("core-image-minimal") sysconfdir = get_bb_var('sysconfdir', 'selftest-chown') def check_ownership(qemu, gid, uid, path): self.logger.info("Check ownership of %s", path) status, output = qemu.run_serial(r'/bin/stat -c "%U %G" ' + path, timeout=60) output = output.split(" ") if output[0] != uid or output[1] != gid: self.logger.error("Incrrect ownership %s [%s:%s]", path, output[0], output[1]) return False return True with runqemu('core-image-minimal') as qemu: for path in [ sysconfdir + "/selftest-chown/file", sysconfdir + "/selftest-chown/dir", sysconfdir + "/selftest-chown/symlink" ]: if not check_ownership(qemu, "test", "test", path): self.fail('Test ownership %s failed' % path)
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_rpm_version_4_support_on_image(self): """ Summary: Check rpm version 4 support on image Expected: Rpm version must be 4.x Product: oe-core Author: Ionut Chisanovici <*****@*****.**> AutomatedBy: Daniel Istrate <*****@*****.**> """ features = 'PREFERRED_VERSION_rpm = "4.%"\n' features += 'PREFERRED_VERSION_rpm-native = "4.%"\n' # Use openssh in IMAGE_INSTALL instead of ssh-server-openssh in EXTRA_IMAGE_FEATURES as a workaround for bug 8047 features += 'IMAGE_INSTALL_append = " openssh"\n' features += 'EXTRA_IMAGE_FEATURES = "empty-root-password allow-empty-password package-management"\n' features += 'RPMROOTFSDEPENDS_remove = "rpmresolve-native:do_populate_sysroot"' # Append 'features' to local.conf self.append_config(features) # Build a core-image-minimal bitbake("core-image-minimal") # Check the native version of rpm is correct native_bindir = get_bb_var("STAGING_BINDIR_NATIVE") result = runCmd(os.path.join(native_bindir, "rpm") + " --version") self.assertIn("version 4.", result.output) # Check manifest for the rpm package deploydir = get_bb_var("DEPLOY_DIR_IMAGE") imgname = get_bb_var("IMAGE_LINK_NAME", "core-image-minimal") with open(os.path.join(deploydir, imgname) + ".manifest", "r") as f: for line in f: splitline = line.split() if len(splitline) > 2: rpm_version = splitline[2] if splitline[0] == "rpm": if not rpm_version.startswith("4."): self.fail("rpm version %s found in image, expected 4.x" % rpm_version) break else: self.fail("No rpm package found in image") # Now do a couple of runtime tests with runqemu("core-image-minimal", self) as qemu: command = "rpm --version" status, output = qemu.run(command) self.assertEqual(0, status, 'Failed to run command "%s": %s' % (command, output)) found_rpm_version = output.strip() # Make sure the retrieved rpm version is the expected one if rpm_version not in found_rpm_version: self.fail("RPM version is not {}, found instead {}.".format(rpm_version, found_rpm_version)) # Test that the rpm database is there and working command = "rpm -qa" status, output = qemu.run(command) self.assertEqual(0, status, 'Failed to run command "%s": %s' % (command, output)) self.assertIn("packagegroup-core-boot", output) self.assertIn("busybox", output)
def test_postinst_roofs_and_boot(self): """ Summary: The purpose of this test case is to verify Post-installation scripts are called when roofs is created and also test that script can be delayed to run at first boot. Dependencies: NA Steps: 1. Add proper configuration to local.conf file 2. Build a "core-image-full-cmdline" image 3. Verify that file created by postinst_rootfs recipe is present on rootfs dir. 4. Boot the image created on qemu and verify that the file created by postinst_boot recipe is present on image. 5. Clean the packages and image created to test with different package managers Expected: The files are successfully created during rootfs and boot time for 3 different package managers: rpm,ipk,deb and for initialization managers: sysvinit and systemd. """ file_rootfs_name = "this-was-created-at-rootfstime" fileboot_name = "this-was-created-at-first-boot" rootfs_pkg = 'postinst-at-rootfs' boot_pkg = 'postinst-delayed-a' #Step 1 features = 'MACHINE = "qemux86"\n' features += 'CORE_IMAGE_EXTRA_INSTALL += "%s %s "\n'% (rootfs_pkg, boot_pkg) for init_manager in ("sysvinit", "systemd"): #for sysvinit no extra configuration is needed, if (init_manager is "systemd"): features += 'DISTRO_FEATURES_append = " systemd"\n' features += 'VIRTUAL-RUNTIME_init_manager = "systemd"\n' features += 'DISTRO_FEATURES_BACKFILL_CONSIDERED = "sysvinit"\n' features += 'VIRTUAL-RUNTIME_initscripts = ""\n' for classes in ("package_rpm package_deb package_ipk", "package_deb package_rpm package_ipk", "package_ipk package_deb package_rpm"): features += 'PACKAGE_CLASSES = "%s"\n' % classes self.write_config(features) #Step 2 bitbake('core-image-full-cmdline') #Step 3 file_rootfs_created = os.path.join(get_bb_var('IMAGE_ROOTFS',"core-image-full-cmdline"), file_rootfs_name) found = os.path.isfile(file_rootfs_created) self.assertTrue(found, "File %s was not created at rootfs time by %s" % \ (file_rootfs_name, rootfs_pkg)) #Step 4 testcommand = 'ls /etc/'+fileboot_name with runqemu('core-image-full-cmdline') as qemu: sshargs = '-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no' result = runCmd('ssh %s root@%s %s' % (sshargs, qemu.ip, testcommand)) self.assertEqual(result.status, 0, 'File %s was not created at firts boot'% fileboot_name) #Step 5 bitbake(' %s %s -c cleanall' % (rootfs_pkg, boot_pkg)) bitbake('core-image-full-cmdline -c cleanall')
def test_rpm_version_4_support_on_image(self): """ Summary: Check rpm version 4 support on image Expected: Rpm version must be 4.x Product: oe-core Author: Ionut Chisanovici <*****@*****.**> AutomatedBy: Daniel Istrate <*****@*****.**> """ features = 'PREFERRED_VERSION_rpm = "4.%"\n' features += 'PREFERRED_VERSION_rpm-native = "4.%"\n' # Use openssh in IMAGE_INSTALL instead of ssh-server-openssh in EXTRA_IMAGE_FEATURES as a workaround for bug 8047 features += 'IMAGE_INSTALL_append = " openssh"\n' features += 'EXTRA_IMAGE_FEATURES = "empty-root-password allow-empty-password package-management"\n' features += 'RPMROOTFSDEPENDS_remove = "rpmresolve-native:do_populate_sysroot"' # Append 'features' to local.conf self.append_config(features) # Build a core-image-minimal bitbake('core-image-minimal') # Check the native version of rpm is correct native_bindir = get_bb_var('STAGING_BINDIR_NATIVE') result = runCmd(os.path.join(native_bindir, 'rpm') + ' --version') self.assertIn('version 4.', result.output) # Check manifest for the rpm package deploydir = get_bb_var('DEPLOY_DIR_IMAGE') imgname = get_bb_var('IMAGE_LINK_NAME', 'core-image-minimal') with open(os.path.join(deploydir, imgname) + '.manifest', 'r') as f: for line in f: splitline = line.split() if len(splitline) > 2: rpm_version = splitline[2] if splitline[0] == 'rpm': if not rpm_version.startswith('4.'): self.fail('rpm version %s found in image, expected 4.x' % rpm_version) break else: self.fail('No rpm package found in image') # Now do a couple of runtime tests with runqemu("core-image-minimal", self) as qemu: command = "rpm --version" status, output = qemu.run(command) self.assertEqual(0, status, 'Failed to run command "%s": %s' % (command, output)) found_rpm_version = output.strip() # Make sure the retrieved rpm version is the expected one if rpm_version not in found_rpm_version: self.fail('RPM version is not {}, found instead {}.'.format(rpm_version, found_rpm_version)) # Test that the rpm database is there and working command = "rpm -qa" status, output = qemu.run(command) self.assertEqual(0, status, 'Failed to run command "%s": %s' % (command, output)) self.assertIn('packagegroup-core-boot', output) self.assertIn('busybox', output)
def test_qemu(self): """Test wic-image-minimal under qemu""" self.assertEqual(0, bitbake('wic-image-minimal').status) with runqemu('wic-image-minimal', ssh=False) as qemu: command = "mount |grep '^/dev/' | cut -f1,3 -d ' '" status, output = qemu.run_serial(command) self.assertEqual(1, status, 'Failed to run command "%s": %s' % (command, output)) self.assertEqual(output, '/dev/root /\r\n/dev/vda3 /mnt')
def test_boot_qemu_boot(self): """Test runqemu /path/to/image.qemuboot.conf""" qemuboot_conf = "%s-%s.qemuboot.conf" % (self.recipe, self.machine) 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: self.assertTrue(qemu.runner.logged, "Failed: %s" % cmd)
def test_boot_rootfs(self): """Test runqemu /path/to/rootfs.ext4""" rootfs = "%s-%s.ext4" % (self.recipe, self.machine) 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: self.assertTrue(qemu.runner.logged, "Failed: %s" % cmd)
def boot_image(self, overrides): """ Calls runqemu() such that commands can be started via run_serial(). Derived classes need to replace with something that adds whatever other parameters are needed or useful. """ return runqemu(self.IMAGE_PN, discard_writes=False, overrides=overrides)
def test_crosstap_helloworld(self): self.write_config(self.default_config()) bitbake('systemtap-native') systemtap_examples = os.path.join(get_bb_var("WORKDIR","systemtap-native"), "usr/share/systemtap/examples") bitbake(self.image) with runqemu(self.image) as qemu: cmd = "crosstap -r [email protected] -s %s/general/helloworld.stp " % systemtap_examples result = runCmd(cmd) self.assertEqual(0, result.status, 'crosstap helloworld returned a non 0 status:%s' % result.output)
def test_postinst_rootfs_and_boot(self): """ Summary: The purpose of this test case is to verify Post-installation scripts are called when rootfs is created and also test that script can be delayed to run at first boot. Dependencies: NA Steps: 1. Add proper configuration to local.conf file 2. Build a "core-image-minimal" image 3. Verify that file created by postinst_rootfs recipe is present on rootfs dir. 4. Boot the image created on qemu and verify that the file created by postinst_boot recipe is present on image. Expected: The files are successfully created during rootfs and boot time for 3 different package managers: rpm,ipk,deb and for initialization managers: sysvinit and systemd. """ file_rootfs_name = "this-was-created-at-rootfstime" fileboot_name = "this-was-created-at-first-boot" rootfs_pkg = 'postinst-at-rootfs' boot_pkg = 'postinst-delayed-a' for init_manager in ("sysvinit", "systemd"): for classes in ("package_rpm", "package_deb", "package_ipk"): with self.subTest(init_manager=init_manager, package_class=classes): features = 'MACHINE = "qemux86"\n' features += 'CORE_IMAGE_EXTRA_INSTALL += "%s %s "\n' % ( rootfs_pkg, boot_pkg) features += 'IMAGE_FEATURES += "package-management empty-root-password"\n' features += 'PACKAGE_CLASSES = "%s"\n' % classes if init_manager == "systemd": features += 'DISTRO_FEATURES_append = " systemd"\n' features += 'VIRTUAL-RUNTIME_init_manager = "systemd"\n' features += 'DISTRO_FEATURES_BACKFILL_CONSIDERED = "sysvinit"\n' features += 'VIRTUAL-RUNTIME_initscripts = ""\n' self.write_config(features) bitbake('core-image-minimal') file_rootfs_created = os.path.join( get_bb_var('IMAGE_ROOTFS', "core-image-minimal"), file_rootfs_name) found = os.path.isfile(file_rootfs_created) self.assertTrue(found, "File %s was not created at rootfs time by %s" % \ (file_rootfs_name, rootfs_pkg)) testcommand = 'ls /etc/' + fileboot_name with runqemu('core-image-minimal') as qemu: status, output = qemu.run_serial("-f /etc/" + fileboot_name) self.assertEqual( status, 0, 'File %s was not created at first boot (%s)' % (fileboot_name, output))
def test_postinst_rootfs_and_boot(self): """ Summary: The purpose of this test case is to verify Post-installation scripts are called when rootfs is created and also test that script can be delayed to run at first boot. Dependencies: NA Steps: 1. Add proper configuration to local.conf file 2. Build a "core-image-minimal" image 3. Verify that file created by postinst_rootfs recipe is present on rootfs dir. 4. Boot the image created on qemu and verify that the file created by postinst_boot recipe is present on image. Expected: The files are successfully created during rootfs and boot time for 3 different package managers: rpm,ipk,deb and for initialization managers: sysvinit and systemd. """ import oe.path vars = get_bb_vars(("IMAGE_ROOTFS", "sysconfdir"), "core-image-minimal") rootfs = vars["IMAGE_ROOTFS"] self.assertIsNotNone(rootfs) sysconfdir = vars["sysconfdir"] self.assertIsNotNone(sysconfdir) # Need to use oe.path here as sysconfdir starts with / hosttestdir = oe.path.join(rootfs, sysconfdir, "postinst-test") targettestdir = os.path.join(sysconfdir, "postinst-test") for init_manager in ("sysvinit", "systemd"): for classes in ("package_rpm", "package_deb", "package_ipk"): with self.subTest(init_manager=init_manager, package_class=classes): features = 'CORE_IMAGE_EXTRA_INSTALL = "postinst-delayed-b"\n' features += 'IMAGE_FEATURES += "package-management empty-root-password"\n' features += 'PACKAGE_CLASSES = "%s"\n' % classes if init_manager == "systemd": features += 'DISTRO_FEATURES_append = " systemd"\n' features += 'VIRTUAL-RUNTIME_init_manager = "systemd"\n' features += 'DISTRO_FEATURES_BACKFILL_CONSIDERED = "sysvinit"\n' features += 'VIRTUAL-RUNTIME_initscripts = ""\n' self.write_config(features) bitbake('core-image-minimal') self.assertTrue(os.path.isfile(os.path.join(hosttestdir, "rootfs")), "rootfs state file was not created") with runqemu('core-image-minimal') as qemu: # Make the test echo a string and search for that as # run_serial()'s status code is useless.' for filename in ("rootfs", "delayed-a", "delayed-b"): status, output = qemu.run_serial("test -f %s && echo found" % os.path.join(targettestdir, filename)) self.assertEqual(output, "found", "%s was not present on boot" % filename)
def test_expand_mbr_image(self): """Test wic write --expand command for mbr image""" # build an image config = 'IMAGE_FSTYPES = "wic"\nWKS_FILE = "directdisk.wks"\n' self.append_config(config) self.assertEqual(0, bitbake('core-image-minimal').status) # get path to the image bb_vars = get_bb_vars(['DEPLOY_DIR_IMAGE', 'MACHINE']) deploy_dir = bb_vars['DEPLOY_DIR_IMAGE'] machine = bb_vars['MACHINE'] image_path = os.path.join(deploy_dir, 'core-image-minimal-%s.wic' % machine) self.remove_config(config) try: # expand image to 1G new_image_path = None with NamedTemporaryFile(mode='wb', suffix='.wic.exp', dir=deploy_dir, delete=False) as sparse: sparse.truncate(1024 ** 3) new_image_path = sparse.name sysroot = get_bb_var('RECIPE_SYSROOT_NATIVE', 'wic-tools') cmd = "wic write -n %s --expand 1:0 %s %s" % (sysroot, image_path, new_image_path) self.assertEqual(0, runCmd(cmd).status) # check if partitions are expanded orig = runCmd("wic ls %s -n %s" % (image_path, sysroot)) exp = runCmd("wic ls %s -n %s" % (new_image_path, sysroot)) orig_sizes = [int(line.split()[3]) for line in orig.output.split('\n')[1:]] exp_sizes = [int(line.split()[3]) for line in exp.output.split('\n')[1:]] self.assertEqual(orig_sizes[0], exp_sizes[0]) # first partition is not resized self.assertTrue(orig_sizes[1] < exp_sizes[1]) # Check if all free space is partitioned result = runCmd("%s/usr/sbin/sfdisk -F %s" % (sysroot, new_image_path)) self.assertTrue("0 B, 0 bytes, 0 sectors" in result.output) os.rename(image_path, image_path + '.bak') os.rename(new_image_path, image_path) # Check if it boots in qemu with runqemu('core-image-minimal', ssh=False) as qemu: cmd = "ls /etc/" status, output = qemu.run_serial('true') self.assertEqual(1, status, 'Failed to run command "%s": %s' % (cmd, output)) finally: if os.path.exists(new_image_path): os.unlink(new_image_path) if os.path.exists(image_path + '.bak'): os.rename(image_path + '.bak', image_path)
def test_expand_mbr_image(self): """Test wic write --expand command for mbr image""" # build an image config = 'IMAGE_FSTYPES = "wic"\nWKS_FILE = "directdisk.wks"\n' self.append_config(config) self.assertEqual(0, bitbake('core-image-minimal').status) # get path to the image bb_vars = get_bb_vars(['DEPLOY_DIR_IMAGE', 'MACHINE']) deploy_dir = bb_vars['DEPLOY_DIR_IMAGE'] machine = bb_vars['MACHINE'] image_path = os.path.join(deploy_dir, 'core-image-minimal-%s.wic' % machine) self.remove_config(config) try: # expand image to 1G new_image_path = None with NamedTemporaryFile(mode='wb', suffix='.wic.exp', dir=deploy_dir, delete=False) as sparse: sparse.truncate(1024 ** 3) new_image_path = sparse.name sysroot = get_bb_var('RECIPE_SYSROOT_NATIVE', 'wic-tools') cmd = "wic write -n %s --expand 1:0 %s %s" % (sysroot, image_path, new_image_path) runCmd(cmd) # check if partitions are expanded orig = runCmd("wic ls %s -n %s" % (image_path, sysroot)) exp = runCmd("wic ls %s -n %s" % (new_image_path, sysroot)) orig_sizes = [int(line.split()[3]) for line in orig.output.split('\n')[1:]] exp_sizes = [int(line.split()[3]) for line in exp.output.split('\n')[1:]] self.assertEqual(orig_sizes[0], exp_sizes[0]) # first partition is not resized self.assertTrue(orig_sizes[1] < exp_sizes[1]) # Check if all free space is partitioned result = runCmd("%s/usr/sbin/sfdisk -F %s" % (sysroot, new_image_path)) self.assertTrue("0 B, 0 bytes, 0 sectors" in result.output) os.rename(image_path, image_path + '.bak') os.rename(new_image_path, image_path) # Check if it boots in qemu with runqemu('core-image-minimal', ssh=False) as qemu: cmd = "ls /etc/" status, output = qemu.run_serial('true') self.assertEqual(1, status, 'Failed to run command "%s": %s' % (cmd, output)) finally: if os.path.exists(new_image_path): os.unlink(new_image_path) if os.path.exists(image_path + '.bak'): os.rename(image_path + '.bak', image_path)
def test_qemu_efi(self): """Test core-image-minimal efi image under qemu""" config = 'IMAGE_FSTYPES = "wic"\nWKS_FILE = "mkefidisk.wks"\n' self.append_config(config) self.assertEqual(0, bitbake('core-image-minimal ovmf').status) self.remove_config(config) with runqemu('core-image-minimal', ssh=False, runqemuparams='ovmf', image_fstype='wic') as qemu: cmd = "grep sda. /proc/partitions |wc -l" status, output = qemu.run_serial(cmd) self.assertEqual(1, status, 'Failed to run command "%s": %s' % (cmd, output)) self.assertEqual(output, '3')
def test_qemu(self): """Test wic-image-minimal under qemu""" config = 'IMAGE_FSTYPES += " hddimg wic"\nWKS_FILE = "wic-image-minimal"\n'\ 'MACHINE_FEATURES_append = " efi"\n' self.append_config(config) self.assertEqual(0, bitbake('wic-image-minimal').status) self.remove_config(config) with runqemu('wic-image-minimal', ssh=False) as qemu: cmd = "mount |grep '^/dev/' | cut -f1,3 -d ' '" status, output = qemu.run_serial(cmd) self.assertEqual(1, status, 'Failed to run command "%s": %s' % (cmd, output)) self.assertEqual(output, '/dev/root /\r\n/dev/vda3 /mnt')
def test_gdb_server(self): target_arch = self.td["TARGET_ARCH"] target_sys = self.td["TARGET_SYS"] deploy_dir = get_bb_var("DEPLOY_DIR_IMAGE") features = """ IMAGE_GEN_DEBUGFS = "1" IMAGE_FSTYPES_DEBUGFS = "tar.bz2" CORE_IMAGE_EXTRA_INSTALL = "gdbserver" """ self.write_config(features) gdb_recipe = "gdb-cross-" + target_arch gdb_binary = target_sys + "-gdb" bitbake("core-image-minimal %s:do_addto_recipe_sysroot" % gdb_recipe) native_sysroot = get_bb_var("RECIPE_SYSROOT_NATIVE", gdb_recipe) r = runCmd("%s --version" % gdb_binary, native_sysroot=native_sysroot, target_sys=target_sys) self.assertEqual(r.status, 0) self.assertIn("GNU gdb", r.output) with tempfile.TemporaryDirectory(prefix="debugfs-") as debugfs: filename = os.path.join(deploy_dir, "core-image-minimal-%s-dbg.tar.bz2" % self.td["MACHINE"]) shutil.unpack_archive(filename, debugfs) filename = os.path.join(deploy_dir, "core-image-minimal-%s.tar.bz2" % self.td["MACHINE"]) shutil.unpack_archive(filename, debugfs) with runqemu("core-image-minimal", runqemuparams="nographic") as qemu: status, output = qemu.run_serial("kmod --help") self.assertIn("modprobe", output) with concurrent.futures.ThreadPoolExecutor(max_workers=1) as executor: def run_gdb(): for _ in range(5): time.sleep(2) cmd = "%s --batch -ex 'set sysroot %s' -ex \"target extended-remote %s:9999\" -ex \"info line kmod_help\"" % (gdb_binary, debugfs, qemu.ip) self.logger.warning("starting gdb %s" % cmd) r = runCmd(cmd, native_sysroot=native_sysroot, target_sys=target_sys) self.assertEqual(0, r.status) line_re = r"Line \d+ of \"/usr/src/debug/kmod/.*/tools/kmod.c\" starts at address 0x[0-9A-Fa-f]+ <kmod_help>" self.assertRegex(r.output, line_re) break else: self.fail("Timed out connecting to gdb") future = executor.submit(run_gdb) status, output = qemu.run_serial("gdbserver --once :9999 kmod --help") self.assertEqual(status, 1) # The future either returns None, or raises an exception future.result()
def test_rawcopy_plugin_qemu(self): """Test rawcopy plugin in qemu""" # build ext4 and wic images for fstype in ("ext4", "wic"): config = 'IMAGE_FSTYPES = "%s"\nWKS_FILE = "test_rawcopy_plugin.wks.in"\n' % fstype self.append_config(config) self.assertEqual(0, bitbake('core-image-minimal').status) self.remove_config(config) with runqemu('core-image-minimal', ssh=False, image_fstype='wic') as qemu: cmd = "grep sda. /proc/partitions |wc -l" status, output = qemu.run_serial(cmd) self.assertEqual(1, status, 'Failed to run command "%s": %s' % (cmd, output)) self.assertEqual(output, '2')
def test_verify_postinst(self): """ Summary: The purpose of this test is to verify the execution order of postinst Bugzilla ID: [5319] Expected : 1. Compile a minimal image. 2. The compiled image will add the created layer with the recipes postinst[ abdpt] 3. Run qemux86 4. Validate the task execution order Author: Francisco Pedraza <*****@*****.**> """ features = 'INHERIT += "testimage"\n' features += 'CORE_IMAGE_EXTRA_INSTALL += "postinst-at-rootfs \ postinst-delayed-a \ postinst-delayed-b \ postinst-delayed-d \ postinst-delayed-p \ postinst-delayed-t \ "\n' self.write_config(features) bitbake('core-image-minimal -f ') postinst_list = [ '100-postinst-at-rootfs', '101-postinst-delayed-a', '102-postinst-delayed-b', '103-postinst-delayed-d', '104-postinst-delayed-p', '105-postinst-delayed-t' ] path_workdir = get_bb_var('WORKDIR', 'core-image-minimal') workspacedir = 'testimage/qemu_boot_log' workspacedir = os.path.join(path_workdir, workspacedir) rexp = re.compile("^Running postinst .*/(?P<postinst>.*)\.\.\.$") with runqemu('core-image-minimal') as qemu: with open(workspacedir) as f: found = False idx = 0 for line in f.readlines(): line = line.strip().replace("^M", "") if not line: # To avoid empty lines continue m = rexp.search(line) if m: self.assertEqual(postinst_list[idx], m.group('postinst'), "Fail") idx = idx + 1 found = True elif found: self.assertEqual(idx, len(postinst_list), "Not found all postinsts") break
def test_postinst_rootfs_and_boot(self): """ Summary: The purpose of this test case is to verify Post-installation scripts are called when rootfs is created and also test that script can be delayed to run at first boot. Dependencies: NA Steps: 1. Add proper configuration to local.conf file 2. Build a "core-image-minimal" image 3. Verify that file created by postinst_rootfs recipe is present on rootfs dir. 4. Boot the image created on qemu and verify that the file created by postinst_boot recipe is present on image. Expected: The files are successfully created during rootfs and boot time for 3 different package managers: rpm,ipk,deb and for initialization managers: sysvinit and systemd. """ file_rootfs_name = "this-was-created-at-rootfstime" fileboot_name = "this-was-created-at-first-boot" rootfs_pkg = 'postinst-at-rootfs' boot_pkg = 'postinst-delayed-a' for init_manager in ("sysvinit", "systemd"): for classes in ("package_rpm", "package_deb", "package_ipk"): with self.subTest(init_manager=init_manager, package_class=classes): features = 'MACHINE = "qemux86"\n' features += 'CORE_IMAGE_EXTRA_INSTALL += "%s %s "\n'% (rootfs_pkg, boot_pkg) features += 'IMAGE_FEATURES += "package-management empty-root-password"\n' features += 'PACKAGE_CLASSES = "%s"\n' % classes if init_manager == "systemd": features += 'DISTRO_FEATURES_append = " systemd"\n' features += 'VIRTUAL-RUNTIME_init_manager = "systemd"\n' features += 'DISTRO_FEATURES_BACKFILL_CONSIDERED = "sysvinit"\n' features += 'VIRTUAL-RUNTIME_initscripts = ""\n' self.write_config(features) bitbake('core-image-minimal') file_rootfs_created = os.path.join(get_bb_var('IMAGE_ROOTFS', "core-image-minimal"), file_rootfs_name) found = os.path.isfile(file_rootfs_created) self.assertTrue(found, "File %s was not created at rootfs time by %s" % \ (file_rootfs_name, rootfs_pkg)) testcommand = 'ls /etc/' + fileboot_name with runqemu('core-image-minimal') as qemu: status, output = qemu.run_serial("-f /etc/" + fileboot_name) self.assertEqual(status, 0, 'File %s was not created at first boot (%s)' % (fileboot_name, output))
def test_verify_postinst(self): """ Summary: The purpose of this test is to verify the execution order of postinst Bugzilla ID: [5319] Expected : 1. Compile a minimal image. 2. The compiled image will add the created layer with the recipes postinst[ abdpt] 3. Run qemux86 4. Validate the task execution order Author: Francisco Pedraza <*****@*****.**> """ features = 'INHERIT += "testimage"\n' features += 'CORE_IMAGE_EXTRA_INSTALL += "postinst-at-rootfs \ postinst-delayed-a \ postinst-delayed-b \ postinst-delayed-d \ postinst-delayed-p \ postinst-delayed-t \ "\n' self.write_config(features) bitbake('core-image-minimal -f ') postinst_list = ['100-postinst-at-rootfs', '101-postinst-delayed-a', '102-postinst-delayed-b', '103-postinst-delayed-d', '104-postinst-delayed-p', '105-postinst-delayed-t'] path_workdir = get_bb_var('WORKDIR','core-image-minimal') workspacedir = 'testimage/qemu_boot_log' workspacedir = os.path.join(path_workdir, workspacedir) rexp = re.compile("^Running postinst .*/(?P<postinst>.*)\.\.\.$") with runqemu('core-image-minimal') as qemu: with open(workspacedir) as f: found = False idx = 0 for line in f.readlines(): line = line.strip().replace("^M","") if not line: # To avoid empty lines continue m = rexp.search(line) if m: self.assertEqual(postinst_list[idx], m.group('postinst'), "Fail") idx = idx+1 found = True elif found: self.assertEqual(idx, len(postinst_list), "Not found all postinsts") break
def test_qemu(self): """Test wic-image-minimal under qemu""" config = 'IMAGE_FSTYPES += "wic"\nWKS_FILE = "wic-image-minimal"\n'\ 'MACHINE_FEATURES_append = " efi"\n' self.append_config(config) self.assertEqual(0, bitbake('wic-image-minimal').status) self.remove_config(config) with runqemu('wic-image-minimal', ssh=False) as qemu: cmd = "mount |grep '^/dev/' | cut -f1,3 -d ' ' | sort" status, output = qemu.run_serial(cmd) self.assertEqual(output, '/dev/root /\r\n/dev/sda1 /boot\r\n/dev/sda3 /media\r\n/dev/sda4 /mnt') cmd = "grep UUID= /etc/fstab" status, output = qemu.run_serial(cmd) self.assertEqual(1, status, 'Failed to run command "%s": %s' % (cmd, output)) self.assertEqual(output, 'UUID=2c71ef06-a81d-4735-9d3a-379b69c6bdba\t/media\text4\tdefaults\t0\t0')
def run_check_emulated(self, *args, **kwargs): # build core-image-minimal with required packages default_installed_packages = ["libgcc", "libstdc++", "libatomic", "libgomp"] features = [] features.append('IMAGE_FEATURES += "ssh-server-openssh"') features.append('CORE_IMAGE_EXTRA_INSTALL += "{0}"'.format(" ".join(default_installed_packages))) self.write_config("\n".join(features)) bitbake("core-image-minimal") # wrap the execution with a qemu instance with runqemu("core-image-minimal", runqemuparams = "nographic") as qemu: # validate that SSH is working status, _ = qemu.run("uname") self.assertEqual(status, 0) return self.run_check(*args, ssh=qemu.ip, **kwargs)
def disabled_test_qemu_can_boot_nfs_and_shutdown(self): self.assertExists(self.qemuboot_conf) bitbake('meta-ide-support') rootfs_tar = "%s-%s.tar.bz2" % (self.recipe, self.machine) rootfs_tar = os.path.join(self.deploy_dir_image, rootfs_tar) self.assertExists(rootfs_tar) tmpdir = tempfile.mkdtemp(prefix='qemu_nfs') tmpdir_nfs = os.path.join(tmpdir, 'nfs') cmd_extract_nfs = 'runqemu-extract-sdk %s %s' % (rootfs_tar, tmpdir_nfs) result = runCmd(cmd_extract_nfs) self.assertEqual(0, result.status, "runqemu-extract-sdk didn't run as expected. %s" % result.output) cmd = "%s nfs %s %s" % (self.cmd_common, self.qemuboot_conf, tmpdir_nfs) 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)) runCmd('rm -rf %s' % tmpdir)
def test_testexport_basic(self): """ Summary: Check basic testexport functionality with only ping test enabled. Expected: 1. testexport directory must be created. 2. runexported.py must run without any error/exception. 3. ping test must succeed. Product: oe-core Author: Mariano Lopez <*****@*****.**> """ features = 'INHERIT += "testexport"\n' # These aren't the actual IP addresses but testexport class needs something defined features += 'TEST_SERVER_IP = "192.168.7.1"\n' features += 'TEST_TARGET_IP = "192.168.7.1"\n' features += 'TEST_SUITES = "ping"\n' self.write_config(features) # Build tesexport for core-image-minimal bitbake('core-image-minimal') bitbake('-c testexport core-image-minimal') testexport_dir = get_bb_var('TEST_EXPORT_DIR', 'core-image-minimal') # Verify if TEST_EXPORT_DIR was created isdir = os.path.isdir(testexport_dir) self.assertEqual(True, isdir, 'Failed to create testexport dir: %s' % testexport_dir) with runqemu('core-image-minimal') as qemu: # Attempt to run runexported.py to perform ping test test_path = os.path.join(testexport_dir, "oe-test") data_file = os.path.join(testexport_dir, 'data', 'testdata.json') manifest = os.path.join(testexport_dir, 'data', 'manifest') cmd = ("%s runtime --test-data-file %s --packages-manifest %s " "--target-ip %s --server-ip %s --quiet" % (test_path, data_file, manifest, qemu.ip, qemu.server_ip)) result = runCmd(cmd) # Verify ping test was succesful self.assertEqual(0, result.status, 'oe-test runtime returned a non 0 status')
def test_testexport_basic(self): """ Summary: Check basic testexport functionality with only ping test enabled. Expected: 1. testexport directory must be created. 2. runexported.py must run without any error/exception. 3. ping test must succeed. Product: oe-core Author: Mariano Lopez <*****@*****.**> """ features = 'INHERIT += "testexport"\n' # These aren't the actual IP addresses but testexport class needs something defined features += 'TEST_SERVER_IP = "192.168.7.1"\n' features += 'TEST_TARGET_IP = "192.168.7.1"\n' features += 'TEST_SUITES = "ping"\n' self.write_config(features) # Build tesexport for core-image-minimal bitbake('core-image-minimal') bitbake('-c testexport core-image-minimal') # Verify if TEST_EXPORT_DIR was created testexport_dir = get_bb_var('TEST_EXPORT_DIR', 'core-image-minimal') isdir = os.path.isdir(testexport_dir) self.assertEqual(True, isdir, 'Failed to create testexport dir: %s' % testexport_dir) with runqemu('core-image-minimal') as qemu: # Attempt to run runexported.py to perform ping test runexported_path = os.path.join(testexport_dir, "runexported.py") testdata_path = os.path.join(testexport_dir, "testdata.json") cmd = "%s -t %s -s %s %s" % (runexported_path, qemu.ip, qemu.server_ip, testdata_path) result = runCmd(cmd) self.assertEqual(0, result.status, 'runexported.py returned a non 0 status') # Verify ping test was succesful failure = True if 'FAIL' in result.output else False self.assertNotEqual(True, failure, 'ping test failed')
def test_devtool_deploy_target(self): # NOTE: Whilst this test would seemingly be better placed as a runtime test, # unfortunately the runtime tests run under bitbake and you can't run # devtool within bitbake (since devtool needs to run bitbake itself). # Additionally we are testing build-time functionality as well, so # really this has to be done as an oe-selftest test. # # Check preconditions machine = get_bb_var('MACHINE') if not machine.startswith('qemu'): self.skipTest('This test only works with qemu machines') if not os.path.exists('/etc/runqemu-nosudo'): self.skipTest('You must set up tap devices with scripts/runqemu-gen-tapdevs before running this test') result = runCmd('PATH="$PATH:/sbin:/usr/sbin" ip tuntap show', ignore_status=True) if result.status != 0: result = runCmd('PATH="$PATH:/sbin:/usr/sbin" ifconfig -a', ignore_status=True) if result.status != 0: self.skipTest('Failed to determine if tap devices exist with ifconfig or ip: %s' % result.output) for line in result.output.splitlines(): if line.startswith('tap'): break else: self.skipTest('No tap devices found - you must set up tap devices with scripts/runqemu-gen-tapdevs before running this test') workspacedir = os.path.join(self.builddir, 'workspace') self.assertTrue(not os.path.exists(workspacedir), 'This test cannot be run with a workspace directory under the build directory') # Definitions testrecipe = 'mdadm' testfile = '/sbin/mdadm' testimage = 'oe-selftest-image' testcommand = '/sbin/mdadm --help' # Build an image to run bitbake("%s qemu-native qemu-helper-native" % testimage) deploy_dir_image = get_bb_var('DEPLOY_DIR_IMAGE') self.add_command_to_tearDown('bitbake -c clean %s' % testimage) self.add_command_to_tearDown('rm -f %s/%s*' % (deploy_dir_image, testimage)) # Clean recipe so the first deploy will fail bitbake("%s -c clean" % testrecipe) # Try devtool modify tempdir = tempfile.mkdtemp(prefix='devtoolqa') self.track_for_cleanup(tempdir) self.track_for_cleanup(workspacedir) self.add_command_to_tearDown('bitbake-layers remove-layer */workspace') self.add_command_to_tearDown('bitbake -c clean %s' % testrecipe) result = runCmd('devtool modify %s -x %s' % (testrecipe, tempdir)) # Test that deploy-target at this point fails (properly) result = runCmd('devtool deploy-target -n %s root@localhost' % testrecipe, ignore_status=True) self.assertNotEqual(result.output, 0, 'devtool deploy-target should have failed, output: %s' % result.output) self.assertNotIn(result.output, 'Traceback', 'devtool deploy-target should have failed with a proper error not a traceback, output: %s' % result.output) result = runCmd('devtool build %s' % testrecipe) # First try a dry-run of deploy-target result = runCmd('devtool deploy-target -n %s root@localhost' % testrecipe) self.assertIn(' %s' % testfile, result.output) # Boot the image with runqemu(testimage, self) as qemu: # Now really test deploy-target result = runCmd('devtool deploy-target -c %s root@%s' % (testrecipe, qemu.ip)) # Run a test command to see if it was installed properly sshargs = '-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no' result = runCmd('ssh %s root@%s %s' % (sshargs, qemu.ip, testcommand)) # Check if it deployed all of the files with the right ownership/perms # First look on the host - need to do this under pseudo to get the correct ownership/perms installdir = get_bb_var('D', testrecipe) fakerootenv = get_bb_var('FAKEROOTENV', testrecipe) fakerootcmd = get_bb_var('FAKEROOTCMD', testrecipe) result = runCmd('%s %s find . -type f -exec ls -l {} \;' % (fakerootenv, fakerootcmd), cwd=installdir) filelist1 = self._process_ls_output(result.output) # Now look on the target tempdir2 = tempfile.mkdtemp(prefix='devtoolqa') self.track_for_cleanup(tempdir2) tmpfilelist = os.path.join(tempdir2, 'files.txt') with open(tmpfilelist, 'w') as f: for line in filelist1: splitline = line.split() f.write(splitline[-1] + '\n') result = runCmd('cat %s | ssh -q %s root@%s \'xargs ls -l\'' % (tmpfilelist, sshargs, qemu.ip)) filelist2 = self._process_ls_output(result.output) filelist1.sort(key=lambda item: item.split()[-1]) filelist2.sort(key=lambda item: item.split()[-1]) self.assertEqual(filelist1, filelist2) # Test undeploy-target result = runCmd('devtool undeploy-target -c %s root@%s' % (testrecipe, qemu.ip)) result = runCmd('ssh %s root@%s %s' % (sshargs, qemu.ip, testcommand), ignore_status=True) self.assertNotEqual(result, 0, 'undeploy-target did not remove command as it should have')
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: self.assertIn('format=vdi', f.read(), "Failed: %s" % cmd)
def test_boot_efi(self): """Test generic boot partition with qemu""" cmd = "%s %s" % (self.cmd_common, self.machine) with runqemu(self.image, ssh=False, launch_cmd=cmd) as qemu: self.assertTrue(qemu.runner.logged, "Failed: %s" % cmd)
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: self.assertIn('rootfs.ext4', f.read(), "Failed: %s" % cmd)
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_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: self.assertIn('media=cdrom', f.read(), "Failed: %s" % cmd)
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)
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: self.assertTrue(qemu.runner.logged, "Failed: %s" % cmd)