예제 #1
0
    def test_bootloader_embed(self, prepared_test_build, bitbake_image):
        """Test that MENDER_IMAGE_BOOTLOADER_FILE causes the bootloader to be embedded
        correctly in the resulting sdimg."""

        loader_file = "bootloader.bin"
        loader_offset = 4

        init_env_cmd = "cd %s && . oe-init-build-env %s" % (
            prepared_test_build["bitbake_corebase"],
            prepared_test_build["build_dir"],
        )
        new_bb_vars = get_bitbake_variables(
            "core-image-minimal", env_setup=init_env_cmd
        )

        loader_dir = new_bb_vars["DEPLOY_DIR_IMAGE"]
        loader_path = os.path.join(loader_dir, loader_file)

        run_verbose("mkdir -p %s" % os.path.dirname(loader_path))
        run_verbose("cp /etc/os-release %s" % loader_path)

        build_image(
            prepared_test_build["build_dir"],
            prepared_test_build["bitbake_corebase"],
            bitbake_image,
            [
                'MENDER_IMAGE_BOOTLOADER_FILE = "%s"' % loader_file,
                'MENDER_IMAGE_BOOTLOADER_BOOTSECTOR_OFFSET = "%d"' % loader_offset,
            ],
        )

        built_sdimg = latest_build_artifact(
            prepared_test_build["build_dir"], "core-image*.sdimg"
        )

        original = os.open(loader_path, os.O_RDONLY)
        embedded = os.open(built_sdimg, os.O_RDONLY)
        os.lseek(embedded, loader_offset * 512, 0)

        block_size = 4096
        while True:
            org_read = os.read(original, block_size)
            org_read_size = len(org_read)
            emb_read = os.read(embedded, org_read_size)

            assert (
                org_read == emb_read
            ), "Embedded bootloader is not identical to the file specified in MENDER_IMAGE_BOOTLOADER_FILE"

            if org_read_size < block_size:
                break

        os.close(original)
        os.close(embedded)
예제 #2
0
    def test_multiple_device_types_compatible(self, prepared_test_build,
                                              bitbake_path, bitbake_variables,
                                              bitbake_image):
        """Tests that we can include multiple device_types in the artifact."""

        build_image(
            prepared_test_build["build_dir"],
            prepared_test_build["bitbake_corebase"],
            bitbake_image,
            ['MENDER_DEVICE_TYPES_COMPATIBLE = "machine1 machine2"'],
        )

        image = latest_build_artifact(prepared_test_build["build_dir"],
                                      "core-image*.mender")

        output = run_verbose("mender-artifact read %s" % image, capture=True)
        assert b"Compatible devices: '[machine1 machine2]'" in output

        output = subprocess.check_output(
            "tar xOf %s header.tar.gz | tar xOz header-info" % image,
            shell=True).decode()
        data = json.loads(output)
        if version_is_minimum(bitbake_variables, "mender-artifact", "3.0.0"):
            assert data["artifact_depends"]["device_type"] == [
                "machine1", "machine2"
            ]
        else:
            assert data["device_types_compatible"] == ["machine1", "machine2"]
