set -e

# allow parallel jobs, but don't load up more than 8
NPROC=$( nproc )
MAX_CPU=8
N_CPU=$(( NPROC > MAX_CPU ? MAX_CPU : NPROC ))

# MPI tests are set up to run on 3 processes. Spread them leanly over the available processors (don't have more than 2 tests using one processor).
# e.g. run 1 MPI test at a time over 1-3 processors, or 2 tests at a time over 4-6 processors, or 3 tests over 7-9 processors, etc.
N_MPI=3
N_MPI_TESTS=$(( (N_CPU+N_MPI-1)/N_MPI ))

export OMPI_MCA_plm_rsh_agent=/bin/false
export OMPI_MCA_rmaps_base_oversubscribe=1


# first check unit tests still pass

UNITTEST_SOURCE_DIR=./test/unit/cpp
DOLFIN_SOURCE_DIR=$(pwd)

# need to run ffc to generate test/unit/cpp/function/Projection.h from ufl
cat >> ${UNITTEST_SOURCE_DIR}/CMakeLists.txt <<EOF
set(CMAKE_MODULE_PATH \${CMAKE_MODULE_PATH} ${DOLFIN_SOURCE_DIR}/cmake/modules)
find_package(PythonInterp 3)
find_package(UFC MODULE \${DOLFIN_VERSION_MAJOR}.\${DOLFIN_VERSION_MINOR})
message(STATUS "Generating form files in test directories. May take some time...")
execute_process(   COMMAND \${PYTHON_EXECUTABLE} "-B" "-u" ${DOLFIN_SOURCE_DIR}/cmake/scripts/generate-form-files.py
    WORKING_DIRECTORY ${DOLFIN_SOURCE_DIR}
    RESULT_VARIABLE FORM_GENERATION_RESULT
    OUTPUT_VARIABLE FORM_GENERATION_OUTPUT
    ERROR_VARIABLE FORM_GENERATION_OUTPUT
    )
enable_testing()
EOF

UNITTEST_DIR=./dolfin-unittests
rm -rf $UNITTEST_DIR
mkdir $UNITTEST_DIR
cd $UNITTEST_DIR
  cmake -DCMAKE_C_COMPILER=mpicc ../${UNITTEST_SOURCE_DIR}
  make -j${N_CPU} unittests VERBOSE=1
  echo "Run C++ unit tests (serial)"
  ctest --output-on-failure -R unittests
cd ..


# then check demos run successfully

DEMO_DIR=./dolfin-demo

rm -rf $DEMO_DIR
cp -rL /usr/share/dolfin/demo $DEMO_DIR

cd $DEMO_DIR
cmake -DCMAKE_C_COMPILER=mpicc .
make -j${N_CPU} all VERBOSE=1

DEMO_LIST=`find . -executable -name demo*[^.dir]`

# construct ctest scripts
# (cf. add_test in source cmake/scripts/generate-cmakefiles.py)
CTESTFILE=CTestTestfile.cmake
for d in ${DEMO_LIST}; do
    demo_bin=`basename $d`
    dir=`dirname $d`
    echo -e "subdirs(\"${dir}\")" >> $CTESTFILE
    echo -e "add_test(${demo_bin}_mpi \"mpirun\" \"-np\" \"${N_MPI}\" \"./${demo_bin}\")" >> $dir/$CTESTFILE
    echo "add_test(${demo_bin}_serial \"./${demo_bin}\")" >> $dir/$CTESTFILE
done

# demo_hyperelasticity_mpi diverges, so skip
echo "set(CTEST_CUSTOM_TESTS_IGNORE demo_hyperelasticity_mpi)" > CTestCustom.cmake

echo "running C++ demos (serial)"
ctest --output-on-failure -j${N_CPU} -R serial

echo "running C++ demos (MPI)"
echo "available CPUs: NPROC=${NPROC}, of which we use N_CPU=${N_CPU}"
echo "using ${N_MPI} processes per demo (i.e. run ${N_MPI_TESTS} demo[s] at once)"
ctest --output-on-failure -j${N_MPI_TESTS} -R mpi

cd ..
