diff options
Diffstat (limited to 'scripts/runtest.sh')
-rw-r--r-- | scripts/runtest.sh | 224 |
1 files changed, 76 insertions, 148 deletions
diff --git a/scripts/runtest.sh b/scripts/runtest.sh index 5a647677..ce6e0fd0 100644 --- a/scripts/runtest.sh +++ b/scripts/runtest.sh @@ -2,9 +2,7 @@ # # Copyright 2005 by Rob Landley -# This file defines two main functions, "testcmd" and "optional". The -# first performs a test, the second enables/disables tests based on -# configuration options. +# This file defines three main functions: "testing", "testcmd", and "txpect". # The following environment variables enable optional behavior in "testing": # DEBUG - Show every command run by test script. @@ -30,26 +28,13 @@ # The environment variable "FAILCOUNT" contains a cumulative total of the # number of failed tests. # -# The "optional" function is used to skip certain tests (by setting the -# environment variable SKIP), ala: -# optional CFG_THINGY +# The environment variable "SKIP" says how many upcoming tests to skip, +# defaulting to 0 and counting down when set to a higher number. # -# The "optional" function checks the environment variable "OPTIONFLAGS", -# which is either empty (in which case it always clears SKIP) or -# else contains a colon-separated list of features (in which case the function -# clears SKIP if the flag was found, or sets it to 1 if the flag was not found). - -export FAILCOUNT=0 -export SKIP= - -# Helper functions - -# Check config to see if option is enabled, set SKIP if not. - -SHOWPASS=PASS -SHOWFAIL=FAIL -SHOWSKIP=SKIP +# Function "optional" enables/disables tests based on configuration options. +export FAILCOUNT=0 SKIP=0 +: ${SHOWPASS:=PASS} ${SHOWFAIL:=FAIL} ${SHOWSKIP:=SKIP} if tty -s <&1 then SHOWPASS="$(echo -e "\033[1;32m${SHOWPASS}\033[0m")" @@ -57,34 +42,64 @@ then SHOWSKIP="$(echo -e "\033[1;33m${SHOWSKIP}\033[0m")" fi -optional() +# Helper functions + +# Check if VERBOSE= contains a given string. (This allows combining.) +verbose_has() { - option=`printf %s "$OPTIONFLAGS" | egrep "(^|:)$1(:|\$)"` - # Not set? - if [ -z "$1" ] || [ -z "$OPTIONFLAGS" ] || [ ${#option} -ne 0 ] + [ "${VERBOSE/$1/}" != "$VERBOSE" ] +} + +wrong_args() +{ + if [ $# -ne 5 ] then - unset SKIP - return + printf "%s\n" "Test $NAME has the wrong number of arguments ($# $*)" >&2 + exit fi - SKIP=1 } -verbose_has() +# Announce success +do_pass() { - [ "${VERBOSE/$1/}" != "$VERBOSE" ] + verbose_has nopass || printf "%s\n" "$SHOWPASS: $NAME" } +# Announce failure and handle fallout for txpect +do_fail() +{ + FAILCOUNT=$(($FAILCOUNT+1)) + printf "%s\n" "$SHOWFAIL: $NAME" + if [ ! -z "$CASE" ] + then + echo "Expected '$CASE'" + echo "Got '$A'" + fi + ! verbose_has all && exit 1 +} + +# Functions test files call directly + +# Set SKIP high if option not enabled in $OPTIONFLAGS (unless OPTIONFLAGS blank) +optional() +{ + [ -n "$OPTIONFLAGS" ] && [ "$OPTIONFLAGS" == "${OPTIONFLAGS/:$1:/}" ] && + SKIP=99999 || SKIP=0 +} + +# Evalute command line and skip next test when false skipnot() { if verbose_has quiet then - eval "$@" 2>/dev/null + eval "$@" >/dev/null 2>&1 else eval "$@" fi - [ $? -eq 0 ] || SKIPNEXT=1 + [ $? -eq 0 ] || { ((++SKIP)); return 1; } } +# Skip this test (rest of command line) when not running toybox. toyonly() { IS_TOYBOX="$("$C" --version 2>/dev/null)" @@ -93,61 +108,40 @@ toyonly() case "$IS_TOYBOX" in toybox*) ;; This\ is\ not\ GNU*) ;; - *) SKIPNEXT=1 ;; + *) [ $SKIP -eq 0 ] && ((++SKIP)) ;; esac "$@" } -wrong_args() -{ - if [ $# -ne 5 ] - then - printf "%s\n" "Test $NAME has the wrong number of arguments ($# $*)" >&2 - exit - fi -} - -# Announce success -do_pass() -{ - ! verbose_has nopass && printf "%s\n" "$SHOWPASS: $NAME" -} - -# The testing function - +# Takes five arguments: "name" "command" "result" "infile" "stdin" testing() { - NAME="$CMDNAME $1" wrong_args "$@" - [ -z "$1" ] && NAME=$2 + [ -z "$1" ] && NAME="$2" || NAME="$1" + [ "${NAME#$CMDNAME }" == "$NAME" ] && NAME="$CMDNAME $1" [ -n "$DEBUG" ] && set -x - if [ -n "$SKIP" -o -n "$SKIP_HOST" -a -n "$TEST_HOST" -o -n "$SKIPNEXT" ] + if [ "$SKIP" -gt 0 ] then - verbose_has quiet && printf "%s\n" "$SHOWSKIP: $NAME" - unset SKIPNEXT + verbose_has quiet || printf "%s\n" "$SHOWSKIP: $NAME" + ((--SKIP)) + return 0 fi - echo -ne "$3" > expected + echo -ne "$3" > ../expected [ ! -z "$4" ] && echo -ne "$4" > input || rm -f input - echo -ne "$5" | ${EVAL:-eval --} "$2" > actual + echo -ne "$5" | ${EVAL:-eval --} "$2" > ../actual RETVAL=$? # Catch segfaults - [ $RETVAL -gt 128 ] && [ $RETVAL -lt 255 ] && + [ $RETVAL -gt 128 ] && echo "exited with signal (or returned $RETVAL)" >> actual - DIFF="$(diff -au${NOSPACE:+w} expected actual)" - if [ -n "$DIFF" ] - then - FAILCOUNT=$(($FAILCOUNT+1)) - printf "%s\n" "$SHOWFAIL: $NAME" - else - ! verbose_has nopass && printf "%s\n" "$SHOWPASS: $NAME" - fi + DIFF="$(cd ..; diff -au${NOSPACE:+w} expected actual)" + [ -z "$DIFF" ] && do_pass || VERBOSE=all do_fail if ! verbose_has quiet && { [ -n "$DIFF" ] || verbose_has spam; } then [ ! -z "$4" ] && printf "%s\n" "echo -ne \"$4\" > input" @@ -156,34 +150,22 @@ testing() fi [ -n "$DIFF" ] && ! verbose_has all && exit 1 - rm -f input expected actual + rm -f input ../expected ../actual [ -n "$DEBUG" ] && set +x return 0 } +# Wrapper for "testing", adds command name being tested to start of command line testcmd() { wrong_args "$@" - X="$1" - [ -z "$X" ] && X="$CMDNAME $2" - testing "$X" "\"$C\" $2" "$3" "$4" "$5" + testing "${1:-$CMDNAME $2}" "\"$C\" $2" "$3" "$4" "$5" } -# Announce failure and handle fallout for txpect -do_fail() -{ - FAILCOUNT=$(($FAILCOUNT+1)) - printf "%s\n" "$SHOWFAIL: $NAME" - if [ ! -z "$CASE" ] - then - echo "Expected '$CASE'" - echo "Got '$A'" - fi - ! verbose_has all && exit 1 -} +# Simple implementation of "expect" written in shell. # txpect NAME COMMAND [I/O/E/Xstring]... # Run COMMAND and interact with it: send I strings to input, read O or E @@ -191,7 +173,7 @@ do_fail() # X means close stdin/stdout/stderr and match return code (blank means nonzero) txpect() { - local NAME CASE VERBOSITY LEN A B X O + local NAME CASE VERBOSITY LEN PID A B X O # Run command with redirection through fifos NAME="$CMDNAME $1" @@ -204,13 +186,14 @@ txpect() return fi eval "$2" <in-$$ >out-$$ 2>err-$$ & + PID=$! shift 2 : {IN}>in-$$ {OUT}<out-$$ {ERR}<err-$$ && rm in-$$ out-$$ err-$$ [ $? -ne 0 ] && { do_fail;return;} # Loop through challenge/response pairs, with 2 second timeout - while [ $# -gt 0 ] + while [ $# -gt 0 -a -n "$PID" ] do VERBOSITY="$VERBOSITY"$'\n'"$1" LEN=$((${#1}-1)) CASE="$1" A= B= @@ -234,29 +217,33 @@ txpect() then [ -z "$A" -o "$X" -ne 0 ] && { do_fail;break;} else - if [ ${1::1} == 'R' ] && [[ "$A" =~ "${1:2}" ]]; then true + if [ ${1::1} == 'R' ] && grep -q "${1:2}" <<< "$A"; then true elif [ ${1::1} != 'R' ] && [ "$A" == "${1:1}" ]; then true else # Append the rest of the output if there is any. read -t.1 B <&$O A="$A$B" read -t.1 -rN 9999 B<&$ERR - do_fail;break; + do_fail + break fi fi ;; # close I/O and wait for exit X) - exec {IN}<&- {OUT}<&- {ERR}<&- - wait + exec {IN}<&- + wait $PID A=$? + exec {OUT}<&- {ERR}<&- if [ -z "$LEN" ] then [ $A -eq 0 ] && { do_fail;break;} # any error else [ $A != "${1:1}" ] && { do_fail;break;} # specific value fi + do_pass + return ;; *) do_fail; break ;; esac @@ -270,65 +257,6 @@ txpect() do_pass else ! verbose_has quiet && echo "$VERBOSITY" >&2 + do_fail fi } - -# Recursively grab an executable and all the libraries needed to run it. -# Source paths beginning with / will be copied into destpath, otherwise -# the file is assumed to already be there and only its library dependencies -# are copied. - -mkchroot() -{ - [ $# -lt 2 ] && return - - echo -n . - - dest=$1 - shift - for i in "$@" - do - [ "${i:0:1}" == "/" ] || i=$(which $i) - [ -f "$dest/$i" ] && continue - if [ -e "$i" ] - then - d=`echo "$i" | grep -o '.*/'` && - mkdir -p "$dest/$d" && - cat "$i" > "$dest/$i" && - chmod +x "$dest/$i" - else - echo "Not found: $i" - fi - mkchroot "$dest" $(ldd "$i" | egrep -o '/.* ') - done -} - -# Set up a chroot environment and run commands within it. -# Needed commands listed on command line -# Script fed to stdin. - -dochroot() -{ - mkdir tmpdir4chroot - mount -t ramfs tmpdir4chroot tmpdir4chroot - mkdir -p tmpdir4chroot/{etc,sys,proc,tmp,dev} - cp -L testing.sh tmpdir4chroot - - # Copy utilities from command line arguments - - echo -n "Setup chroot" - mkchroot tmpdir4chroot $* - echo - - mknod tmpdir4chroot/dev/tty c 5 0 - mknod tmpdir4chroot/dev/null c 1 3 - mknod tmpdir4chroot/dev/zero c 1 5 - - # Copy script from stdin - - cat > tmpdir4chroot/test.sh - chmod +x tmpdir4chroot/test.sh - chroot tmpdir4chroot /test.sh - umount -l tmpdir4chroot - rmdir tmpdir4chroot -} |