Beispiel #1
0
 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')
Beispiel #2
0
    def test_sstate_allarch_samesigs(self):
        """
        The sstate checksums off allarch packages should be independent of whichever 
        MACHINE is set. Check this using bitbake -S.
        """

        topdir = get_bb_var('TOPDIR')
        targetos = get_bb_var('TARGET_OS')
        targetvendor = get_bb_var('TARGET_VENDOR')
        self.write_config("""
TMPDIR = \"${TOPDIR}/tmp-sstatesamehash\"
MACHINE = \"qemux86\"
""")
        self.track_for_cleanup(topdir + "/tmp-sstatesamehash")
        bitbake("world -S none")
        self.write_config("""
TMPDIR = \"${TOPDIR}/tmp-sstatesamehash2\"
MACHINE = \"qemuarm\"
""")
        self.track_for_cleanup(topdir + "/tmp-sstatesamehash2")
        bitbake("world -S none")

        def get_files(d):
            f = []
            for root, dirs, files in os.walk(d):
                for name in files:
                    if "do_build" not in name:
                        f.append(os.path.join(root, name))
            return f
        files1 = get_files(topdir + "/tmp-sstatesamehash/stamps/all" + targetvendor + "-" + targetos)
        files2 = get_files(topdir + "/tmp-sstatesamehash2/stamps/all" + targetvendor + "-" + targetos)
        files2 = [x.replace("tmp-sstatesamehash2", "tmp-sstatesamehash") for x in files2]
        self.maxDiff = None
        self.assertItemsEqual(files1, files2)
    def test_kernel_add_dts(self):
        testrecipe = 'virtual/kernel'
        srcdir = get_bb_var('S', testrecipe)
        workdir = get_bb_var('WORKDIR', testrecipe)
        if srcdir == get_bb_var('STAGING_KERNEL_DIR', testrecipe):
            # If S is directly set to STAGING_KERNEL_DIR, then we most likely
            # have a custom checkout or unpack process like linux-yocto, so we
            # don't know precisely where to place the files relative to
            # WORKDIR. We default to 'git' in this case.
            subdir = 'git'
        else:
            subdir = os.path.relpath(srcdir, workdir)
        arch = get_bb_var('ARCH', testrecipe)
        destdir = '%s/arch/%s/boot/dts' % (subdir, arch)

        expected_file_info = {
            os.path.basename(self.testfile): destdir,
            'testfile2': destdir,
        }

        testfile2 = os.path.join(self.tempdir, 'testfile2')
        with open(testfile2, 'w') as f:
            f.write('Test File 2')

        cmd = 'recipetool kernel_add_dts %s %s %s' % (self.templayerdir, self.testfile, testfile2)
        self._test_kernel_cmd(cmd, testrecipe, expected_file_info)

        devtree = get_bb_var('KERNEL_DEVICETREE', testrecipe)
        if not devtree:
            self.fail('KERNEL_DEVICETREE not defined')
        devtree = devtree.split()

        for f in expected_file_info:
            self.assertIn(f.replace('dts', 'dtb'), devtree)
Beispiel #4
0
    def sstate_allarch_samesigs(self, configA, configB):

        topdir = get_bb_var('TOPDIR')
        targetos = get_bb_var('TARGET_OS')
        targetvendor = get_bb_var('TARGET_VENDOR')
        self.write_config(configA)
        self.track_for_cleanup(topdir + "/tmp-sstatesamehash")
        bitbake("world meta-toolchain -S none")
        self.write_config(configB)
        self.track_for_cleanup(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
        files1 = get_files(topdir + "/tmp-sstatesamehash/stamps/all" + targetvendor + "-" + targetos)
        files2 = get_files(topdir + "/tmp-sstatesamehash2/stamps/all" + targetvendor + "-" + targetos)
        self.maxDiff = None
        self.assertEqual(files1, files2)

        nativesdkdir = os.path.basename(glob.glob(topdir + "/tmp-sstatesamehash/stamps/*-nativesdk*-linux")[0])

        files1 = get_files(topdir + "/tmp-sstatesamehash/stamps/" + nativesdkdir)
        files2 = get_files(topdir + "/tmp-sstatesamehash2/stamps/" + nativesdkdir)
        self.maxDiff = None
        self.assertEqual(files1, files2)
Beispiel #5
0
 def test_devtool_reset_all(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')
     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')
     testrecipe1 = 'mdadm'
     testrecipe2 = 'cronie'
     result = runCmd('devtool modify -x %s %s' % (testrecipe1, os.path.join(tempdir, testrecipe1)))
     result = runCmd('devtool modify -x %s %s' % (testrecipe2, os.path.join(tempdir, testrecipe2)))
     result = runCmd('devtool build %s' % testrecipe1)
     result = runCmd('devtool build %s' % testrecipe2)
     stampprefix1 = get_bb_var('STAMP', testrecipe1)
     self.assertTrue(stampprefix1, 'Unable to get STAMP value for recipe %s' % testrecipe1)
     stampprefix2 = get_bb_var('STAMP', testrecipe2)
     self.assertTrue(stampprefix2, 'Unable to get STAMP value for recipe %s' % testrecipe2)
     result = runCmd('devtool reset -a')
     self.assertIn(testrecipe1, result.output)
     self.assertIn(testrecipe2, result.output)
     result = runCmd('devtool status')
     self.assertNotIn(testrecipe1, result.output)
     self.assertNotIn(testrecipe2, result.output)
     matches1 = glob.glob(stampprefix1 + '*')
     self.assertFalse(matches1, 'Stamp files exist for recipe %s that should have been cleaned' % testrecipe1)
     matches2 = glob.glob(stampprefix2 + '*')
     self.assertFalse(matches2, 'Stamp files exist for recipe %s that should have been cleaned' % testrecipe2)
    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 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 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_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))
