From 572deac00be43b87546d9dd6d3d9886b0963ae1e Mon Sep 17 00:00:00 2001 From: Claudiu Belu Date: Mon, 29 May 2017 02:44:03 -0700 Subject: [PATCH] Fixes import_modules_recursively for Windows The neutron agents fail to start on Windows, due to the fact that neutron.common.utils.import_modules_recursively expects the paths to be forwardslash separated, while on Windows they are backslash separated. Change-Id: I5e15273c2f70b70fad0cf1216ef0b33c6a99d702 Closes-Bug: #1694220 --- neutron/common/utils.py | 6 +++++- neutron/tests/unit/common/test_utils.py | 11 ++++++++--- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/neutron/common/utils.py b/neutron/common/utils.py index c8e3d86a279..08426840c83 100644 --- a/neutron/common/utils.py +++ b/neutron/common/utils.py @@ -23,6 +23,7 @@ import importlib import os import os.path import random +import re import signal import sys import threading @@ -57,6 +58,8 @@ SYNCHRONIZED_PREFIX = 'neutron-' DEFAULT_THROTTLER_VALUE = 2 +_SEPARATOR_REGEX = re.compile(r'[/\\]+') + synchronized = lockutils.synchronized_with_prefix(SYNCHRONIZED_PREFIX) @@ -750,6 +753,7 @@ def extract_exc_details(e): def import_modules_recursively(topdir): '''Import and return all modules below the topdir directory.''' + topdir = _SEPARATOR_REGEX.sub('/', topdir) modules = [] for root, dirs, files in os.walk(topdir): for file_ in files: @@ -760,7 +764,7 @@ def import_modules_recursively(topdir): if module == '__init__': continue - import_base = root.replace('/', '.') + import_base = _SEPARATOR_REGEX.sub('.', root) # NOTE(ihrachys): in Python3, or when we are not located in the # directory containing neutron code, __file__ is absolute, so we diff --git a/neutron/tests/unit/common/test_utils.py b/neutron/tests/unit/common/test_utils.py index 0e3c49aabe9..b609d96a9ce 100644 --- a/neutron/tests/unit/common/test_utils.py +++ b/neutron/tests/unit/common/test_utils.py @@ -14,8 +14,10 @@ import os.path import random +import re import sys +import ddt import eventlet import mock import netaddr @@ -689,17 +691,20 @@ class TestExcDetails(base.BaseTestCase): utils.extract_exc_details(Exception()), six.text_type) +@ddt.ddt class ImportModulesRecursivelyTestCase(base.BaseTestCase): - def test_recursion(self): + @ddt.data('/', r'\\') + def test_recursion(self, separator): expected_modules = ( 'neutron.tests.unit.tests.example.dir.example_module', 'neutron.tests.unit.tests.example.dir.subdir.example_module', ) for module in expected_modules: sys.modules.pop(module, None) - modules = utils.import_modules_recursively( - os.path.dirname(tests.__file__)) + + topdir = re.sub(r'[/\\]+', separator, os.path.dirname(tests.__file__)) + modules = utils.import_modules_recursively(topdir) for module in expected_modules: self.assertIn(module, modules) self.assertIn(module, sys.modules)