Initial functionality framework.
Includes:
rbac_util - Utility for switching between roles for tests.
rbac_auth - Determines if a given role is valid for a given api call.
rbac_rule_validation - Determines if a allowed proper access and denied improper access (403 error)
rbac_role_converter - Converts policy.json files into a list of api's and the roles that can access them.

One example rbac_base in tests/api/rbac_base
One example test in tests/api/images/test_images_rbac.py

New config settings for rbac_flag, rbac_test_role, and rbac_roles

Implements bp: initial-framework
Co-Authored-By: Sangeet Gupta <sg774j@att.com>
Co-Authored-By: Rick Bartra <rb560u@att.com>
Co-Authored-By: Felipe Monteiro <felipe.monteiro@att.com>
Co-Authored-By: Anthony Bellino <ab2434@att.com>
Co-Authored-By: Avishek Dutta <ad620p@att.com>

Change-Id: Ic97b2558ba33ab47ac8174ae37629d36ceb1c9de
diff --git a/tests/test_rbac_rule_validation.py b/tests/test_rbac_rule_validation.py
new file mode 100644
index 0000000..a8e2be3
--- /dev/null
+++ b/tests/test_rbac_rule_validation.py
@@ -0,0 +1,89 @@
+#    Copyright 2017 AT&T Inc.
+#
+#    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.
+
+import mock
+
+from patrole_tempest_plugin import rbac_exceptions
+from patrole_tempest_plugin import rbac_rule_validation as rbac_rv
+
+from tempest.lib import exceptions
+
+from tempest.tests import base
+
+
+class RBACRuleValidationTest(base.TestCase):
+    @mock.patch('patrole_tempest_plugin.rbac_auth.RbacAuthority')
+    def test_RBAC_rv_happy_path(self, mock_auth):
+        decorator = rbac_rv.action("", "", "")
+        mock_function = mock.Mock()
+        wrapper = decorator(mock_function)
+        wrapper()
+        self.assertTrue(mock_function.called)
+
+    @mock.patch('patrole_tempest_plugin.rbac_auth.RbacAuthority')
+    def test_RBAC_rv_forbidden(self, mock_auth):
+        decorator = rbac_rv.action("", "", "")
+        mock_function = mock.Mock()
+        mock_function.side_effect = exceptions.Forbidden
+        wrapper = decorator(mock_function)
+        self.assertRaises(exceptions.Forbidden, wrapper)
+
+    @mock.patch('patrole_tempest_plugin.rbac_auth.RbacAuthority')
+    def test_RBAC_rv_rbac_action_failed(self, mock_auth):
+        decorator = rbac_rv.action("", "", "")
+        mock_function = mock.Mock()
+        mock_function.side_effect = rbac_exceptions.RbacActionFailed
+        wrapper = decorator(mock_function)
+        self.assertRaises(exceptions.Forbidden, wrapper)
+
+    @mock.patch('patrole_tempest_plugin.rbac_auth.RbacAuthority')
+    def test_RBAC_rv_not_allowed(self, mock_auth):
+        decorator = rbac_rv.action("", "", "")
+
+        mock_function = mock.Mock()
+        wrapper = decorator(mock_function)
+
+        mock_permission = mock.Mock()
+        mock_permission.get_permission.return_value = False
+        mock_auth.return_value = mock_permission
+
+        self.assertRaises(rbac_exceptions.RbacOverPermission, wrapper)
+
+    @mock.patch('patrole_tempest_plugin.rbac_auth.RbacAuthority')
+    def test_RBAC_rv_forbidden_not_allowed(self, mock_auth):
+        decorator = rbac_rv.action("", "", "")
+
+        mock_function = mock.Mock()
+        mock_function.side_effect = exceptions.Forbidden
+        wrapper = decorator(mock_function)
+
+        mock_permission = mock.Mock()
+        mock_permission.get_permission.return_value = False
+        mock_auth.return_value = mock_permission
+
+        self.assertIsNone(wrapper())
+
+    @mock.patch('patrole_tempest_plugin.rbac_auth.RbacAuthority')
+    def test_RBAC_rv_rbac_action_failed_not_allowed(self, mock_auth):
+        decorator = rbac_rv.action("", "", "")
+
+        mock_function = mock.Mock()
+        mock_function.side_effect = rbac_exceptions.RbacActionFailed
+        wrapper = decorator(mock_function)
+
+        mock_permission = mock.Mock()
+        mock_permission.get_permission.return_value = False
+        mock_auth.return_value = mock_permission
+
+        self.assertIsNone(wrapper())