Beispiel #10
0
    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)

        shutil.rmtree(get_bb_var('TMPDIR'))
        bitbake("%s %s" % (include_recipe, exclude_recipe))

        src_path = os.path.join(get_bb_var('DEPLOY_DIR_SRC'), get_bb_var('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_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)
Beispiel #12
0
    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 <*****@*****.**>
        """
        tmp_dir = get_bb_var('TMPDIR')
        testloc = oe.path.join(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")

        destdir = get_bb_var('SYSROOT_DESTDIR', 'attr-native')
        bindir = get_bb_var('bindir', 'attr-native')
        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)
Beispiel #13
0
    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)
Beispiel #14
0
    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')
        targetvendor = get_bb_var('TARGET_VENDOR')
        self.write_config("""
TMPDIR = \"${TOPDIR}/tmp-sstatesamehash\"
NATIVELSBSTRING = \"DistroA\"
""")
        self.track_for_cleanup(topdir + "/tmp-sstatesamehash")
        bitbake("core-image-sato -S printdiff", ignore_status=True)
        self.write_config("""
TMPDIR = \"${TOPDIR}/tmp-sstatesamehash2\"
NATIVELSBSTRING = \"DistroB\"
""")
        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") for x in files2]
        self.assertItemsEqual(files1, files2)
Beispiel #15
0
    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_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"'
        self.write_config(features)

        image_name = "core-image-minimal"
        bitbake(image_name)

        deploy_dir = get_bb_var("DEPLOY_DIR_IMAGE")
        link_name = get_bb_var("IMAGE_LINK_NAME", image_name)
        image_path = os.path.join(deploy_dir, "%s.ext4" % link_name)
        bmap_path = "%s.bmap" % image_path

        # check if result image and bmap file are in deploy directory
        self.assertTrue(os.path.exists(image_path))
        self.assertTrue(os.path.exists(bmap_path))

        # check if result image is sparse
        image_stat = os.stat(image_path)
        self.assertTrue(image_stat.st_size > image_stat.st_blocks * 512)
Beispiel #17
0
    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)
Beispiel #18
0
 def test_rm_old_image(self):
     bitbake("core-image-minimal")
     deploydir = get_bb_var("DEPLOY_DIR_IMAGE", target="core-image-minimal")
     imagename = get_bb_var("IMAGE_LINK_NAME", target="core-image-minimal")
     oldimgpath = os.path.realpath(os.path.join(deploydir, imagename + ".ext3"))
     self.append_config("RM_OLD_IMAGE = \"1\"")
     bitbake("core-image-minimal")
     self.assertFalse(os.path.exists(oldimgpath), msg="Old image path still exists: %s" % oldimgpath)
Beispiel #19
0
 def test_ccache_tool(self):
     bitbake("ccache-native")
     self.assertTrue(os.path.isfile(os.path.join(get_bb_var('STAGING_BINDIR_NATIVE', 'ccache-native'), "ccache")))
     self.write_config('INHERIT += "ccache"')
     bitbake("m4 -c cleansstate")
     bitbake("m4 -c compile")
     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")
     bitbake("ccache-native -ccleansstate")
Beispiel #20
0
 def setUpClass(cls):
     super(QemuTest, cls).setUpClass()
     cls.recipe = 'core-image-minimal'
     cls.machine =  get_bb_var('MACHINE')
     cls.deploy_dir_image =  get_bb_var('DEPLOY_DIR_IMAGE')
     cls.cmd_common = "runqemu nographic"
     cls.qemuboot_conf = "%s-%s.qemuboot.conf" % (cls.recipe, cls.machine)
     cls.qemuboot_conf = os.path.join(cls.deploy_dir_image, cls.qemuboot_conf)
     bitbake(cls.recipe)
Beispiel #21
0
 def test_rename_downloaded_file(self):
     data = 'SRC_URI_append = ";downloadfilename=test-aspell.tar.gz"'
     self.write_recipeinc('aspell', data)
     bitbake('-ccleanall aspell')
     result = bitbake('-c fetch aspell', ignore_status=True)
     self.delete_recipeinc('aspell')
     self.assertEqual(result.status, 0)
     self.assertTrue(os.path.isfile(os.path.join(get_bb_var("DL_DIR"), 'test-aspell.tar.gz')))
     self.assertTrue(os.path.isfile(os.path.join(get_bb_var("DL_DIR"), 'test-aspell.tar.gz.done')))
     bitbake('-ccleanall aspell')
Beispiel #22
0
 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_recipetool_appendsrcfile_replace_file_srcdir(self):
        testrecipe = "bash"
        filepath = "Makefile.in"
        srcdir = get_bb_var("S", testrecipe)
        workdir = get_bb_var("WORKDIR", testrecipe)
        subdir = os.path.relpath(srcdir, workdir)

        self._test_appendsrcfile(testrecipe, filepath, srcdir=subdir)
        bitbake("%s:do_unpack" % testrecipe)
        self.assertEqual(open(self.testfile, "r").read(), open(os.path.join(srcdir, filepath), "r").read())
    def test_recipetool_appendsrcfile_replace_file_srcdir(self):
        testrecipe = 'bash'
        filepath = 'Makefile.in'
        srcdir = get_bb_var('S', testrecipe)
        workdir = get_bb_var('WORKDIR', testrecipe)
        subdir = os.path.relpath(srcdir, workdir)

        self._test_appendsrcfile(testrecipe, filepath, srcdir=subdir)
        bitbake('%s:do_unpack' % testrecipe)
        self.assertEqual(open(self.testfile, 'r').read(), open(os.path.join(srcdir, filepath), 'r').read())
Beispiel #25
0
 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')
     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')
     import pexpect
     # Definitions
     testrecipe = 'mdadm'
     testfile = '/sbin/mdadm'
     testimage = 'oe-selftest-image'
     testhost = '192.168.7.2'
     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@%s' % (testrecipe, testhost), 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@%s' % (testrecipe, testhost))
     self.assertIn('  %s' % testfile, result.output)
     # Boot the image
     console = pexpect.spawn('runqemu %s %s qemuparams="-snapshot" nographic' % (machine, testimage))
     console.expect("login:", timeout=120)
     # Now really test deploy-target
     result = runCmd('devtool deploy-target -c %s root@%s' % (testrecipe, testhost))
     result = runCmd('ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no root@%s %s' % (testhost, testcommand))
     # Test undeploy-target
     result = runCmd('devtool undeploy-target -c %s root@%s' % (testrecipe, testhost))
     result = runCmd('ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no root@%s %s' % (testhost, testcommand), ignore_status=True)
     self.assertNotEqual(result, 0, 'undeploy-target did not remove command as it should have')
     console.close()
Beispiel #26
0
 def test_incremental_image_generation(self):
     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")
     res = runCmd("grep 'Installing openssh-sshd' %s" % (os.path.join(get_bb_var("WORKDIR", "core-image-minimal"), "temp/log.do_rootfs")), ignore_status=True)
     self.remove_config('IMAGE_FEATURES += "ssh-server-openssh"')
     self.assertEqual(0, res.status, msg="No match for openssh-sshd in log.do_rootfs")
     bitbake("core-image-minimal")
     res = runCmd("grep 'Removing openssh-sshd' %s" %(os.path.join(get_bb_var("WORKDIR", "core-image-minimal"), "temp/log.do_rootfs")),ignore_status=True)
     self.assertEqual(0, res.status, msg="openssh-sshd was not removed from image")
Beispiel #27
0
    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.

        Also check that SDKMACHINE and PARALLEL_MAKE changing doesn't change any
        of these stamps.
        """

        topdir = get_bb_var('TOPDIR')
        targetvendor = get_bb_var('TARGET_VENDOR')
        self.write_config("""
MACHINE = "qemux86"
TMPDIR = "${TOPDIR}/tmp-sstatesamehash"
BUILD_ARCH = "x86_64"
BUILD_OS = "linux"
SDKMACHINE = "x86_64"
PARALLEL_MAKE = "-j 1"
DL_DIR = "${TOPDIR}/download1"
TIME = "111111"
""")
        self.track_for_cleanup(topdir + "/tmp-sstatesamehash")
        bitbake("core-image-sato -S none")
        self.write_config("""
MACHINE = "qemux86"
TMPDIR = "${TOPDIR}/tmp-sstatesamehash2"
BUILD_ARCH = "i686"
BUILD_OS = "linux"
SDKMACHINE = "i686"
PARALLEL_MAKE = "-j 2"
DL_DIR = "${TOPDIR}/download2"
TIME = "222222"
""")
        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):
                if "core-image-sato" in root:
                    # SDKMACHINE changing will change
                    # do_rootfs/do_testimage/do_build stamps of images which
                    # is safe to ignore.
                    continue
                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.maxDiff = None
        self.assertItemsEqual(files1, files2)
Beispiel #28
0
    def setup_gpg(self):
        bitbake('gnupg-native -c addto_recipe_sysroot')

        self.gpg_dir = tempfile.mkdtemp(prefix="oeqa-signing-")
        self.track_for_cleanup(self.gpg_dir)

        self.pub_key_path = os.path.join(self.testlayer_path, 'files', 'signing', "key.pub")
        self.secret_key_path = os.path.join(self.testlayer_path, 'files', 'signing', "key.secret")

        nsysroot = get_bb_var("RECIPE_SYSROOT_NATIVE", "gnupg-native")
        runCmd('gpg --batch --homedir %s --import %s %s' % (self.gpg_dir, self.pub_key_path, self.secret_key_path), native_sysroot=nsysroot)
        return nsysroot + get_bb_var("bindir_native")
Beispiel #29
0
Datei: wic.py Projekt: kacf/poky
 def test_build_artifacts(self):
     """Test wic create directdisk providing all artifacts."""
     bbvars = dict((var.lower(), get_bb_var(var, 'core-image-minimal'))
                   for var in ('STAGING_DATADIR', 'DEPLOY_DIR_IMAGE', 'IMAGE_ROOTFS'))
     bbvars['recipe_sysroot_native'] = get_bb_var('RECIPE_SYSROOT_NATIVE', 'wic-tools')
     status = runCmd("wic create directdisk "
                     "-b %(staging_datadir)s "
                     "-k %(deploy_dir_image)s "
                     "-n %(recipe_sysroot_native)s "
                     "-r %(image_rootfs)s" % bbvars).status
     self.assertEqual(0, status)
     self.assertEqual(1, len(glob(self.resultdir + "directdisk-*.direct")))
Beispiel #30
0
    def test_wic_image_type(self):
        """Test building wic images by bitbake"""
        self.assertEqual(0, bitbake('wic-image-minimal').status)

        deploy_dir = get_bb_var('DEPLOY_DIR_IMAGE')
        machine = get_bb_var('MACHINE')
        prefix = os.path.join(deploy_dir, 'wic-image-minimal-%s.' % machine)
        # check if we have result image and manifests symlinks
        # pointing to existing files
        for suffix in ('wic', 'manifest'):
            path = prefix + suffix
            self.assertTrue(os.path.islink(path))
            self.assertTrue(os.path.isfile(os.path.realpath(path)))
    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 = 'MACHINE = "qemux86"\n'
        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"'
        self.write_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)
