Merge "Improve tests for test_volume_basic_crud.py"
diff --git a/patrole_tempest_plugin/rbac_utils.py b/patrole_tempest_plugin/rbac_utils.py
index 02b9297..9a9f864 100644
--- a/patrole_tempest_plugin/rbac_utils.py
+++ b/patrole_tempest_plugin/rbac_utils.py
@@ -137,7 +137,9 @@
             with excutils.save_and_reraise_exception():
                 LOG.exception(exp)
         finally:
-            test_obj.os_primary.auth_provider.clear_auth()
+            auth_providers = test_obj.get_auth_providers()
+            for provider in auth_providers:
+                provider.clear_auth()
             # Fernet tokens are not subsecond aware so sleep to ensure we are
             # passing the second boundary before attempting to authenticate.
             # Only sleep if a token revocation occurred as a result of role
@@ -145,7 +147,9 @@
             # ``[identity] admin_role`` == ``[patrole] rbac_test_role``.
             if not role_already_present:
                 time.sleep(1)
-            test_obj.os_primary.auth_provider.set_auth()
+
+            for provider in auth_providers:
+                provider.set_auth()
 
     def _get_roles_by_name(self):
         available_roles = self.admin_roles_client.list_roles()['roles']
@@ -219,6 +223,15 @@
     """
 
     @classmethod
+    def get_auth_providers(cls):
+        """Returns list of auth_providers used within test.
+
+        Tests may redefine this method to include their own or third party
+        client auth_providers.
+        """
+        return [cls.os_primary.auth_provider]
+
+    @classmethod
     def skip_rbac_checks(cls):
         if not CONF.patrole.enable_rbac:
             deprecation_msg = ("The `[patrole].enable_rbac` option is "
diff --git a/patrole_tempest_plugin/tests/api/network/rbac_base.py b/patrole_tempest_plugin/tests/api/network/rbac_base.py
index 6c57a0c..9d3e28b 100644
--- a/patrole_tempest_plugin/tests/api/network/rbac_base.py
+++ b/patrole_tempest_plugin/tests/api/network/rbac_base.py
@@ -40,6 +40,15 @@
     """
 
     @classmethod
+    def get_auth_providers(cls):
+        """Register auth_provider from neutron-tempest-plugin.
+        """
+        providers = super(BaseNetworkPluginRbacTest, cls).get_auth_providers()
+        if cls.is_neutron_tempest_plugin_avaliable():
+            providers.append(cls.ntp_client.auth_provider)
+        return providers
+
+    @classmethod
     def skip_checks(cls):
         super(BaseNetworkPluginRbacTest, cls).skip_checks()
 
diff --git a/patrole_tempest_plugin/tests/api/network/test_auto_allocated_topology_rbac.py b/patrole_tempest_plugin/tests/api/network/test_auto_allocated_topology_rbac.py
new file mode 100644
index 0000000..bcf62d7
--- /dev/null
+++ b/patrole_tempest_plugin/tests/api/network/test_auto_allocated_topology_rbac.py
@@ -0,0 +1,44 @@
+# Copyright 2018 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.common import utils
+from tempest.lib import decorators
+
+from patrole_tempest_plugin import rbac_rule_validation
+from patrole_tempest_plugin.tests.api.network import rbac_base as base
+
+
+class AutoAllocationTopologyPluginRbacTest(base.BaseNetworkPluginRbacTest):
+
+    @classmethod
+    def skip_checks(cls):
+        super(AutoAllocationTopologyPluginRbacTest, cls).skip_checks()
+        if not utils.is_extension_enabled('auto-allocated-topology',
+                                          'network'):
+            msg = "auto-allocated-topology extension not enabled."
+            raise cls.skipException(msg)
+
+    @decorators.idempotent_id('299CB831-F6B2-49CA-882B-E9A8E36945A2')
+    @rbac_rule_validation.action(service="neutron",
+                                 rules=["get_auto_allocated_topology"],
+                                 expected_error_codes=[404])
+    def test_show_auto_allocated_topology(self):
+        """Show auto_allocated_topology.
+
+        RBAC test for the neutron "get_auto_allocated_topology" policy
+        """
+        with self.rbac_utils.override_role(self):
+            self.ntp_client.get_auto_allocated_topology(
+                tenant_id=self.os_primary.credentials.tenant_id)
diff --git a/patrole_tempest_plugin/tests/api/network/test_segments_rbac.py b/patrole_tempest_plugin/tests/api/network/test_segments_rbac.py
index 2db674b..9725e2b 100644
--- a/patrole_tempest_plugin/tests/api/network/test_segments_rbac.py
+++ b/patrole_tempest_plugin/tests/api/network/test_segments_rbac.py
@@ -78,7 +78,8 @@
 
     @decorators.idempotent_id('c02618e7-bb20-1a3a-83c8-6eec2af08127')
     @rbac_rule_validation.action(service="neutron",
-                                 rules=["get_segment"])
+                                 rules=["get_segment"],
+                                 expected_error_codes=[404])
     def test_show_segment(self):
         """Show segment.
 
@@ -92,7 +93,8 @@
     @decorators.idempotent_id('c02618e7-bb20-1a3a-83c8-6eec2af08128')
     @rbac_rule_validation.action(service="neutron",
                                  rules=["get_segment",
-                                        "update_segment"])
+                                        "update_segment"],
+                                 expected_error_codes=[404, 403])
     def test_update_segment(self):
         """Update segment.
 
