#! /bin/sh
# Run ZeroMQ tests, in order.  This is extracted from the tests/Makefile
# which won't run as-is because it relies on libtool building things, and
# thus creating various libtool files, which don't work well on z/OS
#
# noinst_PROGRAMS needs to be kept in sync with tests/Makefile.am, as it
# defines the order in which tests are run.
#
# Written by Ewen McNeill <ewen@imatix.com>, 2014-07-19
# Updated by Ewen McNeill <ewen@imatix.com>, 2014-07-24
#---------------------------------------------------------------------------

set -e    # Stop if a test fails

#---------------------------------------------------------------------------
# Change to tests directory if necessary

# Figure out where we are
BIN_DIR=$(dirname $0)
if [ -z "${BIN_DIR}" ]; then BIN_DIR="."; fi
case "${BIN_DIR}" in
  .)  BIN_DIR="$(pwd)";            ;;
  /*)                              ;;
  *)  BIN_DIR="$(pwd)/${BIN_DIR}"; ;;
esac

# Locate top of source tree, assuming we're in builds/zos
TOP="${BIN_DIR}/../.."
SRCDIR="${TOP}/src"
TESTDIR="${TOP}/tests"

case "$(pwd)" in
  *tests) ;;
  *)      echo "Changing to ${TESTDIR}"
          cd "${TESTDIR}"
          ;;
esac

if [ -x "test_system" ]; then
  :
else
  echo "Run makelibzmq and maketests before runtests" >&2
  exit 1
fi

#---------------------------------------------------------------------------
# Explanation of tests expected to fail:
# test_abstract_ipc: Relies on Linux-specific IPC functionality
# test_fork:         Relies on using pthreads _after_ fork, _before_ exec
# test_diffserv:     Needs IP_PROTO, IP_TOS setsockopt(); the headers
#                    are present on z/OS UNIX System Services, but
#                    fails with:
#                    EDC8109I Protocol not available. (./ip.cpp:164)
#    NOTE: not listed as a valid IP setsockopt() option at:
#       http://pic.dhe.ibm.com/infocenter/zos/v2r1/index.jsp?topic=%2Fcom.ibm.zos.v2r1.bpxbd00%2Fsetopt.htm
#
XFAIL_TESTS="test_abstract_ipc|test_fork|test_diffserv"

# BUILD_TIPC is not defined, so we skip all these tests
SKIP_TESTS="test_.*_tipc"

# Extract list of all test programs from tests/Makefile.am
#
# Excluding tests we know will fail because of missing functionality
#
noinst_PROGRAMS=$(grep "test_" Makefile.am | grep -E -v "_SOURCES|XFAIL" |
                  sed 's/noinst_PROGRAMS.* test/test/; s/^ *//; s/ *\\ *$//;' |
                  grep -v "${SKIP_TESTS}" | grep -E -v "${XFAIL_TESTS}")
#echo "Found tetsts: ${noinst_PROGRAMS}"

# Run tests on command line, or all tests we found
if [ -n "${1}" ]; then
  TESTS="$*"     # Run tests on command line
else
  TESTS="${noinst_PROGRAMS}"
fi

verbose() {
   echo "Starting: $@" >&2
   "$@"
}

# Uncomment TESTS_ENVIRONMENT=verbose to see "Starting: TEST" messages
#TESTS_ENVIRONMENT=verbose
TESTS_ENVIRONMENT=

#---------------------------------------------------------------------------
# Explicitly add SRCDIR into library search path, to make sure we
# use our just-built version
LIBPATH="${SRCDIR}:/lib:/usr/lib"
export LIBPATH

#---------------------------------------------------------------------------
# check-TESTS: target from tests/Makefile, converted from Make syntax to
# shell syntax

failed=0; all=0; xfail=0; xpass=0; skip=0;
srcdir=.; export srcdir;
list="${TESTS}";
red=""; grn=""; lgn=""; blu=""; std="";
if test -n "$list"; then
  for tst in $list; do
    if test -f ./$tst; then dir=./;
    elif test -f $tst; then dir=;
    else dir="${srcdir}/"; fi;
    if ${TESTS_ENVIRONMENT} ${dir}$tst; then
      all=`expr $all + 1`;
      case " ${XFAIL_TESTS} " in
      *"$tst"*)
        xpass=`expr $xpass + 1`;
        failed=`expr $failed + 1`;
        col=$red; res=XPASS;
      ;;
      *)
        col=$grn; res=PASS;
      ;;
      esac;
    elif test $? -ne 77; then
      all=`expr $all + 1`;
      case " ${XFAIL_TESTS} " in
       *"$tst"*)
        xfail=`expr $xfail + 1`;
        col=$lgn; res=XFAIL;
      ;;
      *)
        failed=`expr $failed + 1`;
        col=$red; res=FAIL;
      ;;
      esac;
    else
      skip=`expr $skip + 1`;
      col=$blu; res=SKIP;
    fi;
    echo "${col}$res${std}: $tst";
  done;
  if test "$all" -eq 1; then
    tests="test";
    All="";
  else
    tests="tests";
    All="All ";
  fi;
  if test "$failed" -eq 0; then
    if test "$xfail" -eq 0; then
      banner="$All$all $tests passed";
    else
      if test "$xfail" -eq 1; then failures=failure; else failures=failures; fi;
      banner="$All$all $tests behaved as expected ($xfail expected $failures)";
    fi;
  else
    if test "$xpass" -eq 0; then
      banner="$failed of $all $tests failed";
    else
      if test "$xpass" -eq 1; then passes=pass; else passes=passes; fi;

      banner="$failed of $all $tests did not behave as expected ($xpass unexpected $passes)";
    fi;
  fi;
  dashes="$banner";
  skipped="";
  if test "$skip" -ne 0; then
    if test "$skip" -eq 1; then
      skipped="($skip test was not run)";
    else
      skipped="($skip tests were not run)";
    fi;
    test `echo "$skipped" | wc -c` -le `echo "$banner" | wc -c` ||
       dashes="$skipped"; \
  fi;
  report="";
  if test "$failed" -ne 0 && test -n "${PACKAGE_BUGREPORT}"; then
    report="Please report to ${PACKAGE_BUGREPORT}";
    test `echo "$report" | wc -c` -le `echo "$banner" | wc -c` ||
      dashes="$report";
  fi;
  dashes=`echo "$dashes" | sed s/./=/g`;
  if test "$failed" -eq 0; then
    col="$grn";
  else
    col="$red";
  fi;
  echo "${col}$dashes${std}";
  echo "${col}$banner${std}";
  test -z "$skipped" || echo "${col}$skipped${std}";
  test -z "$report" || echo "${col}$report${std}";
  echo "${col}$dashes${std}";
  test "$failed" -eq 0;
else :; fi
