Merge "Clean up test_server_actions_rbac"
diff --git a/patrole_tempest_plugin/tests/api/compute/test_server_misc_policy_actions_rbac.py b/patrole_tempest_plugin/tests/api/compute/test_server_misc_policy_actions_rbac.py
index 654d3f1..6e62029 100644
--- a/patrole_tempest_plugin/tests/api/compute/test_server_misc_policy_actions_rbac.py
+++ b/patrole_tempest_plugin/tests/api/compute/test_server_misc_policy_actions_rbac.py
@@ -199,6 +199,50 @@
             raise rbac_exceptions.RbacMalformedResponse(
                 attribute=expected_attr)
 
+    @decorators.idempotent_id('4aa5d93e-4887-468a-8eb4-b6eca0ca6437')
+    @test.requires_ext(extension='OS-EXT-SRV-ATTR', service='compute')
+    @rbac_rule_validation.action(
+        service="nova",
+        rule="os_compute_api:os-extended-server-attributes")
+    def test_list_servers_extended_server_attributes(self):
+        """Test list servers with details, with extended server attributes in
+        response body.
+        """
+        self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+        body = self.servers_client.list_servers(detail=True)['servers']
+
+        # NOTE(felipemonteiro): The attributes included below should be
+        # returned by all microversions. We don't include tests for other
+        # microversions since Tempest schema validation takes care of that in
+        # `show_server` call above. (Attributes there are *optional*.)
+        for attr in ('host', 'instance_name'):
+            whole_attr = 'OS-EXT-SRV-ATTR:%s' % attr
+            if whole_attr not in body[0]:
+                raise rbac_exceptions.RbacMalformedResponse(
+                    attribute=whole_attr)
+
+    @decorators.idempotent_id('2ed7aee2-94b2-4a9f-ae63-a51b7f94fe30')
+    @test.requires_ext(extension='OS-EXT-SRV-ATTR', service='compute')
+    @rbac_rule_validation.action(
+        service="nova",
+        rule="os_compute_api:os-extended-server-attributes")
+    def test_show_server_extended_server_attributes(self):
+        """Test show server with extended server attributes in response
+        body.
+        """
+        self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+        body = self.servers_client.show_server(self.server['id'])['server']
+
+        # NOTE(felipemonteiro): The attributes included below should be
+        # returned by all microversions. We don't include tests for other
+        # microversions since Tempest schema validation takes care of that in
+        # `show_server` call above. (Attributes there are *optional*.)
+        for attr in ('host', 'instance_name'):
+            whole_attr = 'OS-EXT-SRV-ATTR:%s' % attr
+            if whole_attr not in body:
+                raise rbac_exceptions.RbacMalformedResponse(
+                    attribute=whole_attr)
+
     @decorators.idempotent_id('82053c27-3134-4003-9b55-bc9fafdb0e3b')
     @test.requires_ext(extension='OS-EXT-STS', service='compute')
     @rbac_rule_validation.action(
diff --git a/patrole_tempest_plugin/tests/unit/fixtures.py b/patrole_tempest_plugin/tests/unit/fixtures.py
index ce13029..52c2598 100644
--- a/patrole_tempest_plugin/tests/unit/fixtures.py
+++ b/patrole_tempest_plugin/tests/unit/fixtures.py
@@ -18,10 +18,12 @@
 
 import fixtures
 import mock
+import time
 
 from tempest import clients
 from tempest.common import credentials_factory as credentials
 from tempest import config
+from tempest import test
 
 from patrole_tempest_plugin import rbac_utils
 
@@ -73,13 +75,19 @@
             'os_primary.credentials.project_id': self.PROJECT_ID,
             'get_identity_version.return_value': 'v3'
         }
-        self.mock_test_obj = mock.Mock(__name__='foo', **test_obj_kwargs)
+        self.mock_test_obj = mock.Mock(
+            __name__='patrole_unit_test', spec=test.BaseTestCase,
+            os_primary=mock.Mock(), **test_obj_kwargs)
 
-        # Mock out functionality that can't be used by unit tests.
-        self.mock_time = mock.patch.object(rbac_utils, 'time').start()
-        mock.patch.object(
-            credentials, 'get_configured_admin_credentials').start()
-        mock_admin_mgr = mock.patch.object(clients, 'Manager').start()
+        # Mock out functionality that can't be used by unit tests. Mocking out
+        # time.sleep is a test optimization.
+        self.mock_time = mock.patch.object(
+            rbac_utils, 'time', __name__='mock_time', spec=time).start()
+        mock.patch.object(credentials, 'get_configured_admin_credentials',
+                          spec=object).start()
+        mock_admin_mgr = mock.patch.object(
+            clients, 'Manager', spec=clients.Manager,
+            roles_v3_client=mock.Mock(), roles_client=mock.Mock()).start()
         self.roles_v3_client = mock_admin_mgr.return_value.roles_v3_client
 
         self.set_roles(['admin', 'member'], [])
