#!/bin/bash
#
# Copyright (c) 2009, Regents of the University of Colorado.
#
# Written by Andrew Jenkins, based on loopbacktest.sh by David Young
#
CONFIGFILES=" \
${CONFIGSROOT}/loopback-ltp/loopback.ionrc \
${CONFIGSROOT}/loopback-ltp/loopback.ltprc \
${CONFIGSROOT}/loopback-ltp/loopback.bprc \
${CONFIGSROOT}/loopback-ltp/loopback.ionsecrc \
${CONFIGSROOT}/loopback-ltp/loopback.ipnrc \
"
echo "########################################"
echo
pwd | sed "s/\/.*\///" | xargs echo "NAME: "
echo
echo "PURPOSE: Tests a simple ltp loopback configuration sending multiple
	bundles to itself.  By default, this runs for 100 iterations.
	The test was originally meant to test for an ION memory leak (with
	thousands of iterations)."
echo
echo "CONFIG: Standard loopback-ltp: "
echo
for N in $CONFIGFILES
do
	echo "$N:"
	cat $N
	echo "# EOF"
	echo
done
echo "OUTPUT: Terminal messages will relay results."
echo
echo "########################################"

# like loopbacktest.sh, but loopbacks bundles over and over a specified 
# number of times (first argument; default 100).  Fails the first time
# a bundle fails.
# Assumes the current working directory contains the built programs of ion.

if [ -z $1 ]; then
    ITERATIONGOAL=100
else
    ITERATIONGOAL=$1
fi

# Guess what ION will say if a bundle containing $1 is received.
predictreceived () {
    echo "ION event: Payload delivered."
    echo "	payload length is ${#1}."
    echo "	'${1}'"
}

# Try 10 times to see if the bundle has been received.
tryreceive () {
    X=0

    while [ $X -lt 200 ]
    do
        # sleep and kill process in case it didn't end properly
        sleep 0.04 

        # Check if bpsink got the file.
        if ! cmp $IONRECEIVEFILE $IONEXPECTEDFILE >/dev/null 2>/dev/null
        then
            X=`expr $X + 1`
        else
            # We received it.  Hooray.
            return 0
        fi
    done
    # We didn't receive it, even after 10 tries; bummer.
    diff $IONRECEIVEFILE $IONEXPECTEDFILE
    return 1
}


# message sent over ion
IONMESSAGE="iontestmessage"
IONSENDFILE=./ionsendfile.txt
IONRECEIVEFILE=./ionreceivefile.txt
IONEXPECTEDFILE=./ionexpectedfile.txt

echo "Killing old ION..."
killm
sleep 1

# Prepare for loop start
rm -f $IONSENDFILE $IONRECEIVEFILE $IONEXPECTEDFILE ion.log
PASS=1
ITERATION=1

echo "Starting ION..."
srcdir=`pwd`
CONFIGDIR="${CONFIGSROOT}/loopback-ltp"
echo "ionstart -i ${CONFIGDIR}/loopback.ionrc -l ${CONFIGDIR}/loopback.ltprc -b ${CONFIGDIR}/loopback.bprc -p ${CONFIGDIR}/loopback.ipnrc -s ${CONFIGDIR}/loopback.ionsecrc"
"ionstart" -i "${CONFIGDIR}/loopback.ionrc" -l "${CONFIGDIR}/loopback.ltprc" -b "${CONFIGDIR}/loopback.bprc" -p "${CONFIGDIR}/loopback.ipnrc" -s "${CONFIGDIR}/loopback.ionsecrc"

# Start the listener that will receive all the bundles.
echo "Starting Message Listener..."
bpsink ipn:1.1 > $IONRECEIVEFILE &
BPSINKPID=$!

# give bpsink some time to start up
sleep 5

while [ ${PASS} -eq 1 ] && [ ! $ITERATION -gt $ITERATIONGOAL ]
do
    IONMESSAGE=$( date )
    
    # create the test message in a sent file
    # the exclamation point signals the bundle sender to quit
    echo "$IONMESSAGE" > $IONSENDFILE
    echo "!" >> $IONSENDFILE

    # send the message in the file via test bundle source
    bpsource ipn:1.1 < $IONSENDFILE 1>/dev/null 2>/dev/null 

    # Predict what should come out the other end.
    predictreceived "$IONMESSAGE" >> $IONEXPECTEDFILE

    if tryreceive 
    then
        echo -n "."
        if [ `expr $ITERATION % 80` -eq 0 ]
        then
            echo $ITERATION
        fi
        ITERATION=`expr $ITERATION + 1`
    else
        PASS=0
        echo "FAILED on ITERATION $ITERATION at `date`."
    fi
done

echo

# bpsink does not self-terminate, so send it SIGINT
echo "Stopping bpsink"
kill -2 $BPSINKPID >/dev/null 2>&1
sleep 1
kill -9 $BPSINKPID >/dev/null 2>&1

# shut down ion processes
echo "Stopping ion..."
ionstop

if [ $ITERATION -eq `expr $ITERATIONGOAL + 1` ]
then
    echo Completed `expr $ITERATION - 1` iterations successfully
    exit 0
else
    exit 1
fi
