Merge "Make create_server tests more policy-granular"
diff --git a/patrole_tempest_plugin/policy_authority.py b/patrole_tempest_plugin/policy_authority.py
index 3f4236b..6851942 100644
--- a/patrole_tempest_plugin/policy_authority.py
+++ b/patrole_tempest_plugin/policy_authority.py
@@ -292,8 +292,9 @@
 
     def _try_rule(self, apply_rule, target, access_data, o):
         if apply_rule not in self.rules:
-            message = "Policy action: {0} not found in policy file: {1}."\
-                      .format(apply_rule, self.path)
+            message = ("Policy action \"{0}\" not found in policy file: {1} or"
+                       " among registered policy in code defaults for service."
+                       ).format(apply_rule, self.path)
             LOG.debug(message)
             raise rbac_exceptions.RbacParsingException(message)
         else:
diff --git a/patrole_tempest_plugin/tests/api/volume/test_capabilities_rbac.py b/patrole_tempest_plugin/tests/api/volume/test_capabilities_rbac.py
index cfca14e..82b89ab 100644
--- a/patrole_tempest_plugin/tests/api/volume/test_capabilities_rbac.py
+++ b/patrole_tempest_plugin/tests/api/volume/test_capabilities_rbac.py
@@ -40,5 +40,5 @@
     @decorators.idempotent_id('40928b74-2141-11e7-93ae-92361f002671')
     def test_show_back_end_capabilities(self):
         host = self.hosts_client.list_hosts()['hosts'][0]['host_name']
-        self.rbac_utils.switch_role(self, toggle_rbac_role=True)
-        self.capabilities_client.show_backend_capabilities(host)
+        with self.rbac_utils.override_role(self):
+            self.capabilities_client.show_backend_capabilities(host)
diff --git a/patrole_tempest_plugin/tests/api/volume/test_encryption_types_rbac.py b/patrole_tempest_plugin/tests/api/volume/test_encryption_types_rbac.py
index a78585f..62ccc9e 100644
--- a/patrole_tempest_plugin/tests/api/volume/test_encryption_types_rbac.py
+++ b/patrole_tempest_plugin/tests/api/volume/test_encryption_types_rbac.py
@@ -48,11 +48,11 @@
         rule="volume_extension:volume_type_encryption")
     def test_create_volume_type_encryption(self):
         vol_type_id = self.create_volume_type()['id']
-        self.rbac_utils.switch_role(self, toggle_rbac_role=True)
-        self.encryption_types_client.create_encryption_type(
-            vol_type_id,
-            provider="nova.volume.encryptors.luks.LuksEncryptor",
-            control_location="front-end")['encryption']
+        with self.rbac_utils.override_role(self):
+            self.encryption_types_client.create_encryption_type(
+                vol_type_id,
+                provider="nova.volume.encryptors.luks.LuksEncryptor",
+                control_location="front-end")['encryption']
 
     @decorators.idempotent_id('6599e72e-acef-4c0d-a9b2-463fca30d1da')
     @rbac_rule_validation.action(
@@ -60,8 +60,8 @@
         rule="volume_extension:volume_type_encryption")
     def test_delete_volume_type_encryption(self):
         vol_type_id = self._create_volume_type_encryption()
-        self.rbac_utils.switch_role(self, toggle_rbac_role=True)
-        self.encryption_types_client.delete_encryption_type(vol_type_id)
+        with self.rbac_utils.override_role(self):
+            self.encryption_types_client.delete_encryption_type(vol_type_id)
 
     @decorators.idempotent_id('42da9fec-32fd-4dca-9242-8a53b2fed25a')
     @rbac_rule_validation.action(
@@ -69,10 +69,10 @@
         rule="volume_extension:volume_type_encryption")
     def test_update_volume_type_encryption(self):
         vol_type_id = self._create_volume_type_encryption()
-        self.rbac_utils.switch_role(self, toggle_rbac_role=True)
-        self.encryption_types_client.update_encryption_type(
-            vol_type_id,
-            control_location="front-end")
+        with self.rbac_utils.override_role(self):
+            self.encryption_types_client.update_encryption_type(
+                vol_type_id,
+                control_location="front-end")
 
     @decorators.idempotent_id('1381a3dc-248f-4282-b231-c9399018c804')
     @rbac_rule_validation.action(
@@ -80,5 +80,5 @@
         rule="volume_extension:volume_type_encryption")
     def test_show_volume_type_encryption(self):
         vol_type_id = self._create_volume_type_encryption()
-        self.rbac_utils.switch_role(self, toggle_rbac_role=True)
-        self.encryption_types_client.show_encryption_type(vol_type_id)
+        with self.rbac_utils.override_role(self):
+            self.encryption_types_client.show_encryption_type(vol_type_id)
diff --git a/patrole_tempest_plugin/tests/api/volume/test_groups_rbac.py b/patrole_tempest_plugin/tests/api/volume/test_groups_rbac.py
index 7f1010f..c9ecdae 100644
--- a/patrole_tempest_plugin/tests/api/volume/test_groups_rbac.py
+++ b/patrole_tempest_plugin/tests/api/volume/test_groups_rbac.py
@@ -24,13 +24,6 @@
 
 
 class BaseGroupRbacTest(rbac_base.BaseVolumeRbacTest):
