示例#1
0
def setup_failover(request):
    env = container_factory.getFailoverServerSetup()
    request.addfinalizer(env.teardown)

    env.setup()
    reset_mender_api(env)

    env.device = MenderDevice(env.get_mender_clients()[0])
    env.device.ssh_is_opened()

    auth.reset_auth_token()
    devauth.accept_devices(1)

    return env
示例#2
0
def standard_setup_with_short_lived_token(request):
    env = container_factory.getShortLivedTokenSetup()
    request.addfinalizer(env.teardown)

    env.setup()

    env.device = MenderDevice(env.get_mender_clients()[0])
    env.device.ssh_is_opened()

    reset_mender_api(env)
    auth.reset_auth_token()
    devauth.accept_devices(1)

    return env
示例#3
0
def standard_setup_one_docker_client_bootstrapped(request):
    env = container_factory.getDockerClientSetup()
    request.addfinalizer(env.teardown)

    env.setup()

    env.device = MenderDevice(env.get_mender_clients()[0])
    env.device.ssh_is_opened()

    reset_mender_api(env)
    devauth.accept_devices(1)

    env.auth = auth
    return env
示例#4
0
    def setup_mender_connect_1_0(self, request):
        self.env = container_factory.getMenderClient_2_5()
        request.addfinalizer(self.env.teardown)
        self.env.setup()

        self.env.populate_clients(replicas=1)

        clients = self.env.get_mender_clients()
        assert len(clients) == 1, "Failed to setup client"
        self.env.device = MenderDevice(clients[0])
        self.env.device.ssh_is_opened()

        reset_mender_api(self.env)

        yield self.env
示例#5
0
def standard_setup_with_signed_artifact_client(request):
    env = container_factory.get_signed_artifact_client_setup()
    request.addfinalizer(env.teardown)

    env.setup()

    env.device = MenderDevice(env.get_mender_clients()[0])
    env.device.ssh_is_opened()

    reset_mender_api(env)
    auth.reset_auth_token()
    devauth.accept_devices(1)

    env.auth = auth
    return env
示例#6
0
    def _make_tenant(self, plan, env):
        tname = "tenant-{}".format(plan)
        email = "user@{}.com".format(tname)

        cli = CliTenantadm(containers_namespace=env.name)
        tid = cli.create_org(tname, email, "correcthorse", plan)

        tenant = cli.get_tenant(tid)
        tenant = json.loads(tenant)
        ttoken = tenant["tenant_token"]

        # the cli now sets all addons to 'enabled' -
        # disable them for initial 'all disabled' state
        update_tenant(
            tenant["id"],
            addons=[],
            container_manager=get_container_manager(),
        )

        auth = Authentication(name=tname,
                              username=email,
                              password="******")
        auth.create_org = False
        auth.reset_auth_token()
        devauth = DeviceAuthV2(auth)

        env.new_tenant_client("test-container-{}".format(plan), ttoken)
        device = MenderDevice(env.get_mender_clients()[0])
        devauth.accept_devices(1)

        devices = list(
            set([
                device["id"]
                for device in devauth.get_devices_status("accepted")
            ]))
        assert 1 == len(devices)

        tenant = Tenant(tname, tid, ttoken)
        u = User("", email, "correcthorse")

        tenant.users.append(u)
        tenant.device = device
        tenant.device_id = devices[0]
        tenant.auth = auth
        tenant.devauth = devauth

        return tenant
示例#7
0
    def test_multi_tenancy_deployment(self, enterprise_no_client, valid_image):
        """ Simply make sure we are able to run the multi tenancy setup and
           bootstrap 2 different devices to different tenants """

        auth.reset_auth_token()

        users = [
            {
                "email": "*****@*****.**",
                "password": "******",
                "username": "******",
                "container": "mender-client-deployment-1",
                "fail": False,
            },
            {
                "email": "*****@*****.**",
                "password": "******",
                "username": "******",
                "container": "mender-client-deployment-2",
                "fail": True,
            },
        ]

        for user in users:
            auth.new_tenant(user["username"], user["email"], user["password"])
            t = auth.current_tenant["tenant_token"]
            enterprise_no_client.new_tenant_client(user["container"], t)
            auth_v2.accept_devices(1)

        for user in users:
            auth.new_tenant(user["username"], user["email"], user["password"])

            assert len(inv.get_devices()) == 1

            mender_device = MenderDevice(
                enterprise_no_client.get_mender_client_by_container_name(
                    user["container"]))
            host_ip = enterprise_no_client.get_virtual_network_host_ip()
            if user["fail"]:
                update_image_failed(mender_device, host_ip)
            else:
                update_image(
                    mender_device,
                    host_ip,
                    install_image=valid_image,
                    skip_reboot_verification=True,
                )
