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