blob: ccfebc805527051250ebb85fbd18560cc5a311ee
1 | # Simple test harness infrastructure for BusyBox |
2 | # |
3 | # Copyright 2005 by Rob Landley |
4 | # |
5 | # License is GPLv2, see LICENSE in the busybox tarball for full license text. |
6 | |
7 | # This file defines two functions, "testing" and "optional" |
8 | # and a couple more... |
9 | |
10 | # The following environment variables may be set to enable optional behavior |
11 | # in "testing": |
12 | # VERBOSE - Print the diff -u of each failed test case. |
13 | # DEBUG - Enable command tracing. |
14 | # SKIP - do not perform this test (this is set by "optional") |
15 | # |
16 | # The "testing" function takes five arguments: |
17 | # $1) Test description |
18 | # $2) Command(s) to run. May have pipes, redirects, etc |
19 | # $3) Expected result on stdout |
20 | # $4) Data to be written to file "input" |
21 | # $5) Data to be written to stdin |
22 | # |
23 | # The exit value of testing is the exit value of $2 it ran. |
24 | # |
25 | # The environment variable "FAILCOUNT" contains a cumulative total of the |
26 | # number of failed tests. |
27 | |
28 | # The "optional" function is used to skip certain tests, ala: |
29 | # optional FEATURE_THINGY |
30 | # |
31 | # The "optional" function checks the environment variable "OPTIONFLAGS", |
32 | # which is either empty (in which case it always clears SKIP) or |
33 | # else contains a colon-separated list of features (in which case the function |
34 | # clears SKIP if the flag was found, or sets it to 1 if the flag was not found). |
35 | |
36 | export FAILCOUNT=0 |
37 | export SKIP= |
38 | |
39 | # Android Specific |
40 | |
41 | if [ ! -x /bin ]; then |
42 | mount -o remount,rw / |
43 | ln -s /system/xbin /bin |
44 | fi |
45 | |
46 | # Helper for helpers. Oh my... |
47 | |
48 | test x"$ECHO" != x"" || { |
49 | ECHO="echo" |
50 | test x"`echo -ne`" = x"" || { |
51 | # Compile and use a replacement 'echo' which understands -e -n |
52 | ECHO="$PWD/echo-ne" |
53 | test -x "$ECHO" || { |
54 | gcc -Os -o "$ECHO" ../scripts/echo.c || exit 1 |
55 | } |
56 | } |
57 | export ECHO |
58 | } |
59 | |
60 | # Helper functions |
61 | |
62 | optional() |
63 | { |
64 | SKIP= |
65 | while test "$1"; do |
66 | case "${OPTIONFLAGS}" in |
67 | *:$1:*) ;; |
68 | *) SKIP=1; return ;; |
69 | esac |
70 | shift |
71 | done |
72 | } |
73 | |
74 | # The testing function |
75 | |
76 | testing() |
77 | { |
78 | NAME="$1" |
79 | [ -n "$1" ] || NAME="$2" |
80 | |
81 | if [ $# -ne 5 ] |
82 | then |
83 | echo "Test $NAME has wrong number of arguments: $# (must be 5)" >&2 |
84 | exit 1 |
85 | fi |
86 | |
87 | [ -z "$DEBUG" ] || set -x |
88 | |
89 | if [ -n "$SKIP" ] |
90 | then |
91 | echo "SKIPPED: $NAME" |
92 | return 0 |
93 | fi |
94 | |
95 | $ECHO -ne "$3" > expected |
96 | $ECHO -ne "$4" > input |
97 | [ -z "$VERBOSE" ] || echo ====================== |
98 | [ -z "$VERBOSE" ] || echo "echo -ne '$4' >input" |
99 | [ -z "$VERBOSE" ] || echo "echo -ne '$5' | $2" |
100 | $ECHO -ne "$5" | eval "$2" > actual |
101 | RETVAL=$? |
102 | |
103 | if cmp expected actual >/dev/null 2>/dev/null |
104 | then |
105 | echo "PASS: $NAME" |
106 | else |
107 | FAILCOUNT=$(($FAILCOUNT + 1)) |
108 | echo "FAIL: $NAME" |
109 | [ -z "$VERBOSE" ] || diff -u expected actual |
110 | fi |
111 | rm -f input expected actual |
112 | |
113 | [ -z "$DEBUG" ] || set +x |
114 | |
115 | return $RETVAL |
116 | } |
117 | |
118 | # Recursively grab an executable and all the libraries needed to run it. |
119 | # Source paths beginning with / will be copied into destpath, otherwise |
120 | # the file is assumed to already be there and only its library dependencies |
121 | # are copied. |
122 | |
123 | mkchroot() |
124 | { |
125 | [ $# -lt 2 ] && return |
126 | |
127 | $ECHO -n . |
128 | |
129 | dest=$1 |
130 | shift |
131 | for i in "$@" |
132 | do |
133 | #bashism: [ "${i:0:1}" == "/" ] || i=$(which $i) |
134 | i=$(which $i) # no-op for /bin/prog |
135 | [ -f "$dest/$i" ] && continue |
136 | if [ -e "$i" ] |
137 | then |
138 | d=`echo "$i" | grep -o '.*/'` && |
139 | mkdir -p "$dest/$d" && |
140 | cat "$i" > "$dest/$i" && |
141 | chmod +x "$dest/$i" |
142 | else |
143 | echo "Not found: $i" |
144 | fi |
145 | mkchroot "$dest" $(ldd "$i" | egrep -o '/.* ') |
146 | done |
147 | } |
148 | |
149 | # Set up a chroot environment and run commands within it. |
150 | # Needed commands listed on command line |
151 | # Script fed to stdin. |
152 | |
153 | dochroot() |
154 | { |
155 | mkdir tmpdir4chroot |
156 | mount -t ramfs tmpdir4chroot tmpdir4chroot |
157 | mkdir -p tmpdir4chroot/{etc,sys,proc,tmp,dev} |
158 | cp -L testing.sh tmpdir4chroot |
159 | |
160 | # Copy utilities from command line arguments |
161 | |
162 | $ECHO -n "Setup chroot" |
163 | mkchroot tmpdir4chroot $* |
164 | echo |
165 | |
166 | mknod tmpdir4chroot/dev/tty c 5 0 |
167 | mknod tmpdir4chroot/dev/null c 1 3 |
168 | mknod tmpdir4chroot/dev/zero c 1 5 |
169 | |
170 | # Copy script from stdin |
171 | |
172 | cat > tmpdir4chroot/test.sh |
173 | chmod +x tmpdir4chroot/test.sh |
174 | chroot tmpdir4chroot /test.sh |
175 | umount -l tmpdir4chroot |
176 | rmdir tmpdir4chroot |
177 | } |
178 |