@@ -107,7 +109,8 @@
     @decorators.idempotent_id('c02618e7-bb20-1a3a-83c8-6eec2af08129')
     @rbac_rule_validation.action(service="neutron",
                                  rules=["get_segment",
-                                        "delete_segment"])
+                                        "delete_segment"],
+                                 expected_error_codes=[404, 403])
     def test_delete_segment(self):
         """Delete segment.
 
diff --git a/patrole_tempest_plugin/tests/unit/fixtures.py b/patrole_tempest_plugin/tests/unit/fixtures.py
index 4e3387e..1c47985 100644
--- a/patrole_tempest_plugin/tests/unit/fixtures.py
+++ b/patrole_tempest_plugin/tests/unit/fixtures.py
@@ -77,7 +77,9 @@
         }
         self.mock_test_obj = mock.Mock(
             __name__='patrole_unit_test', spec=test.BaseTestCase,
-            os_primary=mock.Mock(), **test_obj_kwargs)
+            os_primary=mock.Mock(),
+            get_auth_providers=mock.Mock(return_value=[mock.Mock()]),
+            **test_obj_kwargs)
 
         # Mock out functionality that can't be used by unit tests. Mocking out
         # time.sleep is a test optimization.
diff --git a/patrole_tempest_plugin/tests/unit/test_rbac_utils.py b/patrole_tempest_plugin/tests/unit/test_rbac_utils.py
index 4937318..c5264aa 100644
--- a/patrole_tempest_plugin/tests/unit/test_rbac_utils.py
+++ b/patrole_tempest_plugin/tests/unit/test_rbac_utils.py
@@ -57,9 +57,9 @@
 
         roles_client.create_user_role_on_project.assert_called_once_with(
             self.rbac_utils.PROJECT_ID, self.rbac_utils.USER_ID, 'admin_id')
-        mock_test_obj.os_primary.auth_provider.clear_auth\
+        mock_test_obj.get_auth_providers()[0].clear_auth\
             .assert_called_once_with()
-        mock_test_obj.os_primary.auth_provider.set_auth\
+        mock_test_obj.get_auth_providers()[0].set_auth\
             .assert_called_once_with()
         mock_time.sleep.assert_called_once_with(1)
 
@@ -86,9 +86,9 @@
             mock.call(self.rbac_utils.PROJECT_ID, self.rbac_utils.USER_ID,
                       'member_id')
         ])
-        mock_test_obj.os_primary.auth_provider.clear_auth.assert_has_calls(
+        mock_test_obj.get_auth_providers()[0].clear_auth.assert_has_calls(
             [mock.call()] * 2)
-        mock_test_obj.os_primary.auth_provider.set_auth.assert_has_calls(
+        mock_test_obj.get_auth_providers()[0].set_auth.assert_has_calls(
             [mock.call()] * 2)
         mock_time.sleep.assert_has_calls([mock.call(1)] * 2)
 
@@ -120,9 +120,9 @@
             mock.call(self.rbac_utils.PROJECT_ID, self.rbac_utils.USER_ID,
                       'admin_id')
         ])
-        mock_test_obj.os_primary.auth_provider.clear_auth.assert_has_calls(
+        mock_test_obj.get_auth_providers()[0].clear_auth.assert_has_calls(
             [mock.call()] * 3)
-        mock_test_obj.os_primary.auth_provider.set_auth.assert_has_calls(
+        mock_test_obj.get_auth_providers()[0].set_auth.assert_has_calls(
             [mock.call()] * 3)
         mock_time.sleep.assert_has_calls([mock.call(1)] * 3)