Exemplo n.º 1
0
    def test_device_deployments_already_installed(self):
        """Check case with already installed artifact
        """
        dev = Device()

        self.log.info('fake device with ID: %s', dev.devid)

        self.inventory_add_dev(dev)

        data = b'foo_bar'
        artifact_name = 'hammer-update-' + str(uuid4())
        # come up with an artifact
        with artifact_from_data(name=artifact_name, data=data, devicetype=dev.device_type) as art:
            ac = SimpleArtifactsClient()
            with ac.with_added_artifact(description='desc', size=art.size, data=art) as artid:

                newdep = self.make_new_deployment(name='foo', artifact_name=artifact_name,
                                                  devices=[dev.devid])

                with self.with_added_deployment(newdep) as depid:
                    dc = SimpleDeviceClient()
                    self.log.debug('device token %s', dev.fake_token)

                    # pretend we have the same artifact installed already
                    # NOTE: asking for a deployment while having it already
                    # installed is special in the sense that the status of
                    # deployment for this device will be marked as 'already-installed'
                    nextdep = dc.get_next_deployment(dev.fake_token, artifact_name=artifact_name,
                                                     device_type=dev.device_type)
                    self.log.info('device next: %s', nextdep)
                    assert nextdep == None
                    # verify that device status was properly recorded
                    self.verify_deployment_stats(depid, expected={
                        'already-installed': 1,
                    })
Exemplo n.º 2
0
    def test_deplyments_get_devices(self):
        """Create deployments, get devices with pagination"""
        devices = []
        devices_qty = 30
        device_ids = []
        default_per_page = 20
        device_type = "test-hammer-type"

        # create devices
        for i in range(0, devices_qty):
            device = Device(device_type)
            self.inventory_add_dev(device)
            devices.append(device)
            device_ids.append(device.devid)

        data = b"foo_bar"
        artifact_name = "pagination-test-" + str(uuid4())
        # come up with an artifact
        with artifact_from_data(name=artifact_name,
                                data=data,
                                devicetype=device_type) as art:
            ac = SimpleArtifactsClient()
            ac.add_artifact(description="some description",
                            size=art.size,
                            data=art)

            new_dep = self.d.make_new_deployment(name="pagination deployment",
                                                 artifact_name=artifact_name,
                                                 devices=device_ids)
            dep_id = self.d.add_deployment(new_dep)

            for dev in devices:
                dc = SimpleDeviceClient()
                dc.get_next_deployment(
                    dev.fake_token,
                    artifact_name="different {}".format(artifact_name),
                    device_type=dev.device_type,
                )

            # check default 'page' and 'per_page' values
            res = self.d.client.Management_API.List_Devices_in_Deployment_with_pagination(
                Authorization="foo", deployment_id=dep_id).result()[0]
            assert len(res) == default_per_page

            # check custom 'per_page'
            res = self.d.client.Management_API.List_Devices_in_Deployment_with_pagination(
                Authorization="foo",
                deployment_id=dep_id,
                per_page=devices_qty).result()[0]
            assert len(res) == devices_qty

            # check 2nd page
            devices_qty_on_second_page = devices_qty - default_per_page
            res = self.d.client.Management_API.List_Devices_in_Deployment_with_pagination(
                Authorization="foo",
                deployment_id=dep_id,
                page=2,
                per_page=default_per_page).result()[0]
            assert len(res) == devices_qty_on_second_page
