-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathtest.sh
More file actions
executable file
·324 lines (259 loc) · 6.43 KB
/
test.sh
File metadata and controls
executable file
·324 lines (259 loc) · 6.43 KB
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
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
#!/bin/sh
#
# Test driver.
#
# TODO: Import busybox tests? Need the "testing" framework.
set -o nounset
die() {
echo "$0: $@" 1>&2
exit 1
}
readonly CLANG_DIR=${CLANG_DIR:-}
if test -z "$CLANG_DIR"; then
die 'CLANG_DIR should be set. See env.sh'
fi
# A constant that is used by a lot of the original test scripts. Since we
# don't want to change it all those files, we make a symlink like ../a.out ->
# bwk-asan, so we can run tests against arbitrary build variants.
readonly AWK_SYMLINK=../a.out # relative to tests/ dir
_print_header() {
local oldawk=$1
local newawk=$2
uname -a
echo "Comparing $newawk vs old $oldawk"
}
# ../a.out is hard-coded, so we have to use it
_prepare_bin() {
local awk=$1
make $awk test_bin
ln -s -f --verbose $awk a.out
}
setup() {
mkdir -p _tmp
ln -s -f --verbose /bin/busybox _tmp/awk
}
# We have the expected data
golden() {
local awk=${1:-bwk}
for i in T.*; do
awk=$AWK_SYMLINK ./$i
done
# TODO: Do the tests all use $awk, or a.out too?
echo "Ran $(grep '$awk' T.* | wc -l) test cases"
echo
}
# Wow, this exposes tons of divergences and bugs.
# NOTE: Tests are not consistent because "BAD" is not always echoed to stderr!
# Sometimes it goes to stdout.
golden_all() {
#golden /usr/bin/mawk > _tmp/golden-mawk.log
golden /usr/bin/gawk > _tmp/golden-gawk.log
#golden _tmp/awk > _tmp/golden-busybox.log
grep FAIL _tmp/golden-*.log
}
# Compare vs another version -- book examples
compare_book() {
local oldawk=${1:-awk}
local newawk=${2:-bwk}
_print_header $oldawk $newawk
for i in p.*; do
echo "$i:"
$oldawk -f $i test.countries test.countries >foo1
$AWK_SYMLINK -f $i test.countries test.countries >foo2
if ! cmp -s foo1 foo2; then
echo -n "$i: FAILED"
fi
diff -b foo1 foo2 | sed -e 's/^/ /' -e 10q
done
echo "Ran $(ls p.* | wc -l) test files"
echo
}
# A list of one line programs in lilly.progs, read from lilly.ifile
compare_lilly() {
local oldawk=${1:-awk}
local newawk=${2:-bwk}
_print_header $oldawk $newawk
mkdir -p _tmp
local test_runner='
/./ {
tmp = "_tmp/lilly_line"
print $0 > tmp
print "###", NR, $0
cmd = awk " -f " tmp " < lilly.ifile "
system(cmd)
close(tmp)
}'
# NOTE: Somehow './time' doesn't work here
awk -v awk=$oldawk "$test_runner" <lilly.progs >foo1 2>&1
awk -v awk=$AWK_SYMLINK "$test_runner" <lilly.progs >foo2 2>&1
echo "Ran $(wc -l lilly.progs) lilly tests"
if ! diff foo1 foo2 >lilly.diff; then
echo 'FAILED: T.lilly, see lilly.diff'
cat lilly.diff
fi
echo
}
# Compare vs another version
compare_misc() {
local oldawk=${1:-awk}
local newawk=${2:-bwk}
_print_header $oldawk $newawk
for i in t.*; do
echo "$i:"
$oldawk -f $i test.data >foo1
$AWK_SYMLINK -f $i test.data >foo2
if ! cmp -s foo1 foo2; then
echo -n "$i: FAILED"
fi
# indent the diff
diff -b foo1 foo2 | sed -e 's/^/ /' -e 10q
done
echo "Ran $(ls t.* | wc -l) test files"
echo
}
# Creates a file called foo.td
_create_perf_data() {
cat td.1 td.1 >foo.td
sed 's/^........................//' td.1 >>foo.td
pr -m td.1 td.1 td.1 >>foo.td
pr -2 td.1 >>foo.td
cat bib >>foo.td
wc foo.td
}
# Perf tests on big data.
#
# TODO: Assert that a.out points to bwk, for speed? Though when you run
# coverage and ASAN, you don't want this.
compare_perf() {
local oldawk=${1:-awk}
local newawk=${2:-bwk}
_print_header $oldawk $newawk
time=./time
_create_perf_data
# an arbitrary collection of input data
local td=foo.td
# Is this like touch?
>_tmp/perf_timing.log
for i in tt.*; do
echo $i "($oldawk vs $newawk)":
# ind <$i
$time $oldawk -f $i $td >foo2 2>foo2t
cat foo2t
$time $AWK_SYMLINK -f $i $td >foo1 2>foo1t
cat foo1t
cmp foo1 foo2
# Accumulate timing
echo $i: >>_tmp/perf_timing.log
cat foo1t foo2t >>_tmp/perf_timing.log
done
./ctimes _tmp/perf_timing.log
echo "Ran $(ls tt.* | wc -l) test files"
echo
}
# mawk < gawk < bwk < busybox awk in terms of running time.
compare_perf_all() {
# TODO: Write reports to different files.
#compare_perf /usr/bin/mawk
#compare_perf /usr/bin/gawk
# busybox awk
compare_perf _tmp/awk
}
# NOTE: Sanitizer coverage doesn't have contention on counters, but bwk is
# single-threaded so we don't care.
# NOTE: Clang 3.8 has sancov.py; moving to sancov?
sancov() {
# -covered-functions
# -not-covered-functions
local action='-print'
local action='-covered-functions'
local action='-not-covered-functions'
# This one is only in clang 4.0?
#local action='-html-report'
$CLANG_DIR/bin/sancov $action -obj ../bwk-sancov-func \
_tmp/cov/*.sancov
}
# Different tool
# http://llvm.org/docs/CoverageMappingFormat.html
llvm_cov() {
$CLANG_DIR/bin/llvm-cov "$@"
}
usage() {
cat <<EOF
$0 suite SUITE [MODE]
SUITE is one of: golden, misc, book, lilly, perf, ALL
MODE is one of: none, asan, msan, ubsan, cov (default none)
EOF
}
suite() {
if test $# -eq 0; then
usage
die "Suite required"
fi
local suite=$1 # golden, misc, book, lilly, perf
local mode=${2:-none} # none, asan, msan, ubsan, cov
local bin
case $mode in
none)
bin=bwk
;;
asan)
bin=bwk-asan
;;
msan)
bin=bwk-msan
;;
ubsan)
bin=bwk-ubsan
;;
cov)
# Creates _obj/bwk-cov/*.gcda
bin=bwk-cov
# Clear out the old data first.
rm --verbose _obj/bwk-cov/*.gcda
;;
sancov)
bin=bwk-sancov-func
local dir=_tmp/sancov
mkdir -p $dir
# NOTE: Makefile builds on top of MSAN
export MSAN_OPTIONS="coverage=1:coverage_dir=$dir"
;;
*)
usage
die "Invalid mode '$mode'"
;;
esac
_prepare_bin $bin
cd tests/ # Test functions assume this (no pushd in dash)
case $suite in
golden) golden $bin ;;
# for all the comparisons, compare against default 'awk'
misc) compare_misc '' $bin ;;
book) compare_book '' $bin ;;
lilly) compare_lilly '' $bin ;;
perf) compare_perf '' $bin ;;
# Run all so coverage is unified
ALL)
golden $bin
compare_misc '' $bin
compare_book '' $bin
compare_lilly '' $bin
compare_perf '' $bin
;;
*)
usage; die "Invalid test suite '$suite'"
;;
esac
cd ..
case $mode in
cov)
local out=_gcov/${suite}.html
./run.sh cov-html $out
;;
esac
}
if test $# -eq 0; then
usage
die "Arguments required"
fi
"$@"