xref: /freebsd/sys/contrib/openzfs/scripts/zfs-tests.sh (revision eda14cbc264d6969b02f2b1994cef11148e914f1)
1*eda14cbcSMatt Macy#!/bin/sh
2*eda14cbcSMatt Macy#
3*eda14cbcSMatt Macy# CDDL HEADER START
4*eda14cbcSMatt Macy#
5*eda14cbcSMatt Macy# The contents of this file are subject to the terms of the
6*eda14cbcSMatt Macy# Common Development and Distribution License, Version 1.0 only
7*eda14cbcSMatt Macy# (the "License").  You may not use this file except in compliance
8*eda14cbcSMatt Macy# with the License.
9*eda14cbcSMatt Macy#
10*eda14cbcSMatt Macy# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
11*eda14cbcSMatt Macy# or http://www.opensolaris.org/os/licensing.
12*eda14cbcSMatt Macy# See the License for the specific language governing permissions
13*eda14cbcSMatt Macy# and limitations under the License.
14*eda14cbcSMatt Macy#
15*eda14cbcSMatt Macy# When distributing Covered Code, include this CDDL HEADER in each
16*eda14cbcSMatt Macy# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
17*eda14cbcSMatt Macy# If applicable, add the following below this CDDL HEADER, with the
18*eda14cbcSMatt Macy# fields enclosed by brackets "[]" replaced with your own identifying
19*eda14cbcSMatt Macy# information: Portions Copyright [yyyy] [name of copyright owner]
20*eda14cbcSMatt Macy#
21*eda14cbcSMatt Macy# CDDL HEADER END
22*eda14cbcSMatt Macy#
23*eda14cbcSMatt Macy
24*eda14cbcSMatt MacyBASE_DIR=$(dirname "$0")
25*eda14cbcSMatt MacySCRIPT_COMMON=common.sh
26*eda14cbcSMatt Macyif [ -f "${BASE_DIR}/${SCRIPT_COMMON}" ]; then
27*eda14cbcSMatt Macy. "${BASE_DIR}/${SCRIPT_COMMON}"
28*eda14cbcSMatt Macyelse
29*eda14cbcSMatt Macyecho "Missing helper script ${SCRIPT_COMMON}" && exit 1
30*eda14cbcSMatt Macyfi
31*eda14cbcSMatt Macy
32*eda14cbcSMatt MacyPROG=zfs-tests.sh
33*eda14cbcSMatt MacyVERBOSE="no"
34*eda14cbcSMatt MacyQUIET=""
35*eda14cbcSMatt MacyCLEANUP="yes"
36*eda14cbcSMatt MacyCLEANUPALL="no"
37*eda14cbcSMatt MacyLOOPBACK="yes"
38*eda14cbcSMatt MacySTACK_TRACER="no"
39*eda14cbcSMatt MacyFILESIZE="4G"
40*eda14cbcSMatt MacyDEFAULT_RUNFILES="common.run,$(uname | tr '[:upper:]' '[:lower:]').run"
41*eda14cbcSMatt MacyRUNFILES=${RUNFILES:-$DEFAULT_RUNFILES}
42*eda14cbcSMatt MacyFILEDIR=${FILEDIR:-/var/tmp}
43*eda14cbcSMatt MacyDISKS=${DISKS:-""}
44*eda14cbcSMatt MacySINGLETEST=""
45*eda14cbcSMatt MacySINGLETESTUSER="root"
46*eda14cbcSMatt MacyTAGS=""
47*eda14cbcSMatt MacyITERATIONS=1
48*eda14cbcSMatt MacyZFS_DBGMSG="$STF_SUITE/callbacks/zfs_dbgmsg.ksh"
49*eda14cbcSMatt MacyZFS_DMESG="$STF_SUITE/callbacks/zfs_dmesg.ksh"
50*eda14cbcSMatt MacyUNAME=$(uname -s)
51*eda14cbcSMatt Macy
52*eda14cbcSMatt Macy# Override some defaults if on FreeBSD
53*eda14cbcSMatt Macyif [ "$UNAME" = "FreeBSD" ] ; then
54*eda14cbcSMatt Macy	TESTFAIL_CALLBACKS=${TESTFAIL_CALLBACKS:-"$ZFS_DMESG"}
55*eda14cbcSMatt Macy	LOSETUP=/sbin/mdconfig
56*eda14cbcSMatt Macy	DMSETUP=/sbin/gpart
57*eda14cbcSMatt Macyelse
58*eda14cbcSMatt Macy	ZFS_MMP="$STF_SUITE/callbacks/zfs_mmp.ksh"
59*eda14cbcSMatt Macy	TESTFAIL_CALLBACKS=${TESTFAIL_CALLBACKS:-"$ZFS_DBGMSG:$ZFS_DMESG:$ZFS_MMP"}
60*eda14cbcSMatt Macy	LOSETUP=${LOSETUP:-/sbin/losetup}
61*eda14cbcSMatt Macy	DMSETUP=${DMSETUP:-/sbin/dmsetup}
62*eda14cbcSMatt Macyfi
63*eda14cbcSMatt Macy
64*eda14cbcSMatt Macy#
65*eda14cbcSMatt Macy# Log an informational message when additional verbosity is enabled.
66*eda14cbcSMatt Macy#
67*eda14cbcSMatt Macymsg() {
68*eda14cbcSMatt Macy	if [ "$VERBOSE" = "yes" ]; then
69*eda14cbcSMatt Macy		echo "$@"
70*eda14cbcSMatt Macy	fi
71*eda14cbcSMatt Macy}
72*eda14cbcSMatt Macy
73*eda14cbcSMatt Macy#
74*eda14cbcSMatt Macy# Log a failure message, cleanup, and return an error.
75*eda14cbcSMatt Macy#
76*eda14cbcSMatt Macyfail() {
77*eda14cbcSMatt Macy	echo "$PROG: $1" >&2
78*eda14cbcSMatt Macy	cleanup
79*eda14cbcSMatt Macy	exit 1
80*eda14cbcSMatt Macy}
81*eda14cbcSMatt Macy
82*eda14cbcSMatt Macycleanup_freebsd_loopback() {
83*eda14cbcSMatt Macy	for TEST_LOOPBACK in ${LOOPBACKS}; do
84*eda14cbcSMatt Macy		if [ -c "/dev/${TEST_LOOPBACK}" ]; then
85*eda14cbcSMatt Macy			sudo "${LOSETUP}" -d -u "${TEST_LOOPBACK}" ||
86*eda14cbcSMatt Macy			    echo "Failed to destroy: ${TEST_LOOPBACK}"
87*eda14cbcSMatt Macy		fi
88*eda14cbcSMatt Macy	done
89*eda14cbcSMatt Macy}
90*eda14cbcSMatt Macy
91*eda14cbcSMatt Macycleanup_linux_loopback() {
92*eda14cbcSMatt Macy	for TEST_LOOPBACK in ${LOOPBACKS}; do
93*eda14cbcSMatt Macy		LOOP_DEV=$(basename "$TEST_LOOPBACK")
94*eda14cbcSMatt Macy		DM_DEV=$(sudo "${DMSETUP}" ls 2>/dev/null | \
95*eda14cbcSMatt Macy		    grep "${LOOP_DEV}" | cut -f1)
96*eda14cbcSMatt Macy
97*eda14cbcSMatt Macy		if [ -n "$DM_DEV" ]; then
98*eda14cbcSMatt Macy			sudo "${DMSETUP}" remove "${DM_DEV}" ||
99*eda14cbcSMatt Macy			    echo "Failed to remove: ${DM_DEV}"
100*eda14cbcSMatt Macy		fi
101*eda14cbcSMatt Macy
102*eda14cbcSMatt Macy		if [ -n "${TEST_LOOPBACK}" ]; then
103*eda14cbcSMatt Macy			sudo "${LOSETUP}" -d "${TEST_LOOPBACK}" ||
104*eda14cbcSMatt Macy			    echo "Failed to remove: ${TEST_LOOPBACK}"
105*eda14cbcSMatt Macy		fi
106*eda14cbcSMatt Macy	done
107*eda14cbcSMatt Macy}
108*eda14cbcSMatt Macy
109*eda14cbcSMatt Macy#
110*eda14cbcSMatt Macy# Attempt to remove loopback devices and files which where created earlier
111*eda14cbcSMatt Macy# by this script to run the test framework.  The '-k' option may be passed
112*eda14cbcSMatt Macy# to the script to suppress cleanup for debugging purposes.
113*eda14cbcSMatt Macy#
114*eda14cbcSMatt Macycleanup() {
115*eda14cbcSMatt Macy	if [ "$CLEANUP" = "no" ]; then
116*eda14cbcSMatt Macy		return 0
117*eda14cbcSMatt Macy	fi
118*eda14cbcSMatt Macy
119*eda14cbcSMatt Macy
120*eda14cbcSMatt Macy	if [ "$LOOPBACK" = "yes" ]; then
121*eda14cbcSMatt Macy		if [ "$UNAME" = "FreeBSD" ] ; then
122*eda14cbcSMatt Macy			cleanup_freebsd_loopback
123*eda14cbcSMatt Macy		else
124*eda14cbcSMatt Macy			cleanup_linux_loopback
125*eda14cbcSMatt Macy		fi
126*eda14cbcSMatt Macy	fi
127*eda14cbcSMatt Macy
128*eda14cbcSMatt Macy	for TEST_FILE in ${FILES}; do
129*eda14cbcSMatt Macy		rm -f "${TEST_FILE}" >/dev/null 2>&1
130*eda14cbcSMatt Macy	done
131*eda14cbcSMatt Macy
132*eda14cbcSMatt Macy	if [ "$STF_PATH_REMOVE" = "yes" ] && [ -d "$STF_PATH" ]; then
133*eda14cbcSMatt Macy		rm -Rf "$STF_PATH"
134*eda14cbcSMatt Macy	fi
135*eda14cbcSMatt Macy}
136*eda14cbcSMatt Macytrap cleanup EXIT
137*eda14cbcSMatt Macy
138*eda14cbcSMatt Macy#
139*eda14cbcSMatt Macy# Attempt to remove all testpools (testpool.XXX), unopened dm devices,
140*eda14cbcSMatt Macy# loopback devices, and files.  This is a useful way to cleanup a previous
141*eda14cbcSMatt Macy# test run failure which has left the system in an unknown state.  This can
142*eda14cbcSMatt Macy# be dangerous and should only be used in a dedicated test environment.
143*eda14cbcSMatt Macy#
144*eda14cbcSMatt Macycleanup_all() {
145*eda14cbcSMatt Macy	TEST_POOLS=$(sudo "$ZPOOL" list -H -o name | grep testpool)
146*eda14cbcSMatt Macy	if [ "$UNAME" = "FreeBSD" ] ; then
147*eda14cbcSMatt Macy		TEST_LOOPBACKS=$(sudo "${LOSETUP}" -l)
148*eda14cbcSMatt Macy	else
149*eda14cbcSMatt Macy		TEST_LOOPBACKS=$(sudo "${LOSETUP}" -a|grep file-vdev|cut -f1 -d:)
150*eda14cbcSMatt Macy	fi
151*eda14cbcSMatt Macy	TEST_FILES=$(ls /var/tmp/file-vdev* 2>/dev/null)
152*eda14cbcSMatt Macy
153*eda14cbcSMatt Macy	msg
154*eda14cbcSMatt Macy	msg "--- Cleanup ---"
155*eda14cbcSMatt Macy	msg "Removing pool(s):     $(echo "${TEST_POOLS}" | tr '\n' ' ')"
156*eda14cbcSMatt Macy	for TEST_POOL in $TEST_POOLS; do
157*eda14cbcSMatt Macy		sudo "$ZPOOL" destroy "${TEST_POOL}"
158*eda14cbcSMatt Macy	done
159*eda14cbcSMatt Macy
160*eda14cbcSMatt Macy	if [ "$UNAME" != "FreeBSD" ] ; then
161*eda14cbcSMatt Macy		msg "Removing dm(s):       $(sudo "${DMSETUP}" ls |
162*eda14cbcSMatt Macy		    grep loop | tr '\n' ' ')"
163*eda14cbcSMatt Macy		sudo "${DMSETUP}" remove_all
164*eda14cbcSMatt Macy	fi
165*eda14cbcSMatt Macy
166*eda14cbcSMatt Macy	msg "Removing loopback(s): $(echo "${TEST_LOOPBACKS}" | tr '\n' ' ')"
167*eda14cbcSMatt Macy	for TEST_LOOPBACK in $TEST_LOOPBACKS; do
168*eda14cbcSMatt Macy		if [ "$UNAME" = "FreeBSD" ] ; then
169*eda14cbcSMatt Macy			sudo "${LOSETUP}" -d -u "${TEST_LOOPBACK}"
170*eda14cbcSMatt Macy		else
171*eda14cbcSMatt Macy			sudo "${LOSETUP}" -d "${TEST_LOOPBACK}"
172*eda14cbcSMatt Macy		fi
173*eda14cbcSMatt Macy	done
174*eda14cbcSMatt Macy
175*eda14cbcSMatt Macy	msg "Removing files(s):    $(echo "${TEST_FILES}" | tr '\n' ' ')"
176*eda14cbcSMatt Macy	for TEST_FILE in $TEST_FILES; do
177*eda14cbcSMatt Macy		sudo rm -f "${TEST_FILE}"
178*eda14cbcSMatt Macy	done
179*eda14cbcSMatt Macy}
180*eda14cbcSMatt Macy
181*eda14cbcSMatt Macy#
182*eda14cbcSMatt Macy# Takes a name as the only arguments and looks for the following variations
183*eda14cbcSMatt Macy# on that name.  If one is found it is returned.
184*eda14cbcSMatt Macy#
185*eda14cbcSMatt Macy# $RUNFILE_DIR/<name>
186*eda14cbcSMatt Macy# $RUNFILE_DIR/<name>.run
187*eda14cbcSMatt Macy# <name>
188*eda14cbcSMatt Macy# <name>.run
189*eda14cbcSMatt Macy#
190*eda14cbcSMatt Macyfind_runfile() {
191*eda14cbcSMatt Macy	NAME=$1
192*eda14cbcSMatt Macy	RESULT=""
193*eda14cbcSMatt Macy
194*eda14cbcSMatt Macy	if [ -f "$RUNFILE_DIR/$NAME" ]; then
195*eda14cbcSMatt Macy		RESULT="$RUNFILE_DIR/$NAME"
196*eda14cbcSMatt Macy	elif [ -f "$RUNFILE_DIR/$NAME.run" ]; then
197*eda14cbcSMatt Macy		RESULT="$RUNFILE_DIR/$NAME.run"
198*eda14cbcSMatt Macy	elif [ -f "$NAME" ]; then
199*eda14cbcSMatt Macy		RESULT="$NAME"
200*eda14cbcSMatt Macy	elif [ -f "$NAME.run" ]; then
201*eda14cbcSMatt Macy		RESULT="$NAME.run"
202*eda14cbcSMatt Macy	fi
203*eda14cbcSMatt Macy
204*eda14cbcSMatt Macy	echo "$RESULT"
205*eda14cbcSMatt Macy}
206*eda14cbcSMatt Macy
207*eda14cbcSMatt Macy#
208*eda14cbcSMatt Macy# Symlink file if it appears under any of the given paths.
209*eda14cbcSMatt Macy#
210*eda14cbcSMatt Macycreate_links() {
211*eda14cbcSMatt Macy	dir_list="$1"
212*eda14cbcSMatt Macy	file_list="$2"
213*eda14cbcSMatt Macy
214*eda14cbcSMatt Macy	[ -n "$STF_PATH" ] || fail "STF_PATH wasn't correctly set"
215*eda14cbcSMatt Macy
216*eda14cbcSMatt Macy	for i in $file_list; do
217*eda14cbcSMatt Macy		for j in $dir_list; do
218*eda14cbcSMatt Macy			[ ! -e "$STF_PATH/$i" ] || continue
219*eda14cbcSMatt Macy
220*eda14cbcSMatt Macy			if [ ! -d "$j/$i" ] && [ -e "$j/$i" ]; then
221*eda14cbcSMatt Macy				ln -sf "$j/$i" "$STF_PATH/$i" || \
222*eda14cbcSMatt Macy				    fail "Couldn't link $i"
223*eda14cbcSMatt Macy				break
224*eda14cbcSMatt Macy			fi
225*eda14cbcSMatt Macy		done
226*eda14cbcSMatt Macy
227*eda14cbcSMatt Macy		[ ! -e "$STF_PATH/$i" ] && \
228*eda14cbcSMatt Macy		    STF_MISSING_BIN="$STF_MISSING_BIN $i"
229*eda14cbcSMatt Macy	done
230*eda14cbcSMatt Macy	STF_MISSING_BIN=${STF_MISSING_BIN# }
231*eda14cbcSMatt Macy}
232*eda14cbcSMatt Macy
233*eda14cbcSMatt Macy#
234*eda14cbcSMatt Macy# Constrain the path to limit the available binaries to a known set.
235*eda14cbcSMatt Macy# When running in-tree a top level ./bin/ directory is created for
236*eda14cbcSMatt Macy# convenience, otherwise a temporary directory is used.
237*eda14cbcSMatt Macy#
238*eda14cbcSMatt Macyconstrain_path() {
239*eda14cbcSMatt Macy	. "$STF_SUITE/include/commands.cfg"
240*eda14cbcSMatt Macy
241*eda14cbcSMatt Macy	# On FreeBSD, base system zfs utils are in /sbin and OpenZFS utils
242*eda14cbcSMatt Macy	# install to /usr/local/sbin. To avoid testing the wrong utils we
243*eda14cbcSMatt Macy	# need /usr/local to come before / in the path search order.
244*eda14cbcSMatt Macy	SYSTEM_DIRS="/usr/local/bin /usr/local/sbin"
245*eda14cbcSMatt Macy	SYSTEM_DIRS="$SYSTEM_DIRS /usr/bin /usr/sbin /bin /sbin"
246*eda14cbcSMatt Macy
247*eda14cbcSMatt Macy	if [ "$INTREE" = "yes" ]; then
248*eda14cbcSMatt Macy		# Constrained path set to ./zfs/bin/
249*eda14cbcSMatt Macy		STF_PATH="$BIN_DIR"
250*eda14cbcSMatt Macy		STF_PATH_REMOVE="no"
251*eda14cbcSMatt Macy		STF_MISSING_BIN=""
252*eda14cbcSMatt Macy		if [ ! -d "$STF_PATH" ]; then
253*eda14cbcSMatt Macy			mkdir "$STF_PATH"
254*eda14cbcSMatt Macy			chmod 755 "$STF_PATH" || fail "Couldn't chmod $STF_PATH"
255*eda14cbcSMatt Macy		fi
256*eda14cbcSMatt Macy
257*eda14cbcSMatt Macy		# Special case links for standard zfs utilities
258*eda14cbcSMatt Macy		DIRS="$(find "$CMD_DIR" -type d \( ! -name .deps -a \
259*eda14cbcSMatt Macy		    ! -name .libs \) -print | tr '\n' ' ')"
260*eda14cbcSMatt Macy		create_links "$DIRS" "$ZFS_FILES"
261*eda14cbcSMatt Macy
262*eda14cbcSMatt Macy		# Special case links for zfs test suite utilities
263*eda14cbcSMatt Macy		DIRS="$(find "$STF_SUITE" -type d \( ! -name .deps -a \
264*eda14cbcSMatt Macy		    ! -name .libs \) -print | tr '\n' ' ')"
265*eda14cbcSMatt Macy		create_links "$DIRS" "$ZFSTEST_FILES"
266*eda14cbcSMatt Macy	else
267*eda14cbcSMatt Macy		# Constrained path set to /var/tmp/constrained_path.*
268*eda14cbcSMatt Macy		SYSTEMDIR=${SYSTEMDIR:-/var/tmp/constrained_path.XXXX}
269*eda14cbcSMatt Macy		STF_PATH=$(mktemp -d "$SYSTEMDIR")
270*eda14cbcSMatt Macy		STF_PATH_REMOVE="yes"
271*eda14cbcSMatt Macy		STF_MISSING_BIN=""
272*eda14cbcSMatt Macy
273*eda14cbcSMatt Macy		chmod 755 "$STF_PATH" || fail "Couldn't chmod $STF_PATH"
274*eda14cbcSMatt Macy
275*eda14cbcSMatt Macy		# Special case links for standard zfs utilities
276*eda14cbcSMatt Macy		create_links "$SYSTEM_DIRS" "$ZFS_FILES"
277*eda14cbcSMatt Macy
278*eda14cbcSMatt Macy		# Special case links for zfs test suite utilities
279*eda14cbcSMatt Macy		create_links "$STF_SUITE/bin" "$ZFSTEST_FILES"
280*eda14cbcSMatt Macy	fi
281*eda14cbcSMatt Macy
282*eda14cbcSMatt Macy	# Standard system utilities
283*eda14cbcSMatt Macy	SYSTEM_FILES="$SYSTEM_FILES_COMMON"
284*eda14cbcSMatt Macy	if [ "$UNAME" = "FreeBSD" ] ; then
285*eda14cbcSMatt Macy		SYSTEM_FILES="$SYSTEM_FILES $SYSTEM_FILES_FREEBSD"
286*eda14cbcSMatt Macy	else
287*eda14cbcSMatt Macy		SYSTEM_FILES="$SYSTEM_FILES $SYSTEM_FILES_LINUX"
288*eda14cbcSMatt Macy	fi
289*eda14cbcSMatt Macy	create_links "$SYSTEM_DIRS" "$SYSTEM_FILES"
290*eda14cbcSMatt Macy
291*eda14cbcSMatt Macy	# Exceptions
292*eda14cbcSMatt Macy	ln -fs "$STF_PATH/awk" "$STF_PATH/nawk"
293*eda14cbcSMatt Macy	if [ "$UNAME" = "Linux" ] ; then
294*eda14cbcSMatt Macy		ln -fs /sbin/fsck.ext4 "$STF_PATH/fsck"
295*eda14cbcSMatt Macy		ln -fs /sbin/mkfs.ext4 "$STF_PATH/newfs"
296*eda14cbcSMatt Macy		ln -fs "$STF_PATH/gzip" "$STF_PATH/compress"
297*eda14cbcSMatt Macy		ln -fs "$STF_PATH/gunzip" "$STF_PATH/uncompress"
298*eda14cbcSMatt Macy		ln -fs "$STF_PATH/exportfs" "$STF_PATH/share"
299*eda14cbcSMatt Macy		ln -fs "$STF_PATH/exportfs" "$STF_PATH/unshare"
300*eda14cbcSMatt Macy	elif [ "$UNAME" = "FreeBSD" ] ; then
301*eda14cbcSMatt Macy		ln -fs /usr/local/bin/ksh93 "$STF_PATH/ksh"
302*eda14cbcSMatt Macy	fi
303*eda14cbcSMatt Macy}
304*eda14cbcSMatt Macy
305*eda14cbcSMatt Macy#
306*eda14cbcSMatt Macy# Output a useful usage message.
307*eda14cbcSMatt Macy#
308*eda14cbcSMatt Macyusage() {
309*eda14cbcSMatt Macycat << EOF
310*eda14cbcSMatt MacyUSAGE:
311*eda14cbcSMatt Macy$0 [hvqxkfS] [-s SIZE] [-r RUNFILES] [-t PATH] [-u USER]
312*eda14cbcSMatt Macy
313*eda14cbcSMatt MacyDESCRIPTION:
314*eda14cbcSMatt Macy	ZFS Test Suite launch script
315*eda14cbcSMatt Macy
316*eda14cbcSMatt MacyOPTIONS:
317*eda14cbcSMatt Macy	-h          Show this message
318*eda14cbcSMatt Macy	-v          Verbose zfs-tests.sh output
319*eda14cbcSMatt Macy	-q          Quiet test-runner output
320*eda14cbcSMatt Macy	-x          Remove all testpools, dm, lo, and files (unsafe)
321*eda14cbcSMatt Macy	-k          Disable cleanup after test failure
322*eda14cbcSMatt Macy	-f          Use files only, disables block device tests
323*eda14cbcSMatt Macy	-S          Enable stack tracer (negative performance impact)
324*eda14cbcSMatt Macy	-c          Only create and populate constrained path
325*eda14cbcSMatt Macy	-n NFSFILE  Use the nfsfile to determine the NFS configuration
326*eda14cbcSMatt Macy	-I NUM      Number of iterations
327*eda14cbcSMatt Macy	-d DIR      Use DIR for files and loopback devices
328*eda14cbcSMatt Macy	-s SIZE     Use vdevs of SIZE (default: 4G)
329*eda14cbcSMatt Macy	-r RUNFILES Run tests in RUNFILES (default: ${DEFAULT_RUNFILES})
330*eda14cbcSMatt Macy	-t PATH     Run single test at PATH relative to test suite
331*eda14cbcSMatt Macy	-T TAGS     Comma separated list of tags (default: 'functional')
332*eda14cbcSMatt Macy	-u USER     Run single test as USER (default: root)
333*eda14cbcSMatt Macy
334*eda14cbcSMatt MacyEXAMPLES:
335*eda14cbcSMatt Macy# Run the default (linux) suite of tests and output the configuration used.
336*eda14cbcSMatt Macy$0 -v
337*eda14cbcSMatt Macy
338*eda14cbcSMatt Macy# Run a smaller suite of tests designed to run more quickly.
339*eda14cbcSMatt Macy$0 -r linux-fast
340*eda14cbcSMatt Macy
341*eda14cbcSMatt Macy# Run a single test
342*eda14cbcSMatt Macy$0 -t tests/functional/cli_root/zfs_bookmark/zfs_bookmark_cliargs.ksh
343*eda14cbcSMatt Macy
344*eda14cbcSMatt Macy# Cleanup a previous run of the test suite prior to testing, run the
345*eda14cbcSMatt Macy# default (linux) suite of tests and perform no cleanup on exit.
346*eda14cbcSMatt Macy$0 -x
347*eda14cbcSMatt Macy
348*eda14cbcSMatt MacyEOF
349*eda14cbcSMatt Macy}
350*eda14cbcSMatt Macy
351*eda14cbcSMatt Macywhile getopts 'hvqxkfScn:d:s:r:?t:T:u:I:' OPTION; do
352*eda14cbcSMatt Macy	case $OPTION in
353*eda14cbcSMatt Macy	h)
354*eda14cbcSMatt Macy		usage
355*eda14cbcSMatt Macy		exit 1
356*eda14cbcSMatt Macy		;;
357*eda14cbcSMatt Macy	v)
358*eda14cbcSMatt Macy		# shellcheck disable=SC2034
359*eda14cbcSMatt Macy		VERBOSE="yes"
360*eda14cbcSMatt Macy		;;
361*eda14cbcSMatt Macy	q)
362*eda14cbcSMatt Macy		QUIET="yes"
363*eda14cbcSMatt Macy		;;
364*eda14cbcSMatt Macy	x)
365*eda14cbcSMatt Macy		CLEANUPALL="yes"
366*eda14cbcSMatt Macy		;;
367*eda14cbcSMatt Macy	k)
368*eda14cbcSMatt Macy		CLEANUP="no"
369*eda14cbcSMatt Macy		;;
370*eda14cbcSMatt Macy	f)
371*eda14cbcSMatt Macy		LOOPBACK="no"
372*eda14cbcSMatt Macy		;;
373*eda14cbcSMatt Macy	S)
374*eda14cbcSMatt Macy		STACK_TRACER="yes"
375*eda14cbcSMatt Macy		;;
376*eda14cbcSMatt Macy	c)
377*eda14cbcSMatt Macy		constrain_path
378*eda14cbcSMatt Macy		exit
379*eda14cbcSMatt Macy		;;
380*eda14cbcSMatt Macy	n)
381*eda14cbcSMatt Macy		nfsfile=$OPTARG
382*eda14cbcSMatt Macy		[ -f "$nfsfile" ] || fail "Cannot read file: $nfsfile"
383*eda14cbcSMatt Macy		export NFS=1
384*eda14cbcSMatt Macy		. "$nfsfile"
385*eda14cbcSMatt Macy		;;
386*eda14cbcSMatt Macy	d)
387*eda14cbcSMatt Macy		FILEDIR="$OPTARG"
388*eda14cbcSMatt Macy		;;
389*eda14cbcSMatt Macy	I)
390*eda14cbcSMatt Macy		ITERATIONS="$OPTARG"
391*eda14cbcSMatt Macy		if [ "$ITERATIONS" -le 0 ]; then
392*eda14cbcSMatt Macy			fail "Iterations must be greater than 0."
393*eda14cbcSMatt Macy		fi
394*eda14cbcSMatt Macy		;;
395*eda14cbcSMatt Macy	s)
396*eda14cbcSMatt Macy		FILESIZE="$OPTARG"
397*eda14cbcSMatt Macy		;;
398*eda14cbcSMatt Macy	r)
399*eda14cbcSMatt Macy		RUNFILES="$OPTARG"
400*eda14cbcSMatt Macy		;;
401*eda14cbcSMatt Macy	t)
402*eda14cbcSMatt Macy		if [ -n "$SINGLETEST" ]; then
403*eda14cbcSMatt Macy			fail "-t can only be provided once."
404*eda14cbcSMatt Macy		fi
405*eda14cbcSMatt Macy		SINGLETEST="$OPTARG"
406*eda14cbcSMatt Macy		;;
407*eda14cbcSMatt Macy	T)
408*eda14cbcSMatt Macy		TAGS="$OPTARG"
409*eda14cbcSMatt Macy		;;
410*eda14cbcSMatt Macy	u)
411*eda14cbcSMatt Macy		SINGLETESTUSER="$OPTARG"
412*eda14cbcSMatt Macy		;;
413*eda14cbcSMatt Macy	?)
414*eda14cbcSMatt Macy		usage
415*eda14cbcSMatt Macy		exit
416*eda14cbcSMatt Macy		;;
417*eda14cbcSMatt Macy	esac
418*eda14cbcSMatt Macydone
419*eda14cbcSMatt Macy
420*eda14cbcSMatt Macyshift $((OPTIND-1))
421*eda14cbcSMatt Macy
422*eda14cbcSMatt MacyFILES=${FILES:-"$FILEDIR/file-vdev0 $FILEDIR/file-vdev1 $FILEDIR/file-vdev2"}
423*eda14cbcSMatt MacyLOOPBACKS=${LOOPBACKS:-""}
424*eda14cbcSMatt Macy
425*eda14cbcSMatt Macyif [ -n "$SINGLETEST" ]; then
426*eda14cbcSMatt Macy	if [ -n "$TAGS" ]; then
427*eda14cbcSMatt Macy		fail "-t and -T are mutually exclusive."
428*eda14cbcSMatt Macy	fi
429*eda14cbcSMatt Macy	RUNFILE_DIR="/var/tmp"
430*eda14cbcSMatt Macy	RUNFILES="zfs-tests.$$.run"
431*eda14cbcSMatt Macy	SINGLEQUIET="False"
432*eda14cbcSMatt Macy
433*eda14cbcSMatt Macy	if [ -n "$QUIET" ]; then
434*eda14cbcSMatt Macy		SINGLEQUIET="True"
435*eda14cbcSMatt Macy	fi
436*eda14cbcSMatt Macy
437*eda14cbcSMatt Macy	cat >$RUNFILE_DIR/$RUNFILES << EOF
438*eda14cbcSMatt Macy[DEFAULT]
439*eda14cbcSMatt Macypre =
440*eda14cbcSMatt Macyquiet = $SINGLEQUIET
441*eda14cbcSMatt Macypre_user = root
442*eda14cbcSMatt Macyuser = $SINGLETESTUSER
443*eda14cbcSMatt Macytimeout = 600
444*eda14cbcSMatt Macypost_user = root
445*eda14cbcSMatt Macypost =
446*eda14cbcSMatt Macyoutputdir = /var/tmp/test_results
447*eda14cbcSMatt MacyEOF
448*eda14cbcSMatt Macy	SINGLETESTDIR=$(dirname "$SINGLETEST")
449*eda14cbcSMatt Macy	SINGLETESTFILE=$(basename "$SINGLETEST")
450*eda14cbcSMatt Macy	SETUPSCRIPT=
451*eda14cbcSMatt Macy	CLEANUPSCRIPT=
452*eda14cbcSMatt Macy
453*eda14cbcSMatt Macy	if [ -f "$STF_SUITE/$SINGLETESTDIR/setup.ksh" ]; then
454*eda14cbcSMatt Macy		SETUPSCRIPT="setup"
455*eda14cbcSMatt Macy	fi
456*eda14cbcSMatt Macy
457*eda14cbcSMatt Macy	if [ -f "$STF_SUITE/$SINGLETESTDIR/cleanup.ksh" ]; then
458*eda14cbcSMatt Macy		CLEANUPSCRIPT="cleanup"
459*eda14cbcSMatt Macy	fi
460*eda14cbcSMatt Macy
461*eda14cbcSMatt Macy	cat >>$RUNFILE_DIR/$RUNFILES << EOF
462*eda14cbcSMatt Macy
463*eda14cbcSMatt Macy[$SINGLETESTDIR]
464*eda14cbcSMatt Macytests = ['$SINGLETESTFILE']
465*eda14cbcSMatt Macypre = $SETUPSCRIPT
466*eda14cbcSMatt Macypost = $CLEANUPSCRIPT
467*eda14cbcSMatt Macytags = ['functional']
468*eda14cbcSMatt MacyEOF
469*eda14cbcSMatt Macyfi
470*eda14cbcSMatt Macy
471*eda14cbcSMatt Macy#
472*eda14cbcSMatt Macy# Use default tag if none was specified
473*eda14cbcSMatt Macy#
474*eda14cbcSMatt MacyTAGS=${TAGS:='functional'}
475*eda14cbcSMatt Macy
476*eda14cbcSMatt Macy#
477*eda14cbcSMatt Macy# Attempt to locate the runfiles describing the test workload.
478*eda14cbcSMatt Macy#
479*eda14cbcSMatt MacyR=""
480*eda14cbcSMatt MacyIFS=,
481*eda14cbcSMatt Macyfor RUNFILE in $RUNFILES; do
482*eda14cbcSMatt Macy	if [ -n "$RUNFILE" ]; then
483*eda14cbcSMatt Macy		SAVED_RUNFILE="$RUNFILE"
484*eda14cbcSMatt Macy		RUNFILE=$(find_runfile "$RUNFILE")
485*eda14cbcSMatt Macy		[ -z "$RUNFILE" ] && fail "Cannot find runfile: $SAVED_RUNFILE"
486*eda14cbcSMatt Macy		R="$R,$RUNFILE"
487*eda14cbcSMatt Macy	fi
488*eda14cbcSMatt Macy
489*eda14cbcSMatt Macy	if [ ! -r "$RUNFILE" ]; then
490*eda14cbcSMatt Macy		fail "Cannot read runfile: $RUNFILE"
491*eda14cbcSMatt Macy	fi
492*eda14cbcSMatt Macydone
493*eda14cbcSMatt Macyunset IFS
494*eda14cbcSMatt MacyRUNFILES=${R#,}
495*eda14cbcSMatt Macy
496*eda14cbcSMatt Macy#
497*eda14cbcSMatt Macy# This script should not be run as root.  Instead the test user, which may
498*eda14cbcSMatt Macy# be a normal user account, needs to be configured such that it can
499*eda14cbcSMatt Macy# run commands via sudo passwordlessly.
500*eda14cbcSMatt Macy#
501*eda14cbcSMatt Macyif [ "$(id -u)" = "0" ]; then
502*eda14cbcSMatt Macy	fail "This script must not be run as root."
503*eda14cbcSMatt Macyfi
504*eda14cbcSMatt Macy
505*eda14cbcSMatt Macyif [ "$(sudo whoami)" != "root" ]; then
506*eda14cbcSMatt Macy	fail "Passwordless sudo access required."
507*eda14cbcSMatt Macyfi
508*eda14cbcSMatt Macy
509*eda14cbcSMatt Macy#
510*eda14cbcSMatt Macy# Constrain the available binaries to a known set.
511*eda14cbcSMatt Macy#
512*eda14cbcSMatt Macyconstrain_path
513*eda14cbcSMatt Macy
514*eda14cbcSMatt Macy#
515*eda14cbcSMatt Macy# Check if ksh exists
516*eda14cbcSMatt Macy#
517*eda14cbcSMatt Macyif [ "$UNAME" = "FreeBSD" ]; then
518*eda14cbcSMatt Macy	sudo ln -fs /usr/local/bin/ksh93 /bin/ksh
519*eda14cbcSMatt Macyfi
520*eda14cbcSMatt Macy[ -e "$STF_PATH/ksh" ] || fail "This test suite requires ksh."
521*eda14cbcSMatt Macy[ -e "$STF_SUITE/include/default.cfg" ] || fail \
522*eda14cbcSMatt Macy    "Missing $STF_SUITE/include/default.cfg file."
523*eda14cbcSMatt Macy
524*eda14cbcSMatt Macy#
525*eda14cbcSMatt Macy# Verify the ZFS module stack is loaded.
526*eda14cbcSMatt Macy#
527*eda14cbcSMatt Macyif [ "$STACK_TRACER" = "yes" ]; then
528*eda14cbcSMatt Macy	sudo "${ZFS_SH}" -S >/dev/null 2>&1
529*eda14cbcSMatt Macyelse
530*eda14cbcSMatt Macy	sudo "${ZFS_SH}" >/dev/null 2>&1
531*eda14cbcSMatt Macyfi
532*eda14cbcSMatt Macy
533*eda14cbcSMatt Macy#
534*eda14cbcSMatt Macy# Attempt to cleanup all previous state for a new test run.
535*eda14cbcSMatt Macy#
536*eda14cbcSMatt Macyif [ "$CLEANUPALL" = "yes" ]; then
537*eda14cbcSMatt Macy	cleanup_all
538*eda14cbcSMatt Macyfi
539*eda14cbcSMatt Macy
540*eda14cbcSMatt Macy#
541*eda14cbcSMatt Macy# By default preserve any existing pools
542*eda14cbcSMatt Macy# NOTE: Since 'zpool list' outputs a newline-delimited list convert $KEEP from
543*eda14cbcSMatt Macy# space-delimited to newline-delimited.
544*eda14cbcSMatt Macy#
545*eda14cbcSMatt Macyif [ -z "${KEEP}" ]; then
546*eda14cbcSMatt Macy	KEEP="$(sudo "$ZPOOL" list -H -o name)"
547*eda14cbcSMatt Macy	if [ -z "${KEEP}" ]; then
548*eda14cbcSMatt Macy		KEEP="rpool"
549*eda14cbcSMatt Macy	fi
550*eda14cbcSMatt Macyelse
551*eda14cbcSMatt Macy	KEEP="$(echo "$KEEP" | tr '[:blank:]' '\n')"
552*eda14cbcSMatt Macyfi
553*eda14cbcSMatt Macy
554*eda14cbcSMatt Macy#
555*eda14cbcSMatt Macy# NOTE: The following environment variables are undocumented
556*eda14cbcSMatt Macy# and should be used for testing purposes only:
557*eda14cbcSMatt Macy#
558*eda14cbcSMatt Macy# __ZFS_POOL_EXCLUDE - don't iterate over the pools it lists
559*eda14cbcSMatt Macy# __ZFS_POOL_RESTRICT - iterate only over the pools it lists
560*eda14cbcSMatt Macy#
561*eda14cbcSMatt Macy# See libzfs/libzfs_config.c for more information.
562*eda14cbcSMatt Macy#
563*eda14cbcSMatt Macyif [ "$UNAME" = "FreeBSD" ] ; then
564*eda14cbcSMatt Macy	__ZFS_POOL_EXCLUDE="$(echo "$KEEP" | tr -s '\n' ' ')"
565*eda14cbcSMatt Macyelse
566*eda14cbcSMatt Macy	__ZFS_POOL_EXCLUDE="$(echo "$KEEP" | sed ':a;N;s/\n/ /g;ba')"
567*eda14cbcSMatt Macyfi
568*eda14cbcSMatt Macy
569*eda14cbcSMatt Macy. "$STF_SUITE/include/default.cfg"
570*eda14cbcSMatt Macy
571*eda14cbcSMatt Macymsg
572*eda14cbcSMatt Macymsg "--- Configuration ---"
573*eda14cbcSMatt Macymsg "Runfiles:        $RUNFILES"
574*eda14cbcSMatt Macymsg "STF_TOOLS:       $STF_TOOLS"
575*eda14cbcSMatt Macymsg "STF_SUITE:       $STF_SUITE"
576*eda14cbcSMatt Macymsg "STF_PATH:        $STF_PATH"
577*eda14cbcSMatt Macy
578*eda14cbcSMatt Macy#
579*eda14cbcSMatt Macy# No DISKS have been provided so a basic file or loopback based devices
580*eda14cbcSMatt Macy# must be created for the test suite to use.
581*eda14cbcSMatt Macy#
582*eda14cbcSMatt Macyif [ -z "${DISKS}" ]; then
583*eda14cbcSMatt Macy	#
584*eda14cbcSMatt Macy	# Create sparse files for the test suite.  These may be used
585*eda14cbcSMatt Macy	# directory or have loopback devices layered on them.
586*eda14cbcSMatt Macy	#
587*eda14cbcSMatt Macy	for TEST_FILE in ${FILES}; do
588*eda14cbcSMatt Macy		[ -f "$TEST_FILE" ] && fail "Failed file exists: ${TEST_FILE}"
589*eda14cbcSMatt Macy		truncate -s "${FILESIZE}" "${TEST_FILE}" ||
590*eda14cbcSMatt Macy		    fail "Failed creating: ${TEST_FILE} ($?)"
591*eda14cbcSMatt Macy	done
592*eda14cbcSMatt Macy
593*eda14cbcSMatt Macy	#
594*eda14cbcSMatt Macy	# If requested setup loopback devices backed by the sparse files.
595*eda14cbcSMatt Macy	#
596*eda14cbcSMatt Macy	if [ "$LOOPBACK" = "yes" ]; then
597*eda14cbcSMatt Macy		test -x "$LOSETUP" || fail "$LOSETUP utility must be installed"
598*eda14cbcSMatt Macy
599*eda14cbcSMatt Macy		for TEST_FILE in ${FILES}; do
600*eda14cbcSMatt Macy			if [ "$UNAME" = "FreeBSD" ] ; then
601*eda14cbcSMatt Macy				MDDEVICE=$(sudo "${LOSETUP}" -a -t vnode -f "${TEST_FILE}")
602*eda14cbcSMatt Macy				if [ -z "$MDDEVICE" ] ; then
603*eda14cbcSMatt Macy					fail "Failed: ${TEST_FILE} -> loopback"
604*eda14cbcSMatt Macy				fi
605*eda14cbcSMatt Macy				DISKS="$DISKS $MDDEVICE"
606*eda14cbcSMatt Macy				LOOPBACKS="$LOOPBACKS $MDDEVICE"
607*eda14cbcSMatt Macy			else
608*eda14cbcSMatt Macy				TEST_LOOPBACK=$(sudo "${LOSETUP}" -f)
609*eda14cbcSMatt Macy				sudo "${LOSETUP}" "${TEST_LOOPBACK}" "${TEST_FILE}" ||
610*eda14cbcSMatt Macy				    fail "Failed: ${TEST_FILE} -> ${TEST_LOOPBACK}"
611*eda14cbcSMatt Macy				BASELOOPBACK=$(basename "$TEST_LOOPBACK")
612*eda14cbcSMatt Macy				DISKS="$DISKS $BASELOOPBACK"
613*eda14cbcSMatt Macy				LOOPBACKS="$LOOPBACKS $TEST_LOOPBACK"
614*eda14cbcSMatt Macy			fi
615*eda14cbcSMatt Macy		done
616*eda14cbcSMatt Macy		DISKS=${DISKS# }
617*eda14cbcSMatt Macy		LOOPBACKS=${LOOPBACKS# }
618*eda14cbcSMatt Macy	else
619*eda14cbcSMatt Macy		DISKS="$FILES"
620*eda14cbcSMatt Macy	fi
621*eda14cbcSMatt Macyfi
622*eda14cbcSMatt Macy
623*eda14cbcSMatt MacyNUM_DISKS=$(echo "${DISKS}" | awk '{print NF}')
624*eda14cbcSMatt Macy[ "$NUM_DISKS" -lt 3 ] && fail "Not enough disks ($NUM_DISKS/3 minimum)"
625*eda14cbcSMatt Macy
626*eda14cbcSMatt Macy#
627*eda14cbcSMatt Macy# Disable SELinux until the ZFS Test Suite has been updated accordingly.
628*eda14cbcSMatt Macy#
629*eda14cbcSMatt Macyif [ -x "$STF_PATH/setenforce" ]; then
630*eda14cbcSMatt Macy	sudo setenforce permissive >/dev/null 2>&1
631*eda14cbcSMatt Macyfi
632*eda14cbcSMatt Macy
633*eda14cbcSMatt Macy#
634*eda14cbcSMatt Macy# Enable internal ZFS debug log and clear it.
635*eda14cbcSMatt Macy#
636*eda14cbcSMatt Macyif [ -e /sys/module/zfs/parameters/zfs_dbgmsg_enable ]; then
637*eda14cbcSMatt Macy	sudo /bin/sh -c "echo 1 >/sys/module/zfs/parameters/zfs_dbgmsg_enable"
638*eda14cbcSMatt Macy	sudo /bin/sh -c "echo 0 >/proc/spl/kstat/zfs/dbgmsg"
639*eda14cbcSMatt Macyfi
640*eda14cbcSMatt Macy
641*eda14cbcSMatt Macymsg "FILEDIR:         $FILEDIR"
642*eda14cbcSMatt Macymsg "FILES:           $FILES"
643*eda14cbcSMatt Macymsg "LOOPBACKS:       $LOOPBACKS"
644*eda14cbcSMatt Macymsg "DISKS:           $DISKS"
645*eda14cbcSMatt Macymsg "NUM_DISKS:       $NUM_DISKS"
646*eda14cbcSMatt Macymsg "FILESIZE:        $FILESIZE"
647*eda14cbcSMatt Macymsg "ITERATIONS:      $ITERATIONS"
648*eda14cbcSMatt Macymsg "TAGS:            $TAGS"
649*eda14cbcSMatt Macymsg "STACK_TRACER:    $STACK_TRACER"
650*eda14cbcSMatt Macymsg "Keep pool(s):    $KEEP"
651*eda14cbcSMatt Macymsg "Missing util(s): $STF_MISSING_BIN"
652*eda14cbcSMatt Macymsg ""
653*eda14cbcSMatt Macy
654*eda14cbcSMatt Macyexport STF_TOOLS
655*eda14cbcSMatt Macyexport STF_SUITE
656*eda14cbcSMatt Macyexport STF_PATH
657*eda14cbcSMatt Macyexport DISKS
658*eda14cbcSMatt Macyexport FILEDIR
659*eda14cbcSMatt Macyexport KEEP
660*eda14cbcSMatt Macyexport __ZFS_POOL_EXCLUDE
661*eda14cbcSMatt Macyexport TESTFAIL_CALLBACKS
662*eda14cbcSMatt Macyexport PATH=$STF_PATH
663*eda14cbcSMatt Macy
664*eda14cbcSMatt Macyif [ "$UNAME" = "FreeBSD" ] ; then
665*eda14cbcSMatt Macy	mkdir -p "$FILEDIR" || true
666*eda14cbcSMatt Macy	RESULTS_FILE=$(mktemp -u "${FILEDIR}/zts-results.XXXX")
667*eda14cbcSMatt Macy	REPORT_FILE=$(mktemp -u "${FILEDIR}/zts-report.XXXX")
668*eda14cbcSMatt Macyelse
669*eda14cbcSMatt Macy	RESULTS_FILE=$(mktemp -u -t zts-results.XXXX -p "$FILEDIR")
670*eda14cbcSMatt Macy	REPORT_FILE=$(mktemp -u -t zts-report.XXXX -p "$FILEDIR")
671*eda14cbcSMatt Macyfi
672*eda14cbcSMatt Macy
673*eda14cbcSMatt Macy#
674*eda14cbcSMatt Macy# Run all the tests as specified.
675*eda14cbcSMatt Macy#
676*eda14cbcSMatt Macymsg "${TEST_RUNNER} ${QUIET:+-q}" \
677*eda14cbcSMatt Macy    "-c \"${RUNFILES}\"" \
678*eda14cbcSMatt Macy    "-T \"${TAGS}\"" \
679*eda14cbcSMatt Macy    "-i \"${STF_SUITE}\"" \
680*eda14cbcSMatt Macy    "-I \"${ITERATIONS}\""
681*eda14cbcSMatt Macy${TEST_RUNNER} ${QUIET:+-q} \
682*eda14cbcSMatt Macy    -c "${RUNFILES}" \
683*eda14cbcSMatt Macy    -T "${TAGS}" \
684*eda14cbcSMatt Macy    -i "${STF_SUITE}" \
685*eda14cbcSMatt Macy    -I "${ITERATIONS}" \
686*eda14cbcSMatt Macy    2>&1 | tee "$RESULTS_FILE"
687*eda14cbcSMatt Macy
688*eda14cbcSMatt Macy#
689*eda14cbcSMatt Macy# Analyze the results.
690*eda14cbcSMatt Macy#
691*eda14cbcSMatt Macy${ZTS_REPORT} "$RESULTS_FILE" >"$REPORT_FILE"
692*eda14cbcSMatt MacyRESULT=$?
693*eda14cbcSMatt Macycat "$REPORT_FILE"
694*eda14cbcSMatt Macy
695*eda14cbcSMatt MacyRESULTS_DIR=$(awk '/^Log directory/ { print $3 }' "$RESULTS_FILE")
696*eda14cbcSMatt Macyif [ -d "$RESULTS_DIR" ]; then
697*eda14cbcSMatt Macy	cat "$RESULTS_FILE" "$REPORT_FILE" >"$RESULTS_DIR/results"
698*eda14cbcSMatt Macyfi
699*eda14cbcSMatt Macy
700*eda14cbcSMatt Macyrm -f "$RESULTS_FILE" "$REPORT_FILE"
701*eda14cbcSMatt Macy
702*eda14cbcSMatt Macyif [ -n "$SINGLETEST" ]; then
703*eda14cbcSMatt Macy	rm -f "$RUNFILES" >/dev/null 2>&1
704*eda14cbcSMatt Macyfi
705*eda14cbcSMatt Macy
706*eda14cbcSMatt Macyexit ${RESULT}
707