Introduce lsu.{c,h}, implement help --long for para_server.
[paraslash.git] / t / test-lib.sh
1 #!/bin/bash
2
3 # Test suite helper functions, uses ideas and code from git's test-lib.sh,
4 # Copyright (c) 2005 Junio C Hamano. Licensed under the GPL v2, see file
5 # COPYING.
6
7 get_audio_file_paths()
8 {
9 local suffix="$1"
10
11 if (($# == 0)); then
12 result=$(find "$test_audio_file_dir" -type f)
13 else
14 result=$(find "$test_audio_file_dir" -type f -name "*.$suffix")
15 fi
16 }
17
18 say_color()
19 {
20 if [[ "$o_nocolor" != "true" && -n "$1" ]]; then
21 export TERM=$ORIGINAL_TERM
22 case "$1" in
23 error) tput $C_BOLD; tput $C_SETAF 1;;
24 skip) tput $C_SETAF 5;;
25 ok)
26 (($o_verbose == 0)) && return
27 tput $C_SETAF 2;;
28 pass) tput $C_BOLD; tput $C_SETAF 2;;
29 info) tput $C_SETAF 3;;
30 run)
31 (($o_verbose == 0)) && return
32 tput $C_SETAF 6;;
33 esac
34 fi
35 shift
36 printf "%s\n" "$*"
37 if [[ "$o_nocolor" != "true" && -n "$1" ]]; then
38 tput $C_SGR0
39 export TERM=dumb
40 fi
41 }
42
43 die()
44 {
45 local code=$?
46 [[ "$exit_ok" == "true" ]] && exit $code
47 say_color error "FATAL: Unexpected exit with code $code"
48 exit 1
49 }
50
51 error()
52 {
53 say_color error "error: $*"
54 exit_ok="true"
55 exit 1
56 }
57
58 say()
59 {
60 say_color info "$*"
61 }
62
63 retval_ok()
64 {
65 local rv="$1" expectation="$2"
66
67 if [[ "$expectation" == "success" ]]; then
68 (($rv == 0)) && return 0 || return 1
69 fi
70 if (($rv > 129 && $rv <= 192)); then
71 echo >&2 "died by signal"
72 return 1
73 fi
74 if (($rv == 127)); then
75 echo >&2 "command not found"
76 return 1
77 fi
78 if (($rv == 0)); then
79 echo >&2 "command was supposed to fail but succeeded"
80 return 1
81 fi
82 return 0
83 }
84
85 _test_run()
86 {
87 local f expectation="$3" ret
88
89 let test_count++
90 eval >&3 2>&4 "$2"
91 ret=$?
92 if retval_ok "$ret" "$expectation"; then
93 let test_success++
94 say_color ok "ok $test_count - $1"
95 return
96 fi
97 let test_failure++
98 say_color error "not ok - $test_count $1"
99 f="$o_results_dir/${0##*/}-$$.out"
100 if [[ -s "$f" ]]; then
101 sed -e 's/^/# /' < "$f"
102 else
103 sed -e 's/^/# /' <<< "$2"
104 fi
105 [[ "$o_immediate" != "true" ]] && return
106 exit_ok="true"
107 exit 1
108 }
109
110 test_skip()
111 {
112 (($# != 2)) && error "bug: not 2 parameters to test_skip()"
113 let test_count++
114 let test_skipped++
115 say_color skip >&3 "skipping test $this_test.$test_count ($1): $2"
116 say_color skip "ok $test_count - $1 # skipped ($2)"
117 }
118
119 test_require_objects()
120 {
121 local o1 o2 found
122
123 result=
124 # if no objects were given, we assume this test is run manually
125 # rather than via "make test". We won't check anything in this case
126 [[ -z "$o_objects" ]] && return
127
128 for o1 in $1; do
129 found=
130 for o2 in $o_objects; do
131 [[ "$o1" != "$o2" ]] && continue
132 found="true"
133 break
134 done
135 [[ "$found" == "true" ]] && continue
136 [[ -n "$result" ]] && result+=" "
137 result+="$o1"
138 done
139 [[ -z "$result" ]]
140 }
141
142 test_require_executables()
143 {
144 local i
145
146 result=
147 for i in "$@"; do
148 [[ -n "$(builtin type -t "$i")" ]] && continue
149 [[ -n "$result" ]] && result+=" "
150 result+="$i"
151 done
152 [[ -z "$result" ]]
153 }
154
155 test_duration()
156 {
157 local t=$(exec 2>&1 1>/dev/null; time -p "$@")
158 result=$(awk '{print $2 * 1000; exit 0}' <<< "$t")
159 }
160
161 test_expect_success()
162 {
163 (($# != 2)) && error "bug: not 2 parameters to test_expect_success()"
164 echo >&3 "expecting success: $2"
165 _test_run "$1" "$2" "success"
166 echo >&3 ""
167 }
168
169 test_expect_failure()
170 {
171 (($# != 2)) && error "bug: not 2 parameters to test_expect_failure()"
172 echo >&3 "expecting failure: $2"
173 _test_run "$1" "$2" "failure"
174 echo >&3 ""
175 }
176
177 test_done()
178 {
179 test_results_path="$o_results_dir/${0##*/}-$$.counts"
180 {
181 echo "total $test_count"
182 echo "success $test_success"
183 echo "failed $test_failure"
184 echo "skipped $test_skipped"
185 echo
186 } > $test_results_path
187
188 exit_ok="true"
189 msg="$test_count test(s) ($test_skipped test(s) skipped)"
190 if (($test_failure == 0)); then
191 say_color pass "# ${0##*/}: passed all $msg"
192 exit 0
193 else
194 say_color error "# ${0##*/}: failed $test_failure among $msg"
195 exit 1
196 fi
197 }
198
199 sanitize_environment()
200 {
201 export LANG=C
202 export LC_ALL=C
203 export PAGER=cat
204 export TZ=UTC
205 export TERM=dumb
206 export EDITOR=:
207 export HOME=$(pwd)
208
209 unset VISUAL
210 unset EMAIL
211 unset CDPATH
212 unset GREP_OPTIONS
213 }
214
215 can_use_colors()
216 {
217 result="false"
218 [[ "$TERM" == "dumb" ]] && return
219 [[ -t 1 ]] || return
220 C_BOLD='bold'
221 tput $C_BOLD &>/dev/null || {
222 C_BOLD='md'
223 tput $C_BOLD &>/dev/null
224 } || return
225 C_SETAF='setaf'
226 tput $C_SETAF 1 &>/dev/null || {
227 C_SETAF='AF'
228 tput $C_SETAF 1 &>/dev/null
229 } || return
230 C_SGR0='sgr0'
231 tput $C_SGR0 >/dev/null 2>&1 || {
232 C_SGR0='me'
233 tput $C_SGR0 &>/dev/null
234 } || return
235 result="true"
236 }
237
238 parse_options()
239 {
240 while (($# > 0)); do
241 case "$1" in
242 -i|--immediate) o_immediate="true"; shift;;
243 -l|--long) export o_long="true"; shift;;
244 -h|--help) o_help="true"; shift;;
245 -v=0|--verbose=0) o_verbose="0"; shift;;
246 -v=1|--verbose=1) o_verbose="1"; shift;;
247 -v|--verbose|-v=2|--verbose=2) o_verbose="2"; shift;;
248 --no-color) o_nocolor="true"; shift;;
249 --man-dir) export o_man_dir="$2"; shift; shift;;
250 --results-dir) o_results_dir="$2"; shift; shift;;
251 --trash-dir) o_trash_dir="$2"; shift; shift;;
252 --executables-dir) export o_executables_dir="$2"; shift; shift;;
253 --executables) export o_executables="$2"; shift; shift;;
254 --objects) export o_objects="$2"; shift; shift;;
255 *) echo "error: unknown test option '$1'" >&2; exit 1;;
256 esac
257 done
258 [[ -z "$o_verbose" ]] && o_verbose=1
259 }
260
261 create_trash_dir_and_cd()
262 {
263 local trash="$o_trash_dir/trash-dir.${0##*/}"
264
265 rm -rf "$trash" || error "could not remove trash dir"
266 mkdir -p "$trash" || error "could not make trash dir"
267 cd "$trash" || error "could not change to trash dir"
268 }
269
270 fixup_dirs()
271 {
272 local wd=$(pwd)
273
274 test_dir="$(realpath $wd/${0%/*})"
275 test_audio_file_dir="$test_dir/audio_files"
276
277 [[ -z "$o_results_dir" ]] && o_results_dir="$test_dir/test-results"
278 [[ -z "$o_executables_dir" ]] && o_executables_dir="$test_dir/.."
279 [[ -z "$o_trash_dir" ]] && o_trash_dir="$test_dir/trashes"
280 [[ -z "$o_man_dir" ]] && o_man_dir="$test_dir/../build/man/man1"
281
282 # we want alsolute paths because relative paths become invalid
283 # after changing to the trash dir
284 [[ -n "${o_results_dir##/*}" ]] && o_results_dir="$wd/$o_results_dir"
285 [[ -n "${o_executables_dir##/*}" ]] && o_executables_dir="$wd/$o_results_dir"
286 [[ -n "${o_man_dir##/*}" ]] && o_man_dir="$wd/$o_man_dir"
287 [[ -n "${o_trash_dir##/*}" ]] && o_trash_dir="$wd/$o_trash_dir"
288
289 mkdir -p "$o_results_dir"
290 }
291
292 parse_options "$@"
293 if [[ "$o_nocolor" != "true" ]]; then
294 can_use_colors
295 [[ "$result" != "true" ]] && o_nocolor="true"
296 fi
297
298 # Each test must set test_description
299 [[ -z "${test_description}" ]] && error "${0##*/} did not set test_description"
300 if [[ "$o_help" == "true" ]]; then
301 printf "${0##*/}: "
302 sed -e '1!d' <<< "$test_description"
303 if (($o_verbose >= 2)); then
304 echo
305 sed -e '1,2d' -e 's/^/ /g' <<<"$test_description"
306 echo
307 fi
308 exit 0
309 fi
310 fixup_dirs
311
312 [[ -z "$o_executables" ]] && o_executables="para_afh para_audioc para_audiod
313 para_client para_mixer para_filter para_gui para_recv para_server
314 para_write"
315 for exe in $o_executables; do
316 export $(tr 'a-z' 'A-Z' <<< $exe)="$o_executables_dir/$exe"
317 done
318
319 test_failure=0
320 test_count=0
321 test_success=0
322 test_skipped=0
323
324 ORIGINAL_TERM=$TERM
325 sanitize_environment
326 create_trash_dir_and_cd
327
328 if (($o_verbose >= 2)); then
329 exec 4>&2 3>&1
330 else
331 exec 4>$o_results_dir/${0##*/}-$$.out 3>&4
332 fi
333
334 exit_ok=
335 trap 'die' EXIT
336
337 say_color run "# running ${0##*/}"