Merge "Replace generic api_extensions checks"
diff --git a/patrole_tempest_plugin/tests/api/volume/test_quota_classes_rbac.py b/patrole_tempest_plugin/tests/api/volume/test_quota_classes_rbac.py
new file mode 100644
index 0000000..44c0d3e
--- /dev/null
+++ b/patrole_tempest_plugin/tests/api/volume/test_quota_classes_rbac.py
@@ -0,0 +1,60 @@
+# Copyright 2017 AT&T Corporation.
+# 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.common.utils import data_utils
+from tempest.lib import decorators
+from tempest import test
+
+from patrole_tempest_plugin import rbac_rule_validation
+from patrole_tempest_plugin.tests.api.volume import rbac_base
+
+
+class QuotaClassesRbacTest(rbac_base.BaseVolumeRbacTest):
+
+    @classmethod
+    def skip_checks(cls):
+        super(QuotaClassesRbacTest, cls).skip_checks()
+        if not test.is_extension_enabled('os-quota-class-sets', 'volume'):
+            msg = ("%s skipped as os-quota-class-sets not enabled."
+                   % cls.__name__)
+            raise cls.skipException(msg)
+
+    @classmethod
+    def setup_clients(cls):
+        super(QuotaClassesRbacTest, cls).setup_clients()
+        cls.client = cls.os_primary.quota_classes_client
+        cls.quota_name = data_utils.rand_name(cls.__name__ + '-QuotaClass')
+
+    @decorators.idempotent_id('1a060def-2b43-4534-97f5-5eadbbe8c726')
+    @rbac_rule_validation.action(service="cinder",
+                                 rule="volume_extension:quota_classes")
+    def test_show_quota_class_set(self):
+        self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+        self.client.show_quota_class_set(self.quota_name)['quota_class_set']
+
+    @decorators.idempotent_id('72159478-23a7-4c75-989f-6bac609eca62')
+    @rbac_rule_validation.action(service="cinder",
+                                 rule="volume_extension:quota_classes")
+    def test_update_quota_class_set(self):
+        quota_class_set = self.client.show_quota_class_set(self.quota_name)[
+            'quota_class_set']
+        quota_class_set.pop('id')
+
+        self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+        self.client.update_quota_class_set(self.quota_name, **quota_class_set)
+
+
+class QuotaClassesV3RbacTest(QuotaClassesRbacTest):
+    _api_version = 3
diff --git a/patrole_tempest_plugin/tests/api/volume/test_volume_actions_rbac.py b/patrole_tempest_plugin/tests/api/volume/test_volume_actions_rbac.py
index f94ed43..416fb4d 100644
--- a/patrole_tempest_plugin/tests/api/volume/test_volume_actions_rbac.py
+++ b/patrole_tempest_plugin/tests/api/volume/test_volume_actions_rbac.py
@@ -40,7 +40,6 @@
             cls.image_client = cls.os_primary.image_client
         elif CONF.image_feature_enabled.api_v2:
             cls.image_client = cls.os_primary.image_client_v2
-        cls.image_id = CONF.compute.image_ref
 
     @classmethod
     def resource_setup(cls):
@@ -119,28 +118,6 @@
         self.addCleanup(self.client.update_volume_readonly,
                         self.volume['id'], readonly=False)
 
