xref: /freebsd/tests/sys/cddl/zfs/include/logapi.kshlib (revision ac00d4d59b18a76c6148ca5d7439bb446d38da5c)
1*2fae26bdSAlan Somers# vim: filetype=sh
2*2fae26bdSAlan Somers#
3*2fae26bdSAlan Somers# CDDL HEADER START
4*2fae26bdSAlan Somers#
5*2fae26bdSAlan Somers# The contents of this file are subject to the terms of the
6*2fae26bdSAlan Somers# Common Development and Distribution License (the "License").
7*2fae26bdSAlan Somers# You may not use this file except in compliance with the License.
8*2fae26bdSAlan Somers#
9*2fae26bdSAlan Somers# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*2fae26bdSAlan Somers# or http://www.opensolaris.org/os/licensing.
11*2fae26bdSAlan Somers# See the License for the specific language governing permissions
12*2fae26bdSAlan Somers# and limitations under the License.
13*2fae26bdSAlan Somers#
14*2fae26bdSAlan Somers# When distributing Covered Code, include this CDDL HEADER in each
15*2fae26bdSAlan Somers# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*2fae26bdSAlan Somers# If applicable, add the following below this CDDL HEADER, with the
17*2fae26bdSAlan Somers# fields enclosed by brackets "[]" replaced with your own identifying
18*2fae26bdSAlan Somers# information: Portions Copyright [yyyy] [name of copyright owner]
19*2fae26bdSAlan Somers#
20*2fae26bdSAlan Somers# CDDL HEADER END
21*2fae26bdSAlan Somers#
22*2fae26bdSAlan Somers
23*2fae26bdSAlan Somers#
24*2fae26bdSAlan Somers# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
25*2fae26bdSAlan Somers# Use is subject to license terms.
26*2fae26bdSAlan Somers
27*2fae26bdSAlan Somers#
28*2fae26bdSAlan Somers# This is a ksh function library. It is intended to be sourced into
29*2fae26bdSAlan Somers# other ksh scripts and not executed directly.
30*2fae26bdSAlan Somers#
31*2fae26bdSAlan Somers
32*2fae26bdSAlan Somers. ${STF_SUITE}/include/stf.shlib
33*2fae26bdSAlan Somers
34*2fae26bdSAlan Somers#
35*2fae26bdSAlan Somers# Send a debug message to stderr, if $STF_DEBUG set.
36*2fae26bdSAlan Somers#
37*2fae26bdSAlan Somersfunction log_debug
38*2fae26bdSAlan Somers{
39*2fae26bdSAlan Somers	[ -z "$STF_DEBUG" ] && return
40*2fae26bdSAlan Somers	echo "$*" >&2
41*2fae26bdSAlan Somers}
42*2fae26bdSAlan Somers
43*2fae26bdSAlan Somers# Output an assertion
44*2fae26bdSAlan Somers#
45*2fae26bdSAlan Somers# $@ - assertion text
46*2fae26bdSAlan Somers
47*2fae26bdSAlan Somersfunction log_assert
48*2fae26bdSAlan Somers{
49*2fae26bdSAlan Somers	_printline ASSERTION: "$@"
50*2fae26bdSAlan Somers}
51*2fae26bdSAlan Somers
52*2fae26bdSAlan Somers# Output a comment
53*2fae26bdSAlan Somers#
54*2fae26bdSAlan Somers# $@ - comment text
55*2fae26bdSAlan Somers
56*2fae26bdSAlan Somersfunction log_note
57*2fae26bdSAlan Somers{
58*2fae26bdSAlan Somers	_printline NOTE: "$@"
59*2fae26bdSAlan Somers}
60*2fae26bdSAlan Somers
61*2fae26bdSAlan Somers# Execute a positive test and exit $STF_FAIL is test fails
62*2fae26bdSAlan Somers#
63*2fae26bdSAlan Somers# $@ - command to execute
64*2fae26bdSAlan Somers
65*2fae26bdSAlan Somersfunction log_must
66*2fae26bdSAlan Somers{
67*2fae26bdSAlan Somers	log_pos "$@"
68*2fae26bdSAlan Somers	(( $? != 0 )) && log_fail
69*2fae26bdSAlan Somers}
70*2fae26bdSAlan Somers
71*2fae26bdSAlan Somers# Execute a command that must exit $1
72*2fae26bdSAlan Somers#
73*2fae26bdSAlan Somers# $@ - command to execute
74*2fae26bdSAlan Somersfunction log_mustbe
75*2fae26bdSAlan Somers{
76*2fae26bdSAlan Somers	typeset exitcode_wanted=$1
77*2fae26bdSAlan Somers	shift
78*2fae26bdSAlan Somers
79*2fae26bdSAlan Somers	log_cmd "$@"
80*2fae26bdSAlan Somers	(( $? != $exitcode_wanted )) && log_fail
81*2fae26bdSAlan Somers}
82*2fae26bdSAlan Somers
83*2fae26bdSAlan Somers# Execute a negative test and exit $STF_FAIL if test passes
84*2fae26bdSAlan Somers#
85*2fae26bdSAlan Somers# $@ - command to execute
86*2fae26bdSAlan Somers
87*2fae26bdSAlan Somersfunction log_mustnot
88*2fae26bdSAlan Somers{
89*2fae26bdSAlan Somers	log_neg "$@"
90*2fae26bdSAlan Somers	(( $? != 0 )) && log_fail
91*2fae26bdSAlan Somers}
92*2fae26bdSAlan Somers
93*2fae26bdSAlan Somers# Execute a command that should only be logged if it fails.
94*2fae26bdSAlan Somers#
95*2fae26bdSAlan Somers# $@ - command to execute
96*2fae26bdSAlan Somersfunction log_onfail
97*2fae26bdSAlan Somers{
98*2fae26bdSAlan Somers	eval $@
99*2fae26bdSAlan Somers	typeset status=$?
100*2fae26bdSAlan Somers	[ $status -eq 0 ] && return
101*2fae26bdSAlan Somers	_printerror "$@" "unexpectedly exited $status"
102*2fae26bdSAlan Somers}
103*2fae26bdSAlan Somers
104*2fae26bdSAlan Somers# Execute and print command with status where success equals non-zero result
105*2fae26bdSAlan Somers# or output includes expected keyword
106*2fae26bdSAlan Somers#
107*2fae26bdSAlan Somers# $2-$@ - command to execute
108*2fae26bdSAlan Somers#
109*2fae26bdSAlan Somers# Summary: execute $@.  Return 1 if any of the following hold:
110*2fae26bdSAlan Somers#		1) The command exited 0, 127, 138, or 139
111*2fae26bdSAlan Somers#		2) The command's stderr included "internal error" or
112*2fae26bdSAlan Somers#		   "assertion failed"
113*2fae26bdSAlan Somers#
114*2fae26bdSAlan Somers# return 0 if command fails, or the output contains the keyword expected,
115*2fae26bdSAlan Somers# return 1 otherwise
116*2fae26bdSAlan Somers
117*2fae26bdSAlan Somersfunction log_neg
118*2fae26bdSAlan Somers{
119*2fae26bdSAlan Somers	typeset out=""
120*2fae26bdSAlan Somers	typeset logfile="$TMPDIR/log.$$"
121*2fae26bdSAlan Somers	typeset ret=1
122*2fae26bdSAlan Somers
123*2fae26bdSAlan Somers	while [[ -e $logfile ]]; do
124*2fae26bdSAlan Somers		logfile="$logfile.$$"
125*2fae26bdSAlan Somers	done
126*2fae26bdSAlan Somers
127*2fae26bdSAlan Somers	"$@" 2>$logfile
128*2fae26bdSAlan Somers	typeset status=$?
129*2fae26bdSAlan Somers	out="/bin/cat $logfile"
130*2fae26bdSAlan Somers
131*2fae26bdSAlan Somers	# unexpected status
132*2fae26bdSAlan Somers	if (( $status == 0 )); then
133*2fae26bdSAlan Somers		 print -u2 $($out)
134*2fae26bdSAlan Somers		_printerror "$@" "unexpectedly exited $status"
135*2fae26bdSAlan Somers	# missing binary
136*2fae26bdSAlan Somers	elif (( $status == 127 )); then
137*2fae26bdSAlan Somers		print -u2 $($out)
138*2fae26bdSAlan Somers		_printerror "$@" "unexpectedly exited $status (File not found)"
139*2fae26bdSAlan Somers	# bus error - core dump
140*2fae26bdSAlan Somers	elif (( $status == 138 )); then
141*2fae26bdSAlan Somers		print -u2 $($out)
142*2fae26bdSAlan Somers		_printerror "$@" "unexpectedly exited $status (Bus Error)"
143*2fae26bdSAlan Somers	# segmentation violation - core dump
144*2fae26bdSAlan Somers	elif (( $status == 139 )); then
145*2fae26bdSAlan Somers		print -u2 $($out)
146*2fae26bdSAlan Somers		_printerror "$@" "unexpectedly exited $status (SEGV)"
147*2fae26bdSAlan Somers	else
148*2fae26bdSAlan Somers		$out | /usr/bin/egrep -i "internal error|assertion failed" \
149*2fae26bdSAlan Somers			> /dev/null 2>&1
150*2fae26bdSAlan Somers		# internal error or assertion failed
151*2fae26bdSAlan Somers		if (( $? == 0 )); then
152*2fae26bdSAlan Somers			print -u2 $($out)
153*2fae26bdSAlan Somers			_printerror "$@" "internal error or assertion failure" \
154*2fae26bdSAlan Somers				" exited $status"
155*2fae26bdSAlan Somers		else
156*2fae26bdSAlan Somers			ret=0
157*2fae26bdSAlan Somers		fi
158*2fae26bdSAlan Somers
159*2fae26bdSAlan Somers		if (( $ret == 0 )); then
160*2fae26bdSAlan Somers			[[ -n $LOGAPI_DEBUG ]] && print $($out)
161*2fae26bdSAlan Somers			_printsuccess "$@" "exited $status"
162*2fae26bdSAlan Somers		fi
163*2fae26bdSAlan Somers	fi
164*2fae26bdSAlan Somers	_recursive_output $logfile "false"
165*2fae26bdSAlan Somers	return $ret
166*2fae26bdSAlan Somers}
167*2fae26bdSAlan Somers
168*2fae26bdSAlan Somers# Execute and print command; unconditionally return its exit code.
169*2fae26bdSAlan Somers# Useful for code that needs to do more specialized exit status filtering.
170*2fae26bdSAlan Somersfunction log_cmd
171*2fae26bdSAlan Somers{
172*2fae26bdSAlan Somers	typeset logfile="$TMPDIR/log.$$"
173*2fae26bdSAlan Somers
174*2fae26bdSAlan Somers	while [[ -e $logfile ]]; do
175*2fae26bdSAlan Somers		logfile="$logfile.$$"
176*2fae26bdSAlan Somers	done
177*2fae26bdSAlan Somers
178*2fae26bdSAlan Somers	"$@" 2>$logfile
179*2fae26bdSAlan Somers	typeset status=$?
180*2fae26bdSAlan Somers	_printline "EXECUTED (exited $status): $@"
181*2fae26bdSAlan Somers	_recursive_output $logfile "false"
182*2fae26bdSAlan Somers	return $status
183*2fae26bdSAlan Somers}
184*2fae26bdSAlan Somers
185*2fae26bdSAlan Somers# Execute and print command with status where success equals zero result
186*2fae26bdSAlan Somers#
187*2fae26bdSAlan Somers# $@ command to execute
188*2fae26bdSAlan Somers#
189*2fae26bdSAlan Somers# Summary: run $@.  return 1 if its exit status was nonzero or if it printed
190*2fae26bdSAlan Somers#		 "internal error" or "assertion failed" to stderr.
191*2fae26bdSAlan Somers#		print stderr on failure or if LOGAPI_DEBUG is set.
192*2fae26bdSAlan Somers#
193*2fae26bdSAlan Somers# return command exit status
194*2fae26bdSAlan Somers
195*2fae26bdSAlan Somersfunction log_pos
196*2fae26bdSAlan Somers{
197*2fae26bdSAlan Somers	typeset out=""
198*2fae26bdSAlan Somers	typeset logfile="$TMPDIR/log.$$"
199*2fae26bdSAlan Somers
200*2fae26bdSAlan Somers	while [[ -e $logfile ]]; do
201*2fae26bdSAlan Somers		logfile="$logfile.$$"
202*2fae26bdSAlan Somers	done
203*2fae26bdSAlan Somers
204*2fae26bdSAlan Somers	"$@" 2>$logfile
205*2fae26bdSAlan Somers	typeset status=$?
206*2fae26bdSAlan Somers	out="/bin/cat $logfile"
207*2fae26bdSAlan Somers
208*2fae26bdSAlan Somers	if (( $status != 0 )) ; then
209*2fae26bdSAlan Somers		print -u2 $($out)
210*2fae26bdSAlan Somers		_printerror "$@" "exited $status"
211*2fae26bdSAlan Somers	else
212*2fae26bdSAlan Somers		$out | /usr/bin/egrep -i "internal error|assertion failed" \
213*2fae26bdSAlan Somers			> /dev/null 2>&1
214*2fae26bdSAlan Somers		# internal error or assertion failed
215*2fae26bdSAlan Somers		if [[ $? -eq 0 ]]; then
216*2fae26bdSAlan Somers			print -u2 $($out)
217*2fae26bdSAlan Somers			_printerror "$@" "internal error or assertion failure" \
218*2fae26bdSAlan Somers				" exited $status"
219*2fae26bdSAlan Somers			status=1
220*2fae26bdSAlan Somers		else
221*2fae26bdSAlan Somers			[[ -n $LOGAPI_DEBUG ]] && print $($out)
222*2fae26bdSAlan Somers			_printsuccess "$@"
223*2fae26bdSAlan Somers		fi
224*2fae26bdSAlan Somers	fi
225*2fae26bdSAlan Somers	_recursive_output $logfile "false"
226*2fae26bdSAlan Somers	return $status
227*2fae26bdSAlan Somers}
228*2fae26bdSAlan Somers
229*2fae26bdSAlan Somers# Set an exit handler
230*2fae26bdSAlan Somers#
231*2fae26bdSAlan Somers# $@ - function(s) to perform on exit
232*2fae26bdSAlan Somers
233*2fae26bdSAlan Somersfunction log_onexit
234*2fae26bdSAlan Somers{
235*2fae26bdSAlan Somers	_CLEANUP="$@"
236*2fae26bdSAlan Somers}
237*2fae26bdSAlan Somers
238*2fae26bdSAlan Somers#
239*2fae26bdSAlan Somers# Exit functions
240*2fae26bdSAlan Somers#
241*2fae26bdSAlan Somers
242*2fae26bdSAlan Somers# Perform cleanup and exit $STF_PASS
243*2fae26bdSAlan Somers#
244*2fae26bdSAlan Somers# $@ - message text
245*2fae26bdSAlan Somers
246*2fae26bdSAlan Somersfunction log_pass
247*2fae26bdSAlan Somers{
248*2fae26bdSAlan Somers	_endlog $STF_PASS "$@"
249*2fae26bdSAlan Somers}
250*2fae26bdSAlan Somers
251*2fae26bdSAlan Somers# Perform cleanup and exit $STF_FAIL
252*2fae26bdSAlan Somers#
253*2fae26bdSAlan Somers# $@ - message text
254*2fae26bdSAlan Somers
255*2fae26bdSAlan Somersfunction log_fail
256*2fae26bdSAlan Somers{
257*2fae26bdSAlan Somers	_endlog $STF_FAIL "$@"
258*2fae26bdSAlan Somers}
259*2fae26bdSAlan Somers
260*2fae26bdSAlan Somers# Perform cleanup and exit $STF_UNRESOLVED
261*2fae26bdSAlan Somers#
262*2fae26bdSAlan Somers# $@ - message text
263*2fae26bdSAlan Somers
264*2fae26bdSAlan Somersfunction log_unresolved
265*2fae26bdSAlan Somers{
266*2fae26bdSAlan Somers	_endlog $STF_UNRESOLVED "$@"
267*2fae26bdSAlan Somers}
268*2fae26bdSAlan Somers
269*2fae26bdSAlan Somers# Perform cleanup and exit $STF_NOTINUSE
270*2fae26bdSAlan Somers#
271*2fae26bdSAlan Somers# $@ - message text
272*2fae26bdSAlan Somers
273*2fae26bdSAlan Somersfunction log_notinuse
274*2fae26bdSAlan Somers{
275*2fae26bdSAlan Somers	_endlog $STF_NOTINUSE "$@"
276*2fae26bdSAlan Somers}
277*2fae26bdSAlan Somers
278*2fae26bdSAlan Somers# Perform cleanup and exit $STF_UNSUPPORTED
279*2fae26bdSAlan Somers#
280*2fae26bdSAlan Somers# $@ - message text
281*2fae26bdSAlan Somers
282*2fae26bdSAlan Somersfunction log_unsupported
283*2fae26bdSAlan Somers{
284*2fae26bdSAlan Somers	_endlog $STF_UNSUPPORTED "$@"
285*2fae26bdSAlan Somers}
286*2fae26bdSAlan Somers
287*2fae26bdSAlan Somers# Perform cleanup and exit $STF_UNTESTED
288*2fae26bdSAlan Somers#
289*2fae26bdSAlan Somers# $@ - message text
290*2fae26bdSAlan Somers
291*2fae26bdSAlan Somersfunction log_untested
292*2fae26bdSAlan Somers{
293*2fae26bdSAlan Somers	_endlog $STF_UNTESTED "$@"
294*2fae26bdSAlan Somers}
295*2fae26bdSAlan Somers
296*2fae26bdSAlan Somers# Perform cleanup and exit $STF_UNINITIATED
297*2fae26bdSAlan Somers#
298*2fae26bdSAlan Somers# $@ - message text
299*2fae26bdSAlan Somers
300*2fae26bdSAlan Somersfunction log_uninitiated
301*2fae26bdSAlan Somers{
302*2fae26bdSAlan Somers	_endlog $STF_UNINITIATED "$@"
303*2fae26bdSAlan Somers}
304*2fae26bdSAlan Somers
305*2fae26bdSAlan Somers# Perform cleanup and exit $STF_NORESULT
306*2fae26bdSAlan Somers#
307*2fae26bdSAlan Somers# $@ - message text
308*2fae26bdSAlan Somers
309*2fae26bdSAlan Somersfunction log_noresult
310*2fae26bdSAlan Somers{
311*2fae26bdSAlan Somers	_endlog $STF_NORESULT "$@"
312*2fae26bdSAlan Somers}
313*2fae26bdSAlan Somers
314*2fae26bdSAlan Somers# Perform cleanup and exit $STF_WARNING
315*2fae26bdSAlan Somers#
316*2fae26bdSAlan Somers# $@ - message text
317*2fae26bdSAlan Somers
318*2fae26bdSAlan Somersfunction log_warning
319*2fae26bdSAlan Somers{
320*2fae26bdSAlan Somers	_endlog $STF_WARNING "$@"
321*2fae26bdSAlan Somers}
322*2fae26bdSAlan Somers
323*2fae26bdSAlan Somers# Perform cleanup and exit $STF_TIMED_OUT
324*2fae26bdSAlan Somers#
325*2fae26bdSAlan Somers# $@ - message text
326*2fae26bdSAlan Somers
327*2fae26bdSAlan Somersfunction log_timed_out
328*2fae26bdSAlan Somers{
329*2fae26bdSAlan Somers	_endlog $STF_TIMED_OUT "$@"
330*2fae26bdSAlan Somers}
331*2fae26bdSAlan Somers
332*2fae26bdSAlan Somers# Perform cleanup and exit $STF_OTHER
333*2fae26bdSAlan Somers#
334*2fae26bdSAlan Somers# $@ - message text
335*2fae26bdSAlan Somers
336*2fae26bdSAlan Somersfunction log_other
337*2fae26bdSAlan Somers{
338*2fae26bdSAlan Somers	_endlog $STF_OTHER "$@"
339*2fae26bdSAlan Somers}
340*2fae26bdSAlan Somers
341*2fae26bdSAlan Somers#
342*2fae26bdSAlan Somers# Internal functions
343*2fae26bdSAlan Somers#
344*2fae26bdSAlan Somers
345*2fae26bdSAlan Somers# Perform cleanup and exit
346*2fae26bdSAlan Somers#
347*2fae26bdSAlan Somers# Summary:	Runs any cleanup routine registered with log_onexit.  Prints a
348*2fae26bdSAlan Somers# 		message and exits $1.  Note: the _recursive_output does
349*2fae26bdSAlan Somers# 		nothing, because the rest of this api guarantees that the
350*2fae26bdSAlan Somers# 		logfile will not exist.
351*2fae26bdSAlan Somers# $1 - stf exit code
352*2fae26bdSAlan Somers# $2-$n - message text
353*2fae26bdSAlan Somers
354*2fae26bdSAlan Somersfunction _endlog
355*2fae26bdSAlan Somers{
356*2fae26bdSAlan Somers	typeset logfile="$TMPDIR/log.$$"
357*2fae26bdSAlan Somers	_recursive_output $logfile
358*2fae26bdSAlan Somers
359*2fae26bdSAlan Somers	export STF_EXITCODE=$1
360*2fae26bdSAlan Somers	shift
361*2fae26bdSAlan Somers	(( ${#@} > 0 )) && _printline "$@"
362*2fae26bdSAlan Somers	if [[ -n $_CLEANUP ]] ; then
363*2fae26bdSAlan Somers		typeset cleanup=$_CLEANUP
364*2fae26bdSAlan Somers		log_onexit ""
365*2fae26bdSAlan Somers		log_note "Performing local cleanup via log_onexit ($cleanup)"
366*2fae26bdSAlan Somers		$cleanup
367*2fae26bdSAlan Somers	fi
368*2fae26bdSAlan Somers	exit $STF_EXITCODE
369*2fae26bdSAlan Somers}
370*2fae26bdSAlan Somers
371*2fae26bdSAlan Somers# Output a formatted line
372*2fae26bdSAlan Somers#
373*2fae26bdSAlan Somers# $@ - message text
374*2fae26bdSAlan Somers
375*2fae26bdSAlan Somersfunction _printline
376*2fae26bdSAlan Somers{
377*2fae26bdSAlan Somers	print `/bin/date +%H:%M:%S` "$@"
378*2fae26bdSAlan Somers}
379*2fae26bdSAlan Somers
380*2fae26bdSAlan Somers# Output an error message
381*2fae26bdSAlan Somers#
382*2fae26bdSAlan Somers# $@ - message text
383*2fae26bdSAlan Somers
384*2fae26bdSAlan Somersfunction _printerror
385*2fae26bdSAlan Somers{
386*2fae26bdSAlan Somers	_printline ERROR: "$@"
387*2fae26bdSAlan Somers}
388*2fae26bdSAlan Somers
389*2fae26bdSAlan Somers# Output a success message
390*2fae26bdSAlan Somers#
391*2fae26bdSAlan Somers# $@ - message text
392*2fae26bdSAlan Somers
393*2fae26bdSAlan Somersfunction _printsuccess
394*2fae26bdSAlan Somers{
395*2fae26bdSAlan Somers	_printline SUCCESS: "$@"
396*2fae26bdSAlan Somers}
397*2fae26bdSAlan Somers
398*2fae26bdSAlan Somers# Output logfiles recursively
399*2fae26bdSAlan Somers#
400*2fae26bdSAlan Somers# $1 - start file
401*2fae26bdSAlan Somers# $2 - indicate whether output the start file itself, default as yes.
402*2fae26bdSAlan Somers
403*2fae26bdSAlan Somersfunction _recursive_output #logfile
404*2fae26bdSAlan Somers{
405*2fae26bdSAlan Somers	typeset logfile=$1
406*2fae26bdSAlan Somers
407*2fae26bdSAlan Somers	while [[ -e $logfile ]]; do
408*2fae26bdSAlan Somers		if [[ -z $2 || $logfile != $1 ]]; then
409*2fae26bdSAlan Somers			/bin/cat $logfile
410*2fae26bdSAlan Somers		fi
411*2fae26bdSAlan Somers		/bin/rm -f $logfile
412*2fae26bdSAlan Somers		logfile="$logfile.$$"
413*2fae26bdSAlan Somers        done
414*2fae26bdSAlan Somers}
415