Hacking rule to forbid resource unsafe fixtures

Extend the existing T105, which was missing checks for
tearDownClass anyways. Forbid overriding setUpClass
and tearDownClass except for tempest/test.py where the
test base class is defined.

To be able to enforce the rule, fixing setUpClass
which was added with new tests before this patch could
merge.

Partially-implements bp resource-cleanup

Change-Id: Ib4d98c2ff8776ea1379a044b5a30fb02e351ce75
This commit is contained in:
Andrea Frittoli 2014-09-15 13:41:37 +01:00
parent 1d61edb200
commit 41fa16d214
5 changed files with 29 additions and 15 deletions

View File

@ -222,11 +222,11 @@ class SecGroupIPv6Test(SecGroupTest):
_tenant_network_cidr = CONF.network.tenant_network_v6_cidr
@classmethod
def setUpClass(cls):
def resource_setup(cls):
if not CONF.network_feature_enabled.ipv6:
skip_msg = "IPv6 Tests are disabled."
raise cls.skipException(skip_msg)
super(SecGroupIPv6Test, cls).setUpClass()
super(SecGroupIPv6Test, cls).resource_setup()
class SecGroupIPv6TestXML(SecGroupIPv6Test):

View File

@ -198,11 +198,11 @@ class NegativeSecGroupIPv6Test(NegativeSecGroupTest):
_tenant_network_cidr = CONF.network.tenant_network_v6_cidr
@classmethod
def setUpClass(cls):
def resource_setup(cls):
if not CONF.network_feature_enabled.ipv6:
skip_msg = "IPv6 Tests are disabled."
raise cls.skipException(skip_msg)
super(NegativeSecGroupIPv6Test, cls).setUpClass()
super(NegativeSecGroupIPv6Test, cls).resource_setup()
class NegativeSecGroupIPv6TestXML(NegativeSecGroupIPv6Test):

View File

@ -24,7 +24,7 @@ PYTHON_CLIENTS = ['cinder', 'glance', 'keystone', 'nova', 'swift', 'neutron',
PYTHON_CLIENT_RE = re.compile('import (%s)client' % '|'.join(PYTHON_CLIENTS))
TEST_DEFINITION = re.compile(r'^\s*def test.*')
SETUPCLASS_DEFINITION = re.compile(r'^\s*def setUpClass')
SETUP_TEARDOWN_CLASS_DEFINITION = re.compile(r'^\s+def (setUp|tearDown)Class')
SCENARIO_DECORATOR = re.compile(r'\s*@.*services\((.*)\)')
VI_HEADER_RE = re.compile(r"^#\s+vim?:.+")
mutable_default_args = re.compile(r"^\s*def .+\((.+=\{\}|.+=\[\])")
@ -58,15 +58,15 @@ def scenario_tests_need_service_tags(physical_line, filename,
"T104: Scenario tests require a service decorator")
def no_setupclass_for_unit_tests(physical_line, filename):
def no_setup_teardown_class_for_tests(physical_line, filename):
if pep8.noqa(physical_line):
return
if 'tempest/tests' in filename:
if SETUPCLASS_DEFINITION.match(physical_line):
if 'tempest/test.py' not in filename:
if SETUP_TEARDOWN_CLASS_DEFINITION.match(physical_line):
return (physical_line.find('def'),
"T105: setUpClass can not be used with unit tests")
"T105: (setUp|tearDown)Class can not be used in tests")
def no_vi_headers(physical_line, line_number, lines):
@ -119,7 +119,7 @@ def no_mutable_default_args(logical_line):
def factory(register):
register(import_no_clients_in_api)
register(scenario_tests_need_service_tags)
register(no_setupclass_for_unit_tests)
register(no_setup_teardown_class_for_tests)
register(no_vi_headers)
register(service_tags_not_in_module_path)
register(no_mutable_default_args)

View File

@ -82,7 +82,7 @@ class TestMisc(base.TestCase):
self.assertEqual(':tearDown', tearDown())
def test_find_test_caller_teardown_class(self):
def tearDownClass(cls):
def tearDownClass(cls): # noqa
return misc.find_test_caller()
self.assertEqual('TestMisc:tearDownClass',
tearDownClass(self.__class__))

View File

@ -47,13 +47,27 @@ class HackingTestCase(base.TestCase):
just assertTrue if the check is expected to fail and assertFalse if it
should pass.
"""
def test_no_setupclass_for_unit_tests(self):
self.assertTrue(checks.no_setupclass_for_unit_tests(
def test_no_setup_teardown_class_for_tests(self):
self.assertTrue(checks.no_setup_teardown_class_for_tests(
" def setUpClass(cls):", './tempest/tests/fake_test.py'))
self.assertIsNone(checks.no_setupclass_for_unit_tests(
self.assertIsNone(checks.no_setup_teardown_class_for_tests(
" def setUpClass(cls): # noqa", './tempest/tests/fake_test.py'))
self.assertFalse(checks.no_setupclass_for_unit_tests(
self.assertTrue(checks.no_setup_teardown_class_for_tests(
" def setUpClass(cls):", './tempest/api/fake_test.py'))
self.assertTrue(checks.no_setup_teardown_class_for_tests(
" def setUpClass(cls):", './tempest/scenario/fake_test.py'))
self.assertFalse(checks.no_setup_teardown_class_for_tests(
" def setUpClass(cls):", './tempest/test.py'))
self.assertTrue(checks.no_setup_teardown_class_for_tests(
" def tearDownClass(cls):", './tempest/tests/fake_test.py'))
self.assertIsNone(checks.no_setup_teardown_class_for_tests(
" def tearDownClass(cls): # noqa", './tempest/tests/fake_test.py'))
self.assertTrue(checks.no_setup_teardown_class_for_tests(
" def tearDownClass(cls):", './tempest/api/fake_test.py'))
self.assertTrue(checks.no_setup_teardown_class_for_tests(
" def tearDownClass(cls):", './tempest/scenario/fake_test.py'))
self.assertFalse(checks.no_setup_teardown_class_for_tests(
" def tearDownClass(cls):", './tempest/test.py'))
def test_import_no_clients_in_api(self):
for client in checks.PYTHON_CLIENTS: