#!/bin/bash

# Check that selected examples can build and run without segfaulting

err_code=0

export PRTE_MCA_plm_ssh_agent=/bin/false
export PRTE_MCA_rmaps_default_mapping_policy=:oversubscribe
# MPI is typically more efficient with 1 thread per process
export OMP_NUM_THREADS=1

DEB_HOST_ARCH=$(dpkg-architecture -qDEB_HOST_ARCH)
DEB_HOST_MULTIARCH=$(dpkg-architecture -qDEB_HOST_MULTIARCH)
DEB_HOST_ARCH_ENDIAN=$(dpkg-architecture -qDEB_HOST_ARCH_ENDIAN)

cd examples
TEST_DIR=`pwd`

mkdir test_build
cd test_build

export HOME=${PWD}

# build examples
cmake -DCMAKE_PREFIX_PATH=/usr/lib/${DEB_HOST_MULTIARCH}/cmake/adios2/mpi \
	-DCMAKE_CXX_COMPILER=mpicxx \
	-DCMAKE_BUILD_TYPE=Debug \
	-DCMAKE_VERBOSE_MAKEFILE=ON \
	..
err_code=$(( $? | err_code ))
make
err_code=$(( $? | err_code ))
echo

# don't run examples which do not run cleanly
declare -a SKIP_TEST_LIST
SKIP_TEST_LIST=(${SKIP_TEST_LIST[@]} \
 adios2_simulations_gray-scott-struct adios2_simulations_gray-scott\
 adios2_basics_queryWorker)

# plugin engine examples are not fully configured to run as-is (plugin name is mangled)
SKIP_TEST_LIST=(${SKIP_TEST_LIST[@]} adios2_plugins_examplePluginEngineRead \
    adios2_plugins_examplePluginEngineWrite)

# insituGlobalArraysReaderNxN_mpi is flakey, Bug#1062356
SKIP_TEST_LIST=(${SKIP_TEST_LIST[@]} adios2_useCases_insituGlobalArraysReaderNxN_mpi \
    adios2_basics_globalArray1DRead_*)

# some tests fail or time out on s390x
# Assume all big-endian arches are affected (build with -DADIOS2_USE_Endian_Reverse=ON)
if [ "x${DEB_HOST_ARCH_ENDIAN}" = "xbig" ]; then
  SKIP_TEST_LIST=("${SKIP_TEST_LIST[@]}" adios2_basics_joinedArrayWrite adios2_basics_localArrayRead \
    adios2_basics_variablesShapes_hl adios2_basics_variablesShapes \
    adios2_hello_bpStepsWriteRead adios2_hello_bpAttributeWriteRead adios2_hello_bpReader \
    adios2_hello_helloWorld_hl adios2_hello_helloWorld adios2_hello_helloWorld_c)
  # MPI examples
  SKIP_TEST_LIST=("${SKIP_TEST_LIST[@]}" adios2_useCases_insituGlobalArraysReaderNxN \
    adios2_hello_helloWorld_hl_mpi adios2_hello_helloWorld_mpi adios2_hello_helloWorld_c_mpi \
    adios2_hello_bpStepsWriteRead_mpi adios2_hello_bpReaderHeatMap3D adios2_hello_bpReaderHeatMap2D \
    adios2_hello_bpReader_mpi adios2_hello_bpAttributeWriteRead_mpi \
    adios2_basics_variablesShapes_hl_mpi adios2_basics_variablesShapes_mpi \
    adios2_basics_values_f)
fi

SKIP_TESTS=""
for t in ${SKIP_TEST_LIST[@]}; do
  SKIP_TESTS="${SKIP_TESTS} -not -name $t"
done
echo "skipping examples: SKIP_TEST_LIST=${SKIP_TEST_LIST[@]}"

# *Write should be run before *Read to generate the test file needed to read
# and *Read before *Write_mpi or the read may fail
declare -a TEST_LIST
TEST_LIST=(`find . -maxdepth 3 -executable -type f \( -name *Write -o -name *Writer \) ${SKIP_TESTS}`)
TEST_LIST=(${TEST_LIST[@]} `find . -maxdepth 3 -executable -type f \( -name *Read -o -name *Reader \) ${SKIP_TESTS}`)
TEST_LIST=(${TEST_LIST[@]} `find . -maxdepth 3 -executable -type f -not -path "*CMakeFiles*" ${SKIP_TESTS}`)
# get a unique list (preserving order) cf. https://stackoverflow.com/questions/13648410/how-can-i-get-unique-values-from-an-array-in-bash#comment99138701_13648438
TEST_LIST=(`echo "${TEST_LIST[@]}" | tr " " "\n" | awk '!seen[$0]++'`)

# run examples
for f in ${TEST_LIST[@]}; do
  echo Running $f
  ADIOS2_PLUGIN_PATH=/usr/lib/${DEB_HOST_MULTIARCH}/adios2/mpi/plugins mpirun -n 3 $f 2>$f.err >$f.out
  this_err=$?
  if [ $this_err -ne 0 ]; then
    echo "Error ${this_err} in $f"
    cat $f.out
    cat $f.err
  else
    echo "Passed: $f"
  fi
  err_code=$(( this_err | err_code ))
done

cd ..

# check python examples run successfully
# (only a couple of them run freely)
PYTHON_TESTS=hello/bpWriter/bpWriter.py

if [ "x${DEB_HOST_ARCH_ENDIAN}" = "xbig" ]; then
  echo -e "\nSkipping python example bpReaderHeatMap2D.py on bigendian systems"
else
  PYTHON_TESTS="${PYTHON_TESTS} hello/bpReader/bpReaderHeatMap2D.py"
fi

# confirm MPI Python module is accessible
for pyver in `py3versions -sv`; do
  echo -e "\nChecking Python $pyver installation"
  mpirun -n 1 python$pyver -c "import adios2; print('adios2 version', adios2.__version__); assert adios2.is_built_with_mpi"
  err_code=$(( $? | err_code ))
  mpirun -n 3 python$pyver -c "import adios2; print('adios2 version', adios2.__version__); assert adios2.is_built_with_mpi"
  err_code=$(( $? | err_code ))

  for f in ${PYTHON_TESTS}; do
    echo Running python$pyver example $f
    cd `dirname $f`
    pyscript=`basename $f`
    ADIOS2_PLUGIN_PATH=/usr/lib/${DEB_HOST_MULTIARCH}/adios2/mpi/plugins mpirun -n 3 python$pyver $pyscript 2>$pyscript.err >$pyscript.out
    this_err=$?
    if [ $this_err -ne 0 ]; then
      echo "Error ${this_err} in $f"
      cat $pyscript.out
      cat $pyscript.err
    else
      echo "Passed: $f"
    fi
    err_code=$(( this_err | err_code ))
    cd $TEST_DIR
  done
done

exit ${err_code}
