#!/bin/bash

# Check that selected examples can build and run without segfaulting

err_code=0

export OMPI_MCA_plm_rsh_agent=/bin/false
export OMPI_MCA_rmaps_base_oversubscribe=1
# 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`

cp CMakeLists.txt CMakeLists.txt.orig

# enable examples CMakeLists.txt to operate standalone
cat <<END >CMakeLists.txt
cmake_minimum_required(VERSION 3.12)
project(adios2_examples C CXX Fortran)

find_package(adios2 REQUIRED)

END
cat CMakeLists.txt.orig >>CMakeLists.txt

mkdir test_build
cd test_build

# build examples
cmake -DCMAKE_PREFIX_PATH=/usr/lib/${DEB_HOST_MULTIARCH}/cmake/adios2/mpi -DCMAKE_CXX_COMPILER=mpicxx  ..
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[@]} heatTransfer_read_fileonly_adios2 \
 queryTest hello_bpReader_mpi CppReader \
 examplePluginEngine*)

# simple bpReader example fails with BeginStep error on InquireVariable, not fixed by PR#3856
SKIP_TEST_LIST=(${SKIP_TEST_LIST[@]} hello_bpReader)

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

# 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[@]} exampleOperatorPlugin* joinedArray_write*)
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 must 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 -name *_write ${SKIP_TESTS}`)
TEST_LIST=(${TEST_LIST[@]} `find . -maxdepth 3 -name *_read ${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 ..
cp CMakeLists.txt.orig CMakeLists.txt

# 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 'mpi' in str(adios2.Mode)"
  err_code=$(( $? | err_code ))
  mpirun -n 3 python$pyver -c "import adios2; print('adios2 version', adios2.__version__); assert 'mpi' in str(adios2.Mode)"
  err_code=$(( $? | err_code ))

  # check python examples run successfully
  # (only a couple of them run freely)
  for f in hello/bpWriter/helloBPWriter.py hello/bpReader/helloBPReaderHeatMap2D.py; 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}
