#!/bin/bash
#
# Copyright (c) 2009, Regents of the University of Colorado.
# Written by Sebastian Kuzminsky <seb@highlab.com>
# This script is released into the public domain.
#


#set -x

# This file will contain the tests that failed.
# --dyoung oct 2010
FAILEDFILE="retest"


[ -f pretest-script ] && source pretest-script


function find_tests_in () {
    find "$@" \( -type f -o -type l \) -a -name 'dotest' | grep -v "\.libs/" | xargs -L 1 dirname | cut -d / -f 1- | sort
}


function pass_test () {
    NUM_PASSED=$((NUM_PASSED + 1))
    TESTS_PASSED="$TESTS_PASSED $1"
}


function fail_test () {
    NUM_FAILED=$((NUM_FAILED + 1))
    TESTS_FAILED="$TESTS_FAILED $1"
}


function skip_test () {
    NUM_SKIPPED=$((NUM_SKIPPED + 1))
    TESTS_SKIPPED="$TESTS_SKIPPED $1"
}


# runs one test, updates the test status counters
function run_a_test () {
    TEST=$1

    # see, you can make bash read like perl if you try
    TEST=${TEST##./}
    TEST=${TEST%%/}

    if [ ! -d "$TEST" -o ! -e "$TEST/dotest" ]; then
        echo "test $TEST doesnt exist!"
        NUM_FAILED=$((NUM_FAILED + 1))
        TESTS_FAILED="$TESTS_FAILED $TEST"
        return
    fi

    echo
    echo "***"
    echo "*** ${TEST}"
    echo "***"

    if [ ! -x "$TEST/dotest" ]; then
        echo "disabled, skipping"
        NUM_SKIPPED=$((NUM_SKIPPED + 1))
        TESTS_SKIPPED="$TESTS_SKIPPED $TEST"
        return
    fi

    pushd "$TEST" > /dev/null

    if [ -x "cleanup" ]; then
        ./cleanup
    fi

    # Prefer X/Open Portable tools if Solaris
    if [ -x "/usr/xpg4/bin" ]; then
        PATH="/usr/xpg4/bin:$PATH"
    fi    
        
    ./dotest
    TEST_RETVAL=$?
    if [ $TEST_RETVAL -eq 0 ]; then
        echo "TEST PASSED!"
        pass_test $TEST
        if [ -x "cleanup" ]; then
            ./cleanup
        fi
    elif [ $TEST_RETVAL -eq 1 ]; then
        echo "TEST FAILED!"
        fail_test $TEST
    elif [ $TEST_RETVAL -eq 2 ]; then
        echo "TEST SKIPPED!"
        skip_test $TEST
    else 
        echo "test returned unknown value $TEST_RETVAL"
        echo "skipping"
        skip_test $TEST
    fi

    popd > /dev/null
}


# cleans up one test
function cleanup_a_test () {
    TEST=$1

    # see, you can make bash read like perl if you try
    TEST=${TEST##./}
    TEST=${TEST%%/}

    if [ ! -d "$TEST" -o ! -e "$TEST/dotest" ]; then
        echo "test $TEST doesnt exist!"
        return
    fi

    if [ ! -x "$TEST/cleanup" ]; then
        return
    fi

    pushd "$TEST" > /dev/null
    ./cleanup
    popd > /dev/null
}


# run all tests listed in $@
function run_tests () {
    for TEST in "$@"; do
        run_a_test $TEST
    done
}


# cleanup all tests listed in $@
function cleanup_tests () {
    for TEST in "$@"; do
        cleanup_a_test $TEST
    done
}




# these track how much of the test suite is passing/failing/skipped
NUM_PASSED=0
NUM_FAILED=0
NUM_SKIPPED=0

# these track the names of the tests passed/failed/skipped
# each is a string consisting of the names of all the tests in that category, separated by spaces
TESTS_PASSED=''
TESTS_FAILED=''
TESTS_SKIPPED=''


CLEANUP=""
if [ "$1" = "cleanup" ]; then
    shift
    CLEANUP="cleanup"
fi


if [ $# -eq 0 ]; then
    TESTS=$(find_tests_in .)
else
    TESTS=$(find_tests_in "$@")
fi

if [ -z "$TESTS" ]; then
    echo "no tests found!"
    exit 1
fi


if [ -z "$CLEANUP" ]; then
    run_tests $TESTS
else 
    cleanup_tests $TESTS
    if [ $? -eq 0 ]; then
        exit 0
    else
        echo "some tests failed to clean up"
        exit 1
    fi
fi


echo
echo "passed: $NUM_PASSED"
for TEST in $TESTS_PASSED; do
    echo "    $TEST"
done

echo
echo "failed: $NUM_FAILED"
RIGHTNOW=`date`
echo "# Generated by $0 $RIGHTNOW" > $FAILEDFILE
for TEST in $TESTS_FAILED; do
    echo "    $TEST"
    echo "$TEST" >> $FAILEDFILE
done

echo
echo "skipped: $NUM_SKIPPED"
for TEST in $TESTS_SKIPPED; do
    echo "    $TEST"
done


if [ "$NUM_FAILED" = 0 ]; then
    exit 0
else
    exit 1
fi