Beispiel #32
0
    def test_sstate_samesigs(self):
        """
        The sstate checksums off allarch packages should be independent of whichever 
        MACHINE is set. Check this using bitbake -S.
        Also, rather than duplicate the test, check nativesdk stamps are the same between
        the two MACHINE values.
        Also, when building for multiple machines which share tune flag specific packages,
        those packages also need to have identical signatures.
        Based on oeqa.selftest.sstatetests.SStateTests.test_sstate_allarch_samesigs and
        extended to cover all Ostro OS machines.
        """

        topdir = get_bb_var('TOPDIR')
        targetos = get_bb_var('TARGET_OS')
        targetvendor = get_bb_var('TARGET_VENDOR')
        libcappend = get_bb_var('TCLIBCAPPEND')
        # Select subset of the machines to speed up testing.
        # Edison/intel-core2-32 are particularly sensitive.
        machines = "edison intel-quark intel-core2-32 intel-corei7-64 beaglebone".split(
        )
        # machines = "edison intel-core2-32".split()
        first = machines[0]
        workdir = os.getcwd()
        try:
            pending = []
            for machine in machines:
                builddir = '%s/build-%s' % (topdir, machine)
                os.mkdir(builddir)
                self.track_for_cleanup(builddir)
                os.chdir(builddir)
                shutil.copytree('../conf', 'conf')
                ftools.write_file(
                    'conf/selftest.inc', """
TMPDIR = \"%s/tmp-sstatesamehash-%s\"
MACHINE = \"%s\"
""" % (topdir, machine, machine))
                # Comment out to debug with bitbake-diffstat after running the test.
                # In that case, remember to "rm -r tmp-*" before the next run.
                self.track_for_cleanup(topdir + "/tmp-sstatesamehash-%s%s" %
                                       (machine, libcappend))
                # Replace build targets with individual recipes to investigate just those.
                pending.append(
                    (machine,
                     subprocess.Popen(
                         'bitbake world meta-toolchain -S none'.split(),
                         stdout=open('%s/bitbake.log' % builddir, 'w'),
                         stderr=subprocess.STDOUT)))
            for machine, p in pending:
                returncode = p.wait()
                if returncode:
                    raise AssertionError(
                        "bitbake failed for machine %s with return code %d:\n%s"
                        % (machine, returncode,
                           open('%s/build-%s/bitbake.log' %
                                (topdir, machine)).read()))
        finally:
            os.chdir(workdir)

        def get_hashes(d, subdir):
            f = {}
            for root, dirs, files in os.walk(os.path.join(d, subdir)):
                for name in files:
                    # meta-toolchain depends on cross-canadian.
                    # Not sure about adt-installer. Hash is different, but bitbake-diffstat
                    # shows no difference.
                    # do_deploy is allowed to differ, it just as a performance impact because of
                    # unnecessary rebuilding (minor in our case, not many recipes hit this).
                    if "meta-environment" in root or "cross-canadian" in root or \
                       "do_populate_adt" in name and "adt-installer" in root or \
                       "do_populate_sdk" in name and "meta-toolchain" in root or \
                       "do_build" in name or \
                       "do_deploy" in name:
                        continue
                    components = name.split('.sigdata.')
                    # Map from 'all-ostro-linux/1_1.04-r4.do_build' to '95c22ae3e1c81cdc116db37b68db10be'.
                    # All tasks that are shared by different machines must have the same hash.
                    f[os.path.join(os.path.relpath(root, d),
                                   components[0])] = ''.join(components[1:])
            return f

        # Will be found when building meta-toolchain, otherwise it won't.
        nativesdkdir = glob.glob(
            topdir + ("/tmp-sstatesamehash-%s%s/stamps/*-nativesdk*-linux" %
                      (first, libcappend)))
        if nativesdkdir:
            nativesdkdir = os.path.basename(nativesdkdir[0])
        hashes = {}
        tasks = set()
        for machine in machines:
            hashes[machine] = {}
            # Only some some packages are expected to have the same signature.
            subdirs = [
                "all" + targetvendor + "-" + targetos,  # allarch
                "core2-32" + targetvendor + "-" +
                targetos,  # shared between edison and intel-core2-32
            ]
            if nativesdkdir:
                subdirs.append(nativesdkdir)
            for subdir in subdirs:
                hashes[machine].update(
                    get_hashes(
                        topdir + ("/tmp-sstatesamehash-%s%s/stamps" %
                                  (machine, libcappend)), subdir))
            tasks.update(hashes[machine].keys())
        errors = ['Machines have different hashes:']
        analysis = []
        tasks = list(tasks)
        tasks.sort()
        for task in tasks:
            # Find all machines sharing the same value.
            values = {}
            for machine in machines:
                value = hashes[machine].get(task, None)
                if value:
                    values.setdefault(value, []).append(machine)
            values = sorted(values.items())
            if len(values) > 1:
                errors.append(
                    'Not the same hash for ' + task + ': ' +
                    ' '.join(['/'.join(m) + '=' + v for v, m in values]))
                # Pick the initial two values and the first machine in each where
                # the task differed and compare the signatures.
                cmd = "set -x; bitbake-diffsigs tmp-sstatesamehash-*%s*/stamps/*%s.* tmp-sstatesamehash-*%s*/stamps/*%s.*" % \
                (values[0][1][0], task,
                 values[1][1][0], task)
                p = subprocess.Popen(cmd,
                                     shell=True,
                                     stdout=subprocess.PIPE,
                                     stderr=subprocess.STDOUT)
                stdout, stderr = p.communicate()
                analysis.append(stdout.decode("utf-8"))
        if len(errors) > 1:
            # If this fails, it often fails for a whole range of tasks where one depends on
            # the other. In this example, only the original source file was different:
            #
            # AssertionError: False is not true : Machines have different hashes:
            # Not the same hash for all-poky-linux/initramfs-boot/1.0-r2.do_compile: intel-core2-32=1efd21ed2f11a4a2aef1ade99e0ae523 edison=d4aa4f356187f0902cd5b9e1fed250c4
            # ...
            # Not the same hash for all-ostro-linux/initramfs-boot/1.0-r2.do_fetch: edison=82a397e985e2c570714ab7dfa3e21a6c intel-core2-32=79b455328b0b298423cf52582cc12c7c
            # ...
            self.assertTrue(False,
                            msg='\n'.join(errors) + '\n\n' +
                            '\n\n'.join(analysis))
Beispiel #33
0
 def check_skip(self, suite):
     targets = get_bb_var("RUNTIMETARGET", "gcc-runtime").split()
     if suite not in targets:
         self.skipTest("Target does not use {0}".format(suite))
    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')
Beispiel #35
0
 def test_sstate_creation_distro_specific_fail(self):
     targetarch = get_bb_var('TUNE_ARCH')
     self.run_test_sstate_creation(['binutils-cross-'+ targetarch, 'binutils-native'], distro_specific=False, distro_nonspecific=True, temp_sstate_location=True, should_pass=False)
Beispiel #36
0
 def test_rebuild_distro_specific_sstate_cross_target(self):
     targetarch = get_bb_var('TUNE_ARCH')
     self.run_test_rebuild_distro_specific_sstate(['binutils-cross-' + targetarch], temp_sstate_location=True)
Beispiel #37
0
    def test_signing_packages(self):
        """
        Summary:     Test that packages can be signed in the package feed
        Expected:    Package should be signed with the correct key
        Expected:    Images can be created from signed packages
        Product:     oe-core
        Author:      Daniel Istrate <*****@*****.**>
        Author:      Alexander Kanavin <*****@*****.**>
        AutomatedBy: Daniel Istrate <*****@*****.**>
        """
        import oe.packagedata

        self.setup_gpg()

        package_classes = get_bb_var('PACKAGE_CLASSES')
        if 'package_rpm' not in package_classes:
            self.skipTest('This test requires RPM Packaging.')

        test_recipe = 'ed'

        feature = 'INHERIT += "sign_rpm"\n'
        feature += 'RPM_GPG_PASSPHRASE = "test123"\n'
        feature += 'RPM_GPG_NAME = "testuser"\n'
        feature += 'GPG_PATH = "%s"\n' % self.gpg_dir

        self.write_config(feature)

        bitbake('-c clean %s' % test_recipe)
        bitbake('-f -c package_write_rpm %s' % test_recipe)

        self.add_command_to_tearDown('bitbake -c clean %s' % test_recipe)

        needed_vars = ['PKGDATA_DIR', 'DEPLOY_DIR_RPM', 'PACKAGE_ARCH', 'STAGING_BINDIR_NATIVE']
        bb_vars = get_bb_vars(needed_vars, test_recipe)
        pkgdatadir = bb_vars['PKGDATA_DIR']
        pkgdata = oe.packagedata.read_pkgdatafile(pkgdatadir + "/runtime/ed")
        if 'PKGE' in pkgdata:
            pf = pkgdata['PN'] + "-" + pkgdata['PKGE'] + pkgdata['PKGV'] + '-' + pkgdata['PKGR']
        else:
            pf = pkgdata['PN'] + "-" + pkgdata['PKGV'] + '-' + pkgdata['PKGR']
        deploy_dir_rpm = bb_vars['DEPLOY_DIR_RPM']
        package_arch = bb_vars['PACKAGE_ARCH'].replace('-', '_')
        staging_bindir_native = bb_vars['STAGING_BINDIR_NATIVE']

        pkg_deploy = os.path.join(deploy_dir_rpm, package_arch, '.'.join((pf, package_arch, 'rpm')))

        # Use a temporary rpmdb
        rpmdb = tempfile.mkdtemp(prefix='oeqa-rpmdb')

        runCmd('%s/rpmkeys --define "_dbpath %s" --import %s' %
               (staging_bindir_native, rpmdb, self.pub_key_path))

        ret = runCmd('%s/rpmkeys --define "_dbpath %s" --checksig %s' %
                     (staging_bindir_native, rpmdb, pkg_deploy))
        # tmp/deploy/rpm/i586/ed-1.9-r0.i586.rpm: rsa sha1 md5 OK
        self.assertIn('digests signatures OK', ret.output, 'Package signed incorrectly.')
        shutil.rmtree(rpmdb)

        #Check that an image can be built from signed packages
        self.add_command_to_tearDown('bitbake -c clean core-image-minimal')
        bitbake('-c clean core-image-minimal')
        bitbake('core-image-minimal')
