xref: /freebsd/cddl/usr.sbin/dtrace/tests/tools/dtest.sh (revision 9aff62dee28239f84b4aa4a3429cf26dbbf770cc)
1#!/bin/sh
2
3usage()
4{
5    cat >&2 <<__EOF__
6A harness for test cases in the DTrace test suite.
7
8usage: $(basename $0) <testfile>
9__EOF__
10    exit 1
11}
12
13gettag()
14{
15    local tag
16
17    tag=$(basename $1)
18    tag=${tag#*.}
19    tag=${tag%%[a-z.]*}
20    echo $tag
21}
22
23runtest()
24{
25    local cfile ofile ddep odep dflags exe exstatus pid retval status
26
27    exstatus=0
28    retval=0
29
30    case $TFILE in
31    drp.DTRACEDROP_*.d|err.*.d|tst.*.d)
32        case $TFILE in
33        drp.DTRACEDROP_*.d)
34            dflags="-x droptags"
35            tag=$(gettag "$TFILE")
36            ;;
37        err.D_*.d)
38            exstatus=1
39            dflags="-x errtags"
40            tag=$(gettag "$TFILE")
41            ;;
42        err.*.d)
43            exstatus=1
44            ;;
45        esac
46
47        exe=${TFILE%.*}.exe
48        cfile=${TFILE%.*}.c
49        ddep=${TFILE%.*}.d
50        ddep=${ddep#tst.}
51        if [ -r "$cfile" -a -r "$ddep" ]; then
52            # The tst.xxx.c corresponding to the tst.xxx.d is usually
53            # (cross-)compiled on the build host and installed in the target
54            # system as an executable. However, when there is an associated
55            # xxx.d file to be included in that executable, we must compile
56            # xxx.d in the target system at runtime because DTrace currently
57            # doesn't support cross-compilation and will always use the build
58            # host's ELF format when calling `dtrace -G`.
59            # TODO add support for cross-compilation in DTrace and move it back
60            #      to dtrace.test.mk.
61            ofile="${cfile%.c}.o"
62            odep="${ddep%.d}.o"
63            dtrace -C -x nolibs -h -s "$ddep"
64            cc -O0 -g -I. -o "$ofile" -c "$cfile"
65            dtrace -C -x nolibs -G -s "$ddep" "$ofile"
66            cc -O0 -g -I. -o "$exe" "$ofile" "$odep"
67            rm -f "${ddep%.d}.h" "$ofile" "$odep"
68        fi
69
70        if [ -f "$exe" -a -x "$exe" ]; then
71            ./$exe &
72            pid=$!
73            dflags="$dflags ${pid}"
74        fi
75
76        dtrace -C -s "${TFILE}" $dflags >$STDOUT 2>$STDERR
77        status=$?
78
79        if [ $status -ne $exstatus ]; then
80            ERRMSG="dtrace exited with status ${status}, expected ${exstatus}"
81            retval=1
82        elif [ -n "${tag}" ] && ! grep -Fq " [${tag}] " ${STDERR}; then
83            ERRMSG="dtrace's error output did not contain expected tag ${tag}"
84            retval=1
85        fi
86
87        if [ -n "$pid" ]; then
88            kill -0 $pid >/dev/null 2>&1 && kill -9 $pid >/dev/null 2>&1
89            wait
90        fi
91        ;;
92    err.*.ksh|tst.*.ksh)
93        expr "$TFILE" : 'err.*' >/dev/null && exstatus=1
94
95        tst=$TFILE ksh -p "$TFILE" /usr/sbin/dtrace >$STDOUT 2>$STDERR
96        status=$?
97
98        if [ $status -ne $exstatus ]; then
99            ERRMSG="script exited with status ${status}, expected ${exstatus}"
100            retval=1
101        fi
102        ;;
103    *)
104        ERRMSG="unexpected test file name $TFILE"
105        retval=1
106        ;;
107    esac
108
109    if [ $retval -eq 0 ] && \
110        head -n 1 $STDOUT | grep -q -E '^#!/.*ksh$'; then
111        ksh -p $STDOUT
112        retval=$?
113    fi
114
115    return $retval
116}
117
118[ $# -eq 1 ] || usage
119
120readonly STDERR=$(mktemp)
121readonly STDOUT=$(mktemp)
122readonly TFILE=$(basename $1)
123readonly EXOUT=${TFILE}.out
124
125kldload -n dtrace_test
126cd $(dirname $1)
127runtest
128RESULT=$?
129
130if [ $RESULT -eq 0 -a -f $EXOUT -a -r $EXOUT ] && \
131   ! cmp $STDOUT $EXOUT >/dev/null 2>&1; then
132    ERRMSG="test output mismatch"
133    RESULT=1
134fi
135
136if [ $RESULT -ne 0 ]; then
137    echo "test $TFILE failed: $ERRMSG" >&2
138    if [ $(stat -f '%z' $STDOUT) -gt 0 ]; then
139        cat >&2 <<__EOF__
140test stdout:
141--
142$(cat $STDOUT)
143--
144test stdout diff:
145--
146$(diff -u $EXOUT $STDOUT)
147--
148__EOF__
149    fi
150    if [ $(stat -f '%z' $STDERR) -gt 0 ]; then
151        cat >&2 <<__EOF__
152test stderr:
153--
154$(cat $STDERR)
155--
156__EOF__
157    fi
158fi
159
160rm -f $STDERR $STDOUT
161exit $RESULT
162