Exemplo n.º 3
0
    def test_device_deployments_simple(self):
        """Check that device can get next deployment, simple cases:
        - bogus token
        - valid update
        - device type incompatible with artifact
        """
        dev = Device()

        self.log.info('fake device with ID: %s', dev.devid)

        self.inventory_add_dev(dev)

        data = b'foo_bar'
        artifact_name = 'hammer-update-' + str(uuid4())
        # come up with an artifact
        with artifact_from_data(name=artifact_name, data=data, devicetype=dev.device_type) as art:
            ac = SimpleArtifactsClient()
            with ac.with_added_artifact(description='desc', size=art.size, data=art) as artid:

                newdep = self.make_new_deployment(name='foo', artifact_name=artifact_name,
                                                  devices=[dev.devid])

                with self.with_added_deployment(newdep) as depid:
                    dc = SimpleDeviceClient()
                    self.log.debug('device token %s', dev.fake_token)

                    # try with some bogus token
                    try:
                        dc.get_next_deployment('foo-bar-baz', artifact_name=artifact_name,
                                                     device_type=dev.device_type)
                    except bravado.exception.HTTPError as err:
                        assert 400 <= err.response.status_code < 500
                    else:
                        raise AssertionError('expected to fail')

                    # pretend we have another artifact installed
                    nextdep = dc.get_next_deployment(dev.fake_token,
                                                     artifact_name='different {}'.format(artifact_name),
                                                     device_type=dev.device_type)
                    self.log.info('device next: %s', nextdep)
                    assert nextdep

                    assert dev.device_type in nextdep.artifact['device_types_compatible']

                    # pretend our device type is different than expected
                    nextdep = dc.get_next_deployment(dev.fake_token,
                                                     artifact_name='different {}'.format(artifact_name),
                                                     device_type='other {}'.format(dev.device_type))
                    self.log.info('device next: %s', nextdep)
                    assert nextdep == None
                    # verify that device status was properly recorded
                    self.verify_deployment_stats(depid, expected={
                        'noartifact': 1,
                    })
Exemplo n.º 4
0
    def test_device_deployments_logs(self):
        """Check that device can get next deployment, full cycle
        """
        dev = Device()

        self.log.info('fake device with ID: %s', dev.devid)

        self.inventory_add_dev(dev)

        data = b'foo_bar'
        artifact_name = 'hammer-update ' + str(uuid4())
        # come up with an artifact
        with artifact_from_data(name=artifact_name,
                                data=data,
                                devicetype=dev.device_type) as art:
            ac = SimpleArtifactsClient()
            with ac.with_added_artifact(description='desc',
                                        size=art.size,
                                        data=art) as artid:

                newdep = self.make_new_deployment(name='foo',
                                                  artifact_name=artifact_name,
                                                  devices=[dev.devid])

                with self.with_added_deployment(newdep) as depid:
                    dc = SimpleDeviceClient()
                    self.log.debug('device token %s', dev.fake_token)

                    # pretend we have another artifact installed
                    nextdep = dc.get_next_deployment(
                        dev.fake_token,
                        artifact_name='different {}'.format(artifact_name),
                        device_type=dev.device_type)
                    self.log.info('device next: %s', nextdep)
                    assert nextdep

                    dc.upload_logs(dev.fake_token,
                                   nextdep.id,
                                   logs=[
                                       'foo bar baz',
                                       'lorem ipsum',
                                   ])

                    rsp = self.client.deployments.get_deployments_deployment_id_devices_device_id_log(
                        Authorization='foo',
                        deployment_id=depid,
                        device_id=dev.devid).result()[1]
                    logs = rsp.text
                    self.log.info('device logs\n%s', logs)

                    assert 'lorem ipsum' in logs
                    assert 'foo bar baz' in logs
Exemplo n.º 5
0
    def test_device_deployments_logs(self):
        """Check that device can get next deployment, full cycle"""
        dev = Device()

        self.d.log.info("fake device with ID: %s", dev.devid)

        self.inventory_add_dev(dev)

        data = b"foo_bar"
        artifact_name = "hammer-update-" + str(uuid4())
        # come up with an artifact
        with artifact_from_data(name=artifact_name,
                                data=data,
                                devicetype=dev.device_type) as art:
            ac = SimpleArtifactsClient()
            with ac.with_added_artifact(description="desc",
                                        size=art.size,
                                        data=art) as artid:

                newdep = self.d.make_new_deployment(
                    name="foo",
                    artifact_name=artifact_name,
                    devices=[dev.devid])

                with self.d.with_added_deployment(newdep) as depid:
                    dc = SimpleDeviceClient()
                    self.d.log.debug("device token %s", dev.fake_token)

                    # pretend we have another artifact installed
                    nextdep = dc.get_next_deployment(
                        dev.fake_token,
                        artifact_name="different {}".format(artifact_name),
                        device_type=dev.device_type,
                    )
                    self.d.log.info("device next: %s", nextdep)
                    assert nextdep

                    dc.upload_logs(dev.fake_token,
                                   nextdep.id,
                                   logs=["foo bar baz", "lorem ipsum"])

                    rsp = self.d.client.Management_API.Get_Deployment_Log_for_Device(
                        Authorization="foo",
                        deployment_id=depid,
                        device_id=dev.devid).result()[1]
                    logs = rsp.text
                    self.d.log.info("device logs\n%s", logs)

                    assert "lorem ipsum" in logs
                    assert "foo bar baz" in logs
    def test_artifacts_fails_invalid_size(self, api_client_int):
        artifact_name = str(uuid4())
        description = "description for foo " + artifact_name
        device_type = "project-" + str(uuid4())
        data = b"foo_bar"

        tenant_id = str(ObjectId())

        # generate artifact
        with artifact_from_data(
            name=artifact_name, data=data, devicetype=device_type
        ) as art:
            artifacts_client = SimpleArtifactsClient()

            artifacts_client.log.info("uploading artifact")
            with pytest.raises(ArtifactsClientError):
                api_client_int.add_artifact(tenant_id, description, -1, art)
