Merge "Add support for image deactivate and reactivate"
diff --git a/etc/tempest.conf.sample b/etc/tempest.conf.sample
index 56172f8..6424f55 100644
--- a/etc/tempest.conf.sample
+++ b/etc/tempest.conf.sample
@@ -648,6 +648,10 @@
# Is the v1 image API enabled (boolean value)
#api_v1 = true
+# Is the deactivate-image feature enabled. The feature has been
+# integrated since Kilo. (boolean value)
+#deactivate_image = false
+
[input-scenario]
diff --git a/tempest/api/image/admin/__init__.py b/tempest/api/image/admin/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tempest/api/image/admin/__init__.py
diff --git a/tempest/api/image/admin/v2/__init__.py b/tempest/api/image/admin/v2/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tempest/api/image/admin/v2/__init__.py
diff --git a/tempest/api/image/admin/v2/test_images.py b/tempest/api/image/admin/v2/test_images.py
new file mode 100644
index 0000000..83efc7d
--- /dev/null
+++ b/tempest/api/image/admin/v2/test_images.py
@@ -0,0 +1,55 @@
+# Copyright 2015 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 six import moves
+from tempest_lib.common.utils import data_utils
+import testtools
+
+from tempest.api.image import base
+from tempest import config
+from tempest import test
+
+
+CONF = config.CONF
+
+
+class BasicAdminOperationsImagesTest(base.BaseV2ImageAdminTest):
+
+ """
+ Here we test admin operations of images
+ """
+ @testtools.skipUnless(CONF.image_feature_enabled.deactivate_image,
+ 'deactivate-image is not available.')
+ @test.idempotent_id('951ebe01-969f-4ea9-9898-8a3f1f442ab0')
+ def test_admin_deactivate_reactivate_image(self):
+ # Create image by non-admin tenant
+ image_name = data_utils.rand_name('image')
+ body = self.client.create_image(name=image_name,
+ container_format='bare',
+ disk_format='raw',
+ visibility='private')
+ image_id = body['id']
+ self.addCleanup(self.client.delete_image, image_id)
+ # upload an image file
+ image_file = moves.cStringIO(data_utils.random_bytes())
+ self.client.store_image(image_id, image_file)
+ # deactivate image
+ self.admin_client.deactivate_image(image_id)
+ body = self.client.show_image(image_id)
+ self.assertEqual("deactivated", body['status'])
+ # reactivate image
+ self.admin_client.reactivate_image(image_id)
+ body = self.client.show_image(image_id)
+ self.assertEqual("active", body['status'])
diff --git a/tempest/api/image/base.py b/tempest/api/image/base.py
index 00959d9..dc38cab 100644
--- a/tempest/api/image/base.py
+++ b/tempest/api/image/base.py
@@ -158,3 +158,23 @@
image_id = image['id']
self.addCleanup(self.os_img_client.delete_image, image_id)
return image_id
+
+
+class BaseV1ImageAdminTest(BaseImageTest):
+ credentials = ['admin', 'primary']
+
+ @classmethod
+ def setup_clients(cls):
+ super(BaseV1ImageAdminTest, cls).setup_clients()
+ cls.client = cls.os.image_client
+ cls.admin_client = cls.os_adm.image_client
+
+
+class BaseV2ImageAdminTest(BaseImageTest):
+ credentials = ['admin', 'primary']
+
+ @classmethod
+ def setup_clients(cls):
+ super(BaseV2ImageAdminTest, cls).setup_clients()
+ cls.client = cls.os.image_client_v2
+ cls.admin_client = cls.os_adm.image_client_v2
diff --git a/tempest/config.py b/tempest/config.py
index bbd6772..0fa5bf5 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -433,6 +433,10 @@
cfg.BoolOpt('api_v1',
default=True,
help="Is the v1 image API enabled"),
+ cfg.BoolOpt('deactivate_image',
+ default=False,
+ help="Is the deactivate-image feature enabled."
+ " The feature has been integrated since Kilo."),
]
network_group = cfg.OptGroup(name='network',
diff --git a/tempest/services/image/v2/json/image_client.py b/tempest/services/image/v2/json/image_client.py
index cec81fb..9e37f6e 100644
--- a/tempest/services/image/v2/json/image_client.py
+++ b/tempest/services/image/v2/json/image_client.py
@@ -96,6 +96,18 @@
body = json.loads(body)
return service_client.ResponseBody(resp, body)
+ def deactivate_image(self, image_id):
+ url = 'v2/images/%s/actions/deactivate' % image_id
+ resp, body = self.post(url, None)
+ self.expected_success(204, resp.status)
+ return service_client.ResponseBody(resp, body)
+
+ def reactivate_image(self, image_id):
+ url = 'v2/images/%s/actions/reactivate' % image_id
+ resp, body = self.post(url, None)
+ self.expected_success(204, resp.status)
+ return service_client.ResponseBody(resp, body)
+
def delete_image(self, image_id):
url = 'v2/images/%s' % image_id
resp, _ = self.delete(url)