示例#8
0
    def docker_env(self, request):
        env = container_factory.get_mender_client_2_5()
        request.addfinalizer(env.teardown)
        env.setup()

        env.populate_clients(replicas=1)

        clients = env.get_mender_clients()
        assert len(clients) == 1, "Failed to setup client"
        env.device = MenderDevice(clients[0])
        env.device.ssh_is_opened()

        reset_mender_api(env)
        devauth.accept_devices(1)

        env.devconnect = devconnect
        yield env
    def test_filetransfer(self, enterprise_no_client):
        u = User("", "*****@*****.**", "whatsupdoc")
        cli = CliTenantadm(containers_namespace=enterprise_no_client.name)
        tid = cli.create_org("os-tenant", u.name, u.pwd, plan="os")

        # FT requires "troubleshoot"
        update_tenant(
            tid,
            addons=["troubleshoot"],
            container_manager=get_container_manager(),
        )

        tenant = cli.get_tenant(tid)
        tenant = json.loads(tenant)

        auth = authentication.Authentication(name="os-tenant",
                                             username=u.name,
                                             password=u.pwd)
        auth.create_org = False
        auth.reset_auth_token()
        devauth_tenant = DeviceAuthV2(auth)

        enterprise_no_client.new_tenant_client("configuration-test-container",
                                               tenant["tenant_token"])
        mender_device = MenderDevice(
            enterprise_no_client.get_mender_clients()[0])
        mender_device.ssh_is_opened()

        devauth_tenant.accept_devices(1)

        devices = list(
            set([
                device["id"]
                for device in devauth_tenant.get_devices_status("accepted")
            ]))
        assert 1 == len(devices)

        wait_for_connect(auth, devices[0])

        authtoken = auth.get_auth_token()

        super().test_filetransfer(devices[0],
                                  authtoken,
                                  content_assertion="ServerURL")
示例#10
0
def setup_with_legacy_client(request):
    # The legacy 1.7.0 client was only built for qemux86-64, so skip tests using
    # it when running other platforms.
    if conftest.machine_name != "qemux86-64":
        pytest.skip("Test only works with qemux86-64, and this is %s" %
                    conftest.machine_name)

    env = container_factory.getLegacyClientSetup()
    request.addfinalizer(env.teardown)

    env.setup()

    env.device = MenderDevice(env.get_mender_clients()[0])
    env.device.ssh_is_opened()

    reset_mender_api(env)
    auth_v2.accept_devices(1)

    return env
示例#11
0
def setup_os_compat(request):
    env = container_factory.get_compatibility_setup()
    request.addfinalizer(env.teardown)
    env.setup()

    env.user = create_user(
        "*****@*****.**", "correcthorse", containers_namespace=env.name
    )
    env.populate_clients()

    clients = env.get_mender_clients()
    assert len(clients) > 0, "Failed to setup clients"
    env.devices = []
    for client in clients:
        dev = MenderDevice(client)
        dev.ssh_is_opened()
        env.devices.append(dev)

    return env
示例#12
0
def standard_setup_two_clients_bootstrapped_with_gateway(request):
    env = container_factory.get_standard_setup_with_gateway(num_clients=2)
    request.addfinalizer(env.teardown)

    env.setup()

    env.device_group = MenderDeviceGroup(
        env.get_mender_clients(network="mender_local"))
    env.device_group.ssh_is_opened()

    env.device_gateway = MenderDevice(
        env.get_mender_gateways(network="mender")[0])
    env.device_gateway.ssh_is_opened()

    reset_mender_api(env)
    # Three devices: two client devices and the gateway device (which also runs mender client)
    devauth.accept_devices(3)

    env.auth = auth
    return env