Exemplo n.º 7
0
    def test_artifacts_valid(self, api_client_int, mongo):
        artifact_name = str(uuid4())
        description = "description for foo " + artifact_name
        device_type = "project-" + str(uuid4())
        data = b"foo_bar"

        tenant_id = str(ObjectId())
        _, r = api_client_int.create_tenant(tenant_id)
        assert r.status_code == 201

        # generate artifact
        with artifact_from_data(name=artifact_name,
                                data=data,
                                devicetype=device_type) as art:
            artifacts_client = SimpleArtifactsClient()

            artifacts_client.log.info("uploading artifact")
            artid = api_client_int.add_artifact(tenant_id, description,
                                                art.size, art)
            assert artid is not None

            # verify the artifact has been stored correctly in mongodb
            artifact = mongo["deployment_service-{}".format(
                tenant_id)].images.find_one({"_id": artid})
            assert artifact is not None
            #
            assert artifact["_id"] == artid
            assert artifact["meta_artifact"]["name"] == artifact_name
            assert artifact["meta"]["description"] == description
            assert artifact["size"] == int(art.size)
            assert (device_type
                    in artifact["meta_artifact"]["device_types_compatible"])
            assert len(artifact["meta_artifact"]["updates"]) == 1
            update = artifact["meta_artifact"]["updates"][0]
            assert len(update["files"]) == 1
            uf = update["files"][0]
            assert uf["size"] == len(data)
            assert uf["checksum"]
Exemplo n.º 8
0
    def test_artifacts_valid_multipart(self):
        """
        Uploads an artifact > 10MiB to cover the multipart upload scenario.
        """
        artifact_name = str(uuid4())
        description = "description for foo " + artifact_name
        device_type = "project-" + str(uuid4())
        data = urandom(1024 * 1024 * 15)

        # generate artifact
        with artifact_from_data(name=artifact_name,
                                data=data,
                                devicetype=device_type) as art:
            self.log.info("uploading artifact")
            artid = self.add_artifact(description, art.size, art)

            # artifacts listing should not be empty now
            res = self.client.Management_API.List_Artifacts().result()
            self.log.debug("result: %s", res)
            assert len(res[0]) > 0

            res = self.client.Management_API.Show_Artifact(
                Authorization="foo", id=artid).result()[0]
            self.log.info("artifact: %s", res)

            # verify its data
            assert res.id == artid
            assert res.name == artifact_name
            assert res.description == description
            assert res.size == int(art.size)
            assert device_type in res.device_types_compatible
            assert len(res.updates) == 1
            update = res.updates[0]
            assert len(update.files) == 1
            uf = update.files[0]
            assert uf.size == len(data)
            assert uf.checksum