-    @decorators.idempotent_id('a9d9e825-5ea3-42e6-96f3-7ac4e97b2ed0')
-    @rbac_rule_validation.action(
-        service="cinder",
-        rule="volume:update_volume_metadata")
-    def test_update_volume_image_metadata(self):
-        self.rbac_utils.switch_role(self, toggle_rbac_role=True)
-
-        self.volumes_client.update_volume_image_metadata(
-            self.volume['id'], image_id=self.image_id)
-
-    @decorators.idempotent_id('a41c8eed-2051-4a25-b401-df036faacbdc')
-    @rbac_rule_validation.action(
-        service="cinder",
-        rule="volume:delete_volume_metadata")
-    def test_delete_volume_image_metadata(self):
-        self.volumes_client.update_volume_image_metadata(
-            self.volume['id'], image_id=self.image_id)
-
-        self.rbac_utils.switch_role(self, toggle_rbac_role=True)
-        self.volumes_client.delete_volume_image_metadata(
-            self.volume['id'], 'image_id')
-
     @decorators.idempotent_id('72bab13c-dfaf-4b6d-a132-c83a85fb1776')
     @rbac_rule_validation.action(
         service="cinder",
@@ -149,7 +126,37 @@
         volume = self.create_volume()
 
         self.rbac_utils.switch_role(self, toggle_rbac_role=True)
-        self.volumes_client.unmanage_volume(volume['id'])
+        self.client.unmanage_volume(volume['id'])
+
+    @decorators.idempotent_id('59b783c0-f4ef-430c-8a90-1bad97d4ec5c')
+    @rbac_rule_validation.action(service="cinder",
+                                 rule="volume:update")
+    def test_volume_set_bootable(self):
+        self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+        self.client.set_bootable_volume(self.volume['id'], bootable=True)
+
+    @decorators.idempotent_id('41566922-75a1-4484-99c7-9c8782ee99ac')
+    @rbac_rule_validation.action(service="cinder",
+                                 rule="volume:reserve_volume")
+    def test_volume_reserve(self):
+        self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+        self.client.reserve_volume(self.volume['id'])
+
+    @decorators.idempotent_id('e5fa9564-77d9-4e57-b0c0-3e0ae4d08535')
+    @rbac_rule_validation.action(service="cinder",
+                                 rule="volume:unreserve_volume")
+    def test_volume_unreserve(self):
+        self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+        self.client.unreserve_volume(self.volume['id'])
+
+    @decorators.idempotent_id('c015c82f-7010-48cc-bd71-4ef542046f20')
+    @rbac_rule_validation.action(service="cinder",
+                                 rule="volume:retype")
+    def test_volume_retype(self):
+        volume = self.create_volume()
+        vol_type = self.create_volume_type()['name']
+        self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+        self.client.retype_volume(volume['id'], new_type=vol_type)
 
 
 class VolumesActionsV3RbacTest(VolumesActionsRbacTest):
diff --git a/patrole_tempest_plugin/tests/api/volume/test_volume_metadata_rbac.py b/patrole_tempest_plugin/tests/api/volume/test_volume_metadata_rbac.py
index 91f55c7..d07e5c6 100644
--- a/patrole_tempest_plugin/tests/api/volume/test_volume_metadata_rbac.py
+++ b/patrole_tempest_plugin/tests/api/volume/test_volume_metadata_rbac.py
@@ -13,8 +13,6 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from oslo_log import log as logging
-
 from tempest import config
 from tempest.lib import decorators
 
@@ -22,7 +20,6 @@
 from patrole_tempest_plugin.tests.api.volume import rbac_base
 
 CONF = config.CONF
-LOG = logging.getLogger(__name__)
 
 
 class VolumeMetadataRbacTest(rbac_base.BaseVolumeRbacTest):
@@ -30,54 +27,88 @@
     def setup_clients(cls):
         super(VolumeMetadataRbacTest, cls).setup_clients()
         cls.client = cls.volumes_client
+        if CONF.image_feature_enabled.api_v1:
+            cls.image_client = cls.os_primary.image_client
+        elif CONF.image_feature_enabled.api_v2:
+            cls.image_client = cls.os_primary.image_client_v2
+        cls.image_id = CONF.compute.image_ref
 
-    def _add_metadata(self, volume):
+    @classmethod
+    def resource_setup(cls):
+        super(VolumeMetadataRbacTest, cls).resource_setup()
+        cls.volume = cls.create_volume()
+        cls._add_metadata(cls.volume)
+        cls.image_id = CONF.compute.image_ref
+
+    @classmethod
+    def _add_metadata(cls, volume):
         # Create metadata for the volume
         metadata = {"key1": "value1",
                     "key2": "value2",
                     "key3": "value3",
                     "key4": "<value&special_chars>"}
-        self.volumes_client.create_volume_metadata(volume['id'],
-                                                   metadata)['metadata']
+        cls.client.create_volume_metadata(cls.volume['id'],
+                                          metadata)['metadata']
 
     @rbac_rule_validation.action(service="cinder",
                                  rule="volume:update_volume_metadata")
     @decorators.idempotent_id('232bbb8b-4c29-44dc-9077-b1398c20b738')
     def test_create_volume_metadata(self):
-        volume = self.create_volume()
         self.rbac_utils.switch_role(self, toggle_rbac_role=True)
-        self._add_metadata(volume)
+        self._add_metadata(self.volume)
 
     @rbac_rule_validation.action(service="cinder",
                                  rule="volume:get")
     @decorators.idempotent_id('87ea37d9-23ab-47b2-a59c-16fc4d2c6dfa')
     def test_get_volume_metadata(self):
-        volume = self.create_volume()
-        self._add_metadata(volume)
         self.rbac_utils.switch_role(self, toggle_rbac_role=True)
-        self.volumes_client.show_volume_metadata(volume['id'])['metadata']
+        self.client.show_volume_metadata(self.volume['id'])['metadata']
 
     @rbac_rule_validation.action(service="cinder",
                                  rule="volume:delete_volume_metadata")
     @decorators.idempotent_id('7498dfc1-9db2-4423-ad20-e6dcb25d1beb')
-    def test_delete_volume_metadata(self):
-        volume = self.create_volume()
-        self._add_metadata(volume)
+    def test_delete_volume_metadata_item(self):
         self.rbac_utils.switch_role(self, toggle_rbac_role=True)
-        self.volumes_client.delete_volume_metadata_item(volume['id'],
-                                                        "key1")
+        self.client.delete_volume_metadata_item(self.volume['id'], "key1")
+
+    @decorators.idempotent_id('a41c8eed-2051-4a25-b401-df036faacbdc')
+    @rbac_rule_validation.action(
+        service="cinder",
+        rule="volume:delete_volume_metadata")
+    def test_delete_volume_image_metadata(self):
+        self.client.update_volume_image_metadata(self.volume['id'],
+                                                 image_id=self.image_id)
+        self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+        self.client.delete_volume_image_metadata(self.volume['id'], 'image_id')
 
     @rbac_rule_validation.action(service="cinder",
                                  rule="volume:update_volume_metadata")
     @decorators.idempotent_id('8ce2ff80-99ba-49ae-9bb1-7e96729ee5af')
-    def test_update_volume_metadata(self):
-        volume = self.create_volume()
-        self._add_metadata(volume)
+    def test_update_volume_metadata_item(self):
         # Metadata to update
         update_item = {"key3": "value3_update"}
         self.rbac_utils.switch_role(self, toggle_rbac_role=True)
-        self.volumes_client.update_volume_metadata_item(
-            volume['id'], "key3", update_item)['meta']
+        self.client.update_volume_metadata_item(self.volume['id'], "key3",
+                                                update_item)['meta']
+
+    @decorators.idempotent_id('a231b445-97a5-4657-b05f-245895e88da9')
+    @rbac_rule_validation.action(service="cinder",
+                                 rule="volume:update_volume_metadata")
+    def test_update_volume_metadata(self):
+        # Metadata to update
+        update = {"key1": "value1",
+                  "key3": "value3"}
+        self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+        self.client.update_volume_metadata(self.volume['id'], update)
+
+    @decorators.idempotent_id('a9d9e825-5ea3-42e6-96f3-7ac4e97b2ed0')
+    @rbac_rule_validation.action(
+        service="cinder",
+        rule="volume:update_volume_metadata")
+    def test_update_volume_image_metadata(self):
+        self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+        self.client.update_volume_image_metadata(self.volume['id'],
+                                                 image_id=self.image_id)
 
 
 class VolumeMetadataV3RbacTest(VolumeMetadataRbacTest):
diff --git a/releasenotes/notes/add-quota-classes-tests-3e61e671f6e131df.yaml b/releasenotes/notes/add-quota-classes-tests-3e61e671f6e131df.yaml
new file mode 100644
index 0000000..656f6a1
--- /dev/null
+++ b/releasenotes/notes/add-quota-classes-tests-3e61e671f6e131df.yaml
@@ -0,0 +1,5 @@
+---
+features:
+  - |
+    Add RBAC tests for cinder os-quota-class-sets API, which cover the
+    policy action "volume_extension:quota_classes".
diff --git a/releasenotes/notes/volumes-client-tests-d697a4a75d3e1405.yaml b/releasenotes/notes/volumes-client-tests-d697a4a75d3e1405.yaml
new file mode 100644
index 0000000..5dc9ff3
--- /dev/null
+++ b/releasenotes/notes/volumes-client-tests-d697a4a75d3e1405.yaml
@@ -0,0 +1,8 @@
+---
+features:
+  - Added tests for volumes client functions set
+    bootable, reserve, unreserve, and update metadata.
+other:
+  - Renamed update metadata item and delete metadata
+    item tests to accurately reflect what actions are
+    being performed.