naviat
8/1/2018 - 4:43 PM

Run GENESYS LINE Integration benchmark

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 "$@"