Exemplo n.º 9
0
    def test_deployments_new_valid(self):
        """Add a new valid deployment, verify its status, verify device deployment
        status, abort and verify eveything once again"""
        dev = Device()

        self.log.info('fake device with ID: %s', dev.devid)

        self.inventory_add_dev(dev)

        data = b'foo_bar'
        artifact_name = 'hammer-update-' + str(uuid4())
        # come up with an artifact
        with artifact_from_data(name=artifact_name, data=data, devicetype=dev.device_type) as art:
            ac = SimpleArtifactsClient()
            artid = ac.add_artifact(description='some description', size=art.size,
                                    data=art)

            newdep = self.make_new_deployment(name='fake deployment', artifact_name=artifact_name,
                                              devices=[dev.devid])
            depid = self.add_deployment(newdep)

            # artifact is used in deployment, so attempts to remove it should
            # fail
            try:
                ac.delete_artifact(artid)
            except ArtifactsClientError as ace:
                #  artifact is used in deployment
                assert ace.response.status_code == 409
            else:
                raise AssertionError('expected to fail')

            dep = self.client.deployments.get_deployments_id(Authorization='foo',
                                                             id=depid).result()[0]
            self.log.debug('deployment dep: %s', dep)
            assert dep.artifact_name == artifact_name
            assert dep.id == depid
            assert dep.status == 'pending'

            # fetch device status
            depdevs = self.client.deployments.get_deployments_deployment_id_devices(Authorization='foo',
                                                                         deployment_id=depid).result()[0]
            self.log.debug('deployment devices: %s', depdevs)
            assert len(depdevs) == 1
            depdev = depdevs[0]
            assert depdev.status == 'pending'
            assert depdev.id == dev.devid

            # verify statistics
            self.verify_deployment_stats(depid, expected={
                'pending': 1,
            })

            # abort deployment
            self.abort_deployment(depid)

            # that it's 'finished' now
            aborted_dep = self.client.deployments.get_deployments_id(Authorization='foo',
                                                             id=depid).result()[0]
            self.log.debug('deployment dep: %s', aborted_dep)
            assert aborted_dep.status == 'finished'

            # verify statistics once again
            self.verify_deployment_stats(depid, expected={
                'aborted': 1,
            })

            # fetch device status
            depdevs = self.client.deployments.get_deployments_deployment_id_devices(Authorization='foo',
                                                                         deployment_id=depid).result()[0]
            self.log.debug('deployment devices: %s', depdevs)
            assert len(depdevs) == 1
            depdev = depdevs[0]
            assert depdev.status == 'aborted'

            # deleting artifact should succeed
            ac.delete_artifact(artid)
Exemplo n.º 10
0
    def test_device_deployments_full(self):
        """Check that device can get next deployment, full cycle
        """
        dev = Device()

        self.log.info('fake device with ID: %s', dev.devid)

        self.inventory_add_dev(dev)

        data = b'foo_bar'
        artifact_name = 'hammer-update-' + str(uuid4())
        # come up with an artifact
        with artifact_from_data(name=artifact_name, data=data, devicetype=dev.device_type) as art:
            ac = SimpleArtifactsClient()
            with ac.with_added_artifact(description='desc', size=art.size, data=art) as artid:

                newdep = self.make_new_deployment(name='foo', artifact_name=artifact_name,
                                                  devices=[dev.devid])

                with self.with_added_deployment(newdep) as depid:
                    dc = SimpleDeviceClient()
                    self.log.debug('device token %s', dev.fake_token)

                    self.verify_deployment_stats(depid, expected={
                        'pending': 1,
                    })

                    # pretend we have another artifact installed
                    nextdep = dc.get_next_deployment(dev.fake_token,
                                                     artifact_name='different {}'.format(artifact_name),
                                                     device_type=dev.device_type)
                    self.log.info('device next: %s', nextdep)
                    assert nextdep

                    assert dev.device_type in nextdep.artifact['device_types_compatible']

                    for st in ['downloading', 'installing', 'rebooting']:
                        dc.report_status(token=dev.fake_token, devdepid=nextdep.id, status=st)
                        self.verify_deployment_stats(depid, expected={
                            st: 1,
                        })

                    # we have reported some statuses now, but not the final
                    # status, try to get the next deployment
                    againdep = dc.get_next_deployment(dev.fake_token,
                                                     artifact_name='different {}'.format(artifact_name),
                                                     device_type=dev.device_type)
                    assert againdep
                    assert againdep.id == nextdep.id

                    # deployment should be marked as inprogress
                    dep = self.client.deployments.get_deployments_id(Authorization='foo',
                                                                     id=depid).result()[0]
                    assert dep.status == 'inprogress'

                    # report final status
                    dc.report_status(token=dev.fake_token, devdepid=nextdep.id, status='success')
                    self.verify_deployment_stats(depid, expected={
                        'success': 1,
                    })

                    dep = self.client.deployments.get_deployments_id(Authorization='foo',
                                                                     id=depid).result()[0]
                    assert dep.status == 'finished'

                    # report failure as final status
                    dc.report_status(token=dev.fake_token, devdepid=nextdep.id, status='failure')
                    self.verify_deployment_stats(depid, expected={
                        'failure': 1,
                    })

                    # deployment is finished, should get no more updates
                    nodep = dc.get_next_deployment(dev.fake_token,
                                                     artifact_name='other {}'.format(artifact_name),
                                                     device_type=dev.device_type)
                    assert nodep == None

                    # as a joke, report rebooting now
                    dc.report_status(token=dev.fake_token, devdepid=nextdep.id, status='rebooting')
                    self.verify_deployment_stats(depid, expected={
                        'rebooting': 1,
                    })
                    # deployment is in progress again
                    dep = self.client.deployments.get_deployments_id(Authorization='foo',
                                                                     id=depid).result()[0]
                    assert dep.status == 'inprogress'

                    # go on, let's pretend that the artifact is already installed
                    nodep = dc.get_next_deployment(dev.fake_token,
                                                     artifact_name=artifact_name,
                                                     device_type=dev.device_type)
                    assert nodep == None
                    self.verify_deployment_stats(depid, expected={
                        'already-installed': 1,
                    })