Beispiel #38
0
    def test_sign_cascaded_uboot_fit_image(self):
        """
        Summary:     Check if U-Boot FIT image and Image Tree Source (its) are
                     created and signed correctly for the scenario where both
                     U-Boot proper and Kernel fitImages are being created and
                     signed.
        Expected:    1) U-Boot its and FIT image are built successfully
                     2) Scanning the its file indicates signing is enabled
                        as requested by SPL_SIGN_ENABLE (using keys generated
                        via UBOOT_FIT_GENERATE_KEYS)
                     3) Dumping the FIT image indicates signature values
                        are present
                     4) Examination of the do_uboot_assemble_fitimage
                     runfile/logfile indicate that UBOOT_MKIMAGE, UBOOT_MKIMAGE_SIGN
                     and SPL_MKIMAGE_SIGN_ARGS are working as expected.
        Product:     oe-core
        Author:      Klaus Heinrich Kiwi <*****@*****.**> based upon
                     work by Paul Eggleton <*****@*****.**> and
                     Usama Arif <*****@*****.**>
        """
        config = """
# There's no U-boot deconfig with CONFIG_FIT_SIGNATURE yet, so we need at
# least CONFIG_SPL_LOAD_FIT and CONFIG_SPL_OF_CONTROL set
MACHINE = "qemuarm"
UBOOT_MACHINE = "am57xx_evm_defconfig"
SPL_BINARY = "MLO"
# Enable creation and signing of the U-Boot fitImage
UBOOT_FITIMAGE_ENABLE = "1"
SPL_SIGN_ENABLE = "1"
SPL_SIGN_KEYNAME = "spl-cascaded-oe-selftest"
SPL_SIGN_KEYDIR = "${TOPDIR}/signing-keys"
UBOOT_DTB_BINARY = "u-boot.dtb"
UBOOT_ENTRYPOINT  = "0x80000000"
UBOOT_LOADADDRESS = "0x80000000"
UBOOT_MKIMAGE_DTCOPTS = "-I dts -O dtb -p 2000"
UBOOT_MKIMAGE_SIGN_ARGS = "-c 'a smart cascaded Kernel comment'"
UBOOT_DTB_LOADADDRESS = "0x82000000"
UBOOT_ARCH = "arm"
SPL_MKIMAGE_DTCOPTS = "-I dts -O dtb -p 2000"
SPL_MKIMAGE_SIGN_ARGS = "-c 'a smart cascaded U-Boot comment'"
UBOOT_EXTLINUX = "0"
UBOOT_FIT_GENERATE_KEYS = "1"
UBOOT_FIT_HASH_ALG = "sha256"
KERNEL_IMAGETYPES += " fitImage "
KERNEL_CLASSES = " kernel-fitimage test-mkimage-wrapper "
UBOOT_SIGN_ENABLE = "1"
FIT_GENERATE_KEYS = "1"
UBOOT_SIGN_KEYDIR = "${TOPDIR}/signing-keys"
UBOOT_SIGN_KEYNAME = "kernel-oe-selftest"
FIT_SIGN_INDIVIDUAL = "1"
"""
        self.write_config(config)

        # The U-Boot fitImage is created as part of linux recipe
        bitbake("virtual/kernel")

        image_type = "core-image-minimal"
        deploy_dir_image = get_bb_var('DEPLOY_DIR_IMAGE')
        machine = get_bb_var('MACHINE')
        fitimage_its_path = os.path.join(deploy_dir_image,
            "u-boot-its-%s" % (machine,))
        fitimage_path = os.path.join(deploy_dir_image,
            "u-boot-fitImage-%s" % (machine,))

        self.assertTrue(os.path.exists(fitimage_its_path),
            "%s image tree source doesn't exist" % (fitimage_its_path))
        self.assertTrue(os.path.exists(fitimage_path),
            "%s FIT image doesn't exist" % (fitimage_path))

        req_itspaths = [
            ['/', 'images', 'uboot'],
            ['/', 'images', 'uboot', 'signature'],
            ['/', 'images', 'fdt'],
            ['/', 'images', 'fdt', 'signature'],
        ]

        itspath = []
        itspaths = []
        linect = 0
        sigs = {}
        with open(fitimage_its_path) as its_file:
            linect += 1
            for line in its_file:
                line = line.strip()
                if line.endswith('};'):
                    itspath.pop()
                elif line.endswith('{'):
                    itspath.append(line[:-1].strip())
                    itspaths.append(itspath[:])
                elif itspath and itspath[-1] == 'signature':
                    itsdotpath = '.'.join(itspath)
                    if not itsdotpath in sigs:
                        sigs[itsdotpath] = {}
                    if not '=' in line or not line.endswith(';'):
                        self.fail('Unexpected formatting in %s sigs section line %d:%s' % (fitimage_its_path, linect, line))
                    key, value = line.split('=', 1)
                    sigs[itsdotpath][key.rstrip()] = value.lstrip().rstrip(';')

        for reqpath in req_itspaths:
            if not reqpath in itspaths:
                self.fail('Missing section in its file: %s' % reqpath)

        reqsigvalues_image = {
            'algo': '"sha256,rsa2048"',
            'key-name-hint': '"spl-cascaded-oe-selftest"',
        }

        for itspath, values in sigs.items():
            reqsigvalues = reqsigvalues_image
            for reqkey, reqvalue in reqsigvalues.items():
                value = values.get(reqkey, None)
                if value is None:
                    self.fail('Missing key "%s" in its file signature section %s' % (reqkey, itspath))
                self.assertEqual(value, reqvalue)

        # Dump the image to see if it really got signed
        bitbake("u-boot-tools-native -c addto_recipe_sysroot")
        result = runCmd('bitbake -e u-boot-tools-native | grep ^RECIPE_SYSROOT_NATIVE=')
        recipe_sysroot_native = result.output.split('=')[1].strip('"')
        dumpimage_path = os.path.join(recipe_sysroot_native, 'usr', 'bin', 'dumpimage')
        result = runCmd('%s -l %s' % (dumpimage_path, fitimage_path))
        in_signed = None
        signed_sections = {}
        for line in result.output.splitlines():
            if line.startswith((' Image')):
                in_signed = re.search('\((.*)\)', line).groups()[0]
            elif re.match(' \w', line):
                in_signed = None
            elif in_signed:
                if not in_signed in signed_sections:
                    signed_sections[in_signed] = {}
                key, value = line.split(':', 1)
                signed_sections[in_signed][key.strip()] = value.strip()
        self.assertIn('uboot', signed_sections)
        self.assertIn('fdt', signed_sections)
        for signed_section, values in signed_sections.items():
            value = values.get('Sign algo', None)
            self.assertEqual(value, 'sha256,rsa2048:spl-cascaded-oe-selftest', 'Signature algorithm for %s not expected value' % signed_section)
            value = values.get('Sign value', None)
            self.assertEqual(len(value), 512, 'Signature value for section %s not expected length' % signed_section)

        # Check for SPL_MKIMAGE_SIGN_ARGS
        result = runCmd('bitbake -e virtual/kernel | grep ^T=')
        tempdir = result.output.split('=', 1)[1].strip().strip('')
        result = runCmd('grep "a smart cascaded U-Boot comment" %s/run.do_uboot_assemble_fitimage' % tempdir, ignore_status=True)
        self.assertEqual(result.status, 0, 'SPL_MKIMAGE_SIGN_ARGS value did not get used')

        # Check for evidence of test-mkimage-wrapper class
        result = runCmd('grep "### uboot-mkimage wrapper message" %s/log.do_uboot_assemble_fitimage' % tempdir, ignore_status=True)
        self.assertEqual(result.status, 0, 'UBOOT_MKIMAGE did not work')
        result = runCmd('grep "### uboot-mkimage signing wrapper message" %s/log.do_uboot_assemble_fitimage' % tempdir, ignore_status=True)
        self.assertEqual(result.status, 0, 'UBOOT_MKIMAGE_SIGN did not work')
Beispiel #39
0
    def test_uboot_sign_fit_image(self):
        """
        Summary:     Check if Uboot FIT image and Image Tree Source
                     (its) are built and the Image Tree Source has the
                     correct fields, in the scenario where the Kernel
                     is also creating/signing it's fitImage.
        Expected:    1. u-boot-fitImage and u-boot-its can be built
                     2. The type, load address, entrypoint address and
                     default values of U-boot image are correct in the
                     Image Tree Source. Not all the fields are tested,
                     only the key fields that wont vary between
                     different architectures.
        Product:     oe-core
        Author:      Klaus Heinrich Kiwi <*****@*****.**>
                     based on work by Usama Arif <*****@*****.**>
        """
        config = """
# We need at least CONFIG_SPL_LOAD_FIT and CONFIG_SPL_OF_CONTROL set
MACHINE = "qemuarm"
UBOOT_MACHINE = "am57xx_evm_defconfig"
SPL_BINARY = "MLO"

# Enable creation of the U-Boot fitImage
UBOOT_FITIMAGE_ENABLE = "1"

# (U-boot) fitImage properties
UBOOT_LOADADDRESS = "0x80080000"
UBOOT_ENTRYPOINT = "0x80080000"
UBOOT_FIT_DESC = "A model description"
KERNEL_IMAGETYPES += " fitImage "
KERNEL_CLASSES = " kernel-fitimage test-mkimage-wrapper "
UBOOT_SIGN_ENABLE = "1"
FIT_GENERATE_KEYS = "1"
UBOOT_SIGN_KEYDIR = "${TOPDIR}/signing-keys"
UBOOT_SIGN_KEYNAME = "oe-selftest"
FIT_SIGN_INDIVIDUAL = "1"
UBOOT_MKIMAGE_SIGN_ARGS = "-c 'a smart U-Boot comment'"
"""
        self.write_config(config)

        # The U-Boot fitImage is created as part of linux recipe
        bitbake("virtual/kernel")

        deploy_dir_image = get_bb_var('DEPLOY_DIR_IMAGE')
        machine = get_bb_var('MACHINE')
        fitimage_its_path = os.path.join(deploy_dir_image,
            "u-boot-its-%s" % (machine,))
        fitimage_path = os.path.join(deploy_dir_image,
            "u-boot-fitImage-%s" % (machine,))

        self.assertTrue(os.path.exists(fitimage_its_path),
            "%s image tree source doesn't exist" % (fitimage_its_path))
        self.assertTrue(os.path.exists(fitimage_path),
            "%s FIT image doesn't exist" % (fitimage_path))

        # Check that the type, load address, entrypoint address and default
        # values for kernel and ramdisk in Image Tree Source are as expected.
        # The order of fields in the below array is important. Not all the
        # fields are tested, only the key fields that wont vary between
        # different architectures.
        its_field_check = [
            'description = "A model description";',
            'type = "standalone";',
            'load = <0x80080000>;',
            'entry = <0x80080000>;',
            'default = "conf";',
            'loadables = "uboot";',
            'fdt = "fdt";'
            ]

        with open(fitimage_its_path) as its_file:
            field_index = 0
            for line in its_file:
                if field_index == len(its_field_check):
                    break
                if its_field_check[field_index] in line:
                    field_index +=1

        if field_index != len(its_field_check): # if its equal, the test passed
            self.assertTrue(field_index == len(its_field_check),
                "Fields in Image Tree Source File %s did not match, error in finding %s"
                % (fitimage_its_path, its_field_check[field_index]))
