#!/bin/sh
# PCP QA Test No. 1069
# Exercise pmrep configuration and various reporting modes.
#
# Copyright (c) 2015-2016 Red Hat.
#

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

. ./common.python

$python -c "from pcp import pmapi" >/dev/null 2>&1
[ $? -eq 0 ] || _notrun "python pcp pmapi module not installed"
$python -c "from collections import OrderedDict" >/dev/null 2>&1
[ $? -eq 0 ] || _notrun "python collections OrderedDict module not installed"

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

status=1	# failure is the default!
$sudo rm -rf $tmp $tmp.* $seq.full
trap "cd $here; rm -rf $tmp.*; exit \$status" 0 1 2 3 15

_live_filter()
{
    sed \
	-e "s/[0-9][0-9]:[0-9][0-9]:[0-9][0-9]/HH:MM:SS/g" \
	-e '/timezone/s/ (reporting.*)//' \
    #end
}

#  timezone: :Australia/Melbourne (reporting, current is AEDT-11)
#  this is not deterministic .... ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
_archive_filter()
{
    sed \
	-e '/timezone/s/ (reporting.*)//' \
	-e "s#$here#QAPATH#g" \
    #end
}

log="--archive $here/archives/sample-secs -z"
log2="--archive $here/archives/20130706 -z -O 30m"

# real QA test starts here
echo "== basic live mode reporting"
pmrep -p -s 2 -t 0.25 sample.long.one | _live_filter
pmrep -p -T 2sec -t 1 sample.long.one | _live_filter
pmrep -p -T 2sec -t 0.8 sample.long.one | _live_filter
pmrep -p -T 1sec -t 1 -C sample.long.one sample.colour | _live_filter

echo "== basic duplicate name handling"
pmrep -C -U sample.seconds

echo "== basic archive mode reporting"
pmrep -z -p -s 5 -t 2 -P 2 --archive $here/archives/sample-secs \
	sample.seconds sample.milliseconds

echo "== basic configuration file handling"
echo > $tmp.config <<EOF
[options]
version = 1
source = www.example.com
samples = 1
interval = 1
EOF
pmrep -s 5 -t 2 $log -c $tmp.config sample

echo "== exercise various output options"
pmrep -s 3 -p -u $log2 hinv.machine
pmrep -s 5 -t 2 $log -c $tmp.config -o stdout -p -w 20 sample
echo "---"
pmrep -s 5 -t 2 $log -c $tmp.config -C -x sample | _archive_filter
echo "---"
pmrep -T 7s -t 3 -p $log -c $tmp.config -x sample | _archive_filter
echo "---"
pmrep -s 5 -t 2 $log -c $tmp.config -G -H -U sample
pmrep -s 5 -t 2 $log2 -c $tmp.config -p -l '|' -X "" disk.dev.read disk.dev.write disk.dev.total network.interface.mtu mem.util.free kernel.all.load mem.util.used
pmrep -s 5 -t 2 $log2 -c $tmp.config -p -l '|' -X "Instance name" disk.dev.read disk.dev.write disk.dev.total network.interface.mtu mem.util.free kernel.all.load mem.util.used

echo "== exercise extended header"
pmrep -z -a $here/archives/rep -x -H -U -C -u -I "" | _archive_filter
pmrep -z -a $here/archives/20130706 -x -H -U -C -u -I "" | _archive_filter
pmrep -z -a $here/archives/bug-1044.meta -x -H -U -C -u -I "" | _archive_filter

echo "== invalid command line parameters"
pmrep -s 1 -t 1 -b GB -E 1x mem.util.free
pmrep -s 1 -t 1 -b GB -P 2x mem.util.free
pmrep -s 1 -t 1 -b GB -w 3x mem.util.free

echo "== exercise non-integer options"
pmrep -T 2.5s -t 0.5 -p $log -c $tmp.config -x sample | _archive_filter

echo "== exercise raw counter mode"
pmrep --daemonize -s 5 -t 2 $log -c $tmp.config -r sample
pmsleep 1

