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