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