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