def test_devtool_modify_localfiles(self): # Check preconditions 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') testrecipe = 'lighttpd' src_uri = (get_bb_var('SRC_URI', testrecipe) or '').split() foundlocal = False for item in src_uri: if item.startswith('file://') and '.patch' not in item: foundlocal = True break self.assertTrue(foundlocal, 'This test expects the %s recipe to fetch local files and it seems that it no longer does' % testrecipe) # Clean up anything in the workdir/sysroot/sstate cache bitbake('%s -c cleansstate' % testrecipe) # Try modifying a recipe 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)) self.assertTrue(os.path.exists(os.path.join(tempdir, 'configure.ac')), 'Extracted source could not be found') self.assertTrue(os.path.exists(os.path.join(workspacedir, 'conf', 'layer.conf')), 'Workspace directory not created') matches = glob.glob(os.path.join(workspacedir, 'appends', '%s_*.bbappend' % testrecipe)) self.assertTrue(matches, 'bbappend not created') # Test devtool status result = runCmd('devtool status') self.assertIn(testrecipe, result.output) self.assertIn(tempdir, result.output) # Try building bitbake(testrecipe)
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_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_bmap(self): """ Summary: Check bmap support Expected: 1. core-image-minimal can be build with bmap support 2. core-image-minimal is sparse Product: oe-core Author: Ed Bartosh <*****@*****.**> """ features = 'IMAGE_FSTYPES += " ext4 ext4.bmap ext4.bmap.gz"' self.write_config(features) image_name = 'core-image-minimal' bitbake(image_name) deploy_dir_image = get_bb_var('DEPLOY_DIR_IMAGE') link_name = get_bb_var('IMAGE_LINK_NAME', image_name) image_path = os.path.join(deploy_dir_image, "%s.ext4" % link_name) bmap_path = "%s.bmap" % image_path gzip_path = "%s.gz" % bmap_path # check if result image, bmap and bmap.gz files are in deploy directory self.assertTrue(os.path.exists(image_path)) self.assertTrue(os.path.exists(bmap_path)) self.assertTrue(os.path.exists(gzip_path)) # check if result image is sparse image_stat = os.stat(image_path) self.assertTrue(image_stat.st_size > image_stat.st_blocks * 512) # check if the resulting gzip is valid self.assertTrue(runCmd('gzip -t %s' % gzip_path))
def test_devtool_add(self): # Check preconditions 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') # Fetch source tempdir = tempfile.mkdtemp(prefix='devtoolqa') self.track_for_cleanup(tempdir) url = 'http://www.ivarch.com/programs/sources/pv-1.5.3.tar.bz2' result = runCmd('wget %s' % url, cwd=tempdir) result = runCmd('tar xfv pv-1.5.3.tar.bz2', cwd=tempdir) srcdir = os.path.join(tempdir, 'pv-1.5.3') self.assertTrue(os.path.isfile(os.path.join(srcdir, 'configure')), 'Unable to find configure script in source directory') # Test devtool add self.track_for_cleanup(workspacedir) self.add_command_to_tearDown('bitbake -c cleansstate pv') self.add_command_to_tearDown('bitbake-layers remove-layer */workspace') result = runCmd('devtool add pv %s' % srcdir) self.assertTrue(os.path.exists(os.path.join(workspacedir, 'conf', 'layer.conf')), 'Workspace directory not created') # Test devtool status result = runCmd('devtool status') self.assertIn('pv', result.output) self.assertIn(srcdir, result.output) # Clean up anything in the workdir/sysroot/sstate cache (have to do this *after* devtool add since the recipe only exists then) bitbake('pv -c cleansstate') # Test devtool build result = runCmd('devtool build pv') installdir = get_bb_var('D', 'pv') self.assertTrue(installdir, 'Could not query installdir variable') bindir = get_bb_var('bindir', 'pv') self.assertTrue(bindir, 'Could not query bindir variable') if bindir[0] == '/': bindir = bindir[1:] self.assertTrue(os.path.isfile(os.path.join(installdir, bindir, 'pv')), 'pv binary not found in D')
def test_hypervisor_fmts(self): """ Summary: Check various hypervisor formats Expected: 1. core-image-minimal can be built with vmdk, vdi and qcow2 support. 2. qemu-img says each image has the expected format Product: oe-core Author: Tom Rini <*****@*****.**> """ img_types = [ 'vmdk', 'vdi', 'qcow2' ] features = "" for itype in img_types: features += 'IMAGE_FSTYPES += "wic.%s"\n' % itype self.write_config(features) image_name = 'core-image-minimal' bitbake(image_name) deploy_dir_image = get_bb_var('DEPLOY_DIR_IMAGE') link_name = get_bb_var('IMAGE_LINK_NAME', image_name) for itype in img_types: image_path = os.path.join(deploy_dir_image, "%s.wic.%s" % (link_name, itype)) # check if result image file is in deploy directory self.assertTrue(os.path.exists(image_path)) # check if result image is vmdk sysroot = get_bb_var('STAGING_DIR_NATIVE', 'core-image-minimal') result = runCmd('qemu-img info --output json %s' % image_path, native_sysroot=sysroot) self.assertTrue(json.loads(result.output).get('format') == itype)
def test_sstate_32_64_same_hash(self): """ The sstate checksums for both native and target should not vary whether they're built on a 32 or 64 bit system. Rather than requiring two different build machines and running a builds, override the variables calling uname() manually and check using bitbake -S. """ topdir = get_bb_var('TOPDIR') targetvendor = get_bb_var('TARGET_VENDOR') self.write_config(""" TMPDIR = \"${TOPDIR}/tmp-sstatesamehash\" BUILD_ARCH = \"x86_64\" BUILD_OS = \"linux\" """) self.track_for_cleanup(topdir + "/tmp-sstatesamehash") bitbake("core-image-sato -S printdiff", ignore_status=True) self.write_config(""" TMPDIR = \"${TOPDIR}/tmp-sstatesamehash2\" BUILD_ARCH = \"i686\" BUILD_OS = \"linux\" """) self.track_for_cleanup(topdir + "/tmp-sstatesamehash2") bitbake("core-image-sato -S printdiff", ignore_status=True) def get_files(d): f = [] for root, dirs, files in os.walk(d): f.extend(os.path.join(root, name) for name in files) return f files1 = get_files(topdir + "/tmp-sstatesamehash/stamps/") files2 = get_files(topdir + "/tmp-sstatesamehash2/stamps/") files2 = [x.replace("tmp-sstatesamehash2", "tmp-sstatesamehash").replace("i686-linux", "x86_64-linux").replace("i686" + targetvendor + "-linux", "x86_64" + targetvendor + "-linux", ) for x in files2] self.assertItemsEqual(files1, files2)
def test_invalid_patch(self): self.write_recipeinc('man', 'SRC_URI += "file://man-1.5h1-make.patch"') result = bitbake('man -c patch', ignore_status=True) self.delete_recipeinc('man') bitbake('-cclean man') line = self.getline(result, "Function failed: patch_do_patch") self.assertTrue(line and line.startswith("ERROR:"), msg = "Though no man-1.5h1-make.patch file exists, bitbake didn't output any err. message. bitbake output: %s" % result.output)
def test_sstate_nativelsbstring_same_hash(self): """ The sstate checksums should be independent of whichever NATIVELSBSTRING is detected. Rather than requiring two different build machines and running builds, override the variables manually and check using bitbake -S. """ topdir = get_bb_var('TOPDIR') self.write_config(""" TMPDIR = \"${TOPDIR}/tmp-sstatesamehash\" NATIVELSBSTRING = \"DistroA\" """) self.track_for_cleanup(topdir + "/tmp-sstatesamehash") bitbake("core-image-sato -S none") self.write_config(""" TMPDIR = \"${TOPDIR}/tmp-sstatesamehash2\" NATIVELSBSTRING = \"DistroB\" """) self.track_for_cleanup(topdir + "/tmp-sstatesamehash2") bitbake("core-image-sato -S none") def get_files(d): f = [] for root, dirs, files in os.walk(d): f.extend(os.path.join(root, name) for name in files) return f files1 = get_files(topdir + "/tmp-sstatesamehash/stamps/") files2 = get_files(topdir + "/tmp-sstatesamehash2/stamps/") files2 = [x.replace("tmp-sstatesamehash2", "tmp-sstatesamehash") for x in files2] self.maxDiff = None self.assertItemsEqual(files1, files2)
def setUpLocal(self): super(RunqemuTests, self).setUpLocal() self.recipe = 'core-image-minimal' self.machine = 'qemux86-64' self.fstypes = "ext4 iso hddimg wic.vmdk wic.qcow2 wic.vdi" self.cmd_common = "runqemu nographic" kvm = oe.types.qemu_use_kvm(get_bb_var('QEMU_USE_KVM'), 'x86_64') if kvm: self.cmd_common += " kvm" self.write_config( """ MACHINE = "%s" IMAGE_FSTYPES = "%s" # 10 means 1 second SYSLINUX_TIMEOUT = "10" """ % (self.machine, 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_multiconfig(self): """ Test that a simple multiconfig build works. This uses the mcextend class and the multiconfig-image-packager test recipe to build a core-image-full-cmdline image which contains a tiny core-image-minimal and a musl core-image-minimal, installed as packages. """ config = """ IMAGE_INSTALL_append_pn-core-image-full-cmdline = " multiconfig-image-packager-tiny multiconfig-image-packager-musl" BBMULTICONFIG = "tiny musl" """ self.write_config(config) muslconfig = """ MACHINE = "qemux86-64" DISTRO = "poky" TCLIBC = "musl" TMPDIR = "${TOPDIR}/tmp-mc-musl" """ tinyconfig = """ MACHINE = "qemux86" DISTRO = "poky-tiny" TMPDIR = "${TOPDIR}/tmp-mc-tiny" """ multiconfigdir = self.builddir + "/conf/multiconfig" os.makedirs(multiconfigdir, exist_ok=True) self.track_for_cleanup(multiconfigdir + "/musl.conf") ftools.write_file(multiconfigdir + "/musl.conf", muslconfig) self.track_for_cleanup(multiconfigdir + "/tiny.conf") ftools.write_file(multiconfigdir + "/tiny.conf", tinyconfig) # Build a core-image-minimal bitbake('core-image-full-cmdline')
def _common_build(self): """ Common build for test cases: 1445 , 1528 """ # Build a genericx86-64/efi systemdboot image bitbake('mtools-native core-image-minimal')
def test_force_task(self): bitbake('m4-native') result = bitbake('-C compile m4-native') look_for_tasks = ['do_compile', 'do_install', 'do_populate_sysroot'] for task in look_for_tasks: find_task = re.search("m4-native.*%s" % task, result.output) self.assertTrue(find_task)
def test_archiver_filters_by_type(self): """ Summary: The archiver is documented to filter on the recipe type. Expected: 1. included recipe type (target) should be included 2. other types should be excluded Product: oe-core Author: André Draszik <*****@*****.**> """ target_recipe = 'initscripts' native_recipe = 'zlib-native' features = 'INHERIT += "archiver"\n' features += 'ARCHIVER_MODE[src] = "original"\n' features += 'COPYLEFT_RECIPE_TYPES = "target"\n' self.write_config(features) bitbake('-c clean %s %s' % (target_recipe, native_recipe)) bitbake("%s -c deploy_archives %s" % (target_recipe, native_recipe)) bb_vars = get_bb_vars(['DEPLOY_DIR_SRC', 'TARGET_SYS', 'BUILD_SYS']) src_path_target = os.path.join(bb_vars['DEPLOY_DIR_SRC'], bb_vars['TARGET_SYS']) src_path_native = os.path.join(bb_vars['DEPLOY_DIR_SRC'], bb_vars['BUILD_SYS']) # Check that target_recipe was included included_present = len(glob.glob(src_path_target + '/%s-*' % target_recipe)) self.assertTrue(included_present, 'Recipe %s was not included.' % target_recipe) # Check that native_recipe was excluded excluded_present = len(glob.glob(src_path_native + '/%s-*' % native_recipe)) self.assertFalse(excluded_present, 'Recipe %s was not excluded.' % native_recipe)
def test_testimage_dnf(self): """ Summary: Check package feeds functionality for dnf Expected: 1. Check that remote package feeds can be accessed Product: oe-core Author: Alexander Kanavin <*****@*****.**> """ if get_bb_var('DISTRO') == 'poky-tiny': self.skipTest('core-image-full-cmdline not buildable for poky-tiny') features = 'INHERIT += "testimage"\n' features += 'TEST_SUITES = "ping ssh dnf_runtime dnf.DnfBasicTest.test_dnf_help"\n' # We don't yet know what the server ip and port will be - they will be patched # in at the start of the on-image test features += 'PACKAGE_FEED_URIS = "http://bogus_ip:bogus_port"\n' features += 'EXTRA_IMAGE_FEATURES += "package-management"\n' features += 'PACKAGE_CLASSES = "package_rpm"\n' # Enable package feed signing self.gpg_home = tempfile.mkdtemp(prefix="oeqa-feed-sign-") signing_key_dir = os.path.join(self.testlayer_path, 'files', 'signing') runCmd('gpg --batch --homedir %s --import %s' % (self.gpg_home, os.path.join(signing_key_dir, 'key.secret'))) features += 'INHERIT += "sign_package_feed"\n' features += 'PACKAGE_FEED_GPG_NAME = "testuser"\n' features += 'PACKAGE_FEED_GPG_PASSPHRASE_FILE = "%s"\n' % os.path.join(signing_key_dir, 'key.passphrase') features += 'GPG_PATH = "%s"\n' % self.gpg_home self.write_config(features) # Build core-image-sato and testimage bitbake('core-image-full-cmdline socat') bitbake('-c testimage core-image-full-cmdline') # remove the oeqa-feed-sign temporal directory shutil.rmtree(self.gpg_home, ignore_errors=True)
def test_devtool_modify_invalid(self): # Check preconditions 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') # Try modifying some recipes 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') testrecipes = 'perf kernel-devsrc package-index core-image-minimal meta-toolchain packagegroup-core-sdk meta-ide-support'.split() # Find actual name of gcc-source since it now includes the version - crude, but good enough for this purpose result = runCmd('bitbake-layers show-recipes gcc-source*') reading = False for line in result.output.splitlines(): if line.startswith('=='): reading = True elif reading and not line.startswith(' '): testrecipes.append(line.split(':')[0]) for testrecipe in testrecipes: # Check it's a valid recipe bitbake('%s -e' % testrecipe) # devtool extract should fail result = runCmd('devtool extract %s %s' % (testrecipe, os.path.join(tempdir, testrecipe)), ignore_status=True) self.assertNotEqual(result.status, 0, 'devtool extract on %s should have failed' % testrecipe) self.assertNotIn('Fetching ', result.output, 'devtool extract on %s should have errored out before trying to fetch' % testrecipe) self.assertIn('ERROR: ', result.output, 'devtool extract on %s should have given an ERROR' % testrecipe) # devtool modify should fail result = runCmd('devtool modify %s -x %s' % (testrecipe, os.path.join(tempdir, testrecipe)), ignore_status=True) self.assertNotEqual(result.status, 0, 'devtool modify on %s should have failed' % testrecipe) self.assertIn('ERROR: ', result.output, 'devtool modify on %s should have given an ERROR' % testrecipe)
def test_devtool_modify_git(self): # Check preconditions 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') testrecipe = 'mkelfimage' src_uri = get_bb_var('SRC_URI', testrecipe) self.assertIn('git://', src_uri, 'This test expects the %s recipe to be a git recipe' % testrecipe) # Clean up anything in the workdir/sysroot/sstate cache bitbake('%s -c cleansstate' % testrecipe) # Try modifying a recipe 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)) self.assertTrue(os.path.exists(os.path.join(tempdir, 'Makefile')), 'Extracted source could not be found') self.assertTrue(os.path.isdir(os.path.join(tempdir, '.git')), 'git repository for external source tree not found') self.assertTrue(os.path.exists(os.path.join(workspacedir, 'conf', 'layer.conf')), 'Workspace directory not created') matches = glob.glob(os.path.join(workspacedir, 'appends', 'mkelfimage_*.bbappend')) self.assertTrue(matches, 'bbappend not created') # Test devtool status result = runCmd('devtool status') self.assertIn(testrecipe, result.output) self.assertIn(tempdir, result.output) # Check git repo result = runCmd('git status --porcelain', cwd=tempdir) self.assertEqual(result.output.strip(), "", 'Created git repo is not clean') result = runCmd('git symbolic-ref HEAD', cwd=tempdir) self.assertEqual(result.output.strip(), "refs/heads/devtool", 'Wrong branch in git repo') # Try building bitbake(testrecipe)
def test_archiver_allows_to_filter_on_recipe_name(self): """ Summary: The archiver should offer the possibility to filter on the recipe. (#6929) Expected: 1. Included recipe (busybox) should be included 2. Excluded recipe (zlib) should be excluded Product: oe-core Author: Daniel Istrate <*****@*****.**> AutomatedBy: Daniel Istrate <*****@*****.**> """ include_recipe = 'busybox' exclude_recipe = 'zlib' features = 'INHERIT += "archiver"\n' features += 'ARCHIVER_MODE[src] = "original"\n' features += 'COPYLEFT_PN_INCLUDE = "%s"\n' % include_recipe features += 'COPYLEFT_PN_EXCLUDE = "%s"\n' % exclude_recipe self.write_config(features) bitbake('-c clean %s %s' % (include_recipe, exclude_recipe)) bitbake("-c deploy_archives %s %s" % (include_recipe, exclude_recipe)) bb_vars = get_bb_vars(['DEPLOY_DIR_SRC', 'TARGET_SYS']) src_path = os.path.join(bb_vars['DEPLOY_DIR_SRC'], bb_vars['TARGET_SYS']) # Check that include_recipe was included included_present = len(glob.glob(src_path + '/%s-*' % include_recipe)) self.assertTrue(included_present, 'Recipe %s was not included.' % include_recipe) # Check that exclude_recipe was excluded excluded_present = len(glob.glob(src_path + '/%s-*' % exclude_recipe)) self.assertFalse(excluded_present, 'Recipe %s was not excluded.' % exclude_recipe)
def test_image_fstypes(self): """ Summary: Check if image of supported image fstypes can be built Expected: core-image-minimal can be built for various image types Product: oe-core Author: Ed Bartosh <*****@*****.**> """ image_name = 'core-image-minimal' img_types = [itype for itype in get_bb_var("IMAGE_TYPES", image_name).split() \ if itype not in ('container', 'elf', 'f2fs', 'multiubi')] config = 'IMAGE_FSTYPES += "%s"\n'\ 'MKUBIFS_ARGS ?= "-m 2048 -e 129024 -c 2047"\n'\ 'UBINIZE_ARGS ?= "-m 2048 -p 128KiB -s 512"' % ' '.join(img_types) self.write_config(config) bitbake(image_name) deploy_dir_image = get_bb_var('DEPLOY_DIR_IMAGE') link_name = get_bb_var('IMAGE_LINK_NAME', image_name) for itype in img_types: image_path = os.path.join(deploy_dir_image, "%s.%s" % (link_name, itype)) # check if result image is in deploy directory self.assertTrue(os.path.exists(image_path), "%s image %s doesn't exist" % (itype, image_path))
def test_efi_systemdboot_images_can_be_built(self): """ Summary: Check if systemd-boot images can be built correctly Expected: 1. File systemd-boot.efi should be available in $poky/build/tmp/deploy/images/genericx86-64 2. 'systemd-boot" can be built correctly Product: oe-core Author: Jose Perez Carranza <*****@*****.**> AutomatedBy: Jose Perez Carranza <*****@*****.**> """ # We'd use DEPLOY_DIR_IMAGE here, except that we need its value for # MACHINE="genericx86-64 which is probably not the one configured systemdbootfile = os.path.join(get_bb_var('DEPLOY_DIR'), 'images', 'genericx86-64', 'systemd-bootx64.efi') self._common_setup() # Ensure we're actually testing that this gets built and not that # it was around from an earlier build bitbake('-c clean systemd-boot') runCmd('rm -f %s' % systemdbootfile) self._common_build() found = os.path.isfile(systemdbootfile) self.assertTrue(found, 'Systemd-Boot file %s not found' % systemdbootfile)
def test_no_busybox_base_utils(self): config = """ # Enable x11 DISTRO_FEATURES_append += "x11" # Switch to systemd DISTRO_FEATURES += "systemd" VIRTUAL-RUNTIME_init_manager = "systemd" VIRTUAL-RUNTIME_initscripts = "" VIRTUAL-RUNTIME_syslog = "" VIRTUAL-RUNTIME_login_manager = "shadow-base" DISTRO_FEATURES_BACKFILL_CONSIDERED = "sysvinit" # Replace busybox PREFERRED_PROVIDER_virtual/base-utils = "packagegroup-core-base-utils" VIRTUAL-RUNTIME_base-utils = "packagegroup-core-base-utils" VIRTUAL-RUNTIME_base-utils-hwclock = "util-linux-hwclock" VIRTUAL-RUNTIME_base-utils-syslog = "" # Blacklist busybox PNBLACKLIST[busybox] = "Don't build this" """ self.write_config(config) bitbake("--graphviz core-image-sato")
def test_long_chain_conversion(self): """ Summary: Check for chaining many CONVERSION_CMDs together Expected: 1. core-image-minimal can be built with ext4.bmap.gz.bz2.lzo.xz.u-boot and also create a sha256sum 2. The above image has a valid sha256sum Product: oe-core Author: Tom Rini <*****@*****.**> """ conv = "ext4.bmap.gz.bz2.lzo.xz.u-boot" features = 'IMAGE_FSTYPES += "%s %s.sha256sum"' % (conv, conv) self.write_config(features) image_name = 'core-image-minimal' bitbake(image_name) deploy_dir_image = get_bb_var('DEPLOY_DIR_IMAGE') link_name = get_bb_var('IMAGE_LINK_NAME', image_name) image_path = os.path.join(deploy_dir_image, "%s.%s" % (link_name, conv)) # check if resulting image is in the deploy directory self.assertTrue(os.path.exists(image_path)) self.assertTrue(os.path.exists(image_path + ".sha256sum")) # check if the resulting sha256sum agrees self.assertTrue(runCmd('cd %s;sha256sum -c %s.%s.sha256sum' % (deploy_dir_image, link_name, conv)))
def test_autorev_sstate_works(self): # Test that a git repository which changes is correctly handled by SRCREV = ${AUTOREV} # when PV does not contain SRCPV tempdir = tempfile.mkdtemp(prefix='oeqa') self.track_for_cleanup(tempdir) create_temp_layer(tempdir, 'selftestrecipetool') self.add_command_to_tearDown('bitbake-layers remove-layer %s' % tempdir) runCmd('bitbake-layers add-layer %s' % tempdir) # Use dbus-wait as a local git repo we can add a commit between two builds in pn = 'dbus-wait' srcrev = '6cc6077a36fe2648a5f993fe7c16c9632f946517' url = 'git://git.yoctoproject.org/dbus-wait' result = runCmd('git clone %s noname' % url, cwd=tempdir) srcdir = os.path.join(tempdir, 'noname') result = runCmd('git reset --hard %s' % srcrev, cwd=srcdir) self.assertTrue(os.path.isfile(os.path.join(srcdir, 'configure.ac')), 'Unable to find configure script in source directory') recipefile = os.path.join(tempdir, "recipes-test", "dbus-wait-test", 'dbus-wait-test_git.bb') os.makedirs(os.path.dirname(recipefile)) srcuri = 'git://' + srcdir + ';protocol=file' result = runCmd(['recipetool', 'create', '-o', recipefile, srcuri]) self.assertTrue(os.path.isfile(recipefile), 'recipetool did not create recipe file; output:\n%s' % result.output) with open(recipefile, 'a') as f: f.write('SRCREV = "${AUTOREV}"\n') f.write('PV = "1.0"\n') bitbake("dbus-wait-test -c fetch") with open(os.path.join(srcdir, "bar.txt"), "w") as f: f.write("foo") result = runCmd('git add bar.txt; git commit -asm "add bar"', cwd=srcdir) bitbake("dbus-wait-test -c unpack")
def sstate_allarch_samesigs(self, configA, configB): self.write_config(configA) self.track_for_cleanup(self.topdir + "/tmp-sstatesamehash") bitbake("world meta-toolchain -S none") self.write_config(configB) self.track_for_cleanup(self.topdir + "/tmp-sstatesamehash2") bitbake("world meta-toolchain -S none") def get_files(d): f = {} for root, dirs, files in os.walk(d): for name in files: if "meta-environment" in root or "cross-canadian" in root: continue if "do_build" not in name: # 1.4.1+gitAUTOINC+302fca9f4c-r0.do_package_write_ipk.sigdata.f3a2a38697da743f0dbed8b56aafcf79 (_, task, _, shash) = name.rsplit(".", 3) f[os.path.join(os.path.basename(root), task)] = shash return f nativesdkdir = os.path.basename(glob.glob(self.topdir + "/tmp-sstatesamehash/stamps/*-nativesdk*-linux")[0]) files1 = get_files(self.topdir + "/tmp-sstatesamehash/stamps/" + nativesdkdir) files2 = get_files(self.topdir + "/tmp-sstatesamehash2/stamps/" + nativesdkdir) self.maxDiff = None self.assertEqual(files1, files2)
def run_test_sstate_cache_management_script( self, target, global_config=[""], target_config=[""], ignore_patterns=[] ): self.assertTrue(global_config) self.assertTrue(target_config) self.assertTrue( len(global_config) == len(target_config), msg="Lists global_config and target_config should have the same number of elements", ) self.config_sstate(temp_sstate_location=True, add_local_mirrors=[self.sstate_path]) # If buildhistory is enabled, we need to disable version-going-backwards QA checks for this test. It may report errors otherwise. if ("buildhistory" in get_bb_var("USER_CLASSES")) or ("buildhistory" in get_bb_var("INHERIT")): remove_errors_config = 'ERROR_QA_remove = "version-going-backwards"' self.append_config(remove_errors_config) # For not this only checks if random sstate tasks are handled correctly as a group. # In the future we should add control over what tasks we check for. sstate_archs_list = [] expected_remaining_sstate = [] for idx in range(len(target_config)): self.append_config(global_config[idx]) self.append_recipeinc(target, target_config[idx]) sstate_arch = get_bb_var("SSTATE_PKGARCH", target) if not sstate_arch in sstate_archs_list: sstate_archs_list.append(sstate_arch) if target_config[idx] == target_config[-1]: target_sstate_before_build = self.search_sstate(target + ".*?\.tgz$") bitbake("-cclean %s" % target) result = bitbake(target, ignore_status=True) if target_config[idx] == target_config[-1]: target_sstate_after_build = self.search_sstate(target + ".*?\.tgz$") expected_remaining_sstate += [ x for x in target_sstate_after_build if x not in target_sstate_before_build if not any(pattern in x for pattern in ignore_patterns) ] self.remove_config(global_config[idx]) self.remove_recipeinc(target, target_config[idx]) self.assertEqual(result.status, 0) runCmd( "sstate-cache-management.sh -y --cache-dir=%s --remove-duplicated --extra-archs=%s" % (self.sstate_path, ",".join(map(str, sstate_archs_list))) ) actual_remaining_sstate = [ x for x in self.search_sstate(target + ".*?\.tgz$") if not any(pattern in x for pattern in ignore_patterns) ] actual_not_expected = [x for x in actual_remaining_sstate if x not in expected_remaining_sstate] self.assertFalse( actual_not_expected, msg="Files should have been removed but ware not: %s" % ", ".join(map(str, actual_not_expected)), ) expected_not_actual = [x for x in expected_remaining_sstate if x not in actual_remaining_sstate] self.assertFalse( expected_not_actual, msg="Extra files ware removed: %s" ", ".join(map(str, expected_not_actual)) )
def setUpClass(cls): super(Distrodata, cls).setUpClass() feature = 'INHERIT += "distrodata"\n' feature += 'LICENSE_FLAGS_WHITELIST += " commercial"\n' cls.write_config(cls, feature) bitbake('-c checkpkg world')
def test_image_manifest(self): bitbake('core-image-minimal') bb_vars = get_bb_vars(["DEPLOY_DIR_IMAGE", "IMAGE_LINK_NAME"], "core-image-minimal") deploydir = bb_vars["DEPLOY_DIR_IMAGE"] imagename = bb_vars["IMAGE_LINK_NAME"] manifest = os.path.join(deploydir, imagename + ".manifest") self.assertTrue(os.path.islink(manifest), msg="No manifest file created for image. It should have been created in %s" % manifest)
def test_copy_tree_xattr(self): """ Summary: oe.path.copytree() should preserve xattr on copied files Expected: testxattr file in destination should have user.oetest extended attribute Product: OE-Core Author: Joshua Lock <*****@*****.**> """ testloc = oe.path.join(self.tmp_dir, 'liboetests') src = oe.path.join(testloc, 'src') dst = oe.path.join(testloc, 'dst') bb.utils.mkdirhier(testloc) bb.utils.mkdirhier(src) testfilename = 'testxattr' # ensure we have setfattr available bitbake("attr-native") bb_vars = get_bb_vars(['SYSROOT_DESTDIR', 'bindir'], 'attr-native') destdir = bb_vars['SYSROOT_DESTDIR'] bindir = bb_vars['bindir'] bindir = destdir + bindir # create a file with xattr and copy it open(oe.path.join(src, testfilename), 'w+b').close() runCmd('%s/setfattr -n user.oetest -v "testing liboe" %s' % (bindir, oe.path.join(src, testfilename))) oe.path.copytree(src, dst) # ensure file in dest has user.oetest xattr result = runCmd('%s/getfattr -n user.oetest %s' % (bindir, oe.path.join(dst, testfilename))) self.assertIn('user.oetest="testing liboe"', result.output, 'Extended attribute not sert in dst') oe.path.remove(testloc)
def test_stoptask_behavior(self): self.write_config('BB_DISKMON_DIRS = "STOPTASKS,${TMPDIR},100000G,100K"') res = bitbake("m4", ignore_status=True) self.assertTrue( 'ERROR: No new tasks can be executed since the disk space monitor action is "STOPTASKS"!' in res.output, msg="Tasks should have stopped. Disk monitor is set to STOPTASK: %s" % res.output, ) self.assertEqual( res.status, 1, msg="bitbake reported exit code %s. It should have been 1. Bitbake output: %s" % (str(res.status), res.output), ) self.write_config('BB_DISKMON_DIRS = "ABORT,${TMPDIR},100000G,100K"') res = bitbake("m4", ignore_status=True) self.assertTrue( 'ERROR: Immediately abort since the disk space monitor action is "ABORT"!' in res.output, "Tasks should have been aborted immediatelly. Disk monitor is set to ABORT: %s" % res.output, ) self.assertEqual( res.status, 1, msg="bitbake reported exit code %s. It should have been 1. Bitbake output: %s" % (str(res.status), res.output), ) self.write_config('BB_DISKMON_DIRS = "WARN,${TMPDIR},100000G,100K"') res = bitbake("m4") self.assertTrue( "WARNING: The free space" in res.output, msg="A warning should have been displayed for disk monitor is set to WARN: %s" % res.output, )
def setUpLocal(self): super(RunqemuTests, self).setUpLocal() self.recipe = 'core-image-minimal' self.machine = 'qemux86-64' self.fstypes = "ext4 iso hddimg vmdk qcow2 vdi" self.cmd_common = "runqemu nographic" # Avoid emit the same record multiple times. mainlogger = logging.getLogger("BitBake.Main") mainlogger.propagate = False self.write_config( """ MACHINE = "%s" IMAGE_FSTYPES = "%s" # 10 means 1 second SYSLINUX_TIMEOUT = "10" """ % (self.machine, 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_arch_work_dir_and_export_source(self): """ Test for archiving the work directory and exporting the source files. """ self.write_config( "INHERIT += \"archiver\"\nARCHIVER_MODE[src] = \"original\"\nARCHIVER_MODE[srpm] = \"1\"" ) res = bitbake("xcursor-transparent-theme", ignore_status=True) self.assertEqual( res.status, 0, "\nCouldn't build xcursortransparenttheme.\nbitbake output %s" % res.output) deploy_dir_src = get_bb_var('DEPLOY_DIR_SRC') pkgs_path = g.glob(str(deploy_dir_src) + "/allarch*/xcurs*") src_file_glob = str(pkgs_path[0]) + "/xcursor*.src.rpm" tar_file_glob = str(pkgs_path[0]) + "/xcursor*.tar.gz" self.assertTrue(( g.glob(src_file_glob) and g.glob(tar_file_glob) ), "Couldn't find .src.rpm and .tar.gz files under %s/allarch*/xcursor*" % deploy_dir_src)
def test_not_all_units_installed(self): """ Summary: Test QA check that we have required mount units in the image Expected: Fail because mount unit for overlay partition is not installed Author: Vyacheslav Yurkov <*****@*****.**> """ config = """ IMAGE_INSTALL:append = " overlayfs-user" DISTRO_FEATURES += "systemd overlayfs" """ self.write_config(config) self.add_overlay_conf_to_machine() res = bitbake('core-image-minimal', ignore_status=True) line = getline(res, "Unit name mnt-overlay.mount not found in systemd unit directories") self.assertTrue(line and line.startswith("WARNING:"), msg=res.output) line = getline(res, "Not all mount units are installed by the BSP") self.assertTrue(line and line.startswith("ERROR:"), msg=res.output)
def run_test_cleansstate_task(self, targets, distro_specific=True, distro_nonspecific=True, temp_sstate_location=True): self.config_sstate(temp_sstate_location) bitbake(['-ccleansstate'] + targets) bitbake(targets) tgz_created = self.search_sstate('|'.join(map(str, [s + '.*?\.tgz$' for s in targets])), distro_specific, distro_nonspecific) self.assertTrue(tgz_created, msg="Could not find sstate .tgz files for: %s (%s)" % (', '.join(map(str, targets)), str(tgz_created))) siginfo_created = self.search_sstate('|'.join(map(str, [s + '.*?\.siginfo$' for s in targets])), distro_specific, distro_nonspecific) self.assertTrue(siginfo_created, msg="Could not find sstate .siginfo files for: %s (%s)" % (', '.join(map(str, targets)), str(siginfo_created))) bitbake(['-ccleansstate'] + targets) tgz_removed = self.search_sstate('|'.join(map(str, [s + '.*?\.tgz$' for s in targets])), distro_specific, distro_nonspecific) self.assertTrue(not tgz_removed, msg="do_cleansstate didn't remove .tgz sstate files for: %s (%s)" % (', '.join(map(str, targets)), str(tgz_removed)))
def test_mount_unit_not_set(self): """ Summary: Test whether mount unit was set properly Expected: Fail because mount unit was not set Author: Vyacheslav Yurkov <*****@*****.**> """ config = """ IMAGE_INSTALL:append = " overlayfs-user" DISTRO_FEATURES += "systemd overlayfs" """ self.write_config(config) res = bitbake('core-image-minimal', ignore_status=True) line = self.getline( res, "A recipe uses overlayfs class but there is no OVERLAYFS_MOUNT_POINT set in your MACHINE configuration" ) self.assertTrue(line and line.startswith("Parsing recipes...ERROR:"), msg=res.output)
def test_invalid_recipe_src_uri(self): data = 'SRC_URI = "file://invalid"' self.write_recipeinc('man-db', data) self.write_config("""DL_DIR = \"${TOPDIR}/download-selftest\" SSTATE_DIR = \"${TOPDIR}/download-selftest\" INHERIT:remove = \"report-error\" """) self.track_for_cleanup(os.path.join(self.builddir, "download-selftest")) result = bitbake('-c fetch man-db', ignore_status=True) self.delete_recipeinc('man-db') self.assertEqual( result.status, 1, msg= "Command succeded when it should have failed. bitbake output: %s" % result.output) self.assertIn( 'Unable to get checksum for man-db SRC_URI entry invalid: file could not be found', result.output)
def test_arch_work_dir_and_export_source(self): """ Test for archiving the work directory and exporting the source files. """ self.add_command_to_tearDown('cleanup-workdir') self.write_config( "INHERIT = \"archiver\"\nARCHIVER_MODE[src] = \"original\"\nARCHIVER_MODE[srpm] = \"1\"" ) res = bitbake("xcursor-transparent-theme", ignore_status=True) self.assertEqual( res.status, 0, "\nCouldn't build xcursortransparenttheme.\nbitbake output %s" % res.output) pkgs_path = g.glob( str(self.builddir) + "/tmp/deploy/sources/allarch*/xcurs*") src_file_glob = str(pkgs_path[0]) + "/xcursor*.src.rpm" tar_file_glob = str(pkgs_path[0]) + "/xcursor*.tar.gz" self.assertTrue(( g.glob(src_file_glob) and g.glob(tar_file_glob) ), "Couldn't find .src.rpm and .tar.gz files under tmp/deploy/sources/allarch*/xcursor*" )
def test_locked_signatures(self): """ Summary: Test locked signature mechanism Expected: Locked signatures will prevent task to run Product: oe-core Author: Daniel Istrate <*****@*****.**> AutomatedBy: Daniel Istrate <*****@*****.**> """ test_recipe = 'ed' locked_sigs_file = 'locked-sigs.inc' self.add_command_to_tearDown('rm -f %s' % os.path.join(self.builddir, locked_sigs_file)) bitbake(test_recipe) # Generate locked sigs include file bitbake('-S none %s' % test_recipe) feature = 'require %s\n' % locked_sigs_file feature += 'SIGGEN_LOCKEDSIGS_TASKSIG_CHECK = "warn"\n' self.write_config(feature) # Build a locked recipe bitbake(test_recipe) # Make a change that should cause the locked task signature to change recipe_append_file = test_recipe + '_' + get_bb_var('PV', test_recipe) + '.bbappend' recipe_append_path = os.path.join(self.testlayer_path, 'recipes-test', test_recipe, recipe_append_file) feature = 'SUMMARY += "test locked signature"\n' os.mkdir(os.path.join(self.testlayer_path, 'recipes-test', test_recipe)) write_file(recipe_append_path, feature) self.add_command_to_tearDown('rm -rf %s' % os.path.join(self.testlayer_path, 'recipes-test', test_recipe)) # Build the recipe again ret = bitbake(test_recipe) # Verify you get the warning and that the real task *isn't* run (i.e. the locked signature has worked) patt = r'WARNING: The %s:do_package sig is computed to be \S+, but the sig is locked to \S+ in SIGGEN_LOCKEDSIGS\S+' % test_recipe found_warn = re.search(patt, ret.output) self.assertIsNotNone(found_warn, "Didn't find the expected warning message. Output: %s" % ret.output)
def test_distro_features_missing(self): """ Summary: Check that required DISTRO_FEATURES are set Expected: Fail when either systemd or overlayfs are not in DISTRO_FEATURES Author: Vyacheslav Yurkov <*****@*****.**> """ config = """ IMAGE_INSTALL:append = " overlayfs-user" """ overlayfs_recipe_append = """ inherit overlayfs """ self.write_config(config) self.add_overlay_conf_to_machine() self.write_recipeinc('overlayfs-user', overlayfs_recipe_append) res = bitbake('core-image-minimal', ignore_status=True) line = getline(res, "overlayfs-user was skipped: missing required distro features") self.assertTrue("overlayfs" in res.output, msg=res.output) self.assertTrue("systemd" in res.output, msg=res.output) self.assertTrue("ERROR: Required build target 'core-image-minimal' has no buildable providers." in res.output, msg=res.output)
def test_wrong_mount_unit_set(self): """ Summary: Test whether mount unit was set properly Expected: Fail because not the correct flag used for mount unit Author: Vyacheslav Yurkov <*****@*****.**> """ config = """ IMAGE_INSTALL:append = " overlayfs-user" DISTRO_FEATURES += "systemd overlayfs" """ wrong_machine_config = """ OVERLAYFS_MOUNT_POINT[usr-share-overlay] = "/usr/share/overlay" """ self.write_config(config) self.set_machine_config(wrong_machine_config) res = bitbake('core-image-minimal', ignore_status=True) line = getline(res, "Missing required mount point for OVERLAYFS_MOUNT_POINT[mnt-overlay] in your MACHINE configuration") self.assertTrue(line and line.startswith("Parsing recipes...ERROR:"), msg=res.output)
def test_image_env(self): """Test generation of <image>.env files.""" image = 'core-image-minimal' self.assertEqual(0, bitbake('%s -c do_rootfs_wicenv' % image).status) stdir = get_bb_var('STAGING_DIR_TARGET', image) imgdatadir = os.path.join(stdir, 'imgdata') basename = get_bb_var('IMAGE_BASENAME', image) self.assertEqual(basename, image) path = os.path.join(imgdatadir, basename) + '.env' self.assertTrue(os.path.isfile(path)) wicvars = set(get_bb_var('WICVARS', image).split()) # filter out optional variables wicvars = wicvars.difference(('HDDDIR', 'IMAGE_BOOT_FILES', 'INITRD', 'ISODIR')) with open(path) as envfile: content = dict(line.split("=", 1) for line in envfile) # test if variables used by wic present in the .env file for var in wicvars: self.assertTrue(var in content, "%s is not in .env file" % var) self.assertTrue(content[var])
def test_incremental_image_generation(self): image_pkgtype = get_bb_var("IMAGE_PKGTYPE") if image_pkgtype != 'rpm': self.skipTest('Not using RPM as main package format') bitbake("-c cleanall core-image-minimal") self.write_config('INC_RPM_IMAGE_GEN = "1"') self.append_config('IMAGE_FEATURES += "ssh-server-openssh"') bitbake("core-image-minimal") log_data_file = os.path.join(get_bb_var("WORKDIR", "core-image-minimal"), "temp/log.do_rootfs") log_data_created = ftools.read_file(log_data_file) incremental_created = re.search("NOTE: load old install solution for incremental install\nNOTE: old install solution not exist\nNOTE: creating new install solution for incremental install(\n.*)*NOTE: Installing the following packages:.*packagegroup-core-ssh-openssh", log_data_created) self.remove_config('IMAGE_FEATURES += "ssh-server-openssh"') self.assertTrue(incremental_created, msg = "Match failed in:\n%s" % log_data_created) bitbake("core-image-minimal") log_data_removed = ftools.read_file(log_data_file) incremental_removed = re.search("NOTE: load old install solution for incremental install\nNOTE: creating new install solution for incremental install(\n.*)*NOTE: incremental removed:.*openssh-sshd-.*", log_data_removed) self.assertTrue(incremental_removed, msg = "Match failed in:\n%s" % log_data_removed)
def run_test_rebuild_distro_specific_sstate(self, targets, temp_sstate_location=True): self.config_sstate(temp_sstate_location) bitbake(['-ccleansstate'] + targets) bitbake(targets) self.assertTrue(self.search_sstate('|'.join(map(str, [s + '.*?\.tgz$' for s in targets])), distro_specific=False, distro_nonspecific=True) == [], msg="Found distro non-specific sstate for: %s" % ', '.join(map(str, targets))) file_tracker_1 = self.search_sstate('|'.join(map(str, [s + '.*?\.tgz$' for s in targets])), distro_specific=True, distro_nonspecific=False) self.assertTrue(len(file_tracker_1) >= len(targets), msg = "Not all sstate files ware created for: %s" % ', '.join(map(str, targets))) self.track_for_cleanup(self.distro_specific_sstate + "_old") shutil.copytree(self.distro_specific_sstate, self.distro_specific_sstate + "_old") shutil.rmtree(self.distro_specific_sstate) bitbake(['-cclean'] + targets) bitbake(targets) file_tracker_2 = self.search_sstate('|'.join(map(str, [s + '.*?\.tgz$' for s in targets])), distro_specific=True, distro_nonspecific=False) self.assertTrue(len(file_tracker_2) >= len(targets), msg = "Not all sstate files ware created for: %s" % ', '.join(map(str, targets))) not_recreated = [x for x in file_tracker_1 if x not in file_tracker_2] self.assertTrue(not_recreated == [], msg="The following sstate files ware not recreated: %s" % ', '.join(map(str, not_recreated))) created_once = [x for x in file_tracker_2 if x not in file_tracker_1] self.assertTrue(created_once == [], msg="The following sstate files ware created only in the second run: %s" % ', '.join(map(str, created_once)))
def test_cleanup_workdir(self): path = os.path.dirname(get_bb_var('WORKDIR', 'selftest-ed')) old_version_recipe = os.path.join( get_bb_var('COREBASE'), 'meta-selftest/recipes-test/selftest-ed/selftest-ed_0.5.bb') old_version = '0.5' bitbake("-c clean selftest-ed") bitbake("-c clean -b %s" % old_version_recipe) if os.path.exists(path): initial_contents = os.listdir(path) else: initial_contents = [] bitbake('selftest-ed') intermediary_contents = os.listdir(path) bitbake("-b %s" % old_version_recipe) runCmd('cleanup-workdir') remaining_contents = os.listdir(path) expected_contents = [ x for x in intermediary_contents if x not in initial_contents ] remaining_not_expected = [ x for x in remaining_contents if x not in expected_contents ] self.assertFalse( remaining_not_expected, msg="Not all necessary content has been deleted from %s: %s" % (path, ', '.join(map(str, remaining_not_expected)))) expected_not_remaining = [ x for x in expected_contents if x not in remaining_contents ] self.assertFalse(expected_not_remaining, msg="The script removed extra contents from %s: %s" % (path, ', '.join(map(str, expected_not_remaining))))
def test_incremental_image_generation(self): image_pkgtype = get_bb_var("IMAGE_PKGTYPE") if image_pkgtype != 'rpm': self.skipTest('Not using RPM as main package format') bitbake("-c clean core-image-minimal") self.write_config('INC_RPM_IMAGE_GEN = "1"') self.append_config('IMAGE_FEATURES += "ssh-server-openssh"') bitbake("core-image-minimal") log_data_file = os.path.join(get_bb_var("WORKDIR", "core-image-minimal"), "temp/log.do_rootfs") log_data_created = ftools.read_file(log_data_file) incremental_created = re.search(r"Installing\s*:\s*packagegroup-core-ssh-openssh", log_data_created) self.remove_config('IMAGE_FEATURES += "ssh-server-openssh"') self.assertTrue(incremental_created, msg = "Match failed in:\n%s" % log_data_created) bitbake("core-image-minimal") log_data_removed = ftools.read_file(log_data_file) incremental_removed = re.search(r"Erasing\s*:\s*packagegroup-core-ssh-openssh", log_data_removed) self.assertTrue(incremental_removed, msg = "Match failed in:\n%s" % log_data_removed)
def test_devtool_modify(self): # Check preconditions 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') # Clean up anything in the workdir/sysroot/sstate cache bitbake('mdadm -c cleansstate') # Try modifying a recipe 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 mdadm') result = runCmd('devtool modify mdadm -x %s' % tempdir) self.assertTrue(os.path.exists(os.path.join(tempdir, 'Makefile')), 'Extracted source could not be found') self.assertTrue(os.path.isdir(os.path.join(tempdir, '.git')), 'git repository for external source tree not found') self.assertTrue(os.path.exists(os.path.join(workspacedir, 'conf', 'layer.conf')), 'Workspace directory not created') matches = glob.glob(os.path.join(workspacedir, 'appends', 'mdadm_*.bbappend')) self.assertTrue(matches, 'bbappend not created') # Test devtool status result = runCmd('devtool status') self.assertIn('mdadm', result.output) self.assertIn(tempdir, result.output) # Check git repo result = runCmd('git status --porcelain', cwd=tempdir) self.assertEqual(result.output.strip(), "", 'Created git repo is not clean') result = runCmd('git symbolic-ref HEAD', cwd=tempdir) self.assertEqual(result.output.strip(), "refs/heads/devtool", 'Wrong branch in git repo') # Try building bitbake('mdadm') # Try making (minor) modifications to the source result = runCmd("sed -i 's!^\.TH.*!.TH MDADM 8 \"\" v9.999-custom!' %s" % os.path.join(tempdir, 'mdadm.8.in')) bitbake('mdadm -c package') pkgd = get_bb_var('PKGD', 'mdadm') self.assertTrue(pkgd, 'Could not query PKGD variable') mandir = get_bb_var('mandir', 'mdadm') self.assertTrue(mandir, 'Could not query mandir variable') if mandir[0] == '/': mandir = mandir[1:] with open(os.path.join(pkgd, mandir, 'man8', 'mdadm.8'), 'r') as f: for line in f: if line.startswith('.TH'): self.assertEqual(line.rstrip(), '.TH MDADM 8 "" v9.999-custom', 'man file not modified') # Test devtool reset result = runCmd('devtool reset mdadm') result = runCmd('devtool status') self.assertNotIn('mdadm', result.output)
def test_layer_without_git_dir(self): """ Summary: Test that layer git revisions are displayed and do not fail without git repository Expected: The build to be successful and without "fatal" errors Product: oe-core Author: Daniel Istrate <*****@*****.**> AutomatedBy: Daniel Istrate <*****@*****.**> """ dirpath = tempfile.mkdtemp() dummy_layer_name = 'meta-dummy' dummy_layer_path = os.path.join(dirpath, dummy_layer_name) dummy_layer_conf_dir = os.path.join(dummy_layer_path, 'conf') os.makedirs(dummy_layer_conf_dir) dummy_layer_conf_path = os.path.join(dummy_layer_conf_dir, 'layer.conf') dummy_layer_content = 'BBPATH .= ":${LAYERDIR}"\n' \ 'BBFILES += "${LAYERDIR}/recipes-*/*/*.bb ${LAYERDIR}/recipes-*/*/*.bbappend"\n' \ 'BBFILE_COLLECTIONS += "%s"\n' \ 'BBFILE_PATTERN_%s = "^${LAYERDIR}/"\n' \ 'BBFILE_PRIORITY_%s = "6"\n' % (dummy_layer_name, dummy_layer_name, dummy_layer_name) ftools.write_file(dummy_layer_conf_path, dummy_layer_content) bblayers_conf = 'BBLAYERS += "%s"\n' % dummy_layer_path self.write_bblayers_config(bblayers_conf) test_recipe = 'ed' ret = bitbake('-n %s' % test_recipe) err = 'fatal: Not a git repository' shutil.rmtree(dirpath) self.assertNotIn(err, ret.output)
def setUpLocal(self): """This code is executed before each test method.""" self.distro_features = self.installer_test_vars['DISTRO_FEATURES'].split() self.machine_arch = self.installer_test_vars['MACHINE_ARCH'] self.image_arch = self.machine_arch.replace('_', '-') self.image_dir = self.installer_test_vars['DEPLOY_DIR_IMAGE'] self.resultdir = os.path.join(self.installer_test_vars['TMPDIR'], 'oeselftest', 'image-installer') # Do this here instead of in setUpClass as the base setUp does some # clean up which can result in the native tools built earlier in # setUpClass being unavailable. if not ImageInstaller.image_is_ready: # The tests depend on images done in "development" mode, so set that here # temporarily in a way that it overrides some other IMAGE_MODE setting in local.conf. self.append_config('IMAGE_MODE_forcevariable = "development"') targets = 'refkit-installer-image ovmf swtpm2-wrappers-native' result = bitbake(targets, output_log=self.logger) ImageInstaller.image_is_ready = True # We create the directory under ${TMPDIR} and thus can avoid # deleting it, which is a bit nicer for debugging test failures. rmtree(self.resultdir, ignore_errors=True) bb.utils.mkdirhier(self.resultdir)
def setUpLocal(self): """This code is executed before each test method.""" self.distro_features = get_bb_var('DISTRO_FEATURES').split() self.machine_arch = get_bb_var('MACHINE_ARCH') self.image_arch = self.machine_arch.replace('_', '-') self.image_dir = get_bb_var('DEPLOY_DIR_IMAGE') self.resultdir = os.path.join(get_bb_var('TMPDIR'), 'oeselftest', 'image-installer') # Do this here instead of in setUpClass as the base setUp does some # clean up which can result in the native tools built earlier in # setUpClass being unavailable. if not ImageInstaller.image_is_ready: targets = 'refkit-installer-image ovmf swtpm-wrappers-native' print('Starting: bitbake %s' % targets) result = bitbake(targets) print(result.output) ImageInstaller.image_is_ready = True # We create the directory under ${TMPDIR} and thus can avoid # deleting it, which is a bit nicer for debugging test failures. rmtree(self.resultdir, ignore_errors=True) bb.utils.mkdirhier(self.resultdir)
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 ' ' | egrep -c -e '/dev/sda1 /boot' " \ "-e '/dev/root /|/dev/sda2 /' -e '/dev/sda3 /media' -e '/dev/sda4 /mnt'" status, output = qemu.run_serial(cmd) self.assertEqual(1, status, 'Failed to run command "%s": %s' % (cmd, output)) self.assertEqual(output, '4') 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 test_options_warnqa_errorqa_switch(self): bitbake("xcursor-transparent-theme -ccleansstate") if "packages-list" not in get_bb_var("ERROR_QA"): self.write_config("ERROR_QA_append = \" packages-list\"") self.write_recipeinc('xcursor-transparent-theme', 'PACKAGES += \"${PN}-dbg\"') res = bitbake("xcursor-transparent-theme", ignore_status=True) self.delete_recipeinc('xcursor-transparent-theme') self.assertTrue("ERROR: QA Issue: xcursor-transparent-theme-dbg is listed in PACKAGES multiple times, this leads to packaging errors." in res.output) self.assertEqual(res.status, 1) self.write_recipeinc('xcursor-transparent-theme', 'PACKAGES += \"${PN}-dbg\"') self.append_config('ERROR_QA_remove = "packages-list"') self.append_config('WARN_QA_append = " packages-list"') res = bitbake("xcursor-transparent-theme") bitbake("xcursor-transparent-theme -ccleansstate") self.delete_recipeinc('xcursor-transparent-theme') self.assertTrue("WARNING: QA Issue: xcursor-transparent-theme-dbg is listed in PACKAGES multiple times, this leads to packaging errors." in res.output)
def test_testimage_apt(self): """ Summary: Check package feeds functionality for apt Expected: 1. Check that remote package feeds can be accessed Product: oe-core Author: Ferry Toth <*****@*****.**> """ if get_bb_var('DISTRO') == 'poky-tiny': self.skipTest( 'core-image-full-cmdline not buildable for poky-tiny') features = 'INHERIT += "testimage"\n' features += 'TEST_SUITES = "ping ssh apt.AptRepoTest.test_apt_install_from_repo"\n' # We don't yet know what the server ip and port will be - they will be patched # in at the start of the on-image test features += 'PACKAGE_FEED_URIS = "http://bogus_ip:bogus_port"\n' features += 'EXTRA_IMAGE_FEATURES += "package-management"\n' features += 'PACKAGE_CLASSES = "package_deb"\n' # We need gnupg on the target to install keys features += 'IMAGE_INSTALL:append:pn-core-image-full-cmdline = " gnupg"\n' bitbake('gnupg-native -c addto_recipe_sysroot') # Enable package feed signing self.gpg_home = tempfile.mkdtemp(prefix="oeqa-feed-sign-") self.track_for_cleanup(self.gpg_home) signing_key_dir = os.path.join(self.testlayer_path, 'files', 'signing') runCmd( 'gpgconf --list-dirs --homedir %s; gpg -v --batch --homedir %s --import %s' % (self.gpg_home, self.gpg_home, os.path.join(signing_key_dir, 'key.secret')), native_sysroot=get_bb_var("RECIPE_SYSROOT_NATIVE", "gnupg-native"), shell=True) features += 'INHERIT += "sign_package_feed"\n' features += 'PACKAGE_FEED_GPG_NAME = "testuser"\n' features += 'PACKAGE_FEED_GPG_PASSPHRASE_FILE = "%s"\n' % os.path.join( signing_key_dir, 'key.passphrase') features += 'GPG_PATH = "%s"\n' % self.gpg_home features += 'PSEUDO_IGNORE_PATHS .= ",%s"\n' % self.gpg_home self.write_config(features) # Build core-image-sato and testimage bitbake('core-image-full-cmdline socat') bitbake('-c testimage core-image-full-cmdline')
def test_force_task_1(self): # test 1 from bug 5875 test_recipe = 'zlib' test_data = "Microsoft Made No Profit From Anyone's Zunes Yo" image_dir = get_bb_var('D', test_recipe) pkgsplit_dir = get_bb_var('PKGDEST', test_recipe) man_dir = get_bb_var('mandir', test_recipe) bitbake('-c cleansstate %s' % test_recipe) bitbake(test_recipe) self.add_command_to_tearDown('bitbake -c clean %s' % test_recipe) man_file = os.path.join(image_dir + man_dir, 'man3/zlib.3') ftools.append_file(man_file, test_data) bitbake('-c package -f %s' % test_recipe) man_split_file = os.path.join(pkgsplit_dir, 'zlib-doc' + man_dir, 'man3/zlib.3') man_split_content = ftools.read_file(man_split_file) self.assertIn(test_data, man_split_content, 'The man file has not changed in packages-split.') ret = bitbake(test_recipe) self.assertIn('task do_package_write_rpm:', ret.output, 'Task do_package_write_rpm did not re-executed.')
def test_biosplusefi_plugin(self): """Test biosplusefi plugin""" # Wic generation below may fail depending on the order of the unittests # This is because bootimg-pcbios (that bootimg-biosplusefi uses) generate its MBR inside STAGING_DATADIR directory # which may or may not exists depending on what was built already # If an image hasn't been built yet, directory ${STAGING_DATADIR}/syslinux won't exists and _get_bootimg_dir() # will raise with "Couldn't find correct bootimg_dir" # The easiest way to work-around this issue is to make sure we already built an image here, hence the bitbake call 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) img = 'core-image-minimal' with NamedTemporaryFile("w", suffix=".wks") as wks: wks.writelines(['part /boot --active --source bootimg-biosplusefi --sourceparams="loader=grub-efi"\n', 'part / --source rootfs --fstype=ext4 --align 1024 --use-uuid\n'\ 'bootloader --timeout=0 --append="console=ttyS0,115200n8"\n']) wks.flush() cmd = "wic create %s -e %s -o %s" % (wks.name, img, self.resultdir) runCmd(cmd) wksname = os.path.splitext(os.path.basename(wks.name))[0] out = glob(self.resultdir + "%s-*.direct" % wksname) self.assertEqual(1, len(out))
def test_layer_appends(self): corebase = get_bb_var("COREBASE") for l in ["0", "1", "2"]: layer = os.path.join(corebase, "meta-layertest" + l) self.assertFalse(os.path.exists(layer)) os.mkdir(layer) os.mkdir(layer + "/conf") with open(layer + "/conf/layer.conf", "w") as f: f.write(self.layerconf.replace("INT", l)) os.mkdir(layer + "/recipes-test") if l == "0": with open(layer + "/recipes-test/layerappendtest.bb", "w") as f: f.write(self.recipe) elif l == "1": with open(layer + "/recipes-test/layerappendtest.bbappend", "w") as f: f.write(self.append) os.mkdir(layer + "/recipes-test/layerappendtest") with open(layer + "/recipes-test/layerappendtest/appendtest.txt", "w") as f: f.write("Layer 1 test") elif l == "2": with open(layer + "/recipes-test/layerappendtest.bbappend", "w") as f: f.write(self.append2) os.mkdir(layer + "/recipes-test/layerappendtest") with open(layer + "/recipes-test/layerappendtest/appendtest.txt", "w") as f: f.write("Layer 2 test") self.track_for_cleanup(layer) self.layerappend = "BBLAYERS += \"{0}/meta-layertest0 {0}/meta-layertest1 {0}/meta-layertest2\"".format(corebase) ftools.append_file(self.builddir + "/conf/bblayers.conf", self.layerappend) stagingdir = get_bb_var("SYSROOT_DESTDIR", "layerappendtest") bitbake("layerappendtest") data = ftools.read_file(stagingdir + "/appendtest.txt") self.assertEqual(data, "Layer 2 test") os.remove(corebase + "/meta-layertest2/recipes-test/layerappendtest/appendtest.txt") bitbake("layerappendtest") data = ftools.read_file(stagingdir + "/appendtest.txt") self.assertEqual(data, "Layer 1 test") with open(corebase + "/meta-layertest2/recipes-test/layerappendtest/appendtest.txt", "w") as f: f.write("Layer 2 test") bitbake("layerappendtest") data = ftools.read_file(stagingdir + "/appendtest.txt") self.assertEqual(data, "Layer 2 test")
def test_ccache_tool(self): bitbake("ccache-native") bb_vars = get_bb_vars(['SYSROOT_DESTDIR', 'bindir'], 'ccache-native') p = bb_vars['SYSROOT_DESTDIR'] + bb_vars['bindir'] + "/" + "ccache" self.assertTrue(os.path.isfile(p), msg="No ccache found (%s)" % p) self.write_config('INHERIT += "ccache"') self.add_command_to_tearDown('bitbake -c clean m4-native') bitbake("m4-native -c clean") bitbake("m4-native -f -c compile") log_compile = os.path.join(get_bb_var("WORKDIR", "m4-native"), "temp/log.do_compile") with open(log_compile, "r") as f: loglines = "".join(f.readlines()) self.assertIn( "ccache", loglines, msg= "No match for ccache in m4-native log.do_compile. For further details: %s" % log_compile)
def test_ccache_tool(self): bitbake("ccache-native") p = get_bb_var('SYSROOT_DESTDIR', 'ccache-native') + get_bb_var( 'bindir', 'ccache-native') + "/" + "ccache" self.assertTrue(os.path.isfile(p), msg="No ccache found (%s)" % p) self.write_config('INHERIT += "ccache"') bitbake("m4 -c cleansstate") bitbake("m4 -c compile") self.addCleanup(bitbake, 'ccache-native -ccleansstate') res = runCmd( "grep ccache %s" % (os.path.join(get_bb_var("WORKDIR", "m4"), "temp/log.do_compile")), ignore_status=True) self.assertEqual( 0, res.status, msg= "No match for ccache in m4 log.do_compile. For further details: %s" % os.path.join(get_bb_var("WORKDIR", "m4"), "temp/log.do_compile"))
def test_reproducible_builds(self): capture_vars = ['DEPLOY_DIR_' + c.upper() for c in self.package_classes] common_config = textwrap.dedent('''\ INHERIT += "reproducible_build" PACKAGE_CLASSES = "%s" ''') % (' '.join('package_%s' % c for c in self.package_classes)) # Do an initial build. It's acceptable for this build to use sstate self.write_config(common_config) vars_reference = get_bb_vars(capture_vars) bitbake(' '.join(self.images)) # Build native utilities bitbake("diffutils-native -c addto_recipe_sysroot") diffutils_sysroot = get_bb_var("RECIPE_SYSROOT_NATIVE", "diffutils-native") # Perform another build. This build should *not* share sstate or pull # from any mirrors, but sharing a DL_DIR is fine self.write_config(textwrap.dedent('''\ TMPDIR = "${TOPDIR}/reproducible/tmp" SSTATE_DIR = "${TMPDIR}/sstate" SSTATE_MIRROR = "" ''') + common_config) vars_test = get_bb_vars(capture_vars) bitbake(' '.join(self.images)) for c in self.package_classes: package_class = 'package_' + c deploy_reference = vars_reference['DEPLOY_DIR_' + c.upper()] deploy_test = vars_test['DEPLOY_DIR_' + c.upper()] result = self.compare_packages(deploy_reference, deploy_test, diffutils_sysroot) self.logger.info('Reproducibility summary for %s: %s' % (c, result)) self.append_to_log('\n'.join("%s: %s" % (r.status, r.test) for r in result.total)) if result.missing or result.different: self.fail("The following %s packages are missing or different: %s" % (c, ' '.join(r.test for r in (result.missing + result.different))))
def test_git_mirrors(self): """ Verify that the git fetcher will fall back to the HTTP mirrors. The recipe needs to be one that we have on the Yocto Project source mirror and is hosted in git. """ # TODO: mktempd instead of hardcoding dldir = os.path.join(self.builddir, "download-git-mirrors") self.track_for_cleanup(dldir) # No mirrors, should use git to fetch successfully features = """ DL_DIR = "%s" MIRRORS_forcevariable = "" PREMIRRORS_forcevariable = "" """ % dldir self.write_config(features) oe.path.remove(dldir, recurse=True) bitbake("dbus-wait -c fetch -f") # No mirrors and broken git, should fail features = """ DL_DIR = "%s" GIT_PROXY_COMMAND = "false" MIRRORS_forcevariable = "" PREMIRRORS_forcevariable = "" """ % dldir self.write_config(features) oe.path.remove(dldir, recurse=True) with self.assertRaises(AssertionError): bitbake("dbus-wait -c fetch -f") # Broken git but a specific mirror features = """ DL_DIR = "%s" GIT_PROXY_COMMAND = "false" MIRRORS_forcevariable = "git://.*/.* http://downloads.yoctoproject.org/mirror/sources/" """ % dldir self.write_config(features) oe.path.remove(dldir, recurse=True) bitbake("dbus-wait -c fetch -f")
def test_options_warnqa_errorqa_switch(self): bitbake("xcursor-transparent-theme -ccleansstate") if "packages-list" not in get_bb_var("ERROR_QA"): self.write_config("ERROR_QA_append = \" packages-list\"") self.write_recipeinc('xcursor-transparent-theme', 'PACKAGES += \"${PN}-dbg\"') res = bitbake("xcursor-transparent-theme", ignore_status=True) self.delete_recipeinc('xcursor-transparent-theme') line = self.getline(res, "QA Issue: xcursor-transparent-theme-dbg is listed in PACKAGES multiple times, this leads to packaging errors.") self.assertTrue(line and line.startswith("ERROR:"), msg=res.output) self.assertEqual(res.status, 1, msg = "bitbake reported exit code %s. It should have been 1. Bitbake output: %s" % (str(res.status), res.output)) self.write_recipeinc('xcursor-transparent-theme', 'PACKAGES += \"${PN}-dbg\"') self.append_config('ERROR_QA_remove = "packages-list"') self.append_config('WARN_QA_append = " packages-list"') bitbake("xcursor-transparent-theme -ccleansstate") res = bitbake("xcursor-transparent-theme") self.delete_recipeinc('xcursor-transparent-theme') line = self.getline(res, "QA Issue: xcursor-transparent-theme-dbg is listed in PACKAGES multiple times, this leads to packaging errors.") self.assertTrue(line and line.startswith("WARNING:"), msg=res.output)
def test_testimage_dnf(self): """ Summary: Check package feeds functionality for dnf Expected: 1. Check that remote package feeds can be accessed Product: oe-core Author: Alexander Kanavin <*****@*****.**> """ if get_bb_var('DISTRO') == 'poky-tiny': self.skipTest( 'core-image-full-cmdline not buildable for poky-tiny') features = 'INHERIT += "testimage"\n' features += 'TEST_SUITES = "ping ssh dnf_runtime dnf.DnfBasicTest.test_dnf_help"\n' # We don't yet know what the server ip and port will be - they will be patched # in at the start of the on-image test features += 'PACKAGE_FEED_URIS = "http://bogus_ip:bogus_port"\n' features += 'EXTRA_IMAGE_FEATURES += "package-management"\n' features += 'PACKAGE_CLASSES = "package_rpm"\n' bitbake('gnupg-native -c addto_recipe_sysroot') # Enable package feed signing self.gpg_home = tempfile.mkdtemp(prefix="oeqa-feed-sign-") signing_key_dir = os.path.join(self.testlayer_path, 'files', 'signing') runCmd('gpg --batch --homedir %s --import %s' % (self.gpg_home, os.path.join(signing_key_dir, 'key.secret')), native_sysroot=get_bb_var("RECIPE_SYSROOT_NATIVE", "gnupg-native")) features += 'INHERIT += "sign_package_feed"\n' features += 'PACKAGE_FEED_GPG_NAME = "testuser"\n' features += 'PACKAGE_FEED_GPG_PASSPHRASE_FILE = "%s"\n' % os.path.join( signing_key_dir, 'key.passphrase') features += 'GPG_PATH = "%s"\n' % self.gpg_home self.write_config(features) # Build core-image-sato and testimage bitbake('core-image-full-cmdline socat') bitbake('-c testimage core-image-full-cmdline') # remove the oeqa-feed-sign temporal directory shutil.rmtree(self.gpg_home, ignore_errors=True)