summaryrefslogtreecommitdiff
path: root/share/spack/qa/setup-env-test.sh
blob: 7613637984d68982561a79a18dea1eba9afe9dd0 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
#!/bin/sh
#
# Copyright 2013-2020 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)

#
# This script tests that Spack's setup-env.sh init script works.
#
# The tests are portable to bash, zsh, and bourne shell, and can be run
# in any of these shells.
#

# ------------------------------------------------------------------------
# Functions for color output.
# ------------------------------------------------------------------------

# Colors for output
red='\033[1;31m'
cyan='\033[1;36m'
green='\033[1;32m'
reset='\033[0m'

echo_red() {
    printf "${red}$*${reset}\n"
}

echo_green() {
    printf "${green}$*${reset}\n"
}

echo_msg() {
    printf "${cyan}$*${reset}\n"
}

# ------------------------------------------------------------------------
# Generic functions for testing shell code.
# ------------------------------------------------------------------------

# counts of test successes and failures.
success=0
errors=0

# Print out a header for a group of tests.
title() {
    echo
    echo_msg "$@"
    echo_msg "---------------------------------"
}

# echo FAIL in red text; increment failures
fail() {
    echo_red FAIL
    errors=$((errors+1))
}

#
# Echo SUCCESS in green; increment successes
#
pass() {
    echo_green SUCCESS
    success=$((success+1))
}

#
# Run a command and suppress output unless it fails.
# On failure, echo the exit code and output.
#
succeeds() {
    printf "'%s' succeeds ... " "$*"
    output=$($* 2>&1)
    err="$?"

    if [ "$err" != 0 ]; then
        fail
        echo_red "Command failed with error $err."
        if [ -n "$output" ]; then
            echo_msg "Output:"
            echo "$output"
        else
            echo_msg "No output."
        fi
    else
        pass
    fi
}

#
# Run a command and suppress output unless it succeeds.
# If the command succeeds, echo the output.
#
fails() {
    printf "'%s' fails ... " "$*"
    output=$("$@" 2>&1)
    err="$?"

    if [ "$err" = 0 ]; then
        fail
        echo_red "Command failed with error $err."
        if [ -n "$output" ]; then
            echo_msg "Output:"
            echo "$output"
        else
            echo_msg "No output."
        fi
    else
        pass
    fi
}

#
# Ensure that a string is in the output of a command.
# Suppresses output on success.
# On failure, echo the exit code and output.
#
contains() {
    string="$1"
    shift

    printf "'%s' output contains '$string' ... " "$*"
    output=$("$@" 2>&1)
    err="$?"

    if [ "${output#*$string}" = "${output}" ]; then
        fail
        echo_red "Command exited with error $err."
        echo_red "'$string' was not in output."
        if [ -n "$output" ]; then
            echo_msg "Output:"
            echo "$output"
        else
            echo_msg "No output."
        fi
    else
        pass
    fi
}

#
# Ensure that a variable is set.
#
is_set() {
    printf "'%s' is set ... " "$1"
    if eval "[ -z \${${1:-}+x} ]"; then
        fail
        echo_msg "$1 was not set!"
    else
        pass
    fi
}

#
# Ensure that a variable is not set.
# Fails and prints the value of the variable if it is set.
#
is_not_set() {
    printf "'%s' is not set ... " "$1"
    if eval "[ ! -z \${${1:-}+x} ]"; then
        fail
        echo_msg "$1 was set:"
        echo "    $1"
    else
        pass
    fi
}


# -----------------------------------------------------------------------
# Instead of invoking the module commands, we print the
# arguments that Spack invokes the command with, so we can check that
# Spack passes the expected arguments in the tests below.
#
# We make that happen by defining the sh functions below.
# -----------------------------------------------------------------------
module() {
    echo module "$@"
}

# -----------------------------------------------------------------------
# Setup test environment and do some preliminary checks
# -----------------------------------------------------------------------

# Make sure no environment is active
unset SPACK_ENV

# fail on undefined variables
set -u

# Source setup-env.sh before tests
.  share/spack/setup-env.sh

# bash should expand aliases even when non-interactive
if [ -n "${BASH:-}" ]; then
    shopt -s expand_aliases
fi

title "Testing setup-env.sh with $_sp_shell"

# spack command is now avaialble
succeeds which spack

