Пример #1
0
def update_image_failed(install_image="broken_update.ext4",
                        expected_mender_clients=1):
    """
        Perform a upgrade using a broken image (random data)
        The device will reboot, uboot will detect this is not a bootable image, and revert to the previous partition.
        The resulting upgrade will be considered a failure.
    """

    devices_accepted = get_mender_clients()
    original_image_id = Helpers.yocto_id_installed_on_machine()

    previous_active_part = Helpers.get_active_partition()
    with Helpers.RebootDetector() as reboot:
        deployment_id, _ = common_update_procedure(install_image,
                                                   broken_image=True)
        reboot.verify_reboot_performed()

    with Helpers.RebootDetector() as reboot:
        assert Helpers.get_active_partition() == previous_active_part

        deploy.check_expected_statistics(deployment_id, "failure",
                                         expected_mender_clients)

        for d in adm.get_devices():
            assert "got invalid entrypoint into the state machine" in deploy.get_logs(
                d["device_id"], deployment_id)

        assert Helpers.yocto_id_installed_on_machine() == original_image_id
        reboot.verify_reboot_not_performed()

    deploy.check_expected_status("finished", deployment_id)
Пример #2
0
    def test_original_deployments_persisted(self):
        auth.reset_auth_token()
        auth.get_auth_token()

        # wait for 10 devices to be available
        devices = adm.get_devices_status("accepted", 10)
        provisioned_devices = eval(self.provisioned_devices)

        # check that devices and provisioned_devices are the same
        assert len(devices) == provisioned_devices
        # not sure what else I can do here, the device admission changed from 1.0 to master

        assert deploy.get_statistics(
            self.provisioned_deployment_id)["success"] == 7
        assert deploy.get_statistics(
            self.provisioned_deployment_id)["failure"] == 3

        # check failures still contain logs
        for device_deployment in deploy.get_deployment_overview(
                self.provisioned_deployment_id):
            if device_deployment["status"] == "failure":
                assert "damn" in deploy.get_logs(
                    device_deployment["id"], self.provisioned_deployment_id)

        deployments_in_progress = deploy.get_status("inprogress")
        deployments_pending = deploy.get_status("pending")
        deployments_finished = deploy.get_status("finished")

        assert len(deployments_in_progress) == 0
        assert len(deployments_pending) == 0
        assert len(deployments_finished) == 1

        assert self.provisioned_artifact_id in str(deployments_finished)
    def test_update_image_failed(self, install_image="broken_update.ext4"):
        """
            Perform a upgrade using a broken image (random data)
            The device will reboot, uboot will detect this is not a bootable image, and revert to the previous partition.
            The resulting upgrade will be considered a failure.
        """
        if not env.host_string:
            execute(self.test_update_image_failed,
                    hosts=get_mender_clients(),
                    install_image=install_image)
            return

        devices_accepted = get_mender_clients()
        original_image_id = Helpers.yocto_id_installed_on_machine()

        previous_active_part = Helpers.get_active_partition()
        deployment_id, _ = common_update_proceduce(install_image,
                                                   broken_image=True)

        Helpers.verify_reboot_performed()
        assert Helpers.get_active_partition() == previous_active_part

        deploy.check_expected_status(deployment_id, "failure",
                                     len(devices_accepted))

        for d in adm.get_devices():
            assert "running rollback image" in deploy.get_logs(
                d["id"], deployment_id)

        assert Helpers.yocto_id_installed_on_machine() == original_image_id
        Helpers.verify_reboot_not_performed()
Пример #4
0
def update_image_successful(install_image, regenerate_image_id=True, signed=False, skip_reboot_verification=False, expected_mender_clients=1):
    """
        Perform a successful upgrade, and assert that deployment status/logs are correct.

        A reboot is performed, and running partitions have been swapped.
        Deployment status will be set as successful for device.
        Logs will not be retrieved, and result in 404.
    """

    previous_inactive_part = Helpers.get_passive_partition()
    with Helpers.RebootDetector() as reboot:
        deployment_id, expected_image_id = common_update_procedure(install_image,
                                                                   regenerate_image_id,
                                                                   signed=signed)
        reboot.verify_reboot_performed()

    with Helpers.RebootDetector() as reboot:
        try:
            assert Helpers.get_active_partition() == previous_inactive_part
        except AssertionError:
            logs = []
            for d in adm.get_devices():
                logs.append(deploy.get_logs(d["device_id"], deployment_id))

            pytest.fail("device did not flip partitions during update, here are the device logs:\n\n %s" % (logs))


        deploy.check_expected_statistics(deployment_id, "success", expected_mender_clients)

        for d in adm.get_devices():
            deploy.get_logs(d["device_id"], deployment_id, expected_status=404)

        if not skip_reboot_verification:
            reboot.verify_reboot_not_performed()

    assert Helpers.yocto_id_installed_on_machine() == expected_image_id

    deploy.check_expected_status("finished", deployment_id)

    # make sure backend recognizes signed and unsigned images
    artifact_id = deploy.get_deployment(deployment_id)["artifacts"][0]
    artifact_info = deploy.get_artifact_details(artifact_id)
    assert artifact_info["signed"] is signed, "image was not correct recognized as signed/unsigned"

    return deployment_id
