#!/bin/sh
# PCP QA Test No. 370
#
# exercise sar2pcp
#
# Copyright (c) 2012 Red Hat.
# Copyright (c) 2010 Ken McDonell.  All Rights Reserved.
#

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

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

which sar >/dev/null 2>&1 || _notrun "sar not installed"
which sadf >/dev/null 2>&1 || _notrun "sadf not installed"
which sar2pcp >/dev/null 2>&1 || _notrun "sar2pcp not installed"

platform=`uname -m`
[ $platform = "x86_64" ] || _notrun "No qualified input data for $platform platform"

version=`sar -V 2>&1 | sed -n -e '/sysstat version /{
s/.* //
p
}'`

_fuzzy()
{
    case "$version"
    in
	11.1.5)
	    sed \
		-e '/kernel.all.cpu.sys/s/0.001[78]/0.0017 or 0.0018/' \
		-e '/diskdev8-2/s/0.3[78]/0.37 or 0.38/' \
	    # end
	    ;;
	12.0.6)
	    sed \
		-e '/^19:14:42 129060.79687500/s/129060.79687500/129061/' \
	    # end
	    ;;
	*)	# no fuzziness required
	    cat
	    ;;
    esac
}

rm -f $seq.out
file_version=$version
case "$version"
in
    9.0.4*)	# RHEL6
	eval `pmprobe -v kernel.uname.distro | sed -e 's/.*distro 1 /distro=/g'`
	case "$distro"
	in
	    Red*Hat*6.*|CentOS*6.*)
		# special case for systat in RHEL >=6.5 (see --legacy
		# note in sar(1) on these systems for the way the sar
		# data format and versioning was broken).
		#
		minor=`echo $distro | sed -e 's/.*release 6.//g' -e 's/ .*//g'`
		if [ $minor -ge 5 ]; then
		    unxz < $seq.out.8.xz > $seq.out || exit 1
		    file_version=9.0.4_rh6.5
		else
		    unxz < $seq.out.4.xz > $seq.out || exit 1
		    file_version=9.0.4
		fi
		;;
	    *)
		unxz < $seq.out.4.xz > $seq.out || exit 1
		file_version=9.0.4
		;;
	esac
	;;
    9.0.6.1)
	unxz < $seq.out.5.xz > $seq.out || exit 1
	;;
    9.0.6*)
	unxz < $seq.out.1.xz > $seq.out || exit 1
	file_version=9.0.6
	;;
    9.1.7*)
	unxz < $seq.out.2.xz > $seq.out || exit 1
	file_version=9.1.7
	;;
    10.0.1*)
	unxz < $seq.out.3.xz > $seq.out || exit 1
	file_version=10.0.1
	;;
    10.0.5*)
	unxz < $seq.out.6.xz > $seq.out || exit 1
	file_version=10.0.5
	;;
    10.1.5)
	unxz < $seq.out.12.xz > $seq.out || exit 1
	;;
    10.1.6)
	unxz < $seq.out.11.xz > $seq.out || exit 1
	;;
    10.2.0|10.2.1)
	unxz < $seq.out.7.xz > $seq.out || exit 1
	file_version=10.2.0
	;;
    11.0.0|11.0.1)
	unxz < $seq.out.9.xz > $seq.out || exit 1
	file_version=11.0.1
	;;
    11.1.5)
	unxz < $seq.out.10.xz > $seq.out || exit 1
	;;
    11.2.0)
	unxz < $seq.out.13.xz > $seq.out || exit 1
	;;
    11.5.7)
	unxz < $seq.out.14.xz > $seq.out || exit 1
	;;
    12.0.6)
	unxz < $seq.out.15.xz > $seq.out || exit 1
	file_version=12.0.6
	;;
    *)
	_notrun "no qualified output for sysstat version $version"
	;;
esac
[ -f sadist/sa-sysstat-$file_version.xz ] || \
    _notrun "no data file (sa-sysstat-$file_version.xz) for sysstat version $version"