Beispiel #40
0
    def test_fit_image(self):
        """
        Summary:     Check if FIT image and Image Tree Source (its) are built
                     and the Image Tree Source has the correct fields.
        Expected:    1. fitImage and fitImage-its can be built
                     2. The type, load address, entrypoint address and
                     default values of kernel and ramdisk are as expected
                     in the Image Tree Source. Not all the fields are tested,
                     only the key fields that wont vary between different
                     architectures.
        Product:     oe-core
        Author:      Usama Arif <*****@*****.**>
        """
        config = """
# Enable creation of fitImage
KERNEL_IMAGETYPE = "Image"
KERNEL_IMAGETYPES += " fitImage "
KERNEL_CLASSES = " kernel-fitimage "

# RAM disk variables including load address and entrypoint for kernel and RAM disk
IMAGE_FSTYPES += "cpio.gz"
INITRAMFS_IMAGE = "core-image-minimal"
UBOOT_RD_LOADADDRESS = "0x88000000"
UBOOT_RD_ENTRYPOINT = "0x88000000"
UBOOT_LOADADDRESS = "0x80080000"
UBOOT_ENTRYPOINT = "0x80080000"
FIT_DESC = "A model description"
"""
        self.write_config(config)

        # fitImage is created as part of linux recipe
        bitbake("virtual/kernel")

        image_type = "core-image-minimal"
        deploy_dir_image = get_bb_var('DEPLOY_DIR_IMAGE')
        machine = get_bb_var('MACHINE')
        fitimage_its_path = os.path.join(deploy_dir_image,
            "fitImage-its-%s-%s-%s" % (image_type, machine, machine))
        fitimage_path = os.path.join(deploy_dir_image,
            "fitImage-%s-%s-%s" % (image_type, machine, machine))

        self.assertTrue(os.path.exists(fitimage_its_path),
            "%s image tree source doesn't exist" % (fitimage_its_path))
        self.assertTrue(os.path.exists(fitimage_path),
            "%s FIT image doesn't exist" % (fitimage_path))

        # Check that the type, load address, entrypoint address and default
        # values for kernel and ramdisk in Image Tree Source are as expected.
        # The order of fields in the below array is important. Not all the
        # fields are tested, only the key fields that wont vary between
        # different architectures.
        its_field_check = [
            'description = "A model description";',
            'type = "kernel";',
            'load = <0x80080000>;',
            'entry = <0x80080000>;',
            'type = "ramdisk";',
            'load = <0x88000000>;',
            'entry = <0x88000000>;',
            'default = "conf-1";',
            'kernel = "kernel-1";',
            'ramdisk = "ramdisk-1";'
            ]

        with open(fitimage_its_path) as its_file:
            field_index = 0
            for line in its_file:
                if field_index == len(its_field_check):
                    break
                if its_field_check[field_index] in line:
                    field_index +=1

        if field_index != len(its_field_check): # if its equal, the test passed
            self.assertTrue(field_index == len(its_field_check),
                "Fields in Image Tree Source File %s did not match, error in finding %s"
                % (fitimage_its_path, its_field_check[field_index]))
Beispiel #41
0
    def test_exclude_path(self):
        """Test --exclude-path wks option."""

        oldpath = os.environ['PATH']
        os.environ['PATH'] = get_bb_var("PATH", "wic-tools")

        try:
            wks_file = 'temp.wks'
            with open(wks_file, 'w') as wks:
                rootfs_dir = get_bb_var('IMAGE_ROOTFS', 'core-image-minimal')
                wks.write("""
part / --source rootfs --ondisk mmcblk0 --fstype=ext4 --exclude-path usr
part /usr --source rootfs --ondisk mmcblk0 --fstype=ext4 --rootfs-dir %s/usr
part /etc --source rootfs --ondisk mmcblk0 --fstype=ext4 --exclude-path bin/ --rootfs-dir %s/usr"""
                          % (rootfs_dir, rootfs_dir))
            runCmd("wic create %s -e core-image-minimal -o %s" \
                                       % (wks_file, self.resultdir))

            os.remove(wks_file)
            wicout = glob(self.resultdir + "%s-*direct" % 'temp')
            self.assertEqual(1, len(wicout))

            wicimg = wicout[0]

            # verify partition size with wic
            res = runCmd("parted -m %s unit b p 2>/dev/null" % wicimg)

            # parse parted output which looks like this:
            # BYT;\n
            # /var/tmp/wic/build/tmpfwvjjkf_-201611101222-hda.direct:200MiB:file:512:512:msdos::;\n
            # 1:0.00MiB:200MiB:200MiB:ext4::;\n
            partlns = res.output.splitlines()[2:]

            self.assertEqual(3, len(partlns))

            for part in [1, 2, 3]:
                part_file = os.path.join(self.resultdir,
                                         "selftest_img.part%d" % part)
                partln = partlns[part - 1].split(":")
                self.assertEqual(7, len(partln))
                start = int(partln[1].rstrip("B")) / 512
                length = int(partln[3].rstrip("B")) / 512
                runCmd("dd if=%s of=%s skip=%d count=%d" %
                       (wicimg, part_file, start, length))

            # Test partition 1, should contain the normal root directories, except
            # /usr.
            res = runCmd("debugfs -R 'ls -p' %s 2>/dev/null" % \
                             os.path.join(self.resultdir, "selftest_img.part1"))
            files = extract_files(res.output)
            self.assertIn("etc", files)
            self.assertNotIn("usr", files)

            # Partition 2, should contain common directories for /usr, not root
            # directories.
            res = runCmd("debugfs -R 'ls -p' %s 2>/dev/null" % \
                             os.path.join(self.resultdir, "selftest_img.part2"))
            files = extract_files(res.output)
            self.assertNotIn("etc", files)
            self.assertNotIn("usr", files)
            self.assertIn("share", files)

            # Partition 3, should contain the same as partition 2, including the bin
            # directory, but not the files inside it.
            res = runCmd("debugfs -R 'ls -p' %s 2>/dev/null" % \
                             os.path.join(self.resultdir, "selftest_img.part3"))
            files = extract_files(res.output)
            self.assertNotIn("etc", files)
            self.assertNotIn("usr", files)
            self.assertIn("share", files)
            self.assertIn("bin", files)
            res = runCmd("debugfs -R 'ls -p bin' %s 2>/dev/null" % \
                             os.path.join(self.resultdir, "selftest_img.part3"))
            files = extract_files(res.output)
            self.assertIn(".", files)
            self.assertIn("..", files)
            self.assertEqual(2, len(files))

            for part in [1, 2, 3]:
                part_file = os.path.join(self.resultdir,
                                         "selftest_img.part%d" % part)
                os.remove(part_file)

        finally:
            os.environ['PATH'] = oldpath
Beispiel #42
0
def get_host_arch(recipe):
    """A cached call to get_bb_var('HOST_ARCH', <recipe>)"""
    return get_bb_var('HOST_ARCH', recipe)
 def setUpClass(cls):
     super(BitbakePrTests, cls).setUpClass()
     cls.pkgdata_dir = get_bb_var('PKGDATA_DIR')
 def test_specify_pkgdatadir(self):
     result = runCmd('oe-pkgdata-util -p %s lookup-pkg zlib' %
                     get_bb_var('PKGDATA_DIR'))
     self.assertEqual(result.output, 'libz1')
    def test_reproducible_builds(self):
        def strip_topdir(s):
            if s.startswith(self.topdir):
                return s[len(self.topdir):]
            return s

        # Build native utilities
        self.write_config('')
        bitbake("diffoscope-native diffutils-native jquery-native -c addto_recipe_sysroot")
        diffutils_sysroot = get_bb_var("RECIPE_SYSROOT_NATIVE", "diffutils-native")
        diffoscope_sysroot = get_bb_var("RECIPE_SYSROOT_NATIVE", "diffoscope-native")
        jquery_sysroot = get_bb_var("RECIPE_SYSROOT_NATIVE", "jquery-native")

        if self.save_results:
            os.makedirs(self.save_results, exist_ok=True)
            datestr = datetime.datetime.now().strftime('%Y%m%d')
            save_dir = tempfile.mkdtemp(prefix='oe-reproducible-%s-' % datestr, dir=self.save_results)
            os.chmod(save_dir, stat.S_IRWXU | stat.S_IRGRP | stat.S_IXGRP | stat.S_IROTH | stat.S_IXOTH)
            self.logger.info('Non-reproducible packages will be copied to %s', save_dir)

        vars_A = self.do_test_build('reproducibleA', self.build_from_sstate)

        vars_B = self.do_test_build('reproducibleB', False)

        # NOTE: The temp directories from the reproducible build are purposely
        # kept after the build so it can be diffed for debugging.

        fails = []

        for c in self.package_classes:
            with self.subTest(package_class=c):
                package_class = 'package_' + c

                deploy_A = vars_A['DEPLOY_DIR_' + c.upper()]
                deploy_B = vars_B['DEPLOY_DIR_' + c.upper()]

                self.logger.info('Checking %s packages for differences...' % c)
                result = self.compare_packages(deploy_A, deploy_B, 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))

                self.write_package_list(package_class, 'missing', result.missing)
                self.write_package_list(package_class, 'different', result.different)
                self.write_package_list(package_class, 'same', result.same)

                if self.save_results:
                    for d in result.different:
                        self.copy_file(d.reference, '/'.join([save_dir, 'packages', strip_topdir(d.reference)]))
                        self.copy_file(d.test, '/'.join([save_dir, 'packages', strip_topdir(d.test)]))

                if result.missing or result.different:
                    fails.append("The following %s packages are missing or different: %s" %
                            (c, '\n'.join(r.test for r in (result.missing + result.different))))

        # Clean up empty directories
        if self.save_results:
            if not os.listdir(save_dir):
                os.rmdir(save_dir)
            else:
                self.logger.info('Running diffoscope')
                package_dir = os.path.join(save_dir, 'packages')
                package_html_dir = os.path.join(package_dir, 'diff-html')

                # Copy jquery to improve the diffoscope output usability
                self.copy_file(os.path.join(jquery_sysroot, 'usr/share/javascript/jquery/jquery.min.js'), os.path.join(package_html_dir, 'jquery.js'))

                runCmd(['diffoscope', '--no-default-limits', '--exclude-directory-metadata', '--html-dir', package_html_dir, 'reproducibleA', 'reproducibleB'],
                        native_sysroot=diffoscope_sysroot, ignore_status=True, cwd=package_dir)

        if fails:
            self.fail('\n'.join(fails))
