]> eyrie.org Git - kerberos/krb5-strength.git/blobdiff - tests/tap/libtap.sh
Declare fast forward from 3.1-2
[kerberos/krb5-strength.git] / tests / tap / libtap.sh
index 322f95c0072fa3f5ce11632a4e0ae13f9f60f04f..1827a689e380ee9af32e4c51407c98af1d97f334 100644 (file)
@@ -1,10 +1,38 @@
 # Shell function library for test cases.
 #
-# Written by Russ Allbery <rra@stanford.edu>
-# Copyright 2009 Russ Allbery <rra@stanford.edu>
-# Copyright 2006, 2007, 2008 Board of Trustees, Leland Stanford Jr. University
+# Note that while many of the functions in this library could benefit from
+# using "local" to avoid possibly hammering global variables, Solaris /bin/sh
+# doesn't support local and this library aspires to be portable to Solaris
+# Bourne shell.  Instead, all private variables are prefixed with "tap_".
 #
-# See LICENSE for licensing terms.
+# This file provides a TAP-compatible shell function library useful for
+# writing test cases.  It is part of C TAP Harness, which can be found at
+# <https://www.eyrie.org/~eagle/software/c-tap-harness/>.
+#
+# Written by Russ Allbery <eagle@eyrie.org>
+# Copyright 2009-2012, 2016 Russ Allbery <eagle@eyrie.org>
+# Copyright 2006-2008, 2013
+#     The Board of Trustees of the Leland Stanford Junior University
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to
+# deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+# sell copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+# IN THE SOFTWARE.
+#
+# SPDX-License-Identifier: MIT
 
 # Print out the number of test cases we expect to run.
 plan () {
@@ -15,31 +43,45 @@ plan () {
     trap finish 0
 }
 
+# Prepare for lazy planning.
+plan_lazy () {
+    count=1
+    planned=0
+    failed=0
+    trap finish 0
+}
+
 # Report the test status on exit.
 finish () {
-    local highest looks
-    highest=`expr "$count" - 1`
-    looks='# Looks like you'
+    tap_highest=`expr "$count" - 1`
+    if [ "$planned" = 0 ] ; then
+        echo "1..$tap_highest"
+        planned="$tap_highest"
+    fi
+    tap_looks='# Looks like you'
     if [ "$planned" -gt 0 ] ; then
-        if [ "$planned" -gt "$highest" ] ; then
+        if [ "$planned" -gt "$tap_highest" ] ; then
             if [ "$planned" -gt 1 ] ; then
-                echo "$looks planned $planned tests but only ran $highest"
+                echo "$tap_looks planned $planned tests but only ran" \
+                    "$tap_highest"
             else
-                echo "$looks planned $planned test but only ran $highest"
+                echo "$tap_looks planned $planned test but only ran" \
+                    "$tap_highest"
             fi
-        elif [ "$planned" -lt "$highest" ] ; then
-            local extra
-            extra=`expr "$highest" - "$planned"`
+        elif [ "$planned" -lt "$tap_highest" ] ; then
+            tap_extra=`expr "$tap_highest" - "$planned"`
             if [ "$planned" -gt 1 ] ; then
-                echo "$looks planned $planned tests but ran $extra extra"
+                echo "$tap_looks planned $planned tests but ran" \
+                    "$tap_extra extra"
             else
-                echo "$looks planned $planned test but ran $extra extra"
+                echo "$tap_looks planned $planned test but ran" \
+                    "$tap_extra extra"
             fi
         elif [ "$failed" -gt 0 ] ; then
             if [ "$failed" -gt 1 ] ; then
-                echo "$looks failed $failed tests of $planned"
+                echo "$tap_looks failed $failed tests of $planned"
             else
-                echo "$looks failed $failed test of $planned"
+                echo "$tap_looks failed $failed test of $planned"
             fi
         elif [ "$planned" -gt 1 ] ; then
             echo "# All $planned tests successful or skipped"
@@ -51,10 +93,9 @@ finish () {
 
 # Skip the entire test suite.  Should be run instead of plan.
 skip_all () {
-    local desc
-    desc="$1"
-    if [ -n "$desc" ] ; then
-        echo "1..0 # skip $desc"
+    tap_desc="$1"
+    if [ -n "$tap_desc" ] ; then
+        echo "1..0 # skip $tap_desc"
     else
         echo "1..0 # skip"
     fi
@@ -65,16 +106,15 @@ skip_all () {
 # command is successful, false otherwise.  The count starts at 1 and is
 # updated each time ok is printed.
 ok () {
-    local desc
-    desc="$1"
-    if [ -n "$desc" ] ; then
-        desc=" - $desc"
+    tap_desc="$1"
+    if [ -n "$tap_desc" ] ; then
+        tap_desc=" - $tap_desc"
     fi
     shift
     if "$@" ; then
-        echo ok $count$desc
+        echo ok "$count$tap_desc"
     else
-        echo not ok $count$desc
+        echo not ok "$count$tap_desc"
         failed=`expr $failed + 1`
     fi
     count=`expr $count + 1`
@@ -89,60 +129,120 @@ skip () {
 # Report the same status on a whole set of tests.  Takes the count of tests,
 # the description, and then the command to run to determine the status.
 ok_block () {
-    local end i desc
-    i=$count
-    end=`expr $count + $1`
-    shift
-    desc="$1"
+    tap_i=$count
+    tap_end=`expr $count + $1`
     shift
-    while [ "$i" -lt "$end" ] ; do
-        ok "$desc" "$@"
-        i=`expr $i + 1`
+    while [ "$tap_i" -lt "$tap_end" ] ; do
+        ok "$@"
+        tap_i=`expr $tap_i + 1`
     done
 }
 
 # Skip a whole set of tests.  Takes the count and then the reason for skipping
 # the test.
 skip_block () {
-    local i end
-    i=$count
-    end=`expr $count + $1`
+    tap_i=$count
+    tap_end=`expr $count + $1`
     shift
-    while [ "$i" -lt "$end" ] ; do
+    while [ "$tap_i" -lt "$tap_end" ] ; do
         skip "$@"
-        i=`expr $i + 1`
+        tap_i=`expr $tap_i + 1`
     done
 }
 
+# Portable variant of printf '%s\n' "$*".  In the majority of cases, this
+# function is slower than printf, because the latter is often implemented
+# as a builtin command.  The value of the variable IFS is ignored.
+#
+# This macro must not be called via backticks inside double quotes, since this
+# will result in bizarre escaping behavior and lots of extra backslashes on
+# Solaris.
+puts () {
+    cat << EOH
+$@
+EOH
+}
+
 # Run a program expected to succeed, and print ok if it does and produces the
 # correct output.  Takes the description, expected exit status, the expected
-# output, the command to run, and then any arguments for that command.  Strip
-# a colon and everything after it off the output if the expected status is
-# non-zero, since this is probably a system-specific error message.
+# output, the command to run, and then any arguments for that command.
+# Standard output and standard error are combined when analyzing the output of
+# the command.
+#
+# If the command may contain system-specific error messages in its output,
+# add strip_colon_error before the command to post-process its output.
 ok_program () {
-    local desc w_status w_output output status
-    desc="$1"
+    tap_desc="$1"
     shift
-    w_status="$1"
+    tap_w_status="$1"
     shift
-    w_output="$1"
+    tap_w_output="$1"
     shift
-    output=`"$@" 2>&1`
-    status=$?
-    if [ "$w_status" -ne 0 ] ; then
-        output=`echo "$output" | sed 's/^\([^:]*\):.*/\1/'`
-    fi
-    if [ $status = $w_status ] && [ x"$output" = x"$w_output" ] ; then
-        ok "$desc" true
+    tap_output=`"$@" 2>&1`
+    tap_status=$?
+    if [ $tap_status = $tap_w_status ] \
+        && [ x"$tap_output" = x"$tap_w_output" ] ; then
+        ok "$tap_desc" true
     else
-        echo "#  saw: ($status) $output"
-        echo "#  not: ($w_status) $w_output"
-        ok "$desc" false
+        echo "#  saw: ($tap_status) $tap_output"
+        echo "#  not: ($tap_w_status) $tap_w_output"
+        ok "$tap_desc" false
     fi
 }
 
+# Strip a colon and everything after it off the output of a command, as long
+# as that colon comes after at least one whitespace character.  (This is done
+# to avoid stripping the name of the program from the start of an error
+# message.)  This is used to remove system-specific error messages (coming
+# from strerror, for example).
+strip_colon_error() {
+    tap_output=`"$@" 2>&1`
+    tap_status=$?
+    tap_output=`puts "$tap_output" | sed 's/^\([^ ]* [^:]*\):.*/\1/'`
+    puts "$tap_output"
+    return $tap_status
+}
+
 # Bail out with an error message.
 bail () {
     echo 'Bail out!' "$@"
-    exit 1
+    exit 255
+}
+
+# Output a diagnostic on standard error, preceded by the required # mark.
+diag () {
+    echo '#' "$@"
+}
+
+# Search for the given file first in $C_TAP_BUILD and then in $C_TAP_SOURCE
+# and echo the path where the file was found, or the empty string if the file
+# wasn't found.
+#
+# This macro uses puts, so don't run it using backticks inside double quotes
+# or bizarre quoting behavior will happen with Solaris sh.
+test_file_path () {
+    if [ -n "$C_TAP_BUILD" ] && [ -f "$C_TAP_BUILD/$1" ] ; then
+        puts "$C_TAP_BUILD/$1"
+    elif [ -n "$C_TAP_SOURCE" ] && [ -f "$C_TAP_SOURCE/$1" ] ; then
+        puts "$C_TAP_SOURCE/$1"
+    else
+        echo ''
+    fi
+}
+
+# Create $C_TAP_BUILD/tmp for use by tests for storing temporary files and
+# return the path (via standard output).
+#
+# This macro uses puts, so don't run it using backticks inside double quotes
+# or bizarre quoting behavior will happen with Solaris sh.
+test_tmpdir () {
+    if [ -z "$C_TAP_BUILD" ] ; then
+        tap_tmpdir="./tmp"
+    else
+        tap_tmpdir="$C_TAP_BUILD"/tmp
+    fi
+    if [ ! -d "$tap_tmpdir" ] ; then
+        mkdir "$tap_tmpdir" || bail "Error creating $tap_tmpdir"
+    fi
+    puts "$tap_tmpdir"
 }