status=0	# success is the default!
trap "rm -f $tmp.*; exit \$status" 0 1 2 3 15

# real QA test starts here
$sudo rm -f sadist/sa-sysstat-$file_version
unxz < sadist/sa-sysstat-$file_version.xz > sadist/sa-sysstat-$file_version

# For this test, don't load any global derived metric configs by default. 
# So the PCP_DERIVED_CONFIG environment variable is initially set to an
# empty string, except below where PCP_DERIVED_CONFIG is used for sar's -u view
export PCP_DERIVED_CONFIG=""

echo "Using sa-sysstat-$file_version" >>$seq_full

sar2pcp sadist/sa-sysstat-$file_version $tmp

# version 9.x output
# 11:07:39        CPU     %user     %nice   %system   %iowait    %steal     %idle
# 11:07:44        all      3.20      0.10      1.60      0.00      0.00     95.10
#
# version 10.x output
# 04:50:52 PM     CPU     %user     %nice   %system   %iowait    %steal     %idle
# 04:50:57 PM     all      0.31      0.00      0.31      0.00      0.00     99.38
#
sar $sar_opt -f sadist/sa-sysstat-$file_version -u \
| tee -a $seq_full \
| sed -n '/^[0-2][0-9]:/{
s/^01\(:..:..\) PM/13\1/
s/^02\(:..:..\) PM/14\1/
s/^03\(:..:..\) PM/15\1/
s/^04\(:..:..\) PM/16\1/
s/^05\(:..:..\) PM/17\1/
s/^06\(:..:..\) PM/18\1/
s/^07\(:..:..\) PM/19\1/
s/^08\(:..:..\) PM/20\1/
s/^09\(:..:..\) PM/21\1/
s/^10\(:..:..\) PM/22\1/
s/^11\(:..:..\) PM/23\1/
s/^12\(:..:..\) AM/00\1/
s/^\(..:..:..\) AM/\1/
p
}' \
| $PCP_AWK_PROG >$tmp.sar '
NR == 1		{ next }
		# percent to utilization
		{ for (i = 2; i <= NF; i++) { $i = $i / 100 }
		  print
		}'

echo "check user CPU time ..."
# note sar's -u view of user is really usr+guest
# ... saved by derived metrics!
# also need to relax tolerance in comparison, 'cause sar seems to get
# the arithmetic "not quite right" (tm)
echo "user = kernel.all.cpu.user + kernel.all.cpu.guest" >$tmp.config
export PCP_DERIVED_CONFIG=$tmp.config
pmval -f 8 -t 5 -a $tmp user \
| sed -n '/^[0-2][0-9]:/{
s/\.[0-9][0-9]*[0-9]//
p
}' >$tmp.pcp
( echo ""; echo "user = kernel.all.cpu.user + kernel.all.cpu.guest" ) >>$seq_full
cat $tmp.pcp >>$seq_full
paste $tmp.sar $tmp.pcp >$tmp.both
$PCP_AWK_PROG <$tmp.both '
{ if ($3-$NF > 0.001 || $3-$NF < -0.001) print "[",NR,"] mismatch:",$1,$3,$NF }'

echo
echo "check timestamps ..."
$PCP_AWK_PROG <$tmp.both '
$1 != $9	{ print "[",NR,"] mismatch:",$0 }'

echo
echo "check sys CPU time ..."
# note sar's -u view of system is really sys+intr
# ... saved by derived metrics!
# also need to relax tolerance in comparison, 'cause sar seems to get
# the arithmetic "not quite right" (tm)
echo "system = kernel.all.cpu.sys + kernel.all.cpu.intr" >$tmp.config
export PCP_DERIVED_CONFIG=$tmp.config
pmval -f 8 -t 5 -a $tmp system \
| sed -n '/^[0-2][0-9]:/{
s/\.[0-9][0-9][0-9]//
p
}' >$tmp.pcp
( echo ""; echo "system = kernel.all.cpu.sys + kernel.all.cpu.intr" ) >>$seq_full
cat $tmp.pcp >>$seq_full
paste $tmp.sar $tmp.pcp >$tmp.both
$PCP_AWK_PROG <$tmp.both '
{ if ($5-$NF > 0.001 || $5-$NF < -0.001) print "[",NR,"] mismatch:",$1,$5,$NF }'

