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

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