tests: Add a RX functionality test
[openafs.git] / tests / tap / libtap.sh
1 # Shell function library for test cases.
2 #
3 # This file provides a TAP-compatible shell function library useful for
4 # writing test cases.  It is part of C TAP Harness, which can be found at
5 # <http://www.eyrie.org/~eagle/software/c-tap-harness/>.
6 #
7 # Written by Russ Allbery <rra@stanford.edu>
8 # Copyright 2009, 2010 Russ Allbery <rra@stanford.edu>
9 # Copyright 2006, 2007, 2008
10 #     The Board of Trustees of the Leland Stanford Junior University
11 #
12 # Permission is hereby granted, free of charge, to any person obtaining a copy
13 # of this software and associated documentation files (the "Software"), to
14 # deal in the Software without restriction, including without limitation the
15 # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
16 # sell copies of the Software, and to permit persons to whom the Software is
17 # furnished to do so, subject to the following conditions:
18 #
19 # The above copyright notice and this permission notice shall be included in
20 # all copies or substantial portions of the Software.
21 #
22 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
25 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27 # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
28 # IN THE SOFTWARE.
29
30 # Print out the number of test cases we expect to run.
31 plan () {
32     count=1
33     planned="$1"
34     failed=0
35     echo "1..$1"
36     trap finish 0
37 }
38
39 # Prepare for lazy planning.
40 plan_lazy () {
41     count=1
42     planned=0
43     failed=0
44     trap finish 0
45 }
46
47 # Report the test status on exit.
48 finish () {
49     local highest looks
50     highest=`expr "$count" - 1`
51     if [ "$planned" = 0 ] ; then
52         echo "1..$highest"
53         planned="$highest"
54     fi
55     looks='# Looks like you'
56     if [ "$planned" -gt 0 ] ; then
57         if [ "$planned" -gt "$highest" ] ; then
58             if [ "$planned" -gt 1 ] ; then
59                 echo "$looks planned $planned tests but only ran $highest"
60             else
61                 echo "$looks planned $planned test but only ran $highest"
62             fi
63         elif [ "$planned" -lt "$highest" ] ; then
64             local extra
65             extra=`expr "$highest" - "$planned"`
66             if [ "$planned" -gt 1 ] ; then
67                 echo "$looks planned $planned tests but ran $extra extra"
68             else
69                 echo "$looks planned $planned test but ran $extra extra"
70             fi
71         elif [ "$failed" -gt 0 ] ; then
72             if [ "$failed" -gt 1 ] ; then
73                 echo "$looks failed $failed tests of $planned"
74             else
75                 echo "$looks failed $failed test of $planned"
76             fi
77         elif [ "$planned" -gt 1 ] ; then
78             echo "# All $planned tests successful or skipped"
79         else
80             echo "# $planned test successful or skipped"
81         fi
82     fi
83 }
84
85 # Skip the entire test suite.  Should be run instead of plan.
86 skip_all () {
87     local desc
88     desc="$1"
89     if [ -n "$desc" ] ; then
90         echo "1..0 # skip $desc"
91     else
92         echo "1..0 # skip"
93     fi
94     exit 0
95 }
96
97 # ok takes a test description and a command to run and prints success if that
98 # command is successful, false otherwise.  The count starts at 1 and is
99 # updated each time ok is printed.
100 ok () {
101     local desc
102     desc="$1"
103     if [ -n "$desc" ] ; then
104         desc=" - $desc"
105     fi
106     shift
107     if "$@" ; then
108         echo ok $count$desc
109     else
110         echo not ok $count$desc
111         failed=`expr $failed + 1`
112     fi
113     count=`expr $count + 1`
114 }
115
116 # Skip the next test.  Takes the reason why the test is skipped.
117 skip () {
118     echo "ok $count # skip $*"
119     count=`expr $count + 1`
120 }
121
122 # Report the same status on a whole set of tests.  Takes the count of tests,
123 # the description, and then the command to run to determine the status.
124 ok_block () {
125     local end i desc
126     i=$count
127     end=`expr $count + $1`
128     shift
129     desc="$1"
130     shift
131     while [ "$i" -lt "$end" ] ; do
132         ok "$desc" "$@"
133         i=`expr $i + 1`
134     done
135 }
136
137 # Skip a whole set of tests.  Takes the count and then the reason for skipping
138 # the test.
139 skip_block () {
140     local i end
141     i=$count
142     end=`expr $count + $1`
143     shift
144     while [ "$i" -lt "$end" ] ; do
145         skip "$@"
146         i=`expr $i + 1`
147     done
148 }
149
150 # Portable variant of printf '%s\n' "$*".  In the majority of cases, this
151 # function is slower than printf, because the latter is often implemented
152 # as a builtin command.  The value of the variable IFS is ignored.
153 puts () {
154     cat << EOH
155 $@
156 EOH
157 }
158
159 # Run a program expected to succeed, and print ok if it does and produces the
160 # correct output.  Takes the description, expected exit status, the expected
161 # output, the command to run, and then any arguments for that command.
162 # Standard output and standard error are combined when analyzing the output of
163 # the command.
164 #
165 # If the command may contain system-specific error messages in its output,
166 # add strip_colon_error before the command to post-process its output.
167 ok_program () {
168     local desc w_status w_output output status
169     desc="$1"
170     shift
171     w_status="$1"
172     shift
173     w_output="$1"
174     shift
175     output=`"$@" 2>&1`
176     status=$?
177     if [ $status = $w_status ] && [ x"$output" = x"$w_output" ] ; then
178         ok "$desc" true
179     else
180         echo "#  saw: ($status) $output"
181         echo "#  not: ($w_status) $w_output"
182         ok "$desc" false
183     fi
184 }
185
186 # Strip a colon and everything after it off the output of a command, as long
187 # as that colon comes after at least one whitespace character.  (This is done
188 # to avoid stripping the name of the program from the start of an error
189 # message.)  This is used to remove system-specific error messages (coming
190 # from strerror, for example).
191 strip_colon_error() {
192     local output status
193     output=`"$@" 2>&1`
194     status=$?
195     output=`puts "$output" | sed 's/^\([^ ]* [^:]*\):.*/\1/'`
196     puts "$output"
197     return $status
198 }
199
200 # Bail out with an error message.
201 bail () {
202     echo 'Bail out!' "$@"
203     exit 1
204 }
205
206 # Output a diagnostic on standard error, preceded by the required # mark.
207 diag () {
208     echo '#' "$@"
209 }
210
211 # Search for the given file first in $BUILD and then in $SOURCE and echo the
212 # path where the file was found, or the empty string if the file wasn't
213 # found.
214 test_file_path () {
215     if [ -n "$BUILD" ] && [ -f "$BUILD/$1" ] ; then
216         puts "$BUILD/$1"
217     elif [ -n "$SOURCE" ] && [ -f "$SOURCE/$1" ] ; then
218         puts "$SOURCE/$1"
219     else
220         echo ''
221     fi
222 }