#!/usr/bin/env bash
#
#/**
# * Licensed to the Apache Software Foundation (ASF) under one
# * or more contributor license agreements.  See the NOTICE file
# * distributed with this work for additional information
# * regarding copyright ownership.  The ASF licenses this file
# * to you under the Apache License, Version 2.0 (the
# * "License"); you may not use this file except in compliance
# * with the License.  You may obtain a copy of the License at
# *
# *     http://www.apache.org/licenses/LICENSE-2.0
# *
# * Unless required by applicable law or agreed to in writing, software
# * distributed under the License is distributed on an "AS IS" BASIS,
# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# * See the License for the specific language governing permissions and
# * limitations under the License.
# */

usage()
{
cat << EOF
usage: $0 [options] [test-name...]

Run a set of hbase tests. Individual tests may be specified on the
command line or in a file using -f, with one test per line.  Runs all
tests by default.  Each specified tests should include the fully
qualified package name.

options:
   -h          Show this message
   -c          Run 'mvn clean' before running the tests
   -f FILE     Run the additional tests listed in the FILE
   -u          Only run unit tests. Default is to run 
               unit and integration tests
   -n N        Run each test N times. Default = 1.
   -s N        Print N slowest tests
   -H          Print which tests are hanging (if any)
   -e          Echo the maven call before running. Default: not enabled
   -r          Runs remotely, on the build server. Default: not enabled
EOF
}

echoUsage=0
server=0
testFile=
doClean=""
testType=verify
numIters=1
showSlowest=
showHanging=

# normalize path refs for surefire
if [[ "$0" != /* ]]; then
    # relative path
    scriptDir=`pwd`/$(dirname $0)
else
    # absolute path
    scriptDir=$(dirname $0)
fi
testDir=$scriptDir/../../../target/surefire-reports

while getopts "hcerHun:s:f:" OPTION
do
     case $OPTION in
         h)
             usage
             exit 0
             ;;
	 c)
	     doClean="clean"
	     ;;
         H)
             showHanging=1
             ;;
         u)
	     testType=test
             ;;
         n)
             numIters=$OPTARG
             ;;
         s)
             showSlowest=$OPTARG
             ;;
         f)
             testFile=$OPTARG
             ;;
        e)
             echoUsage=1
             ;;
        r)
            server=1
            ;;
	 ?) 
	     usage
	     exit 1
     esac
done

testIdx=0

# add tests specified in a file
if [ ! -z $testFile ]; then
    exec 3<$testFile

    while read <&3 line ; do
	if [ ! -z "$line" ]; then
	    test[$testIdx]="$line"
	fi
	testIdx=$(($testIdx+1))
    done
fi

# add tests specified on cmd line
if [ ! -z $BASH_ARGC ]; then
    shift $(($OPTIND - 1))
    for (( i = $OPTIND; i <= $BASH_ARGC; i++ ))
    do
	test[$testIdx]=$1;
	testIdx=$(($testIdx+1))
	shift
    done
fi

echo "Running tests..."
numTests=${#test[@]}

for ((  i = 1 ;  i <= $numIters; i++  ))
do
    if [[ $numTests > 0 ]]; then
        #Now loop through each test
	for (( j = 0; j < $numTests; j++ ))
	do
        # Create the general command
        cmd="nice -10 mvn $doClean $testType -Dtest=${test[$j]}"

        # Add that is should run locally, if not on the server
        if [ ${server} -eq 0 ]; then
            cmd="${cmd} -P localTests"
        fi

        # Print the command, if we should
        if [ ${echoUsage} -eq 1 ]; then
            echo "${cmd}"
        fi

        # Run the command
        $cmd

        if [ $? -ne 0 ]; then
		echo "${test[$j]} failed, iteration: $i"
		exit 1
	    fi
	done
    else
	echo "EXECUTING ALL TESTS"
    # Create the general command
    cmd="nice -10 mvn $doClean $testType"

    # Add that is should run locally, if not on the server
    if [ ${server} -eq 0 ]; then
       cmd="${cmd} -P localTests"
    fi

    # Print the command, if we should
    if [ ${echoUsage} -eq 1 ]; then
        echo "${cmd}"
    fi

    #now run the command
    $cmd
    fi
done

# Print a report of the slowest running tests
if [ ! -z $showSlowest ]; then
    
    testNameIdx=0
    for (( i = 0; i < ${#test[@]}; i++ ))
    do
	testNames[$i]=$testDir/'TEST-'${test[$i]}'.xml'
    done

    echo "Slowest $showSlowest tests:"

    awk '/<testsuite/ { \
              gsub(/\"/,""); \
              gsub(/>/,""); \
              split($7,testname,"="); \
              split($3,time,"="); \
              print  testname[2]"\t"time[2]}' \
	${testNames[@]} \
	| sort -k2,2rn \
	| head -n $showSlowest
fi

# Print a report of tests that hung
if [ ! -z $showHanging ]; then
    echo "Hanging tests:"
    find $testDir -type f -name *.xml -size 0k \
	| xargs basename \
	| cut -d"." -f -1
fi
