From 41aeaf2a3043622e90a6364be5dfe7be164258d9 Mon Sep 17 00:00:00 2001
From: Mark Johnston <markj@FreeBSD.org>
Date: Mon, 30 Mar 2015 04:01:49 +0000
Subject: [PATCH] Replace dtest.pl, the upstream DTrace test suite harness,
 with a shell script. This reimplementation is much simpler than dtest.pl and
 is more amenable to being run under Kyua - dtest.pl writes error output to a
 temporary directory that is deleted when the run finishes, making it hard to
 debug test failures. This change also removes the test suite's dependency on
 perl.

---
 cddl/usr.sbin/dtrace/tests/Makefile         |   6 +-
 cddl/usr.sbin/dtrace/tests/Makefile.inc1    |   1 -
 cddl/usr.sbin/dtrace/tests/tools/dtest.sh   | 129 ++++++++++++++++++++
 cddl/usr.sbin/dtrace/tests/tools/gentest.sh |   4 +-
 4 files changed, 133 insertions(+), 7 deletions(-)
 create mode 100755 cddl/usr.sbin/dtrace/tests/tools/dtest.sh

diff --git a/cddl/usr.sbin/dtrace/tests/Makefile b/cddl/usr.sbin/dtrace/tests/Makefile
index 252b6be3472e..dfd2b54e1e2c 100644
--- a/cddl/usr.sbin/dtrace/tests/Makefile
+++ b/cddl/usr.sbin/dtrace/tests/Makefile
@@ -8,10 +8,8 @@ TESTS_SUBDIRS+=	common
 .PATH:		${.CURDIR:H:H:H:H}/tests
 KYUAFILE=	YES
 
-.PATH:		${.CURDIR:H:H:H}/contrib/opensolaris/cmd/dtrace/test/cmd/scripts
+.PATH:		${.CURDIR}/tools
 SCRIPTSDIR=	${TESTSDIR}
-SCRIPTS=	dtest.pl
-
-SUBDIR_PARALLEL=
+SCRIPTS=	dtest.sh
 
 .include <bsd.test.mk>
diff --git a/cddl/usr.sbin/dtrace/tests/Makefile.inc1 b/cddl/usr.sbin/dtrace/tests/Makefile.inc1
index 9600a30e7464..6958f787343a 100644
--- a/cddl/usr.sbin/dtrace/tests/Makefile.inc1
+++ b/cddl/usr.sbin/dtrace/tests/Makefile.inc1
@@ -16,7 +16,6 @@ ${TESTGROUP}EXEDIR= ${TESTSDIR}
 
 TESTWRAPPER=	t_dtrace_contrib
 ATF_TESTS_SH+=	${TESTWRAPPER}
-TEST_METADATA.t_dtrace_contrib+= required_files="/usr/local/bin/perl"
 TEST_METADATA.t_dtrace_contrib+= required_files="/usr/local/bin/ksh"
 TEST_METADATA.t_dtrace_contrib+= required_user="root"
 
