class TestArtifact(ArtifactsClient): m = MinioClient() def setup(self): self.setup_swagger() def test_artifacts_all(self): res = self.client.Management_API.List_Artifacts().result() self.log.debug("result: %s", res) @pytest.mark.usefixtures("clean_minio", "clean_db") def test_artifacts_new_bogus_empty(self): # try bogus image data try: res = self.client.Management_API.Upload_Artifact( Authorization="foo", size=100, artifact="".encode(), description="bar", ).result() except bravado.exception.HTTPError as e: assert sum( 1 for x in self.m.list_objects("mender-artifact-storage")) == 0 assert e.response.status_code == 400 else: raise AssertionError("expected to fail") @pytest.mark.usefixtures("clean_minio", "clean_db") def test_artifacts_new_bogus_data(self): with artifact_from_raw_data(b"foo_bar") as art: files = ArtifactsClient.make_upload_meta({ "description": "bar", "size": str(art.size), "artifact": ( "firmware", art, "application/octet-stream", {}, ), }) rsp = requests.post(self.make_api_url("/artifacts"), files=files) assert sum( 1 for x in self.m.list_objects("mender-artifact-storage")) == 0 assert rsp.status_code == 400 @pytest.mark.usefixtures("clean_minio", "clean_db") 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") @pytest.mark.usefixtures("clean_minio", "clean_db") 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 def test_single_artifact(self): # try with bogus image ID try: res = self.client.Management_API.Show_Artifact(Authorization="foo", id="foo").result() except bravado.exception.HTTPError as e: assert e.response.status_code == 400 else: raise AssertionError("expected to fail") # try with nonexistent image ID try: res = self.client.Management_API.Show_Artifact( Authorization="foo", id=uuid4()).result() except bravado.exception.HTTPError as e: assert e.response.status_code == 404 else: raise AssertionError("expected to fail") @pytest.mark.usefixtures("clean_minio", "clean_db") def test_artifacts_generate_valid(self): artifact_name = str(uuid4()) description = "description for foo " + artifact_name device_type = "project-" + str(uuid4()) data = b"foo_bar" # generate artifact self.log.info("uploading artifact") artid = self.generate_artifact( name=artifact_name, description=description, device_types_compatible=device_type, type="single_file", args="", data=data, ) # the file has been stored assert sum( 1 for x in self.m.list_objects("mender-artifact-storage")) == 1
class TestRelease: m = MinioClient() d = DeploymentsClient() @pytest.mark.usefixtures("clean_db") def test_releases_no_artifacts(self): rsp = self.d.client.Management_API.List_Releases( Authorization="foo").result() assert len(rsp[0]) == 0 @pytest.mark.usefixtures("clean_minio", "clean_db") def test_get_all_releses(self): with artifacts_added_from_data([ ("foo", "device-type-1"), ("foo", "device-type-2"), ("bar", "device-type-2"), ]): rsp = self.d.client.Management_API.List_Releases( Authorization="foo").result() res = rsp[0] assert len(res) == 2 release1 = res[0] release2 = res[1] assert release1.Name == "foo" assert len(release1.Artifacts) == 2 r1a1 = release1.Artifacts[0] r1a2 = release1.Artifacts[1] assert r1a1["name"] == "foo" assert r1a1["device_types_compatible"] == ["device-type-1"] assert r1a2["name"] == "foo" assert r1a2["device_types_compatible"] == ["device-type-2"] assert release2.Name == "bar" assert len(release2.Artifacts) == 1 r2a = release2.Artifacts[0] assert r2a["name"] == "bar" assert r2a["device_types_compatible"] == ["device-type-2"] @pytest.mark.usefixtures("clean_minio", "clean_db") def test_get_releses_by_name(self): with artifacts_added_from_data([ ("foo", "device-type-1"), ("foo", "device-type-2"), ("bar", "device-type-2"), ]): rsp = self.d.client.Management_API.List_Releases( Authorization="foo", name="bar").result() res = rsp[0] assert len(res) == 1 release = res[0] assert release.Name == "bar" assert len(release.Artifacts) == 1 artifact = release.Artifacts[0] assert artifact["name"] == "bar" assert artifact["device_types_compatible"] == ["device-type-2"] @pytest.mark.usefixtures("clean_minio", "clean_db") def test_get_releses_by_name_no_result(self): with artifacts_added_from_data([ ("foo", "device-type-1"), ("foo", "device-type-2"), ("bar", "device-type-2"), ]): rsp = self.d.client.Management_API.List_Releases( Authorization="foo", name="baz").result() res = rsp[0] assert len(res) == 0
class TestArtifact(ArtifactsClient): m = MinioClient() def setup(self): self.setup_swagger() def test_artifacts_all(self): res = self.client.artifacts.get_artifacts().result() self.log.debug('result: %s', res) @pytest.mark.usefixtures("clean_minio") def test_artifacts_new_bogus_empty(self): # try bogus image data try: res = self.client.artifacts.post_artifacts(Authorization='foo', size=100, artifact=''.encode(), description="bar").result() except bravado.exception.HTTPError as e: assert sum(1 for x in self.m.list_objects("mender-artifact-storage")) == 0 assert e.response.status_code == 400 else: raise AssertionError('expected to fail') @pytest.mark.usefixtures("clean_minio") def test_artifacts_new_bogus_data(self): with artifact_from_raw_data(b'foo_bar') as art: files = ArtifactsClient.make_upload_meta({ 'description': 'bar', 'size': str(art.size), 'artifact': ('firmware', art, 'application/octet-stream', {}), }) rsp = requests.post(self.make_api_url('/artifacts'), files=files) assert sum(1 for x in self.m.list_objects("mender-artifact-storage")) == 0 assert rsp.status_code == 400 @pytest.mark.usefixtures("clean_minio") 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.artifacts.get_artifacts().result() self.log.debug('result: %s', res) assert len(res[0]) > 0 res = self.client.artifacts.get_artifacts_id(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 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.artifacts.get_artifacts_id_download(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.artifacts.get_artifacts_id(Authorization='foo', id=artid).result() except bravado.exception.HTTPError as e: assert e.response.status_code == 404 else: raise AssertionError('expected to fail') def test_single_artifact(self): # try with bogus image ID try: res = self.client.artifacts.get_artifacts_id(Authorization='foo', id='foo').result() except bravado.exception.HTTPError as e: assert e.response.status_code == 400 else: raise AssertionError('expected to fail') # try with nonexistent image ID try: res = self.client.artifacts.get_artifacts_id(Authorization='foo', id=uuid4()).result() except bravado.exception.HTTPError as e: assert e.response.status_code == 404 else: raise AssertionError('expected to fail')