-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtests
executable file
·213 lines (203 loc) · 4.37 KB
/
tests
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
#! /bin/sh
set -e
target=diffprep
cleanup() {
local rc; rc=$?
test -n "$TD" && rm -r -- "$TD"
test $rc = 0 || echo "$0 failed!" >& 2
}
TD=
trap cleanup 0
trap 'exit $?' INT TERM QUIT HUP
redir_from() {
local source; source=$1; shift
"$@" < "$source"
}
redir_to() {
local target; target=$1; shift
"$@" > "$target"
}
launch() {
local launched_cmd launched_pid_varname
launched_pid_varname=$1; shift
launched_cmd=$*
eval $launched_pid_varname'_cmd=$launched_cmd'
"$@" &
eval $launched_pid_varname'=$!'
}
say() {
printf '%s\n' "$*" >& 2
}
die() {
say "$*"
false || exit
}
run() {
"$@" && return
{
echo "There was a problem executing the following command:"
echo ">>>$*<<<"
$examine && echo "Examine, then 'exit' to quit."
} >& 2
$examine && xterm -e "$SHELL" -l
false || exit
}
# The last character in each of the space-separated groups needs to be the
# option character for converting back the transformed test case into the
# original. The remaining characters are the (clustered) option characters for
# transforming the original.
tests='bB xX baB xaX wW cC wtW ctC'
single_test='cC'
tests_overridden=false
verbose=true
args_are_generators=false
while getopts qt:g opt
do
case $opt in
g) args_are_generators=true;;
q) verbose=false;;
t) tests=$OPTARG; tests_overridden=true;;
*) false || exit
esac
done
shift `expr $OPTIND - 1 || :`
test -n "$SHELL"
examine=false
run test -n "$tests"
run make -s -- "$target"
run test -f "$target"
run test -x "$target"
TD=`mktemp -d -- "${TMPDIR:-/tmp}/${0##*/}.XXXXXXXXXX"`
process_stream() {
local procs fifos f p rc rcd worst_rc
procs='from into back cmp'
fifos="$procs orig"
for f in $fifos
do
mkfifo -- "$TD"/$f
done
run test ${#1} -ge 2
into=${1%?}
back=${1#"$into"}
$verbose && printf %s "-$into" >& 2
run launch from_pid redir_to "$TD"/from tee "$TD"/orig
run launch into_pid redir_to "$TD"/into redir_from "$TD"/from \
./"$target" -$into
$verbose && printf %s " and -$back" >& 2
run launch back_pid redir_to "$TD"/back redir_from "$TD"/into \
./"$target" -$back
run launch cmp_pid cmp -s -- "$TD"/back "$TD"/orig
worst_rc=0
for p in $procs
do
if eval "wait \$${p}_pid"
then
:
else
rc=$?
if test $rc -gt 128
then
if rcd=`kill -l $rc 2> /dev/null`
then
if test "$rcd" = PIPE
then
rc=0
else
rcd="signal $rcd"
fi
fi
else
rcd=
fi
if test $rc != 0
then
test -z "$rcd" && rcd="return code $rc"
eval "cmd=\$${p}_pid_cmd"
say "Command >>>$cmd<<< failed" \
"with $rcd!"
test $rc -gt $worst_rc && worst_rc=$rc
fi
fi
done
if (exit $worst_rc)
then
say " passed."
else
say " FAILED!"
exit $worst_rc
fi
# Unfortunately, using "local" somewhere other than at the beginning
# of a function is not portable. But at least we can unset the
# dynamically created variables.
for p in $procs
do
unset ${p}_pid
unset ${p}_pid_cmd
done
for f in $fifos
do
rm -- "$TD"/$f
done
}
if $args_are_generators
then
test $# != 0 || die "No generator has been specified!"
mkfifo "$TD"/gen
for generator
do
$verbose && say "Test case from generator '$generator':"
run test -f "$generator"; run test -x "$generator"
for modes in $tests
do
launch gen_pid redir_to "$TD"/gen "$generator"
rc=0; (process_stream "$modes") < "$TD"/gen || rc=$?
if test $rc != 0
then
kill $gen 2> /dev/null || :
fi
rc2=0; wait $gen || rc2=$?
test $rc2 -gt $rc && rc=$rc2
test $rc != 0 && exit $rc
done
done
elif test $# = 0
then
$tests_overridden || tests=$single_test
if expr x"$tests" : x'.*[[:space:]]' > /dev/null
then
die "Only a single test is allowed when reading from $1!"
fi
$verbose && say "Test case from standard input:"
process_stream "$tests"
else
examine=true
for f
do
test -f "$f"
# For examiner's sake.
$verbose && say "Test case '$f':"
printf '%s\n' "$f" > "$TD"/origin
cat "$f" > "$TD"/from
cp -p -- "$target" "$TD"/
for modes in $tests
do
run test ${#modes} -ge 2
into=${modes%?}
back=${modes#"$into"}
$verbose && printf %s "-$into" >& 2
run redir_to "$TD"/into ./"$target" -$into "$TD"/from
$verbose && printf %s " and -$back" >& 2
run redir_from "$TD"/into redir_to "$TD"/back \
./"$target" -$back
set cmp -s -- "$TD"/back "$f"
if "$@"
then
say " passed."
else
say " FAILED!"
run "$@"; false || exit
fi
done
done
fi
say "All tests passed!"