1#!/bin/sh 2# 3# eval_tools.sh 4# 5# Output functions for script tests. Source this from other test scripts 6# to establish a standardized repertory of test functions. 7# 8# 9# Except where noted, all functions return: 10# 0 On success, (Bourne Shell's ``true'') 11# non-0 Otherwise. 12# 13# Input arguments to each function are documented with each function. 14# 15# 16# XXX Suggestions: 17# DEBUG ON|OFF 18# dump CAPTURE output to stdout as well as to junkoutputfile. 19# 20 21# 22# Only allow ourselves to be eval'ed once 23# 24if [ "x$EVAL_TOOLS_SH_EVALED" != "xyes" ]; then 25 EVAL_TOOLS_SH_EVALED=yes 26 27# 28# Variables used in global environment of calling script. 29# 30failcount=0 31testnum=0 32errnum=0 33junkoutputfilebase="$SNMP_TMPDIR/output-`basename $0`$$" 34junkoutputfile=$junkoutputfilebase 35outputcount=0 36separator="-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=" 37if [ -z "$OK_TO_SAVE_RESULT" ] ; then 38OK_TO_SAVE_RESULT=1 39export OK_TO_SAVE_RESULT 40fi 41 42if [ `uname -s` = SunOS ] 43then PATH=/usr/xpg4/bin:$PATH 44fi 45 46# 47# HEADER: returns a single line when SNMP_HEADERONLY mode and exits. 48# 49HEADER() { 50 if [ "x$SNMP_HEADERONLY" != "x" ]; then 51 echo test $* 52 exit 0; 53 else 54 { echo "# testing $*"; echo ""; } >> $SNMP_TMPDIR/invoked 55 fi 56} 57 58 59#------------------------------------ -o- 60# 61OUTPUT() { # <any_arguments> 62 cat <<GRONK 63 64 65$* 66 67 68GRONK 69} 70 71CAN_USLEEP() { 72 if [ "$SNMP_CAN_USLEEP" = 0 -o "$SNMP_CAN_USLEEP" = 1 ] ; then 73 return 0 74 fi 75 sleep .1 > /dev/null 2>&1 76 if [ $? = 0 ] ; then 77 SNMP_CAN_USLEEP=1 78 else 79 SNMP_CAN_USLEEP=0 80 fi 81 export SNMP_CAN_USLEEP 82} 83 84 85#------------------------------------ -o- 86# 87SUCCESS() { # <any_arguments> 88 [ "$failcount" -ne 0 ] && return 89 cat <<GROINK 90 91SUCCESS: $* 92 93GROINK 94} 95 96 97 98#------------------------------------ -o- 99# 100FAILED() { # <return_value>, <any_arguments> 101 [ "$1" -eq 0 ] && return 102 shift 103 104 failcount=`expr $failcount + 1` 105 cat <<GRONIK 106 107FAILED: $* 108 109GRONIK 110} 111 112#------------------------------------ -o- 113# 114SKIP() { 115 REMOVETESTDATA 116 echo "1..0 # SKIP $*" 117 exit 0 118} 119 120ISDEFINED() { 121 grep "^#define $1 " ${builddir}/include/net-snmp/net-snmp-config.h ${builddir}/include/net-snmp/agent/mib_module_config.h ${builddir}/include/net-snmp/agent/agent_module_config.h > /dev/null 122} 123 124SKIPIFNOT() { 125 ISDEFINED "$1" || SKIP "$1 is not defined" 126} 127 128SKIPIF() { 129 ISDEFINED "$1" && SKIP "$1 is defined" 130} 131 132#------------------------------------ -o- 133# 134VERIFY() { # <path_to_file(s)> 135 missingfiles="" 136 137 for f in $*; do 138 [ -f "$f" ] && continue 139 echo "FAILED: Cannot find file \"$f\"." 140 missingfiles=true 141 done 142 143 [ "$missingfiles" = true ] && exit 1000 144} 145 146NEWOUTPUTFILE() { 147 outputcount=`expr $outputcount + 1` 148 junkoutputfile="${junkoutputfilebase}-$outputcount" 149} 150 151#------------------------------------ -o- 152# 153STARTTEST() { 154 NEWOUTPUTFILE 155 [ ! -f "$junkoutputfile" ] && { 156 touch $junkoutputfile 157 return 158 } 159 echo "FAILED: Output file already exists: \"$junkoutputfile\"." 160 exit 1000 161} 162 163 164#------------------------------------ -o- 165# 166STOPTEST() { 167 rm -f "$junkoutputfile" 168} 169 170 171#------------------------------------ -o- 172# 173REMOVETESTDATA() { 174# ECHO "removing $SNMP_TMPDIR " 175 rm -rf $SNMP_TMPDIR 176} 177 178#------------------------------------ -o- 179# 180OUTPUTENVVARS() { 181 echo "SNMPCONFPATH=$SNMPCONFPATH" >> $1 182 echo "SNMP_PERSISTENT_DIR=$SNMP_PERSISTENT_DIR" >> $1 183 echo "MIBDIRS=$MIBDIRS" >> $1 184 echo "PATH=$PATH" >> $1 185 echo "export SNMPCONFPATH" >> $1 186 echo "export SNMP_PERSISTENT_DIR" >> $1 187 echo "export MIBDIRS" >> $1 188 echo "export PATH" >> $1 189} 190 191#------------------------------------ -o- 192# Captures output from command, and returns the command's exit code. 193loggedvars=0 194CAPTURE() { # <command_with_arguments_to_execute> 195 NEWOUTPUTFILE 196 197 # track invoked command per test when verbose 198 if [ $SNMP_VERBOSE -gt 0 ]; then 199 OUTPUTENVVARS $junkoutputfile.invoked 200 echo $* >> $junkoutputfile.invoked 201 fi 202 203 if [ $loggedvars = 0 ]; then 204 OUTPUTENVVARS $SNMP_TMPDIR/invoked 205 loggedvars=1 206 fi 207 echo $* >> $SNMP_TMPDIR/invoked 208 209 if [ $SNMP_VERBOSE -gt 0 ]; then 210 cat <<KNORG 211 212EXECUTING: $* 213 214KNORG 215 216 fi 217 echo "RUNNING: $*" > $junkoutputfile 218 ( $DYNAMIC_ANALYZER $* 2>&1 ) >> $junkoutputfile 2>&1 219 RC=$? 220 221 if [ $SNMP_VERBOSE -gt 1 ]; then 222 echo "Command Output: " 223 echo "MIBDIR $MIBDIRS $MIBS" 224 echo "$separator" 225 cat $junkoutputfile | sed 's/^/ /' 226 echo "$separator" 227 fi 228 return $RC 229} 230 231#------------------------------------ -o- 232# Delay to let processes settle 233DELAY() { 234 if [ "$SNMP_SLEEP" != "0" ] ; then 235 sleep $SNMP_SLEEP 236 fi 237} 238 239SAVE_RESULTS() { 240 real_return_value=$return_value 241} 242 243# 244# Checks the output result against what we expect. 245# Sets return_value to 0 or 1. 246# 247EXPECTRESULT() { 248 if [ $OK_TO_SAVE_RESULT -ne 0 ] ; then 249 if [ "$snmp_last_test_result" = "$1" ]; then 250 return_value=0 251 else 252 return_value=1 253 fi 254 fi 255} 256 257CHECKCOUNT() { 258 CHECKFILECOUNT "$junkoutputfile" $@ 259} 260 261CHECKVALUEIS() { 262 value1=$1 263 value2=$2 264 if [ "x$value1" = "x$value2" ]; then 265 GOOD "$3" 266 else 267 BAD "$3" 268 fi 269} 270 271CHECKVALUEISNT() { 272 value1=$1 273 value2=$2 274 if [ "x$value1" = "x$value2" ]; then 275 BAD "$3" 276 else 277 GOOD "$3" 278 fi 279} 280 281#------------------------------------ -o- 282# Returns: Count of matched lines. 283# 284CHECKFILECOUNT() { # <pattern_to_match> 285 chkfile=$1 286 ckfcount=$2 287 shift 288 shift 289 if [ $SNMP_VERBOSE -gt 0 ]; then 290 echo -n "checking $chkfile for $ckfcount \"$*\"..." 291 fi 292 293 if [ -f $chkfile ]; then 294 rval=`grep -c "$*" "$chkfile" 2>/dev/null` 295 else 296 COMMENT "Note: file $chkfile does not exist and we were asked to check it" 297 rval=0 298 fi 299 300 if [ $SNMP_VERBOSE -gt 0 ]; then 301 echo "$rval matches found" 302 fi 303 304 snmp_last_test_result=$rval 305 EXPECTRESULT $ckfcount # default 306 if [ "$ckfcount" != "noerror" ]; then 307 if [ "$ckfcount" = "atleastone" ]; then 308 if [ "$rval" -ne "0" ]; then 309 GOOD "found $ckfcount copies of '$*' in output ($chkfile); needed one" 310 else 311 BAD "found $rval copies of '$*' in output ($chkfile); expected 1" 312 COMMENT "Outputfile: $chkfile" 313 fi 314 else 315 if [ "$rval" = "$ckfcount" ]; then 316 GOOD "found $ckfcount copies of '$*' in output ($chkfile)" 317 else 318 BAD "found $rval copies of '$*' in output ($chkfile); expected $ckfcount" 319 COMMENT "Outputfile: $chkfile" 320 fi 321 fi 322 fi 323 return $rval 324} 325 326CHECK() { 327 CHECKCOUNT 1 $@ 328} 329 330CHECKFILE() { 331 file=$1 332 shift 333 CHECKFILECOUNT $file 1 $@ 334} 335 336CHECKTRAPD() { 337 CHECKFILE $SNMP_SNMPTRAPD_LOG_FILE $@ 338} 339 340CHECKTRAPDCOUNT() { 341 count=$1 342 shift 343 CHECKFILECOUNT $SNMP_SNMPTRAPD_LOG_FILE $count $@ 344} 345 346CHECKTRAPDORDIE() { 347 CHECKORDIE $@ $SNMP_SNMPTRAPD_LOG_FILE 348} 349 350CHECKAGENT() { 351 CHECKFILE $SNMP_SNMPD_LOG_FILE $@ 352} 353 354CHECKAGENTCOUNT() { 355 count=$1 356 shift 357 CHECKFILECOUNT $SNMP_SNMPD_LOG_FILE $count $@ 358} 359 360# Return 0 (true) if a process with pid $1 exists and 1 (false) if no process 361# with pid $1 exists. 362ISRUNNING() { 363 if [ "x$OSTYPE" = "xmsys" ]; then 364 pslist.exe "$1" 2>&1 | while read name pspid rest; do 365 if [ "$1" = "$pspid" ]; then 366 return 0 367 fi 368 done 369 return 1 370 else 371 kill -0 "$1" 2>/dev/null 372 fi 373} 374 375# Echo a command that asks the process with pid $1 to stop. 376ECHOSENDSIGTERM() { 377 if [ "x$OSTYPE" = "xmsys" ]; then 378 echo pskill.exe $1 379 else 380 echo kill -TERM $1 381 fi 382} 383 384# Echo a command that stops the process with pid $1 forcibly. 385ECHOSENDSIGKILL() { 386 if [ "x$OSTYPE" = "xmsys" ]; then 387 echo pskill.exe $1 388 else 389 echo kill -KILL $1 390 fi 391} 392 393# Wait until the shell statement "$@" evaluates to false. 394WAITFORNOTCOND() { 395 CAN_USLEEP 396 if [ $SNMP_CAN_USLEEP = 1 ] ; then 397 sleeptime=`expr $SNMP_SLEEP '*' 50` 398 else 399 sleeptime=`expr $SNMP_SLEEP '*' 5` 400 fi 401 while [ $sleeptime -gt 0 ] && eval "$@"; do 402 if [ $SNMP_CAN_USLEEP = 1 ]; then 403 sleep .1 404 else 405 sleep 1 406 fi 407 sleeptime=`expr $sleeptime - 1` 408 done 409} 410 411# Wait until the shell statement "$@" evaluates to true. 412WAITFORCOND() { 413 WAITFORNOTCOND if "$@;" then false ";" else true ";" fi 414} 415 416WAITFORAGENT() { 417 WAITFOR "$@" $SNMP_SNMPD_LOG_FILE 418 if [ $SNMP_CAN_USLEEP = 1 ]; then 419 sleep .1 420 else 421 sleep 1 422 fi 423} 424 425WAITFORTRAPD() { 426 WAITFOR "$@" $SNMP_SNMPTRAPD_LOG_FILE 427 if [ $SNMP_CAN_USLEEP = 1 ]; then 428 sleep .1 429 else 430 sleep 1 431 fi 432} 433 434# Wait until pattern "$1" appears in file "$2". 435WAITFOR() { 436 WAITFORCOND grep "$1" "$2" ">/dev/null" "2>&1" 437} 438 439GOOD() { 440 testnum=`expr $testnum + 1` 441 echo "ok $testnum - $1" 442 echo "# ok $testnum - $1" >> $SNMP_TMPDIR/invoked 443} 444 445BAD() { 446 testnum=`expr $testnum + 1` 447 errnum=`expr $errnum + 1` 448 echo "not ok $testnum - $1" 449 echo "# not ok $testnum - $1" >> $SNMP_TMPDIR/invoked 450} 451 452COMMENT() { 453 echo "# $@" 454 echo "# $@" >> $SNMP_TMPDIR/invoked 455} 456 457# CHECKORDIE "grep string" ["file"] .. FAIL if "grep string" is *not* found 458CHECKORDIE() { 459 if [ "x$2" = "x" ]; then 460 CHECKFILE "$junkoutputfile" "$1" 461 else 462 CHECKFILECOUNT "$2" 1 "$1" 463 fi 464} 465 466# CHECKANDDIE "grep string" ["file"] .. FAIL if "grep string" *is* found 467CHECKANDDIE() { 468 if [ "x$2" = "x" ]; then 469 CHECKFILECOUNT "$junkoutputfile" 0 "$1" 470 else 471 CHECKFILECOUNT "$2" 0 "$1" 472 fi 473} 474 475#------------------------------------ -o- 476# Returns: Count of matched lines. 477# 478CHECKEXACT() { # <pattern_to_match_exactly> 479 rval=`egrep -c "^$*\$|^$*[^a-zA-Z0-9_]|[^a-zA-Z0-9_]$*\$|[^a-zA-Z0-9_]$*[^a-zA-Z0-9_]" "$junkoutputfile" 2>/dev/null` 480 snmp_last_test_result=$rval 481 EXPECTRESULT 1 # default 482 return $rval 483} 484 485CONFIGAGENT() { 486 if [ "x$SNMP_CONFIG_FILE" = "x" ]; then 487 echo "$0: failed because var: SNMP_CONFIG_FILE wasn't set" 488 exit 1; 489 fi 490 echo $* >> $SNMP_CONFIG_FILE 491} 492 493CONFIGTRAPD() { 494 if [ "x$SNMPTRAPD_CONFIG_FILE" = "x" ]; then 495 echo "$0: failed because var: SNMPTRAPD_CONFIG_FILE wasn't set" 496 exit 1; 497 fi 498 echo $* >> $SNMPTRAPD_CONFIG_FILE 499} 500 501CONFIGAPP() { 502 if [ "x$SNMPAPP_CONFIG_FILE" = "x" ]; then 503 echo "$0: failed because var: SNMPAPP_CONFIG_FILE wasn't set" 504 exit 1; 505 fi 506 echo $* >> $SNMPAPP_CONFIG_FILE 507} 508 509# 510# common to STARTAGENT and STARTTRAPD 511# log command to "invoked" file 512# 513STARTPROG() { 514 if [ "x$DYNAMIC_ANALYZER" != "x" ]; then 515 COMMAND="$DYNAMIC_ANALYZER $COMMAND" 516 fi 517 if [ $SNMP_VERBOSE -gt 1 ]; then 518 echo "$CFG_FILE contains: " 519 if [ -f $CFG_FILE ]; then 520 cat $CFG_FILE 521 else 522 echo "[no config file]" 523 fi 524 fi 525 if test -f $CFG_FILE; then 526 COMMAND="$COMMAND -C -c $CFG_FILE" 527 fi 528 if [ "x$PORT_SPEC" != "x" ]; then 529 COMMAND="$COMMAND $PORT_SPEC" 530 fi 531 if [ $SNMP_VERBOSE -gt 0 ]; then 532 echo "running: $COMMAND" 533 fi 534 echo $COMMAND >> $SNMP_TMPDIR/invoked 535 if [ $SNMP_VERBOSE -gt 0 ]; then 536 OUTPUTENVVARS $LOG_FILE.command 537 echo $COMMAND >> $LOG_FILE.command 538 fi 539 if [ "x$OSTYPE" = "xmsys" ]; then 540 $COMMAND > $LOG_FILE.stdout 2>&1 & 541 ## COMMAND="cmd.exe //c start //min $COMMAND" 542 ## start $COMMAND > $LOG_FILE.stdout 2>&1 543 else 544 $COMMAND > $LOG_FILE.stdout 2>&1 545 fi 546} 547 548#------------------------------------ -o- 549STARTAGENT() { 550 SNMPDSTARTED=1 551 COMMAND="snmpd $SNMP_FLAGS -r -U -p $SNMP_SNMPD_PID_FILE -Lf $SNMP_SNMPD_LOG_FILE $AGENT_FLAGS" 552 CFG_FILE=$SNMP_CONFIG_FILE 553 LOG_FILE=$SNMP_SNMPD_LOG_FILE 554 PORT_SPEC="$SNMP_SNMPD_PORT" 555 if [ "x$SNMP_TRANSPORT_SPEC" != "x" ]; then 556 PORT_SPEC="${SNMP_TRANSPORT_SPEC}:${SNMP_TEST_DEST}${PORT_SPEC}" 557 fi 558 STARTPROG 559 WAITFORCOND test -f $SNMP_SNMPD_PID_FILE 560 WAITFORAGENT "NET-SNMP.version" 561} 562 563#------------------------------------ -o- 564STARTTRAPD() { 565 TRAPDSTARTED=1 566 COMMAND="snmptrapd -d -p $SNMP_SNMPTRAPD_PID_FILE -Lf $SNMP_SNMPTRAPD_LOG_FILE $TRAPD_FLAGS" 567 CFG_FILE=$SNMPTRAPD_CONFIG_FILE 568 LOG_FILE=$SNMP_SNMPTRAPD_LOG_FILE 569 PORT_SPEC="$SNMP_SNMPTRAPD_PORT" 570 if [ "x$SNMP_TRANSPORT_SPEC" != "x" ]; then 571 PORT_SPEC="${SNMP_TRANSPORT_SPEC}:${SNMP_TEST_DEST}${PORT_SPEC}" 572 fi 573 STARTPROG 574 WAITFORCOND test -f $SNMP_SNMPTRAPD_PID_FILE 575 WAITFORTRAPD "NET-SNMP.version" 576} 577 578## sending SIGHUP for reconfiguration 579# 580HUPPROG() { 581 if [ -f $1 ]; then 582 if [ "x$OSTYPE" = "xmsys" ]; then 583 COMMAND='echo "Skipping SIGHUP (not possible with MinGW)"' 584 else 585 COMMAND="kill -HUP `cat $1`" 586 fi 587 echo $COMMAND >> $SNMP_TMPDIR/invoked 588 VERBOSE_OUT 0 $COMMAND 589 $COMMAND > /dev/null 2>&1 590 fi 591} 592 593HUPAGENT() { 594 HUPPROG $SNMP_SNMPD_PID_FILE 595 if [ "x$OSTYPE" != "xmsys" ]; then 596 WAITFORAGENT "restarted" 597 fi 598} 599 600HUPTRAPD() { 601 HUPPROG $SNMP_SNMPTRAPD_PID_FILE 602 if [ "x$OSTYPE" != "xmsys" ]; then 603 WAITFORTRAPD "restarted" 604 fi 605} 606 607 608## used by STOPAGENT and STOPTRAPD 609# delay before kill to allow previous action to finish 610# this is especially important for interaction between 611# master agent and sub agent. 612STOPPROG() { 613 pid="`cat $1 2>/dev/null`" 614 if [ "x$pid" != "x" ]; then 615 COMMAND="`ECHOSENDSIGTERM $pid`" 616 echo "$COMMAND ($1)" >> $SNMP_TMPDIR/invoked 617 VERBOSE_OUT 0 "$COMMAND ($1)" 618 $COMMAND >/dev/null 2>&1 619 WAITFORNOTCOND "ISRUNNING $pid" 620 fi 621} 622 623#------------------------------------ -o- 624# 625STOPAGENT() { 626 SAVE_RESULTS 627 STOPPROG $SNMP_SNMPD_PID_FILE 628 if [ $SNMP_VERBOSE -gt 1 ]; then 629 echo "Agent Output:" 630 echo "$separator [stdout]" 631 cat $SNMP_SNMPD_LOG_FILE.stdout 632 echo "$separator [logfile]" 633 cat $SNMP_SNMPD_LOG_FILE 634 echo "$separator" 635 fi 636} 637 638#------------------------------------ -o- 639# 640STOPTRAPD() { 641 SAVE_RESULTS 642 STOPPROG $SNMP_SNMPTRAPD_PID_FILE 643 if [ $SNMP_VERBOSE -gt 1 ]; then 644 echo "snmptrapd Output:" 645 echo "$separator [stdout]" 646 cat $SNMP_SNMPTRAPD_LOG_FILE.stdout 647 echo "$separator [logfile]" 648 cat $SNMP_SNMPTRAPD_LOG_FILE 649 echo "$separator" 650 fi 651} 652 653#------------------------------------ -o- 654# 655FINISHED() { 656 657 ## no more changes to test result. 658 OK_TO_SAVE_RESULT=0 659 660 pids="`cat $SNMP_TMPDIR/*pid* 2>/dev/null`" 661 if [ "$SNMPDSTARTED" = "1" ] ; then 662 STOPAGENT 663 fi 664 if [ "$TRAPDSTARTED" = "1" ] ; then 665 STOPTRAPD 666 fi 667 for pid in $pids; do 668 if ISRUNNING $pid; then 669 SNMP_SAVE_TMPDIR=yes 670 COMMAND="`ECHOSENDSIGKILL $pid`" 671 echo "$COMMAND ($pfile)" >> $SNMP_TMPDIR/invoked 672 VERBOSE_OUT 0 "$COMMAND ($pfile)" 673 $COMMAND > /dev/null 2>&1 674 return_value=1 675 fi 676 done 677 678 # report the number of tests done 679 GOOD "got to FINISHED" 680 echo "1..$testnum" 681 682 if [ "x$errnum" != "x0" ]; then 683 if [ -s core ] ; then 684 # XX hope that only one prog cores ! 685 cp core $SNMP_TMPDIR/core.$$ 686 rm -f core 687 fi 688 echo "$headerStr...FAIL" >> $SNMP_TMPDIR/invoked 689 if [ -n "${TRAVIS_OS_NAME}" ] || [ -n "$APPVEYOR" ] || 690 [ -n "$CIRRUS_CI" ]; then 691 { 692 find "$SNMP_TMPDIR" -type f | 693 while read -r f; do 694 local lines 695 echo "==== $f" 696 lines=$(wc -l "$f" | { read -r a b; echo "$a"; }) 697 if [ "$lines" -gt 512 ]; then 698 head -n 256 "$f" 699 echo "..." 700 tail -n 256 "$f" 701 else 702 cat "$f" 703 fi 704 done; 705 } 1>&2 706 fi 707 exit 1 708 fi 709 710 echo "$headerStr...ok" >> $SNMP_TMPDIR/invoked 711 712 if [ "x$SNMP_SAVE_TMPDIR" != "xyes" ]; then 713 REMOVETESTDATA 714 fi 715 exit 0 716} 717 718#------------------------------------ -o- 719# 720VERBOSE_OUT() { 721 if [ $SNMP_VERBOSE -gt $1 ]; then 722 shift 723 echo "$*" 724 fi 725} 726 727fi # Only allow ourselves to be eval'ed once 728