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