Whamcloud - gitweb
b=23408 disable failure temporarily while we collect performance stats
[fs/lustre-release.git] / lustre / tests / functions.sh
1 #!/bin/bash
2
3 # Simple function used by run_*.sh scripts
4
5 assert_env() {
6     local failed=""
7     for name in $@; do
8         if [ -z "${!name}" ]; then
9             echo "$0: $name must be set"
10             failed=1
11         fi
12     done
13     [ $failed ] && exit 1 || true
14 }
15
16 # lrepl - Lustre test Read-Eval-Print Loop.
17 #
18 # This function implements a REPL for the Lustre test framework.  It
19 # doesn't exec an actual shell because the user may want to inspect
20 # variables and use functions from the test framework.
21 lrepl() {
22     local line
23     local rawline
24     local prompt
25
26     cat <<EOF
27         This is an interactive read-eval-print loop interactive shell
28         simulation that you can use to debug failing tests.  You can
29         enter most bash command lines (see notes below).
30
31         Use this REPL to inspect variables, set them, call test
32         framework shell functions, etcetera.
33
34         'exit' or EOF to exit this shell.
35
36         set \$retcode to 0 to cause the assertion failure that
37         triggered this REPL to be ignored.
38
39         Examples:
40             do_facet ost1 lctl get_param ost.*.ost.threads_*
41             do_rpc_nodes \$OSTNODES unload_modules
42
43         NOTES:
44             All but the last line of multi-line statements or blocks
45             must end in a backslash.
46
47             "Here documents" are not supported.
48
49             History is not supported, but command-line editing is.
50
51 EOF
52
53     # Prompt escapes don't work in read -p, sadly.
54     prompt=":test_${testnum:-UNKNOWN}:$(uname -n):$(basename $PWD)% "
55
56     # We use read -r to get close to a shell experience
57     while read -e -r -p "$prompt" rawline; do
58         line=
59         case "$rawline" in
60         # Don't want to exit-exit, just exit the REPL
61         exit) break;;
62         # We need to handle continuations, and read -r doesn't do
63         # that for us.  Yet we need read -r.
64         #
65         # We also use case/esac to compare lines read to "*\\"
66         # because [ "$line" = *\\ ] and variants of that don't work.
67         *\\) line="$rawline"
68             while read -e -r -p '> ' rawline
69             do
70                 line="$line"$'\n'"$rawline"
71                 case "$rawline" in
72                 # We could check for here documents by matching
73                 # against *<<*, but who cares.
74                 *\\) continue;;
75                 *) break;;
76                 esac
77             done
78             ;;
79         *) line=$rawline
80         esac
81
82         case "$line" in
83         *\\) break;;
84         esac
85
86         # Finally!  Time to eval.
87         eval "$line"
88     done
89
90     echo $'\n\tExiting interactive shell...\n'
91     return 0
92 }
93
94 # lassert - Lustre test framework assert
95 #
96 # Arguments: failure code, failure message, expression/statement
97 #
98 # lassert evaluates the expression given, and, if false, calls
99 # error() to trigger test failure.  If REPL_ON_LASSERT is true then
100 # lassert will call lrepl() to give the user an interactive shell.
101 # If the REPL sets retcode=0 then the assertion failure will be
102 # ignored.
103 lassert() {
104     local retcode=$1
105     local msg=$2
106     shift 2
107
108     echo "checking $* ($(eval echo \""$*"\"))..."
109     eval "$@" && return 0;
110
111     if ${REPL_ON_LASSERT:-false}; then
112         echo "Assertion $retcode failed: $* (expanded: $(eval echo \""$*"\"))
113 $msg"
114         lrepl
115     fi
116
117     error "Assertion $retcode failed: $* (expanded: $(eval echo \""$*"\"))
118 $msg"
119     return $retcode
120 }
121
122 # setmodopts- set module options for subsequent calls to load_modules
123 #
124 # Usage: setmodopts module_name new_value [var_in_which_to_save_old_value]
125 #        setmodopts -a module_name new_value [var_in_which_to_save_old_value]
126 #
127 # In the second usage the new value is appended to the old.
128 setmodopts() {
129         local _append=false
130
131         if [ "$1" = -a ]; then
132             _append=true
133             shift
134         fi
135
136         local _var=MODOPTS_$1
137         local _newvalue=$2
138         local _savevar=$3
139         local _oldvalue
140
141         # Dynamic naming of variables is a pain in bash.  In ksh93 we could
142         # write "nameref opts_var=${modname}_MODOPTS" then assign directly
143         # to opts_var.  Associative arrays would also help, alternatively.
144         # Alas, we're stuck with eval until all distros move to a more recent
145         # version of bash.  Fortunately we don't need to eval unset and export.
146
147         if [ -z "$_newvalue" ]; then
148             unset $_var
149             return 0
150         fi
151
152         _oldvalue=${!var}
153         $_append && _newvalue="$_oldvalue $_newvalue"
154         export $_var="$_newvalue"
155         echo setmodopts: ${_var}=${_newvalue}
156
157         [ -n "$_savevar" ] && eval $_savevar=\""$_oldvalue"\"
158 }
159
160 echoerr () { echo "$@" 1>&2 ; }
161
162 signaled() {
163     echoerr "$(date +'%F %H:%M:%S'): client load was signaled to terminate"
164
165     local PGID=$(ps -eo "%c %p %r" | awk "/ $PPID / {print \$3}")
166     kill -TERM -$PGID
167     sleep 5
168     kill -KILL -$PGID
169 }
170
171 mpi_run () {
172     local mpirun="$MPIRUN $MPIRUN_OPTIONS"
173     local command="$mpirun $@"
174     local mpilog=$TMP/mpi.log
175     local rc
176
177     if [ "$MPI_USER" != root -a $mpirun ]; then
178         echo "+ chmod 0777 $MOUNT"
179         chmod 0777 $MOUNT
180         command="su $MPI_USER sh -c \"$command \""
181     fi
182
183     ls -ald $MOUNT
184     echo "+ $command"
185     eval $command 2>&1 | tee $mpilog || true
186
187     rc=${PIPESTATUS[0]}
188     if [ $rc -eq 0 ] && grep -q "p4_error:" $mpilog ; then
189        rc=1
190     fi
191     return $rc
192 }
193
194 nids_list () {
195    local list
196    for i in ${1//,/ }; do
197        list="$list $i@$NETTYPE"
198    done
199    echo $list
200 }
201
202 # FIXME: all setup/cleanup can be done without rpc.sh
203 lst_end_session () {
204     local verbose=false
205     [ x$1 = x--verbose ] && verbose=true
206
207     export LST_SESSION=`$LST show_session 2>/dev/null | awk -F " " '{print $5}'`
208     [ "$LST_SESSION" == "" ] && return
209
210     if $verbose; then 
211         $LST show_error c s
212     fi
213     $LST stop b
214     $LST end_session
215 }
216
217 lst_session_cleanup_all () {
218     local list=$(comma_list $(nodes_list))
219     do_rpc_nodes $list lst_end_session
220 }
221
222 lst_cleanup () {
223     lsmod | grep -q lnet_selftest && rmmod lnet_selftest > /dev/null 2>&1 || true
224 }
225
226 lst_cleanup_all () {
227    local list=$(comma_list $(nodes_list))
228
229    # lst end_session needs to be executed only locally
230    # i.e. on node where lst new_session was called
231    lst_end_session --verbose 
232    do_rpc_nodes $list lst_cleanup
233 }
234
235 lst_setup () {
236     load_module lnet_selftest
237 }
238
239 lst_setup_all () {
240     local list=$(comma_list $(nodes_list))
241     do_rpc_nodes $list lst_setup 
242 }
243