[docs] Update rbac_utils.rst documentation

This PS updates the rbac_utils.rst documentation to replace
occurrences of switch_role (which has been deprecated) with
override_role. The documentation has also been updated to
include correct and incorrect examples for how to use
the override_role contextmanager.

Change-Id: Ia68a58267cda2c31af0e296aba32b2f949788fd7
diff --git a/doc/source/framework/rbac_utils.rst b/doc/source/framework/rbac_utils.rst
index 0f000ff..69ba045 100644
--- a/doc/source/framework/rbac_utils.rst
+++ b/doc/source/framework/rbac_utils.rst
@@ -1,7 +1,7 @@
 .. _rbac-utils:
 
-The RBAC Utils Module
-=====================
+RBAC Utils Module
+=================
 
 Overview
 --------
@@ -30,10 +30,10 @@
 
 #. Setup: Admin role is used automatically. The primary credentials are
    overridden with the admin role.
-#. Test execution: ``[patrole] rbac_test_role`` is used manually via a call
-   to ``rbac_utils.switch_role(self, toggle_rbac_role=True)``. Everything that
-   is executed after this call, until the end of the test, uses the primary
-   credentials overridden with the ``rbac_test_role``.
+#. Test execution: ``[patrole] rbac_test_role`` is used manually via the
+   call to ``with rbac_utils.override_role(self)``. Everything that
+   is executed within this contextmanager uses the primary
+   credentials overridden with the ``[patrole] rbac_test_role``.
 #. Teardown: Admin role is used automatically. The primary credentials have
    been overridden with the admin role.
 
@@ -64,26 +64,90 @@
 "Test execution" here means calling the API endpoint that enforces the policy
 action expected by the ``rbac_rule_validation`` decorator. Test execution
 should be performed *only after* calling
-``rbac_utils.switch_role(self, toggle_rbac_role=True)``.
+``with rbac_utils.override_role(self)``.
 
 Immediately after that call, the API endpoint that enforces the policy should
 be called.
 
+Examples
+^^^^^^^^
+
+Always use the contextmanager before calling the API that enforces the
+expected policy action.
+
 Example::
 
-    # Always apply the RBAC decorator to the test.
     @rbac_rule_validation.action(
         service="nova",
         rule="os_compute_api:os-aggregates:show")
     def test_show_aggregate_rbac(self):
-        # Do test setup before the switch_role call.
+        # Do test setup before the ``override_role`` call.
         aggregate_id = self._create_aggregate()
-        # Call the switch_role method so that the primary credentials have
-        # the test role needed for test execution.
-        self.rbac_utils.switch_role(self, toggle_rbac_role=True)
-        # Call the endpoint that enforces the expected policy action, described
-        # by the "rule" kwarg in the decorator above.
-        self.aggregates_client.show_aggregate(aggregate_id)
+        # Call the ``override_role`` method so that the primary credentials
+        # have the test role needed for test execution.
+        with self.rbac_utils.override_role(self):
+            self.aggregates_client.show_aggregate(aggregate_id)
+
+When using a waiter, do the wait outside the contextmanager. "Waiting" always
+entails executing a ``GET`` request to the server, until the state of the
+returned resource matches a desired state. These ``GET`` requests enforce
+a different policy than the one expected. This is undesirable because
+Patrole should only test policies in isolation from one another.
+
+Otherwise, the test result will be tainted, because instead of only the
+expected policy getting enforced with the ``os_primary`` role, at least
+two policies get enforced.
+
+Example using waiter::
+
+    @rbac_rule_validation.action(
+        service="nova",
+        rule="os_compute_api:os-admin-password")
+    def test_change_server_password(self):
+        original_password = self.servers_client.show_password(
+            self.server['id'])
+        self.addCleanup(self.servers_client.change_password, self.server['id'],
+                        adminPass=original_password)
+
+        with self.rbac_utils.override_role(self):
+            self.servers_client.change_password(
+                self.server['id'], adminPass=data_utils.rand_password())
+        # Call the waiter outside the ``override_role`` contextmanager, so that
+        # it is executed with admin role.
+        waiters.wait_for_server_status(
+            self.servers_client, self.server['id'], 'ACTIVE')
+
+Below is an example of a method that enforces multiple policies getting
+called inside the contextmanager. The ``_complex_setup_method`` below
+performs the correct API that enforces the expected policy -- in this
+case ``self.resources_client.create_resource`` -- but then proceeds to
+use a waiter.
+
+Incorrect::
+
+    def _complex_setup_method(self):
+        resource = self.resources_client.create_resource(
+            **kwargs)['resource']
+        self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+                        self._delete_resource, resource)
+        waiters.wait_for_resource_status(
+            self.resources_client, resource['id'], 'available')
+        return resource
+
+    @rbac_rule_validation.action(
+        service="example-service",
+        rule="example-rule")
+    def test_change_server_password(self):
+        # Never call a helper function inside the contextmanager that calls a
+        # bunch of APIs. Only call the API that enforces the policy action
+        # contained in the decorator above.
+        with self.rbac_utils.override_role(self):
+            self._complex_setup_method()
+
+To fix this test, see the "Example using waiter" section above. It is
+recommended to re-implement the logic in a helper method inside a test such
+that only the relevant API is called inside the contextmanager, with
+everything extraneous outside.
 
 Test Cleanup
 ------------