# 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

echo "== running C++ tests =="

# first check unit tests still pass

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

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


UNITTEST_DIR=./dolfinx-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=./dolfinx-demo

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

cd $DEMO_DIR

# need to run ffcx to generate .c from ufl
topdir=`pwd`; for u in `find . -name *.ufl`; do cd `dirname $u`; ffcx *.ufl; cd $topdir; done

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 ..
