#!/usr/bin/env bash
trap 'killm f' EXIT
#
# Tests that bping produces expected output and behaves well.
#
# documentation boilerplate
CONFIGFILES="${CONFIGSROOT}/loopback-udp/loopback.rc"

echo "########################################"
echo
pwd | sed "s/\/.*\///" | xargs echo "NAME: "
echo
echo "PURPOSE: Testing the basic functionality of the bping application.
    Described in issue 190, bping is a simple ping-like utility which sends
    and receives bundles.  It doesn't strictly follow the standards of
    ICMP echo messages, but performs a similar functionality."
echo
echo "CONFIG: Standard loopback-udp: "
echo
for N in $CONFIGFILES
do
    echo "$N:"
    cat $N
    echo "# EOF"
    echo
done
echo "OUTPUT: Bping and bpecho are used to ensure that bping can send and
    receive bundles, and to ensure that it ignores malformed/unsolicited
    bundles from an unintended application like bptrace.  The time required
    to close the bping program is also tested. ERROR messages are given on
    failure.  No explicit PASS messages are given, but the overall test
    return value will reflect test success."
echo
echo "########################################"

FAIL=0
# set timeouts based on OS type
if [[ $1 == "linux" ]] || [[ $1 == "mac" ]] ; then
    TIMETOWAIT1=4
    TIMETOWAIT2=15
else
    TIMETOWAIT1=5
    TIMETOWAIT2=25
fi

echo "Killing old ION..."
./cleanup
sleep $TIMETOWAIT1

# Prepare for loop start
rm -f ion.log bpingoutput1 bpingoutput2 bpingoutput3 bpingoutput4

echo "Starting ION..."
srcdir=`pwd`
CONFIGDIR="${CONFIGSROOT}/loopback-udp"
echo "ionstart -I ${CONFIGDIR}/loopback.rc"
"ionstart" -I "${CONFIGDIR}/loopback.rc"


echo "Start a bpecho."
bpecho ipn:1.1 & BPECHOPID=$!
sleep $TIMETOWAIT1

echo ""
echo "Verify that bping can ping bpecho loopback..."
bping -c 5 -i 1 -q 0 ipn:1.2 ipn:1.1 > bpingoutput1

if ! grep -q "5 bundles transmitted, 5 bundles received" bpingoutput1; then
    echo "ERROR: Didn't receive expected 5 ping responses:"
    cat bpingoutput1
    FAIL=1
fi

echo ""
echo "Verify that bping doesn't choke on unexpected bundles..."
bping -c 5 -i 1 -q 0 ipn:1.2 ipn:1.1 > bpingoutput2 &
sleep $TIMETOWAIT1
bptrace ipn:1.3 ipn:1.2 dtn:none 60 1.0 "this is a bundle that bping isn't expecting and can't parse"
sleep $TIMETOWAIT1

if grep -q "ipn:1.3" bpingoutput2; then
    echo "ERROR: bping tried to parse the non-ping bundle from ipn:1.3"
    cat bpingoutput2
    FAIL=1
fi

if ! grep -q "5 bundles transmitted, 5 bundles received" bpingoutput2; then
    echo "ERROR: bping didn't ignore the non-ping bundle from ipn:1.3"
    cat bpingoutput2
    FAIL=1
fi

echo ""
echo "Verify that if bping is given SIGINT, it terminates quickly..."
bping -c 2 -i 15 -q 0 ipn:1.2 ipn:1.1 > bpingoutput3 & BPINGPID=$!
sleep $TIMETOWAIT1
SECONDS=0
kill -s SIGINT $BPINGPID
wait $BPINGPID
PINGSECONDS=$SECONDS
if [ $PINGSECONDS -ge 15 ]; then
    echo "ERROR: It took $PINGSECONDS seconds for bping to clean up and exit, too long."
    FAIL=1
fi

echo ""
echo "Verify that bping returns after a timeout if so configured..."
bping -c 3 -i 5 -q 5 ipn:1.2 ipn:1.1 > bpingoutput4 & BPINGPID=$!
sleep $TIMETOWAIT1
kill $BPECHOPID
sleep $TIMETOWAIT2
if ! grep -q "3 bundles transmitted, 1 bundles received" bpingoutput4; then
    echo "ERROR: bping didn't properly terminate after timing out"
    kill $BPINGPID > /dev/null
    cat bpingoutput4
    FAIL=1
fi

echo ""
echo "Terminating node."
killm

exit $FAIL