Exemplo n.º 11
0
    def test_deployments_new_valid(self):
        """Add a new valid deployment, verify its status, verify device deployment
        status, abort and verify eveything once again"""
        dev = Device()

        self.d.log.info("fake device with ID: %s", dev.devid)

        self.inventory_add_dev(dev)

        data = b"foo_bar"
        artifact_name = "hammer-update-" + str(uuid4())
        # come up with an artifact
        with artifact_from_data(name=artifact_name,
                                data=data,
                                devicetype=dev.device_type) as art:
            ac = SimpleArtifactsClient()
            artid = ac.add_artifact(description="some description",
                                    size=art.size,
                                    data=art)

            newdep = self.d.make_new_deployment(name="fake deployment",
                                                artifact_name=artifact_name,
                                                devices=[dev.devid])
            depid = self.d.add_deployment(newdep)

            # artifact is used in deployment, so attempts to remove it should
            # fail
            try:
                ac.delete_artifact(artid)
            except ArtifactsClientError as ace:
                #  artifact is used in deployment
                assert ace.response.status_code == 409
            else:
                raise AssertionError("expected to fail")

            dc = SimpleDeviceClient()
            nextdep = dc.get_next_deployment(
                dev.fake_token,
                artifact_name="different {}".format(artifact_name),
                device_type=dev.device_type,
            )

            dep = self.d.client.Management_API.Show_Deployment(
                Authorization="foo", id=depid).result()[0]
            assert dep.artifact_name == artifact_name
            assert dep.id == depid
            assert dep.status == "pending"

            # fetch device status
            depdevs = self.d.client.Management_API.List_Devices_in_Deployment(
                Authorization="foo", deployment_id=depid).result()[0]
            assert len(depdevs) == 1
            depdev = depdevs[0]
            assert depdev.status == "pending"
            assert depdev.id == dev.devid

            # verify statistics
            self.d.verify_deployment_stats(depid, expected={"pending": 1})

            # abort deployment
            self.d.abort_deployment(depid)

            # that it's 'finished' now
            aborted_dep = self.d.client.Management_API.Show_Deployment(
                Authorization="foo", id=depid).result()[0]
            self.d.log.debug("deployment dep: %s", aborted_dep)
            assert aborted_dep.status == "finished"

            # verify statistics once again
            self.d.verify_deployment_stats(depid, expected={"aborted": 1})

            # fetch device status
            depdevs = self.d.client.Management_API.List_Devices_in_Deployment(
                Authorization="foo", deployment_id=depid).result()[0]
            self.d.log.debug("deployment devices: %s", depdevs)
            assert len(depdevs) == 1
            depdev = depdevs[0]
            assert depdev.status == "aborted"

            # deleting artifact should succeed
            ac.delete_artifact(artid)