echo "== exercise timezone setting"
pmrep -s 5 -t 2 --archive $here/archives/sample-secs -p -x -Z XYZ sample \
| _archive_filter
pmrep -s 5 -t 2 --archive $here/archives/sample-secs -p -x -Z UTC-0 sample \
| _archive_filter
pmrep -s 5 -t 2 --archive $here/archives/sample-secs -p -x -Z No/Such/Zone sample \
| _archive_filter
pmrep -s 5 -t 2 --archive $here/archives/sample-secs -p -x -Z UTC sample \
| _archive_filter
pmrep -s 5 -t 2 --archive $here/archives/sample-secs -p -x -Z UTC-5 sample \
| _archive_filter
pmrep -s 5 -t 2 --archive $here/archives/sample-secs -p -x -Z UTC+5 sample \
| _archive_filter
pmrep -s 5 -t 2 --archive $here/archives/sample-secs -p -x -Z America/New_York sample \
| _archive_filter
pmrep -s 5 -t 2 --archive $here/archives/sample-secs -p -x -Z :Europe/Helsinki sample \
| _archive_filter
pmrep -s 5 -t 2 --archive $here/archives/sample-secs -p -x -Z Asia/Kolkata sample \
| _archive_filter
pmrep -C -x -H -U -z -a $here/archives/numa hinv.machine | _archive_filter
pmrep -C -x -H -U -z -a $here/archives/rep hinv.machine | _archive_filter

echo "== exercise extended CSV output"
pmrep -z -u -H -k -o csv -a $here/archives/bug1057 -I "" | wc -l
pmrep -s 5 -t 2 $log -o csv -k sample 2>&1 | _archive_filter

echo "== exercise CSV and alternate delimiters"
pmrep -s 5 -t 2 $log -c $tmp.config -o csv -p -P 1 sample
pmrep -s 5 -t 2 $log -c $tmp.config -o csv --delimiter '|' sample | \
    tee -a $tmp.out1
echo "== exercise CSV and instance handling"
pmrep -s 5 -t 2 $log2 -c $tmp.config -o csv hinv.map.scsi kernel.all.load
echo "== compare output-to-file versus stdout"
pmrep -s 5 -t 2 $log -c $tmp.config -o csv --delimiter '|' -F $tmp.out2 sample
diff $tmp.out1 $tmp.out2
test $? -eq 0 && echo ok

echo "== exercise repeated headers option"
pmrep -s 5 -t 2 $log -E 2 sample.seconds

echo "== exercise units conversion options"
pmrep -s 5 -t 2 $log2 -w 15 -P 1 -p -b MB mem.util.free mem.util.used
pmrep -s 5 -t 2 $log2 -w 15 -P 2 -p -b GB mem.util.free mem.util.used
pmrep -s 5 -t 2 $log2 -w 15 -P 3 -p -q "count x 10^2" disk.dev.read
pmrep -s 5 -t 2 $log2 -w 15 -P 4 -p -q "count x 10^-2" disk.dev.read
pmrep -s 5 -t 2 $log2 -w 15 -P 5 -p -y sec -u disk.dev.avactive
pmrep -s 5 -t 2 $log2 -w 15 -P 6 -p -y microsec -u disk.dev.avactive
pmrep -s 5 -t 2 $log2 -w 15 -P 7 -p -q "count x 10^6" -r kernel.all.sysfork
pmrep -s 5 -t 2 $log2 -w 15 -P 8 -p -b kB mem.util.free mem.util.used
pmrep -s 5 -t 2 $log2 -w 15 -P 9 -p -b MB/s mem.util.free mem.util.used
pmrep -s 5 -t 2 $log2 -w 15 -P 8 -p mem.util.free,,,kb/s mem.util.used,,,GB/ms
pmrep -s 5 -t 2 -z -a $here/archives/rep -u -p mem.util.used,,,GB/ms network.interface.speed,,,GB/hr

echo "== derived metrics configuration file"
cat > $tmp.derived <<EOF
sample.combo = sample.seconds + (sample.milliseconds / 1000)
EOF
pmrep -s 5 -t 2 $log -e $tmp.derived sample.combo

echo "== derived metrics directly on command line"
combo="sample.combo = sample.seconds + (sample.milliseconds / 1000)"
pmrep -s 5 -t 2 $log -e "$combo" sample.combo