示例#13
0
    def prepare_env(self, env, user_name):
        u = User("", user_name, "whatsupdoc")
        cli = CliTenantadm(containers_namespace=env.name)
        tid = cli.create_org("monitor-tenant", u.name, u.pwd, plan="enterprise")

        # at the moment we do not have a notion of a monitor add-on in the
        # backend, but this will be needed here, see MEN-4809
        # update_tenant(
        #  tid, addons=["monitor"], container_manager=get_container_manager(),
        # )

        tenant = cli.get_tenant(tid)
        tenant = json.loads(tenant)

        auth = authentication.Authentication(
            name="monitor-tenant", username=u.name, password=u.pwd
        )
        auth.create_org = False
        auth.reset_auth_token()
        devauth_tenant = DeviceAuthV2(auth)

        env.new_tenant_client("configuration-test-container", tenant["tenant_token"])
        env.device = mender_device = MenderDevice(env.get_mender_clients()[0])
        mender_device.ssh_is_opened()

        devauth_tenant.accept_devices(1)

        devices = list(
            set(
                [
                    device["id"]
                    for device in devauth_tenant.get_devices_status("accepted")
                ]
            )
        )
        assert 1 == len(devices)

        devid = devices[0]
        authtoken = auth.get_auth_token()

        return devid, authtoken, auth, mender_device
示例#14
0
    def connected_device(self, env):
        u = User("", "*****@*****.**", "whatsupdoc")
        cli = CliTenantadm(containers_namespace=env.name)
        tid = cli.create_org("enterprise-tenant", u.name, u.pwd, "enterprise")
        update_tenant(
            tid,
            addons=["troubleshoot"],
            container_manager=get_container_manager(),
        )
        tenant = cli.get_tenant(tid)
        tenant = json.loads(tenant)
        ttoken = tenant["tenant_token"]

        auth = Authentication(name="enterprise-tenant",
                              username=u.name,
                              password=u.pwd)
        auth.create_org = False
        auth.reset_auth_token()
        devauth = DeviceAuthV2(auth)

        env.new_tenant_client("configuration-test-container", ttoken)
        device = MenderDevice(env.get_mender_clients()[0])
        devauth.accept_devices(1)

        devices = list(
            set([
                device["id"]
                for device in devauth.get_devices_status("accepted")
            ]))
        assert 1 == len(devices)

        wait_for_connect(auth, devices[0])

        devconn = DeviceConnect(auth, devauth)

        return device, devconn
