blob: 3a3114e3eca6684f50ce670f3de350dbca5085e5 [file] [log] [blame]
#!/usr/bin/env bash
#*******************************************************************************
# Copyright (c) 2016 IBM Corporation and others.
#
# This program and the accompanying materials
# are made available under the terms of the Eclipse Public License 2.0
# which accompanies this distribution, and is available at
# https://www.eclipse.org/legal/epl-2.0/
#
# SPDX-License-Identifier: EPL-2.0
#
# Contributors:
# David Williams - initial API and implementation
#*******************************************************************************
# General purpose utilities that are only related to bash (not
# the build, per se.
# A general purpose utility to check number of arguments match
# what was expected. Its purpose is to help bullet-proof these scripts
# when future changes made.
# Example: (such as in first line of a function)
# checkNArgs $# 3
# NOTE: can not be called, until buildDirectory has been defined.
checkNArgs ()
{
actual=$1
expected=$2
if [[ -z "$actual" || -z "$expected" ]]
then
BUILD_FAILED="${buildDirectory}/buildFailed-program-error"
printf "\n\tPROGRAM ERROR: number of arguments, $actual, or number expected, $expected, was not provided as arguments.\n\n" >${BUILD_FAILED}
printf " Called from ${FUNCNAME[1]}, called from line number ${BASH_LINENO[1]} in ${BASH_SOURCE[2]}.\n\n" >>${BUILD_FAILED}
return 9
fi
# possible is used when there are optional arguments, corresponds to "max possible", then "expected" means "min possible"
possible=$3
#echo " DEBUG checkNArgs funcName[1]: ${FUNCNAME[1]}" >> ${TRACE_OUTPUT}
#echo " DEBUG checkNArgs bashSource[2]: ${BASH_SOURCE[2]}" >> ${TRACE_OUTPUT}
#echo " DEBUG checkNArgs bashLineNo[1]: ${BASH_LINENO[1]}" >> ${TRACE_OUTPUT}
if [[ -n "${possible}" ]]
then
# if 3 total arguments, make sure first is between 2 and 3rd args (inclusive)
#echo DEBUG: actual: $actual
#echo DEBUG: min expected: $expected
#echo DEBUG: max possible: $possible
#arg1=$(( $expected <= $actual ))
#arg2=$(( $actual <= $possible ))
#echo "DEBUG: expected <= actual $arg1"
#echo "DEBUG: actual <= possible $arg2"
if (( $expected <= $actual )) && (( $actual <= $possible ))
then
#echo DEBUG: return 0
return 0
else
BUILD_FAILED="${buildDirectory}/buildFailed-program-error"
printf "\n\tPROGRAM ERROR: number of arguments, $actual, was not betwen expected, $expected, and possible, $possible.\n" >${BUILD_FAILED}
printf " Called from ${FUNCNAME[1]}, called from line number ${BASH_LINENO[1]} in ${BASH_SOURCE[2]}.\n\n" >>${BUILD_FAILED}
#echo DEBUG: return 1
return 1
fi
elif [[ $actual != $expected ]]
then
# depends on buildDirectory being exported
BUILD_FAILED="${buildDirectory}/buildFailed-program-error"
printf "\n\tPROGRAM ERROR: expected $expected arguments but was passed $actual.\n" >${BUILD_FAILED}
printf " Called from ${FUNCNAME[1]}, called from line number ${BASH_LINENO[1]} in ${BASH_SOURCE[2]}.\n\n" >>${BUILD_FAILED}
return 1
else
return 0
fi
}
# general purpose utility for "hard exit" if return code not zero.
# especially useful to call/check after basic things that should normally
# easily succeeed.
# usage:
# checkForErrorExit $? "Failed to copy file (for example)"
checkForErrorExit ()
{
# arg 1 must be return code, $?
# arg 2 (remaining line) can be message to print before exiting do to non-zero exit code
exitCode=$1
shift
message="$*"
if [[ -z "${exitCode}" ]]
then
echo "PROGRAM ERROR: checkForErrorExit called with no arguments"
exit 1
fi
if [[ -z "${message}" ]]
then
echo "WARNING: checkForErrorExit called without message"
message="(Calling program provided no message)"
fi
# first make sure exit code is well formed
if [[ "${exitCode}" =~ [0] ]]
then
#echo "exitcode was zero"
exitrc=0
else
if [[ "${exitCode}" =~ ^-?[0-9]+$ ]]
then
#echo "exitcode was indeed a legal, non-zero numeric return code"
exitrc=$exitCode
else
#echo "exitode was not numeric, so will force to 1"
exitrc=1
fi
fi
if [[ $exitrc != 0 ]]
then
echo
echo " ERROR. exit code: ${exitrc}"
echo " ERROR. message: ${message}"
echo
exit $exitrc
fi
}
# A general purpose utility to check if variable is
# undefinded or empty string and exit if so,
# printing a useful diagnosic trace if variable was empty.
# NOTE: only the variable NAME should be passed as argument,
# note its value. Such as
# assertNotEmpty BUILD_ID
# not
# assertNotEmpty $BUILD_ID
assertNotEmpty ()
{
VAR_NAME=$1
#echo "DEBUG: VAR_NAME: $VAR_NAME" >&2
#echo "DEBUG: \$VAR_NAME: ${!VAR_NAME}" >&2
if [[ -z "${!VAR_NAME}" ]]
then
printf "\n\tPROGRAM ERROR: %s\n" "${VAR_NAME} was unexpectedly empty or undefined."
printf "\t%s\n\n" "in ${FUNCNAME[1]}, called from line number ${BASH_LINENO[0]} in ${BASH_SOURCE[1]}."
exit 1
else
printf "\n\t%s:\t%s\n" "${VAR_NAME}" "${!VAR_NAME}"
fi
}
function show_time () {
num=$1
min=0
hour=0
day=0
if((num>59));then
((sec=num%60))
((num=num/60))
if((num>59));then
((min=num%60))
((num=num/60))
if((num>23));then
((hour=num%24))
((day=num/24))
else
((hour=num))
fi
else
((min=num))
fi
else
((sec=num))
fi
if [[ $day > 0 ]]
then
echo "$day d $hour h $min m $sec s"
elif [[ $hour > 0 ]]
then
echo "$hour h $min m $sec s"
elif [[ $min > 0 ]]
then
echo "$min m $sec s"
else
echo "$sec s"
fi
}
# This funtion needs three arguments, in order.
# StartTime (in epoch seconds)
# EndTime (in epock seconds)
# Message. Optional quoted string that is printed with elapsed time. If not provided, "Elapsed Time" is used.
#
elapsedTime ()
{
start=$1
end=$2
message=$3
# TODO: could improve error checking, by making sure times are "all digits"
if [[ -z "$start" ]]
then
"[ERROR] Start time must be provided to ${0##*/}"
exit 1
fi
if [[ -z "$end" ]]
then
"[ERROR] End time must be provided to ${0##*/}"
exit 1
fi
if [[ -z "$message" ]]
then
message="Elapsed Time"
fi
elapsedSeconds=$(( ${end} - ${start} ))
elapsedTime=$( show_time $elapsedSeconds )
echo -e "\n\t${message}: $elapsedTime"
if [[ -n "${timeFile}" ]]
then
# elapsed time is for human readers. elapsedSeconds is recorded too in case we ever do more
# statistics or graphs with the data.
echo -e "\n\t${message}: $elapsedTime\n\t${message}: RawSeconds: ${elapsedSeconds}" >> "${timeFile}"
else
echo -e "\n\t[WARNING] timeFile variable was not defined in ${0##*/}"
fi
}
testElapsedTime ()
{
#RAW_DATE_START="$(date -u +%s )"
RAW_DATE_START="$(date +%s )"
echo -e "\n\tRAW Date Start: ${RAW_DATE_START} \n"
echo -e "\tStart Time: $( date +%Y%m%d%H%M%S -d @${RAW_DATE_START} )"
sleep 6
RAW_DATE_END="$(date +%s )"
echo -e "\n\tRAW Date End: ${RAW_DATE_END} \n"
echo -e "\tEnd Time: $( date +%Y%m%d%H%M%S -d @${RAW_DATE_END} )"
elapsedTime $RAW_DATE_START $RAW_DATE_END "Testing Elapsed Time"
}