diff --git a/releasenotes/notes/image-client-add-versions-and-tasks-ac289dbfe1c899cc.yaml b/releasenotes/notes/image-client-add-versions-and-tasks-ac289dbfe1c899cc.yaml new file mode 100644 index 0000000000..fde6193a17 --- /dev/null +++ b/releasenotes/notes/image-client-add-versions-and-tasks-ac289dbfe1c899cc.yaml @@ -0,0 +1,6 @@ +--- +features: + - | + Adds a method to images_client to get tasks relevant to a given image. Also adds + has_version() method to image versions_client to probe for availability of a given + API version. diff --git a/tempest/api/image/v2/test_images.py b/tempest/api/image/v2/test_images.py index 8dba311bae..efa23bb83a 100644 --- a/tempest/api/image/v2/test_images.py +++ b/tempest/api/image/v2/test_images.py @@ -96,9 +96,26 @@ class ImportImagesTest(base.BaseV2ImageTest): image_id = self._stage_and_check() # import image from staging to backend - self.client.image_import(image_id, method='glance-direct') + resp = self.client.image_import(image_id, method='glance-direct') waiters.wait_for_image_imported_to_stores(self.client, image_id) + if not self.versions_client.has_version('2.12'): + # API is not new enough to support image/tasks API + LOG.info('Glance does not support v2.12, so I am unable to ' + 'validate the image/tasks API.') + return + + # Make sure we can access the task and that some of the key + # fields look legit. + tasks = self.client.show_image_tasks(image_id) + self.assertEqual(1, len(tasks['tasks'])) + task = tasks['tasks'][0] + self.assertEqual('success', task['status']) + self.assertEqual(resp.response['x-openstack-request-id'], + task['request_id']) + self.assertEqual('glance-direct', + task['input']['import_req']['method']['name']) + @decorators.idempotent_id('f6feb7a4-b04f-4706-a011-206129f83e62') def test_image_web_download_import(self): """Test 'web-download' import functionalities diff --git a/tempest/lib/services/image/v2/images_client.py b/tempest/lib/services/image/v2/images_client.py index fa3bb8c5f5..abf427cd9c 100644 --- a/tempest/lib/services/image/v2/images_client.py +++ b/tempest/lib/services/image/v2/images_client.py @@ -121,6 +121,14 @@ class ImagesClient(rest_client.RestClient): body = json.loads(body) return rest_client.ResponseBody(resp, body) + def show_image_tasks(self, image_id): + """Show image tasks.""" + url = 'images/%s/tasks' % image_id + resp, body = self.get(url) + self.expected_success(200, resp.status) + body = json.loads(body) + return rest_client.ResponseBody(resp, body) + def is_resource_deleted(self, id): try: self.show_image(id) diff --git a/tempest/lib/services/image/v2/versions_client.py b/tempest/lib/services/image/v2/versions_client.py index 1b7f8064f0..98b4fb6209 100644 --- a/tempest/lib/services/image/v2/versions_client.py +++ b/tempest/lib/services/image/v2/versions_client.py @@ -30,3 +30,13 @@ class VersionsClient(rest_client.RestClient): self.expected_success(300, resp.status) body = json.loads(body) return rest_client.ResponseBody(resp, body) + + def has_version(self, version): + """Return True if a version is supported.""" + version = 'v%s' % version + supported = ['SUPPORTED', 'CURRENT'] + versions = self.list_versions() + for version_struct in versions['versions']: + if version_struct['id'] == version: + return version_struct['status'] in supported + return False diff --git a/tempest/tests/lib/services/image/v2/test_images_client.py b/tempest/tests/lib/services/image/v2/test_images_client.py index 7ee61d2577..5b162f83c3 100644 --- a/tempest/tests/lib/services/image/v2/test_images_client.py +++ b/tempest/tests/lib/services/image/v2/test_images_client.py @@ -105,6 +105,44 @@ class TestImagesClient(base.BaseServiceTest): "first": "/v2/images" } + FAKE_SHOW_IMAGE_TASKS = { + "tasks": [ + { + "id": "ee22890e-8948-4ea6-9668-831f973c84f5", + "image_id": "dddddddd-dddd-dddd-dddd-dddddddddddd", + "request-id": "rrrrrrr-rrrr-rrrr-rrrr-rrrrrrrrrrrr", + "user": "uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu", + "type": "api_image_import", + "status": "processing", + "owner": "64f0efc9955145aeb06f297a8a6fe402", + "expires_at": None, + "created_at": "2020-12-18T05:20:38.000000", + "updated_at": "2020-12-18T05:25:39.000000", + "deleted_at": None, + "deleted": False, + "input": { + "image_id": "829c729b-ebc4-4cc7-a164-6f43f1149b17", + "import_req": { + "method": { + "name": "copy-image", + }, + "all_stores": True, + "all_stores_must_succeed": False, + }, + "backend": [ + "fast", + "cheap", + "slow", + "reliable", + "common", + ] + }, + "result": None, + "message": "Copied 15 MiB", + } + ] + } + FAKE_TAG_NAME = "fake tag" def setUp(self): @@ -230,3 +268,11 @@ class TestImagesClient(base.BaseServiceTest): def test_list_images_with_bytes_body(self): self._test_list_images(bytes_body=True) + + def test_show_image_tasks(self): + self.check_service_client_function( + self.client.show_image_tasks, + 'tempest.lib.common.rest_client.RestClient.get', + self.FAKE_SHOW_IMAGE_TASKS, + True, + image_id="e485aab9-0907-4973-921c-bb6da8a8fcf8") diff --git a/tempest/tests/lib/services/image/v2/test_versions_client.py b/tempest/tests/lib/services/image/v2/test_versions_client.py index 6234b0699d..98c558acd7 100644 --- a/tempest/tests/lib/services/image/v2/test_versions_client.py +++ b/tempest/tests/lib/services/image/v2/test_versions_client.py @@ -12,6 +12,8 @@ # License for the specific language governing permissions and limitations # under the License. +import fixtures + from tempest.lib.services.image.v2 import versions_client from tempest.tests.lib import fake_auth_provider from tempest.tests.lib.services import base @@ -92,3 +94,13 @@ class TestVersionsClient(base.BaseServiceTest): def test_list_versions_with_bytes_body(self): self._test_list_versions(bytes_body=True) + + def test_has_version(self): + mocked_r = self.create_response(self.FAKE_VERSIONS_INFO, False, + 300, None) + self.useFixture(fixtures.MockPatch( + 'tempest.lib.common.rest_client.RestClient.raw_request', + return_value=mocked_r)) + + self.assertTrue(self.client.has_version('2.1')) + self.assertFalse(self.client.has_version('9.9'))