示例#15
0
    def test_configuration(self, enterprise_no_client):
        """Tests the deployment and reporting of the configuration

        The tests set the configuration of a device and verifies the new
        configuration is reported back to the back-end.
        """

        env = enterprise_no_client

        # Create an enterprise plan tenant
        u = User("", "*****@*****.**", "whatsupdoc")
        cli = CliTenantadm(containers_namespace=env.name)
        tid = cli.create_org("enterprise-tenant",
                             u.name,
                             u.pwd,
                             plan="enterprise")
        tenant = cli.get_tenant(tid)
        tenant = json.loads(tenant)
        ttoken = tenant["tenant_token"]
        logger.info(f"tenant json: {tenant}")
        tenant = Tenant("tenant", tid, ttoken)
        tenant.users.append(u)

        # And authorize the user to the tenant account
        auth = Authentication(name="enterprise-tenant",
                              username=u.name,
                              password=u.pwd)
        auth.create_org = False
        auth.reset_auth_token()
        devauth_tenant = DeviceAuthV2(auth)

        # Add a client to the tenant
        enterprise_no_client.new_tenant_client("configuration-test-container",
                                               tenant.tenant_token)
        mender_device = MenderDevice(
            enterprise_no_client.get_mender_clients()[0])
        mender_device.ssh_is_opened()

        devauth_tenant.accept_devices(1)

        # list of devices
        devices = list(
            set([
                device["id"]
                for device in devauth_tenant.get_devices_status("accepted")
            ]))
        assert 1 == len(devices)

        wait_for_connect(auth, devices[0])

        # set and verify the device's configuration
        # retry to skip possible race conditions between update poll and update trigger
        for _ in redo.retrier(attempts=3, sleeptime=1):
            set_and_verify_config({"key": "value"}, devices[0],
                                  auth.get_auth_token())

            forced = was_update_forced(mender_device)
            if forced:
                return

        assert False, "the update check was never triggered"
    def test_deployment_retry_failed_update(self, enterprise_no_client):
        """Tests that a client installing a deployment created with a retry limit

        This is done through setting up a new tenant on the enterprise plan,
        with a device bootstrapped to the tenant. Then an Artifact is created
        which contains a script, for the script update module. The script will
        store a retry-count in a temp-file on the device, and fail, as long as
        the retry-count < 3. On the third go, the script will, pass, and along
        with it, so should the update.

        """

        env = enterprise_no_client

        # Create an enterprise plan tenant
        u = User("", "*****@*****.**", "whatsupdoc")
        cli = CliTenantadm(containers_namespace=env.name)
        tid = cli.create_org("enterprise-tenant",
                             u.name,
                             u.pwd,
                             plan="enterprise")
        tenant = cli.get_tenant(tid)
        tenant = json.loads(tenant)
        ttoken = tenant["tenant_token"]
        logger.info(f"tenant json: {tenant}")
        tenant = Tenant("tenant", tid, ttoken)
        tenant.users.append(u)

        # And authorize the user to the tenant account
        auth = Authentication(name="enterprise-tenant",
                              username=u.name,
                              password=u.pwd)
        auth.create_org = False
        auth.reset_auth_token()
        devauth = DeviceAuthV2(auth)
        deploy = Deployments(auth, devauth)

        # Add a client to the tenant
        enterprise_no_client.new_tenant_client("retry-test-container",
                                               tenant.tenant_token)
        devauth.accept_devices(1)
        device = MenderDevice(env.get_mender_clients()[0])

        with tempfile.NamedTemporaryFile() as tf:

            artifact = make_script_artifact("retry-artifact",
                                            conftest.machine_name, tf.name)

            deploy.upload_image(artifact)

            devices = list(
                set([
                    device["id"]
                    for device in devauth.get_devices_status("accepted")
                ]))
            assert len(devices) == 1

            deployment_id = deploy.trigger_deployment(
                "retry-test",
                artifact_name="retry-artifact",
                devices=devices,
                retries=3)
            logger.info(deploy.get_deployment(deployment_id))

            # Now just wait for the update to succeed
            deploy.check_expected_statistics(deployment_id, "success", 1)
            deploy.check_expected_status("finished", deployment_id)

            # Verify the update was actually installed on the device
            out = device.run("mender -show-artifact").strip()
            assert out == "retry-artifact"

            # Verify the number of attempts taken to install the update
            out = device.run("cat /tmp/retry-attempts").strip()
            assert out == "3"
示例#17
0
    def test_update_provides_depends(self, enterprise_no_client):
        """
        Perform two consecutive updates, the first adds virtual provides
        to the artifact and the second artifact depends on these provides.
        """

        # Create tenant user
        auth.reset_auth_token()
        auth.new_tenant("admin", "*****@*****.**", "secret-service",
                        "enterprise")
        token = auth.current_tenant["tenant_token"]

        # Create client setup with tenant token
        enterprise_no_client.new_tenant_docker_client("mender-client", token)
        mender_device = MenderDevice(
            enterprise_no_client.get_mender_clients()[0])
        host_ip = enterprise_no_client.get_virtual_network_host_ip()

        # Wait for ssh to be open
        mender_device.ssh_is_opened()
        # Check that the device has authorized with the backend.
        devauth.get_devices(expected_devices=1)
        devauth.accept_devices(1)
        assert len(devauth.get_devices_status("accepted")) == 1

        # Update client with and artifact with custom provides
        def prepare_provides_artifact(artifact_file, artifact_id):
            cmd = (
                # Package tests folder in the artifact, just a random folder.
                "directory-artifact-gen -o %s -n %s -t docker-client -d /tmp/test_file_update_module tests -- --provides rootfs-image.directory.foo:bar"
                % (artifact_file, artifact_id))
            logger.info("Executing: " + cmd)
            subprocess.check_call(cmd, shell=True)
            return artifact_file

        deployment_id, _ = common_update_procedure(
            make_artifact=prepare_provides_artifact,
            # We use verify_status=False, because update module updates are so
            # quick that it sometimes races past the 'inprogress' status without
            # the test framework having time to register it. That's not really
            # the part we're interested in though, so just skip it.
            verify_status=False,
        )
        deploy.check_expected_status("finished", deployment_id)

        # Issue another update which depends on the custom provides
        def prepare_depends_artifact(artifact_file, artifact_id):
            cmd = (
                # Package tests folder in the artifact, just a random folder.
                "directory-artifact-gen -o %s -n %s -t docker-client -d /tmp/test_file_update_module tests -- --depends rootfs-image.directory.foo:bar"
                % (artifact_file, artifact_id))
            logger.info("Executing: " + cmd)
            subprocess.check_call(cmd, shell=True)
            return artifact_file

        deployment_id, _ = common_update_procedure(
            make_artifact=prepare_depends_artifact,
            verify_status=False,
        )
        deploy.check_expected_status("finished", deployment_id)

        # Issue a third update with the same update as previous, this time
        # with insufficient provides -> no artifact status
        deployment_id, _ = common_update_procedure(
            make_artifact=prepare_depends_artifact, verify_status=False)

        # Retry for at most 60 seconds checking for deployment status update
        stat = None
        noartifact = 0
        for i in range(60):
            time.sleep(1)
            stat = deploy.get_statistics(deployment_id)
            if stat.get("noartifact") == 1:
                noartifact = 1
                break

        assert stat is not None
        assert noartifact == 1
