#!/bin/bash
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
#

# This script is used to measure memory consumption by Apache Qpid Broker-J running in Oracle JDK
# Use plot.py to plot graphs of memory usage from results collected by this test

function waitfor()
{
  counter=1
  until grep -a -l "$2" $1 >/dev/null 2>&1 ; do
    sleep 1 ;
    let "counter += 1"
    if [ "$counter" -gt "$3" ]; then
      break
    fi
  done
}

function awaitBroker()
{
  echo "Awaiting broker..."
  waitfor ${QPID_WORK}/log/qpid.log "BRK-1004" "30"
  echo "Broker is ready"
}

function startBroker()
{
  echo "Starting broker"
  export QPID_OPTS="-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=${RMI_PORT} -Dcom.sun.management.jmxremote.local.only=false -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false"
  ${QPID_HOME}/bin/qpid-server 2>${QPID_WORK}/log/qpid.stderr > ${QPID_WORK}/log/qpid.stdout &
  brokerpid=$!
  echo "Broker started: PID $brokerpid"
}

function stopBroker()
{
  messageSize=$1
  messageCount=$2
  resultFile=$3

  echo "Killing broker with pid $brokerpid"
  kill -15 $brokerpid 2>&1 1> /dev/null
  sleep 1
  (kill -9 $brokerpid 2>&1) > /dev/null
  grep BRK-1014 ${QPID_WORK}/log/qpid.log | sed 's/,/ /g' | sed 's/^/# /' >> $resultFile
  mv  ${QPID_WORK}/log/qpid.log  ${QPID_WORK}/log/qpid.log.$messageSize_$messageCount
  rm -fr ${QPID_WORK}/default/messages
}

function performTest()
{
  messageSize=$1
  messageCount=$2
  resultFile=$3
  connections=${4:-1}
  sessions=${5:-1}
  producers=${6:-1}

  startBroker
  awaitBroker
  echo "Running test: messageSize=$messageSize messageNumber=$messageCount connections=${connections} sessions=${sessions}"

  tmp=$(mktemp)
  mvn -f ${TOOLS_DIR}/pom.xml \
       exec:java \
       -Dmemorytest=${PROFILE} \
       -Dexec.args="jndiProperties=${JNDI_PROPERTIES} jmxhost=${BROKER_HOSTNAME} jmxport=${RMI_PORT} jmxuser=guest jmxpassword=guest jndiConnectionFactory=qpidConnectionFactoryTls connections=${connections} sessions=${sessions} producers=${producers} messagecount=${messageCount} size=${messageSize} resultsFile=${tmp}"
  cat ${tmp} >> $resultFile
  stopBroker $messageSize $messageCount $resultFile
}

function performMessageNumberTests()
{
  messageSize=$1
  messageNumbers=$2
  resultFile=$3

  for messageNumber in $messageNumbers
  do
    performTest $messageSize $messageNumber $resultFile 1 1 1
  done
}

function performConnectionsTests()
{
  sessionNumber=${1}
  connectionsNumbers=$2
  resultFile=$3

  for connectionsNumber in $connectionsNumbers
  do
    performTest 0 2 $resultFile ${connectionsNumber} ${sessionNumber} 1
  done
}

if [ -z ${QPID_HOME+x} ]
then
  echo "QPID_HOME environment variable is unset"
  exit 1
else
  echo "QPID_HOME=$QPID_HOME"
fi
if [ -z ${QPID_WORK+x} ]
then
  echo "QPID_WORK environment variable is unset"
  exit 1
else
  echo "QPID_WORK=$QPID_WORK"
fi

echo "QPID_OPTS=$QPID_OPTS"

if [ command -v readlink >/dev/null 2>&1 ]
then
  TOOLS_DIR=$(dirname $(dirname $(readlink -f ${0})))
else
  TOOLS_DIR=$(dirname $(cd "$(dirname "${0}")"; pwd))
fi
echo "Tools module folder ${TOOLS_DIR}"

PROTOCOL=${1:-0-9}
BROKER_HOSTNAME=${2:-"localhost"}
RMI_PORT=${3:-8999}

case ${PROTOCOL} in
0-9|0-10)
  JNDI_PROPERTIES=stress-test-client-qpid-jms-client-0-x.properties
  PROFILE=jms-client-${PROTOCOL}
  ;;
1-0)
  JNDI_PROPERTIES=stress-test-client-qpid-jms-client.properties
  PROFILE=qpid-jms-client
  ;;
*)
  echo "Unrecognised protocol ${PROTOCOL}"
  exit 1
  ;;
esac


brokerVersion=`$QPID_HOME/bin/qpid-server -v | grep "qpid -" | awk '{print $3 " rev" $5}'`
javaVersion=`java -version 2>&1 | grep "java version" | awk '{print $3}' | sed -e "s/\"//g"`
startTime=`date "+%Y-%m-%d %H:%M:%S"`
startTimeFile=`date "+%Y-%m-%d-%H-%M-%S"`
resultFile="${TOOLS_DIR}/target/results-${PROTOCOL}-${javaVersion}-${startTimeFile}.txt"

echo "Results will be written into ${resultFile}"

rm -fr  ${QPID_WORK}/default/messages
mkdir -p ${QPID_WORK}/log

echo "# $startTime" > ${resultFile}
echo "# amqp=${PROTOCOL} java=${javaVersion} broker=${brokerVersion} QPID_OPTS=${QPID_OPTS}" >> ${resultFile}
echo "# heap usage, direct memory usage, connections, sessions, producers, is transacted, messages, message size, delivery mode, user friendly heap usage, user friendly direct memory usage" >> ${resultFile}

performMessageNumberTests 0        "10 50 100 1000 10000 100000 1000000" ${resultFile}
performMessageNumberTests 1024     "10 50 100 1000 10000 100000 1000000" ${resultFile}
performMessageNumberTests 102400   "10 50 100 1000 10000 100000" ${resultFile}
performMessageNumberTests 1048576  "10 50 100 1000 10000" ${resultFile}
performMessageNumberTests 10485760 "10 50 100 1000" ${resultFile}
performMessageNumberTests 32768000 "10 50 100" ${resultFile}

performConnectionsTests 1   "1 100 1000 10000" ${resultFile}
performConnectionsTests 10  "1 100 1000 10000" ${resultFile}
performConnectionsTests 100 "1 100 1000 10000" ${resultFile}
performConnectionsTests 200 "1 100 1000 10000" ${resultFile}

endTime=`date "+%Y-%m-%d %H:%M:%S"`
echo "# $endTime" >> results.txt
