Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Test file import versus system module #5716

Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 26 additions & 47 deletions avocado/core/utils/loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,6 @@
import sys

from avocado.core import test
from avocado.utils import stacktrace


class TestError(test.Test):
"""
Generic test error.
"""

def __init__(self, *args, **kwargs):
exception = kwargs.pop("exception")
test.Test.__init__(self, *args, **kwargs)
self.exception = exception

def test(self):
self.error(self.exception)


def load_test(test_factory):
Expand All @@ -32,36 +17,30 @@ def load_test(test_factory):
test_class, test_parameters = test_factory
if "run.results_dir" in test_parameters:
test_parameters["base_logdir"] = test_parameters.pop("run.results_dir")
if "modulePath" in test_parameters:
test_path = test_parameters.pop("modulePath")
else:
test_path = None
if isinstance(test_class, str):
module_name = os.path.basename(test_path).split(".")[0]
test_module_dir = os.path.abspath(os.path.dirname(test_path))
if "modulePath" not in test_parameters:
raise RuntimeError(
'Test factory parameters is missing the module\'s path ("modulePath")'
)

test_path = test_parameters.pop("modulePath")
module_name = os.path.basename(test_path).split(".")[0]
test_module_dir = os.path.abspath(os.path.dirname(test_path))
spec = importlib.util.spec_from_file_location(module_name, test_path)
test_module = importlib.util.module_from_spec(spec)
sys.modules[module_name] = test_module
try:
# Tests with local dir imports need this
try:
sys.path.insert(0, test_module_dir)
test_module = importlib.import_module(module_name)
except: # pylint: disable=W0702
# On load_module exception we fake the test class and pass
# the exc_info as parameter to be logged.
test_parameters["methodName"] = "test"
exception = stacktrace.prepare_exc_info(sys.exc_info())
test_parameters["exception"] = exception
return TestError(**test_parameters)
finally:
if test_module_dir in sys.path:
sys.path.remove(test_module_dir)
for _, obj in inspect.getmembers(test_module):
if (
inspect.isclass(obj)
and obj.__name__ == test_class
and inspect.getmodule(obj) == test_module
):
if issubclass(obj, test.Test):
test_class = obj
break
test_instance = test_class(**test_parameters)

return test_instance
sys.path.insert(0, test_module_dir)
spec.loader.exec_module(test_module)
finally:
if test_module_dir in sys.path:
sys.path.remove(test_module_dir)
for _, obj in inspect.getmembers(test_module):
if (
inspect.isclass(obj)
and obj.__name__ == test_class
and inspect.getmodule(obj) == test_module
and issubclass(obj, test.Test)
):
return obj(**test_parameters)
raise ImportError(f'Failed to find/load class "{test_class}" in "{test_path}"')
Loading