Beispiel #46
0
    def test_initramfs_bundle(self):
        """
        Summary:     Verifies the content of the initramfs bundle node in the FIT Image Tree Source (its)
                     The FIT settings are set by the test case.
                     The machine used is beaglebone-yocto.
        Expected:    1. The ITS is generated with initramfs bundle support
                     2. All the fields in the kernel node are as expected (matching the
                        conf settings)
                     3. The kernel is included in all the available configurations and
                        its hash is included in the configuration signature

        Product:     oe-core
        Author:      Abdellatif El Khlifi <*****@*****.**>
        """

        config = """
DISTRO="poky"
MACHINE = "beaglebone-yocto"
INITRAMFS_IMAGE_BUNDLE = "1"
INITRAMFS_IMAGE = "core-image-minimal-initramfs"
INITRAMFS_SCRIPTS = ""
UBOOT_MACHINE = "am335x_evm_defconfig"
KERNEL_CLASSES = " kernel-fitimage "
KERNEL_IMAGETYPES = "fitImage"
UBOOT_SIGN_ENABLE = "1"
UBOOT_SIGN_KEYNAME = "beaglebonekey"
UBOOT_SIGN_KEYDIR ?= "${DEPLOY_DIR_IMAGE}"
UBOOT_DTB_BINARY = "u-boot.dtb"
UBOOT_ENTRYPOINT  = "0x80000000"
UBOOT_LOADADDRESS = "0x80000000"
UBOOT_DTB_LOADADDRESS = "0x82000000"
UBOOT_ARCH = "arm"
UBOOT_MKIMAGE_DTCOPTS = "-I dts -O dtb -p 2000"
UBOOT_EXTLINUX = "0"
FIT_GENERATE_KEYS = "1"
KERNEL_IMAGETYPE_REPLACEMENT = "zImage"
FIT_HASH_ALG = "sha256"
"""
        self.write_config(config)

        # fitImage is created as part of linux recipe
        bitbake("virtual/kernel")

        image_type = get_bb_var('INITRAMFS_IMAGE')
        deploy_dir_image = get_bb_var('DEPLOY_DIR_IMAGE')
        machine = get_bb_var('MACHINE')
        fitimage_its_path = os.path.join(deploy_dir_image,
                    "fitImage-its-%s-%s-%s" % (image_type, machine, machine))
        fitimage_path = os.path.join(deploy_dir_image,"fitImage")

        self.assertTrue(os.path.exists(fitimage_its_path),
            "%s image tree source doesn't exist" % (fitimage_its_path))
        self.assertTrue(os.path.exists(fitimage_path),
            "%s FIT image doesn't exist" % (fitimage_path))

        kernel_load = str(get_bb_var('UBOOT_LOADADDRESS'))
        kernel_entry = str(get_bb_var('UBOOT_ENTRYPOINT'))
        initramfs_bundle_format = str(get_bb_var('KERNEL_IMAGETYPE_REPLACEMENT'))
        uboot_arch = str(get_bb_var('UBOOT_ARCH'))
        initramfs_bundle = "arch/" + uboot_arch + "/boot/" + initramfs_bundle_format + ".initramfs"
        fit_hash_alg = str(get_bb_var('FIT_HASH_ALG'))

        its_file = open(fitimage_its_path)

        its_lines = [line.strip() for line in its_file.readlines()]

        exp_node_lines = [
            'kernel-1 {',
            'description = "Linux kernel";',
            'data = /incbin/("' + initramfs_bundle + '");',
            'type = "kernel";',
            'arch = "' + uboot_arch + '";',
            'os = "linux";',
            'compression = "none";',
            'load = <' + kernel_load + '>;',
            'entry = <' + kernel_entry + '>;',
            'hash-1 {',
            'algo = "' + fit_hash_alg +'";',
            '};',
            '};'
        ]

        node_str = exp_node_lines[0]

        test_passed = False

        print ("checking kernel node\n")

        if node_str in its_lines:
            node_start_idx = its_lines.index(node_str)
            node = its_lines[node_start_idx:(node_start_idx + len(exp_node_lines))]
            if node == exp_node_lines:
                print("kernel node verified")
            else:
                self.assertTrue(test_passed == True,"kernel node does not match expectation")

        rx_configs = re.compile("^conf-.*")
        its_configs = list(filter(rx_configs.match, its_lines))

        for cfg_str in its_configs:
            cfg_start_idx = its_lines.index(cfg_str)
            line_idx = cfg_start_idx + 2
            node_end = False
            while node_end == False:
                if its_lines[line_idx] == "};" and its_lines[line_idx-1] == "};" :
                    node_end = True
                line_idx = line_idx + 1

            node = its_lines[cfg_start_idx:line_idx]
            print("checking configuration " + cfg_str.rstrip(" {"))
            rx_desc_line = re.compile("^description.*1 Linux kernel.*")
            if len(list(filter(rx_desc_line.match, node))) != 1:
                self.assertTrue(test_passed == True,"kernel keyword not found in the description line")
                break
            else:
                print("kernel keyword found in the description line")

            if 'kernel = "kernel-1";' not in node:
                self.assertTrue(test_passed == True,"kernel line not found")
                break
            else:
                print("kernel line found")

            rx_sign_line = re.compile("^sign-images.*kernel.*")
            if len(list(filter(rx_sign_line.match, node))) != 1:
                self.assertTrue(test_passed == True,"kernel hash not signed")
                break
            else:
                print("kernel hash signed")

            test_passed = True
            self.assertTrue(test_passed == True,"Initramfs bundle test success")
    def run_test_sstate_rebuild(self,
                                primary_targets,
                                relocate=False,
                                rebuild_dependencies=False):
        buildA = os.path.join(self.builddir, 'buildA')
        if relocate:
            buildB = os.path.join(self.builddir, 'buildB')
        else:
            buildB = buildA

        if rebuild_dependencies:
            rebuild_targets = self.get_dep_targets(primary_targets)
        else:
            rebuild_targets = primary_targets

        self.configure_builddir(buildA)
        runCmd((". %s/oe-init-build-env %s && " %
                (get_bb_var('COREBASE'), buildA)) + 'bitbake  ' +
               ' '.join(map(str, primary_targets)),
               shell=True,
               executable='/bin/bash')
        self.hardlink_tree(os.path.join(buildA, 'sstate-cache'),
                           os.path.join(self.builddir, 'sstate-cache-buildA'))
        shutil.rmtree(buildA)

        failed_rebuild = []
        failed_cleansstate = []
        for target in rebuild_targets:
            self.configure_builddir(buildB)
            self.hardlink_tree(
                os.path.join(self.builddir, 'sstate-cache-buildA'),
                os.path.join(buildB, 'sstate-cache'))

            result_cleansstate = runCmd((". %s/oe-init-build-env %s && " %
                                         (get_bb_var('COREBASE'), buildB)) +
                                        'bitbake -ccleansstate ' + target,
                                        ignore_status=True,
                                        shell=True,
                                        executable='/bin/bash')
            if not result_cleansstate.status == 0:
                failed_cleansstate.append(target)
                shutil.rmtree(buildB)
                continue

            result_build = runCmd(
                (". %s/oe-init-build-env %s && " %
                 (get_bb_var('COREBASE'), buildB)) + 'bitbake ' + target,
                ignore_status=True,
                shell=True,
                executable='/bin/bash')
            if not result_build.status == 0:
                failed_rebuild.append(target)

            shutil.rmtree(buildB)

        self.assertFalse(
            failed_rebuild,
            msg="The following recipes have failed to rebuild: %s" %
            ' '.join(map(str, failed_rebuild)))
        self.assertFalse(
            failed_cleansstate,
            msg=
            "The following recipes have failed cleansstate(all others have passed both cleansstate and rebuild from sstate tests): %s"
            % ' '.join(map(str, failed_cleansstate)))