示例#18
0
    def _make_trial_tenant(self, env):
        tname = "tenant-{}".format("trial")
        email = "user@{}.com".format(tname)

        tadmm = ApiClient(
            host=get_container_manager().get_mender_gateway(),
            base_url=tenantadm_v2.URL_MGMT,
        )

        args = {
            "organization": tname,
            "email": email,
            "password": "******",
            "name": "foo",
            "g-recaptcha-response": "dummy",
            "plan": "enterprise",
        }

        res = tadmm.call(
            "POST",
            tenantadm_v2.URL_CREATE_ORG_TRIAL,
            body=args,
        )

        assert res.status_code == 202

        # get tenant id
        tadmi = ApiClient(
            host=get_container_manager().get_ip_of_service("mender-tenantadm")
            [0] + ":8080",
            base_url=tenantadm.URL_INTERNAL,
            schema="http://",
        )

        res = tadmi.call("GET",
                         tenantadm.URL_INTERNAL_TENANTS,
                         qs_params={"username": email})
        assert res.status_code == 200
        assert len(res.json()) == 1

        apitenant = res.json()[0]

        cli = CliTenantadm(containers_namespace=env.name)

        tenant = cli.get_tenant(apitenant["id"])
        tenant = json.loads(tenant)
        ttoken = tenant["tenant_token"]

        auth = Authentication(name=tname,
                              username=email,
                              password="******")
        auth.create_org = False
        auth.reset_auth_token()
        devauth = DeviceAuthV2(auth)

        env.new_tenant_client("test-container-trial", ttoken)
        device = MenderDevice(env.get_mender_clients()[0])
        devauth.accept_devices(1)

        devices = list(
            set([
                device["id"]
                for device in devauth.get_devices_status("accepted")
            ]))
        assert 1 == len(devices)

        tenant = Tenant(tname, apitenant["id"], ttoken)
        u = User("", email, "correcthorse")

        tenant.users.append(u)
        tenant.device = device
        tenant.device_id = devices[0]
        tenant.auth = auth
        tenant.devauth = devauth

        return tenant
