#!/bin/bash #============================================================================== # Copyright and license info is available in the LICENSE file included with # the Server Deployment Package (SDP), and also available online: # https://swarm.workshop.perforce.com/projects/perforce-software-sdp/view/main/LICENSE #------------------------------------------------------------------------------ #============================================================================== # Declarations and Environment # Allow override of P4U_HOME, which is set only when testing P4U scripts. export P4U_HOME=${P4U_HOME:-/p4/common/bin} export P4U_LIB=${P4U_LIB:-/p4/common/lib} export P4U_ENV=$P4U_LIB/p4u_env.sh export P4U_LOG="/tmp/test_utils.sh.$(date +'%Y%m%d-%H%M%S').log" export VERBOSITY=${VERBOSITY:-3} # Environment isolation. For stability and security reasons, prepend # PATH to include dirs where known-good scripts exist. # known/tested PATH and, by implication, executables on the PATH. export PATH=$P4U_HOME:$PATH:~/bin:. export P4CONFIG=${P4CONFIG:-.p4config} [[ -r "$P4U_ENV" ]] || { echo -e "\nError: Cannot load environment from: $P4U_ENV\n\n" exit 1 } . $P4U_ENV . $P4U_LIB/libcore.sh . $P4U_LIB/libp4u.sh declare -i SilentMode=0 declare Version=1.0.3 #============================================================================== # Local Functions #------------------------------------------------------------------------------ # Function: terminate function terminate { # Disable signal trapping. trap - EXIT SIGINT SIGTERM # Don't litter. cleanTrash vvmsg "$THISSCRIPT: EXITCODE: $OverallReturnStatus" # Stop logging. [[ "${P4U_LOG}" == off ]] || stoplog # With the trap removed, exit. exit $OverallReturnStatus } #------------------------------------------------------------------------------ # Function: usage (required function) # # Input: # $1 - style, either -h (for short form) or -man (for man-page like format). #------------------------------------------------------------------------------ function usage { declare style=${1:--h} echo "USAGE: $THISSCRIPT [-L <log>] [-si] [-v<n>] [-n] [-D] or $THISSCRIPT [-h|-man] " if [[ $style == -man ]]; then echo -e " DESCRIPTION: This script tests runCmd(), runRemoteCmd(), run(), and rrun() utilities. OPTIONS: -v<n> Set verbosity 1-5 (-v1 = quiet, -v5 = highest). -L <log> Specify the path to a log file, or the special value 'off' to disable logging. By default, all output (stdout and stderr) goes to: $(dirname ${P4U_LOG}). NOTE: This script is self-logging. That is, output displayed on the screen is simultaneously captured in the log file. Do not run this script with redirection operators like '> log' or '2>&1', and do not use 'tee.' -si Operate silently. All output (stdout and stderr) is redirected to the log only; no output appears on the terminal. This cannot be used with '-L off'. -n No-Op. Prints commands instead of running them. -D Set extreme debugging verbosity. HELP OPTIONS: -h Display short help message -man Display man-style help message FILES: EXAMPLES: SEE ALSO: " fi exit 1 } #============================================================================== # Command Line Processing declare -i shiftArgs=0 set +u while [[ $# -gt 0 ]]; do case $1 in (-h) usage -h;; (-man) usage -man;; (-v1) export VERBOSITY=1;; (-v2) export VERBOSITY=2;; (-v3) export VERBOSITY=3;; (-v4) export VERBOSITY=4;; (-v5) export VERBOSITY=5;; (-L) export P4U_LOG=$2; shiftArgs=1;; (-si) SilentMode=1;; (-n) export NO_OP=1;; (-D) set -x;; # Debug; use 'set -x' mode. (*) usageError "Unknown arg ($1).";; esac # Shift (modify $#) the appropriate number of times. shift; while [[ $shiftArgs -gt 0 ]]; do [[ $# -eq 0 ]] && usageError "Bad usage." shiftArgs=$shiftArgs-1 shift done done set -u #============================================================================== # Command Line Verification [[ $SilentMode -eq 1 && $P4U_LOG == off ]] && \ usageError "Cannot use '-si' with '-L off'." #============================================================================== # Main Program trap terminate EXIT SIGINT SIGTERM declare -i OverallReturnStatus=0 if [[ "${P4U_LOG}" != off ]]; then touch ${P4U_LOG} || bail "Couldn't touch log file [${P4U_LOG}]." # Redirect stdout and stderr to a log file. if [[ $SilentMode -eq 0 ]]; then exec > >(tee ${P4U_LOG}) exec 2>&1 else exec >${P4U_LOG} exec 2>&1 fi initlog fi msg "Started ${0##*/} v$Version at $(date)." echo "Testing capture of stdout." echo "foo" echo "Testing capture of stderr." echo "bar" >&2 runCmd "ls /tmp/xxx" "List /tmp/xxx with runCmd()." echo CMDEXITCODE=$CMDEXITCODE echo CMDOUTPUT=$CMDOUTPUT run "ls /tmp/xxx" "List /tmp/xxx with run()." echo CMDEXITCODE=$CMDEXITCODE runCmd "ls" "Directory List: (std) with runCmd()" 1 1 0 echo CMDEXITCODE=$CMDEXITCODE echo CMDOUTPUT=$CMDOUTPUT run "ls" "Directory List: (std) with run()" 1 1 0 echo CMDEXITCODE=$CMDEXITCODE runCmd "ls" "Directory List: (inline) with runCmd()" 1 1 1 echo CMDEXITCODE=$CMDEXITCODE echo CMDOUTPUT=$CMDOUTPUT runCmd "ls" "Directory List: (inline) with run()" 1 1 1 echo CMDEXITCODE=$CMDEXITCODE runCmd "ls 2>&1 | tail -1 | grep chuckayukyuk" "Chained command sequence: (inline) with runCmd()" 1 1 echo CMDEXITCODE=$CMDEXITCODE echo CMDOUTPUT=$CMDOUTPUT runCmd "ls 2>&1 | tail -1 | grep chuckayukyuk" "Chained command sequence: (inline) with run()" 1 1 echo CMDEXITCODE=$CMDEXITCODE runCmd "/bin/sleep 1" "Taking a short nap with runCmd()." 1 0 echo CMDEXITCODE=$CMDEXITCODE echo CMDOUTPUT=$CMDOUTPUT runCmd "/bin/sleep 1" "Taking a short nap with run()." 1 0 echo CMDEXITCODE=$CMDEXITCODE # Illustrate stringing together a series of commands using a '|'. # runCmd() can handle this. grep_string="Mar 15" runCmd "ls -lrt|grep \"$grep_string\"|head -2|tail -1" "Showing last file with runCmd():" 1 1 echo CMDEXITCODE=$CMDEXITCODE echo CMDOUTPUT=$CMDOUTPUT run "ls -lrt|grep \"$grep_string\"|head -2|tail -1" "Showing last file with run():" 1 1 echo CMDEXITCODE=$CMDEXITCODE msg "Sample Info Message - 1" vmsg "Sample Verbose Info Message - 2" vvmsg "Sample Very Verbose Info Message - 3" warnmsg "Sample Warning Message - 4" errmsg "Sample Error Message - 5" runRemoteCmd "localhost" "ls" "Listing with runRemoteCmd()." echo RCMDEXITCODE=$RCMDEXITCODE echo RCMDOUTPUT=$RCMDOUTPUT rrun "localhost" "ls" "Listing with rrun()." echo RCMDEXITCODE=$RCMDEXITCODE if [[ $OverallReturnStatus -eq 0 ]]; then msg "${H}\nAll processing completed successfully.\n" else msg "${H}\nProcessing completed, but with errors. Scan above output carefully.\n" fi # Illustrate using $SECONDS to display runtime of a script. msg "That took about $(($SECONDS/3600)) hours $(($SECONDS%3600/60)) minutes $(($SECONDS%60)) seconds.\n" # See the terminate() function, which is really where this script exits. exit $OverallReturnStatus
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#1 | 23960 | noe_gonzalez | "Forking branch Dev of perforce-software-sdp to noe_gonzalez-sdp." | ||
//guest/perforce_software/sdp/dev/Server/Unix/p4/common/test/test_utils.sh | |||||
#3 | 21962 | C. Thomas Tyler |
Updated various scripts to use run() and rrun() functions in favor of predecessor runCmd() and runRemoteCmd(). The older functions won't be removed to avoid breaking scripts that rely on their behavior and have no issues with them. The newer fuctions are more scalable and avoid erroneous "Argument list too long" from bash due to buffer overruns when used with commands with large amounts of output. Enhanced runRemoteCmd() to clean up after itself, as it generated files in /tmp that didn't get automatically cleaned up. If used in scripts called very often (e.g. every 5 minutes in a crontab), this leads to significant issues with /tmp filling up with garbage files over a period of several weeks. Enhanced test_utils.sh to test new run() and rrun() calls. |
||
#2 | 16029 | C. Thomas Tyler |
Routine merge to dev from main using: p4 merge -b perforce_software-sdp-dev |
||
#1 | 10638 | C. Thomas Tyler | Populate perforce_software-sdp-dev. | ||
//guest/perforce_software/sdp/main/Server/Unix/p4/common/test/test_utils.sh | |||||
#1 | 10148 | C. Thomas Tyler | Promoted the Perforce Server Deployment Package to The Workshop. |