Пример #5
0
    def abort_deployment(self, abort_step=None, mender_performs_reboot=False):
        """
            Trigger a deployment, and cancel it within 15 seconds, make sure no deployment is performed.

            Args:
                mender_performs_reboot: if set to False, a manual reboot is performed and
                                            checks are performed.
                                        if set to True, wait until device is rebooted.
        """
        if not env.host_string:
            execute(self.abort_deployment,
                    abort_step=abort_step,
                    mender_performs_reboot=mender_performs_reboot,
                    hosts=get_mender_clients())
            return

        install_image=conftest.get_valid_image()
        expected_partition = Helpers.get_active_partition()
        expected_image_id = Helpers.yocto_id_installed_on_machine()
        with Helpers.RebootDetector() as reboot:
            deployment_id, _ = common_update_procedure(install_image, verify_status=False)

            if abort_step is not None:
                deploy.check_expected_statistics(deployment_id, abort_step, len(get_mender_clients()))
            deploy.abort(deployment_id)
            deploy.check_expected_statistics(deployment_id, "aborted", len(get_mender_clients()))

            # no deployment logs are sent by the client, is this expected?
            for d in adm.get_devices():
                deploy.get_logs(d["device_id"], deployment_id, expected_status=404)

            if mender_performs_reboot:
                # If Mender performs reboot, we need to wait for it to reboot
                # back into the original filesystem.
                reboot.verify_reboot_performed(number_of_reboots=2)
            else:
                # Else we reboot ourselves, just to make sure that we have not
                # unintentionally switched to the new partition.
                reboot.verify_reboot_not_performed()
                run("( sleep 10 ; reboot ) 2>/dev/null >/dev/null &")
                reboot.verify_reboot_performed()

        assert Helpers.get_active_partition() == expected_partition
        assert Helpers.yocto_id_installed_on_machine() == expected_image_id
        deploy.check_expected_status("finished", deployment_id)
    def abort_deployment(self, abort_step=None, mender_performs_reboot=False):
        """
            Trigger a deployment, and cancel it within 15 seconds, make sure no deployment is performed.

            Args:
                mender_performs_reboot: if set to False, a manual reboot is performed and
                                            checks are performed.
                                        if set to True, wait until device is rebooted.
        """
        if not env.host_string:
            execute(self.abort_deployment,
                    abort_step=abort_step,
                    mender_performs_reboot=mender_performs_reboot,
                    hosts=get_mender_clients())
            return

        install_image = conftest.get_valid_image()
        expected_partition = Helpers.get_active_partition()
        expected_image_id = Helpers.yocto_id_installed_on_machine()
        token = Helpers.place_reboot_token()
        deployment_id, _ = common_update_procedure(install_image,
                                                   verify_status=False)

        if abort_step is not None:
            deploy.check_expected_statistics(deployment_id, abort_step,
                                             len(get_mender_clients()))
        deploy.abort(deployment_id)
        deploy.check_expected_statistics(deployment_id, "aborted",
                                         len(get_mender_clients()))

        # no deployment logs are sent by the client, is this expected?
        for d in adm.get_devices():
            deploy.get_logs(d["device_id"], deployment_id, expected_status=404)

        if not mender_performs_reboot:
            token.verify_reboot_not_performed()
            run("( sleep 10 ; reboot ) 2>/dev/null >/dev/null &")

        token.verify_reboot_performed()

        assert Helpers.get_active_partition() == expected_partition
        assert Helpers.yocto_id_installed_on_machine() == expected_image_id
        deploy.check_expected_status("finished", deployment_id)
