#!/bin/bash

# This script runs a simple direct I/O dd in the specified directory and reports
# the results.
#
# Return value:
#	1	If mean throughput is less than 25MB/s or varies by more than 30%.
#	0	Otherwise.


ME=$(basename $0);

source //etc/common-utils.rc


function usage()
{
    usage_banner;
    echo -e "\nUsage: $0 <EBS mountpoint>"
}


function run_dd()
{
    file=$1
    bs=$2
    count=$3

    throughput=$(dd if=/dev/zero of=$file bs=$bs count=$count oflag=direct 2>&1 | grep "copied" | cut -f3 -d,|awk '{print $1}')

    echo $throughput
}


function perftest()
{
    dir=$1
    ntests=30
    bs=1M
    count=128

    MEAN_LIMIT=25
    VARIATION_LIMIT=30

    results=""
    for i in $(seq 1 $ntests); do
    	file=$1/gluster-ami-perftest.$RANDOM

     	if [ -f $file ]; then
     	    rm -f $file
     	fi

    	results="$results $(run_dd $file $bs $count)"
	rm -f $file
    done

    mean=$(echo "scale=1; ($(echo $results|sed 's/ / + /g')) / $ntests" | bc -ql)
    sum_diffs=$(echo $results|sed "s/\([0-9]\+\.\?[0-9]*\)/($mean - \1)^2/g"|sed "s/2 (/2 + (/g" | bc -ql)
    stdev=$(echo "scale=1; sqrt($sum_diffs/$ntests)" | bc -ql)
    cv=$(echo "scale=2; $stdev/$mean" | bc -ql)

    rounded_mean=$(echo "scale=0; $mean/1"|bc -ql)
    rounded_cv=$(echo "scale=0; ($cv*100)/1"|bc -ql)

    cat >&2 <<EOF
------------------------------------
EBS dd direct I/O write test result
Mountpoint: $dir
Block size=$bs, count=$count
Iterations: $ntests
------------------------------------

Mean = $mean MB/s, stdev = $stdev, co-efficient of variation = $rounded_cv%

EOF

    if [ $rounded_mean -lt $MEAN_LIMIT ]; then
	echo -e "WARNING: Direct I/O dd mean write throughput is less than $MEAN_LIMIT MB/s.\nThis instance might be abnormally slow." >&2
	slow="true"
    elif [ $rounded_cv -gt $VARIATION_LIMIT ]; then
	echo -e "WARNING: Direct I/O dd write throughput has more than $VARIATION_LIMIT% variation.\nThis instance might be abnormally slow." >&2
	slow="true"
    else
	slow="false"
    fi

    if [ $slow == "true" ]; then
	cat >&2 <<EOF

Individual runs:$results
EOF
	exit 1
    else
	exit 0
    fi
}


function show_help()
{
    usage_banner;
    cat <<EOF

Usage:  $ME [-h] EBS_MOUNTPOINT

Run perftest on EBS_MOUNTPOINT.  EBS_MOUNTPOINT is a directory where
a EBS volume is mounted.

Miscellaneous:
  -h                        display this help and exit

Example:
  $ME /mnt
EOF
}


function main()
{
    # Parse command line arguments.
    while getopts :h OPT; do
	case "$OPT" in
	    h)
		show_help
		exit 0
		;;
	    \?)
                # getopts issues an error message
		echo "Invalid option: -$OPTARG"
		show_help
		exit 1
		;;
	esac
    done

    # Remove the switches we parsed above.
    shift `expr $OPTIND - 1`

    # We want only one non-option argument.
    if [ $# -ne 1 ]; then
	show_help
	exit 1
    fi

    perftest $1
}


main "$@"