Beispiel #48
0
    def test_sign_fit_image(self):
        """
        Summary:     Check if FIT image and Image Tree Source (its) are created
                     and signed correctly.
        Expected:    1) its and FIT image are built successfully
                     2) Scanning the its file indicates signing is enabled
                        as requested by UBOOT_SIGN_ENABLE (using keys generated
                        via FIT_GENERATE_KEYS)
                     3) Dumping the FIT image indicates signature values
                        are present (including for images as enabled via
                        FIT_SIGN_INDIVIDUAL)
                     4) Examination of the do_assemble_fitimage runfile/logfile
                        indicate that UBOOT_MKIMAGE, UBOOT_MKIMAGE_SIGN and
                        UBOOT_MKIMAGE_SIGN_ARGS are working as expected.
        Product:     oe-core
        Author:      Paul Eggleton <*****@*****.**> based upon
                     work by Usama Arif <*****@*****.**>
        """
        config = """
# Enable creation of fitImage
MACHINE = "beaglebone-yocto"
KERNEL_IMAGETYPES += " fitImage "
KERNEL_CLASSES = " kernel-fitimage test-mkimage-wrapper "
UBOOT_SIGN_ENABLE = "1"
FIT_GENERATE_KEYS = "1"
UBOOT_SIGN_KEYDIR = "${TOPDIR}/signing-keys"
UBOOT_SIGN_KEYNAME = "oe-selftest"
FIT_SIGN_INDIVIDUAL = "1"
UBOOT_MKIMAGE_SIGN_ARGS = "-c 'a smart comment'"
"""
        self.write_config(config)

        # fitImage is created as part of linux recipe
        bitbake("virtual/kernel")

        image_type = "core-image-minimal"
        deploy_dir_image = get_bb_var('DEPLOY_DIR_IMAGE')
        machine = get_bb_var('MACHINE')
        fitimage_its_path = os.path.join(deploy_dir_image,
            "fitImage-its-%s" % (machine,))
        fitimage_path = os.path.join(deploy_dir_image,
            "fitImage-%s.bin" % (machine,))

        self.assertTrue(os.path.exists(fitimage_its_path),
            "%s image tree source doesn't exist" % (fitimage_its_path))
        self.assertTrue(os.path.exists(fitimage_path),
            "%s FIT image doesn't exist" % (fitimage_path))

        req_itspaths = [
            ['/', 'images', 'kernel-1'],
            ['/', 'images', 'kernel-1', 'signature-1'],
            ['/', 'images', 'fdt-am335x-boneblack.dtb'],
            ['/', 'images', 'fdt-am335x-boneblack.dtb', 'signature-1'],
            ['/', 'configurations', 'conf-am335x-boneblack.dtb'],
            ['/', 'configurations', 'conf-am335x-boneblack.dtb', 'signature-1'],
        ]

        itspath = []
        itspaths = []
        linect = 0
        sigs = {}
        with open(fitimage_its_path) as its_file:
            linect += 1
            for line in its_file:
                line = line.strip()
                if line.endswith('};'):
                    itspath.pop()
                elif line.endswith('{'):
                    itspath.append(line[:-1].strip())
                    itspaths.append(itspath[:])
                elif itspath and itspath[-1] == 'signature-1':
                    itsdotpath = '.'.join(itspath)
                    if not itsdotpath in sigs:
                        sigs[itsdotpath] = {}
                    if not '=' in line or not line.endswith(';'):
                        self.fail('Unexpected formatting in %s sigs section line %d:%s' % (fitimage_its_path, linect, line))
                    key, value = line.split('=', 1)
                    sigs[itsdotpath][key.rstrip()] = value.lstrip().rstrip(';')

        for reqpath in req_itspaths:
            if not reqpath in itspaths:
                self.fail('Missing section in its file: %s' % reqpath)

        reqsigvalues_image = {
            'algo': '"sha256,rsa2048"',
            'key-name-hint': '"oe-selftest"',
        }
        reqsigvalues_config = {
            'algo': '"sha256,rsa2048"',
            'key-name-hint': '"oe-selftest"',
            'sign-images': '"kernel", "fdt"',
        }

        for itspath, values in sigs.items():
            if 'conf-' in itspath:
                reqsigvalues = reqsigvalues_config
            else:
                reqsigvalues = reqsigvalues_image
            for reqkey, reqvalue in reqsigvalues.items():
                value = values.get(reqkey, None)
                if value is None:
                    self.fail('Missing key "%s" in its file signature section %s' % (reqkey, itspath))
                self.assertEqual(value, reqvalue)

        # Dump the image to see if it really got signed
        bitbake("u-boot-tools-native -c addto_recipe_sysroot")
        result = runCmd('bitbake -e u-boot-tools-native | grep ^RECIPE_SYSROOT_NATIVE=')
        recipe_sysroot_native = result.output.split('=')[1].strip('"')
        dumpimage_path = os.path.join(recipe_sysroot_native, 'usr', 'bin', 'dumpimage')
        result = runCmd('%s -l %s' % (dumpimage_path, fitimage_path))
        in_signed = None
        signed_sections = {}
        for line in result.output.splitlines():
            if line.startswith((' Configuration', ' Image')):
                in_signed = re.search('\((.*)\)', line).groups()[0]
            elif re.match('^ *', line) in (' ', ''):
                in_signed = None
            elif in_signed:
                if not in_signed in signed_sections:
                    signed_sections[in_signed] = {}
                key, value = line.split(':', 1)
                signed_sections[in_signed][key.strip()] = value.strip()
        self.assertIn('kernel-1', signed_sections)
        self.assertIn('fdt-am335x-boneblack.dtb', signed_sections)
        self.assertIn('conf-am335x-boneblack.dtb', signed_sections)
        for signed_section, values in signed_sections.items():
            value = values.get('Sign algo', None)
            self.assertEqual(value, 'sha256,rsa2048:oe-selftest', 'Signature algorithm for %s not expected value' % signed_section)
            value = values.get('Sign value', None)
            self.assertEqual(len(value), 512, 'Signature value for section %s not expected length' % signed_section)

        # Check for UBOOT_MKIMAGE_SIGN_ARGS
        result = runCmd('bitbake -e virtual/kernel | grep ^T=')
        tempdir = result.output.split('=', 1)[1].strip().strip('')
        result = runCmd('grep "a smart comment" %s/run.do_assemble_fitimage' % tempdir, ignore_status=True)
        self.assertEqual(result.status, 0, 'UBOOT_MKIMAGE_SIGN_ARGS value did not get used')

        # Check for evidence of test-mkimage-wrapper class
        result = runCmd('grep "### uboot-mkimage wrapper message" %s/log.do_assemble_fitimage' % tempdir, ignore_status=True)
        self.assertEqual(result.status, 0, 'UBOOT_MKIMAGE did not work')
        result = runCmd('grep "### uboot-mkimage signing wrapper message" %s/log.do_assemble_fitimage' % tempdir, ignore_status=True)
        self.assertEqual(result.status, 0, 'UBOOT_MKIMAGE_SIGN did not work')
Beispiel #49
0
    def test_sstate_noop_samesigs(self):
        """
        The sstate checksums of two builds with these variables changed or
        classes inherits should be the same.
        """

        topdir = get_bb_var('TOPDIR')
        targetvendor = get_bb_var('TARGET_VENDOR')
        self.write_config("""
TMPDIR = "${TOPDIR}/tmp-sstatesamehash"
BB_NUMBER_THREADS = "1"
PARALLEL_MAKE = "-j 1"
DL_DIR = "${TOPDIR}/download1"
TIME = "111111"
DATE = "20161111"
INHERIT_remove = "buildstats-summary buildhistory uninative"
http_proxy = ""
""")
        self.track_for_cleanup(topdir + "/tmp-sstatesamehash")
        self.track_for_cleanup(topdir + "/download1")
        bitbake("world meta-toolchain -S none")
        self.write_config("""
TMPDIR = "${TOPDIR}/tmp-sstatesamehash2"
BB_NUMBER_THREADS = "2"
PARALLEL_MAKE = "-j 2"
DL_DIR = "${TOPDIR}/download2"
TIME = "222222"
DATE = "20161212"
# Always remove uninative as we're changing proxies
INHERIT_remove = "uninative"
INHERIT += "buildstats-summary buildhistory"
http_proxy = "http://example.com/"
""")
        self.track_for_cleanup(topdir + "/tmp-sstatesamehash2")
        self.track_for_cleanup(topdir + "/download2")
        bitbake("world meta-toolchain -S none")

        def get_files(d):
            f = {}
            for root, dirs, files in os.walk(d):
                for name in files:
                    name, shash = name.rsplit('.', 1)
                    # Extract just the machine and recipe name
                    base = os.sep.join(root.rsplit(os.sep, 2)[-2:] + [name])
                    f[base] = shash
            return f
        files1 = get_files(topdir + "/tmp-sstatesamehash/stamps/")
        files2 = get_files(topdir + "/tmp-sstatesamehash2/stamps/")
        # Remove items that are identical in both sets
        for k,v in files1.items() & files2.items():
            del files1[k]
            del files2[k]
        if not files1 and not files2:
            # No changes, so we're done
            return

        for k in files1.keys() | files2.keys():
            if k in files1 and k in files2:
                print("%s differs:" % k)
                print(subprocess.check_output(("bitbake-diffsigs",
                                               topdir + "/tmp-sstatesamehash/stamps/" + k + "." + files1[k],
                                               topdir + "/tmp-sstatesamehash2/stamps/" + k + "." + files2[k])))
            elif k in files1 and k not in files2:
                print("%s in files1" % k)
            elif k not in files1 and k in files2:
                print("%s in files2" % k)
            else:
                assert "shouldn't reach here"
        self.fail("sstate hashes not identical.")
Beispiel #50
0
 def test_image_manifest(self):
     bitbake('core-image-minimal')
     deploydir = get_bb_var("DEPLOY_DIR_IMAGE", target="core-image-minimal")
     imagename = get_bb_var("IMAGE_LINK_NAME", target="core-image-minimal")
     manifest = os.path.join(deploydir, imagename + ".manifest")
     self.assertTrue(os.path.islink(manifest), msg="No manifest file created for image")