Exemplo n.º 12
0
    def test_device_deployments_full(self):
        """Check that device can get next deployment, full cycle"""
        dev = Device()

        self.d.log.info("fake device with ID: %s", dev.devid)

        self.inventory_add_dev(dev)

        data = b"foo_bar"
        artifact_name = "hammer-update-" + str(uuid4())
        # come up with an artifact
        with artifact_from_data(name=artifact_name,
                                data=data,
                                devicetype=dev.device_type) as art:
            ac = SimpleArtifactsClient()
            with ac.with_added_artifact(description="desc",
                                        size=art.size,
                                        data=art) as artid:

                newdep = self.d.make_new_deployment(
                    name="foo",
                    artifact_name=artifact_name,
                    devices=[dev.devid])

                with self.d.with_added_deployment(newdep) as depid:
                    dc = SimpleDeviceClient()
                    self.d.log.debug("device token %s", dev.fake_token)

                    # pretend we have another artifact installed
                    nextdep = dc.get_next_deployment(
                        dev.fake_token,
                        artifact_name="different {}".format(artifact_name),
                        device_type=dev.device_type,
                    )
                    self.d.log.info("device next: %s", nextdep)
                    assert nextdep

                    assert (dev.device_type
                            in nextdep.artifact["device_types_compatible"])

                    self.d.verify_deployment_stats(depid,
                                                   expected={"pending": 1})

                    for st in ["downloading", "installing", "rebooting"]:
                        dc.report_status(token=dev.fake_token,
                                         devdepid=nextdep.id,
                                         status=st)
                        self.d.verify_deployment_stats(depid, expected={st: 1})

                    # we have reported some statuses now, but not the final
                    # status, try to get the next deployment
                    againdep = dc.get_next_deployment(
                        dev.fake_token,
                        artifact_name="different {}".format(artifact_name),
                        device_type=dev.device_type,
                    )
                    assert againdep
                    assert againdep.id == nextdep.id

                    # deployment should be marked as inprogress
                    dep = self.d.client.Management_API.Show_Deployment(
                        Authorization="foo", id=depid).result()[0]
                    assert dep.status == "inprogress"

                    # report final status
                    dc.report_status(token=dev.fake_token,
                                     devdepid=nextdep.id,
                                     status="success")
                    self.d.verify_deployment_stats(depid,
                                                   expected={"success": 1})

                    dep = self.d.client.Management_API.Show_Deployment(
                        Authorization="foo", id=depid).result()[0]
                    assert dep.status == "finished"

                    # report failure as final status
                    dc.report_status(token=dev.fake_token,
                                     devdepid=nextdep.id,
                                     status="failure")
                    self.d.verify_deployment_stats(depid,
                                                   expected={"failure": 1})

                    # deployment is finished, should get no more updates
                    nodep = dc.get_next_deployment(
                        dev.fake_token,
                        artifact_name="other {}".format(artifact_name),
                        device_type=dev.device_type,
                    )
                    assert nodep == None

                    # as a joke, report rebooting now
                    dc.report_status(token=dev.fake_token,
                                     devdepid=nextdep.id,
                                     status="rebooting")
                    self.d.verify_deployment_stats(depid,
                                                   expected={"rebooting": 1})
                    # deployment is in progress again
                    dep = self.d.client.Management_API.Show_Deployment(
                        Authorization="foo", id=depid).result()[0]
                    assert dep.status == "inprogress"

                    # go on, let's pretend that the artifact is already installed
                    nodep = dc.get_next_deployment(
                        dev.fake_token,
                        artifact_name=artifact_name,
                        device_type=dev.device_type,
                    )
                    assert nodep == None
                    self.d.verify_deployment_stats(
                        depid, expected={"already-installed": 1})