예제 #3
0
    def test_preferred_versions(self, prepared_test_build, recipe, version):
        """Most Jenkins builds build with PREFERRED_VERSION set, because we want to
        build from a specific SHA. This test tests that we can change that or
        turn it off and the build still works."""

        old_file = get_local_conf_orig_path(prepared_test_build["build_dir"])
        new_file = get_local_conf_path(prepared_test_build["build_dir"])

        if recipe.endswith("-native"):
            base_recipe = recipe[: -len("-native")]
        else:
            base_recipe = recipe

        for pn_style in ["", "pn-"]:
            with open(old_file) as old_fd, open(new_file, "w") as new_fd:
                for line in old_fd.readlines():
                    if (
                        re.match("^EXTERNALSRC_pn-%s(-native)? *=" % base_recipe, line)
                        is not None
                    ):
                        continue
                    elif (
                        re.match(
                            "^PREFERRED_VERSION_(pn-)?%s(-native)? *=" % base_recipe,
                            line,
                        )
                        is not None
                    ):
                        continue
                    else:
                        new_fd.write(line)
                if version is not None:
                    new_fd.write(
                        'PREFERRED_VERSION_%s%s = "%s"\n'
                        % (pn_style, base_recipe, version)
                    )
                    new_fd.write(
                        'PREFERRED_VERSION_%s%s-native = "%s"\n'
                        % (pn_style, base_recipe, version)
                    )

            init_env_cmd = "cd %s && . oe-init-build-env %s" % (
                prepared_test_build["bitbake_corebase"],
                prepared_test_build["build_dir"],
            )
            run_verbose("%s && bitbake %s" % (init_env_cmd, recipe))
예제 #4
0
def bitbake_path(request, conversion):
    """Fixture that enables the PATH we need for our testing tools."""

    old_path = os.environ["PATH"]

    if not conversion:
        run_verbose(
            "bitbake -c prepare_recipe_sysroot mender-test-dependencies")
        bb_testing_variables = get_bitbake_variables(
            "mender-test-dependencies")
        os.environ[
            "PATH"] = bb_testing_variables["PATH"] + ":" + os.environ["PATH"]

    def path_restore():
        os.environ["PATH"] = old_path

    request.addfinalizer(path_restore)

    return os.environ["PATH"]
예제 #5
0
def prepared_test_build_base(request, conversion, bitbake_variables,
                             no_tmp_build_dir):

    if conversion:
        return {"build_dir": None, "bitbake_corebase": None}

    if no_tmp_build_dir:
        build_dir = os.environ["BUILDDIR"]
    else:
        build_dir = tempfile.mkdtemp(prefix="test-build-",
                                     dir=os.environ["BUILDDIR"])

    local_conf = get_local_conf_path(build_dir)
    local_conf_orig = get_local_conf_orig_path(build_dir)
    bblayers_conf = get_bblayers_conf_path(build_dir)
    bblayers_conf_orig = get_bblayers_conf_orig_path(build_dir)

    def cleanup_test_build():
        if not no_tmp_build_dir:
            run_verbose("rm -rf %s" % build_dir)
        else:
            reset_build_conf(build_dir, full_cleanup=True)

    cleanup_test_build()
    request.addfinalizer(cleanup_test_build)

    env_setup = "cd %s && . oe-init-build-env %s" % (
        bitbake_variables["COREBASE"],
        build_dir,
    )
    run_verbose(env_setup)

    if not no_tmp_build_dir:
        run_verbose("cp %s/conf/* %s/conf" %
                    (os.environ["BUILDDIR"], build_dir))
        with open(local_conf, "a") as fd:
            fd.write('SSTATE_MIRRORS = " file://.* file://%s/PATH"\n' %
                     bitbake_variables["SSTATE_DIR"])
            fd.write('DL_DIR = "%s"\n' % bitbake_variables["DL_DIR"])

    run_verbose("cp %s %s" % (local_conf, local_conf_orig))
    run_verbose("cp %s %s" % (bblayers_conf, bblayers_conf_orig))

    return {
        "build_dir": build_dir,
        "bitbake_corebase": bitbake_variables["COREBASE"]
    }