diff --git a/cddl/usr.sbin/dtrace/tests/tools/dtest.sh b/cddl/usr.sbin/dtrace/tests/tools/dtest.sh
new file mode 100755
index 000000000000..e60837b4ad08
--- /dev/null
+++ b/cddl/usr.sbin/dtrace/tests/tools/dtest.sh
@@ -0,0 +1,129 @@
+# $FreeBSD$
+
+usage()
+{
+    cat >&2 <<__EOF__
+A harness for test cases in the DTrace test suite.
+
+usage: $(basename $0) <testfile>
+__EOF__
+    exit 1
+}
+
+gettag()
+{
+    local tag
+
+    tag=$(basename $1)
+    tag=${tag#*.}
+    tag=${tag%%[a-z.]*}
+    echo $tag
+}
+
+runtest()
+{
+    local dflags exe exstatus pid retval status
+
+    exstatus=0
+    retval=0
+
+    case $TFILE in
+    drp.DTRACEDROP_*.d|err.*.d|tst.*.d)
+        case $TFILE in
+        drp.DTRACEDROP_*.d)
+            dflags="-x droptags"
+            tag=$(gettag "$TFILE")
+            ;;
+        err.D_*.d)
+            exstatus=1
+            dflags="-x errtags"
+            tag=$(gettag "$TFILE")
+            ;;
+        err.*.d)
+            exstatus=1
+            ;;
+        esac
+
+        exe=${TFILE%.*}.exe
+        if [ -f "$exe" -a -x "$exe" ]; then
+            ./$exe &
+            pid=$!
+            dflags="$dflags ${pid}"
+        fi
+
+        dtrace -C -s "${TFILE}" $dflags >$STDOUT 2>$STDERR
+        status=$?
+
+        if [ $status -ne $exstatus ]; then
+            ERRMSG="dtrace exited with status ${status}, expected ${exstatus}"
+            retval=1
+        elif [ -n "${tag}" ] && ! grep -Fq " [${tag}] " ${STDERR}; then
+            ERRMSG="dtrace's error output did not contain expected tag ${tag}"
+            retval=1
+        fi
+
+        if [ -n "$pid" ]; then
+            kill -0 $pid >/dev/null 2>&1 && kill -9 $pid >/dev/null 2>&1
+            wait
+        fi
+        ;;
+    err.*.ksh|tst.*.ksh)
+        expr "$TFILE" : 'err.*' >/dev/null && exstatus=1
+
+        ksh "$TFILE" /usr/sbin/dtrace >$STDOUT 2>$STDERR
+        status=$?
+
+        if [ $status -ne $exstatus ]; then
+            ERRMSG="script exited with status ${status}, expected ${exstatus}"
+            retval=1
+        fi
+        ;;
+    *)
+        ERRMSG="unexpected test file name $TFILE"
+        retval=1
+        ;;
+    esac
+
+    return $retval
+}
+
+[ $# -eq 1 ] || usage
+
+readonly STDERR=$(mktemp)
+readonly STDOUT=$(mktemp)
+readonly TFILE=$(basename $1)
+readonly EXOUT=${TFILE}.out
+
+kldstat -q -m dtrace_test || kldload dtrace_test
+cd $(dirname $1)
+runtest
+RESULT=$?
+
+if [ $RESULT -eq 0 -a -f $EXOUT -a -r $EXOUT ] && \
+   ! cmp $STDOUT $EXOUT >/dev/null 2>&1; then
+    ERRMSG="test output mismatch"
+    RESULT=1
+fi
+
+if [ $RESULT -ne 0 ]; then
+    echo "test $TFILE failed: $ERRMSG" >&2
+    if [ $(stat -f '%z' $STDOUT) -gt 0 ]; then
+        cat >&2 <<__EOF__
+test stdout:
+--
+$(cat $STDOUT)
+--
+__EOF__
+    fi
+    if [ $(stat -f '%z' $STDERR) -gt 0 ]; then
+        cat >&2 <<__EOF__
+test stderr:
+--
+$(cat $STDERR)
+--
+__EOF__
+    fi
+fi
+
+rm -f $STDERR $STDOUT
+exit $RESULT
diff --git a/cddl/usr.sbin/dtrace/tests/tools/gentest.sh b/cddl/usr.sbin/dtrace/tests/tools/gentest.sh
index a63f7465a986..9c34b79f547d 100755
--- a/cddl/usr.sbin/dtrace/tests/tools/gentest.sh
+++ b/cddl/usr.sbin/dtrace/tests/tools/gentest.sh
@@ -33,8 +33,8 @@ ${tcase}_head()
 ${tcase}_body()
 {
     $mod
-    atf_check -s exit:0 -o ignore -e ignore \\
-        "\$(atf_get_srcdir)/../../dtest" -n "\$(atf_get_srcdir)/${tfile}"
+    atf_check -s exit:0 -o empty -e empty \\
+        "\$(atf_get_srcdir)/../../dtest" "\$(atf_get_srcdir)/${tfile}"
 }
 __EOF__
 }