Fix role validation edge case bug in rbac_utils
Currently, a history of the order of switchToRbacRole calls is
maintained by class name in rbac_utils. This means that each
uniquely named class has its own distinct history, allowing
for determination of whether proper role-switching is being
performed.
However, sometimes class names are not unique across modules:
for example, both network and compute service folders have
a test called test_floating_ips_rbac, causing essentially
collisions to take place in the role-switching history dictionary.
This currently causes a false negative in role validation
in the logs [0].
The solution to this edge case is straightforward: the key
that indexes into the history dictionary should be changed
from class name to module path + class name. For example,
the key "TestFloatingIpsRbac" will be changed to:
- "patrole_tempest_plugin.tests.api.compute..." + class name
- "patrole_tempest_plugin.tests.api.network..." + class name
This also works for different versions of, say, test_users_rbac:
- "patrole_tempest_plugin.tests.api.identity.v2..." + class name
- "patrole_tempest_plugin.tests.api.identity.v3..." + class name
[0] http://logs.openstack.org/82/448782/11/check/gate-tempest-dsvm-patrole-member-ubuntu-xenial-nv/bce54d8/console.html
Change-Id: I4a1273e56a25dbc7fee950cf55f439f36cbf8e5c
Closes-Bug: #1680262
diff --git a/patrole_tempest_plugin/rbac_utils.py b/patrole_tempest_plugin/rbac_utils.py
index f61ccdf..70fe0b7 100644
--- a/patrole_tempest_plugin/rbac_utils.py
+++ b/patrole_tempest_plugin/rbac_utils.py
@@ -45,7 +45,8 @@
# References the last value of `switch_to_rbac_role` that was passed to
# `switch_role`. Used for ensuring that `switch_role` is correctly used
# in a test file, so that false positives are prevented. The key used
- # to index into the dictionary is the class name, which is unique.
+ # to index into the dictionary is the module path plus class name, which is
+ # unique.
switch_role_history = {}
admin_role_id = None
rbac_role_id = None
@@ -127,8 +128,12 @@
raise rbac_exceptions.RbacResourceSetupFailed(
'switchToRbacRole must be a boolean value.')
- key = test_obj.__name__ if isinstance(test_obj, type) else \
+ # The unique key is the combination of module path plus class name.
+ class_name = test_obj.__name__ if isinstance(test_obj, type) else \
test_obj.__class__.__name__
+ module_name = test_obj.__module__
+ key = '%s.%s' % (module_name, class_name)
+
self.switch_role_history.setdefault(key, None)
if self.switch_role_history[key] == switchToRbacRole: