OILS / benchmarks / time-test.sh View on Github | oilshell.org

315 lines, 179 significant
1#!/usr/bin/env bash
2#
3# Usage:
4# benchmarks/time-test.sh <function name>
5
6set -o nounset
7set -o pipefail
8set -o errexit
9
10REPO_ROOT=$(cd "$(dirname $0)/.."; pwd)
11
12source test/common.sh
13source test/tsv-lib.sh
14
15# TODO: This would be a nice little program for Oil
16count-lines-and-cols() {
17 python2 -c '
18import sys
19
20expected_num_lines = int(sys.argv[1])
21expected_num_cols = int(sys.argv[2])
22try:
23 sep = sys.argv[3]
24except IndexError:
25 sep = "\t"
26
27num_lines = 0
28tab_counts = []
29for line in sys.stdin:
30 tab_counts.append(line.count(sep))
31 num_lines += 1
32 # Show what we get
33 sys.stdout.write(line)
34
35if any(tab_counts[0] != n for n in tab_counts):
36 raise AssertionError(tab_counts)
37
38num_tabs = tab_counts[0]
39
40assert expected_num_lines == num_lines, \
41 "expected %d lines, got %d" % (expected_num_lines, num_lines)
42assert expected_num_cols == num_tabs + 1, \
43 "expected %d cols, got %d" % (expected_num_cols, num_tabs + 1)
44' "$@"
45}
46
47time-tool() {
48 $(dirname $0)/time_.py "$@"
49}
50
51test-csv() {
52 local out=_tmp/time.csv
53
54 time-tool -o $out -- echo hi
55 cat $out | count-lines-and-cols 1 2 ,
56
57 time-tool -o $out --field a --field b -- echo hi
58 cat $out | count-lines-and-cols 1 4 ,
59 echo csv fields=$?
60
61 time-tool -o $out --rusage -- echo hi
62 cat $out | count-lines-and-cols 1 5 ,
63 echo csv rusage=$?
64
65 time-tool -o $out --rusage --field a --field b -- echo hi
66 cat $out | count-lines-and-cols 1 7 ,
67 echo csv rusage fields=$?
68}
69
70test-tsv() {
71 local out=_tmp/time.tsv
72 rm -f $out
73
74 for i in 1 2 3; do
75 time-tool --tsv -o $out --append --time-fmt '%.2f' -- sleep 0.0${i}
76 done
77 cat $out | count-lines-and-cols 3 2
78
79 time-tool --tsv -o $out --field a --field b -- echo hi
80 cat $out | count-lines-and-cols 1 4
81 echo fields=$?
82
83 time-tool --tsv -o $out --rusage --field a --field b -- echo hi
84 cat $out | count-lines-and-cols 1 7
85 echo rusage=$?
86
87 time-tool --tsv -o $out --print-header \
88 --rusage-2
89 time-tool --tsv -o $out --append \
90 --rusage-2 -- echo hi
91 cat $out | count-lines-and-cols 2 10
92 echo rusage-2=$?
93}
94
95test-append() {
96 local out=_tmp/overwrite.tsv
97 for i in 4 5; do
98 time-tool --tsv -o $out -- sleep 0.0${i}
99 done
100 cat $out | count-lines-and-cols 1 2
101
102 echo ---
103
104 local out=_tmp/append.tsv
105 rm -f $out
106
107 for i in 4 5; do
108 time-tool --tsv -o $out --append -- sleep 0.0${i}
109 done
110 cat $out | count-lines-and-cols 2 2
111}
112
113test-usage() {
114 # no args
115 set +o errexit
116
117 time-tool; status=$?
118 assert $status -eq 2
119
120 time-tool --output; status=$?
121 assert $status -eq 2
122
123 time-tool sleep 0.1
124 time-tool --append sleep 0.1; status=$?
125 assert $status -eq 0
126
127 set -o errexit
128}
129
130test-bad-tsv-chars() {
131 local out=_tmp/time2.tsv
132 rm -f $out
133
134 set +o errexit
135
136 # Newline should fail
137 time-tool --tsv -o $out --field $'\n' -- sleep 0.001; status=$?
138 assert $status -eq 1
139
140 # Tab should fail
141 time-tool --tsv -o $out --field $'\t' -- sleep 0.001; status=$?
142 assert $status -eq 1
143
144 # Quote should fail
145 time-tool --tsv -o $out --field '"' -- sleep 0.001; status=$?
146 assert $status -eq 1
147
148 # Backslash is OK
149 time-tool --tsv -o $out --field '\' -- sleep 0.001; status=$?
150 assert $status -eq 0
151
152 # Space is OK, although canonical form would be " "
153 time-tool --tsv -o $out --field ' ' -- sleep 0.001; status=$?
154 assert $status -eq 0
155
156 set -o errexit
157
158 cat $out
159
160 echo $'OK\ttest-bad-tsv-chars'
161}
162
163test-stdout() {
164 local out=_tmp/time-stdout.csv
165 time-tool -o $out --stdout _tmp/stdout.txt -- seq 3
166
167 diff _tmp/stdout.txt - <<EOF
1681
1692
1703
171EOF
172
173 # No assertions here yet
174 md5sum _tmp/stdout.txt
175 cat $out | count-lines-and-cols 1 3 ,
176
177 time-tool -o $out --rusage --stdout _tmp/stdout.txt -- seq 3
178 cat $out | count-lines-and-cols 1 6 ,
179}
180
181test-rusage() {
182 local out=_tmp/time-rusage.csv
183 time-tool --tsv -o $out --rusage -- bash -c 'echo bash'
184 cat $out | count-lines-and-cols 1 5
185
186 #time-tool --tsv -o $out --rusage -- dash -c 'echo dash'
187 #cat $out
188
189 # Blow up memory size for testing
190 local py='a=[42]*500000; print "python"'
191
192 time-tool --tsv -o $out --rusage -- python2 -c "$py"
193 cat $out | count-lines-and-cols 1 5
194
195 #time-tool --tsv -o $out --rusage -- bin/osh -c 'echo osh'
196 #cat $out
197}
198
199test-time-span() {
200 local out=_tmp/time-span.csv
201
202 time-tool --tsv -o $out --time-span --print-header
203 cat $out | count-lines-and-cols 1 4
204
205 time-tool --tsv -o $out --time-span -- bash -c 'echo bash'
206 cat $out | count-lines-and-cols 1 4
207}
208
209# Compare vs. /usr/bin/time.
210test-maxrss() {
211 if which time; then # Ignore this on continuous build
212 command time --format '%x %U %M' -- seq 1
213 fi
214
215 # Showing a discrepancy. FIXED!
216 time-tool -o _tmp/maxrss --tsv --rusage -- seq 1
217 cat _tmp/maxrss
218}
219
220test-print-header() {
221 set +o errexit
222
223 # no arguments allowed
224 time-tool --tsv --print-header foo bar
225 assert $? -eq 2
226
227 time-tool --tsv --print-header --field name
228 assert $? -eq 0
229
230 time-tool --tsv --print-header --rusage --field name
231 assert $? -eq 0
232
233 time-tool --print-header --rusage --field foo --field bar
234 assert $? -eq 0
235
236 time-tool -o _tmp/time-test-1 \
237 --print-header --rusage --stdout DUMMY --tsv --field a --field b
238 assert $? -eq 0
239
240 #set -x
241 head _tmp/time-test-1
242}
243
244test-time-helper() {
245 set +o errexit
246
247 local tmp=_tmp/time-helper.txt
248
249 local th=_devbuild/bin/time-helper
250
251 # Make some work show up
252 local cmd='{ md5sum */*.md; sleep 0.15; exit 42; } > /dev/null'
253
254 echo 'will be overwritten' > $tmp
255 cat $tmp
256
257 $th
258 assert $? -ne 0 # it's 1, but could be 2
259
260 $th /bad
261 assert $? -eq 1
262
263 $th -o $tmp -d $'\t' -x -e -- sh -c "$cmd"
264 assert $? -eq 42
265 cat $tmp
266 echo
267
268 # Now append
269 $th -o $tmp -a -d , -x -e -U -S -M -- sh -c "$cmd"
270 assert $? -eq 42
271 cat $tmp
272 echo
273
274 # Error case
275 $th -q
276 assert $? -eq 2
277}
278
279test-time-tsv() {
280 local status
281
282 local out=_tmp/time-test-zz
283 rm -f -v $out
284
285 # Similar to what soil/worker.sh does
286 set +o errexit
287 time-tsv -o $out --append -- zz
288 status=$?
289 set -o errexit
290
291 echo status=$status
292 assert $status -eq 1
293
294 cat $out
295 echo
296}
297
298test-grandchild-memory() {
299 local -a use_mem=( python2 -c 'import sys; ["X" * int(sys.argv[1])]' 10000000 )
300
301 time-tsv -o /dev/stdout --rusage -- "${use_mem[@]}"
302
303 # RUSAGE_CHILDREN includes grandchildren!
304 time-tsv -o /dev/stdout --rusage -- sh -c 'echo; "$@"' dummy "${use_mem[@]}"
305
306 # 'exec' doesn't make a consistent difference, because /bin/sh doesn't use
307 # much memory
308 time-tsv -o /dev/stdout --rusage -- sh -c 'echo; exec "$@"' dummy "${use_mem[@]}"
309}
310
311soil-run() {
312 run-test-funcs
313}
314
315"$@"