diff --git a/HACKING.rst b/HACKING.rst index 1076469ddc97..8683b2ed9254 100644 --- a/HACKING.rst +++ b/HACKING.rst @@ -50,6 +50,7 @@ Nova Specific Commandments assertEqual(A in B, False) or assertEqual(False, A in B) to the more specific assertIn/NotIn(A, B) - [N339] Check common raise_feature_not_supported() is used for v2.1 HTTPNotImplemented response. +- [N340] Check nova.utils.spawn() is used instead of greenthread.spawn() Creating Unit Tests ------------------- diff --git a/nova/hacking/checks.py b/nova/hacking/checks.py index 5696ab8ccf61..5fcefe587d4e 100644 --- a/nova/hacking/checks.py +++ b/nova/hacking/checks.py @@ -96,6 +96,8 @@ api_version_re = re.compile(r"@.*api_version") dict_constructor_with_list_copy_re = re.compile(r".*\bdict\((\[)?(\(|\[)") decorator_re = re.compile(r"@.*") http_not_implemented_re = re.compile(r"raise .*HTTPNotImplemented\(") +greenthread_spawn_re = re.compile(r".*greenthread.spawn\(.*\)") +greenthread_spawn_n_re = re.compile(r".*greenthread.spawn_n\(.*\)") class BaseASTChecker(ast.NodeVisitor): @@ -519,6 +521,19 @@ def check_http_not_implemented(logical_line, physical_line, filename): yield(0, msg) +def check_greenthread_spawns(logical_line, physical_line, filename): + """Check for use of greenthread.spawn() and greenthread.spawn_n() + + N340 + """ + msg = ("N340: Use nova.utils.%(spawn)s() rather than " + "greenthread.%(spawn)s()") + if re.match(greenthread_spawn_re, logical_line): + yield (0, msg % {'spawn': 'spawn'}) + if re.match(greenthread_spawn_n_re, logical_line): + yield (0, msg % {'spawn': 'spawn_n'}) + + def factory(register): register(import_no_db_in_virt) register(no_db_session_in_public_api) @@ -545,3 +560,4 @@ def factory(register): register(dict_constructor_with_list_copy) register(assert_equal_in) register(check_http_not_implemented) + register(check_greenthread_spawns) diff --git a/nova/tests/unit/test_hacking.py b/nova/tests/unit/test_hacking.py index 800b3647bcd5..ab4c0e5db20a 100644 --- a/nova/tests/unit/test_hacking.py +++ b/nova/tests/unit/test_hacking.py @@ -534,3 +534,24 @@ class HackingTestCase(test.NoDBTestCase): filename = "nova/api/openstack/compute/contrib/test.py" self._assert_has_no_errors(code, checks.check_http_not_implemented, filename=filename) + + def test_check_greenthread_spawns(self): + errors = [(1, 0, "N340")] + + code = "greenthread.spawn(func, arg1, kwarg1=kwarg1)" + self._assert_has_errors(code, checks.check_greenthread_spawns, + expected_errors=errors) + + code = "greenthread.spawn_n(func, arg1, kwarg1=kwarg1)" + self._assert_has_errors(code, checks.check_greenthread_spawns, + expected_errors=errors) + + code = "eventlet.greenthread.spawn(func, arg1, kwarg1=kwarg1)" + self._assert_has_errors(code, checks.check_greenthread_spawns, + expected_errors=errors) + + code = "nova.utils.spawn(func, arg1, kwarg1=kwarg1)" + self._assert_has_no_errors(code, checks.check_greenthread_spawns) + + code = "nova.utils.spawn_n(func, arg1, kwarg1=kwarg1)" + self._assert_has_no_errors(code, checks.check_greenthread_spawns)