Create rbac utils fixture and refactor tests
This commit creates a test fixture for rbac_utils.RbacUtils
and refactors test_rbac_utils tests accordingly. This
allows other tests to use the fixture as needed, improving
code maintenance and readability, as well as the ease
with which tests can be written.
Specifically:
- adds fixtures file for overriding conf settings and
for rbac_utils.RbacUtils
- refactors rbac_utils tests to use the appropriate
fixture
Change-Id: I2f49137ff71089ecf9764ee1f7887b64185249dd
diff --git a/patrole_tempest_plugin/tests/unit/fixtures.py b/patrole_tempest_plugin/tests/unit/fixtures.py
new file mode 100644
index 0000000..f25e05d
--- /dev/null
+++ b/patrole_tempest_plugin/tests/unit/fixtures.py
@@ -0,0 +1,109 @@
+# 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.
+
+"""Fixtures for Patrole tests."""
+from __future__ import absolute_import
+
+import fixtures
+import mock
+
+from tempest import config
+
+from patrole_tempest_plugin import rbac_utils
+
+
+CONF = config.CONF
+
+
+class ConfPatcher(fixtures.Fixture):
+ """Fixture to patch and restore global CONF. Adopted from Nova.
+
+ This also resets overrides for everything that is patched during
+ its teardown.
+ """
+
+ def __init__(self, **kwargs):
+ """Constructor
+
+ :params group: if specified all config options apply to that group.
+ :params **kwargs: the rest of the kwargs are processed as a
+ set of key/value pairs to be set as configuration override.
+ """
+ super(ConfPatcher, self).__init__()
+ self.group = kwargs.pop('group', None)
+ self.args = kwargs
+
+ def setUp(self):
+ super(ConfPatcher, self).setUp()
+ for k, v in self.args.items():
+ self.addCleanup(CONF.clear_override, k, self.group)
+ CONF.set_override(k, v, self.group)
+
+
+class RbacUtilsFixture(fixtures.Fixture):
+ """Fixture for RbacUtils class."""
+
+ USER_ID = mock.sentinel.user_id
+ PROJECT_ID = mock.sentinel.project_id
+
+ def __init__(self, **kwargs):
+ super(RbacUtilsFixture, self).__init__()
+ self.available_roles = None
+
+ def setUp(self):
+ super(RbacUtilsFixture, self).setUp()
+
+ self.useFixture(ConfPatcher(rbac_test_role='member', group='rbac'))
+ self.useFixture(ConfPatcher(
+ admin_role='admin', auth_version='v3', group='identity'))
+
+ test_obj_kwargs = {
+ 'os_primary.credentials.user_id': self.USER_ID,
+ 'os_primary.credentials.tenant_id': self.PROJECT_ID,
+ 'os_primary.credentials.project_id': self.PROJECT_ID,
+ 'get_identity_version.return_value': 'v3'
+ }
+ self.mock_test_obj = mock.Mock(**test_obj_kwargs)
+ self.mock_time = mock.patch.object(rbac_utils, 'time').start()
+
+ self.roles_v3_client = (
+ self.mock_test_obj.get_client_manager.return_value.roles_v3_client)
+
+ def switch_role(self, *role_toggles):
+ """Instantiate `rbac_utils.RbacUtils` and call `switch_role`.
+
+ Create an instance of `rbac_utils.RbacUtils` and call `switch_role`
+ for each boolean value in `role_toggles`. The number of calls to
+ `switch_role` is always 1 + len(role_toggles) because the
+ `rbac_utils.RbacUtils` constructor automatically calls `switch_role`.
+
+ :param role_toggles: the list of boolean values iterated over and
+ passed to `switch_role`.
+ """
+ if not self.available_roles:
+ self.set_roles('admin', 'member')
+
+ self.fake_rbac_utils = rbac_utils.RbacUtils(self.mock_test_obj)
+ for role_toggle in role_toggles:
+ self.fake_rbac_utils.switch_role(self.mock_test_obj, role_toggle)
+
+ def set_roles(self, *roles):
+ """Set the list of available roles in the system to `roles`."""
+ self.available_roles = {
+ 'roles': [{'name': role, 'id': '%s_id' % role} for role in roles]
+ }
+ self.roles_v3_client.list_user_roles_on_project.return_value =\
+ self.available_roles
+ self.roles_v3_client.list_roles.return_value = self.available_roles