The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/contrib/openzfs/tests/test-runner/include/logapi.shlib

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: 08b2800f1adab01bdbb1ca2d17469bf9


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.