Skip to content
Merged
Show file tree
Hide file tree
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
8 changes: 7 additions & 1 deletion reframe/utility/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import reframe

from collections import UserDict
from hashlib import sha256
from . import typecheck as typ


Expand Down Expand Up @@ -87,7 +88,12 @@ def import_module_from_file(filename, force=False):
module_name = _get_module_name(rel_filename)
if rel_filename.startswith('..'):
# We cannot use the standard Python import mechanism here, because the
# module to import is outside the top-level package
# module to import is outside the top-level package. We also mangle
# the name that we assign to the module, in order to avoid clashes
# with other modules loaded with a standard `import` or with multiple
# test files with the same name that reside in different directories.
module_hash = sha256(filename.encode('utf-8')).hexdigest()[:8]
module_name = f'{module_name}@{module_hash}'
return _do_import_module_from_file(filename, module_name)

# Extract module name if `filename` is under `site-packages/` or the
Expand Down
29 changes: 29 additions & 0 deletions unittests/test_loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import os
import pytest
import shutil

import reframe as rfm
from reframe.core.exceptions import ReframeSyntaxError
Expand All @@ -24,6 +25,21 @@ def loader_with_path():
)


@pytest.fixture
def loader_with_path_tmpdir(tmp_path):
test_dir_a = tmp_path / 'a'
test_dir_b = tmp_path / 'b'
os.mkdir(test_dir_a)
os.mkdir(test_dir_b)
test_a = 'unittests/resources/checks/emptycheck.py'
test_b = 'unittests/resources/checks/hellocheck.py'
shutil.copyfile(test_a, test_dir_a / 'test.py')
shutil.copyfile(test_b, test_dir_b / 'test.py')
return RegressionCheckLoader(
[test_dir_a.as_posix(), test_dir_b.as_posix()]
)


def test_load_file_relative(loader):
checks = loader.load_from_file('unittests/resources/checks/emptycheck.py')
assert 1 == len(checks)
Expand Down Expand Up @@ -73,6 +89,19 @@ def test_load_fixtures(loader):
assert 5 == len(tests)


def test_existing_module_name(loader, tmp_path):
test_file = tmp_path / 'os.py'
shutil.copyfile('unittests/resources/checks/emptycheck.py', test_file)
checks = loader.load_from_file(test_file)
assert 1 == len(checks)
assert checks[0].name == 'EmptyTest'


def test_same_filename_different_path(loader_with_path_tmpdir):
checks = loader_with_path_tmpdir.load_all()
assert 3 == len(checks)


def test_special_test():
with pytest.raises(ReframeSyntaxError):
@rfm.simple_test
Expand Down
27 changes: 9 additions & 18 deletions unittests/test_utility.py
Original file line number Diff line number Diff line change
Expand Up @@ -479,13 +479,15 @@ def test_import_from_file_load_abspath():
assert module is sys.modules.get('reframe')


def test_import_from_file_load_unknown_path():
try:
util.import_module_from_file('/foo')
pytest.fail()
except ImportError as e:
assert 'foo' == e.name
assert '/foo' == e.path
def test_import_from_file_existing_module_name(tmp_path):
test_file = tmp_path / 'os.py'
with open(test_file, 'w') as fp:
print('var = 1', file=fp)

module = util.import_module_from_file(test_file)
assert module.var == 1
assert not hasattr(module, 'path')
assert hasattr(os, 'path')


def test_import_from_file_load_directory_relative():
Expand All @@ -510,17 +512,6 @@ def test_import_from_file_load_relative():
assert module is sys.modules.get('reframe.utility.osext')


def test_import_from_file_load_outside_pkg():
module = util.import_module_from_file(os.path.__file__)

# os imports the OS-specific path libraries under the name `path`. Our
# importer will import the actual file, thus the module name should be
# the real one.
assert (module is sys.modules.get('posixpath') or
module is sys.modules.get('ntpath') or
module is sys.modules.get('macpath'))


def test_import_from_file_load_twice():
filename = os.path.abspath('reframe')
module1 = util.import_module_from_file(filename)
Expand Down