]> granicus.if.org Git - strace/blob - tests/init.sh
tests: use fixed timestamps in utime related tests
[strace] / tests / init.sh
1 #!/bin/sh
2 #
3 # Copyright (c) 2011-2016 Dmitry V. Levin <ldv@altlinux.org>
4 # All rights reserved.
5 #
6 # Redistribution and use in source and binary forms, with or without
7 # modification, are permitted provided that the following conditions
8 # are met:
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.
16 #
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.
27
28 ME_="${0##*/}"
29 LOG="log"
30 OUT="out"
31 EXP="exp"
32
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; }
38
39 check_prog()
40 {
41         type "$@" > /dev/null 2>&1 ||
42                 framework_skip_ "$* is not available"
43 }
44
45 dump_log_and_fail_with()
46 {
47         cat < "$LOG"
48         fail_ "$*"
49 }
50
51 run_prog()
52 {
53         if [ $# -eq 0 ]; then
54                 set -- "../$NAME"
55         fi
56         args="$*"
57         "$@" || {
58                 rc=$?
59                 if [ $rc -eq 77 ]; then
60                         skip_ "$args exited with code 77"
61                 else
62                         fail_ "$args failed with code $rc"
63                 fi
64         }
65 }
66
67
68 run_prog_skip_if_failed()
69 {
70         args="$*"
71         "$@" || framework_skip_ "$args failed with code $?"
72 }
73
74 try_run_prog()
75 {
76         local rc
77
78         "$@" > /dev/null || {
79                 rc=$?
80                 if [ $rc -eq 77 ]; then
81                         return 1
82                 else
83                         fail_ "$* failed with code $rc"
84                 fi
85         }
86 }
87
88 run_strace()
89 {
90         > "$LOG" || fail_ "failed to write $LOG"
91         args="$*"
92         $STRACE -o "$LOG" "$@" ||
93                 dump_log_and_fail_with "$STRACE $args failed with code $?"
94 }
95
96 run_strace_merge()
97 {
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]*
103 }
104
105 check_gawk()
106 {
107         check_prog gawk
108         check_prog grep
109
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'
114         fi
115 }
116
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.
120 match_awk()
121 {
122         local output program error
123         if [ $# -eq 0 ]; then
124                 output="$LOG"
125         else
126                 output="$1"; shift
127         fi
128         if [ $# -eq 0 ]; then
129                 program="$srcdir/$NAME.awk"
130         else
131                 program="$1"; shift
132         fi
133         if [ $# -eq 0 ]; then
134                 error="$STRACE $args output mismatch"
135         else
136                 error="$1"; shift
137         fi
138
139         check_gawk "$program"
140
141         AWKPATH="$srcdir" gawk -f "$program" "$@" < "$output" || {
142                 cat < "$output"
143                 fail_ "$error"
144         }
145 }
146
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.
150 match_diff()
151 {
152         local output expected error
153         if [ $# -eq 0 ]; then
154                 output="$LOG"
155         else
156                 output="$1"; shift
157         fi
158         if [ $# -eq 0 ]; then
159                 expected="$srcdir/$NAME.expected"
160         else
161                 expected="$1"; shift
162         fi
163         if [ $# -eq 0 ]; then
164                 error="$STRACE $args output mismatch"
165         else
166                 error="$1"; shift
167         fi
168
169         check_prog diff
170
171         diff -- "$expected" "$output" ||
172                 fail_ "$error"
173 }
174
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.
180 match_grep()
181 {
182         local output patterns error pattern cnt failed=
183         if [ $# -eq 0 ]; then
184                 output="$LOG"
185         else
186                 output="$1"; shift
187         fi
188         if [ $# -eq 0 ]; then
189                 patterns="$srcdir/$NAME.expected"
190         else
191                 patterns="$1"; shift
192         fi
193         if [ $# -eq 0 ]; then
194                 error="$STRACE $args output mismatch"
195         else
196                 error="$1"; shift
197         fi
198
199         check_prog wc
200         check_prog grep
201
202         cnt=1
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:'
207                                 failed=1
208                         }
209                         printf '#%d: %s\n' "$cnt" "$pattern"
210                 }
211                 cnt=$(($cnt + 1))
212         done < "$patterns"
213         test -z "$failed" || {
214                 echo 'Actual output:'
215                 cat < "$output"
216                 fail_ "$error"
217         }
218 }
219
220 # Usage: run_strace_match_diff [args to run_strace]
221 run_strace_match_diff()
222 {
223         args="$*"
224         [ -n "$args" -a -z "${args##*-e trace=*}" ] ||
225                 set -- -e trace="$NAME" "$@"
226         run_prog > /dev/null
227         run_strace "$@" $args > "$EXP"
228         match_diff "$LOG" "$EXP"
229 }
230
231 # Print kernel version code.
232 # usage: kernel_version_code $(uname -r)
233 kernel_version_code()
234 {
235         (
236                 set -f
237                 IFS=.
238                 set -- $1
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))"
243         )
244 }
245
246 # Usage: require_min_kernel_version_or_skip 3.0
247 require_min_kernel_version_or_skip()
248 {
249         local uname_r
250         uname_r="$(uname -r)"
251
252         [ "$(kernel_version_code "$uname_r")" -ge \
253           "$(kernel_version_code "$1")" ] ||
254                 skip_ "the kernel release $uname_r is not $1 or newer"
255 }
256
257 # Usage: grep_pid_status $pid GREP-OPTIONS...
258 grep_pid_status()
259 {
260         local pid
261         pid=$1; shift
262         cat < "/proc/$pid/status" | grep "$@"
263 }
264
265 check_prog cat
266 check_prog rm
267
268 case "$ME_" in
269         *.gen.test) NAME="${ME_%.gen.test}" ;;
270         *.test) NAME="${ME_%.test}" ;;
271         *) NAME=
272 esac
273
274 if [ -n "$NAME" ]; then
275         TESTDIR="$NAME.dir"
276         rm -rf -- "$TESTDIR"
277         mkdir -- "$TESTDIR"
278         cd "$TESTDIR"
279
280         case "$srcdir" in
281                 /*) ;;
282                 *) srcdir="../$srcdir" ;;
283         esac
284
285         [ -n "${STRACE-}" ] || {
286                 STRACE=../../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"
291                         ;;
292                 esac
293         }
294 else
295         [ -n "${STRACE-}" ] ||
296                 STRACE=../strace
297 fi
298
299 : "${TIMEOUT_DURATION:=60}"
300 : "${SLEEP_A_BIT:=sleep 1}"
301
302 [ -z "${VERBOSE-}" ] ||
303         set -x