# mock cd command (intentionally define only AFTER setup-env.sh)
cd() {
    echo cd "$@"
}

# create a fake mock package install and store its location for later
title "Setup"
echo "Creating a mock package installation"
spack -m install --fake a
a_install=$(spack location -i a)
a_module=$(spack -m module tcl find a)

b_install=$(spack location -i b)
b_module=$(spack -m module tcl find b)

# create a test environment for tesitng environment commands
echo "Creating a mock environment"
spack env create spack_test_env
test_env_location=$(spack location -e spack_test_env)

# ensure that we uninstall b on exit
cleanup() {
    if [ "$?" != 0 ]; then
        trapped_error=true
    else
        trapped_error=false
    fi

    echo "Removing test environment before exiting."
    spack env deactivate 2>&1 > /dev/null
    spack env rm -y spack_test_env

    title "Cleanup"
    echo "Removing test packages before exiting."
    spack -m uninstall -yf b a

    echo
    echo "$success tests succeeded."
    echo "$errors tests failed."

    if [ "$trapped_error" = true ]; then
        echo "Exited due to an error."
    fi

    if [ "$errors" = 0 ] && [ "$trapped_error" = false ]; then
        pass
        exit 0
    else
        fail
        exit 1
    fi
}
trap cleanup EXIT

# -----------------------------------------------------------------------
# Test all spack commands with special env support
# -----------------------------------------------------------------------
title 'Testing `spack`'
contains 'usage: spack ' spack
contains "usage: spack " spack -h
contains "usage: spack " spack help
contains "usage: spack " spack -H
contains "usage: spack " spack help --all

title 'Testing `spack cd`'
contains "usage: spack cd " spack cd -h
contains "usage: spack cd " spack cd --help
contains "cd $b_install" spack cd -i b

title 'Testing `spack module`'
contains "usage: spack module " spack -m module -h
contains "usage: spack module " spack -m module --help
contains "usage: spack module " spack -m module

title 'Testing `spack load`'
contains "module load $b_module" spack -m load b
fails spack -m load -l
contains "module load -l --arg $b_module" spack -m load -l --arg b
contains "module load $b_module $a_module" spack -m load -r a
contains "module load $b_module $a_module" spack -m load --dependencies a
fails spack -m load d
contains "usage: spack load " spack -m load -h
contains "usage: spack load " spack -m load -h d
contains "usage: spack load " spack -m load --help

title 'Testing `spack unload`'
contains "module unload $b_module" spack -m unload b
fails spack -m unload -l
contains "module unload -l --arg $b_module" spack -m unload -l --arg b
fails spack -m unload d
contains "usage: spack unload " spack -m unload -h
contains "usage: spack unload " spack -m unload -h d
contains "usage: spack unload " spack -m unload --help

title 'Testing `spack env`'
contains "usage: spack env " spack env -h
contains "usage: spack env " spack env --help

title 'Testing `spack env list`'
contains " spack env list " spack env list -h
contains " spack env list " spack env list --help

title 'Testing `spack env activate`'
contains "No such environment:" spack env activate no_such_environment
contains "usage: spack env activate " spack env activate
contains "usage: spack env activate " spack env activate -h
contains "usage: spack env activate " spack env activate --help

title 'Testing `spack env deactivate`'
contains "Error: No environment is currently active" spack env deactivate
contains "usage: spack env deactivate " spack env deactivate no_such_environment
contains "usage: spack env deactivate " spack env deactivate -h
contains "usage: spack env deactivate " spack env deactivate --help

title 'Testing activate and deactivate together'
echo "Testing 'spack env activate spack_test_env'"
spack env activate spack_test_env
is_set SPACK_ENV

echo "Testing 'spack env deactivate'"
spack env deactivate
is_not_set SPACK_ENV

echo "Testing 'spack env activate spack_test_env'"
spack env activate spack_test_env
is_set SPACK_ENV

echo "Testing 'despacktivate'"
despacktivate
is_not_set SPACK_ENV

echo "Testing 'spack env activate --prompt spack_test_env'"
spack env activate --prompt spack_test_env
is_set SPACK_ENV
is_set SPACK_OLD_PS1

echo "Testing 'despacktivate'"
despacktivate
is_not_set SPACK_ENV
is_not_set SPACK_OLD_PS1