Пример #7
0
def update_image_successful(
        install_image=conftest.get_valid_image(), regenerate_image_id=True):
    """
        Perform a successful upgrade, and assert that deployment status/logs are correct.

        A reboot is performed, and running partitions have been swapped.
        Deployment status will be set as successful for device.
        Logs will not be retrieved, and result in 404.
    """

    previous_inactive_part = Helpers.get_passive_partition()
    deployment_id, expected_image_id = common_update_procedure(
        install_image, regenerate_image_id)

    Helpers.verify_reboot_performed()

    try:
        assert Helpers.get_active_partition() == previous_inactive_part
    except AssertionError:
        logs = []
        for d in adm.get_devices():
            logs.append(deploy.get_logs(d["device_id"], deployment_id))

        pytest.fail(
            "device did not flip partitions during update, here are the device logs:\n\n %s"
            % (logs))

    deploy.check_expected_statistics(deployment_id, "success",
                                     len(get_mender_clients()))

    for d in adm.get_devices():
        deploy.get_logs(d["device_id"], deployment_id, expected_status=404)

    Helpers.verify_reboot_not_performed()
    assert Helpers.yocto_id_installed_on_machine() == expected_image_id

    deploy.check_expected_status("finished", deployment_id)
    def test_unsigned_artifact_fails_deployment(self, standard_setup_with_signed_artifact_client):
        """
            Make sure that an unsigned image fails, and is handled by the backend.
            Notice that this test needs a fresh new version of the backend, since
            we installed a signed image earlier without a verification key in mender.conf
        """
        if not env.host_string:
            execute(self.test_unsigned_artifact_fails_deployment,
                    standard_setup_with_signed_artifact_client,
                    hosts=get_mender_clients())
            return

        deployment_id, _ = common_update_procedure(install_image=conftest.get_valid_image())
        deploy.check_expected_status("finished", deployment_id)
        deploy.check_expected_statistics(deployment_id, "failure", 1)

        for d in adm.get_devices():
            assert "expecting signed artifact, but no signature file found" in \
                deploy.get_logs(d["device_id"], deployment_id)
Пример #9
0
    def test_update_device_group(self):
        """
            Perform a successful upgrade on one group of devices, and assert that:
            * deployment status/logs are correct.
            * only the correct group is updated, not the other one.

            A reboot is performed, and running partitions have been swapped.
            Deployment status will be set as successful for device.
            Logs will not be retrieved, and result in 404.
        """

        # Beware that there will two parallel things going on below, one for
        # each group, hence a lot of separate execute() calls for each. We aim
        # to update the group alpha, not beta.

        clients = get_mender_clients()
        assert(len(clients) == 2)
        alpha = clients[0]
        bravo = clients[1]

        ip_to_device_id = Helpers.ip_to_device_id_map(clients)
        id_alpha = ip_to_device_id[alpha]
        id_bravo = ip_to_device_id[bravo]
        print("ID of alpha host: %s\nID of bravo host: %s" % (id_alpha, id_bravo))

        ret = execute(Helpers.get_passive_partition, hosts=clients)
        pass_part_alpha = ret[alpha]
        pass_part_bravo = ret[bravo]

        inv.put_device_in_group(id_alpha, "Update")

        @parallel
        def place_reboot_tokens():
            return Helpers.place_reboot_token()
        tokens = execute(place_reboot_tokens, hosts=clients)

        deployment_id, expected_image_id = common_update_procedure(conftest.get_valid_image(),
                                                                   devices=[id_alpha])

        @parallel
        def verify_reboot_performed_for_alpha_only(tokens):
            if env.host_string == alpha:
                tokens[alpha].verify_reboot_performed()
            elif env.host_string == bravo:
                # Extra long wait here, because a real update takes quite a lot
                # of time.
                tokens[bravo].verify_reboot_not_performed(180)
            else:
                raise Exception("verify_reboot_performed_for_alpha_only() called with unknown host")

        execute(verify_reboot_performed_for_alpha_only, tokens, hosts=clients)

        ret = execute(Helpers.get_passive_partition, hosts=clients)
        assert ret[alpha] != pass_part_alpha
        assert ret[bravo] == pass_part_bravo
        ret = execute(Helpers.get_active_partition, hosts=clients)
        assert ret[alpha] == pass_part_alpha
        assert ret[bravo] != pass_part_bravo

        deploy.check_expected_statistics(deployment_id, expected_status="success", expected_count=1)

        # No logs for either host: alpha because it was successful, bravo
        # because it should never have attempted an update in the first place.
        for id in [id_alpha, id_bravo]:
            deploy.get_logs(id, deployment_id, expected_status=404)

        assert execute(Helpers.yocto_id_installed_on_machine, hosts=alpha)[alpha] == expected_image_id
        assert execute(Helpers.yocto_id_installed_on_machine, hosts=bravo)[bravo] != expected_image_id

        # Important: Leave the groups as you found them: Empty.
        inv.delete_device_from_group(id_alpha, "Update")