1 | #!/usr/bin/env bash
|
2 | #
|
3 | # Run test executables that obey the BYO protocol.
|
4 | #
|
5 | # TODO: doc/byo.md
|
6 | #
|
7 | # Usage:
|
8 | # test/byo-client.sh run-tests FLAGS* ARGS*
|
9 | #
|
10 | # TODO:
|
11 | # - client creates a clean process state for each test
|
12 | # - clean directory state for each test.
|
13 |
|
14 | : ${LIB_OSH=stdlib/osh}
|
15 | source $LIB_OSH/bash-strict.sh
|
16 | source $LIB_OSH/two.sh
|
17 | source $LIB_OSH/task-five.sh
|
18 |
|
19 | readonly TAB=$'\t'
|
20 |
|
21 | detect() {
|
22 | if test $# -eq 0; then
|
23 | die "Expected argv to run"
|
24 | fi
|
25 |
|
26 | local out
|
27 |
|
28 | local status=0
|
29 | set +o errexit
|
30 | out=$(BYO_COMMAND=detect "$@" < /dev/null)
|
31 | status=$?
|
32 | set -o errexit
|
33 |
|
34 | if test $status -ne 66; then
|
35 | die "$(printf '%q ' "$@") doesn't implement BYO: expected status 66, got $status"
|
36 | fi
|
37 |
|
38 | # Verbose
|
39 | if false; then
|
40 | echo
|
41 | echo "BYO commands detected in $(printf '%q ' "$@"):"
|
42 | echo "$out"
|
43 | fi
|
44 | }
|
45 |
|
46 | print-help() {
|
47 | # Other flags:
|
48 | #
|
49 | # --host host to upload to?
|
50 | # --auth allow writing to host
|
51 | # --no-taskset disable taskset?
|
52 |
|
53 | cat <<EOF
|
54 | Usage: byo run-tests FLAGS*
|
55 | EOF
|
56 | }
|
57 |
|
58 | # Test params:
|
59 | #
|
60 | # SH=dash SH=bash SH=bin/osh # test/spec.sh
|
61 | # OSH=bin/osh OSH=_bin/cxx-asan/osh # e.g. test/*{parse,runtime}-errors.sh
|
62 | # YSH=bin/osh YSH=_bin/cxx-asan/osh # e.g. test/*{parse,runtime}-errors.sh
|
63 | #
|
64 | # benchmarks/compute.sh has 3 dimensions:
|
65 | # ( workload name, param1, param2 )
|
66 | #
|
67 | # Pretty much all tests are parameterized by shell
|
68 | #
|
69 | # There's also python2 vs. python3 vs. awk etc.
|
70 | # benchmarks/compute
|
71 | #
|
72 | # Should it be
|
73 | # BYO_PARAM_OSH
|
74 | #
|
75 | # Usage:
|
76 | #
|
77 | # $ byo run-tests test/osh-usage
|
78 | # $ byo run-tests --param OSH=bin/osh test/osh-usage
|
79 | # $ byo run-tests --param OSH=bin/osh --param OSH=_bin/cxx-asan/osh test/osh-usage
|
80 | # $ byo run-tests --param OSH='bin/osh;_bin/cxx-asan/osh' test/osh-usage
|
81 | #
|
82 | # Run with each value of param in sequence, and then make a big table later?
|
83 | # I think you just loop over the param flags
|
84 |
|
85 | # If no params, we run once. Otherwise we run once per param value
|
86 | FLAG_params=()
|
87 | FLAG_fresh_dir=''
|
88 | FLAG_capture=''
|
89 |
|
90 | parse-flags-for-test() {
|
91 | ### Sets global vars FLAG_*
|
92 |
|
93 | while test $# -ne 0; do
|
94 | case "$1" in
|
95 | -h|--help)
|
96 | print-help
|
97 | exit
|
98 | ;;
|
99 |
|
100 | # Capture stdout and stderr? Or let it go to the terminal
|
101 | --capture)
|
102 | FLAG_capture=T
|
103 | ;;
|
104 |
|
105 | # Is each test case run in its own dir? Or set TEST_TEMP_DIR
|
106 | --fresh-dir)
|
107 | FLAG_fresh_dir=T
|
108 | ;;
|
109 |
|
110 | --param)
|
111 | if test $# -eq 1; then
|
112 | die "--param requires an argument"
|
113 | fi
|
114 | shift
|
115 |
|
116 | pat='[A-Z_]+=.*'
|
117 | if ! [[ $1 =~ $pat ]]; then
|
118 | die "Expected string like PARAM_NAME=value, got $1"
|
119 | fi
|
120 | FLAG_params+=( $1 )
|
121 | ;;
|
122 |
|
123 | -*)
|
124 | die "Invalid flag '$1'"
|
125 | break
|
126 | ;;
|
127 |
|
128 | --)
|
129 | shift
|
130 | break
|
131 | ;;
|
132 |
|
133 | *)
|
134 | # Move on to args
|
135 | break
|
136 | ;;
|
137 |
|
138 | esac
|
139 | shift
|
140 | done
|
141 |
|
142 | ARGV=( "$@" )
|
143 | }
|
144 |
|
145 | run-tests() {
|
146 | if test $# -eq 0; then
|
147 | die "Expected argv to run"
|
148 | fi
|
149 |
|
150 | # Set FLAG_* and ARGV
|
151 | parse-flags-for-test "$@"
|
152 |
|
153 | # ARGV is the command to run, like bash foo.sh
|
154 | #
|
155 | # It's an array rather than a single command, so you can run the same scripts
|
156 | # under multiple shells:
|
157 | #
|
158 | # bash myscript.sh
|
159 | # osh myscript.sh
|
160 | #
|
161 | # This matters so two-test.sh can SOURCE two.sh, and run under both bash and
|
162 | # OSH.
|
163 | # That could be or --use-interp bin/osh
|
164 | #
|
165 | # could you have --use-interp python3 too? e.g. I want benchmarks/time_.py
|
166 | # to work under both? See time-tsv3 in tsv-lib.sh
|
167 | #
|
168 | # No that's a test param PYTHON=python3 PYTHON=python2
|
169 |
|
170 | detect "${ARGV[@]}"
|
171 |
|
172 | log '---'
|
173 | log "byo run-tests: ${ARGV[@]}"
|
174 | log
|
175 |
|
176 | mkdir -p _tmp
|
177 | local tmp=_tmp/byo-list.txt
|
178 |
|
179 | # First list the tests
|
180 | BYO_COMMAND=list-tests "${ARGV[@]}" > $tmp
|
181 |
|
182 | local i=0
|
183 | local status
|
184 |
|
185 | while read -r test_name; do
|
186 |
|
187 | echo "${TAB}${test_name}"
|
188 |
|
189 | set +o errexit
|
190 | if test -n "$FLAG_capture"; then
|
191 | # TODO: Capture it to a string
|
192 | # - Write to nice HTML file?
|
193 | BYO_COMMAND=run-test BYO_ARG="$test_name" "${ARGV[@]}" >/dev/null 2>&1
|
194 | else
|
195 | BYO_COMMAND=run-test BYO_ARG="$test_name" "${ARGV[@]}"
|
196 | fi
|
197 | status=$?
|
198 | set -o errexit
|
199 |
|
200 | if test $status -eq 0; then
|
201 | echo "${TAB}OK"
|
202 | else
|
203 | echo "${TAB}FAIL with status $status"
|
204 | exit 1
|
205 | fi
|
206 |
|
207 | i=$(( i + 1 ))
|
208 | done < $tmp
|
209 |
|
210 | echo
|
211 | echo "$0: $i tests passed."
|
212 | }
|
213 |
|
214 | task-five "$@"
|