#! /bin/bash
#
# $Id: cp_test.sh 480 2015-08-14 15:44:08Z fabien $
#
# pg option tests
#
# usage: $0 <name> <test>

[ $# -eq 2 ] || {
  echo "usage: $0 <name> <test>"
  exit 1
}

name=$1 test=$2

# check for pg binaries
type initdb || exit 1
type pg_ctl || exit 1
type pgbench || exit 1
type psql || exit 1

# for option tests:
checkpoint_flush_to_disk="on off"
checkpoint_sort="on off"

# for head:
#checkpoint_flush_to_disk="skip"
#checkpoint_sort="skip"

# for rerun
#checkpoint_flush_to_disk="off"
#checkpoint_sort="off"

# common
ntests=1
para="-j 2 -c 4"
checkpoint_completion_target=0.8

case $name in
    tiny)
	warmup=
	time=6400
	scale=10
	shared_buffers=1GB
	checkpoint_timeout=30s
	;;
    tiny2)
	warmup=600
	scale=10
	shared_buffers=1GB
	checkpoint_timeout=300s
	time=4000
	max_wal_size=1GB
	;;
    small)
	warmup=1200
	scale=120
	shared_buffers=2GB
	checkpoint_timeout=300s
	time=4000
	#max_wal_size=<default>
	;;
    medium)
	warmup=1200
	scale=250
	shared_buffers=4GB
	checkpoint_timeout=15min
	time=4000
        max_wal_size=4GB
	;;
    medium2)
	warmup=1200
	scale=300
	shared_buffers=4GB
	checkpoint_timeout=30min
	time=7500
        max_wal_size=5GB
	;;
    medium3)
	warmup=1200
	scale=200
	shared_buffers=4GB
	checkpoint_timeout=15min
	time=6000
        max_wal_size=4GB
	synchronous_commit=off
	para='-j 2 -c 6'
	;;
    medium3bis)
	warmup=1200
	scale=200
	shared_buffers=4GB
	checkpoint_timeout=15min
	time=6000
        max_wal_size=4GB
	synchronous_commit=off
	;;
    large)
	warmup=1200
	scale=1000
	shared_buffers=4GB
	checkpoint_timeout=40min
	time=7500
        max_wal_size=2GB
	;;
    *)
	echo "unexpected name: $name" >&2
	exit 1
	;;
esac

# pgbench run
case $test in
    fs)  ## full speed sequential simple update pgbench
	run="FS"
	opts="-M prepared -N -P 1 -T $time"
	;;
    fp)  ## full speed parallel simple update pgbench
	run="FP"
	opts="-M prepared -N -P 1 -T $time $para"
	;;
    t1)  ## 100 tps latency limited simple update pgbench
	run="R100"
	opts="-M prepared -N -P 1 -T $time -R 100 -L 100 $para"
	;;
    t2)  ## 200 tps latency limited simple update pgbench
	run="R200"
	opts="-M prepared -N -P 1 -T $time -R 200 -L 100 $para"
	;;
    t4)  ## 400 tps latency limited simple update pgbench
	run="R400"
	opts="-M prepared -N -P 1 -T $time -R 400 -L 100 $para"
	;;
    t8) ## 800 tps 4-clients latency limited simple update pgbench
	run="R800"
	opts="-M prepared -N -P 1 -T $time -R 800 -L 100 $para"
	;;
    tc) ## 1200 tps 4-clients latency limited simple update pgbench
	run="R1200"
	opts="-M prepared -N -P 1 -T $time -R 1200 -L 100 $para"
	;;
    tg) ## 1600 tps 4-clients latency limited simple update pgbench
	run="R1600"
	opts="-M prepared -N -P 1 -T $time -R 1600 -L 100 $para"
	;;
    *)  ## unexpected test
	echo "unexpected test: $test" >&2
	exit 1
	;;
esac

echo "## starting test $1 on $(date)"

for cs in $checkpoint_sort ; do
for cpftd in $checkpoint_flush_to_disk ; do

    what="${name}_${run}_${cpftd}_${cs}"

    data=./data_${what}
    test -d $data && exit 1

    out=./test_${what}.out
    test -f $out && exit 1

    {
      echo "# TEST $what STARTING"
      echo "# pgbench: $pgbench $opts"
      echo "# data: ${data}"

      # creating $data
      date
      initdb -D $data || exit 2

      {
	echo "## configurations added by $0:"
	echo "log_checkpoints = on"
	echo "log_line_prefix = '%m '"
	[ "$shared_buffers" ] && \
            echo "shared_buffers = $shared_buffers"
	[ "$checkpoint_timeout" ] && \
            echo "checkpoint_timeout = $checkpoint_timeout"
	[ "$checkpoint_completion_target" ] && \
            echo "checkpoint_completion_target = $checkpoint_completion_target"
	[ "$max_wal_size" ] && \
	    echo "max_wal_size = $max_wal_size"
	[ "$synchronous_commit" ] && \
	    echo "synchronous_commit = $synchronous_commit"

	# tested options
	[ "$cpftd" -a "$cpftd" != 'skip' ] && \
            echo "checkpoint_flush_to_disk = $cpftd"
	[ "$cs" -a "$cs" != 'skip' ] && \
	    echo "checkpoint_sort = $cs"

	#echo "log_connections = on"
      } >> $data/postgresql.conf

      # show actual configuration
      egrep -v '^\s*#' $data/postgresql.conf | grep '.'

      # starting and initializing $data
      date
      pg_ctl -D $data -l $data/postgres.log start || exit 3
      # wait...
      sleep 30
      createdb test || exit 4
      ${PGBENCH:-pgbench} -s $scale -i test || exit 5
      sync

      echo "# database whole size:"
      du -sh $data

      # warmup OS & PG
      find $data -type f -print0 | xargs -0 cat > /dev/null
      psql -c 'SELECT AVG(abalance) FROM pgbench_accounts' test > /dev/null
      [ "$warmup" ] && \
	  ${PGBENCH:-pgbench} -M prepared -S -T $warmup $para test \
	      > /dev/null 2>&1
      psql -c 'CHECKPOINT' test > /dev/null

      n=$ntests
      while let n-- ; do
	echo "## $n starting on $(date)"
  	${PGBENCH:-pgbench} $opts test
	echo "## $n done on $(date)"
      done

      # close test
      time psql -c 'CHECKPOINT' test

      # done on $data
      pg_ctl -D $data stop || exit 6

      echo "# database whole size:"
      du -sh $data


      echo "# TEST $what DONE"

      echo
      echo "# log file:"
      cat $data/postgres.log

    } > $out 2>&1

    # cleanup
    echo "# removing $data..."
    time rm -rf $data
    sync

    echo "# sleeping 10 minutes..."
    sleep 600
done
done

echo "## done test $1 on $(date)"
echo "## total time: $SECONDS"
