Merge "trivial: Add hacking checks to irrelevant-files in .zuul.yaml"
diff --git a/patrole_tempest_plugin/hacking/checks.py b/patrole_tempest_plugin/hacking/checks.py
index 853d65c..1f06258 100644
--- a/patrole_tempest_plugin/hacking/checks.py
+++ b/patrole_tempest_plugin/hacking/checks.py
@@ -36,7 +36,8 @@
RULE_VALIDATION_DECORATOR = re.compile(
r'\s*@rbac_rule_validation.action\(.*')
IDEMPOTENT_ID_DECORATOR = re.compile(r'\s*@decorators\.idempotent_id\((.*)\)')
-PLUGIN_RBAC_TEST = re.compile(r"class .+\(.+PluginRbacTest\)")
+PLUGIN_RBAC_TEST = re.compile(
+ r"class .+\(.+PluginRbacTest\)|class .+PluginRbacTest\(.+\)")
have_rbac_decorator = False
@@ -218,12 +219,36 @@
P104
"""
+ suffix = "PluginRbacTest"
if "patrole_tempest_plugin/tests/api" in filename:
if PLUGIN_RBAC_TEST.match(physical_line):
- subclass = physical_line.split('(')[0]
- if not subclass.endswith("PluginRbacTest"):
- error = "Plugin RBAC test classes must end in 'PluginRbacTest'"
- return len(subclass) - 1, error
+ subclass, superclass = physical_line.split('(')
+ subclass = subclass.split('class')[1].strip()
+ superclass = superclass.split(')')[0].strip()
+ if "." in superclass:
+ superclass = superclass.split(".")[1]
+
+ both_have = all(
+ clazz.endswith(suffix) for clazz in [subclass, superclass])
+ none_have = not any(
+ clazz.endswith(suffix) for clazz in [subclass, superclass])
+
+ if not (both_have or none_have):
+ if (subclass.startswith("Base") and
+ superclass.startswith("Base")):
+ return
+
+ # Case 1: Subclass of "BasePluginRbacTest" must end in `suffix`
+ # Case 2: Subclass that ends in `suffix` must inherit from base
+ # class ending in `suffix`.
+ if not subclass.endswith(suffix):
+ error = ("Plugin RBAC test subclasses must end in "
+ "'PluginRbacTest'")
+ return len(subclass) - 1, error
+ elif not superclass.endswith(suffix):
+ error = ("Plugin RBAC test subclasses must inherit from a "
+ "'PluginRbacTest' base class")
+ return len(superclass) - 1, error
def factory(register):
diff --git a/patrole_tempest_plugin/tests/api/network/test_auto_allocated_topology_rbac.py b/patrole_tempest_plugin/tests/api/network/test_auto_allocated_topology_rbac.py
index bcf62d7..7098e55 100644
--- a/patrole_tempest_plugin/tests/api/network/test_auto_allocated_topology_rbac.py
+++ b/patrole_tempest_plugin/tests/api/network/test_auto_allocated_topology_rbac.py
@@ -35,10 +35,44 @@
rules=["get_auto_allocated_topology"],
expected_error_codes=[404])
def test_show_auto_allocated_topology(self):
- """Show auto_allocated_topology.
+ """Test show auto_allocated_topology.
RBAC test for the neutron "get_auto_allocated_topology" policy
"""
with self.rbac_utils.override_role(self):
self.ntp_client.get_auto_allocated_topology(
tenant_id=self.os_primary.credentials.tenant_id)
+
+ def _ensure_network_not_in_use(cls, network_id):
+ ports = cls.ntp_client.list_ports(network_id=network_id)["ports"]
+
+ # Every subnet within network should have a router interface
+ expected_ports_count = len(
+ cls.ntp_client.show_network(network_id)["network"]["subnets"])
+ # Every network should have a single dhcp interface
+ expected_ports_count += 1
+
+ if len(ports) != expected_ports_count:
+ msg = "Auto Allocated Topology in use."
+ cls.skipException(msg)
+
+ @decorators.idempotent_id('A0606AFE-065E-4C09-8E51-58EE7FBA30A2')
+ @decorators.attr(type='slow')
+ @rbac_rule_validation.action(service="neutron",
+ rules=["get_auto_allocated_topology",
+ "delete_auto_allocated_topology"],
+ expected_error_codes=[404, 403])
+ def test_delete_auto_allocated_topology(self):
+ """Test delete auto_allocated_topology.
+
+ RBAC test for the neutron "delete_auto_allocated_topology" policy
+ """
+ tenant_id = self.os_primary.credentials.tenant_id
+ net_id = self.ntp_client.get_auto_allocated_topology(
+ tenant_id=tenant_id)["auto_allocated_topology"]["id"]
+
+ self._ensure_network_not_in_use(net_id)
+
+ with self.rbac_utils.override_role(self):
+ self.ntp_client.delete_auto_allocated_topology(
+ tenant_id=self.os_primary.credentials.tenant_id)
diff --git a/patrole_tempest_plugin/tests/api/volume/test_volume_transfers_rbac.py b/patrole_tempest_plugin/tests/api/volume/test_volume_transfers_rbac.py
index a18a370..b7e45f9 100644
--- a/patrole_tempest_plugin/tests/api/volume/test_volume_transfers_rbac.py
+++ b/patrole_tempest_plugin/tests/api/volume/test_volume_transfers_rbac.py
@@ -54,12 +54,17 @@
def test_create_volume_transfer(self):
with self.rbac_utils.override_role(self):
self._create_transfer()
+ waiters.wait_for_volume_resource_status(
+ self.volumes_client, self.volume['id'], 'awaiting-transfer')
@rbac_rule_validation.action(service="cinder",
rules=["volume:get_transfer"])
@decorators.idempotent_id('7a0925d3-ed97-4c25-8299-e5cdabe2eb55')
def test_get_volume_transfer(self):
transfer = self._create_transfer()
+ waiters.wait_for_volume_resource_status(
+ self.volumes_client, self.volume['id'], 'awaiting-transfer')
+
with self.rbac_utils.override_role(self):
self.transfers_client.show_volume_transfer(transfer['id'])
@@ -82,15 +87,23 @@
@decorators.idempotent_id('987f2a11-d657-4984-a6c9-28f06c1cd014')
def test_accept_volume_transfer(self):
transfer = self._create_transfer()
+ waiters.wait_for_volume_resource_status(
+ self.volumes_client, self.volume['id'], 'awaiting-transfer')
+
with self.rbac_utils.override_role(self):
self.transfers_client.accept_volume_transfer(
transfer['id'], auth_key=transfer['auth_key'])
+ waiters.wait_for_volume_resource_status(self.volumes_client,
+ self.volume['id'], 'available')
@rbac_rule_validation.action(service="cinder",
rules=["volume:delete_transfer"])
@decorators.idempotent_id('4672187e-7fff-454b-832a-5c8865dda868')
def test_delete_volume_transfer(self):
transfer = self._create_transfer()
+ waiters.wait_for_volume_resource_status(
+ self.volumes_client, self.volume['id'], 'awaiting-transfer')
+
with self.rbac_utils.override_role(self):
self.transfers_client.delete_volume_transfer(transfer['id'])
waiters.wait_for_volume_resource_status(
diff --git a/patrole_tempest_plugin/tests/unit/test_hacking.py b/patrole_tempest_plugin/tests/unit/test_hacking.py
index f75bffe..d35b816 100644
--- a/patrole_tempest_plugin/tests/unit/test_hacking.py
+++ b/patrole_tempest_plugin/tests/unit/test_hacking.py
@@ -262,7 +262,7 @@
# Passing cases: these do not inherit from "PluginRbacTest" base class.
self.assertFalse(check(
- "class FakeRbacTest",
+ "class FakeRbacTest(BaseFakeRbacTest)",
"./patrole_tempest_plugin/tests/api/fake_test_rbac.py"))
self.assertFalse(check(
"class FakeRbacTest(base.BaseFakeRbacTest)",
@@ -270,16 +270,39 @@
# Passing cases: these **do** end in correct test class suffix.
self.assertFalse(check(
- "class FakePluginRbacTest",
+ "class FakePluginRbacTest(BaseFakePluginRbacTest)",
"./patrole_tempest_plugin/tests/api/fake_test_rbac.py"))
self.assertFalse(check(
- "class FakePluginRbacTest(base.BaseFakeRbacTest)",
+ "class FakePluginRbacTest(base.BaseFakePluginRbacTest)",
+ "./patrole_tempest_plugin/tests/api/fake_test_rbac.py"))
+
+ # Passing cases: plugin base class inherits from another base class.
+ self.assertFalse(check(
+ "class BaseFakePluginRbacTest(base.BaseFakeRbacTest)",
+ "./patrole_tempest_plugin/tests/api/fake_test_rbac.py"))
+ self.assertFalse(check(
+ "class BaseFakePluginRbacTest(BaseFakeRbacTest)",
"./patrole_tempest_plugin/tests/api/fake_test_rbac.py"))
# Failing cases: these **do not** end in correct test class suffix.
+ # Case 1: RbacTest subclass doesn't end in PluginRbacTest.
+ self.assertTrue(check(
+ "class FakeRbacTest(base.BaseFakePluginRbacTest)",
+ "./patrole_tempest_plugin/tests/api/fake_test_rbac.py"))
self.assertTrue(check(
"class FakeRbacTest(BaseFakePluginRbacTest)",
"./patrole_tempest_plugin/tests/api/fake_test_rbac.py"))
self.assertTrue(check(
"class FakeRbacTest(BaseFakeNetworkPluginRbacTest)",
"./patrole_tempest_plugin/tests/api/network/fake_test_rbac.py"))
+ # Case 2: PluginRbacTest subclass doesn't inherit from
+ # BasePluginRbacTest.
+ self.assertTrue(check(
+ "class FakePluginRbacTest(base.BaseFakeRbacTest)",
+ "./patrole_tempest_plugin/tests/api/fake_test_rbac.py"))
+ self.assertTrue(check(
+ "class FakePluginRbacTest(BaseFakeRbacTest)",
+ "./patrole_tempest_plugin/tests/api/fake_test_rbac.py"))
+ self.assertTrue(check(
+ "class FakeNeutronPluginRbacTest(BaseFakeNeutronRbacTest)",
+ "./patrole_tempest_plugin/tests/api/fake_test_rbac.py"))
diff --git a/setup.cfg b/setup.cfg
index 02ce831..77a039a 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -26,20 +26,6 @@
[upload_sphinx]
upload-dir = doc/build/html
-[compile_catalog]
-directory = patrole/locale
-domain = patrole
-
-[update_catalog]
-domain = patrole
-output_dir = patrole/locale
-input_file = patrole/locale/patrole.pot
-
-[extract_messages]
-keywords = _ gettext ngettext l_ lazy_gettext
-mapping_file = babel.cfg
-output_file = patrole/locale/patrole.pot
-
[build_releasenotes]
all_files = 1
build-dir = releasenotes/build
diff --git a/tox.ini b/tox.ini
index ea9abf1..bc829d2 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,5 +1,5 @@
[tox]
-minversion = 1.6
+minversion = 2.0
envlist = pep8,py35,py27
skipsdist = True