Add image task validation
Glance is adding a /image/$image/tasks API to make it easier to consume the import API. This fetches the tasks after glance-direct import, and validates that they look like we expect. Because this is only supported after v2.12, we check for that before doing the validation. To make that easier, this adds a has_version() helper to the VersionsClient. Change-Id: I2850f0659e82bf5c5a1005de0a063e7fcacadb51
This commit is contained in:
parent
08b38f5dc9
commit
7bde7bf537
|
@ -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.
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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'))
|
||||
|
|
Loading…
Reference in New Issue