|
1 | 1 | #!/bin/bash |
2 | | -EESSI_VERSION="2023.06" |
3 | 2 | export LMOD_PAGER=cat |
4 | 3 |
|
| 4 | +if [ -z ${EESSI_VERSION} ] || [ ! -d /cvmfs/software.eessi.io/versions/${EESSI_VERSION} ]; then |
| 5 | + echo "\$EESSI_VERSION has to be set to a valid EESSI version." |
| 6 | + exit 1 |
| 7 | +fi |
| 8 | + |
| 9 | +if [ -z ${EXPECTED_EASYBUILD_VERSION} ]; then |
| 10 | + echo "\$EXPECTED_EASYBUILD_VERSION has to be set to an EasyBuild version that is expected to be available in EESSI version ${EESSI_VERSION}." |
| 11 | + exit 1 |
| 12 | +fi |
| 13 | + |
| 14 | +if [ -z ${EESSI_SOFTWARE_SUBDIR_OVERRIDE} ]; then |
| 15 | + echo "\$EESSI_SOFTWARE_SUBDIR_OVERRIDE has to be set (e.g., x86_64/intel/haswell) so we can do well defined string comparison for the architecture." |
| 16 | + exit 1 |
| 17 | +fi |
| 18 | + |
5 | 19 | # initialize assert framework |
6 | 20 | if [ ! -d assert.sh ]; then |
7 | | - echo "assert.sh not cloned." |
8 | | - echo "" |
9 | | - echo "run \`git clone https://github.com/lehmannro/assert.sh.git\`" |
10 | | - exit 1 |
| 21 | + echo "assert.sh not cloned." |
| 22 | + echo "" |
| 23 | + echo "run \`git clone https://github.com/lehmannro/assert.sh.git\`" |
| 24 | + echo "(see workflow file that calls this script for how to only clone specific commit if you are worried about security)" |
| 25 | + exit 1 |
11 | 26 | fi |
12 | 27 | . assert.sh/assert.sh |
13 | 28 |
|
14 | | -TEST_SHELLS=("bash" "zsh" "fish" "ksh") |
| 29 | +TEST_SHELLS=("bash" "zsh" "fish" "ksh" "csh" "sh") |
15 | 30 | SHELLS=$@ |
16 | 31 |
|
17 | 32 | for shell in ${SHELLS[@]}; do |
18 | | - echo = | awk 'NF += (OFS = $_) + 100' |
19 | | - echo RUNNING TESTS FOR SHELL: $shell |
20 | | - echo = | awk 'NF += (OFS = $_) + 100' |
| 33 | + echo = | awk 'NF += (OFS = $_) + 100' |
| 34 | + echo RUNNING TESTS FOR SHELL: $shell |
| 35 | + echo = | awk 'NF += (OFS = $_) + 100' |
21 | 36 | if [[ ! " ${TEST_SHELLS[*]} " =~ [[:space:]]${shell}[[:space:]] ]]; then |
22 | | - ### EXCEPTION FOR CSH ### |
23 | | - echo -e "\033[33mWe don't now how to test the shell '$shell', PRs are Welcome.\033[0m" |
| 37 | + echo -e "\033[33mWe don't now how to test the shell '$shell', PRs are Welcome.\033[0m" |
24 | 38 | else |
25 | | - # TEST 1: Source Script and check Module Output |
26 | | - assert "$shell -c 'source init/lmod/$shell' 2>&1 " "EESSI/$EESSI_VERSION loaded successfully" |
27 | | - # TEST 2: Check if module overviews first section is the loaded EESSI module |
28 | | - MODULE_SECTIONS=($($shell -c "source init/lmod/$shell 2>/dev/null; module ov 2>&1 | grep -e '---'")) |
29 | | - PATTERN="/cvmfs/software\.eessi\.io/versions/$EESSI_VERSION/software/linux/x86_64/(intel/haswell|amd/zen3)/modules/all" |
30 | | - assert_raises 'echo "${MODULE_SECTIONS[1]}" | grep -E "$PATTERN"' |
31 | | - # TEST 3: Check if module overviews second section is the EESSI init module |
32 | | - assert "echo ${MODULE_SECTIONS[4]}" "/cvmfs/software.eessi.io/versions/$EESSI_VERSION/init/modules" |
33 | | - # Test 4: Load Python module and check version |
34 | | - command="$shell -c 'source init/lmod/$shell 2>/dev/null; module load Python/3.10.8-GCCcore-12.2.0; python --version'" |
35 | | - expected="Python 3.10.8" |
36 | | - assert "$command" "$expected" |
37 | | - # Test 5: Load Python module and check path |
38 | | - PYTHON_PATH=$($shell -c "source init/lmod/$shell 2>/dev/null; module load Python/3.10.8-GCCcore-12.2.0; which python") |
39 | | - PATTERN="/cvmfs/software\.eessi\.io/versions/$EESSI_VERSION/software/linux/x86_64/(intel/haswell|amd/zen3)/software/Python/3\.10\.8-GCCcore-12\.2\.0/bin/python" |
40 | | - echo "$PYTHON_PATH" | grep -E "$PATTERN" |
41 | | - assert_raises 'echo "$PYTHON_PATH" | grep -E "$PATTERN"' |
42 | | - |
43 | | - #End Test Suite |
44 | | - assert_end "source_eessi_$shell" |
45 | | - fi |
46 | | -done |
| 39 | + if [ "$shell" = "csh" ]; then |
| 40 | + # make sure our .cshrc is empty before we begin as we will clobber it |
| 41 | + [ -f ~/.cshrc ] && mv ~/.cshrc ~/.cshrc_orig |
| 42 | + fi |
| 43 | + |
| 44 | + # TEST 1: Source Script and check Module Output |
| 45 | + expected_pattern=".*EESSI has selected $EESSI_SOFTWARE_SUBDIR_OVERRIDE as the compatible CPU target for EESSI/$EESSI_VERSION.*" |
| 46 | + if [ "$shell" = "csh" ]; then |
| 47 | + assert_raises "$shell -c 'source init/lmod/$shell' 2>&1 | grep -E \"${expected_pattern}\"" |
| 48 | + else |
| 49 | + assert_raises "$shell -c '. init/lmod/$shell' 2>&1 | grep -E \"${expected_pattern}\"" |
| 50 | + fi |
| 51 | + |
| 52 | + # TEST 2: Source Script again in an subshell and check Module Output |
| 53 | + expected_pattern=".*EESSI has selected $EESSI_SOFTWARE_SUBDIR_OVERRIDE as the compatible CPU target for EESSI/$EESSI_VERSION.*" |
| 54 | + if [ "$shell" = "csh" ]; then |
| 55 | + # Cannot figure out how to chain shells with silenced output to test this in csh but it does work |
| 56 | + # assert_raises "$shell -c 'setenv LMOD_QUIET 1 ; source init/lmod/$shell ; ($shell -c \"unsetenv LMOD_QUIET ; source init/lmod/$shell\")' 2>&1 | grep -E \"${expected_pattern}\"" |
| 57 | + echo "Skipping chained shell check for csh as can't figure out how to silence output in first call" |
| 58 | + else |
| 59 | + assert_raises "$shell -c '. init/lmod/$shell > /dev/null 2>&1; $shell -c \". init/lmod/$shell\"' 2>&1 | grep -E \"${expected_pattern}\"" |
| 60 | + fi |
| 61 | + |
| 62 | + # TEST 3: Check if module overviews first section is the loaded EESSI module |
| 63 | + if [ "$shell" = "csh" ]; then |
| 64 | + # module is defined as alias, but aliases are only retained in interactive |
| 65 | + # shells we work around this by creating a .cshrc file (which sources the |
| 66 | + # init script), and then simply run the remaining commands |
| 67 | + echo "source init/lmod/$shell" > ~/.cshrc |
| 68 | + MODULE_SECTIONS=($($shell -c "module ov" 2>&1 | grep -e '---')) |
| 69 | + else |
| 70 | + MODULE_SECTIONS=($($shell -c ". init/lmod/$shell >/dev/null 2>&1; module ov 2>&1 | grep -e '---'")) |
| 71 | + fi |
| 72 | + PATTERN="/cvmfs/software\.eessi\.io/versions/$EESSI_VERSION/software/linux/$EESSI_SOFTWARE_SUBDIR_OVERRIDE/modules/all" |
| 73 | + assert_raises 'echo "${MODULE_SECTIONS[1]}" | grep -E "$PATTERN"' |
| 74 | + # echo "${MODULE_SECTIONS[1]}" "$PATTERN" |
47 | 75 |
|
| 76 | + # TEST 4: Check if module overviews second section is the EESSI init module |
| 77 | + assert "echo ${MODULE_SECTIONS[4]}" "/cvmfs/software.eessi.io/init/modules" |
| 78 | + |
| 79 | + # TEST 5: Load EasyBuild module and check version |
| 80 | + # eb --version outputs: "This is EasyBuild 5.1.1 (framework: 5.1.1, easyblocks: 5.1.1) on host ..." |
| 81 | + if [ "$shell" = "csh" ]; then |
| 82 | + echo "source init/lmod/$shell" > ~/.cshrc |
| 83 | + command="$shell -c 'module load EasyBuild/${EXPECTED_EASYBUILD_VERSION}; eb --version' | tail -n 1 | awk '{print \$4}'" |
| 84 | + else |
| 85 | + command="$shell -c '. init/lmod/$shell >/dev/null 2>&1; module load EasyBuild/${EXPECTED_EASYBUILD_VERSION}; eb --version' | tail -n 1 | awk '{print \$4}'" |
| 86 | + fi |
| 87 | + assert "$command" "$EXPECTED_EASYBUILD_VERSION" |
| 88 | + |
| 89 | + # TEST 6: Load EasyBuild module and check path |
| 90 | + if [ "$shell" = "csh" ]; then |
| 91 | + echo "source init/lmod/$shell" > ~/.cshrc |
| 92 | + EASYBUILD_PATH=$($shell -c "module load EasyBuild/${EXPECTED_EASYBUILD_VERSION}; which eb") |
| 93 | + else |
| 94 | + EASYBUILD_PATH=$($shell -c ". init/lmod/$shell 2>/dev/null; module load EasyBuild/${EXPECTED_EASYBUILD_VERSION}; which eb") |
| 95 | + fi |
| 96 | + # escape the dots in ${EASYBUILD_VERSION} |
| 97 | + PATTERN="/cvmfs/software\.eessi\.io/versions/$EESSI_VERSION/software/linux/$EESSI_SOFTWARE_SUBDIR_OVERRIDE/software/EasyBuild/${EXPECTED_EASYBUILD_VERSION//./\\.}/bin/eb" |
| 98 | + # echo "$EASYBUILD_PATH" | grep -E "$PATTERN" |
| 99 | + assert_raises 'echo "$EASYBUILD_PATH" | grep -E "$PATTERN"' |
| 100 | + # echo "$EASYBUILD_PATH" "$PATTERN" |
| 101 | + |
| 102 | + # TEST 7 and 8: Check the various options (EESSI_DEFAULT_MODULES_APPEND, EESSI_DEFAULT_MODULES_APPEND, EESSI_EXTRA_MODULEPATH) all work |
| 103 | + if [ "$shell" = "csh" ]; then |
| 104 | + echo "setenv EESSI_DEFAULT_MODULES_APPEND append_module" > ~/.cshrc |
| 105 | + echo "setenv EESSI_DEFAULT_MODULES_PREPEND prepend_module" >> ~/.cshrc |
| 106 | + echo "setenv EESSI_EXTRA_MODULEPATH .github/workflows/modules" >> ~/.cshrc |
| 107 | + echo "source init/lmod/$shell" >> ~/.cshrc |
| 108 | + TEST_LMOD_SYSTEM_DEFAULT_MODULES=$($shell -c 'echo $LMOD_SYSTEM_DEFAULT_MODULES') |
| 109 | + TEST_MODULEPATH=$($shell -c 'echo $MODULEPATH') |
| 110 | + elif [ "$shell" = "fish" ]; then |
| 111 | + TEST_LMOD_SYSTEM_DEFAULT_MODULES=$($shell -c 'set -x EESSI_DEFAULT_MODULES_APPEND append_module ; set -x EESSI_DEFAULT_MODULES_PREPEND prepend_module ; set -x EESSI_EXTRA_MODULEPATH .github/workflows/modules ; source init/lmod/'"$shell"' 2>/dev/null; echo $LMOD_SYSTEM_DEFAULT_MODULES') |
| 112 | + TEST_MODULEPATH=$($shell -c 'set -x EESSI_DEFAULT_MODULES_APPEND append_module ; set -x EESSI_DEFAULT_MODULES_PREPEND prepend_module ; set -x EESSI_EXTRA_MODULEPATH .github/workflows/modules ; source init/lmod/'"$shell"' 2>/dev/null; echo $MODULEPATH') |
| 113 | + else |
| 114 | + TEST_LMOD_SYSTEM_DEFAULT_MODULES=$($shell -c 'export EESSI_DEFAULT_MODULES_APPEND=append_module ; export EESSI_DEFAULT_MODULES_PREPEND=prepend_module ; export EESSI_EXTRA_MODULEPATH=.github/workflows/modules ; . init/lmod/'"$shell"' ; echo $LMOD_SYSTEM_DEFAULT_MODULES') |
| 115 | + TEST_MODULEPATH=$($shell -c 'export EESSI_DEFAULT_MODULES_APPEND=append_module ; export EESSI_DEFAULT_MODULES_PREPEND=prepend_module ; export EESSI_EXTRA_MODULEPATH=.github/workflows/modules ; . init/lmod/'"$shell"' 2>/dev/null; echo $MODULEPATH') |
| 116 | + fi |
| 117 | + LMOD_SYSTEM_DEFAULT_MODULES_PATTERN='^prepend_module:.*:append_module$' |
| 118 | + # echo "$TEST_LMOD_SYSTEM_DEFAULT_MODULES" AND "$LMOD_SYSTEM_DEFAULT_MODULES_PATTERN" |
| 119 | + assert_raises 'echo "$TEST_LMOD_SYSTEM_DEFAULT_MODULES" | grep -E "$LMOD_SYSTEM_DEFAULT_MODULES_PATTERN"' |
| 120 | + if [ "$shell" = "fish" ]; then |
| 121 | + MODULEPATH_PATTERN='\.github/workflows/modules$' |
| 122 | + else |
| 123 | + MODULEPATH_PATTERN=':\.github/workflows/modules$' |
| 124 | + fi |
| 125 | + # echo "$TEST_MODULEPATH" AND "$MODULEPATH_PATTERN" |
| 126 | + assert_raises 'echo "$TEST_MODULEPATH" | grep -E "$MODULEPATH_PATTERN"' |
| 127 | + |
| 128 | + # TEST 9 and 10: Add a conditional test depending on whether we have the Lmod command is available locally or not (Ubuntu-based location for CI) |
| 129 | + if [ -d "$LMOD_PKG/init" ]; then |
| 130 | + echo "Running check for locally available Lmod with purge" |
| 131 | + if [ "$shell" = "csh" ]; then |
| 132 | + echo "source $LMOD_PKG/init/$shell" > ~/.cshrc |
| 133 | + echo "source init/lmod/$shell" >> ~/.cshrc |
| 134 | + TEST_EESSI_WITH_PURGE=$($shell -c 'echo') |
| 135 | + echo "source $LMOD_PKG/init/$shell" > ~/.cshrc |
| 136 | + echo "setenv EESSI_NO_MODULE_PURGE_ON_INIT 1" >> ~/.cshrc |
| 137 | + echo "source init/lmod/$shell" >> ~/.cshrc |
| 138 | + TEST_EESSI_WITHOUT_PURGE=$($shell -c 'echo $EESSI_NO_MODULE_PURGE_ON_INIT') |
| 139 | + elif [ "$shell" = "fish" ]; then |
| 140 | + TEST_EESSI_WITH_PURGE=$($shell -c "source $LMOD_PKG/init/$shell 2>/dev/null ; source init/lmod/$shell 2>/dev/null") |
| 141 | + TEST_EESSI_WITHOUT_PURGE=$($shell -c "set -x EESSI_NO_MODULE_PURGE_ON_INIT 1 ; source $LMOD_PKG/init/$shell 2>/dev/null ; source init/lmod/$shell 2>/dev/null") |
| 142 | + else |
| 143 | + TEST_EESSI_WITH_PURGE=$($shell -c ". $LMOD_PKG/init/$shell 2>/dev/null ; . init/lmod/$shell 2>/dev/null") |
| 144 | + TEST_EESSI_WITHOUT_PURGE=$($shell -c "export EESSI_NO_MODULE_PURGE_ON_INIT=1 ; . $LMOD_PKG/init/$shell 2>/dev/null ; . init/lmod/$shell 2>/dev/null") |
| 145 | + fi |
| 146 | + # In the first case we should have the test and in the second case we shouldn't |
| 147 | + pattern="Modules purged before initialising EESSI" |
| 148 | + echo $TEST_EESSI_WITH_PURGE |
| 149 | + assert_raises 'echo "$TEST_EESSI_WITH_PURGE" | grep "$pattern"' |
| 150 | + # this case should raise 1 |
| 151 | + echo $TEST_EESSI_WITHOUT_PURGE |
| 152 | + assert_raises 'echo "$TEST_EESSI_WITHOUT_PURGE" | grep "$pattern"' 1 |
| 153 | + fi |
| 154 | + |
| 155 | + # Optional test 11, check if the prompt has been updated |
| 156 | + if [ "$shell" = "bash" ] || [ "$shell" = "ksh" ] || [ "$shell" = "zsh" ] || [ "$shell" = "sh" ]; then |
| 157 | + # Let's configure things to use the EESSI module within the PR |
| 158 | + sed 's|export MODULEPATH=.*|export MODULEPATH=init/modules|' init/lmod/sh >init/lmod/sh.test |
| 159 | + ln -srf init/lmod/sh.test init/lmod/bash.test |
| 160 | + ln -srf init/lmod/sh.test init/lmod/ksh.test |
| 161 | + ln -srf init/lmod/sh.test init/lmod/zsh.test |
| 162 | + # Typically this is a non-interactive shell, so manually unset PS1 and reset to a non-exported variable when testing |
| 163 | + TEST_EESSI_PS1_UPDATE=$($shell -c "unset PS1 ; PS1='$ ' ; . init/lmod/$shell.test 2>/dev/null ; echo \"\$PS1\"") |
| 164 | + TEST_EESSI_NO_PS1_UPDATE=$($shell -c "unset PS1 ; . init/lmod/$shell.test 2>/dev/null ; echo \"\$PS1\"") |
| 165 | + pattern="{EESSI/${EESSI_VERSION}} " |
| 166 | + assert_raises 'echo "$TEST_EESSI_PS1_UPDATE" | grep "$pattern"' |
| 167 | + assert_raises 'echo "$TEST_EESSI_NO_PS1_UPDATE" | grep "$pattern"' 1 |
| 168 | + # Also check when we explicitly ask for it not to be updated |
| 169 | + TEST_EESSI_EXPLICIT_NO_PS1_UPDATE=$($shell -c "unset PS1 ; PS1='test> ' ; export EESSI_MODULE_UPDATE_PS1=0 ; . init/lmod/$shell.test 2>/dev/null ; echo \"\$PS1\"") |
| 170 | + TEST_EESSI_EXPLICIT_NO_PS1_UPDATE_CALLED_TWICE=$($shell -c "unset PS1 ; PS1='$ ' ; export EESSI_MODULE_UPDATE_PS1=0 ; . init/lmod/$shell.test 2>/dev/null ; . init/lmod/$shell.test 2>/dev/null ; echo \"\$PS1\"") |
| 171 | + assert_raises 'echo "$TEST_EESSI_EXPLICIT_NO_PS1_UPDATE" | grep "$pattern"' 1 |
| 172 | + assert_raises 'echo "$TEST_EESSI_EXPLICIT_NO_PS1_UPDATE_CALLED_TWICE" | grep "$pattern"' 1 |
| 173 | + # Also check complex prompts, and unloading/purging the EESSI module |
| 174 | + prompt="\$(echo '\['✘) $ " |
| 175 | + promptstr="\[✘ $ " |
| 176 | + updated_promptstr="{EESSI/${EESSI_VERSION}} \[✘ $ " |
| 177 | + TEST_EESSI_PS1_UPDATE=$($shell -c "unset PS1 ; PS1=\"$prompt\" ; . init/lmod/$shell.test >/dev/null ; echo \"\$PS1\"") |
| 178 | + TEST_EESSI_PS1_REVERT=$($shell -c "unset PS1 ; PS1=\"$prompt\" ; . init/lmod/$shell.test >/dev/null ; module purge; echo \"\$PS1\"") |
| 179 | + assert 'echo "$TEST_EESSI_PS1_UPDATE"' "$updated_promptstr" |
| 180 | + assert 'echo "$TEST_EESSI_PS1_REVERT"' "$promptstr" |
| 181 | + fi |
| 182 | + |
| 183 | + # End Test Suite |
| 184 | + assert_end "source_eessi_$shell" |
| 185 | + |
| 186 | + if [ "$shell" = "csh" ]; then |
| 187 | + # Restore our .cshrc |
| 188 | + [ -f ~/.cshrc_orig ] && mv ~/.cshrc_orig ~/.cshrc |
| 189 | + fi |
| 190 | + |
| 191 | + fi |
| 192 | +done |
48 | 193 |
|
49 | 194 | # RESET PAGER |
50 | 195 | export LMOD_PAGER= |
0 commit comments