Run GENESYS LINE Integration benchmark
#!/usr/bin/env bash
shopt -s extglob
set -o errtrace
#set -o errexit
set +o noclobber
# Defaults {{{
ASSUMEYES=0
NOOP=
FORCE=0
VERBOSE=1
WEBHOOK=
SECRET=
USERID=
COUNT=1
RATE=
UNIT_RATE=
TIMEOUT=5000
# }}}
BENCHMARK_CONTAINER=docker.apac.inin.com/line-integration/benchmark:latest
BENCHMARK_VOLUME=benchmark
# Tools {{{
RED='\033[0;31m'
NC='\033[0m'
function verbose() { # {{{2
[[ $VERBOSE > 0 ]] && echo -e "$@"
} # 2}}}
function warn() { # {{{2
echo -e "Warning: $@"
} # 2}}}
function error() { # {{{2
echo -e "${RED}Error: $@${NC}" >&2
} # 2}}}
function die() { # {{{2
local message=$1
local errorlevel=$2
[[ -z $message ]] && message='Died'
[[ -z $errorlevel ]] && errorlevel=1
echo -e "${RED}$message${NC}" >&2
exit $errorlevel
} # 2}}}
function die_on_error() { # {{{2
local status=$?
local message=$1
if [[ $status != 0 ]]; then
die "${message}, Error: $status" $status
fi
} # 2}}}
# }}}
function benchmark_run() { # {{{2
local name=$1
local webhook=$2
local secret=$3
local userid=$4
local count=$5
local timeout=$6
verbose "Starting container $name ($count requests)"
docker run --rm -t -v ${BENCHMARK_VOLUME}:/usr/local/src/tmp -e "CONTAINER_NAME=$name" --name $name ${BENCHMARK_CONTAINER} \
--log=target=path,path=./tmp/$name --output=./tmp/$name \
--dest=$webhook --secret=$secret --userId=$userid \
--progress --stats --count=$count --timeout=$timeout &
return 0
} # 2}}}
function parse_args() { # {{{2
# options = ( (USAGE=1 0 -h --help) (USER 1 -u --user --id) (0 --gendoc --gen_doc) )
while :; do
case $1 in
--count)
[[ -z $2 || ${2:0:1} == '-' ]] && die "Argument for option $1 is missing"
COUNT=$2
shift 2
continue
;;
--count=*?)
COUNT=${1#*=} # delete everything up to =
;;
--count=)
die "Argument for option $1 is missing"
;;
--rate)
[[ -z $2 || ${2:0:1} == '-' ]] && die "Argument for option $1 is missing"
RATE=$2
shift 2
continue
;;
--rate=*?)
RATE=${1#*=} # delete everything up to =
;;
--rate=)
die "Argument for option $1 is missing"
;;
--secret)
[[ -z $2 || ${2:0:1} == '-' ]] && die "Argument for option $1 is missing"
SECRET=$2
shift 2
continue
;;
--secret=*?)
SECRET=${1#*=} # delete everything up to =
;;
--secret=)
die "Argument for option $1 is missing"
;;
--timeout)
[[ -z $2 || ${2:0:1} == '-' ]] && die "Argument for option $1 is missing"
TIMEOUT=$2
shift 2
continue
;;
--timeout=*?)
TIMEOUT=${1#*=} # delete everything up to =
;;
--timeout=)
die "Argument for option $1 is missing"
;;
--unitrate|--unit_rate|--unit-rate)
[[ -z $2 || ${2:0:1} == '-' ]] && die "Argument for option $1 is missing"
UNIT_RATE=$2
shift 2
continue
;;
--unitrate=*?|--unit_rate=*?|--unit-rate=*?)
UNIT_RATE=${1#*=} # delete everything up to =
;;
--unitrate=|--unit_rate=|--unit-rate=)
die "Argument for option $1 is missing"
;;
--user[iI]d|--user_id|--user-id)
[[ -z $2 || ${2:0:1} == '-' ]] && die "Argument for option $1 is missing"
USERID=$2
shift 2
continue
;;
--user[iI]d=*?|--user_id=*?|--user-id=*?)
USERID=${1#*=} # delete everything up to =
;;
--user[iI]d=|--user_id=|--user-id=)
die "Argument for option $1 is missing"
;;
--webhook)
[[ -z $2 || ${2:0:1} == '-' ]] && die "Argument for option $1 is missing"
WEBHOOK=$2
shift 2
continue
;;
--webhook=*?)
WEBHOOK=${1#*=} # delete everything up to =
;;
--webhook=)
die "Argument for option $1 is missing"
;;
# Standard options
--force)
warn "This program will overwrite the current configuration"
FORCE=1
;;
-h|-\?|--help)
trace "Showing usage"
usage
exit 0
;;
--noop|--dry_run|--dry-run)
warn "This program will execute in dry mode, your system will not be modified"
NOOP=:
;;
--quiet)
VERBOSE=0
trace "Verbose level: $VERBOSE"
;;
-v|--verbose)
VERBOSE=$((VERBOSE + 1))
trace "Verbose level: $VERBOSE"
;;
-y|--yes|--assumeyes|--assume_yes|--assume-yes) # All questions will get a "yes" answer automatically
ASSUMEYES=1
trace "All prompts will be answered \"yes\" automatically"
;;
-?*) # Invalid options
warn "Unknown option $1 will be ignored"
;;
--) # Force end of options
shift
break
;;
*) # End of options
break
;;
esac
shift
done
[[ -z $COUNT ]] && COUNT=1
[[ -z $RATE ]] && RATE=1
[[ -z $SECRET ]] && die "Secret is a mandatory option"
[[ -z $TIMEOUT ]] && TIMEOUT=5000
[[ -z $UNIT_RATE ]] && UNIT_RATE=$RATE
[[ -z $USERID ]] && die "Userid is a mandatory option"
[[ -z $WEBHOOK ]] && die "Webhook is a mandatory option"
return 0
} # 2}}}
function main() { # {{{2
local container_count
local result=0
local pids=()
parse_args "$@"
let "container_count = $RATE / $UNIT_RATE"
verbose "Starting $container_count containers to run the benchmark"
for c in `seq 1 $container_count`; do
name=$(printf "benchmark%02d" $c)
benchmark_run $name $WEBHOOK $SECRET $USERID $COUNT $TIMEOUT
pids=(${pids[@]} $!)
done
verbose "Waiting for $container_count containers to finish"
for pid in ${pids[@]}; do
echo "Waiting for PID $pid..."
wait $pid || let "result=1"
done
[[ $result == 1 ]] && die "Some container failed! Not sure the results are relevant..."
verbose "Collecting logs"
docker run --rm -v /$(pwd):/backup -v ${BENCHMARK_VOLUME}:/benchmark alpine:edge \
tar czf /backup/benchmark-$(date "+%Y%m%dT%H%M%S").tar.gz -C / benchmark
} # 2}}}
main "$@"