1 # Simple test harness infrastructure 2 # 3 # Copyright 2005 by Rob Landley 4 5 # This file defines two main functions, "testcmd" and "optional". The 6 # first performs a test, the second enables/disables tests based on 7 # configuration options. 8 9 # The following environment variables enable optional behavior in "testing": 10 # DEBUG - Show every command run by test script. 11 # VERBOSE - Print the diff -u of each failed test case. 12 # If equal to "fail", stop after first failed test. 13 # 14 # The "testcmd" function takes five arguments: 15 # $1) Description to display when running command 16 # $2) Command line arguments to command 17 # $3) Expected result (on stdout) 18 # $4) Data written to file "input" 19 # $5) Data written to stdin 20 # 21 # The "testing" function is like testcmd but takes a complete command line 22 # (I.E. you have to include the command name.) The variable $C is an absolute 23 # path to the command being tested, which can bypass shell builtins. 24 # 25 # The exit value of testcmd is the exit value of the command it ran. 26 # 27 # The environment variable "FAILCOUNT" contains a cumulative total of the 28 # number of failed tests. 29 # 30 # The "optional" function is used to skip certain tests (by setting the 31 # environment variable SKIP), ala: 32 # optional CFG_THINGY 33 # 34 # The "optional" function checks the environment variable "OPTIONFLAGS", 35 # which is either empty (in which case it always clears SKIP) or 36 # else contains a colon-separated list of features (in which case the function 37 # clears SKIP if the flag was found, or sets it to 1 if the flag was not found). 38 39 export FAILCOUNT=0 40 export SKIP= 41 42 # Helper functions 43 44 # Check config to see if option is enabled, set SKIP if not. 45 46 SHOWPASS=PASS 47 SHOWFAIL=FAIL 48 SHOWSKIP=SKIP 49 50 if tty -s <&1 51 then 52 SHOWPASS="$(echo -e "\033[1;32m${SHOWPASS}\033[0m")" 53 SHOWFAIL="$(echo -e "\033[1;31m${SHOWFAIL}\033[0m")" 54 SHOWSKIP="$(echo -e "\033[1;33m${SHOWSKIP}\033[0m")" 55 fi 56 57 optional() 58 { 59 option=`echo "$OPTIONFLAGS" | egrep "(^|:)$1(:|\$)"` 60 # Not set? 61 if [ -z "$1" ] || [ -z "$OPTIONFLAGS" ] || [ ${#option} -ne 0 ] 62 then 63 SKIP="" 64 return 65 fi 66 SKIP=1 67 } 68 69 wrong_args() 70 { 71 if [ $# -ne 5 ] 72 then 73 echo "Test $NAME has the wrong number of arguments ($# $*)" >&2 74 exit 75 fi 76 } 77 78 # The testing function 79 80 testing() 81 { 82 wrong_args "$@" 83 84 NAME="$CMDNAME $1" 85 [ -z "$1" ] && NAME=$2 86 87 [ -n "$DEBUG" ] && set -x 88 89 if [ -n "$SKIP" ] || ( [ -n "$SKIP_HOST" ] && [ -n "$TEST_HOST" ]) 90 then 91 [ ! -z "$VERBOSE" ] && echo "$SHOWSKIP: $NAME" 92 return 0 93 fi 94 95 echo -ne "$3" > expected 96 echo -ne "$4" > input 97 echo -ne "$5" | ${EVAL:-eval} "$2" > actual 98 RETVAL=$? 99 100 # Catch segfaults 101 [ $RETVAL -gt 128 ] && [ $RETVAL -lt 255 ] && 102 echo "exited with signal (or returned $RETVAL)" >> actual 103 104 DIFF="$(diff -au${NOSPACE:+b} expected actual)" 105 if [ ! -z "$DIFF" ] 106 then 107 FAILCOUNT=$[$FAILCOUNT+1] 108 echo "$SHOWFAIL: $NAME" 109 if [ -n "$VERBOSE" ] 110 then 111 [ ! -z "$4" ] && echo "echo -ne \"$4\" > input" 112 echo "echo -ne '$5' |$EVAL $2" 113 echo "$DIFF" 114 [ "$VERBOSE" == fail ] && exit 1 115 fi 116 else 117 echo "$SHOWPASS: $NAME" 118 fi 119 rm -f input expected actual 120 121 [ -n "$DEBUG" ] && set +x 122 123 return 0 124 } 125 126 testcmd() 127 { 128 wrong_args "$@" 129 130 testing "$1" "$C $2" "$3" "$4" "$5" 131 } 132 133 # Recursively grab an executable and all the libraries needed to run it. 134 # Source paths beginning with / will be copied into destpath, otherwise 135 # the file is assumed to already be there and only its library dependencies 136 # are copied. 137 138 mkchroot() 139 { 140 [ $# -lt 2 ] && return 141 142 echo -n . 143 144 dest=$1 145 shift 146 for i in "$@" 147 do 148 [ "${i:0:1}" == "/" ] || i=$(which $i) 149 [ -f "$dest/$i" ] && continue 150 if [ -e "$i" ] 151 then 152 d=`echo "$i" | grep -o '.*/'` && 153 mkdir -p "$dest/$d" && 154 cat "$i" > "$dest/$i" && 155 chmod +x "$dest/$i" 156 else 157 echo "Not found: $i" 158 fi 159 mkchroot "$dest" $(ldd "$i" | egrep -o '/.* ') 160 done 161 } 162 163 # Set up a chroot environment and run commands within it. 164 # Needed commands listed on command line 165 # Script fed to stdin. 166 167 dochroot() 168 { 169 mkdir tmpdir4chroot 170 mount -t ramfs tmpdir4chroot tmpdir4chroot 171 mkdir -p tmpdir4chroot/{etc,sys,proc,tmp,dev} 172 cp -L testing.sh tmpdir4chroot 173 174 # Copy utilities from command line arguments 175 176 echo -n "Setup chroot" 177 mkchroot tmpdir4chroot $* 178 echo 179 180 mknod tmpdir4chroot/dev/tty c 5 0 181 mknod tmpdir4chroot/dev/null c 1 3 182 mknod tmpdir4chroot/dev/zero c 1 5 183 184 # Copy script from stdin 185 186 cat > tmpdir4chroot/test.sh 187 chmod +x tmpdir4chroot/test.sh 188 chroot tmpdir4chroot /test.sh 189 umount -l tmpdir4chroot 190 rmdir tmpdir4chroot 191 } 192 193