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)