Merge "Add basic image filtering tests"
diff --git a/tempest/services/image/json/image_client.py b/tempest/services/image/json/image_client.py
index e9276aa..f119664 100644
--- a/tempest/services/image/json/image_client.py
+++ b/tempest/services/image/json/image_client.py
@@ -176,11 +176,21 @@
url = '/' + url
self.http.raw_request('DELETE', url)
- def image_list(self, params=None):
+ def image_list(self, **kwargs):
url = 'v1/images'
- if params:
- url += '?%s' % urllib.urlencode(params)
+ if len(kwargs) > 0:
+ url += '?%s' % urllib.urlencode(kwargs)
+
+ resp, body = self.get(url)
+ body = json.loads(body)
+ return resp, body['images']
+
+ def image_list_detail(self, **kwargs):
+ url = 'v1/images/detail'
+
+ if len(kwargs) > 0:
+ url += '?%s' % urllib.urlencode(kwargs)
resp, body = self.get(url)
body = json.loads(body)
diff --git a/tempest/tests/image/test_images.py b/tempest/tests/image/test_images.py
index 3a70b3d..84bb650 100644
--- a/tempest/tests/image/test_images.py
+++ b/tempest/tests/image/test_images.py
@@ -16,15 +16,11 @@
# under the License.
import cStringIO as StringIO
-import random
-
-import tempest.test
-
-from tempest.test import attr
-
from tempest import clients
from tempest import exceptions
+import tempest.test
+from tempest.test import attr
class CreateRegisterImagesTest(tempest.test.BaseTestCase):
@@ -113,12 +109,27 @@
# We add a few images here to test the listing functionality of
# the images API
- for x in xrange(0, 10):
- # We make even images remote and odd images standard
- if x % 2 == 0:
- cls.created_images.append(cls._create_remote_image(x))
- else:
- cls.created_images.append(cls._create_standard_image(x))
+ img1 = cls._create_remote_image('one', 'bare', 'raw')
+ img2 = cls._create_remote_image('two', 'ami', 'ami')
+ img3 = cls._create_remote_image('dup', 'bare', 'raw')
+ img4 = cls._create_remote_image('dup', 'bare', 'raw')
+ img5 = cls._create_standard_image('1', 'ami', 'ami', 42)
+ img6 = cls._create_standard_image('2', 'ami', 'ami', 142)
+ img7 = cls._create_standard_image('33', 'bare', 'raw', 142)
+ img8 = cls._create_standard_image('33', 'bare', 'raw', 142)
+ cls.created_set = set(cls.created_images)
+ # 4x-4x remote image
+ cls.remote_set = set((img1, img2, img3, img4))
+ cls.standard_set = set((img5, img6, img7, img8))
+ # 5x bare, 3x ami
+ cls.bare_set = set((img1, img3, img4, img7, img8))
+ cls.ami_set = set((img2, img5, img6))
+ # 1x with size 42
+ cls.size42_set = set((img5,))
+ # 3x with size 142
+ cls.size142_set = set((img6, img7, img8))
+ # dup named
+ cls.dup_set = set((img3, img4))
@classmethod
def tearDownClass(cls):
@@ -127,31 +138,36 @@
cls.client.wait_for_resource_deletion(image_id)
@classmethod
- def _create_remote_image(cls, x):
+ def _create_remote_image(cls, name, container_format, disk_format):
"""
Create a new remote image and return the ID of the newly-registered
image
"""
- name = 'New Remote Image %s' % x
- location = 'http://example.com/someimage_%s.iso' % x
- resp, body = cls.client.create_image(name, 'bare', 'raw',
- is_public=True,
- location=location)
- image_id = body['id']
+ name = 'New Remote Image %s' % name
+ location = 'http://example.com/someimage_%s.iso' % name
+ resp, image = cls.client.create_image(name,
+ container_format, disk_format,
+ is_public=True,
+ location=location)
+ image_id = image['id']
+ cls.created_images.append(image_id)
return image_id
@classmethod
- def _create_standard_image(cls, x):
+ def _create_standard_image(cls, name, container_format,
+ disk_format, size):
"""
Create a new standard image and return the ID of the newly-registered
image. Note that the size of the new image is a random number between
1024 and 4096
"""
- image_file = StringIO.StringIO('*' * random.randint(1024, 4096))
- name = 'New Standard Image %s' % x
- resp, body = cls.client.create_image(name, 'bare', 'raw',
- is_public=True, data=image_file)
- image_id = body['id']
+ image_file = StringIO.StringIO('*' * size)
+ name = 'New Standard Image %s' % name
+ resp, image = cls.client.create_image(name,
+ container_format, disk_format,
+ is_public=True, data=image_file)
+ image_id = image['id']
+ cls.created_images.append(image_id)
return image_id
@attr(type='image')
@@ -160,5 +176,69 @@
resp, images_list = self.client.image_list()
self.assertEqual(resp['status'], '200')
image_list = map(lambda x: x['id'], images_list)
- for image in self.created_images:
- self.assertTrue(image in image_list)
+ for image_id in self.created_images:
+ self.assertTrue(image_id in image_list)
+
+ @attr(type='image')
+ def test_index_disk_format(self):
+ resp, images_list = self.client.image_list(disk_format='ami')
+ self.assertEqual(resp['status'], '200')
+ for image in images_list:
+ self.assertEqual(image['disk_format'], 'ami')
+ result_set = set(map(lambda x: x['id'], images_list))
+ self.assertTrue(self.ami_set <= result_set)
+ self.assertFalse(self.created_set - self.ami_set <= result_set)
+
+ @attr(type='image')
+ def test_index_container_format(self):
+ resp, images_list = self.client.image_list(container_format='bare')
+ self.assertEqual(resp['status'], '200')
+ for image in images_list:
+ self.assertEqual(image['container_format'], 'bare')
+ result_set = set(map(lambda x: x['id'], images_list))
+ self.assertTrue(self.bare_set <= result_set)
+ self.assertFalse(self.created_set - self.bare_set <= result_set)
+
+ @attr(type='image')
+ def test_index_max_size(self):
+ resp, images_list = self.client.image_list(size_max=42)
+ self.assertEqual(resp['status'], '200')
+ for image in images_list:
+ self.assertTrue(image['size'] <= 42)
+ result_set = set(map(lambda x: x['id'], images_list))
+ self.assertTrue(self.size42_set <= result_set)
+ self.assertFalse(self.created_set - self.size42_set <= result_set)
+
+ @attr(type='image')
+ def test_index_min_size(self):
+ resp, images_list = self.client.image_list(size_min=142)
+ self.assertEqual(resp['status'], '200')
+ for image in images_list:
+ self.assertTrue(image['size'] >= 142)
+ result_set = set(map(lambda x: x['id'], images_list))
+ self.assertTrue(self.size142_set <= result_set)
+ self.assertFalse(self.size42_set <= result_set)
+
+ @attr(type='image')
+ def test_index_status_active_detail(self):
+ resp, images_list = self.client.image_list_detail(status='active',
+ sort_key='size',
+ sort_dir='desc')
+ self.assertEqual(resp['status'], '200')
+ top_size = images_list[0]['size'] # We have non-zero sized images
+ for image in images_list:
+ size = image['size']
+ self.assertTrue(size <= top_size)
+ top_size = size
+ self.assertEqual(image['status'], 'active')
+
+ @attr(type='image')
+ def test_index_name(self):
+ resp, images_list = self.client.image_list_detail(
+ name='New Remote Image dup')
+ self.assertEqual(resp['status'], '200')
+ result_set = set(map(lambda x: x['id'], images_list))
+ for image in images_list:
+ self.assertEqual(image['name'], 'New Remote Image dup')
+ self.assertTrue(self.dup_set <= result_set)
+ self.assertFalse(self.created_set - self.dup_set <= result_set)