echo "== derived metrics in pmrep.conf"
cat > $tmp.derived-test.conf <<EOF
[derived-test]
iopct = p.i.io_pct
iopct.formula = delta(disk.all.read_bytes) + delta(disk.all.write_bytes) == 0 ? mkconst(0, type="double", semantics="instant") : 100 * (delta(proc.io.read_bytes) + delta(proc.io.write_bytes) - delta(proc.io.cancelled_write_bytes)) / (delta(disk.all.read_bytes) + delta(disk.all.write_bytes))
EOF
pmrep -C -H -U -a $here/archives/proc -c $tmp.derived-test.conf :derived-test
echo "No output expected."

echo "== extended existing sample configuration"
cp $tmp.config $tmp.dconfig
cat >> $tmp.dconfig <<EOF
[global]
combo = sample.combo
EOF
pmrep -s 5 -t 2 $log -e $tmp.derived -c $tmp.dconfig sample

echo "== exercise good config version"
echo '[options]' > $tmp.vconfig
echo 'version = 1' >> $tmp.vconfig
cat $tmp.config >> $tmp.vconfig 
pmrep -s 5 -t 2 $log -c $tmp.vconfig sample
echo "== exercise bad config version"
echo '[options]' > $tmp.vconfig
echo 'version = 99' >> $tmp.vconfig
cat $tmp.config >> $tmp.vconfig
pmrep -s 5 -t 2 $log -c $tmp.vconfig sample

echo "== un/interpolated archive mode reporting"
pmrep -s 5 -t 2 $log2 -p    mem.util.free
pmrep -s 5 -t 2 $log2 -p -u mem.util.free

echo "== un/interpolated archive mode reporting with endtime"
pmrep -t 20 $log2 -p    -T @00:50:00 mem.util.free
pmrep       $log2 -p -u -T @00:50:00 mem.util.free

echo "== time alignment with archive/host"
pmrep -s 5 -t 2 $log2 -p -A 2m mem.util.free
pmrep -s 2 -t 2 -p -A 2s -l X sample.long.one \
| sed -r -e 's,[0-9][0-9]:[0-9][0-9]:[0-9][02468]X,ALIGN_OK_X,g'

echo "== basic string value reporting"
# sets variable named $pcp_version
eval `pmprobe -v pmcd.version | sed -e 's/ 1 /=/g' -e 's/pmcd./pcp_/g'`
pmrep -s 1 pmcd.version | sed -e "s/  *$pcp_version/PCP_VERSION/g"

echo "== divide-by-zero error handling"
pmrep -t .01 -s 1 -e 'fail = sample.long.one / 0' fail

echo "== user-requested instance handling"
pmrep -s 1 -i wrong $log2 disk.dev.read
pmrep -s 1 -i wrong $log2 mem.util.free
pmrep -s 1 -i wrong $log2 disk.dev.read mem.util.free
pmrep -s 1 -i wrong,sda $log2 disk.dev.read
pmrep -s 1 -i wrong,sda,wrong $log2 disk.dev.read
pmrep -s 1 -i '"1 minute",wrong,sda,"5 minute","still,wrong"' $log2 disk.dev.read kernel.all.load
pmrep -s 1 -i '"1 minute",wrong,"5 minute"' $log2 kernel.all.load,,"1 minute",,,16
pmrep -s 1 -i "1 minute" -i wrong -i "5 minute" $log2 kernel.all.load
pmrep -s 1 $log2 disk.dev.read,,sda
pmrep -s 1 $log2 disk.dev.read,,sda,,,16
pmrep -s 1 $log2 disk.dev.read,,"'sda','sdb'"
pmrep -s 1 $log2 disk.dev.read,,"'sda','sdb'",,,16
echo '[test]' > $tmp.iconfig
echo 'instances = wrong' >> $tmp.iconfig
echo 'sysfork = kernel.all.sysfork' >> $tmp.iconfig
echo 'mem.util.free = free,,,,16' >> $tmp.iconfig
# We want: kernel.all.load = load,"'1 minute','5 minute','15 min'",,,16
echo "kernel.all.load = load,\"'1 minute','5 minute','15 min'\",,,16" >> $tmp.iconfig
echo 'disk.dev.read = read,sda,,,16' >> $tmp.iconfig
echo 'disk.dev.write = write,wrong,,,16' >> $tmp.iconfig
pmrep -s 1 $log2 -c $tmp.iconfig :test

