Merge "Add image cache client"
diff --git a/releasenotes/notes/add-image-cache-apis-as-tempest-clients-fbcd186927a85e2f.yaml b/releasenotes/notes/add-image-cache-apis-as-tempest-clients-fbcd186927a85e2f.yaml
new file mode 100644
index 0000000..38cc9ac
--- /dev/null
+++ b/releasenotes/notes/add-image-cache-apis-as-tempest-clients-fbcd186927a85e2f.yaml
@@ -0,0 +1,6 @@
+---
+features:
+  - |
+    The following ``image_cache`` tempest client for glance v2 image
+    caching API is implemented in this release.
+
diff --git a/tempest/clients.py b/tempest/clients.py
index 4c3d875..b7fa54a 100644
--- a/tempest/clients.py
+++ b/tempest/clients.py
@@ -87,6 +87,7 @@
             self.image_member_client = self.image_v1.ImageMembersClient()
             self.image_client_v2 = self.image_v2.ImagesClient()
             self.image_member_client_v2 = self.image_v2.ImageMembersClient()
+            self.image_cache_client = self.image_v2.ImageCacheClient()
             self.namespaces_client = self.image_v2.NamespacesClient()
             self.resource_types_client = self.image_v2.ResourceTypesClient()
             self.namespace_objects_client = \
diff --git a/tempest/lib/services/image/v2/__init__.py b/tempest/lib/services/image/v2/__init__.py
index 99a5321..a2f5bdc 100644
--- a/tempest/lib/services/image/v2/__init__.py
+++ b/tempest/lib/services/image/v2/__init__.py
@@ -12,6 +12,8 @@
 # License for the specific language governing permissions and limitations under
 # the License.
 
+from tempest.lib.services.image.v2.image_cache_client import \
+    ImageCacheClient
 from tempest.lib.services.image.v2.image_members_client import \
     ImageMembersClient
 from tempest.lib.services.image.v2.images_client import ImagesClient
@@ -27,7 +29,7 @@
 from tempest.lib.services.image.v2.schemas_client import SchemasClient
 from tempest.lib.services.image.v2.versions_client import VersionsClient
 
-__all__ = ['ImageMembersClient', 'ImagesClient', 'NamespaceObjectsClient',
-           'NamespacePropertiesClient', 'NamespaceTagsClient',
-           'NamespacesClient', 'ResourceTypesClient', 'SchemasClient',
-           'VersionsClient']
+__all__ = ['ImageMembersClient', 'ImagesClient', 'ImageCacheClient',
+           'NamespaceObjectsClient', 'NamespacePropertiesClient',
+           'NamespaceTagsClient', 'NamespacesClient', 'ResourceTypesClient',
+           'SchemasClient', 'VersionsClient']
diff --git a/tempest/lib/services/image/v2/image_cache_client.py b/tempest/lib/services/image/v2/image_cache_client.py
new file mode 100644
index 0000000..90ff776
--- /dev/null
+++ b/tempest/lib/services/image/v2/image_cache_client.py
@@ -0,0 +1,74 @@
+# Copyright 2022 Red Hat, Inc.
+# All Rights Reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+from oslo_serialization import jsonutils as json
+
+from tempest.lib.common import rest_client
+
+
+class ImageCacheClient(rest_client.RestClient):
+    api_version = "v2"
+
+    def list_cache(self):
+        """Lists all images in cache or queue. (Since Image API v2.14)
+
+        For a full list of available parameters, please refer to the official
+        API reference:
+        https://docs.openstack.org/api-ref/image/v2/?expanded=query-cache-status-detail#cache-manage
+        """
+        url = 'cache'
+        resp, body = self.get(url)
+        self.expected_success(200, resp.status)
+        body = json.loads(body)
+        return rest_client.ResponseBody(resp, body)
+
+    def cache_queue(self, image_id):
+        """Queues image for caching. (Since Image API v2.14)
+
+        For a full list of available parameters, please refer to the official
+        API reference:
+        https://docs.openstack.org/api-ref/image/v2/?expanded=queue-image-detail#queue-image
+        """
+        url = 'cache/%s' % image_id
+        resp, body = self.put(url, body=None)
+        self.expected_success(202, resp.status)
+        return rest_client.ResponseBody(resp, body=body)
+
+    def cache_delete(self, image_id):
+        """Deletes a image from cache. (Since Image API v2.14)
+
+        For a full list of available parameters, please refer to the official
+        API reference:
+        https://docs.openstack.org/api-ref/image/v2/?expanded=delete-image-from-cache-detail#delete-image-from-cache
+        """
+        url = 'cache/%s' % image_id
+        resp, _ = self.delete(url)
+        self.expected_success(204, resp.status)
+        return rest_client.ResponseBody(resp)
+
+    def cache_clear(self, target=None):
+        """Clears the cache and its queue. (Since Image API v2.14)
+
+        For a full list of available parameters, please refer to the official
+        API reference:
+        https://docs.openstack.org/api-ref/image/v2/?expanded=clear-images-from-cache-detail#delete-image-from-cache
+        """
+        url = 'cache'
+        headers = {}
+        if target:
+            headers['x-image-cache-clear-target'] = target
+        resp, _ = self.delete(url, headers=headers)
+        self.expected_success(204, resp.status)
+        return rest_client.ResponseBody(resp)
diff --git a/tempest/tests/lib/services/image/v2/test_image_cache_client.py b/tempest/tests/lib/services/image/v2/test_image_cache_client.py
new file mode 100644
index 0000000..1a99115
--- /dev/null
+++ b/tempest/tests/lib/services/image/v2/test_image_cache_client.py
@@ -0,0 +1,64 @@
+# Copyright 2022 Red Hat, Inc.  All rights reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+from tempest.lib.services.image.v2 import image_cache_client
+from tempest.tests.lib import fake_auth_provider
+from tempest.tests.lib.services import base
+
+
+class TestImageCacheClient(base.BaseServiceTest):
+    def setUp(self):
+        super(TestImageCacheClient, self).setUp()
+        fake_auth = fake_auth_provider.FakeAuthProvider()
+        self.client = image_cache_client.ImageCacheClient(
+            fake_auth, 'image', 'regionOne')
+
+    def test_list_cache(self):
+        fake_result = {
+            "cached_images": [{
+                "image_id": "8f332e84-ea60-4501-8e11-5efcddb81f30",
+                "hits": 3,
+                "last_accessed": 1639578364.65118,
+                "last_modified": 1639389612.596718,
+                "size": 16300544
+            }],
+            "queued_images": ['1bea47ed-f6a9-463b-b423-14b9cca9ad27']}
+        self.check_service_client_function(
+            self.client.list_cache,
+            'tempest.lib.common.rest_client.RestClient.get',
+            fake_result,
+            mock_args=['cache'])
+
+    def test_cache_queue(self):
+        self.check_service_client_function(
+            self.client.cache_queue,
+            'tempest.lib.common.rest_client.RestClient.put',
+            {},
+            status=202,
+            image_id="e485aab9-0907-4973-921c-bb6da8a8fcf8")
+
+    def test_cache_delete(self):
+        fake_result = {}
+        self.check_service_client_function(
+            self.client.cache_delete,
+            'tempest.lib.common.rest_client.RestClient.delete',
+            fake_result, image_id="e485aab9-0907-4973-921c-bb6da8a8fcf8",
+            status=204)
+
+    def test_cache_clear_without_target(self):
+        fake_result = {}
+        self.check_service_client_function(
+            self.client.cache_clear,
+            'tempest.lib.common.rest_client.RestClient.delete',
+            fake_result, status=204)