コード例 #1
0
    def test_build_nodbus(self, request, prepared_test_build, bitbake_path):
        """Test that we can remove dbus from PACKAGECONFIG, and that this causes the
        library dependency to be gone. The opposite is not tested, since we
        assume failure to link to the library will be caught in other tests that
        test DBus functionality."""

        build_image(
            prepared_test_build["build_dir"],
            prepared_test_build["bitbake_corebase"],
            "mender-client",
            ['PACKAGECONFIG_remove = "dbus"'],
        )

        env = get_bitbake_variables(request,
                                    "mender-client",
                                    prepared_test_build=prepared_test_build)

        # Get dynamic section info from binary.
        output = subprocess.check_output(
            [env["READELF"], "-d",
             os.path.join(env["D"], "usr/bin/mender")]).decode()

        # Verify the output is sane.
        assert "libc" in output

        # Actual test.
        assert "libglib" not in output

        # Make sure busconfig files are also gone.
        assert not os.path.exists(
            os.path.join(env["D"], "usr/share/dbus-1/system.d/io.mender.conf"))
        assert not os.path.exists(
            os.path.join(env["D"], "etc/dbus-1/system.d/io.mender.conf"))
コード例 #2
0
    def test_dataimg_creation(self, request, bitbake_variables,
                              prepared_test_build, bitbake_image):
        """Test that we can build a dataimg successfully."""

        build_image(
            prepared_test_build["build_dir"],
            prepared_test_build["bitbake_corebase"],
            bitbake_image,
            ['IMAGE_FSTYPES = "dataimg"'],
        )

        built_img = latest_build_artifact(request,
                                          prepared_test_build["build_dir"],
                                          "core-image*.dataimg")

        # Check that it contains the device_type file, as we expect.
        with make_tempdir() as tmpdir:
            menderdir = os.path.join(tmpdir, "mender")
            if ("ARTIFACTIMG_FSTYPE" in bitbake_variables
                    and bitbake_variables["ARTIFACTIMG_FSTYPE"] == "ubifs"):
                subprocess.check_call(
                    ["ubireader_extract_files", "-o", tmpdir, built_img])
            else:
                os.mkdir(menderdir)
                subprocess.check_call([
                    "debugfs",
                    "-R",
                    "dump -p /mender/device_type %s" %
                    os.path.join(menderdir, "device_type"),
                    built_img,
                ])
            with open(os.path.join(menderdir, "device_type")) as fd:
                content = fd.read()
            assert (content == "device_type=%s\n" %
                    bitbake_variables["MENDER_DEVICE_TYPE"])
コード例 #3
0
def ubimg_without_uboot_env(request, latest_ubimg, prepared_test_build,
                            bitbake_image):
    """The ubireader_utils_info tool and friends don't support our UBI volumes
    that contain the U-Boot environment and hence not valid UBIFS structures.
    Therefore, make a new temporary image that doesn't contain U-Boot."""

    # The tests are marked with "only_with_image('ubimg')", but that is checked
    # using a function fixture, and this is a session fixture, which cannot
    # depend on that. So we need this check here to bail out if we don't find a
    # ubimg.
    if not latest_ubimg:
        pytest.skip("No ubimg found")

    reset_build_conf(prepared_test_build["build_dir"])
    build_image(
        prepared_test_build["build_dir"],
        prepared_test_build["bitbake_corebase"],
        bitbake_image,
        ['MENDER_FEATURES_DISABLE_append = " mender-uboot"'],
    )

    ubimg = latest_build_artifact(request, prepared_test_build["build_dir"],
                                  "core-image*.ubimg")
    imgdir = tempfile.mkdtemp()
    tmpimg = os.path.join(imgdir, os.path.basename(ubimg))
    shutil.copyfile(ubimg, tmpimg)

    def remove_ubimg():
        os.unlink(tmpimg)

    request.addfinalizer(remove_ubimg)

    return tmpimg
コード例 #4
0
    def test_build_and_run_module(self, request, bitbake_variables,
                                  prepared_test_build, bitbake_image):

        build_image(
            prepared_test_build["build_dir"],
            prepared_test_build["bitbake_corebase"],
            bitbake_image,
            ['IMAGE_INSTALL_append = " mender-binary-delta"'],
            [
                'BBLAYERS_append = " %s/../meta-mender-commercial"' %
                bitbake_variables["LAYERDIR_MENDER"]
            ],
        )

        image = latest_build_artifact(request,
                                      prepared_test_build["build_dir"],
                                      "core-image*.ext4")
        output = subprocess.check_output(
            ["debugfs", "-R", "ls -p /usr/share/mender/modules/v3",
             image]).decode()

        # Debugfs has output like this:
        #   /3018/100755/0/0/mender-binary-delta/142672/
        #   /3015/100755/0/0/rootfs-image-v2/1606/
        assert "mender-binary-delta" in [
            line.split("/")[5] for line in output.split("\n")
            if line.startswith("/")
        ]
コード例 #5
0
    def test_tenant_token(self, request, prepared_test_build, bitbake_image):
        """Test setting a custom tenant-token"""

        build_image(
            prepared_test_build["build_dir"],
            prepared_test_build["bitbake_corebase"],
            bitbake_image,
            [
                'MENDER_TENANT_TOKEN = "%s"' % "authtentoken",
                'IMAGE_FSTYPES += "dataimg"',
            ],
        )

        built_rootfs = latest_build_artifact(request,
                                             prepared_test_build["build_dir"],
                                             "core-image*.dataimg")

        subprocess.check_call([
            "debugfs",
            "-R",
            "dump -p /etc/mender/mender.conf mender.conf",
            built_rootfs,
        ])

        try:
            with open("mender.conf") as fd:
                data = json.load(fd)
            assert data["TenantToken"] == "authtentoken"

        finally:
            os.remove("mender.conf")
