Merge "Add image task validation"
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 0000000..fde6193
--- /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 8dba311..efa23bb 100644
--- a/tempest/api/image/v2/test_images.py
+++ b/tempest/api/image/v2/test_images.py
@@ -96,9 +96,26 @@
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 fa3bb8c..abf427c 100644
--- a/tempest/lib/services/image/v2/images_client.py
+++ b/tempest/lib/services/image/v2/images_client.py
@@ -121,6 +121,14 @@
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 1b7f806..98b4fb6 100644
--- a/tempest/lib/services/image/v2/versions_client.py
+++ b/tempest/lib/services/image/v2/versions_client.py
@@ -30,3 +30,13 @@
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 7ee61d2..5b162f8 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 @@
"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 @@
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 6234b06..98c558a 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 @@
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'))