# Copyright 2013-2022 Lawrence Livermore National Security, LLC and other
# Spack Project Developers. See the top-level COPYRIGHT file for details.
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
import os
import sys
import pytest
import spack
import spack.util.module_cmd
from spack.util.module_cmd import (
get_path_args_from_module_line,
get_path_from_module_contents,
module,
path_from_modules,
)
pytestmark = pytest.mark.skipif(sys.platform == 'win32',
reason="Tests fail on Windows")
test_module_lines = ['prepend-path LD_LIBRARY_PATH /path/to/lib',
'setenv MOD_DIR /path/to',
'setenv LDFLAGS -Wl,-rpath/path/to/lib',
'setenv LDFLAGS -L/path/to/lib',
'prepend-path PATH /path/to/bin']
[docs]def test_module_function_change_env(tmpdir, working_env):
src_file = str(tmpdir.join('src_me'))
with open(src_file, 'w') as f:
f.write('export TEST_MODULE_ENV_VAR=TEST_SUCCESS\n')
os.environ['NOT_AFFECTED'] = "NOT_AFFECTED"
module('load', src_file, module_template='. {0} 2>&1'.format(src_file))
assert os.environ['TEST_MODULE_ENV_VAR'] == 'TEST_SUCCESS'
assert os.environ['NOT_AFFECTED'] == "NOT_AFFECTED"
[docs]def test_module_function_no_change(tmpdir):
src_file = str(tmpdir.join('src_me'))
with open(src_file, 'w') as f:
f.write('echo TEST_MODULE_FUNCTION_PRINT')
old_env = os.environ.copy()
text = module('show', src_file, module_template='. {0} 2>&1'.format(src_file))
assert text == 'TEST_MODULE_FUNCTION_PRINT\n'
assert os.environ == old_env
[docs]def test_get_path_from_module_faked(monkeypatch):
for line in test_module_lines:
def fake_module(*args):
return line
monkeypatch.setattr(spack.util.module_cmd, 'module', fake_module)
path = path_from_modules(['mod'])
assert path == '/path/to'
[docs]def test_get_path_from_module_contents():
# A line with "MODULEPATH" appears early on, and the test confirms that it
# is not extracted as the package's path
module_show_output = """
os.environ["MODULEPATH"] = "/path/to/modules1:/path/to/modules2";
----------------------------------------------------------------------------
/root/cmake/3.9.2.lua:
----------------------------------------------------------------------------
help([[CMake Version 3.9.2
]])
whatis("Name: CMake")
whatis("Version: 3.9.2")
whatis("Category: Tools")
whatis("URL: https://cmake.org/")
prepend_path("LD_LIBRARY_PATH","/bad/path")
prepend_path("PATH","/path/to/cmake-3.9.2/bin:/other/bad/path")
prepend_path("MANPATH","/path/to/cmake/cmake-3.9.2/share/man")
prepend_path("LD_LIBRARY_PATH","/path/to/cmake-3.9.2/lib64")
"""
module_show_lines = module_show_output.split('\n')
# PATH and LD_LIBRARY_PATH outvote MANPATH and the other PATH and
# LD_LIBRARY_PATH entries
assert (get_path_from_module_contents(module_show_lines, 'cmake-3.9.2') ==
'/path/to/cmake-3.9.2')
[docs]def test_get_path_from_empty_module():
assert get_path_from_module_contents('', 'test') is None
[docs]def test_pkg_dir_from_module_name():
module_show_lines = ['setenv FOO_BAR_DIR /path/to/foo-bar']
assert (get_path_from_module_contents(module_show_lines, 'foo-bar') ==
'/path/to/foo-bar')
assert (get_path_from_module_contents(module_show_lines, 'foo-bar/1.0') ==
'/path/to/foo-bar')
[docs]def test_get_argument_from_module_line():
simple_lines = ['prepend-path LD_LIBRARY_PATH /lib/path',
'prepend-path LD_LIBRARY_PATH /lib/path',
"prepend_path('PATH' , '/lib/path')",
'prepend_path( "PATH" , "/lib/path" )',
'prepend_path("PATH",' + "'/lib/path')"]
complex_lines = ['prepend-path LD_LIBRARY_PATH /lib/path:/pkg/path',
'prepend-path LD_LIBRARY_PATH /lib/path:/pkg/path',
"prepend_path('PATH' , '/lib/path:/pkg/path')",
'prepend_path( "PATH" , "/lib/path:/pkg/path" )',
'prepend_path("PATH",' + "'/lib/path:/pkg/path')"]
bad_lines = ['prepend_path(PATH,/lib/path)',
'prepend-path (LD_LIBRARY_PATH) /lib/path']
assert all(get_path_args_from_module_line(x) == ['/lib/path']
for x in simple_lines)
assert all(get_path_args_from_module_line(x) == ['/lib/path', '/pkg/path']
for x in complex_lines)
for bl in bad_lines:
with pytest.raises(ValueError):
get_path_args_from_module_line(bl)
# lmod is entirely unsupported on Windows
[docs]def test_lmod_quote_parsing():
lines = ['setenv("SOME_PARTICULAR_DIR","-L/opt/cray/pe/mpich/8.1.4/gtl/lib")']
result = get_path_from_module_contents(lines, 'some-module')
assert '/opt/cray/pe/mpich/8.1.4/gtl' == result