1#!/bin/sh
2
3ME_="${0##*/}"
4
5warn_() { printf >&2 '%s\n' "$*"; }
6fail_() { warn_ "$ME_: failed test: $*"; exit 1; }
7skip_() { warn_ "$ME_: skipped test: $*"; exit 77; }
8framework_failure_() { warn_ "$ME_: framework failure: $*"; exit 99; }
9framework_skip_() { warn_ "$ME_: framework skip: $*"; exit 77; }
10
11check_prog()
12{
13	type "$@" > /dev/null 2>&1 ||
14		framework_skip_ "$* is not available"
15}
16
17dump_log_and_fail_with()
18{
19	cat < "$LOG"
20	fail_ "$*"
21}
22
23run_prog()
24{
25	if [ $# -eq 0 ]; then
26		set -- "./${ME_%.test}"
27	fi
28	args="$*"
29	"$@" || {
30		if [ $? -eq 77 ]; then
31			skip_ "$args exited with code 77"
32		else
33			fail_ "$args failed"
34		fi
35	}
36}
37
38
39run_prog_skip_if_failed()
40{
41	args="$*"
42	"$@" || framework_skip_ "$args failed"
43}
44
45run_strace()
46{
47	> "$LOG" || fail_ "failed to write $LOG"
48	args="$*"
49	$STRACE -o "$LOG" "$@" ||
50		dump_log_and_fail_with "$STRACE $args failed"
51}
52
53run_strace_merge()
54{
55	rm -f -- "$LOG".[0-9]*
56	run_strace -ff -tt "$@"
57	"$srcdir"/../strace-log-merge "$LOG" > "$LOG" ||
58		dump_log_and_fail_with 'strace-log-merge failed'
59	rm -f -- "$LOG".[0-9]*
60}
61
62check_gawk()
63{
64	check_prog gawk
65	check_prog grep
66
67	local program="$1"; shift
68	if grep '^@include[[:space:]]' < "$program" > /dev/null; then
69		gawk '@include "/dev/null"' < /dev/null ||
70			framework_skip_ 'gawk does not support @include'
71	fi
72}
73
74# Usage: [FILE_TO_CHECK [AWK_PROGRAM [ERROR_MESSAGE [EXTRA_AWK_OPTIONS...]]]]
75# Check whether all patterns listed in AWK_PROGRAM
76# match FILE_TO_CHECK using egrep.
77# If at least one of these patterns does not match,
78# dump both files and fail with ERROR_MESSAGE.
79match_awk()
80{
81	local output program error
82	if [ $# -eq 0 ]; then
83		output="$LOG"
84	else
85		output="$1"; shift
86	fi
87	if [ $# -eq 0 ]; then
88		program="$srcdir/${ME_%.test}.awk"
89	else
90		program="$1"; shift
91	fi
92	if [ $# -eq 0 ]; then
93		error="$STRACE $args output mismatch"
94	else
95		error="$1"; shift
96	fi
97
98	check_gawk "$program"
99
100	AWKPATH="$srcdir" gawk -f "$program" "$@" < "$output" || {
101		cat < "$output"
102		fail_ "$error"
103	}
104}
105
106# Usage: [FILE_TO_CHECK [FILE_TO_COMPATE_WITH [ERROR_MESSAGE]]]
107# Check whether FILE_TO_CHECK differs from FILE_TO_COMPATE_WITH.
108# If it does, dump the difference and fail with ERROR_MESSAGE.
109match_diff()
110{
111	local output expected error
112	if [ $# -eq 0 ]; then
113		output="$LOG"
114	else
115		output="$1"; shift
116	fi
117	if [ $# -eq 0 ]; then
118		expected="$srcdir/${ME_%.test}.expected"
119	else
120		expected="$1"; shift
121	fi
122	if [ $# -eq 0 ]; then
123		error="$STRACE $args output mismatch"
124	else
125		error="$1"; shift
126	fi
127
128	check_prog diff
129
130	diff -- "$expected" "$output" ||
131		fail_ "$error"
132}
133
134# Usage: [FILE_TO_CHECK [FILE_WITH_PATTERNS [ERROR_MESSAGE]]]
135# Check whether all patterns listed in FILE_WITH_PATTERNS
136# match FILE_TO_CHECK using egrep.
137# If at least one of these patterns does not match,
138# dump both files and fail with ERROR_MESSAGE.
139match_grep()
140{
141	local output patterns error expected matched
142	if [ $# -eq 0 ]; then
143		output="$LOG"
144	else
145		output="$1"; shift
146	fi
147	if [ $# -eq 0 ]; then
148		patterns="$srcdir/${ME_%.test}.expected"
149	else
150		patterns="$1"; shift
151	fi
152	if [ $# -eq 0 ]; then
153		error="$STRACE $args output mismatch"
154	else
155		error="$1"; shift
156	fi
157
158	check_prog wc
159	check_prog grep
160
161	expected=$(wc -l < "$patterns") &&
162	matched=$(LC_ALL=C grep -c -E -x -f "$patterns" < "$output") &&
163	test "$expected" -eq "$matched" || {
164		echo 'Patterns of expected output:'
165		cat < "$patterns"
166		echo 'Actual output:'
167		cat < "$output"
168		fail_ "$error"
169	}
170}
171
172check_prog cat
173check_prog rm
174
175LOG="$ME_.tmp"
176rm -f "$LOG"
177
178: "${STRACE:=../strace}"
179: "${TIMEOUT_DURATION:=60}"
180: "${SLEEP_A_BIT:=sleep 1}"
181