コード例 #6
0
    def test_multiple_device_types_compatible(
        self,
        request,
        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(request,
                                      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"]
コード例 #7
0
    def test_mender_inventory_network_scripts(self, request,
                                              prepared_test_build,
                                              bitbake_image):
        """
        Test the 'inventory-network-scripts' build feature configuration through
        'PACKAGECONFIG' is working as expected.

        This verifies that the 'inventory-network-scripts' option is a part
        build, and also that the inventory scripts are not included when
        removed.


        The test only runs for sdimg, as the build image should not really matter here.
        """

        #
        # Feature enabled
        #
        reset_build_conf(prepared_test_build["build_dir"])
        build_image(
            prepared_test_build["build_dir"],
            prepared_test_build["bitbake_corebase"],
            bitbake_image,
            [
                'PACKAGECONFIG_append_pn-mender-client = " inventory-network-scripts"'
            ],
        )
        rootfs = latest_build_artifact(request,
                                       prepared_test_build["build_dir"],
                                       "core-image*.ext4")
        assert len(rootfs) > 0, "rootfs not generated"

        output = subprocess.check_output(
            ["debugfs", "-R", "ls /usr/share/mender/inventory", rootfs])
        assert (
            b"mender-inventory-geo" in output
        ), "mender-inventory-network-scripts seems not to be a part of the image, like they should"

        #
        # Feature disabled
        #
        reset_build_conf(prepared_test_build["build_dir"])
        build_image(
            prepared_test_build["build_dir"],
            prepared_test_build["bitbake_corebase"],
            bitbake_image,
            [
                'PACKAGECONFIG_remove_pn-mender-client = " inventory-network-scripts"'
            ],
        )
        rootfs = latest_build_artifact(request,
                                       prepared_test_build["build_dir"],
                                       "core-image*.ext4")
        assert len(rootfs) > 0, "ext4 not generated"
        output = subprocess.check_output(
            ["debugfs", "-R", "ls /usr/share/mender/inventory", rootfs])
        assert (
            b"mender-inventory-geo" not in output
        ), "mender-inventory-network-scripts unexpectedly a part of the image"
コード例 #8
0
    def test_module_install(
        self, request, prepared_test_build, bitbake_path, latest_rootfs, bitbake_image
    ):
        # List of expected update modules
        default_update_modules = [
            "deb",
            "directory",
            "docker",
            "rootfs-image-v2",
            "rpm",
            "script",
            "single-file",
        ]

        mender_vars = get_bitbake_variables(request, "mender-client")
        if "modules" in mender_vars["PACKAGECONFIG"].split():
            originally_on = True
        else:
            originally_on = False

        output = subprocess.check_output(
            ["debugfs", "-R", "ls -p /usr/share/mender/modules/v3", latest_rootfs]
        ).decode()
        entries = [
            elem.split("/")[5] for elem in output.split("\n") if elem.startswith("/")
        ]

        if originally_on:
            assert all([e in entries for e in default_update_modules])
            build_image(
                prepared_test_build["build_dir"],
                prepared_test_build["bitbake_corebase"],
                bitbake_image,
                ['PACKAGECONFIG_remove = "modules"'],
            )
        else:
            assert not any([e in entries for e in default_update_modules])
            build_image(
                prepared_test_build["build_dir"],
                prepared_test_build["bitbake_corebase"],
                bitbake_image,
                ['PACKAGECONFIG_append = " modules"'],
            )

        new_rootfs = latest_build_artifact(
            request, prepared_test_build["build_dir"], "core-image*.ext4"
        )

        output = subprocess.check_output(
            ["debugfs", "-R", "ls -p /usr/share/mender/modules/v3", new_rootfs]
        ).decode()
        entries = [
            elem.split("/")[5] for elem in output.split("\n") if elem.startswith("/")
        ]

        if originally_on:
            assert not any([e in entries for e in default_update_modules])
        else:
            assert all([e in entries for e in default_update_modules])
コード例 #9
0
    def test_artifact_signing_keys(
        self,
        request,
        prepared_test_build,
        bitbake_variables,
        bitbake_path,
        bitbake_image,
    ):
        """Test that MENDER_ARTIFACT_SIGNING_KEY and MENDER_ARTIFACT_VERIFY_KEY
        works correctly."""

        build_image(
            prepared_test_build["build_dir"],
            prepared_test_build["bitbake_corebase"],
            bitbake_image,
            [
                'MENDER_ARTIFACT_SIGNING_KEY = "%s"'
                % os.path.join(os.getcwd(), signing_key("RSA").private),
                'MENDER_ARTIFACT_VERIFY_KEY = "%s"'
                % os.path.join(os.getcwd(), signing_key("RSA").public),
            ],
        )

        built_rootfs = latest_build_artifact(
            request, prepared_test_build["build_dir"], "core-image*.ext[234]"
        )
        # Copy out the key we just added from the image and use that to
        # verify instead of the original, just to be sure.
        subprocess.check_call(
            [
                "debugfs",
                "-R",
                "dump -p /etc/mender/artifact-verify-key.pem artifact-verify-key.pem",
                built_rootfs,
            ]
        )
        try:
            built_artifact = latest_build_artifact(
                request, prepared_test_build["build_dir"], "core-image*.mender"
            )
            output = subprocess.check_output(
                [
                    "mender-artifact",
                    "read",
                    "-k",
                    os.path.join(os.getcwd(), "artifact-verify-key.pem"),
                    built_artifact,
                ]
            ).decode()
            assert output.find("Signature: signed and verified correctly") >= 0

        finally:
            os.remove("artifact-verify-key.pem")
コード例 #10
0
    def test_bootloader_embed(self, request, 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

        new_bb_vars = get_bitbake_variables(
            request,
            "core-image-minimal",
            prepared_test_build=prepared_test_build)

        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(request,
                                            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)
コード例 #11
0
def versioned_mender_image(request, prepared_test_build, latest_mender_image,
                           bitbake_variables, bitbake_image):
    """Gets the correct version of the artifact, whether it's the one we
    build by default, or one we have to produce ourselves.
    Returns a tuple of version and built image."""

    global LAST_BUILD_VERSION

    version = request.param

    if version == 1:
        pytest.fail()

    if (version >= 2 and not version_is_minimum(
            bitbake_variables, "mender-artifact", "2.0.0")) or (
                version >= 3 and not version_is_minimum(
                    bitbake_variables, "mender-artifact", "3.0.0")):
        pytest.skip("Requires version %d of mender-artifact format." % version)

    if version_is_minimum(bitbake_variables, "mender-artifact", "3.0.0"):
        default_version = 3
    elif version_is_minimum(bitbake_variables, "mender-artifact", "2.0.0"):
        default_version = 2
    else:
        default_version = 2

    if LAST_BUILD_VERSION != version:
        # Run a separate build for this artifact. This doesn't conflict with the
        # above version because the non-default version ends up in a different
        # directory.
        if version != default_version:
            build_image(
                prepared_test_build["build_dir"],
                prepared_test_build["bitbake_corebase"],
                bitbake_image,
                ['MENDER_ARTIFACT_EXTRA_ARGS = "-v %d"' % version],
            )
        else:
            build_image(
                prepared_test_build["build_dir"],
                prepared_test_build["bitbake_corebase"],
                bitbake_image,
            )

        LAST_BUILD_VERSION = version
    return (
        version,
        latest_build_artifact(request, prepared_test_build["build_dir"],
                              "core-image*.mender"),
    )
コード例 #12
0
    def test_mender_dbus_interface_file(self, request, prepared_test_build,
                                        bitbake_image):
        """
        Test the D-Bus interface file is provided by the mender-client-dev package,
        but not installed by default.
        """

        EXPECTED_FILES = [
            "io.mender.Authentication1.xml",
            "io.mender.Update1.xml",
        ]

        for dbus_enabled in [True, False]:

            # clean up the mender-client
            build_image(
                prepared_test_build["build_dir"],
                prepared_test_build["bitbake_corebase"],
                bitbake_image,
                target="-c clean mender-client",
            )

            # build mender-client
            maybe_remove_dbus = []
            if not dbus_enabled:
                maybe_remove_dbus.append('PACKAGECONFIG_remove = "dbus"')
            build_image(
                prepared_test_build["build_dir"],
                prepared_test_build["bitbake_corebase"],
                "mender-client",
                extra_conf_params=maybe_remove_dbus,
            )

            # verify the files
            deploy_dir_rpm = os.path.join(prepared_test_build["build_dir"],
                                          "tmp", "deploy", "rpm")
            output = subprocess.check_output(
                ["rpm", "-qlp", f"{deploy_dir_rpm}/*/mender-client-dev-*.rpm"
                 ], )
            for file in EXPECTED_FILES:
                if dbus_enabled:
                    assert (
                        bytes(file, "utf-8") in output
                    ), f"{file} seems not to be a part of the mender-client-dev package, like it should"
                else:
                    assert (
                        bytes(file, "utf-8") not in output
                    ), f"{file} seems to be a part of the mender-client-dev package, but it should not"
コード例 #13
0
    def test_module_install(self, request, prepared_test_build, bitbake_path,
                            latest_rootfs, bitbake_image):
        mender_vars = get_bitbake_variables(request, "mender-client")
        if "modules" in mender_vars["PACKAGECONFIG"].split():
            originally_on = True
        else:
            originally_on = False

        output = subprocess.check_output(
            ["debugfs", "-R", "ls -p /usr/share/mender",
             latest_rootfs]).decode()
        entries = [
            elem.split("/")[5] for elem in output.split("\n")
            if elem.startswith("/")
        ]

        if originally_on:
            assert "modules" in entries
            build_image(
                prepared_test_build["build_dir"],
                prepared_test_build["bitbake_corebase"],
                bitbake_image,
                ['PACKAGECONFIG_remove = "modules"'],
            )
        else:
            assert "modules" not in entries
            build_image(
                prepared_test_build["build_dir"],
                prepared_test_build["bitbake_corebase"],
                bitbake_image,
                ['PACKAGECONFIG_append = " modules"'],
            )

        new_rootfs = latest_build_artifact(request,
                                           prepared_test_build["build_dir"],
                                           "core-image*.ext4")

        output = subprocess.check_output(
            ["debugfs", "-R", "ls -p /usr/share/mender", new_rootfs]).decode()
        entries = [
            elem.split("/")[5] for elem in output.split("\n")
            if elem.startswith("/")
        ]

        if originally_on:
            assert "modules" not in entries
        else:
            assert "modules" in entries
コード例 #14
0
    def test_older_uboot_build(self, request, prepared_test_build,
                               bitbake_image):
        """Test that we can provide our own custom U-Boot provider."""

        # Get rid of build outputs in deploy directory that may get in the way.
        build_image(
            prepared_test_build["build_dir"],
            prepared_test_build["bitbake_corebase"],
            bitbake_image,
            target="-c clean u-boot",
        )

        try:
            build_image(
                prepared_test_build["build_dir"],
                prepared_test_build["bitbake_corebase"],
                bitbake_image,
                [
                    'PREFERRED_PROVIDER_u-boot = "u-boot-testing"',
                    'PREFERRED_RPROVIDER_u-boot = "u-boot-testing"',
                ],
            )

        finally:
            # Get rid of build outputs in deploy directory that may get in the
            # way.
            build_image(
                prepared_test_build["build_dir"],
                prepared_test_build["bitbake_corebase"],
                bitbake_image,
                target="-c clean u-boot-testing",
            )

        # Reset local.conf.
        reset_build_conf(prepared_test_build["build_dir"])

        bitbake_vars = get_bitbake_variables(
            request, "u-boot", prepared_test_build=prepared_test_build)
        if bitbake_vars["MENDER_UBOOT_AUTO_CONFIGURE"] == "0":
            # The rest of the test is irrelevant if MENDER_UBOOT_AUTO_CONFIGURE
            # is already off.
            return

        try:
            # Capture and discard output, it looks very ugly in the log.
            build_image(
                prepared_test_build["build_dir"],
                prepared_test_build["bitbake_corebase"],
                bitbake_image,
                ['MENDER_UBOOT_AUTO_CONFIGURE_pn-u-boot = "0"'],
                capture=True,
            )

            pytest.fail(
                "Build should not succeed when MENDER_UBOOT_AUTO_CONFIGURE is turned off"
            )
        except subprocess.CalledProcessError:
            pass
コード例 #15
0
    def test_image_rootfs_extra_space(self, request, prepared_test_build,
                                      bitbake_variables, bitbake_image):
        """Test that setting IMAGE_ROOTFS_EXTRA_SPACE to arbitrary values does
        not break the build."""

        build_image(
            prepared_test_build["build_dir"],
            prepared_test_build["bitbake_corebase"],
            bitbake_image,
            ['IMAGE_ROOTFS_EXTRA_SPACE_append = " + 640 - 222 + 900"'],
        )

        built_rootfs = latest_build_artifact(request,
                                             prepared_test_build["build_dir"],
                                             "core-image*.ext4")

        assert (os.stat(built_rootfs).st_size == int(
            bitbake_variables["MENDER_CALC_ROOTFS_SIZE"]) * 1024)
コード例 #16
0
    def test_various_mtd_combinations(self, request, test_case_name, test_case,
                                      prepared_test_build, bitbake_image):
        """Tests that we can build with various combinations of MTD variables,
        and that they receive the correct values."""

        try:
            build_image(
                prepared_test_build["build_dir"],
                prepared_test_build["bitbake_corebase"],
                bitbake_image,
                ["\n".join(test_case["vars"])],
            )
            assert test_case["success"], "Build succeeded, but should fail"
        except subprocess.CalledProcessError:
            assert not test_case["success"], "Build failed"

        variables = get_bitbake_variables(
            request, bitbake_image, prepared_test_build=prepared_test_build)

        for key in test_case["expected"]:
            assert test_case["expected"][key] == variables[key]
コード例 #17
0
    def test_build_artifact_depends_and_provides(self, request,
                                                 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(request,
                                      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__
コード例 #18
0
    def test_bootimg_creation(
        self, request, bitbake_variables, prepared_test_build, bitbake_image
    ):
        """Test that we can build a bootimg successfully."""

        build_image(
            prepared_test_build["build_dir"],
            prepared_test_build["bitbake_corebase"],
            bitbake_image,
            ['IMAGE_FSTYPES = "bootimg"'],
        )

        built_img = latest_build_artifact(
            request, prepared_test_build["build_dir"], "core-image*.bootimg"
        )

        distro_features = bitbake_variables["MENDER_FEATURES"].split()
        if "mender-grub" in distro_features and "mender-image-uefi" in distro_features:
            output = subprocess.check_output(
                ["mdir", "-i", built_img, "-b", "/EFI/BOOT"]
            ).decode()
            assert "mender_grubenv1" in output.split("/")
コード例 #19
0
    def test_build_addon(
        self, request, bitbake_variables, prepared_test_build, bitbake_image
    ):
        build_image(
            prepared_test_build["build_dir"],
            prepared_test_build["bitbake_corebase"],
            bitbake_image,
            ['IMAGE_INSTALL_append = " mender-monitor"'],
            [
                'BBLAYERS_append = " %s/../meta-mender-commercial"'
                % bitbake_variables["LAYERDIR_MENDER"]
            ],
        )
        image = latest_build_artifact(
            request, prepared_test_build["build_dir"], "core-image*.ext4"
        )

        for expected_node in (
            "/usr/bin/mender-monitorctl",
            "/usr/bin/mender-monitord",
            "/etc/mender-monitor/monitor.d/log.sh",
            "/etc/mender-monitor/monitor.d/service.sh",
            "/usr/share/mender-monitor/mender-monitorctl",
            "/usr/share/mender-monitor/mender-monitord",
            "/usr/share/mender-monitor/ctl.sh",
            "/usr/share/mender-monitor/daemon.sh",
            "/usr/share/mender-monitor/common/common.sh",
            "/usr/share/mender-monitor/config/config.sh",
            "/usr/share/mender-monitor/lib/monitor-lib.sh",
            "/usr/share/mender-monitor/lib/service-lib.sh",
            "/var/lib/mender-monitor",
        ):
            output = subprocess.check_output(
                ["debugfs", "-R", "stat %s" % expected_node, image]
            ).decode()

            # The nodes are either files or symlinks
            assert "Type: regular" in output or "Type: symlink" in output
コード例 #20
0
    def test_build_mender_gateway(self, request, bitbake_variables,
                                  prepared_test_build, bitbake_image):
        build_image(
            prepared_test_build["build_dir"],
            prepared_test_build["bitbake_corebase"],
            bitbake_image,
            ['IMAGE_INSTALL_append = " mender-gateway"'],
            [
                'BBLAYERS_append = " %s/../meta-mender-commercial"' %
                bitbake_variables["LAYERDIR_MENDER"]
            ],
        )
        image = latest_build_artifact(request,
                                      prepared_test_build["build_dir"],
                                      "core-image*.ext4")

        for file in (
                "/usr/bin/mender-gateway",
                "/usr/share/mender/inventory/mender-inventory-mender-gateway",
        ):
            output = subprocess.check_output(
                ["debugfs", "-R", f"stat {file}", image]).decode()
            assert "Type: regular" in output
コード例 #21
0
    def test_mender_dbus_interface_file(
        self, request, prepared_test_build, bitbake_image
    ):
        """
        Test the D-Bus interface file is provided by the mender-client-dev package,
        but not installed by default.
        """

        EXPECTED_FILES = [
            "io.mender.Authentication1.xml",
        ]

        # clean up the mender-client
        build_image(
            prepared_test_build["build_dir"],
            prepared_test_build["bitbake_corebase"],
            bitbake_image,
            target="-c clean mender-client",
        )

        # build mender-client
        build_image(
            prepared_test_build["build_dir"],
            prepared_test_build["bitbake_corebase"],
            "mender-client",
        )

        # verify the files
        deploy_dir_rpm = get_bitbake_variables(request, bitbake_image)["DEPLOY_DIR_RPM"]
        output = subprocess.check_output(
            ["rpm", "-qlp", f"{deploy_dir_rpm}/*/mender-client-dev-*.rpm"],
        )
        for file in EXPECTED_FILES:
            assert (
                bytes(file, "utf-8") in output
            ), f"{file} seems not to be a part of the mender-client-dev package, like it should"
コード例 #22
0
    def do_install_mender_binary_delta(
        self,
        request,
        prepared_test_build,
        bitbake_variables,
        bitbake_image,
        connection,
        http_server,
        board_type,
        use_s3,
        s3_address,
    ):
        build_image(
            prepared_test_build["build_dir"],
            prepared_test_build["bitbake_corebase"],
            bitbake_image,
            ['IMAGE_INSTALL_append = " mender-binary-delta"'],
            [
                'BBLAYERS_append = " %s/../meta-mender-commercial"' %
                bitbake_variables["LAYERDIR_MENDER"]
            ],
        )

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

        Helpers.install_update(image, connection, http_server, board_type,
                               use_s3, s3_address)

        reboot(connection)

        run_after_connect("true", connection)
        connection.run("mender -commit")

        return image
コード例 #23
0
    def test_boot_partition_population(self, request, 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(request,
                                      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")
コード例 #24
0
    def test_extra_parts(self, request, latest_part_image, prepared_test_build,
                         bitbake_image):
        sdimg = latest_part_image.endswith(".sdimg")
        uefiimg = latest_part_image.endswith(".uefiimg")
        gptimg = latest_part_image.endswith(".gptimg")
        biosimg = latest_part_image.endswith(".biosimg")

        with make_tempdir() as tmpdir1, make_tempdir(
        ) as tmpdir2, make_tempdir() as tmpdir3, make_tempdir() as tmpdir4:
            with open(os.path.join(tmpdir1, "tmpfile1"), "w") as fd:
                fd.write("Test content1\n")
            with open(os.path.join(tmpdir2, "tmpfile2"), "w") as fd:
                fd.write("Test content2\n")
            with open(os.path.join(tmpdir3, "tmpfile3"), "w") as fd:
                fd.write("Test content3\n")
            with open(os.path.join(tmpdir4, "tmpfile4"), "w") as fd:
                fd.write("Test content4\n")

            build_image(
                prepared_test_build["build_dir"],
                prepared_test_build["bitbake_corebase"],
                bitbake_image,
                [
                    'MENDER_EXTRA_PARTS = "test1 test2 test3 test4"',
                    'MENDER_EXTRA_PARTS[test1] = "--fixed-size 100M --label=test1 --fstype=ext4 --source rootfs --rootfs-dir %s"'
                    % tmpdir1,
                    'MENDER_EXTRA_PARTS[test2] = "--fixed-size 50M --fstype=ext4 --source rootfs --rootfs-dir %s --label=test2"'
                    % tmpdir2,
                    'MENDER_EXTRA_PARTS[test3] = "--fixed-size 50M --fstype=ext4 --source rootfs --rootfs-dir %s --label=test3"'
                    % tmpdir3,
                    'MENDER_EXTRA_PARTS[test4] = "--fixed-size 50M --fstype=ext4 --source rootfs --rootfs-dir %s --label=test4"'
                    % tmpdir4,
                    'MENDER_EXTRA_PARTS_FSTAB[test1] = "auto nouser"',
                    'MENDER_EXTRA_PARTS_FSTAB[test2] = "ext4 default,ro"',
                    'MENDER_EXTRA_PARTS_FSTAB[test3] = "ext4 default,ro 1"',
                    'MENDER_EXTRA_PARTS_FSTAB[test4] = "ext4 default,ro 1 0"',
                ],
            )

        image = latest_build_artifact(request,
                                      prepared_test_build["build_dir"], "*img")

        # Take extended partition into account for MBR partition tables.
        if uefiimg or gptimg:
            # Example
            # 1           16384           49151   16.0 MiB    0700  Microsoft basic data
            # 2           49152          507903   224.0 MiB   8300  Linux filesystem
            # 3          507904          966655   224.0 MiB   8300  Linux filesystem
            # 4          983040         1245183   128.0 MiB   8300  Linux filesystem
            # 5         1261568         1466367   100.0 MiB   8300  Linux filesystem
            # 6         1474560         1679359   100.0 MiB   8300  Linux filesystem
            output = subprocess.check_output(["sgdisk", "-p", image]).decode()
            test1_re = r"^\s*5\s+([0-9]+)\s+([0-9]+)\s+100.0\s+MiB\s+8300\s+"
            test2_re = r"^\s*6\s+([0-9]+)\s+([0-9]+)\s+50.0\s+MiB\s+8300\s+"
            test3_re = r"^\s*7\s+([0-9]+)\s+([0-9]+)\s+50.0\s+MiB\s+8300\s+"
            test4_re = r"^\s*8\s+([0-9]+)\s+([0-9]+)\s+50.0\s+MiB\s+8300\s+"
            extra_start = 5
        else:
            # Example:
            # ...sdimg1 *      16384   49151   32768   16M  c W95 FAT32 (LBA)
            # ...sdimg2        49152  507903  458752  224M 83 Linux
            # ...sdimg3       507904  966655  458752  224M 83 Linux
            # ...sdimg4       983039 1576959  593921  290M  f W95 Ext'd (LBA)
            # ...sdimg5       983040 1245183  262144  128M 83 Linux
            # ...sdimg6      1261568 1466367  204800  100M 83 Linux
            # ...sdimg7      1474560 1576959  102400   50M 83 Linux
            output = subprocess.check_output(["fdisk", "-l", image]).decode()
            test1_re = r"img6(?:\s|\*)+([0-9]+)\s+([0-9]+)\s+[0-9]+\s+100M\s+83\s+"
            test2_re = r"img7(?:\s|\*)+([0-9]+)\s+([0-9]+)\s+[0-9]+\s+50M\s+83\s+"
            test3_re = r"img8(?:\s|\*)+([0-9]+)\s+([0-9]+)\s+[0-9]+\s+50M\s+83\s+"
            test4_re = r"img9(?:\s|\*)+([0-9]+)\s+([0-9]+)\s+[0-9]+\s+50M\s+83\s+"
            extra_start = 6

        match1 = re.search(test1_re, output, flags=re.MULTILINE)
        match2 = re.search(test2_re, output, flags=re.MULTILINE)
        match3 = re.search(test3_re, output, flags=re.MULTILINE)
        match4 = re.search(test4_re, output, flags=re.MULTILINE)
        assert match1 is not None
        assert match2 is not None
        assert match3 is not None
        assert match4 is not None

        ext4 = latest_build_artifact(request, prepared_test_build["build_dir"],
                                     "*.ext4")
        fstab = subprocess.check_output(
            ["debugfs", "-R", "cat /etc/fstab", ext4]).decode()

        # Example:
        # /dev/mmcblk0p5       /mnt/test1           auto       nouser                0  2
        # /dev/mmcblk0p6       /mnt/test2           auto       default,ro            0  2
        # /dev/mmcblk0p7       /mnt/test3           auto       default,ro            1  2
        # /dev/mmcblk0p8       /mnt/test4           auto       default,ro            1  0

        test1_re = (
            r"^/dev/[a-z0-9]+%d\s+/mnt/test1\s+auto\s+nouser\s+0\s+2\s*$" %
            extra_start)
        test2_re = r"^/dev/[a-z0-9]+%d\s+/mnt/test2\s+ext4\s+default,ro\s+0\s+2\s*$" % (
            extra_start + 1)
        test3_re = r"^/dev/[a-z0-9]+%d\s+/mnt/test3\s+ext4\s+default,ro\s+1\s+2\s*$" % (
            extra_start + 2)
        test4_re = r"^/dev/[a-z0-9]+%d\s+/mnt/test4\s+ext4\s+default,ro\s+1\s+0\s*$" % (
            extra_start + 3)
        assert re.search(test1_re, fstab, flags=re.MULTILINE) is not None
        assert re.search(test2_re, fstab, flags=re.MULTILINE) is not None
        assert re.search(test3_re, fstab, flags=re.MULTILINE) is not None
        assert re.search(test4_re, fstab, flags=re.MULTILINE) is not None
コード例 #25
0
    def test_perform_update(
        self,
        request,
        setup_board,
        prepared_test_build,
        bitbake_variables,
        bitbake_image,
        connection,
        http_server,
        board_type,
        use_s3,
        s3_address,
    ):
        """Perform a delta update.

        """

        if ("read-only-rootfs"
                not in bitbake_variables["IMAGE_FEATURES"].strip().split()):
            pytest.skip("Only works when using read-only-rootfs IMAGE_FEATURE")

        if distutils.spawn.find_executable(
                "mender-binary-delta-generator") is None:
            pytest.fail("mender-binary-delta-generator not found in PATH")

        built_artifact = self.do_install_mender_binary_delta(
            request,
            prepared_test_build,
            bitbake_variables,
            bitbake_image,
            connection,
            http_server,
            board_type,
            use_s3,
            s3_address,
        )

        with make_tempdir() as tmpdir:
            # Copy previous build
            artifact_from = os.path.join(tmpdir, "artifact_from.mender")
            shutil.copyfile(built_artifact, artifact_from)

            # Create new image installing some extra software
            build_image(
                prepared_test_build["build_dir"],
                prepared_test_build["bitbake_corebase"],
                bitbake_image,
                ['IMAGE_INSTALL_append = " nano"'],
            )
            built_artifact = latest_build_artifact(
                request, prepared_test_build["build_dir"],
                "core-image*.mender")
            artifact_to = os.path.join(tmpdir, "artifact_to.mender")
            shutil.copyfile(built_artifact, artifact_to)

            # Create delta Artifact using mender-binary-delta-generator
            artifact_delta = os.path.join(tmpdir, "artifact_delta.mender")
            subprocess.check_call(
                f"mender-binary-delta-generator -n v2.0-deltafrom-v1.0 {artifact_from} {artifact_to} -o {artifact_delta}",
                shell=True,
            )

            # Verbose provides/depends of the different Artifacts and the client (when supported)
            connection.run("mender show-provides", warn=True)
            subprocess.check_call(
                "mender-artifact read %s" % artifact_from,
                shell=True,
            )
            subprocess.check_call(
                "mender-artifact read %s" % artifact_to,
                shell=True,
            )
            subprocess.check_call(
                "mender-artifact read %s" % artifact_delta,
                shell=True,
            )

            # Install Artifact, verify partitions and commit
            (active,
             passive) = determine_active_passive_part(bitbake_variables,
                                                      connection)
            Helpers.install_update(artifact_delta, connection, http_server,
                                   board_type, use_s3, s3_address)
            reboot(connection)
            run_after_connect("true", connection)
            (new_active, new_passive) = determine_active_passive_part(
                bitbake_variables, connection)
            assert new_active == passive
            assert new_passive == active
            connection.run("mender -commit")
コード例 #26
0
    def test_incorrect_Kconfig_setting(self, request, prepared_test_build,
                                       bitbake_image):
        """First produce a patch using the auto-patcher, then disable
        auto-patching and apply the patch with a slight modification that makes
        its settings incompatible, and check that this is detected."""

        bitbake_variables = get_bitbake_variables(
            request, "u-boot", prepared_test_build=prepared_test_build)

        # Only run if auto-configuration is on.
        if ("MENDER_UBOOT_AUTO_CONFIGURE" in bitbake_variables
                and bitbake_variables["MENDER_UBOOT_AUTO_CONFIGURE"] == "0"):
            pytest.skip(
                "Test is not applicable when MENDER_UBOOT_AUTO_CONFIGURE is off"
            )

        build_image(
            prepared_test_build["build_dir"],
            prepared_test_build["bitbake_corebase"],
            bitbake_image,
            target="-c save_mender_auto_configured_patch u-boot",
        )

        try:
            patch_name = os.path.join(bitbake_variables["WORKDIR"],
                                      "mender_auto_configured.patch")
            new_patch_name = "../../meta-mender-core/recipes-bsp/u-boot/patches/mender_broken_definition.patch"
            with open(patch_name) as patch, open(new_patch_name,
                                                 "w") as new_patch:
                for line in patch.readlines():
                    if line.startswith("+CONFIG_MTDIDS_DEFAULT="):
                        # Change to a wrong value:
                        new_patch.write(
                            '+CONFIG_MTDIDS_DEFAULT="nand0-wrongvalue=00000000.flash"\n'
                        )
                    else:
                        new_patch.write(line)

            # We need to add the code using TEST_SRC_URI_APPEND make sure it is
            # absolutely last, otherwise platform specific layers may add
            # patches after us.

            # Normally changes to SRC_URI are picked up automatically, but since
            # we are sneaking it in via the TEST_SRC_URI_APPEND and its
            # associated python snippet, we need to clean the build manually.

            build_image(
                prepared_test_build["build_dir"],
                prepared_test_build["bitbake_corebase"],
                bitbake_image,
                [
                    'MENDER_UBOOT_AUTO_CONFIGURE_pn-u-boot = "0"',
                    'TEST_SRC_URI_APPEND_pn-u-boot = " file://%s"' %
                    os.path.basename(new_patch_name),
                ],
                target="-c clean u-boot",
            )

            try:
                build_image(
                    prepared_test_build["build_dir"],
                    prepared_test_build["bitbake_corebase"],
                    bitbake_image,
                    target="-c compile u-boot",
                )

                # Should never get here.
                pytest.fail(
                    "Bitbake succeeded even though we intentionally broke the patch!"
                )

            except subprocess.CalledProcessError as e:
                # A bit risky change after upgrading tests from python2.7 to python3.
                # It seems that underneath subprocess.check_output() call in not
                # capturing the output as `capture_output` flag is not set.
                if e.output:
                    assert e.output.find(
                        "Please fix U-Boot's configuration file") >= 0

        finally:
            build_image(
                prepared_test_build["build_dir"],
                prepared_test_build["bitbake_corebase"],
                bitbake_image,
                target="-c clean u-boot",
            )
            os.unlink(new_patch_name)
コード例 #27
0
    def test_save_mender_auto_configured_patch(self, request,
                                               prepared_test_build,
                                               bitbake_image):
        """Test that we can invoke the save_mender_auto_configured_patch task,
        that it produces a patch file, and that this patch file can be used
        instead of MENDER_UBOOT_AUTO_CONFIGURE."""

        bitbake_variables = get_bitbake_variables(
            request, "u-boot", prepared_test_build=prepared_test_build)

        # Only run if auto-configuration is on.
        if ("MENDER_UBOOT_AUTO_CONFIGURE" in bitbake_variables
                and bitbake_variables["MENDER_UBOOT_AUTO_CONFIGURE"] == "0"):
            pytest.skip(
                "Test is not applicable when MENDER_UBOOT_AUTO_CONFIGURE is off"
            )

        build_image(
            prepared_test_build["build_dir"],
            prepared_test_build["bitbake_corebase"],
            bitbake_image,
            target="-c save_mender_auto_configured_patch u-boot",
        )

        patch_name = os.path.join(bitbake_variables["WORKDIR"],
                                  "mender_auto_configured.patch")
        with open(patch_name) as fd:
            content = fd.read()
            # Make sure it looks like a patch.
            assert "---" in content
            assert "+++" in content

        # Now check if we can use the patch.
        new_patch_name = "../../meta-mender-core/recipes-bsp/u-boot/patches/mender_auto_configured.patch"
        shutil.copyfile(patch_name, new_patch_name)

        try:
            # We need to add the code using TEST_SRC_URI_APPEND make sure it is
            # absolutely last, otherwise platform specific layers may add
            # patches after us.

            # Normally changes to SRC_URI are picked up automatically, but since
            # we are sneaking it in via the TEST_SRC_URI_APPEND and its
            # associated python snippet, we need to clean the build manually.
            build_image(
                prepared_test_build["build_dir"],
                prepared_test_build["bitbake_corebase"],
                bitbake_image,
                [
                    'MENDER_UBOOT_AUTO_CONFIGURE_pn-u-boot = "0"',
                    'TEST_SRC_URI_APPEND_pn-u-boot = " file://%s"' %
                    os.path.basename(new_patch_name),
                ],
                target="-c clean u-boot",
            )

            build_image(
                prepared_test_build["build_dir"],
                prepared_test_build["bitbake_corebase"],
                bitbake_image,
                target="u-boot",
            )

        finally:
            build_image(
                prepared_test_build["build_dir"],
                prepared_test_build["bitbake_corebase"],
                bitbake_image,
                target="-c clean u-boot",
            )
            os.unlink(new_patch_name)
コード例 #28
0
    def test_state_scripts(
        self,
        request,
        prepared_test_build,
        bitbake_variables,
        bitbake_path,
        latest_rootfs,
        latest_mender_image,
        bitbake_image,
    ):
        """Test that state scripts that are specified in the build are included
        correctly."""

        # First verify that the base build does *not* contain any state scripts.
        # Check rootfs.
        output = subprocess.check_output(
            ["debugfs", "-R", "ls -p /etc/mender", latest_rootfs]).decode()
        for line in output.split("\n"):
            if len(line) == 0:
                continue

            entry = line.split("/")
            if entry[5] == "scripts":
                # The scripts directory exists. That is fine in itself, but it
                # should not contain any script files ("version" is allowed).
                output = subprocess.check_output([
                    "debugfs", "-R", "ls -p /etc/mender/scripts", latest_rootfs
                ]).decode()
                for line in output.split("\n"):
                    if len(line) == 0:
                        continue

                    entry = line.split("/")
                    assert (
                        entry[5] == "." or entry[5] == ".."
                        or entry[5] == "version"
                    ), "There should be no script file in /etc/mender/scripts"
                break

        # Check artifact.
        output = subprocess.check_output("tar xOf %s header.tar.gz| tar tz" %
                                         latest_mender_image,
                                         shell=True).decode()
        for line in output.strip().split("\n"):
            if line == "scripts":
                output = subprocess.check_output(
                    "tar xOf %s header.tar.gz| tar tz scripts" %
                    latest_mender_image,
                    shell=True,
                ).decode()
                assert len(output.strip()) == 0, (
                    "Unexpected scripts in base image: %s" % output)

        try:
            # Alright, now build a new image containing scripts.
            build_image(
                prepared_test_build["build_dir"],
                prepared_test_build["bitbake_corebase"],
                bitbake_image,
                ['IMAGE_INSTALL_append = " example-state-scripts"'],
            )

            found_rootfs_scripts = {
                "version": False,
                "Idle_Enter_00": False,
                "Sync_Enter_10": False,
                "Sync_Leave_90": False,
            }
            found_artifact_scripts = {
                "ArtifactInstall_Enter_00": False,
                "ArtifactInstall_Leave_99": False,
                "ArtifactReboot_Leave_50": False,
                "ArtifactCommit_Enter_50": False,
                "ArtifactCommit_Leave_50": False,
            }

            # Check new rootfs.
            built_rootfs = latest_build_artifact(
                request, prepared_test_build["build_dir"],
                "core-image*.ext[234]")
            output = subprocess.check_output(
                ["debugfs", "-R", "ls -p /etc/mender/scripts",
                 built_rootfs]).decode()
            for line in output.split("\n"):
                if len(line) == 0:
                    continue

                entry = line.split("/")

                if entry[5] == "." or entry[5] == "..":
                    continue

                assert found_rootfs_scripts.get(
                    entry[5]) is not None, ("Unexpected script in rootfs %s" %
                                            entry[5])
                found_rootfs_scripts[entry[5]] = True

            for script in found_rootfs_scripts:
                assert found_rootfs_scripts[script], (
                    "%s not found in rootfs script list" % script)

            # Check new artifact.
            built_mender_image = latest_build_artifact(
                request, prepared_test_build["build_dir"],
                "core-image*.mender")
            output = subprocess.check_output(
                "tar xOf %s header.tar.gz| tar tz scripts" %
                built_mender_image,
                shell=True,
            ).decode()
            for line in output.strip().split("\n"):
                script = os.path.basename(line)
                assert found_artifact_scripts.get(script) is not None, (
                    "Unexpected script in image: %s" % script)
                found_artifact_scripts[script] = True

            for script in found_artifact_scripts:
                assert found_artifact_scripts[script], (
                    "%s not found in artifact script list" % script)

        finally:
            # Clean up the state scripts directory. Ideally this wouldn't be
            # necessary, but unfortunately bitbake does not clean up deployment
            # files from recipes that are not included in the current build, so
            # we have to do it manually.
            build_image(
                prepared_test_build["build_dir"],
                prepared_test_build["bitbake_corebase"],
                bitbake_image,
                target="-c clean example-state-scripts",
            )
コード例 #29
0
    def test_equal_checksum_ubimg_and_artifact(self, request,
                                               prepared_test_build,
                                               bitbake_image):

        # See ubimg_without_uboot_env() for why this is needed. We need to do it
        # explicitly here because we need both the artifact and the ubimg.

        build_image(
            prepared_test_build["build_dir"],
            prepared_test_build["bitbake_corebase"],
            bitbake_image,
            ['MENDER_FEATURES_DISABLE_append = " mender-uboot"'],
        )

        bufsize = 1048576  # 1MiB
        with tempfile.NamedTemporaryFile() as tmp_artifact:
            latest_mender_image = latest_build_artifact(
                request, prepared_test_build["build_dir"], "*.mender")
            subprocess.check_call(
                "tar xOf %s data/0000.tar.gz | tar xzO > %s" %
                (latest_mender_image, tmp_artifact.name),
                shell=True,
            )
            size = os.stat(tmp_artifact.name).st_size
            hash = hashlib.md5()
            while True:
                buf = tmp_artifact.read(bufsize)
                if len(buf) == 0:
                    break
                hash.update(buf)
            artifact_hash = hash.hexdigest()
            artifact_info = subprocess.check_output(
                ["ubireader_display_info", tmp_artifact.name])
            artifact_ls = subprocess.check_output(
                ["ls", "-l", tmp_artifact.name])

        tmpdir = tempfile.mkdtemp()
        try:
            ubifsdir = extract_ubimg_images(
                latest_build_artifact(request,
                                      prepared_test_build["build_dir"],
                                      "*.ubimg"),
                tmpdir,
            )
            rootfsa = os.path.join(ubifsdir, [
                img for img in os.listdir(ubifsdir) if "rootfsa" in img
            ][0])
            bytes_read = 0
            hash = hashlib.md5()
            with open(rootfsa, "rb") as fd:
                while bytes_read < size:
                    buf = fd.read(min(size - bytes_read, bufsize))
                    if len(buf) == 0:
                        break
                    bytes_read += len(buf)
                    hash.update(buf)
                image_hash = hash.hexdigest()
            image_info = subprocess.check_output(
                ["ubireader_display_info", rootfsa])
            image_ls = subprocess.check_output(["ls", "-l", rootfsa])
        finally:
            shutil.rmtree(tmpdir)

        assert artifact_info == image_info
        assert artifact_hash == image_hash, "Artifact:\n%s\nImage:\n%s" % (
            artifact_ls,
            image_ls,
        )