xref: /freebsd/sys/contrib/openzfs/tests/test-runner/include/logapi.shlib (revision 716fd348e01c5f2ba125f878a634a753436c2994)
1eda14cbcSMatt Macy#
2eda14cbcSMatt Macy# CDDL HEADER START
3eda14cbcSMatt Macy#
4eda14cbcSMatt Macy# The contents of this file are subject to the terms of the
5eda14cbcSMatt Macy# Common Development and Distribution License (the "License").
6eda14cbcSMatt Macy# You may not use this file except in compliance with the License.
7eda14cbcSMatt Macy#
8eda14cbcSMatt Macy# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9eda14cbcSMatt Macy# or http://www.opensolaris.org/os/licensing.
10eda14cbcSMatt Macy# See the License for the specific language governing permissions
11eda14cbcSMatt Macy# and limitations under the License.
12eda14cbcSMatt Macy#
13eda14cbcSMatt Macy# When distributing Covered Code, include this CDDL HEADER in each
14eda14cbcSMatt Macy# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15eda14cbcSMatt Macy# If applicable, add the following below this CDDL HEADER, with the
16eda14cbcSMatt Macy# fields enclosed by brackets "[]" replaced with your own identifying
17eda14cbcSMatt Macy# information: Portions Copyright [yyyy] [name of copyright owner]
18eda14cbcSMatt Macy#
19eda14cbcSMatt Macy# CDDL HEADER END
20eda14cbcSMatt Macy#
21eda14cbcSMatt Macy
22eda14cbcSMatt Macy#
23eda14cbcSMatt Macy# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
24eda14cbcSMatt Macy# Use is subject to license terms.
25eda14cbcSMatt Macy#
26eda14cbcSMatt Macy# Copyright (c) 2012, 2020 by Delphix. All rights reserved.
27eda14cbcSMatt Macy#
28eda14cbcSMatt Macy
29*716fd348SMartin MatuskaSTF_PASS=0
30*716fd348SMartin MatuskaSTF_FAIL=1
31*716fd348SMartin MatuskaSTF_UNRESOLVED=2
32*716fd348SMartin MatuskaSTF_UNSUPPORTED=4
33*716fd348SMartin MatuskaSTF_UNTESTED=5
34eda14cbcSMatt Macy
35eda14cbcSMatt Macy# Output an assertion
36eda14cbcSMatt Macy#
37eda14cbcSMatt Macy# $@ - assertion text
38eda14cbcSMatt Macy
39eda14cbcSMatt Macyfunction log_assert
40eda14cbcSMatt Macy{
41eda14cbcSMatt Macy	_printline ASSERTION: "$@"
42eda14cbcSMatt Macy}
43eda14cbcSMatt Macy
44eda14cbcSMatt Macy# Output a comment
45eda14cbcSMatt Macy#
46eda14cbcSMatt Macy# $@ - comment text
47eda14cbcSMatt Macy
48eda14cbcSMatt Macyfunction log_note
49eda14cbcSMatt Macy{
50eda14cbcSMatt Macy	_printline NOTE: "$@"
51eda14cbcSMatt Macy}
52eda14cbcSMatt Macy
53eda14cbcSMatt Macy# Execute and print command with status where success equals non-zero result
54eda14cbcSMatt Macy#
55eda14cbcSMatt Macy# $@ - command to execute
56eda14cbcSMatt Macy#
57eda14cbcSMatt Macy# return 0 if command fails, otherwise return 1
58eda14cbcSMatt Macy
59eda14cbcSMatt Macyfunction log_neg
60eda14cbcSMatt Macy{
61eda14cbcSMatt Macy	log_neg_expect "" "$@"
62eda14cbcSMatt Macy}
63eda14cbcSMatt Macy
64eda14cbcSMatt Macy# Execute a positive test and exit $STF_FAIL is test fails
65eda14cbcSMatt Macy#
66eda14cbcSMatt Macy# $@ - command to execute
67eda14cbcSMatt Macy
68eda14cbcSMatt Macyfunction log_must
69eda14cbcSMatt Macy{
70da5137abSMartin Matuska	log_pos "$@" || log_fail
71eda14cbcSMatt Macy}
72eda14cbcSMatt Macy
736ba2210eSMartin Matuska# Execute a positive test (expecting no stderr) and exit $STF_FAIL
746ba2210eSMartin Matuska# if test fails
756ba2210eSMartin Matuska# $@ - command to execute
766ba2210eSMartin Matuska
776ba2210eSMartin Matuskafunction log_must_nostderr
786ba2210eSMartin Matuska{
79da5137abSMartin Matuska	log_pos_nostderr "$@" || log_fail
806ba2210eSMartin Matuska}
816ba2210eSMartin Matuska
82eda14cbcSMatt Macy# Execute a positive test but retry the command on failure if the output
83eda14cbcSMatt Macy# matches an expected pattern.  Otherwise behave like log_must and exit
84eda14cbcSMatt Macy# $STF_FAIL is test fails.
85eda14cbcSMatt Macy#
86eda14cbcSMatt Macy# $1 - retry keyword
87eda14cbcSMatt Macy# $2 - retry attempts
88eda14cbcSMatt Macy# $3-$@ - command to execute
89eda14cbcSMatt Macy#
90eda14cbcSMatt Macyfunction log_must_retry
91eda14cbcSMatt Macy{
92eda14cbcSMatt Macy	typeset logfile="/tmp/log.$$"
93eda14cbcSMatt Macy	typeset status=1
94eda14cbcSMatt Macy	typeset expect=$1
95eda14cbcSMatt Macy	typeset retry=$2
96eda14cbcSMatt Macy	typeset delay=1
97eda14cbcSMatt Macy	shift 2
98eda14cbcSMatt Macy
99eda14cbcSMatt Macy	while [[ -e $logfile ]]; do
100eda14cbcSMatt Macy		logfile="$logfile.$$"
101eda14cbcSMatt Macy	done
102eda14cbcSMatt Macy
103eda14cbcSMatt Macy	while (( $retry > 0 )); do
104eda14cbcSMatt Macy		"$@" 2>$logfile
105eda14cbcSMatt Macy		status=$?
106eda14cbcSMatt Macy
107eda14cbcSMatt Macy		if (( $status == 0 )); then
108*716fd348SMartin Matuska			if grep -qEi "internal error|assertion failed" $logfile; then
109*716fd348SMartin Matuska				cat $logfile >&2
110eda14cbcSMatt Macy				_printerror "$@" "internal error or" \
111eda14cbcSMatt Macy					" assertion failure exited $status"
112eda14cbcSMatt Macy				status=1
113eda14cbcSMatt Macy			else
114184c1b94SMartin Matuska				[[ -n $LOGAPI_DEBUG ]] && cat $logfile
115eda14cbcSMatt Macy				_printsuccess "$@"
116eda14cbcSMatt Macy			fi
117eda14cbcSMatt Macy			break
118eda14cbcSMatt Macy		else
119*716fd348SMartin Matuska			if grep -qi "$expect" $logfile; then
120*716fd348SMartin Matuska				cat $logfile >&2
121eda14cbcSMatt Macy				_printerror "$@" "Retry in $delay seconds"
122eda14cbcSMatt Macy				sleep $delay
123eda14cbcSMatt Macy
124eda14cbcSMatt Macy				(( retry=retry - 1 ))
125eda14cbcSMatt Macy				(( delay=delay * 2 ))
126eda14cbcSMatt Macy			else
127eda14cbcSMatt Macy				break;
128eda14cbcSMatt Macy			fi
129eda14cbcSMatt Macy		fi
130eda14cbcSMatt Macy	done
131eda14cbcSMatt Macy
132eda14cbcSMatt Macy	if (( $status != 0 )) ; then
133*716fd348SMartin Matuska		cat $logfile >&2
134eda14cbcSMatt Macy		_printerror "$@" "exited $status"
135eda14cbcSMatt Macy	fi
136eda14cbcSMatt Macy
137eda14cbcSMatt Macy	_recursive_output $logfile "false"
138eda14cbcSMatt Macy	return $status
139eda14cbcSMatt Macy}
140eda14cbcSMatt Macy
141eda14cbcSMatt Macy# Execute a positive test and exit $STF_FAIL is test fails after being
142eda14cbcSMatt Macy# retried up to 5 times when the command returns the keyword "busy".
143eda14cbcSMatt Macy#
144eda14cbcSMatt Macy# $@ - command to execute
145eda14cbcSMatt Macyfunction log_must_busy
146eda14cbcSMatt Macy{
147da5137abSMartin Matuska	log_must_retry "busy" 5 "$@" || log_fail
148eda14cbcSMatt Macy}
149eda14cbcSMatt Macy
150eda14cbcSMatt Macy# Execute a negative test and exit $STF_FAIL if test passes
151eda14cbcSMatt Macy#
152eda14cbcSMatt Macy# $@ - command to execute
153eda14cbcSMatt Macy
154eda14cbcSMatt Macyfunction log_mustnot
155eda14cbcSMatt Macy{
156da5137abSMartin Matuska	log_neg "$@" || log_fail
157eda14cbcSMatt Macy}
158eda14cbcSMatt Macy
159eda14cbcSMatt Macy# Execute a negative test with keyword expected, and exit
160eda14cbcSMatt Macy# $STF_FAIL if test passes
161eda14cbcSMatt Macy#
162eda14cbcSMatt Macy# $1 - keyword expected
163eda14cbcSMatt Macy# $2-$@ - command to execute
164eda14cbcSMatt Macy
165eda14cbcSMatt Macyfunction log_mustnot_expect
166eda14cbcSMatt Macy{
167da5137abSMartin Matuska	log_neg_expect "$@" || log_fail
168eda14cbcSMatt Macy}
169eda14cbcSMatt Macy
170eda14cbcSMatt Macy# Signal numbers are platform-dependent
171eda14cbcSMatt Macycase $(uname) in
172eda14cbcSMatt MacyDarwin|FreeBSD)
173eda14cbcSMatt Macy	SIGBUS=10
174eda14cbcSMatt Macy	SIGSEGV=11
175eda14cbcSMatt Macy	;;
176eda14cbcSMatt Macyillumos|Linux|*)
177eda14cbcSMatt Macy	SIGBUS=7
178eda14cbcSMatt Macy	SIGSEGV=11
179eda14cbcSMatt Macy	;;
180eda14cbcSMatt Macyesac
181eda14cbcSMatt MacyEXIT_SUCCESS=0
182eda14cbcSMatt MacyEXIT_NOTFOUND=127
183eda14cbcSMatt MacyEXIT_SIGNAL=256
184eda14cbcSMatt MacyEXIT_SIGBUS=$((EXIT_SIGNAL + SIGBUS))
185eda14cbcSMatt MacyEXIT_SIGSEGV=$((EXIT_SIGNAL + SIGSEGV))
186eda14cbcSMatt Macy
187eda14cbcSMatt Macy# Execute and print command with status where success equals non-zero result
188eda14cbcSMatt Macy# or output includes expected keyword
189eda14cbcSMatt Macy#
190eda14cbcSMatt Macy# $1 - keyword expected
191eda14cbcSMatt Macy# $2-$@ - command to execute
192eda14cbcSMatt Macy#
193eda14cbcSMatt Macy# return 0 if command fails, or the output contains the keyword expected,
194eda14cbcSMatt Macy# return 1 otherwise
195eda14cbcSMatt Macy
196eda14cbcSMatt Macyfunction log_neg_expect
197eda14cbcSMatt Macy{
198eda14cbcSMatt Macy	typeset logfile="/tmp/log.$$"
199eda14cbcSMatt Macy	typeset ret=1
200eda14cbcSMatt Macy	typeset expect=$1
201eda14cbcSMatt Macy	shift
202eda14cbcSMatt Macy
203eda14cbcSMatt Macy	while [[ -e $logfile ]]; do
204eda14cbcSMatt Macy		logfile="$logfile.$$"
205eda14cbcSMatt Macy	done
206eda14cbcSMatt Macy
207eda14cbcSMatt Macy	"$@" 2>$logfile
208eda14cbcSMatt Macy	typeset status=$?
209eda14cbcSMatt Macy
210eda14cbcSMatt Macy	# unexpected status
211eda14cbcSMatt Macy	if (( $status == EXIT_SUCCESS )); then
212*716fd348SMartin Matuska		 cat $logfile >&2
213eda14cbcSMatt Macy		_printerror "$@" "unexpectedly exited $status"
214eda14cbcSMatt Macy	# missing binary
215eda14cbcSMatt Macy	elif (( $status == EXIT_NOTFOUND )); then
216*716fd348SMartin Matuska		cat $logfile >&2
217eda14cbcSMatt Macy		_printerror "$@" "unexpectedly exited $status (File not found)"
218eda14cbcSMatt Macy	# bus error - core dump
219eda14cbcSMatt Macy	elif (( $status == EXIT_SIGBUS )); then
220*716fd348SMartin Matuska		cat $logfile >&2
221eda14cbcSMatt Macy		_printerror "$@" "unexpectedly exited $status (Bus Error)"
222eda14cbcSMatt Macy	# segmentation violation - core dump
223eda14cbcSMatt Macy	elif (( $status == EXIT_SIGSEGV )); then
224*716fd348SMartin Matuska		cat $logfile >&2
225eda14cbcSMatt Macy		_printerror "$@" "unexpectedly exited $status (SEGV)"
226eda14cbcSMatt Macy	else
227*716fd348SMartin Matuska		if grep -qEi "internal error|assertion failed" $logfile; then
228*716fd348SMartin Matuska			cat $logfile >&2
229eda14cbcSMatt Macy			_printerror "$@" "internal error or assertion failure" \
230eda14cbcSMatt Macy				" exited $status"
231eda14cbcSMatt Macy		elif [[ -n $expect ]] ; then
232*716fd348SMartin Matuska			if grep -qi "$expect" $logfile; then
233eda14cbcSMatt Macy				ret=0
234eda14cbcSMatt Macy			else
235*716fd348SMartin Matuska				cat $logfile >&2
236eda14cbcSMatt Macy				_printerror "$@" "unexpectedly exited $status"
237eda14cbcSMatt Macy			fi
238eda14cbcSMatt Macy		else
239eda14cbcSMatt Macy			ret=0
240eda14cbcSMatt Macy		fi
241eda14cbcSMatt Macy
242eda14cbcSMatt Macy		if (( $ret == 0 )); then
243184c1b94SMartin Matuska			[[ -n $LOGAPI_DEBUG ]] && cat $logfile
244eda14cbcSMatt Macy			_printsuccess "$@" "exited $status"
245eda14cbcSMatt Macy		fi
246eda14cbcSMatt Macy	fi
247eda14cbcSMatt Macy	_recursive_output $logfile "false"
248eda14cbcSMatt Macy	return $ret
249eda14cbcSMatt Macy}
250eda14cbcSMatt Macy
251eda14cbcSMatt Macy# Execute and print command with status where success equals zero result
252eda14cbcSMatt Macy#
253eda14cbcSMatt Macy# $@ command to execute
254eda14cbcSMatt Macy#
255eda14cbcSMatt Macy# return command exit status
256eda14cbcSMatt Macy
257eda14cbcSMatt Macyfunction log_pos
258eda14cbcSMatt Macy{
259eda14cbcSMatt Macy	typeset logfile="/tmp/log.$$"
260eda14cbcSMatt Macy
261eda14cbcSMatt Macy	while [[ -e $logfile ]]; do
262eda14cbcSMatt Macy		logfile="$logfile.$$"
263eda14cbcSMatt Macy	done
264eda14cbcSMatt Macy
265eda14cbcSMatt Macy	"$@" 2>$logfile
266eda14cbcSMatt Macy	typeset status=$?
267eda14cbcSMatt Macy
268eda14cbcSMatt Macy	if (( $status != 0 )) ; then
269*716fd348SMartin Matuska		cat $logfile >&2
270eda14cbcSMatt Macy		_printerror "$@" "exited $status"
271eda14cbcSMatt Macy	else
272*716fd348SMartin Matuska		if grep -qEi "internal error|assertion failed" $logfile; then
273*716fd348SMartin Matuska			cat $logfile >&2
274eda14cbcSMatt Macy			_printerror "$@" "internal error or assertion failure" \
275eda14cbcSMatt Macy				" exited $status"
276eda14cbcSMatt Macy			status=1
277eda14cbcSMatt Macy		else
278184c1b94SMartin Matuska			[[ -n $LOGAPI_DEBUG ]] && cat $logfile
279eda14cbcSMatt Macy			_printsuccess "$@"
280eda14cbcSMatt Macy		fi
281eda14cbcSMatt Macy	fi
282eda14cbcSMatt Macy	_recursive_output $logfile "false"
283eda14cbcSMatt Macy	return $status
284eda14cbcSMatt Macy}
285eda14cbcSMatt Macy
2866ba2210eSMartin Matuska# Execute and print command with status where success equals zero result
2876ba2210eSMartin Matuska# and no stderr output
2886ba2210eSMartin Matuska#
2896ba2210eSMartin Matuska# $@ command to execute
2906ba2210eSMartin Matuska#
2916ba2210eSMartin Matuska# return 0 if command succeeds and no stderr output
2926ba2210eSMartin Matuska# return 1 othersie
2936ba2210eSMartin Matuska
2946ba2210eSMartin Matuskafunction log_pos_nostderr
2956ba2210eSMartin Matuska{
2966ba2210eSMartin Matuska	typeset logfile="/tmp/log.$$"
2976ba2210eSMartin Matuska
2986ba2210eSMartin Matuska	while [[ -e $logfile ]]; do
2996ba2210eSMartin Matuska		logfile="$logfile.$$"
3006ba2210eSMartin Matuska	done
3016ba2210eSMartin Matuska
3026ba2210eSMartin Matuska	"$@" 2>$logfile
3036ba2210eSMartin Matuska	typeset status=$?
3046ba2210eSMartin Matuska
3056ba2210eSMartin Matuska	if (( $status != 0 )) ; then
306*716fd348SMartin Matuska		cat $logfile >&2
3076ba2210eSMartin Matuska		_printerror "$@" "exited $status"
3086ba2210eSMartin Matuska	else
309*716fd348SMartin Matuska		if [ -s "$logfile" ]; then
310*716fd348SMartin Matuska			cat $logfile >&2
3116ba2210eSMartin Matuska			_printerror "$@" "message in stderr" \
3126ba2210eSMartin Matuska				" exited $status"
3136ba2210eSMartin Matuska			status=1
3146ba2210eSMartin Matuska		else
3156ba2210eSMartin Matuska			[[ -n $LOGAPI_DEBUG ]] && cat $logfile
3166ba2210eSMartin Matuska			_printsuccess "$@"
3176ba2210eSMartin Matuska		fi
3186ba2210eSMartin Matuska	fi
3196ba2210eSMartin Matuska	_recursive_output $logfile "false"
3206ba2210eSMartin Matuska	return $status
3216ba2210eSMartin Matuska}
3226ba2210eSMartin Matuska
323eda14cbcSMatt Macy# Set an exit handler
324eda14cbcSMatt Macy#
325eda14cbcSMatt Macy# $@ - function(s) to perform on exit
326eda14cbcSMatt Macy
327eda14cbcSMatt Macyfunction log_onexit
328eda14cbcSMatt Macy{
329eda14cbcSMatt Macy	_CLEANUP=("$*")
330eda14cbcSMatt Macy}
331eda14cbcSMatt Macy
332eda14cbcSMatt Macy# Push an exit handler on the cleanup stack
333eda14cbcSMatt Macy#
334eda14cbcSMatt Macy# $@ - function(s) to perform on exit
335eda14cbcSMatt Macy
336eda14cbcSMatt Macyfunction log_onexit_push
337eda14cbcSMatt Macy{
338eda14cbcSMatt Macy	_CLEANUP+=("$*")
339eda14cbcSMatt Macy}
340eda14cbcSMatt Macy
341eda14cbcSMatt Macy# Pop an exit handler off the cleanup stack
342eda14cbcSMatt Macy
343eda14cbcSMatt Macyfunction log_onexit_pop
344eda14cbcSMatt Macy{
345eda14cbcSMatt Macy	_CLEANUP=("${_CLEANUP[@]:0:${#_CLEANUP[@]}-1}")
346eda14cbcSMatt Macy}
347eda14cbcSMatt Macy
348eda14cbcSMatt Macy#
349eda14cbcSMatt Macy# Exit functions
350eda14cbcSMatt Macy#
351eda14cbcSMatt Macy
352eda14cbcSMatt Macy# Perform cleanup and exit $STF_PASS
353eda14cbcSMatt Macy#
354eda14cbcSMatt Macy# $@ - message text
355eda14cbcSMatt Macy
356eda14cbcSMatt Macyfunction log_pass
357eda14cbcSMatt Macy{
358eda14cbcSMatt Macy	_endlog $STF_PASS "$@"
359eda14cbcSMatt Macy}
360eda14cbcSMatt Macy
361eda14cbcSMatt Macy# Perform cleanup and exit $STF_FAIL
362eda14cbcSMatt Macy#
363eda14cbcSMatt Macy# $@ - message text
364eda14cbcSMatt Macy
365eda14cbcSMatt Macyfunction log_fail
366eda14cbcSMatt Macy{
367eda14cbcSMatt Macy	_endlog $STF_FAIL "$@"
368eda14cbcSMatt Macy}
369eda14cbcSMatt Macy
370eda14cbcSMatt Macy# Perform cleanup and exit $STF_UNRESOLVED
371eda14cbcSMatt Macy#
372eda14cbcSMatt Macy# $@ - message text
373eda14cbcSMatt Macy
374eda14cbcSMatt Macyfunction log_unresolved
375eda14cbcSMatt Macy{
376eda14cbcSMatt Macy	_endlog $STF_UNRESOLVED "$@"
377eda14cbcSMatt Macy}
378eda14cbcSMatt Macy
379eda14cbcSMatt Macy# Perform cleanup and exit $STF_UNSUPPORTED
380eda14cbcSMatt Macy#
381eda14cbcSMatt Macy# $@ - message text
382eda14cbcSMatt Macy
383eda14cbcSMatt Macyfunction log_unsupported
384eda14cbcSMatt Macy{
385eda14cbcSMatt Macy	_endlog $STF_UNSUPPORTED "$@"
386eda14cbcSMatt Macy}
387eda14cbcSMatt Macy
388eda14cbcSMatt Macy# Perform cleanup and exit $STF_UNTESTED
389eda14cbcSMatt Macy#
390eda14cbcSMatt Macy# $@ - message text
391eda14cbcSMatt Macy
392eda14cbcSMatt Macyfunction log_untested
393eda14cbcSMatt Macy{
394eda14cbcSMatt Macy	_endlog $STF_UNTESTED "$@"
395eda14cbcSMatt Macy}
396eda14cbcSMatt Macy
397eda14cbcSMatt Macyfunction set_main_pid
398eda14cbcSMatt Macy{
399eda14cbcSMatt Macy	_MAINPID=$1
400eda14cbcSMatt Macy}
401eda14cbcSMatt Macy
402eda14cbcSMatt Macy#
403eda14cbcSMatt Macy# Internal functions
404eda14cbcSMatt Macy#
405eda14cbcSMatt Macy
406eda14cbcSMatt Macy# Execute custom callback scripts on test failure
407eda14cbcSMatt Macy#
408eda14cbcSMatt Macy# callback script paths are stored in TESTFAIL_CALLBACKS, delimited by ':'.
409eda14cbcSMatt Macy
410eda14cbcSMatt Macyfunction _execute_testfail_callbacks
411eda14cbcSMatt Macy{
412eda14cbcSMatt Macy	typeset callback
413eda14cbcSMatt Macy
414*716fd348SMartin Matuska	while read -d ":" callback; do
415eda14cbcSMatt Macy		if [[ -n "$callback" ]] ; then
416eda14cbcSMatt Macy			log_note "Performing test-fail callback ($callback)"
417eda14cbcSMatt Macy			$callback
418eda14cbcSMatt Macy		fi
419*716fd348SMartin Matuska	done <<<"$TESTFAIL_CALLBACKS:"
420eda14cbcSMatt Macy}
421eda14cbcSMatt Macy
422eda14cbcSMatt Macy# Perform cleanup and exit
423eda14cbcSMatt Macy#
424eda14cbcSMatt Macy# $1 - stf exit code
425eda14cbcSMatt Macy# $2-$n - message text
426eda14cbcSMatt Macy
427eda14cbcSMatt Macyfunction _endlog
428eda14cbcSMatt Macy{
429eda14cbcSMatt Macy	typeset logfile="/tmp/log.$$"
430eda14cbcSMatt Macy	_recursive_output $logfile
431eda14cbcSMatt Macy
432eda14cbcSMatt Macy	typeset exitcode=$1
433eda14cbcSMatt Macy	shift
434eda14cbcSMatt Macy	(( ${#@} > 0 )) && _printline "$@"
435eda14cbcSMatt Macy
436eda14cbcSMatt Macy	#
437eda14cbcSMatt Macy	# If we're running in a subshell then just exit and let
438eda14cbcSMatt Macy	# the parent handle the failures
439eda14cbcSMatt Macy	#
440eda14cbcSMatt Macy	if [[ -n "$_MAINPID" && $$ != "$_MAINPID" ]]; then
441eda14cbcSMatt Macy		log_note "subshell exited: "$_MAINPID
442eda14cbcSMatt Macy		exit $exitcode
443eda14cbcSMatt Macy	fi
444eda14cbcSMatt Macy
445eda14cbcSMatt Macy	if [[ $exitcode == $STF_FAIL ]] ; then
446eda14cbcSMatt Macy		_execute_testfail_callbacks
447eda14cbcSMatt Macy	fi
448eda14cbcSMatt Macy
449eda14cbcSMatt Macy	typeset stack=("${_CLEANUP[@]}")
450eda14cbcSMatt Macy	log_onexit ""
451eda14cbcSMatt Macy	typeset i=${#stack[@]}
452eda14cbcSMatt Macy	while (( i-- )); do
453eda14cbcSMatt Macy		typeset cleanup="${stack[i]}"
454eda14cbcSMatt Macy		log_note "Performing local cleanup via log_onexit ($cleanup)"
455eda14cbcSMatt Macy		$cleanup
456eda14cbcSMatt Macy	done
457eda14cbcSMatt Macy
458eda14cbcSMatt Macy	exit $exitcode
459eda14cbcSMatt Macy}
460eda14cbcSMatt Macy
461eda14cbcSMatt Macy# Output a formatted line
462eda14cbcSMatt Macy#
463eda14cbcSMatt Macy# $@ - message text
464eda14cbcSMatt Macy
465eda14cbcSMatt Macyfunction _printline
466eda14cbcSMatt Macy{
467*716fd348SMartin Matuska	echo "$@"
468eda14cbcSMatt Macy}
469eda14cbcSMatt Macy
470eda14cbcSMatt Macy# Output an error message
471eda14cbcSMatt Macy#
472eda14cbcSMatt Macy# $@ - message text
473eda14cbcSMatt Macy
474eda14cbcSMatt Macyfunction _printerror
475eda14cbcSMatt Macy{
476eda14cbcSMatt Macy	_printline ERROR: "$@"
477eda14cbcSMatt Macy}
478eda14cbcSMatt Macy
479eda14cbcSMatt Macy# Output a success message
480eda14cbcSMatt Macy#
481eda14cbcSMatt Macy# $@ - message text
482eda14cbcSMatt Macy
483eda14cbcSMatt Macyfunction _printsuccess
484eda14cbcSMatt Macy{
485eda14cbcSMatt Macy	_printline SUCCESS: "$@"
486eda14cbcSMatt Macy}
487eda14cbcSMatt Macy
488eda14cbcSMatt Macy# Output logfiles recursively
489eda14cbcSMatt Macy#
490eda14cbcSMatt Macy# $1 - start file
491eda14cbcSMatt Macy# $2 - indicate whether output the start file itself, default as yes.
492eda14cbcSMatt Macy
493eda14cbcSMatt Macyfunction _recursive_output #logfile
494eda14cbcSMatt Macy{
495eda14cbcSMatt Macy	typeset logfile=$1
496eda14cbcSMatt Macy
497eda14cbcSMatt Macy	while [[ -e $logfile ]]; do
498eda14cbcSMatt Macy		if [[ -z $2 || $logfile != $1 ]]; then
499eda14cbcSMatt Macy			cat $logfile
500eda14cbcSMatt Macy		fi
501eda14cbcSMatt Macy		rm -f $logfile
502eda14cbcSMatt Macy		logfile="$logfile.$$"
503eda14cbcSMatt Macy	done
504eda14cbcSMatt Macy}
505