Beispiel #51
0
 def test_buildhistory_basic(self):
     self.run_buildhistory_operation('xcursor-transparent-theme')
     self.assertTrue(os.path.isdir(get_bb_var('BUILDHISTORY_DIR')),
                     "buildhistory dir was not created.")
Beispiel #52
0
    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.
        self.append_config('ERROR_QA_remove = "version-going-backwards"')

        # 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,
                             msg="build of %s failed with %s" %
                             (target, result.output))

        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)))
Beispiel #53
0
    def secureboot_with_image(self,
                              signing_key="",
                              efishell=False,
                              boot_timeout=600):
        """Boot the image with UEFI SecureBoot enabled and see the result. """

        config = ''

        if signing_key:
            meta_refkit_base = get_bb_var('META_REFKIT_BASE')

            config += 'REFKIT_DB_KEY = "%s/files/secureboot/%s.key"\n' % (
                meta_refkit_base, signing_key)
            config += 'REFKIT_DB_CERT = "%s/files/secureboot/%s.crt"\n' % (
                meta_refkit_base, signing_key)
            config += 'REFKIT_IMAGE_EXTRA_FEATURES_append = " secureboot"\n'
            config += 'REFKIT_IMAGE_EXTRA_INSTALL_append = " efivar"\n'

        print('Building %s' % self.test_image)

        self.write_config(config)
        bitbake(self.test_image)
        self.remove_config(config)

        # Some of the cases depend on the timeout to expire. Allow overrides
        # so that we don't have to wait 1000s which is the default.
        overrides = {
            'TEST_QEMUBOOT_TIMEOUT': boot_timeout,
        }

        print('Booting %s' % self.test_image)

        try:
            with runqemu(self.test_image,
                         ssh=False,
                         runqemuparams='slirp',
                         qemuparams=self.ovmf_qemuparams,
                         overrides=overrides,
                         image_fstype='wic') as qemu:

                cmd = 'modprobe efivarfs ; mount -t efivarfs none /sys/firmware/efi/efivars/'
                cmd2 = 'SB_GUID_NAME=$(efivar -l|grep SecureBoot); efivar -d -n $SB_GUID_NAME'

                status, output = qemu.run_serial(cmd)

                self.assertTrue(
                    status, 'Failed to mount efivarfs (status=%s):\n%s' %
                    (status, output))

                status, output = qemu.run_serial(cmd2)

                # Test if the signed image has booted and the BIOS says UEFI
                # Secure Boot is enabled.
                self.assertTrue(
                    status, 'SecureBoot not enabled (status=%s):\n%s' %
                    (status, output))

        except Exception:

            # Currently runqemu() fails if 'login:'******'s
            # not possible to login as 'root'. Those conditions aren't met when
            # booting to EFI shell (See [YOCTO #11438]). We catch the failure
            # and parse the boot log to determine the success. Note: the
            # timeout triggers verbose bb.error() but that's normal with some
            # of the test cases.

            workdir = get_bb_var('WORKDIR', self.test_image)
            bootlog = "%s/testimage/qemu_boot_log" % workdir

            with open(bootlog, "r") as log:

                # This isn't right but all we can do at this point. The right
                # approach would run commands in the EFI shell to determine
                # the BIOS rejects unsigned and/or images signed with keys in
                # dbx key store but that needs changes in oeqa framework.

                output = log.read()

                # PASS if the test case wants EFI shell and we see it in logs
                if not (efishell and re.search('Shell>', output)):
                    self.fail(
                        'The image did not boot properly. Boot log:\n%s' %
                        output)
Beispiel #54
0
 def test_recipetool_appendsrcfile_basic_wildcard(self):
     testrecipe = 'base-files'
     self._test_appendsrcfile(testrecipe, 'a-file', options='-w')
     recipefile = get_bb_var('FILE', testrecipe)
     bbappendfile = self._check_bbappend(testrecipe, recipefile, self.templayerdir)
     self.assertEqual(os.path.basename(bbappendfile), '%s_%%.bbappend' % testrecipe)
Beispiel #55
0
    def test_provisioning(self):
        print('Checking machine name (hostname) of device:')
        stdout, stderr, retcode = self.qemu_command('hostname')
        self.assertEqual(
            retcode, 0, "Unable to check hostname. " +
            "Is an ssh daemon (such as dropbear or openssh) installed on the device?"
        )
        machine = get_bb_var('MACHINE', 'core-image-minimal')
        self.assertEqual(stderr, b'', 'Error: ' + stderr.decode())
        # Strip off line ending.
        value = stdout.decode()[:-1]
        self.assertEqual(
            value, machine,
            'MACHINE does not match hostname: ' + machine + ', ' + value)

        verifyNotProvisioned(self, machine)

        # Verify that HSM is not yet initialized.
        pkcs11_command = 'pkcs11-tool --module=/usr/lib/softhsm/libsofthsm2.so -O'
        stdout, stderr, retcode = self.qemu_command(pkcs11_command)
        self.assertNotEqual(
            retcode, 0, 'pkcs11-tool succeeded before initialization: ' +
            stdout.decode() + stderr.decode())
        softhsm2_command = 'softhsm2-util --show-slots'
        stdout, stderr, retcode = self.qemu_command(softhsm2_command)
        self.assertNotEqual(
            retcode, 0, 'softhsm2-tool succeeded before initialization: ' +
            stdout.decode() + stderr.decode())

        # Run aktualizr-cert-provider.
        bb_vars = get_bb_vars(['SOTA_PACKED_CREDENTIALS'], 'aktualizr-native')
        creds = bb_vars['SOTA_PACKED_CREDENTIALS']
        bb_vars_prov = get_bb_vars(['WORKDIR', 'libdir'],
                                   'aktualizr-device-prov-hsm')
        config = bb_vars_prov['WORKDIR'] + '/sysroot-destdir' + bb_vars_prov[
            'libdir'] + '/sota/conf.d/20-sota-device-cred-hsm.toml'

        akt_native_run(
            self,
            'aktualizr-cert-provider -c {creds} -t root@localhost -p {port} -r -s -u -g {config}'
            .format(creds=creds, port=self.qemu.ssh_port, config=config))

        # Verify that HSM is able to initialize.
        for delay in [5, 5, 5, 5, 10]:
            sleep(delay)
            p11_out, p11_err, p11_ret = self.qemu_command(pkcs11_command)
            hsm_out, hsm_err, hsm_ret = self.qemu_command(softhsm2_command)
            if (p11_ret == 0 and hsm_ret == 0 and hsm_err == b''
                    and b'X.509 cert' in p11_out
                    and b'present token' in p11_err):
                break
        else:
            self.fail('pkcs11-tool or softhsm2-tool failed: ' +
                      p11_err.decode() + p11_out.decode() + hsm_err.decode() +
                      hsm_out.decode())

        self.assertIn(
            b'Initialized:      yes', hsm_out,
            'softhsm2-tool failed: ' + hsm_err.decode() + hsm_out.decode())
        self.assertIn(
            b'User PIN init.:   yes', hsm_out,
            'softhsm2-tool failed: ' + hsm_err.decode() + hsm_out.decode())

        # Check that pkcs11 output matches sofhsm output.
        p11_p = re.compile(
            r'Using slot [0-9] with a present token \((0x[0-9a-f]*)\)\s')
        p11_m = p11_p.search(p11_err.decode())
        self.assertTrue(
            p11_m, 'Slot number not found with pkcs11-tool: ' +
            p11_err.decode() + p11_out.decode())
        self.assertGreater(
            p11_m.lastindex, 0, 'Slot number not found with pkcs11-tool: ' +
            p11_err.decode() + p11_out.decode())
        hsm_p = re.compile(r'Description:\s*SoftHSM slot ID (0x[0-9a-f]*)\s')
        hsm_m = hsm_p.search(hsm_out.decode())
        self.assertTrue(
            hsm_m, 'Slot number not found with softhsm2-tool: ' +
            hsm_err.decode() + hsm_out.decode())
        self.assertGreater(
            hsm_m.lastindex, 0, 'Slot number not found with softhsm2-tool: ' +
            hsm_err.decode() + hsm_out.decode())
        self.assertEqual(
            p11_m.group(1), hsm_m.group(1),
            'Slot number does not match: ' + p11_err.decode() +
            p11_out.decode() + hsm_err.decode() + hsm_out.decode())

        verifyProvisioned(self, machine)
Beispiel #56
0
 def test_recipetool_appendsrcfile_srcdir_basic(self):
     testrecipe = 'bash'
     srcdir = get_bb_var('S', testrecipe)
     workdir = get_bb_var('WORKDIR', testrecipe)
     subdir = os.path.relpath(srcdir, workdir)
     self._test_appendsrcfile(testrecipe, 'a-file', srcdir=subdir)
Beispiel #57
0
 def test_read_only_image(self):
     distro_features = get_bb_var('DISTRO_FEATURES')
     if not ('x11' in distro_features and 'opengl' in distro_features):
         self.skipTest('core-image-sato requires x11 and opengl in distro features')
     self.write_config('IMAGE_FEATURES += "read-only-rootfs"')
     bitbake("core-image-sato")
Beispiel #58
0
 def setUpClass(cls):
     super(LibOE, cls).setUpClass()
     cls.tmp_dir = get_bb_var('TMPDIR')
Beispiel #59
0
    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)
Beispiel #60
0
    def get_eSDK_toolchain(image):
        pn_task = '%s -c populate_sdk_ext' % image

        sdk_deploy = get_bb_var('SDK_DEPLOY', pn_task)
        toolchain_name = get_bb_var('TOOLCHAINEXT_OUTPUTNAME', pn_task)
        return os.path.join(sdk_deploy, toolchain_name + '.sh')