示例#19
0
    def test_update_control(
        self,
        enterprise_no_client,
        valid_image,
    ):
        """
        Schedule an update with a pause in ArtifactInstall_Enter,
        ArtifactReboot_Enter, and ArtifactCommit_Enter, then continue, after the
        client has reported the paused substate back to the server, all the way
        until the deployment is successfully finished.
        """

        u = User("", "*****@*****.**", "whatsupdoc")
        cli = CliTenantadm(containers_namespace=enterprise_no_client.name)
        tid = cli.create_org("enterprise-tenant", u.name, u.pwd, "enterprise")
        tenant = cli.get_tenant(tid)
        tenant = json.loads(tenant)
        ttoken = tenant["tenant_token"]

        auth = Authentication(name="enterprise-tenant",
                              username=u.name,
                              password=u.pwd)
        auth.create_org = False
        auth.reset_auth_token()
        devauth = DeviceAuthV2(auth)

        enterprise_no_client.new_tenant_client("control-map-test-container",
                                               ttoken)
        device = MenderDevice(enterprise_no_client.get_mender_clients()[0])
        devauth.accept_devices(1)

        deploy = Deployments(auth, devauth)

        devices = list(
            set([
                device["id"]
                for device in devauth.get_devices_status("accepted")
            ]))
        assert 1 == len(devices)

        with tempfile.NamedTemporaryFile() as artifact_file:
            created_artifact = image.make_rootfs_artifact(
                valid_image,
                conftest.machine_name,
                "test-update-control",
                artifact_file.name,
            )

            deploy.upload_image(artifact_file.name,
                                description="control map update test")

        deployment_id = deploy.trigger_deployment(
            name="New valid update",
            artifact_name="test-update-control",
            devices=devices,
            update_control_map={
                "Priority": 1,
                "States": {
                    "ArtifactInstall_Enter": {
                        "action": "pause",
                    },
                },
            },
        )

        # Query the deployment, and verify that the map returned contains the
        # deployment ID
        res_json = deploy.get_deployment(deployment_id)
        assert deployment_id == res_json.get("update_control_map").get(
            "id"), res_json

        # Wait for the device to pause in ArtifactInstall
        deploy.check_expected_statistics(deployment_id,
                                         "pause_before_installing", 1)
        deploy.patch_deployment(
            deployment_id,
            update_control_map={
                "Priority": 2,
                "States": {
                    "ArtifactInstall_Enter": {
                        "action": "force_continue",
                    },
                    "ArtifactReboot_Enter": {
                        "action": "pause",
                    },
                },
            },
        )

        # Wait for the device to pause in ArtifactReboot
        deploy.check_expected_statistics(deployment_id,
                                         "pause_before_rebooting", 1)
        deploy.patch_deployment(
            deployment_id,
            update_control_map={
                "Priority": 2,
                "States": {
                    "ArtifactReboot_Enter": {
                        "action": "force_continue",
                    },
                    "ArtifactCommit_Enter": {
                        "action": "pause"
                    },
                },
            },
        )

        # Wait for the device to pause in ArtifactCommit
        deploy.check_expected_statistics(deployment_id,
                                         "pause_before_committing", 1)
        deploy.patch_deployment(
            deployment_id,
            update_control_map={
                "Priority": 2,
                "States": {
                    "ArtifactCommit_Enter": {
                        "action": "force_continue",
                    },
                },
            },
        )

        deploy.check_expected_status("finished", deployment_id)
        deploy.check_expected_statistics(deployment_id, "success", 1)
示例#20
0
    def test_update_control_with_broken_map(
        self,
        enterprise_no_client,
        valid_image,
    ):
        """
        Schedule an update with an invalid map, which should fail.
        """

        u = User("", "*****@*****.**", "whatsupdoc")
        cli = CliTenantadm(containers_namespace=enterprise_no_client.name)
        tid = cli.create_org("enterprise-tenant", u.name, u.pwd, "enterprise")
        tenant = cli.get_tenant(tid)
        tenant = json.loads(tenant)
        ttoken = tenant["tenant_token"]

        auth = Authentication(name="enterprise-tenant",
                              username=u.name,
                              password=u.pwd)
        auth.create_org = False
        auth.reset_auth_token()
        devauth = DeviceAuthV2(auth)

        enterprise_no_client.new_tenant_client("control-map-test-container",
                                               ttoken)
        device = MenderDevice(enterprise_no_client.get_mender_clients()[0])
        devauth.accept_devices(1)

        deploy = Deployments(auth, devauth)

        devices = list(
            set([
                device["id"]
                for device in devauth.get_devices_status("accepted")
            ]))
        assert 1 == len(devices)

        with tempfile.NamedTemporaryFile() as artifact_file:
            created_artifact = image.make_rootfs_artifact(
                valid_image,
                conftest.machine_name,
                "test-update-control",
                artifact_file.name,
            )

            deploy.upload_image(artifact_file.name,
                                description="control map update test")

        deployment_id = deploy.trigger_deployment(
            name="New valid update",
            artifact_name="test-update-control",
            devices=devices,
            update_control_map={
                "Priority": 1,
                "States": {
                    "BogusState_Enter": {
                        "action": "pause",
                    },
                },
            },
        )

        # Query the deployment, and verify that the map returned contains the
        # deployment ID
        res_json = deploy.get_deployment(deployment_id)
        assert deployment_id == res_json.get("update_control_map").get(
            "id"), res_json

        # Wait for the device to reject it and fail.
        deploy.check_expected_status("finished", deployment_id)
        deploy.check_expected_statistics(deployment_id, "failure", 1)