diff --git a/patrole_tempest_plugin/tests/unit/test_policy_authority.py b/patrole_tempest_plugin/tests/unit/test_policy_authority.py
index 2a8da9d..db651fc 100644
--- a/patrole_tempest_plugin/tests/unit/test_policy_authority.py
+++ b/patrole_tempest_plugin/tests/unit/test_policy_authority.py
@@ -499,7 +499,8 @@
 
     def _test_validate_service(self, v2_services, v3_services,
                                expected_failure=False, expected_services=None):
-        with mock.patch.object(policy_authority, 'clients') as m_creds:
+        with mock.patch.object(
+            policy_authority, 'clients', autospec=True) as m_creds:
             m_creds.Manager().identity_services_client.list_services.\
                 return_value = v2_services
             m_creds.Manager().identity_services_v3_client.list_services.\
diff --git a/patrole_tempest_plugin/tests/unit/test_rbac_rule_validation.py b/patrole_tempest_plugin/tests/unit/test_rbac_rule_validation.py
index afadb43..3065cfe 100644
--- a/patrole_tempest_plugin/tests/unit/test_rbac_rule_validation.py
+++ b/patrole_tempest_plugin/tests/unit/test_rbac_rule_validation.py
@@ -42,9 +42,9 @@
 
         self.useFixture(
             fixtures.ConfPatcher(rbac_test_role='Member', group='patrole'))
-
-        # Mock the RBAC log so that it is not written to for any unit tests.
-        mock.patch.object(rbac_rv.RBACLOG, 'info').start()
+        # Disable patrole log for unit tests.
+        self.useFixture(
+            fixtures.ConfPatcher(enable_reporting=False, group='patrole_log'))
 
     @mock.patch.object(rbac_rv, 'LOG', autospec=True)
     @mock.patch.object(rbac_rv, 'policy_authority', autospec=True)
diff --git a/releasenotes/notes/extended-server-attributes-36623af87e714369.yaml b/releasenotes/notes/extended-server-attributes-36623af87e714369.yaml
new file mode 100644
index 0000000..a7ccd8e
--- /dev/null
+++ b/releasenotes/notes/extended-server-attributes-36623af87e714369.yaml
@@ -0,0 +1,5 @@
+---
+features:
+  - |
+    Add complete RBAC test coverage for the compute APIs that enforce:
+    "os_compute_api:os-extended-server-attributes".
diff --git a/requirements.txt b/requirements.txt
index abccb62..0e46596 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,7 +1,7 @@
 # The order of packages is significant, because pip processes them in the order
 # of appearance. Changing the order has an impact on the overall integration
 # process, which may cause wedges in the gate later.
-hacking!=0.13.0,<0.14,>=0.12.0 # Apache-2.0
+hacking>=1.0.0 # Apache-2.0
 pbr!=2.1.0,>=2.0.0 # Apache-2.0
 oslo.log>=3.30.0 # Apache-2.0
 oslo.config>=4.6.0 # Apache-2.0
diff --git a/test-requirements.txt b/test-requirements.txt
index dc2fec9..1953685 100644
--- a/test-requirements.txt
+++ b/test-requirements.txt
@@ -1,7 +1,7 @@
 # The order of packages is significant, because pip processes them in the order
 # of appearance. Changing the order has an impact on the overall integration
 # process, which may cause wedges in the gate later.
-hacking!=0.13.0,<0.14,>=0.12.0 # Apache-2.0
+hacking>=1.0.0 # Apache-2.0
 
 sphinx>=1.6.2 # BSD
 openstackdocstheme>=1.17.0 # Apache-2.0
diff --git a/tox.ini b/tox.ini
index f1b5b86..320eb4e 100644
--- a/tox.ini
+++ b/tox.ini
@@ -56,7 +56,13 @@
 commands = oslo_debug_helper -t patrole_tempest_plugin/tests {posargs}
 
 [flake8]
-enable-extensions = H106,H203,H904
+# [H106] Don’t put vim configuration in source files.
+# [H203] Use assertIs(Not)None to check for None.
+# [H204] Use assert(Not)Equal to check for equality.
+# [H205] Use assert(Greater|Less)(Equal) for comparison.
+# [H210] Require ‘autospec’, ‘spec’, or ‘spec_set’ in mock.patch/mock.patch.object calls
+# [H904] Delay string interpolations at logging calls.
+enable-extensions = H106,H203,H204,H205,H210,H904
 show-source = True
 # E123, E125 skipped as they are invalid PEP-8.
 #