Merge "Reduce chance of name collision for resources."
diff --git a/tempest/common/rest_client.py b/tempest/common/rest_client.py
index d68b9ed..88c8886 100644
--- a/tempest/common/rest_client.py
+++ b/tempest/common/rest_client.py
@@ -320,6 +320,10 @@
except KeyError:
ctype = 'application/json'
+ # It is not an error response
+ if resp.status < 400:
+ return
+
JSON_ENC = ['application/json; charset=UTF-8', 'application/json',
'application/json; charset=utf-8']
# NOTE(mtreinish): This is for compatibility with Glance and swift
diff --git a/tempest/services/image/v1/json/image_client.py b/tempest/services/image/v1/json/image_client.py
index 77c9cd2..9c7269f 100644
--- a/tempest/services/image/v1/json/image_client.py
+++ b/tempest/services/image/v1/json/image_client.py
@@ -18,13 +18,17 @@
import copy
import errno
import json
+import logging
import os
+import time
import urllib
from tempest.common import glance_http
from tempest.common.rest_client import RestClient
from tempest import exceptions
+LOG = logging.getLogger(__name__)
+
class ImageClientJSON(RestClient):
@@ -59,8 +63,13 @@
def _image_meta_to_headers(self, fields):
headers = {}
fields_copy = copy.deepcopy(fields)
+ copy_from = fields_copy.pop('copy_from', None)
+ if copy_from is not None:
+ headers['x-glance-api-copy-from'] = copy_from
for key, value in fields_copy.pop('properties', {}).iteritems():
headers['x-image-meta-property-%s' % key] = str(value)
+ for key, value in fields_copy.pop('api', {}).iteritems():
+ headers['x-glance-api-property-%s' % key] = str(value)
for key, value in fields_copy.iteritems():
headers['x-image-meta-%s' % key] = str(value)
return headers
@@ -130,7 +139,7 @@
headers = {}
- for option in ['is_public', 'location', 'properties']:
+ for option in ['is_public', 'location', 'properties', 'copy_from']:
if option in kwargs:
params[option] = kwargs.get(option)
@@ -187,10 +196,15 @@
body = json.loads(body)
return resp, body['images']
+ def get_image_meta(self, image_id):
+ url = 'v1/images/%s' % image_id
+ resp, __ = self.head(url)
+ body = self._image_meta_from_headers(resp)
+ return resp, body
+
def get_image(self, image_id):
url = 'v1/images/%s' % image_id
- resp, __ = self.get(url)
- body = self._image_meta_from_headers(resp)
+ resp, body = self.get(url)
return resp, body
def is_resource_deleted(self, id):
@@ -231,3 +245,34 @@
resp, data = self.put(url, body, self.headers)
data = json.loads(data)
return resp, data
+
+ #NOTE(afazekas): just for the wait function
+ def _get_image_status(self, image_id):
+ resp, meta = self.get_image_meta(image_id)
+ status = meta['status']
+ return status
+
+ #NOTE(afazkas): Wait reinvented again. It is not in the correct layer
+ def wait_for_image_status(self, image_id, status):
+ """Waits for a Image to reach a given status."""
+ start_time = time.time()
+ old_value = value = self._get_image_status(image_id)
+ while True:
+ dtime = time.time() - start_time
+ time.sleep(self.build_interval)
+ if value != old_value:
+ LOG.info('Value transition from "%s" to "%s"'
+ 'in %d second(s).', old_value,
+ value, dtime)
+ if (value == status):
+ return value
+
+ if dtime > self.build_timeout:
+ message = ('Time Limit Exceeded! (%ds)'
+ 'while waiting for %s, '
+ 'but we got %s.' %
+ (self.build_timeout, status, value))
+ raise exceptions.TimeoutException(message)
+ time.sleep(self.build_interval)
+ old_value = value
+ value = self._get_image_status(image_id)
diff --git a/tempest/tests/compute/images/test_images_oneserver.py b/tempest/tests/compute/images/test_images_oneserver.py
index 9412d39..ca3dbb5 100644
--- a/tempest/tests/compute/images/test_images_oneserver.py
+++ b/tempest/tests/compute/images/test_images_oneserver.py
@@ -41,7 +41,12 @@
super(ImagesOneServerTestJSON, cls).setUpClass()
cls.client = cls.images_client
cls.servers_client = cls.servers_client
- resp, cls.server = cls.create_server(wait_until='ACTIVE')
+
+ try:
+ resp, cls.server = cls.create_server(wait_until='ACTIVE')
+ except Exception:
+ cls.tearDownClass()
+ raise
cls.image_ids = []
diff --git a/tempest/tests/identity/admin/test_users.py b/tempest/tests/identity/admin/test_users.py
index 80c6fc9..0573b21 100644
--- a/tempest/tests/identity/admin/test_users.py
+++ b/tempest/tests/identity/admin/test_users.py
@@ -326,17 +326,9 @@
invalid_id.append(rand_name("dddd@#%%^$"))
invalid_id.append('!@#()$%^&*?<>{}[]')
#List the users with invalid tenant id
- fail = list()
for invalid in invalid_id:
- try:
- resp, body = self.client.list_users_for_tenant(invalid)
- except exceptions.NotFound:
- pass
- else:
- fail.append(invalid)
- if len(fail) != 0:
- self.fail('Should raise Not Found when list users with invalid'
- 'tenant ids %s' % fail)
+ self.assertRaises(exceptions.NotFound,
+ self.client.list_users_for_tenant, invalid)
class UsersTestXML(UsersTestJSON):
diff --git a/tempest/tests/image/v1/test_images.py b/tempest/tests/image/v1/test_images.py
index 9304a33..1b6fa10 100644
--- a/tempest/tests/image/v1/test_images.py
+++ b/tempest/tests/image/v1/test_images.py
@@ -80,6 +80,43 @@
self.assertEqual(properties['key1'], 'value1')
self.assertEqual(properties['key2'], 'value2')
+ def test_register_http_image(self):
+ container_client = self.os.container_client
+ object_client = self.os.object_client
+ container_name = "image_container"
+ object_name = "test_image.img"
+ container_client.create_container(container_name)
+ self.addCleanup(container_client.delete_container, container_name)
+ cont_headers = {'X-Container-Read': '.r:*'}
+ resp, _ = container_client.update_container_metadata(
+ container_name,
+ metadata=cont_headers,
+ metadata_prefix='')
+ self.assertEqual(resp['status'], '204')
+
+ data = "TESTIMAGE"
+ resp, _ = object_client.create_object(container_name,
+ object_name, data)
+ self.addCleanup(object_client.delete_object, container_name,
+ object_name)
+ self.assertEqual(resp['status'], '201')
+ object_url = '/'.join((object_client.base_url,
+ container_name,
+ object_name))
+ resp, body = self.create_image(name='New Http Image',
+ container_format='bare',
+ disk_format='raw', is_public=True,
+ copy_from=object_url)
+ self.assertTrue('id' in body)
+ image_id = body.get('id')
+ self.created_images.append(image_id)
+ self.assertEqual('New Http Image', body.get('name'))
+ self.assertTrue(body.get('is_public'))
+ self.client.wait_for_image_status(image_id, 'active')
+ resp, body = self.client.get_image(image_id)
+ self.assertEqual(resp['status'], '200')
+ self.assertEqual(body, data)
+
class ListImagesTest(base.BaseV1ImageTest):