diff --git a/reframe/frontend/loader.py b/reframe/frontend/loader.py index 734e69b4b2..39a4d48dde 100644 --- a/reframe/frontend/loader.py +++ b/reframe/frontend/loader.py @@ -177,17 +177,23 @@ def load_from_module(self, module): if not self._validate_check(c): continue - testfile = module.__file__ + # Get the original filename in case of a different module name + if module.__name__ == c.__module__: + testfile = module.__file__ + else: + testfile = inspect.getfile(c.__class__) + try: conflicted = self._loaded[c.unique_name] except KeyError: self._loaded[c.unique_name] = testfile final_tests.append(c) else: - raise NameConflictError( - f'test {c.unique_name!r} from {testfile!r} ' - f'is already defined in {conflicted!r}' - ) + if not c.is_fixture(): + raise NameConflictError( + f'test {c.unique_name!r} from {testfile!r} ' + f'is already defined in {conflicted!r}' + ) getlogger().debug(f' > Loaded {len(final_tests)} test(s)') return final_tests diff --git a/unittests/resources/checks_unlisted/testlib_inheritance_bar.py b/unittests/resources/checks_unlisted/testlib_inheritance_bar.py new file mode 100644 index 0000000000..874587335c --- /dev/null +++ b/unittests/resources/checks_unlisted/testlib_inheritance_bar.py @@ -0,0 +1,13 @@ +# Copyright 2016-2023 Swiss National Supercomputing Centre (CSCS/ETH Zurich) +# ReFrame Project Developers. See the top-level LICENSE file for details. +# +# SPDX-License-Identifier: BSD-3-Clause + +import reframe as rfm + +from testlib.simple import simple_echo_check + + +@rfm.simple_test +class HelloBar(simple_echo_check): + message = 'Bar' diff --git a/unittests/resources/checks_unlisted/testlib_inheritance_foo.py b/unittests/resources/checks_unlisted/testlib_inheritance_foo.py new file mode 100644 index 0000000000..9efd1b281f --- /dev/null +++ b/unittests/resources/checks_unlisted/testlib_inheritance_foo.py @@ -0,0 +1,13 @@ +# Copyright 2016-2023 Swiss National Supercomputing Centre (CSCS/ETH Zurich) +# ReFrame Project Developers. See the top-level LICENSE file for details. +# +# SPDX-License-Identifier: BSD-3-Clause + +import reframe as rfm + +from testlib.simple import simple_echo_check + + +@rfm.simple_test +class HelloFoo(simple_echo_check): + message = 'Foo' diff --git a/unittests/resources/testlib/simple.py b/unittests/resources/testlib/simple.py new file mode 100644 index 0000000000..a8be65e55f --- /dev/null +++ b/unittests/resources/testlib/simple.py @@ -0,0 +1,31 @@ +# Copyright 2016-2023 Swiss National Supercomputing Centre (CSCS/ETH Zurich) +# ReFrame Project Developers. See the top-level LICENSE file for details. +# +# SPDX-License-Identifier: BSD-3-Clause + +import reframe as rfm +import reframe.utility.sanity as sn + + +class dummy_fixture(rfm.RunOnlyRegressionTest, pin_prefix=True): + executable = 'echo' + sanity_patterns = sn.assert_true(1) + + +@rfm.simple_test +class simple_echo_check(rfm.RunOnlyRegressionTest): + descr = 'Simple Echo Test' + valid_systems = ['*'] + valid_prog_environs = ['builtin'] + executable = 'echo' + executable_opts = ['Hello'] + message = variable(str, value='World') + dummy = fixture(dummy_fixture, scope='environment') + + @run_before('run') + def set_executable_opts(self): + self.executable_opts += [self.message] + + @sanity_function + def assert_sanity(self): + return sn.assert_found(rf'Hello {self.message}', self.stdout) diff --git a/unittests/test_cli.py b/unittests/test_cli.py index 4cf8609204..bfdb59f366 100644 --- a/unittests/test_cli.py +++ b/unittests/test_cli.py @@ -1045,3 +1045,17 @@ def test_dynamic_tests_filtering(run_reframe, tmp_path): assert returncode == 0 assert 'Ran 7/7 test case(s)' in stdout assert 'FAILED' not in stdout + + +def test_testlib_inherit_fixture_in_different_files(run_reframe, monkeypatch): + monkeypatch.syspath_prepend('unittests/resources') + returncode, stdout, _ = run_reframe( + checkpath=[ + 'unittests/resources/checks_unlisted/testlib_inheritance_foo.py', + 'unittests/resources/checks_unlisted/testlib_inheritance_bar.py' + ], + action='run', + ) + assert returncode == 0 + assert 'Ran 3/3 test case(s)' in stdout + assert 'FAILED' not in stdout