echo "=== more instance handling"
cat << EOF > $tmp.iiconfig
[test1] # fails
instances = xxx,yyy,zzz
foo = disk.dev.read
foo.instances = wrong

[test2] # fails
instances = sda,sdc
foo = disk.dev.read
foo.instances = sdx

[test3] # fails
instances = sda
disk.dev.read = sdx,sdy

[test4] # 1: fails, 2,3: works
instances = sda
disk.dev.read = l1,sdx
disk.dev.write = l2
disk.dev.total = l3,

[test5] # works
instances = sdx
foo = disk.dev.read
foo.instances = sda

[test6] # works
instances = sda,sdx
foo = disk.dev.read
foo.instances = sda

[test7] # works
instances = sdx
disk.dev.read = label,'sda,sdx'
EOF
pmrep -s 1 $log2 -c $tmp.iiconfig :test1
pmrep -s 1 $log2 -c $tmp.iiconfig :test2
pmrep -s 1 $log2 -c $tmp.iiconfig :test3
pmrep -s 1 $log2 -c $tmp.iiconfig :test4
pmrep -s 1 $log2 -c $tmp.iiconfig :test5
pmrep -s 1 $log2 -c $tmp.iiconfig :test6
pmrep -s 1 $log2 -c $tmp.iiconfig :test7

echo "== test ignoring and omitting metrics"
pmrep -C $log2 -u -U -q MB    mem.util
pmrep -C $log2 -u -U -q MB -I mem.util
pmrep -C $log2 -u    -i sda mem.util.free disk.dev mem.util
pmrep -C $log2 -u -v -i sda mem.util.free disk.dev mem.util

echo "== exercise option priority"
echo '[options]' > $tmp.pconfig
echo 'header = yes' >> $tmp.pconfig
echo 'unitinfo = no' >> $tmp.pconfig
echo 'interval = 2s' >> $tmp.pconfig
pmrep -s 5 $log2 -p mem.util.free
echo "---"
pmrep -s 5 $log2 -p -c $tmp.pconfig mem.util.free
echo "---"
pmrep -s 5 $log2 -t 3s -p -H -c $tmp.pconfig mem.util.free
echo "---"
echo '[options]' > $tmp.pconfig
echo "source = $here/archives/no-such-archive" >> $tmp.pconfig
echo '[source]' >> $tmp.pconfig
echo "source = $here/archives/rep" >> $tmp.pconfig
echo 'kernel.all.uptime = uptime,,,,8' >> $tmp.pconfig
pmrep -s 5 -c $tmp.pconfig -z -p -u :source
echo "---"
echo '[source]' > $tmp.pconfig
echo 'source = wrong.example.com' >> $tmp.pconfig
echo 'kernel.all.uptime = uptime,,,,8' >> $tmp.pconfig
pmrep -s 5 $log2 -c $tmp.pconfig -p -u :source
echo "---"
echo '[source]' > $tmp.pconfig
echo 'source = @' >> $tmp.pconfig
echo "speclocal = clear|add,29,sample/pmda_sample.$DSO_SUFFIX,sample_init" >> $tmp.pconfig
echo 'sample.long.one = one,,,,8' >> $tmp.pconfig
pmrep -s 1 -c $tmp.pconfig -p -u :source | _live_filter
echo "---"
echo '[source]' > $tmp.pconfig
echo 'source = @' >> $tmp.pconfig
echo 'speclocal = fail' >> $tmp.pconfig
echo 'sample.long.one = one,,,,8' >> $tmp.pconfig
pmrep -s 1 -K clear -K add,29,sample/pmda_sample.$DSO_SUFFIX,sample_init -c $tmp.pconfig -p -u :source | _live_filter

# success, all done
echo "== done"
status=0
exit
