]>
jfr.im git - solanum.git/blob - tests/tap/libtap.sh
1 # Shell function library for test cases.
3 # Note that while many of the functions in this library could benefit from
4 # using "local" to avoid possibly hammering global variables, Solaris /bin/sh
5 # doesn't support local and this library aspires to be portable to Solaris
6 # Bourne shell. Instead, all private variables are prefixed with "tap_".
8 # This file provides a TAP-compatible shell function library useful for
9 # writing test cases. It is part of C TAP Harness, which can be found at
10 # <https://www.eyrie.org/~eagle/software/c-tap-harness/>.
12 # Written by Russ Allbery <eagle@eyrie.org>
13 # Copyright 2009, 2010, 2011, 2012, 2016 Russ Allbery <eagle@eyrie.org>
14 # Copyright 2006, 2007, 2008, 2013
15 # The Board of Trustees of the Leland Stanford Junior University
17 # Permission is hereby granted, free of charge, to any person obtaining a copy
18 # of this software and associated documentation files (the "Software"), to
19 # deal in the Software without restriction, including without limitation the
20 # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
21 # sell copies of the Software, and to permit persons to whom the Software is
22 # furnished to do so, subject to the following conditions:
24 # The above copyright notice and this permission notice shall be included in
25 # all copies or substantial portions of the Software.
27 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
28 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
29 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
30 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
31 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
32 # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
35 # Print out the number of test cases we expect to run.
44 # Prepare for lazy planning.
52 # Report the test status on exit.
54 tap_highest
=`expr "$count" - 1`
55 if [ "$planned" = 0 ] ; then
56 echo "1..$tap_highest"
57 planned
="$tap_highest"
59 tap_looks
='# Looks like you'
60 if [ "$planned" -gt 0 ] ; then
61 if [ "$planned" -gt "$tap_highest" ] ; then
62 if [ "$planned" -gt 1 ] ; then
63 echo "$tap_looks planned $planned tests but only ran" \
66 echo "$tap_looks planned $planned test but only ran" \
69 elif [ "$planned" -lt "$tap_highest" ] ; then
70 tap_extra
=`expr "$tap_highest" - "$planned"`
71 if [ "$planned" -gt 1 ] ; then
72 echo "$tap_looks planned $planned tests but ran" \
75 echo "$tap_looks planned $planned test but ran" \
78 elif [ "$failed" -gt 0 ] ; then
79 if [ "$failed" -gt 1 ] ; then
80 echo "$tap_looks failed $failed tests of $planned"
82 echo "$tap_looks failed $failed test of $planned"
84 elif [ "$planned" -gt 1 ] ; then
85 echo "# All $planned tests successful or skipped"
87 echo "# $planned test successful or skipped"
92 # Skip the entire test suite. Should be run instead of plan.
95 if [ -n "$tap_desc" ] ; then
96 echo "1..0 # skip $tap_desc"
103 # ok takes a test description and a command to run and prints success if that
104 # command is successful, false otherwise. The count starts at 1 and is
105 # updated each time ok is printed.
108 if [ -n "$tap_desc" ] ; then
109 tap_desc
=" - $tap_desc"
113 echo ok
"$count$tap_desc"
115 echo not ok
"$count$tap_desc"
116 failed
=`expr $failed + 1`
118 count
=`expr $count + 1`
121 # Skip the next test. Takes the reason why the test is skipped.
123 echo "ok $count # skip $*"
124 count
=`expr $count + 1`
127 # Report the same status on a whole set of tests. Takes the count of tests,
128 # the description, and then the command to run to determine the status.
131 tap_end
=`expr $count + $1`
133 while [ "$tap_i" -lt "$tap_end" ] ; do
135 tap_i
=`expr $tap_i + 1`
139 # Skip a whole set of tests. Takes the count and then the reason for skipping
143 tap_end
=`expr $count + $1`
145 while [ "$tap_i" -lt "$tap_end" ] ; do
147 tap_i
=`expr $tap_i + 1`
151 # Portable variant of printf '%s\n' "$*". In the majority of cases, this
152 # function is slower than printf, because the latter is often implemented
153 # as a builtin command. The value of the variable IFS is ignored.
155 # This macro must not be called via backticks inside double quotes, since this
156 # will result in bizarre escaping behavior and lots of extra backslashes on
164 # Run a program expected to succeed, and print ok if it does and produces the
165 # correct output. Takes the description, expected exit status, the expected
166 # output, the command to run, and then any arguments for that command.
167 # Standard output and standard error are combined when analyzing the output of
170 # If the command may contain system-specific error messages in its output,
171 # add strip_colon_error before the command to post-process its output.
179 tap_output
=`"$@" 2>&1`
181 if [ $tap_status = $tap_w_status ] \
182 && [ x
"$tap_output" = x
"$tap_w_output" ] ; then
185 echo "# saw: ($tap_status) $tap_output"
186 echo "# not: ($tap_w_status) $tap_w_output"
191 # Strip a colon and everything after it off the output of a command, as long
192 # as that colon comes after at least one whitespace character. (This is done
193 # to avoid stripping the name of the program from the start of an error
194 # message.) This is used to remove system-specific error messages (coming
195 # from strerror, for example).
196 strip_colon_error
() {
197 tap_output
=`"$@" 2>&1`
199 tap_output
=`puts "$tap_output" | sed 's/^\([^ ]* [^:]*\):.*/\1/'`
204 # Bail out with an error message.
206 echo 'Bail out!' "$@"
210 # Output a diagnostic on standard error, preceded by the required # mark.
215 # Search for the given file first in $C_TAP_BUILD and then in $C_TAP_SOURCE
216 # and echo the path where the file was found, or the empty string if the file
219 # This macro uses puts, so don't run it using backticks inside double quotes
220 # or bizarre quoting behavior will happen with Solaris sh.
222 if [ -n "$C_TAP_BUILD" ] && [ -f "$C_TAP_BUILD/$1" ] ; then
223 puts
"$C_TAP_BUILD/$1"
224 elif [ -n "$C_TAP_SOURCE" ] && [ -f "$C_TAP_SOURCE/$1" ] ; then
225 puts
"$C_TAP_SOURCE/$1"
231 # Create $C_TAP_BUILD/tmp for use by tests for storing temporary files and
232 # return the path (via standard output).
234 # This macro uses puts, so don't run it using backticks inside double quotes
235 # or bizarre quoting behavior will happen with Solaris sh.
237 if [ -z "$C_TAP_BUILD" ] ; then
240 tap_tmpdir
="$C_TAP_BUILD"/tmp
242 if [ ! -d "$tap_tmpdir" ] ; then
243 mkdir "$tap_tmpdir" || bail
"Error creating $tap_tmpdir"