예제 #1
0
    def test_update_image_id_already_installed(
        self, install_image=conftest.get_valid_image()):
        """Uploading an image with an incorrect name set results in failure and rollback."""

        if not env.host_string:
            execute(self.test_update_image_id_already_installed,
                    hosts=get_mender_clients(),
                    install_image=install_image)
            return

        with Helpers.RebootDetector() as reboot:
            deployment_id, expected_image_id = common_update_procedure(
                install_image, True)
            reboot.verify_reboot_performed()

        devices_accepted_id = [
            device["id"] for device in auth_v2.get_devices_status("accepted")
        ]
        deployment_id = deploy.trigger_deployment(
            name="New valid update",
            artifact_name=expected_image_id,
            devices=devices_accepted_id)

        deploy.check_expected_statistics(deployment_id, "already-installed",
                                         len(get_mender_clients()))
        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 = auth_v2.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

        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)
예제 #3
0
def common_update_procedure(install_image,
                            regenerate_image_id=True,
                            device_type=conftest.machine_name,
                            broken_image=False,
                            verify_status=True,
                            signed=False,
                            devices=None,
                            scripts=[],
                            pre_upload_callback=lambda: None,
                            pre_deployment_callback=lambda: None,
                            deployment_triggered_callback=lambda: None,
                            compression_type="gzip"):

    with artifact_lock:
        if broken_image:
            artifact_id = "broken_image_" + str(random.randint(0, 999999))
        elif regenerate_image_id:
            artifact_id = Helpers.artifact_id_randomize(install_image)
            logger.debug("randomized image id: " + artifact_id)
        else:
            artifact_id = Helpers.yocto_id_from_ext4(install_image)

        compression_arg = "--compression " + compression_type

        # create atrifact
        with tempfile.NamedTemporaryFile() as artifact_file:
            created_artifact = image.make_artifact(
                install_image,
                device_type,
                artifact_id,
                artifact_file,
                signed=signed,
                scripts=scripts,
                global_flags=compression_arg)

            if created_artifact:
                pre_upload_callback()
                deploy.upload_image(created_artifact)
                if devices is None:
                    devices = list(
                        set([
                            device["id"] for device in
                            auth_v2.get_devices_status("accepted")
                        ]))
                pre_deployment_callback()
                deployment_id = deploy.trigger_deployment(
                    name="New valid update",
                    artifact_name=artifact_id,
                    devices=devices)
            else:
                logger.warn("failed to create artifact")
                pytest.fail("error creating artifact")

    deployment_triggered_callback()
    # wait until deployment is in correct state
    if verify_status:
        deploy.check_expected_status("inprogress", deployment_id)

    return deployment_id, artifact_id
예제 #4
0
    def test_deployments_post_upgrade(self):
        auth_v2.get_devices_status("accepted", 10)

        # perform upgrade
        devices_to_update = list(
            set([
                device["id"]
                for device in auth_v2.get_devices_status("accepted",
                                                         expected_devices=10)
            ]))
        deployment_id, artifact_id = common_update_procedure(
            "core-image-full-cmdline-%s.ext4" % conftest.machine_name,
            device_type="test",
            devices=devices_to_update)

        deploy.check_expected_status("finished", deployment_id)
        assert deploy.get_statistics(deployment_id)["success"] == 7
        assert deploy.get_statistics(deployment_id)["failure"] == 3

        deploy.get_status("finished")
예제 #5
0
 def test_artifacts_persisted(self):
     devices_to_update = list(
         set([
             device["id"]
             for device in auth_v2.get_devices_status("accepted",
                                                      expected_devices=10)
         ]))
     deployment_id = deploy.trigger_deployment(
         name="artifact survived backed upgrade",
         artifact_name=self.provisioned_artifact_id,
         devices=devices_to_update)
     deploy.check_expected_status("finished", deployment_id)