-    credentials = ['primary', 'admin']
-
-    @classmethod
-    def setup_clients(cls):
-        super(BaseGroupRbacTest, cls).setup_clients()
-        cls.admin_groups_client = cls.os_admin.groups_v3_client
-        cls.admin_volumes_client = cls.os_admin.volumes_v3_client
 
     def setUp(self):
         super(BaseGroupRbacTest, self).setUp()
@@ -48,18 +41,18 @@
         else:
             self.addCleanup(self._delete_group, group['id'])
         waiters.wait_for_volume_resource_status(
-            self.admin_groups_client, group['id'], 'available')
+            self.groups_client, group['id'], 'available')
         return group
 
     def _delete_group(self, group_id):
         self.groups_client.delete_group(group_id, delete_volumes=True)
-        self.admin_groups_client.wait_for_resource_deletion(group_id)
+        self.groups_client.wait_for_resource_deletion(group_id)
 
-        vols = self.admin_volumes_client.list_volumes(
+        vols = self.volumes_client.list_volumes(
             detail=True, params={'all_tenants': True})['volumes']
         for vol in vols:
             if vol['group_id'] == group_id:
-                self.admin_volumes_client.wait_for_resource_deletion(
+                self.volumes_client.wait_for_resource_deletion(
                     vol['id'])
 
 
@@ -71,11 +64,18 @@
     @rbac_rule_validation.action(
         service="cinder",
         rule="group:create")
-    def test_create_group(self):
-        self.rbac_utils.switch_role(self, toggle_rbac_role=True)
-        self._create_group(ignore_notfound=True,
-                           group_type=self.group_type_id,
-                           volume_types=[self.volume_type_id])
+    def test_create_group(self, name=None):
+
+        group_name = name or data_utils.rand_name(
+            self.__class__.__name__ + '-Group')
+        with self.rbac_utils.override_role(self):
+            group = self.groups_client.create_group(
+                name=group_name, group_type=self.group_type_id,
+                volume_types=[self.volume_type_id])['group']
+        self.addCleanup(self._delete_group, group['id'])
+
+        waiters.wait_for_volume_resource_status(
+            self.groups_client, group['id'], 'available')
 
     @decorators.idempotent_id('9dc34a62-ae3e-439e-92b6-9389ea4c2863')
     @rbac_rule_validation.action(
@@ -85,24 +85,24 @@
         group = self._create_group(group_type=self.group_type_id,
                                    volume_types=[self.volume_type_id])
 
-        self.rbac_utils.switch_role(self, toggle_rbac_role=True)
-        self.groups_client.show_group(group['id'])
+        with self.rbac_utils.override_role(self):
+            self.groups_client.show_group(group['id'])
 
     @decorators.idempotent_id('db43841b-a173-4317-acfc-f83e4e48e4ee')
     @rbac_rule_validation.action(
         service="cinder",
         rule="group:get_all")
     def test_list_groups(self):
-        self.rbac_utils.switch_role(self, toggle_rbac_role=True)
-        self.groups_client.list_groups()['groups']
+        with self.rbac_utils.override_role(self):
+            self.groups_client.list_groups()['groups']
 
     @decorators.idempotent_id('5378da93-9c26-4ad4-b039-0555e2b8f668')
     @rbac_rule_validation.action(
         service="cinder",
         rule="group:get_all")
     def test_list_groups_with_details(self):
-        self.rbac_utils.switch_role(self, toggle_rbac_role=True)
-        self.groups_client.list_groups(detail=True)['groups']
+        with self.rbac_utils.override_role(self):
+            self.groups_client.list_groups(detail=True)['groups']
 
     @decorators.idempotent_id('f499fc48-df83-4917-bf8d-783ebf6f080b')
     @rbac_rule_validation.action(
@@ -113,20 +113,29 @@
                                    volume_types=[self.volume_type_id])
         updated_name = data_utils.rand_name(self.__class__.__name__ + '-Group')
 
-        self.rbac_utils.switch_role(self, toggle_rbac_role=True)
-        self.groups_client.update_group(group['id'], name=updated_name)
+        with self.rbac_utils.override_role(self):
+            self.groups_client.update_group(group['id'], name=updated_name)
 
     @decorators.idempotent_id('66fda391-5774-42a9-a018-80b34e57ab76')
     @rbac_rule_validation.action(
         service="cinder",
         rule="group:delete")
     def test_delete_group(self):
+
         group = self._create_group(ignore_notfound=True,
                                    group_type=self.group_type_id,
                                    volume_types=[self.volume_type_id])
+        group_id = group['id']
+        with self.rbac_utils.override_role(self):
+            self.groups_client.delete_group(group_id, delete_volumes=True)
 
-        self.rbac_utils.switch_role(self, toggle_rbac_role=True)
-        self._delete_group(group['id'])
+        self.groups_client.wait_for_resource_deletion(group_id)
+        vols = self.volumes_client.list_volumes(
+            detail=True, params={'all_tenants': True})['volumes']
+        for vol in vols:
+            if vol['group_id'] == group_id:
+                self.volumes_client.wait_for_resource_deletion(
+                    vol['id'])
 
 
 class GroupV320RbacTest(BaseGroupRbacTest):
@@ -159,8 +168,8 @@
         service="cinder",
         rule="group:group_types_manage")
     def test_create_group_type(self):
-        self.rbac_utils.switch_role(self, toggle_rbac_role=True)
-        self.create_group_type(ignore_notfound=True)
+        with self.rbac_utils.override_role(self):
+            self.create_group_type(ignore_notfound=True)
 
     @decorators.idempotent_id('a5f88c26-df7c-4f21-a3ae-7a4c2d6212b4')
     @rbac_rule_validation.action(
@@ -170,8 +179,8 @@
         # TODO(felipemonteiro): Combine with ``test_create_group_type``
         # once multiple policy testing is supported. This policy is
         # only enforced after "group:group_types_manage".
-        self.rbac_utils.switch_role(self, toggle_rbac_role=True)
-        group_type = self.create_group_type(ignore_notfound=True)
+        with self.rbac_utils.override_role(self):
+            group_type = self.create_group_type(ignore_notfound=True)
 
         if 'group_specs' not in group_type:
             raise rbac_exceptions.RbacMalformedResponse(
@@ -184,8 +193,8 @@
     def test_delete_group_type(self):
         group_type = self.create_group_type(ignore_notfound=True)
 
-        self.rbac_utils.switch_role(self, toggle_rbac_role=True)
-        self.group_types_client.delete_group_type(group_type['id'])
+        with self.rbac_utils.override_role(self):
+            self.group_types_client.delete_group_type(group_type['id'])
 
     @decorators.idempotent_id('8d9e2831-24c3-47b7-a76a-2e563287f12f')
     @rbac_rule_validation.action(
@@ -193,9 +202,8 @@
         rule="group:access_group_types_specs")
     def test_show_group_type(self):
         group_type = self.create_group_type()
-        self.rbac_utils.switch_role(self, toggle_rbac_role=True)
-        resp_body = \
-            self.group_types_client.show_group_type(
+        with self.rbac_utils.override_role(self):
+            resp_body = self.group_types_client.show_group_type(
                 group_type['id'])['group_type']
         if 'group_specs' not in resp_body:
             raise rbac_exceptions.RbacMalformedResponse(
diff --git a/patrole_tempest_plugin/tests/unit/test_policy_authority.py b/patrole_tempest_plugin/tests/unit/test_policy_authority.py
index db651fc..d2074e7 100644
--- a/patrole_tempest_plugin/tests/unit/test_policy_authority.py
+++ b/patrole_tempest_plugin/tests/unit/test_policy_authority.py
@@ -269,8 +269,10 @@
             test_tenant_id, test_user_id, "custom_rbac_policy")
 
         fake_rule = 'fake_rule'
-        expected_message = "Policy action: {0} not found in policy file: {1}."\
-                           .format(fake_rule, self.custom_policy_file)
+        expected_message = (
+            "Policy action \"{0}\" not found in policy file: {1} or among "
+            "registered policy in code defaults for service.").format(
+            fake_rule, self.custom_policy_file)
 
         e = self.assertRaises(rbac_exceptions.RbacParsingException,
                               authority.allowed, fake_rule, None)
@@ -289,9 +291,10 @@
             **{'__getitem__.return_value.side_effect': Exception(
                mock.sentinel.error)})
 
-        expected_message = "Policy action: {0} not found in "\
-                           "policy file: {1}.".format(mock.sentinel.rule,
-                                                      self.custom_policy_file)
+        expected_message = (
+            "Policy action \"{0}\" not found in policy file: {1} or among "
+            "registered policy in code defaults for service.").format(
+            mock.sentinel.rule, self.custom_policy_file)
 
         e = self.assertRaises(rbac_exceptions.RbacParsingException,
                               authority.allowed, mock.sentinel.rule, None)
diff --git a/test-requirements.txt b/test-requirements.txt
index 0437566..7a4ec28 100644
--- a/test-requirements.txt
+++ b/test-requirements.txt
@@ -3,7 +3,7 @@
 # process, which may cause wedges in the gate later.
 hacking>=1.0.0 # Apache-2.0
 
-sphinx>=1.6.2 # BSD
+sphinx!=1.6.6,>=1.6.2 # BSD
 openstackdocstheme>=1.17.0 # Apache-2.0
 reno>=2.5.0 # Apache-2.0
 fixtures>=3.0.0 # Apache-2.0/BSD