]> git.proxmox.com Git - mirror_zfs-debian.git/blob - tests/test-runner/include/logapi.shlib
New upstream version 0.7.9
[mirror_zfs-debian.git] / tests / test-runner / include / logapi.shlib
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
35 function log_assert
36 {
37 _printline ASSERTION: "$@"
38 }
39
40 # Output a comment
41 #
42 # $@ - comment text
43
44 function 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
55 function 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
65 function log_must
66 {
67 log_pos "$@"
68 (( $? != 0 )) && log_fail
69 }
70
71 # Execute a positive test but retry the command on failure if the output
72 # matches an expected pattern. Otherwise behave like log_must and exit
73 # $STF_FAIL is test fails.
74 #
75 # $1 - retry keyword
76 # $2 - retry attempts
77 # $3-$@ - command to execute
78 #
79 function log_must_retry
80 {
81 typeset out=""
82 typeset logfile="/tmp/log.$$"
83 typeset status=1
84 typeset expect=$1
85 typeset retry=$2
86 typeset delay=1
87 shift 2
88
89 while [[ -e $logfile ]]; do
90 logfile="$logfile.$$"
91 done
92
93 while (( $retry > 0 )); do
94 "$@" 2>$logfile
95 status=$?
96 out="cat $logfile"
97
98 if (( $status == 0 )); then
99 $out | egrep -i "internal error|assertion failed" \
100 > /dev/null 2>&1
101 # internal error or assertion failed
102 if [[ $? -eq 0 ]]; then
103 print -u2 $($out)
104 _printerror "$@" "internal error or" \
105 " assertion failure exited $status"
106 status=1
107 else
108 [[ -n $LOGAPI_DEBUG ]] && print $($out)
109 _printsuccess "$@"
110 fi
111 break
112 else
113 $out | grep -i "$expect" > /dev/null 2>&1
114 if (( $? == 0 )); then
115 print -u2 $($out)
116 _printerror "$@" "Retry in $delay seconds"
117 sleep $delay
118
119 (( retry=retry - 1 ))
120 (( delay=delay * 2 ))
121 else
122 break;
123 fi
124 fi
125 done
126
127 if (( $status != 0 )) ; then
128 print -u2 $($out)
129 _printerror "$@" "exited $status"
130 fi
131
132 _recursive_output $logfile "false"
133 return $status
134 }
135
136 # Execute a positive test and exit $STF_FAIL is test fails after being
137 # retried up to 5 times when the command returns the keyword "busy".
138 #
139 # $@ - command to execute
140 function log_must_busy
141 {
142 log_must_retry "busy" 5 "$@"
143 (( $? != 0 )) && log_fail
144 }
145
146 # Execute a negative test and exit $STF_FAIL if test passes
147 #
148 # $@ - command to execute
149
150 function log_mustnot
151 {
152 log_neg "$@"
153 (( $? != 0 )) && log_fail
154 }
155
156 # Execute a negative test with keyword expected, and exit
157 # $STF_FAIL if test passes
158 #
159 # $1 - keyword expected
160 # $2-$@ - command to execute
161
162 function log_mustnot_expect
163 {
164 log_neg_expect "$@"
165 (( $? != 0 )) && log_fail
166 }
167
168 # Execute and print command with status where success equals non-zero result
169 # or output includes expected keyword
170 #
171 # $1 - keyword expected
172 # $2-$@ - command to execute
173 #
174 # return 0 if command fails, or the output contains the keyword expected,
175 # return 1 otherwise
176
177 function log_neg_expect
178 {
179 typeset out=""
180 typeset logfile="/tmp/log.$$"
181 typeset ret=1
182 typeset expect=$1
183 shift
184
185 while [[ -e $logfile ]]; do
186 logfile="$logfile.$$"
187 done
188
189 "$@" 2>$logfile
190 typeset status=$?
191 out="cat $logfile"
192
193 # unexpected status
194 if (( $status == 0 )); then
195 print -u2 $($out)
196 _printerror "$@" "unexpectedly exited $status"
197 # missing binary
198 elif (( $status == 127 )); then
199 print -u2 $($out)
200 _printerror "$@" "unexpectedly exited $status (File not found)"
201 # bus error - core dump
202 elif (( $status == 138 )); then
203 print -u2 $($out)
204 _printerror "$@" "unexpectedly exited $status (Bus Error)"
205 # segmentation violation - core dump
206 elif (( $status == 139 )); then
207 print -u2 $($out)
208 _printerror "$@" "unexpectedly exited $status (SEGV)"
209 else
210 $out | egrep -i "internal error|assertion failed" \
211 > /dev/null 2>&1
212 # internal error or assertion failed
213 if (( $? == 0 )); then
214 print -u2 $($out)
215 _printerror "$@" "internal error or assertion failure" \
216 " exited $status"
217 elif [[ -n $expect ]] ; then
218 $out | grep -i "$expect" > /dev/null 2>&1
219 if (( $? == 0 )); then
220 ret=0
221 else
222 print -u2 $($out)
223 _printerror "$@" "unexpectedly exited $status"
224 fi
225 else
226 ret=0
227 fi
228
229 if (( $ret == 0 )); then
230 [[ -n $LOGAPI_DEBUG ]] && print $($out)
231 _printsuccess "$@" "exited $status"
232 fi
233 fi
234 _recursive_output $logfile "false"
235 return $ret
236 }
237
238 # Execute and print command with status where success equals zero result
239 #
240 # $@ command to execute
241 #
242 # return command exit status
243
244 function log_pos
245 {
246 typeset out=""
247 typeset logfile="/tmp/log.$$"
248
249 while [[ -e $logfile ]]; do
250 logfile="$logfile.$$"
251 done
252
253 "$@" 2>$logfile
254 typeset status=$?
255 out="cat $logfile"
256
257 if (( $status != 0 )) ; then
258 print -u2 $($out)
259 _printerror "$@" "exited $status"
260 else
261 $out | egrep -i "internal error|assertion failed" \
262 > /dev/null 2>&1
263 # internal error or assertion failed
264 if [[ $? -eq 0 ]]; then
265 print -u2 $($out)
266 _printerror "$@" "internal error or assertion failure" \
267 " exited $status"
268 status=1
269 else
270 [[ -n $LOGAPI_DEBUG ]] && print $($out)
271 _printsuccess "$@"
272 fi
273 fi
274 _recursive_output $logfile "false"
275 return $status
276 }
277
278 # Set an exit handler
279 #
280 # $@ - function(s) to perform on exit
281
282 function log_onexit
283 {
284 _CLEANUP="$@"
285 }
286
287 #
288 # Exit functions
289 #
290
291 # Perform cleanup and exit $STF_PASS
292 #
293 # $@ - message text
294
295 function log_pass
296 {
297 _endlog $STF_PASS "$@"
298 }
299
300 # Perform cleanup and exit $STF_FAIL
301 #
302 # $@ - message text
303
304 function log_fail
305 {
306 _endlog $STF_FAIL "$@"
307 }
308
309 # Perform cleanup and exit $STF_UNRESOLVED
310 #
311 # $@ - message text
312
313 function log_unresolved
314 {
315 _endlog $STF_UNRESOLVED "$@"
316 }
317
318 # Perform cleanup and exit $STF_NOTINUSE
319 #
320 # $@ - message text
321
322 function log_notinuse
323 {
324 _endlog $STF_NOTINUSE "$@"
325 }
326
327 # Perform cleanup and exit $STF_UNSUPPORTED
328 #
329 # $@ - message text
330
331 function log_unsupported
332 {
333 _endlog $STF_UNSUPPORTED "$@"
334 }
335
336 # Perform cleanup and exit $STF_UNTESTED
337 #
338 # $@ - message text
339
340 function log_untested
341 {
342 _endlog $STF_UNTESTED "$@"
343 }
344
345 # Perform cleanup and exit $STF_UNINITIATED
346 #
347 # $@ - message text
348
349 function log_uninitiated
350 {
351 _endlog $STF_UNINITIATED "$@"
352 }
353
354 # Perform cleanup and exit $STF_NORESULT
355 #
356 # $@ - message text
357
358 function log_noresult
359 {
360 _endlog $STF_NORESULT "$@"
361 }
362
363 # Perform cleanup and exit $STF_WARNING
364 #
365 # $@ - message text
366
367 function log_warning
368 {
369 _endlog $STF_WARNING "$@"
370 }
371
372 # Perform cleanup and exit $STF_TIMED_OUT
373 #
374 # $@ - message text
375
376 function log_timed_out
377 {
378 _endlog $STF_TIMED_OUT "$@"
379 }
380
381 # Perform cleanup and exit $STF_OTHER
382 #
383 # $@ - message text
384
385 function log_other
386 {
387 _endlog $STF_OTHER "$@"
388 }
389
390 #
391 # Internal functions
392 #
393
394 # Execute custom callback scripts on test failure
395 #
396 # callback script paths are stored in TESTFAIL_CALLBACKS, delimited by ':'.
397
398 function _execute_testfail_callbacks
399 {
400 typeset callback
401
402 print "$TESTFAIL_CALLBACKS:" | while read -d ":" callback; do
403 if [[ -n "$callback" ]] ; then
404 log_note "Performing test-fail callback ($callback)"
405 $callback
406 fi
407 done
408 }
409
410 # Perform cleanup and exit
411 #
412 # $1 - stf exit code
413 # $2-$n - message text
414
415 function _endlog
416 {
417 typeset logfile="/tmp/log.$$"
418 _recursive_output $logfile
419
420 typeset exitcode=$1
421 shift
422 (( ${#@} > 0 )) && _printline "$@"
423
424 if [[ $exitcode == $STF_FAIL ]] ; then
425 _execute_testfail_callbacks
426 fi
427
428 if [[ -n $_CLEANUP ]] ; then
429 typeset cleanup=$_CLEANUP
430 log_onexit ""
431 log_note "Performing local cleanup via log_onexit ($cleanup)"
432 $cleanup
433 fi
434
435 exit $exitcode
436 }
437
438 # Output a formatted line
439 #
440 # $@ - message text
441
442 function _printline
443 {
444 print "$@"
445 }
446
447 # Output an error message
448 #
449 # $@ - message text
450
451 function _printerror
452 {
453 _printline ERROR: "$@"
454 }
455
456 # Output a success message
457 #
458 # $@ - message text
459
460 function _printsuccess
461 {
462 _printline SUCCESS: "$@"
463 }
464
465 # Output logfiles recursively
466 #
467 # $1 - start file
468 # $2 - indicate whether output the start file itself, default as yes.
469
470 function _recursive_output #logfile
471 {
472 typeset logfile=$1
473
474 while [[ -e $logfile ]]; do
475 if [[ -z $2 || $logfile != $1 ]]; then
476 cat $logfile
477 fi
478 rm -f $logfile
479 logfile="$logfile.$$"
480 done
481 }