예제 #6
0
    def accept_devices(self):
        auth_v2.check_expected_status("pending", len(get_mender_clients()))

        # iterate over devices and accept them
        for d in auth_v2.get_devices():
            auth_v2.set_device_auth_set_status(d["id"], d["auth_sets"][0]["id"], "accepted")
            logging.info("Accepting DeviceID: %s" % d["id"])

        # make sure all devices are accepted
        auth_v2.check_expected_status("accepted", len(get_mender_clients()))

        # make sure mender-store contains authtoken
        have_token()

        # print all device ids
        for device in auth_v2.get_devices_status("accepted"):
            logging.info("Accepted DeviceID: %s" % device["id"])
예제 #7
0
    def do_test_ok_preauth_and_bootstrap(self):
        """
            Test the happy path from preauthorizing a device to a successful bootstrap.
            Verify that the device/auth set appear correctly in devauth API results.
        """
        client = get_mender_clients()[0]

        # we'll use the same pub key for the preauth'd device, so get it
        res = execute(Client.get_pub_key, hosts=client)
        preauth_key = res[client].exportKey()

        # stick an extra newline on the key - this is how a device would send it
        preauth_key += '\n'

        # preauthorize a new device
        preauth_iddata = {"mac": "mac-preauth"}
        # serialize manually to avoid an extra space (id data helper doesn't insert one)
        preauth_iddata_str = "{\"mac\":\"mac-preauth\"}"

        r = auth_v2.preauth(json.loads(preauth_iddata_str), preauth_key)
        assert r.status_code == 201

        # verify the device appears correctly in api results
        devs = auth_v2.get_devices(2)

        dev_preauth = [d for d in devs if d['status'] == 'preauthorized']
        assert len(dev_preauth) == 1
        dev_preauth = dev_preauth[0]
        assert dev_preauth['identity_data'] == preauth_iddata_str
        assert dev_preauth['pubkey'] == preauth_key

        # make one of the existing devices the preauthorized device
        # by substituting id data and restarting
        res = execute(Client.substitute_id_data, preauth_iddata, hosts=client)
        res = execute(Client.restart, hosts=client)

        # verify api results - after some time the device should be 'accepted'
        for _ in range(120):
            time.sleep(15)
            dev_accepted = auth_v2.get_devices_status(status="accepted",
                                                      expected_devices=2)
            if len([d for d in dev_accepted
                    if d['status'] == 'accepted']) == 1:
                break

        logging.info("devices: " + str(dev_accepted))
        dev_accepted = [d for d in dev_accepted if d['status'] == 'accepted']
        logging.info("accepted devices: " + str(dev_accepted))

        execute(Client.get_logs, hosts=client)

        assert len(
            dev_accepted) == 1, "looks like the device was never accepted"
        dev_accepted = dev_accepted[0]
        logging.info("accepted device: " + str(dev_accepted))

        assert dev_accepted['identity_data'] == preauth_iddata_str
        assert dev_accepted['pubkey'] == preauth_key

        # verify device was issued a token
        res = execute(Client.have_authtoken, hosts=client)
        assert res[client]
예제 #8
0
    assert len(devices) == 10

    # accept all devices
    for d in devices:
        auth_v2.set_device_auth_set_status(d["id"], d["auth_sets"][0]["id"],
                                           "accepted")

    # make sure artifact tool in current workdir is being used
    os.environ["PATH"] = os.path.dirname(os.path.realpath(
        __file__)) + "/downloaded-tools" + os.pathsep + os.environ["PATH"]

    # perform upgrade
    devices_to_update = list(
        set([
            device["id"]
            for device in auth_v2.get_devices_status("accepted",
                                                     expected_devices=10)
        ]))
    deployment_id, artifact_id = common_update_procedure(
        "core-image-full-cmdline-%s.ext4" % machine_name,
        device_type="test",
        devices=devices_to_update)

    print("deployment_id=%s" % deployment_id)
    print("artifact_id=%s" % artifact_id)
    print("devices=%d" % len(devices))

if args.kill:
    subprocess.call([
        "docker-compose", "-p", conftest.docker_compose_instance, "down", "-v",
        "--remove-orphans"
    ])