#!/bin/sh
# PCP QA Test No. 983
# pmie via proxies
#
# Copyright (c) 2015 Red Hat
#

seq=`basename $0`
echo "QA output created by $seq"

# get standard environment, filters and checks
. ./common.product
. ./common.filter
. ./common.check

which socat >/dev/null 2>&1 || _notrun "socat binary not installed"

port2=55432 # just some random port
port1=55431 # just some random port
$PCP_BINADM_DIR/telnet-probe -c localhost $port1 \
    && _notrun "Someone already listening on IPv4 port $port1"
$PCP_BINADM_DIR/telnet-probe -c localhost $port2 \
    && _notrun "Someone already listening on IPv4 port $port2"
$PCP_BINADM_DIR/telnet-probe -c '::1' $port1 \
    && _notrun "Someone already listening on IPv6 port $port1"
$PCP_BINADM_DIR/telnet-probe -c '::1' $port2 \
    && _notrun "Someone already listening on IPv6 port $port2"
# (technically, this is a TOCTTOU race condition)

status=1	# failure is the default!

signal=$PCP_BINADM_DIR/pmsignal

_cleanup()
{
    [ -z "$pmcd_pid" ] || $sudo $signal $pmcd_pid
    [ -z "$socat_pid" ] || $sudo $signal $socat_pid
    export PMCD_PORT=$port1
    _wait_pmcd_end
    unset PMCD_PORT
    _service pmcd restart 2>&1 | _filter_pcp_restart \
    | sed -e '/Waiting for pmcd to terminate/d'
    _wait_for_pmcd
    _restore_auto_restart pmcd
    _service pmlogger restart 2>&1 | _filter_pcp_restart
    _wait_for_pmlogger
    $sudo rm -rf $tmp $tmp.*
}
trap "_cleanup; exit \$status" 0 1 2 3 15
_stop_auto_restart pmcd

mkdir $tmp

# ditch timestamps and exact hostnames 
_filter_pmie()
{
    hostname=`hostname`
    _filter_pmie_log |
        sed -e 's/^\[.*\]/[TIMESTAMP]/' |
        sed -e 's/'$hostname'/HOSTNAME/'
}

# real QA test starts here

# We use socat to create a loopback proxy for pmcd on some oddball
# port, and have pmie be forced to talk to it there.  The idea is that
# if pmie were to still use the host-name as a pmNewContext attempt,
# it will fail (since there won't be a pmcd there).

# see also qa/283 for "pmcd -p" testing.
if ! _service pmcd stop >/dev/null 2>&1; then _exit 1; fi
# wait for cleanup and closing all sockets
_wait_pmcd_end || _exit 1


echo "=== starting pmcd on port $port1 ===" |tee -a $seq_full
cat >$tmp.sh <<END
#!/bin/sh
cd $tmp
PATH=$PATH
$PCP_PMCD_PROG -f -l $tmp.log -p $port1 &
echo \$!
END

# Filter the stderr of this using a temp file
pmcd_pid=`$sudo sh $tmp.sh 2>$tmp.tmp`
cat $tmp.tmp 1>&2
export PMCD_PORT=$port1
_wait_for_pmcd || _exit 1
unset PMCD_PORT

echo "=== starting socat on port $port2 ===" |tee -a $seq_full

# Filter the stderr of this using a temp file
socat -d -d TCP-LISTEN:$port2,fork TCP:localhost:$port1 2>>$tmp.err &
socat_pid=$!
rm -f $tmp.socat
i=0
while [ ! -f $tmp.socat -a $i -lt 10 ]
do
    sleep 2
    if $PCP_BINADM_DIR/telnet-probe -cv localhost $port1 2>>$seq_full
    then
	touch $tmp.socat
    else
	i=`expr $i + 1`
    fi
done
cat $tmp.err >>$seq_full
if [ ! -f $tmp.socat ]
then
    echo "Failed to get socat started ... see $seq.full"
    exit
fi

cat >$tmp.pmie <<END
delta = 1sec;
(sample.load > 40) -> print "found the meaning of %h %c %v";
END


for port in $port2 $port1 44321  # the latter will fail
do
    echo "=== running pmie via $port ===" |tee -a $seq_full
    pmie -f -h localhost:$port -c $tmp.pmie -T 5s > $tmp.out 2>&1
    cat $tmp.out >> $seq_full
    # Especially on slow VMs (like bozo-vm) we may need to dodge warnings
    # from pmie's rule scheduler around pmcd reconnection ... the final
    # awk script does this.
    #
    cat $tmp.out \
    | _filter_pmie \
    | $PCP_AWK_PROG '
skip == 1 && /^[^ ]/		{ skip = 0 }
/^run: schedule eval/		{ skip = 1 }
/^sleepTight: negative/		{ skip = 1 }
/^Last sleepTight until:/	{ skip = 1 }
/^This sleepTight\() entry:/	{ skip = 1 }
/^Harvest children done:/	{ skip = 1 }
/^Want sleepTight until:/	{ skip = 1 }
/Task dump @/			{ skip = 1 }
skip == 0			{ print }'

    #(echo f $tmp.pmie; echo l; echo r 5s) | pmie -d -f -h localhost:$port | _filter_pmie
done


# collect misc.
echo "pmie log" >> $seq_full
cat $tmp.log >> $seq_full
echo "socat log" >> $seq_full
cat $tmp.socat >> $seq_full

# success, all done
status=0
exit
