Skip to content

Commit 3fb386c

Browse files
authored
Merge pull request #4371 from xdelaruelle/_module_raw_function_check
Adapt module function check for Environment Modules v4+
2 parents 5af05dc + 757b8ee commit 3fb386c

File tree

3 files changed

+44
-1
lines changed

3 files changed

+44
-1
lines changed

easybuild/tools/modules.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1328,6 +1328,31 @@ class EnvironmentModules(EnvironmentModulesTcl):
13281328
MAX_VERSION = None
13291329
VERSION_REGEXP = r'^Modules\s+Release\s+(?P<version>\d\S*)\s'
13301330

1331+
def check_module_function(self, allow_mismatch=False, regex=None):
1332+
"""Check whether selected module tool matches 'module' function definition."""
1333+
# Modules 5.1.0+: module command is called from _module_raw shell function
1334+
# Modules 4.2.0..5.0.1: module command is called from _module_raw shell function if it has
1335+
# been initialized in an interactive shell session (i.e., a session attached to a tty)
1336+
if self.testing:
1337+
if '_module_raw' in os.environ:
1338+
out, ec = os.environ['_module_raw'], 0
1339+
else:
1340+
out, ec = None, 1
1341+
else:
1342+
cmd = "type _module_raw"
1343+
out, ec = run_cmd(cmd, simple=False, log_ok=False, log_all=False, force_in_dry_run=True, trace=False)
1344+
1345+
if regex is None:
1346+
regex = r".*%s" % os.path.basename(self.cmd)
1347+
mod_cmd_re = re.compile(regex, re.M)
1348+
1349+
if ec == 0 and mod_cmd_re.search(out):
1350+
self.log.debug("Found pattern '%s' in defined '_module_raw' function." % mod_cmd_re.pattern)
1351+
else:
1352+
self.log.debug("Pattern '%s' not found in '_module_raw' function, falling back to 'module' function",
1353+
mod_cmd_re.pattern)
1354+
super(EnvironmentModules, self).check_module_function(allow_mismatch, regex)
1355+
13311356
def check_module_output(self, cmd, stdout, stderr):
13321357
"""Check output of 'module' command, see if if is potentially invalid."""
13331358
if "_mlstatus = False" in stdout:

easybuild/tools/run.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@
7171
"sysctl -n machdep.cpu.brand_string", # used in get_cpu_model (OS X)
7272
"sysctl -n machdep.cpu.vendor", # used in get_cpu_vendor (OS X)
7373
"type module", # used in ModulesTool.check_module_function
74+
"type _module_raw", # used in EnvironmentModules.check_module_function
7475
"ulimit -u", # used in det_parallelism
7576
]
7677

test/framework/modulestool.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
from easybuild.tools import modules, StrictVersion
4040
from easybuild.tools.build_log import EasyBuildError
4141
from easybuild.tools.filetools import read_file, which, write_file
42-
from easybuild.tools.modules import Lmod
42+
from easybuild.tools.modules import EnvironmentModules, Lmod
4343
from test.framework.utilities import init_config
4444

4545

@@ -192,6 +192,23 @@ def test_lmod_specific(self):
192192
# test updating local spider cache (but don't actually update the local cache file!)
193193
self.assertTrue(lmod.update(), "Updated local Lmod spider cache is non-empty")
194194

195+
def test_environment_modules_specific(self):
196+
"""Environment Modules-specific test (skipped unless installed)."""
197+
modulecmd_abspath = which(EnvironmentModules.COMMAND)
198+
# only run this test if 'modulecmd.tcl' is installed
199+
if modulecmd_abspath is not None:
200+
# redefine 'module' and '_module_raw' function (deliberate mismatch with used module
201+
# command in EnvironmentModules)
202+
os.environ['_module_raw'] = "() { eval `/usr/share/Modules/libexec/foo.tcl' bash $*`;\n}"
203+
os.environ['module'] = "() { _module_raw \"$@\" 2>&1;\n}"
204+
error_regex = ".*pattern .* not found in defined 'module' function"
205+
self.assertErrorRegex(EasyBuildError, error_regex, EnvironmentModules, testing=True)
206+
207+
# redefine '_module_raw' function with correct module command
208+
os.environ['_module_raw'] = "() { eval `/usr/share/Modules/libexec/modulecmd.tcl' bash $*`;\n}"
209+
mt = EnvironmentModules(testing=True)
210+
self.assertIsInstance(mt.loaded_modules(), list) # dummy usage
211+
195212
def tearDown(self):
196213
"""Testcase cleanup."""
197214
super(ModulesToolTest, self).tearDown()

0 commit comments

Comments
 (0)