Exemplo n.º 13
0
    def test_artifacts_valid(self):
        artifact_name = str(uuid4())
        description = "description for foo " + artifact_name
        device_type = "project-" + str(uuid4())
        data = b"foo_bar"

        # generate artifact
        with artifact_from_data(name=artifact_name,
                                data=data,
                                devicetype=device_type) as art:
            self.log.info("uploading artifact")
            artid = self.add_artifact(description, art.size, art)

            # artifacts listing should not be empty now
            res = self.client.Management_API.List_Artifacts().result()
            self.log.debug("result: %s", res)
            assert len(res[0]) > 0

            res = self.client.Management_API.Show_Artifact(
                Authorization="foo", id=artid).result()[0]
            self.log.info("artifact: %s", res)

            # verify its data
            assert res.id == artid
            assert res.name == artifact_name
            assert res.description == description
            assert res.size == int(art.size)
            assert device_type in res.device_types_compatible
            assert len(res.updates) == 1
            update = res.updates[0]
            assert len(update.files) == 1
            uf = update.files[0]
            assert uf.size == len(data)
            assert uf.checksum
            # TODO: verify uf signature once it's supported
            # assert uf.signature

            # try to fetch the update
            res = self.client.Management_API.Download_Artifact(
                Authorization="foo", id=artid).result()[0]
            self.log.info("download result %s", res)
            assert res.uri
            # fetch it now (disable SSL verification)
            rsp = requests.get(res.uri, verify=False, stream=True)

            assert rsp.status_code == 200
            assert sum(
                1 for x in self.m.list_objects("mender-artifact-storage")) == 1

            # receive artifact and compare its checksum
            dig = sha256()
            while True:
                rspdata = rsp.raw.read()
                if rspdata:
                    dig.update(rspdata)
                else:
                    break

            self.log.info(
                "artifact checksum %s expecting %s",
                dig.hexdigest(),
                art.checksum,
            )
            assert dig.hexdigest() == art.checksum

            # delete it now
            self.delete_artifact(artid)

            # should be unavailable now
            try:
                res = self.client.Management_API.Show_Artifact(
                    Authorization="foo", id=artid).result()
            except bravado.exception.HTTPError as e:
                assert e.response.status_code == 404
            else:
                raise AssertionError("expected to fail")
Exemplo n.º 14
0
    def test_device_deployments_simple(self):
        """Check that device can get next deployment, simple cases:
        - bogus token
        - valid update
        - already installed
        - device type incompatible with artifact
        """
        dev = Device()

        self.log.info('fake device with ID: %s', dev.devid)

        self.inventory_add_dev(dev)

        data = b'foo_bar'
        artifact_name = 'hammer-update ' + str(uuid4())
        # come up with an artifact
        with artifact_from_data(name=artifact_name,
                                data=data,
                                devicetype=dev.device_type) as art:
            ac = SimpleArtifactsClient()
            with ac.with_added_artifact(description='desc',
                                        size=art.size,
                                        data=art) as artid:

                newdep = self.make_new_deployment(name='foo',
                                                  artifact_name=artifact_name,
                                                  devices=[dev.devid])

                with self.with_added_deployment(newdep) as depid:
                    dc = SimpleDeviceClient()
                    self.log.debug('device token %s', dev.fake_token)

                    # try with some bogus token
                    try:
                        dc.get_next_deployment('foo-bar-baz',
                                               artifact_name=artifact_name,
                                               device_type=dev.device_type)
                    except bravado.exception.HTTPError as err:
                        assert 400 <= err.response.status_code < 500
                    else:
                        raise AssertionError('expected to fail')

                    # pretend we have another artifact installed
                    nextdep = dc.get_next_deployment(
                        dev.fake_token,
                        artifact_name='different {}'.format(artifact_name),
                        device_type=dev.device_type)
                    self.log.info('device next: %s', nextdep)
                    assert nextdep

                    assert dev.device_type in nextdep.artifact[
                        'device_types_compatible']

                    # pretend our device type is different than expected
                    nextdep = dc.get_next_deployment(
                        dev.fake_token,
                        artifact_name='different {}'.format(artifact_name),
                        device_type='other {}'.format(dev.device_type))
                    self.log.info('device next: %s', nextdep)
                    # TODO: this should fail or a deployment should come with a
                    # new artifact, come back when
                    # https://tracker.mender.io/browse/MEN-782 is resolved
                    # assert nextdep == None

                    # pretend we have the same artifact installed already
                    # NOTE: asking for a deployment while having it already
                    # installed is special in the sense that the status of
                    # deployment for this device will be marked as 'already-installed'
                    nextdep = dc.get_next_deployment(
                        dev.fake_token,
                        artifact_name=artifact_name,
                        device_type=dev.device_type)
                    self.log.info('device next: %s', nextdep)
                    assert nextdep == None
                    # verify that device status was properly recorded
                    self.verify_deployment_stats(depid,
                                                 expected={
                                                     'already-installed': 1,
                                                 })