echo >>$seq_full
# version 9.x output
# 11:07:39          tps      rtps      wtps   bread/s   bwrtn/s
# 11:07:44         0.00      0.00      0.00      0.00      0.00
#
# version 10.x output
# 04:50:52 PM       tps      rtps      wtps   bread/s   bwrtn/s
# 04:50:57 PM      0.80      0.00      0.80      0.00      6.40
#
sar -f sadist/sa-sysstat-$file_version -b \
| tee -a $seq_full \
| sed -n '/^[0-2][0-9]:/{
s/^00\(:..:..\) PM/12\1/
s/^01\(:..:..\) PM/13\1/
s/^02\(:..:..\) PM/14\1/
s/^03\(:..:..\) PM/15\1/
s/^04\(:..:..\) PM/16\1/
s/^05\(:..:..\) PM/17\1/
s/^06\(:..:..\) PM/18\1/
s/^07\(:..:..\) PM/19\1/
s/^08\(:..:..\) PM/20\1/
s/^09\(:..:..\) PM/21\1/
s/^10\(:..:..\) PM/22\1/
s/^11\(:..:..\) PM/23\1/
s/^\(..:..:..\) AM/\1/
p
}' \
| $PCP_AWK_PROG >$tmp.sar '
NR == 1		{ next }
		# blocks to Kbytes
		{ for (i = 5; i <= NF; i++) { $i = $i /2 }
		  print
		}'
rm -f sadist/sa-sysstat-$file_version

echo
echo "check disk iops ..."
# units are iops, so within 0.01 iop is ok
pmval -f 8 -t 5 -a $tmp disk.all.total \
| sed -n '/^[0-2][0-9]:/{
s/\.[0-9][0-9][0-9]//
p
}' >$tmp.pcp
( echo ""; echo "disk.all.total" ) >>$seq_full
cat $tmp.pcp >>$seq_full
paste $tmp.sar $tmp.pcp >$tmp.both
$PCP_AWK_PROG <$tmp.both '
{ if ($2-$NF > 0.02 || $2-$NF < -0.02) print "[",NR,"] mismatch:",$1,$2,$NF }'

echo
echo "check disk write thruput ..."
# units are iops, so within 0.01 iop is ok
pmval -f 8 -w 16 -t 5 -a $tmp disk.all.write_bytes \
| sed -n '/^[0-2][0-9]:/{
s/\.[0-9][0-9][0-9]//
p
}' \
| _fuzzy >$tmp.pcp
( echo ""; echo "disk.all.write_bytes" ) >>$seq_full
cat $tmp.pcp >>$seq_full
paste $tmp.sar $tmp.pcp >$tmp.both
$PCP_AWK_PROG <$tmp.both '
{ if ($6-$NF > 0.02 || $6-$NF < -0.02) print "[",NR,"] mismatch:",$1,$6,$NF }'

echo
echo "full dump ..."
# note proc.nprocs -> proc.nproc mapping needed after sar2pcp changes in
# commit 48e373f0609a0a0804bc052d5e9dec41a5a2928e so output matches 370's
# "out" files
# note also that when V3 archives become the norm, we have to "fake"
# the pmdumplog output to look like V2, 'cause that's what is in the
# historical *.out.* files
#
pmdumplog -lm -z $tmp 2>&1 \
| sed \
	-e 's/245\.0\.[0-9][0-9]*/245.0.NN/g' \
	-e 's/(proc.nprocs)/(proc.nproc)/' \
	-e '/Log Label/s/ 3)/ 2)/' \
	-e '/commencing/s/\.000000000 /.000000 /' \
	-e '/ending/s/\.000000000 /.000000 /' \
	-e '/ metrics$/s/\.000000000 /.000000 /' \
| _fuzzy

# success, all done
exit