예제 #6
0
    def test_build_artifact_depends_and_provides(self, prepared_test_build,
                                                 bitbake_image, bitbake_path,
                                                 dependsprovides):
        """Test whether a build with enabled Artifact Provides and Depends does
        indeed add the parameters to the built Artifact"""

        build_image(
            prepared_test_build["build_dir"],
            prepared_test_build["bitbake_corebase"],
            bitbake_image,
            [param for param in str(dependsprovides).splitlines()],
        )

        image = latest_build_artifact(prepared_test_build["build_dir"],
                                      "core-image*.mender")

        output = run_verbose("mender-artifact read %s" % image,
                             capture=True).decode()
        other = TestBuild.BuildDependsProvides.parse(output)

        # MEN-2956: Mender-Artifact now writes rootfs-image-checksum by default.
        # MEN-3482: The new key for the rootfs image checksum is rootfs-image.checksum
        assert (
            "rootfs-image.checksum" in other.provides
            or "rootfs_image_checksum" in other.provides
        ), "Empty rootfs_image_checksum in the built rootfs-image artifact, this should be added by default by `mender-artifact write rootfs-image`"
        # Then remove it, not to mess up the expected test output
        if "rootfs-image.checksum" in other.provides.keys():
            del other.provides["rootfs-image.checksum"]
        if "rootfs_image_checksum" in other.provides.keys():
            del other.provides["rootfs_image_checksum"]

        # MEN-3076: Mender-Artifacts writes software version by default
        # older versions did not, thus we remove the key before asserting the content
        if "rootfs-image.version" in other.provides.keys():
            del other.provides["rootfs-image.version"]

        assert dependsprovides.__dict__ == other.__dict__
예제 #7
0
 def cleanup_test_build():
     if not no_tmp_build_dir:
         run_verbose("rm -rf %s" % build_dir)
     else:
         reset_build_conf(build_dir, full_cleanup=True)
예제 #8
0
    def test_boot_partition_population(self, prepared_test_build, bitbake_path,
                                       bitbake_image):
        # Notice in particular a mix of tabs, newlines and spaces. All there to
        # check that whitespace it treated correctly.

        build_image(
            prepared_test_build["build_dir"],
            prepared_test_build["bitbake_corebase"],
            bitbake_image,
            [
                """
IMAGE_INSTALL_append = " test-boot-files"

IMAGE_BOOT_FILES_append = " deployed-test1 deployed-test-dir2/deployed-test2 \
    deployed-test3;renamed-deployed-test3 \
 deployed-test-dir4/deployed-test4;renamed-deployed-test4	deployed-test5;renamed-deployed-test-dir5/renamed-deployed-test5 \
deployed-test-dir6/deployed-test6;renamed-deployed-test-dir6/renamed-deployed-test6 \
deployed-test-dir7/* \
deployed-test-dir8/*;./ \
deployed-test-dir9/*;renamed-deployed-test-dir9/ \
"
"""
            ],
        )

        image = latest_build_artifact(prepared_test_build["build_dir"],
                                      "core-image*.*img")
        extract_partition(image, 1)
        try:
            listing = (run_verbose("mdir -i img1.fs -b -/",
                                   capture=True).decode().split())
            expected = [
                "::/deployed-test1",
                "::/deployed-test2",
                "::/renamed-deployed-test3",
                "::/renamed-deployed-test4",
                "::/renamed-deployed-test-dir5/renamed-deployed-test5",
                "::/renamed-deployed-test-dir6/renamed-deployed-test6",
                "::/deployed-test7",
                "::/deployed-test8",
                "::/renamed-deployed-test-dir9/deployed-test9",
            ]
            assert all([item in listing for item in expected])

            # Conflicting file with the same content should pass.
            build_image(
                prepared_test_build["build_dir"],
                prepared_test_build["bitbake_corebase"],
                bitbake_image,
                ['IMAGE_BOOT_FILES_append = " conflict-test1"'],
            )

            # Conflicting file with different content should fail.
            try:
                build_image(
                    prepared_test_build["build_dir"],
                    prepared_test_build["bitbake_corebase"],
                    bitbake_image,
                    ['IMAGE_BOOT_FILES_append = " conflict-test2"'],
                )
                pytest.fail(
                    "Bitbake succeeded, but should have failed with a file conflict"
                )
            except subprocess.CalledProcessError:
                pass
        finally:
            os.remove("img1.fs")