blob: e07c6a2eec71570d69958207832f1d417dd7ddfb [file] [log] [blame]
Rob Landley2c226852007-11-15 18:30:30 -06001# Simple test harness infrastructure
Rob Landley5f1d7e22007-02-18 14:23:10 -05002#
3# Copyright 2005 by Rob Landley
4
Rob Landley216e4da2017-04-04 18:13:51 -05005# 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.
Rob Landley5f1d7e22007-02-18 14:23:10 -05008
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.
Rob Landley50b82972014-08-30 13:03:40 -050012# If equal to "fail", stop after first failed test.
Rob Landley5f1d7e22007-02-18 14:23:10 -050013#
Rob Landley216e4da2017-04-04 18:13:51 -050014# The "testcmd" function takes five arguments:
Rob Landley5f1d7e22007-02-18 14:23:10 -050015# $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#
Rob Landley216e4da2017-04-04 18:13:51 -050021# 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.
Rob Landley5f1d7e22007-02-18 14:23:10 -050026#
27# The environment variable "FAILCOUNT" contains a cumulative total of the
28# number of failed tests.
Rob Landley216e4da2017-04-04 18:13:51 -050029#
30# The "optional" function is used to skip certain tests (by setting the
31# environment variable SKIP), ala:
32# optional CFG_THINGY
Rob Landley5f1d7e22007-02-18 14:23:10 -050033#
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
39export FAILCOUNT=0
40export SKIP=
41
42# Helper functions
43
Rob Landley9201a012012-02-02 07:29:09 -060044# Check config to see if option is enabled, set SKIP if not.
45
Rob Landley9dbcee42014-11-14 16:44:00 -060046SHOWPASS=PASS
47SHOWFAIL=FAIL
48SHOWSKIP=SKIP
49
50if tty -s <&1
51then
Rob Landley8cbde4b2016-02-02 14:56:27 -060052 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")"
Rob Landley9dbcee42014-11-14 16:44:00 -060055fi
56
Rob Landley5f1d7e22007-02-18 14:23:10 -050057optional()
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
Rob Landley216e4da2017-04-04 18:13:51 -050069wrong_args()
Rob Landley5f1d7e22007-02-18 14:23:10 -050070{
Rob Landley5f1d7e22007-02-18 14:23:10 -050071 if [ $# -ne 5 ]
72 then
73 echo "Test $NAME has the wrong number of arguments ($# $*)" >&2
74 exit
75 fi
Rob Landley216e4da2017-04-04 18:13:51 -050076}
77
78# The testing function
79
80testing()
81{
82 wrong_args "$@"
83
84 NAME="$CMDNAME $1"
85 [ -z "$1" ] && NAME=$2
Rob Landley5f1d7e22007-02-18 14:23:10 -050086
87 [ -n "$DEBUG" ] && set -x
88
Rob Landley9dbcee42014-11-14 16:44:00 -060089 if [ -n "$SKIP" ] || ( [ -n "$SKIP_HOST" ] && [ -n "$TEST_HOST" ])
Rob Landley5f1d7e22007-02-18 14:23:10 -050090 then
Rob Landley9dbcee42014-11-14 16:44:00 -060091 [ ! -z "$VERBOSE" ] && echo "$SHOWSKIP: $NAME"
Rob Landley5f1d7e22007-02-18 14:23:10 -050092 return 0
93 fi
94
95 echo -ne "$3" > expected
96 echo -ne "$4" > input
Rob Landley4b026672016-04-22 19:08:56 -050097 echo -ne "$5" | ${EVAL:-eval} "$2" > actual
Rob Landley5f1d7e22007-02-18 14:23:10 -050098 RETVAL=$?
99
Rob Landley325e02e2015-06-25 17:55:54 -0500100 # Catch segfaults
101 [ $RETVAL -gt 128 ] && [ $RETVAL -lt 255 ] &&
102 echo "exited with signal (or returned $RETVAL)" >> actual
Rob Landley216e4da2017-04-04 18:13:51 -0500103
Rob Landleyfcbf55a2016-06-30 10:39:23 -0500104 DIFF="$(diff -au${NOSPACE:+b} expected actual)"
105 if [ ! -z "$DIFF" ]
Rob Landley5f1d7e22007-02-18 14:23:10 -0500106 then
107 FAILCOUNT=$[$FAILCOUNT+1]
Rob Landley9dbcee42014-11-14 16:44:00 -0600108 echo "$SHOWFAIL: $NAME"
Rob Landley273f2782007-12-16 17:56:31 -0600109 if [ -n "$VERBOSE" ]
110 then
Rob Landley9dbcee42014-11-14 16:44:00 -0600111 [ ! -z "$4" ] && echo "echo -ne \"$4\" > input"
Rob Landley4b026672016-04-22 19:08:56 -0500112 echo "echo -ne '$5' |$EVAL $2"
Rob Landleyfcbf55a2016-06-30 10:39:23 -0500113 echo "$DIFF"
Rob Landley50b82972014-08-30 13:03:40 -0500114 [ "$VERBOSE" == fail ] && exit 1
Rob Landley273f2782007-12-16 17:56:31 -0600115 fi
Rob Landley5f1d7e22007-02-18 14:23:10 -0500116 else
Rob Landley9dbcee42014-11-14 16:44:00 -0600117 echo "$SHOWPASS: $NAME"
Rob Landley5f1d7e22007-02-18 14:23:10 -0500118 fi
119 rm -f input expected actual
120
121 [ -n "$DEBUG" ] && set +x
122
Rob Landley8361fbd2016-09-04 19:13:31 -0500123 return 0
Rob Landley5f1d7e22007-02-18 14:23:10 -0500124}
125
Rob Landley216e4da2017-04-04 18:13:51 -0500126testcmd()
127{
128 wrong_args "$@"
129
130 testing "$1" "$C $2" "$3" "$4" "$5"
131}
132
Rob Landley5f1d7e22007-02-18 14:23:10 -0500133# 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
Rob Landley387edf52014-09-20 13:09:14 -0500138mkchroot()
Rob Landley5f1d7e22007-02-18 14:23:10 -0500139{
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
Rob Landley387edf52014-09-20 13:09:14 -0500167dochroot()
Rob Landley5f1d7e22007-02-18 14:23:10 -0500168{
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