#!/bin/sh
# PCP QA Test No. 1600
# Exercise log discovery, pmproxy and pmseries.
#
# Copyright (c) 2018-2020 Red Hat.
#

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

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

_check_series

_cleanup()
{
    [ -n "$pmproxy_pid" ] && $signal -s TERM $pmproxy_pid
    [ -n "$options" ] && redis-cli $options shutdown
    cd $here
    if $need_restore
    then
	need_restore=false
	$sudo rm -rf $PCP_SYSCONF_DIR/pcp/labels/*
	_restore_config $PCP_SYSCONF_DIR/labels
        _restore_config $PCP_SYSCONF_DIR/pmproxy
        _restore_config $PCP_SYSCONF_DIR/pmseries
	[ -d $PCP_TMP_DIR/mmv.$seq ] && _restore_config $PCP_TMP_DIR/mmv
	_sighup_pmcd
    fi
    $sudo rm -rf $tmp $tmp.*
}

status=1	# failure is the default!
signal=$PCP_BINADM_DIR/pmsignal

userid=`id -u`
groupid=`id -g`
username=`id -u -n`
hostname=`hostname`
machineid=`_machine_id`
domainname=`_domain_name`

need_restore=false
$sudo rm -rf $tmp $tmp.* $seq.full
trap "_cleanup; exit \$status" 0 1 2 3 15

_filter_series()
{
    sed \
	-e 's/[0-9a-z]\{40\}/TIMESERIES/g' \
    #end
}

_filter_labels()
{
    sed \
	-e "s/.domainname.:.${domainname}./\"domainname\":\"DOMAIN\"/g" \
	-e "s/.machineid.:.${machineid}./\"machineid\":\"MACHINE\"/g" \
	-e "s/.hostname.:.${hostname}./\"hostname\":\"HOST\"/g" \
	-e "s/.groupid.:$groupid/\"groupid\":GID/g" \
	-e "s/.userid.:$userid/\"userid\":UID/g" \
    #end
}

# not only dodge the timestamp and value, but the number of
#    [TIMESTAMP] VALUE
# lines may be 1 or 2
#
_filter_values()
{
    sed \
	-e 's/\[[0-9][0-9]*\.[0-9][0-9]*\]/[TIMESTAMP]/g' \
	-e 's/ [0-9][0-9]*$/ VALUE/g' \
    | $PCP_AWK_PROG '
BEGIN		{ n = 0 }
$2 == "VALUE"	{ n++
		  if (n > 2) {
		      print "Unexpected extra line:",$0
		  }
		  else {
		      if (n == 1) print
		      next
		  }
		}
		{ print }'
}

_filter_label_values()
{
    sed \
	-e "s/^domainname: \"${domainname}\"/domainname: \"DOMAIN\"/g" \
	-e "s/^machineid: \"${machineid}\"/machineid: \"MACHINE\"/g" \
	-e "s/^hostname: \"${hostname}\"/hostname: \"HOSTNAME\"/g" \
	-e "s/^groupid: $groupid/groupid: GID/g" \
	-e "s/^userid: $userid/userid: UID/g" \
	-e "s/transient: false, true/transient: false/g" \
	-e "s/changed: false, true/changed: false/g" \
	-e "/metric_label: null/d" \
    #end
}

# sort the values in this line
#	agent: "mmv", "sample", "pmcd"
#
_filter_agents()
{
    LC_COLLATE=POSIX $PCP_AWK_PROG '
$1 == "agent:"	{ printf "%s ",$1
		  for (i = 2; i <= NF; i++) {
		      small = -1
		      for (j = 2; j <= NF; j++) {
			if ($j == "")
			    continue
			if (small == -1 || $j < $small)
			    small = j
		      }
		      if (i > 2)
			printf ", "
		      gsub(/,/, "", $small)
		      printf "%s",$small
		      $small = ""
		   }
		   printf "\n"
		   next
		}
		{ print }'
}

# real QA test starts here
_save_config $PCP_SYSCONF_DIR/labels
_save_config $PCP_SYSCONF_DIR/pmproxy
_save_config $PCP_SYSCONF_DIR/pmseries
[ -d $PCP_TMP_DIR/mmv ] && _save_config $PCP_TMP_DIR/mmv
$sudo rm -f $PCP_SYSCONF_DIR/pmseries/*
$sudo rm -f $PCP_SYSCONF_DIR/pmproxy/*
$sudo rm -rf $PCP_SYSCONF_DIR/labels/*
$sudo rm -f $PCP_TMP_DIR/mmv/*
need_restore=true
echo '{"latitude": -25.28496, "longitude": 152.87886}' > $tmp.labels
$sudo cp $tmp.labels $PCP_SYSCONF_DIR/labels/pcpqa.location
_sighup_pmcd

echo "Start test Redis server ..."
redisport=`_find_free_port`
redis-server --port $redisport --save "" > $tmp.redis 2>&1 &
echo "PING"
pmsleep 0.125
options="-p $redisport"
redis-cli $options ping
_check_redis_server $redisport
echo

_check_redis_server_version $redisport

# prepare logging location and config
export PCP_ARCHIVE_DIR=$tmp.log/pmlogger
mkdir -p $PCP_ARCHIVE_DIR

cat >$tmp.pmlogger.conf << End-Of-File
log mandatory on default {
    mmv
    pmcd
    sample.long
    sample.ulong
    sample.double
    sample.rapid
    sample.colour
    sample.mirage
    sample.needprofile
}
End-Of-File
cat >$tmp.pmproxy.conf << End-Of-File
[discover]
enabled = true
[pmseries]
enabled = true
End-Of-File

# start long-running pmlogger actively writing archives
pmlogger -t 0.25 -T 3sec -c $tmp.pmlogger.conf -l $tmp.pmlogger.log $PCP_ARCHIVE_DIR/archive &
pmlogger_pid=$!
#echo pmlogger=$pmlogger_pid
_wait_for_pmlogger $pmlogger_pid $tmp.pmlogger.log
pmsleep 0.5	# time for pmlogger to start logging

# start pmproxy 
proxyport=`_find_free_port`
proxyopts="-f -A -p $proxyport -r $redisport -U $username"
#proxyopts="$pmproxyopts -Dseries,discovery"
pmproxy -c $tmp.pmproxy.conf -x $seq.full -l $tmp.pmproxy.log $proxyopts &
pmproxy_pid=$!
#echo pmproxy=$pmproxy_pid

# check pmproxy has started and is discovering timeseries
pmcd_wait -h localhost@localhost:$proxyport -v -t 5sec
pmsleep 0.5	# time for pmproxy to start discovering

$PCP_PS_PROG $PCP_PS_ALL_FLAGS | egrep 'pmlogger|pmproxy|redis' >> $seq.full
redis-cli $options keys pcp:* >> $seq.full
ls -lR $PCP_ARCHIVE_DIR >> $seq.full
cat $tmp.pmproxy.log >> $seq.full

#echo "pausing for diagnosis ($options ... $PCP_ARCHIVE_DIR)"
#echo pmlogger:
#cat $tmp.pmlogger.log
#echo pmproxy:
#cat $tmp.pmproxy.log
#read

#
# verify we have data loading and can issue various queries
#
echo "== verify metric names" | tee -a $seq.full
pmseries $options sample.double.bin* | _filter_series

echo "== verify metric descs" | tee -a $seq.full
series=`pmseries $options sample.long.ten`
[ -z "$series" ] && _fail "Cannot find any timeseries matching sample.long.ten"
pmseries $options -d $series | _filter_series

echo "== verify metric insts" | tee -a $seq.full
series=`pmseries $options sample.ulong.bin`
[ -z "$series" ] && _fail "Cannot find any timeseries matching sample.ulong.bin"
pmseries $options -i $series | _filter_series

echo "== verify metric labels" | tee -a $seq.full
series=`pmseries $options sample.double.bin`
[ -z "$series" ] && _fail "Cannot find any timeseries matching sample.double.bin"
pmseries $options -l $series | _filter_labels | _filter_series

echo "== verify metric values" | tee -a  $seq.full
pmsleep 0.5
pmseries $options -t sample.ulong.million[samples:2] \
| tee -a $seq.full \
| _filter_values \
| _filter_series

echo "== verify label names and values" | tee -a  $seq.full
labels=`pmseries $options -l | LC_COLLATE=POSIX sort`
pmseries $options -v $labels | _filter_label_values | _filter_agents

# pause until pmlogger exits to prevent confusion when removing archives
wait $pmlogger_pid

#
# verify discovery handling of archive deletion
#
echo "== verify archive removal" | tee -a  $seq.full
rm -fr $PCP_ARCHIVE_DIR
pmsleep 0.5	# allow filesystem event some time to arrive
pmcd_wait -h localhost@localhost:$proxyport -v -t 1sec	# pmproxy still up?

echo "== log " >> $seq.full
cat $tmp.pmproxy.log >> $seq.full

echo "== all done" | tee -a $seq.full

# success, all done
status=0
exit
