3 # Copyright (c) 2011-2016 Dmitry V. Levin <ldv@altlinux.org>
6 # Redistribution and use in source and binary forms, with or without
7 # modification, are permitted provided that the following conditions
9 # 1. Redistributions of source code must retain the above copyright
10 # notice, this list of conditions and the following disclaimer.
11 # 2. Redistributions in binary form must reproduce the above copyright
12 # notice, this list of conditions and the following disclaimer in the
13 # documentation and/or other materials provided with the distribution.
14 # 3. The name of the author may not be used to endorse or promote products
15 # derived from this software without specific prior written permission.
17 # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 # IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 # IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 # NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 warn_() { printf >&2 '%s\n' "$*"; }
34 fail_() { warn_ "$ME_: failed test: $*"; exit 1; }
35 skip_() { warn_ "$ME_: skipped test: $*"; exit 77; }
36 framework_failure_() { warn_ "$ME_: framework failure: $*"; exit 99; }
37 framework_skip_() { warn_ "$ME_: framework skip: $*"; exit 77; }
41 type "$@" > /dev/null 2>&1 ||
42 framework_skip_ "$* is not available"
45 dump_log_and_fail_with()
59 if [ $rc -eq 77 ]; then
60 skip_ "$args exited with code 77"
62 fail_ "$args failed with code $rc"
68 run_prog_skip_if_failed()
71 "$@" || framework_skip_ "$args failed with code $?"
80 if [ $rc -eq 77 ]; then
83 fail_ "$* failed with code $rc"
90 > "$LOG" || fail_ "failed to write $LOG"
92 $STRACE -o "$LOG" "$@" ||
93 dump_log_and_fail_with "$STRACE $args failed with code $?"
98 rm -f -- "$LOG".[0-9]*
99 run_strace -ff -tt "$@"
100 "$srcdir"/../strace-log-merge "$LOG" > "$LOG" ||
101 dump_log_and_fail_with 'strace-log-merge failed with code $?'
102 rm -f -- "$LOG".[0-9]*
110 local program="$1"; shift
111 if grep '^@include[[:space:]]' < "$program" > /dev/null; then
112 gawk '@include "/dev/null"' < /dev/null ||
113 framework_skip_ 'gawk does not support @include'
117 # Usage: [FILE_TO_CHECK [AWK_PROGRAM [ERROR_MESSAGE [EXTRA_AWK_OPTIONS...]]]]
118 # Check whether AWK_PROGRAM matches FILE_TO_CHECK using gawk.
119 # If it doesn't, dump FILE_TO_CHECK and fail with ERROR_MESSAGE.
122 local output program error
123 if [ $# -eq 0 ]; then
128 if [ $# -eq 0 ]; then
129 program="$srcdir/$NAME.awk"
133 if [ $# -eq 0 ]; then
134 error="$STRACE $args output mismatch"
139 check_gawk "$program"
141 AWKPATH="$srcdir" gawk -f "$program" "$@" < "$output" || {
147 # Usage: [FILE_TO_CHECK [FILE_TO_COMPATE_WITH [ERROR_MESSAGE]]]
148 # Check whether FILE_TO_CHECK differs from FILE_TO_COMPATE_WITH.
149 # If it does, dump the difference and fail with ERROR_MESSAGE.
152 local output expected error
153 if [ $# -eq 0 ]; then
158 if [ $# -eq 0 ]; then
159 expected="$srcdir/$NAME.expected"
163 if [ $# -eq 0 ]; then
164 error="$STRACE $args output mismatch"
171 diff -- "$expected" "$output" ||
175 # Usage: [FILE_TO_CHECK [FILE_WITH_PATTERNS [ERROR_MESSAGE]]]
176 # Check whether all patterns listed in FILE_WITH_PATTERNS
177 # match FILE_TO_CHECK using egrep.
178 # If at least one of these patterns does not match,
179 # dump both files and fail with ERROR_MESSAGE.
182 local output patterns error pattern cnt failed=
183 if [ $# -eq 0 ]; then
188 if [ $# -eq 0 ]; then
189 patterns="$srcdir/$NAME.expected"
193 if [ $# -eq 0 ]; then
194 error="$STRACE $args output mismatch"
203 while read -r pattern; do
204 LC_ALL=C grep -E -x -e "$pattern" < "$output" > /dev/null || {
205 test -n "$failed" || {
206 echo 'Failed patterns of expected output:'
209 printf '#%d: %s\n' "$cnt" "$pattern"
213 test -z "$failed" || {
214 echo 'Actual output:'
220 # Usage: run_strace_match_diff [args to run_strace]
221 run_strace_match_diff()
224 [ -n "$args" -a -z "${args##*-e trace=*}" ] ||
225 set -- -e trace="$NAME" "$@"
227 run_strace "$@" $args > "$EXP"
228 match_diff "$LOG" "$EXP"
231 # Print kernel version code.
232 # usage: kernel_version_code $(uname -r)
233 kernel_version_code()
239 v1="${1%%[!0-9]*}" && [ -n "$v1" ] || v1=0
240 v2="${2%%[!0-9]*}" && [ -n "$v2" ] || v2=0
241 v3="${3%%[!0-9]*}" && [ -n "$v3" ] || v3=0
242 echo "$(($v1 * 65536 + $v2 * 256 + $v3))"
246 # Usage: require_min_kernel_version_or_skip 3.0
247 require_min_kernel_version_or_skip()
250 uname_r="$(uname -r)"
252 [ "$(kernel_version_code "$uname_r")" -ge \
253 "$(kernel_version_code "$1")" ] ||
254 skip_ "the kernel release $uname_r is not $1 or newer"
257 # Usage: grep_pid_status $pid GREP-OPTIONS...
262 cat < "/proc/$pid/status" | grep "$@"
269 *.gen.test) NAME="${ME_%.gen.test}" ;;
270 *.test) NAME="${ME_%.test}" ;;
274 if [ -n "$NAME" ]; then
282 *) srcdir="../$srcdir" ;;
285 [ -n "${STRACE-}" ] || {
287 case "${LOG_COMPILER-} ${LOG_FLAGS-}" in
288 *--suppressions=*--error-exitcode=*--tool=*)
289 # add valgrind command prefix
290 STRACE="${LOG_COMPILER-} ${LOG_FLAGS-} $STRACE"
295 [ -n "${STRACE-}" ] ||
299 : "${TIMEOUT_DURATION:=60}"
300 : "${SLEEP_A_BIT:=sleep 1}"
302 [ -z "${VERBOSE-}" ] ||