From 641d59b5f1f6435f28a2a86bde939842ad5d94e4 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Thu, 4 Mar 2021 18:45:05 -0500 Subject: [PATCH 01/32] Add nproc.sh as a replacement for nproc --- test/utilities/nproc.sh | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100755 test/utilities/nproc.sh diff --git a/test/utilities/nproc.sh b/test/utilities/nproc.sh new file mode 100755 index 0000000000..bdb8474199 --- /dev/null +++ b/test/utilities/nproc.sh @@ -0,0 +1,21 @@ +#!/bin/bash + +# Assuming DO_PARALLEL is set with the command to execute mpirun, +# determine how many processes. + +if [ -z "`which grep`" ] ; then + >&2 echo "Error: nproc.sh relies on grep" + exit 1 +fi +if [ -z "`which wc`" ] ; then + >&2 echo "Error: nproc.sh relies on wc" + exit 1 +fi + +NPROC=0 + +if [ ! -z "$DO_PARALLEL" ] ; then + NPROC=`$DO_PARALLEL echo "cpptraj_nproc_test" | grep "cpptraj_nproc_test" | wc -l` +fi +echo $NPROC +exit 0 From 53f22ceec408c7c4c87859c17af68034063a2e91 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Thu, 4 Mar 2021 20:54:25 -0500 Subject: [PATCH 02/32] Use nproc.sh for CPPTRAJ_NPROC --- test/MasterTest.sh | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/test/MasterTest.sh b/test/MasterTest.sh index d7d80c99d7..7e878dfc6e 100644 --- a/test/MasterTest.sh +++ b/test/MasterTest.sh @@ -611,7 +611,7 @@ SetNthreads() { export N_THREADS=1 return 1 fi - export N_THREADS=`$DO_PARALLEL $CPPTRAJ_NPROC` + export N_THREADS=`$CPPTRAJ_NPROC` echo " $N_THREADS MPI threads." fi return 0 @@ -851,14 +851,12 @@ SetBinaries() { # Determine location of nproc/numprocs if [ -z "$CPPTRAJ_NPROC" ] ; then if [ ! -z "$DO_PARALLEL" ] ; then - if [ $STANDALONE -eq 0 ] ; then - CPPTRAJ_NPROC=$DIRPREFIX/AmberTools/test/numprocs - elif [ ! -z "$CPPTRAJSRC" ] ; then - CPPTRAJ_NPROC=$CPPTRAJSRC/test/nproc + if [ ! -z "$CPPTRAJSRC" ] ; then + CPPTRAJ_NPROC=$CPPTRAJSRC/test/utilities/nproc.sh else - CPPTRAJ_NPROC=$CPPTRAJ_TEST_ROOT/nproc + CPPTRAJ_NPROC=$CPPTRAJ_TEST_ROOT/utilities/nproc.sh fi - if [ -z "$CPPTRAJ_NPROC" ] ; then + if [ ! -f "$CPPTRAJ_NPROC" ] ; then ErrMsg "Error: nproc $CPPTRAJ_NPROC not found." exit 1 fi From c5e07a5a629871817c42f64d40fda649798e0fdc Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Thu, 4 Mar 2021 21:00:33 -0500 Subject: [PATCH 03/32] Remove nproc --- configure | 5 ----- src/Makefile | 4 ---- util/Makefile | 7 ------- util/nproc.c | 18 ------------------ 4 files changed, 34 deletions(-) delete mode 100644 util/Makefile delete mode 100644 util/nproc.c diff --git a/configure b/configure index ec4b24d269..8a0f7f43c4 100755 --- a/configure +++ b/configure @@ -2406,11 +2406,6 @@ if [ $USE_SHARED -eq 1 ] ; then else LIBCPPTRAJ_TARGET='nolibcpptraj' fi -# Only build nproc for MPI -if [ $USE_MPI -ne 0 ] ; then - NPROC_TARGET=nproc - INSTALL_TARGETS=$INSTALL_TARGETS" $NPROC_TARGET" -fi # CUDA if [ $USE_CUDA -eq 1 ] ; then CUDA_TARGET='cuda_kernels/libcpptraj_cuda.a' diff --git a/src/Makefile b/src/Makefile index 5299508d59..2ef782e335 100644 --- a/src/Makefile +++ b/src/Makefile @@ -62,10 +62,6 @@ nolibcpptraj: @echo "" @exit 1 -# nproc -------------------------------- -nproc: - cd ../util && $(MAKE) - # Internal object/library targets pub_fft.o: pub_fft.F90 $(FC) $(FPPFLAGS) -c $(FFLAGS) -o $@ pub_fft.F90 diff --git a/util/Makefile b/util/Makefile deleted file mode 100644 index 27f8a0663b..0000000000 --- a/util/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -# Misc utility programs for CPPTRAJ tests, etc -include ../config.h - -all: nproc - -nproc: nproc.c - $(CC) $(DIRECTIVES) -o ../test/nproc $(CFLAGS) nproc.c diff --git a/util/nproc.c b/util/nproc.c deleted file mode 100644 index e1dce75214..0000000000 --- a/util/nproc.c +++ /dev/null @@ -1,18 +0,0 @@ -#include -#ifdef MPI -#include -#endif - -int main(int argc, char** argv) { - int size = 1; - int rank = 0; -# ifdef MPI - MPI_Init(&argc, &argv); - MPI_Comm_size(MPI_COMM_WORLD, &size); - MPI_Comm_rank(MPI_COMM_WORLD, &rank); - MPI_Barrier(MPI_COMM_WORLD); - MPI_Finalize(); -# endif - if (rank == 0) printf("%i\n", size); - return 0; -} From d995897655aa0d620caf1b1af2ab01fc54659cee Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Thu, 4 Mar 2021 21:01:09 -0500 Subject: [PATCH 04/32] Move to test directory --- {util => test/utilities}/ndiff/COPYING | 0 {util => test/utilities}/ndiff/README | 0 {util => test/utilities}/ndiff/ndiff.awk | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename {util => test/utilities}/ndiff/COPYING (100%) rename {util => test/utilities}/ndiff/README (100%) rename {util => test/utilities}/ndiff/ndiff.awk (100%) diff --git a/util/ndiff/COPYING b/test/utilities/ndiff/COPYING similarity index 100% rename from util/ndiff/COPYING rename to test/utilities/ndiff/COPYING diff --git a/util/ndiff/README b/test/utilities/ndiff/README similarity index 100% rename from util/ndiff/README rename to test/utilities/ndiff/README diff --git a/util/ndiff/ndiff.awk b/test/utilities/ndiff/ndiff.awk similarity index 100% rename from util/ndiff/ndiff.awk rename to test/utilities/ndiff/ndiff.awk From cc03f0a5386092833f0b7186e1c7c5a3978b4e09 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Thu, 4 Mar 2021 21:05:19 -0500 Subject: [PATCH 05/32] Only rely on CPPTRAJ_TEST_ROOT for test utilities --- test/MasterTest.sh | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/test/MasterTest.sh b/test/MasterTest.sh index 7e878dfc6e..5bc6a4f1ce 100644 --- a/test/MasterTest.sh +++ b/test/MasterTest.sh @@ -835,13 +835,7 @@ SetBinaries() { fi # Determine location of ndiff.awk if [ -z "$CPPTRAJ_NDIFF" ] ; then - if [ $STANDALONE -eq 0 ] ; then - CPPTRAJ_NDIFF=$DIRPREFIX/test/ndiff.awk - elif [ ! -z "$CPPTRAJSRC" ] ; then - CPPTRAJ_NDIFF=$CPPTRAJSRC/util/ndiff/ndiff.awk - else - CPPTRAJ_NDIFF=$CPPTRAJ_TEST_ROOT/../util/ndiff/ndiff.awk - fi + CPPTRAJ_NDIFF=$CPPTRAJ_TEST_ROOT/utilities/ndiff/ndiff.awk if [ ! -f "$CPPTRAJ_NDIFF" ] ; then ErrMsg "'ndiff.awk' not present: $CPPTRAJ_NDIFF" exit 1 @@ -851,11 +845,7 @@ SetBinaries() { # Determine location of nproc/numprocs if [ -z "$CPPTRAJ_NPROC" ] ; then if [ ! -z "$DO_PARALLEL" ] ; then - if [ ! -z "$CPPTRAJSRC" ] ; then - CPPTRAJ_NPROC=$CPPTRAJSRC/test/utilities/nproc.sh - else - CPPTRAJ_NPROC=$CPPTRAJ_TEST_ROOT/utilities/nproc.sh - fi + CPPTRAJ_NPROC=$CPPTRAJ_TEST_ROOT/utilities/nproc.sh if [ ! -f "$CPPTRAJ_NPROC" ] ; then ErrMsg "Error: nproc $CPPTRAJ_NPROC not found." exit 1 From ab0e62b2e4775dfc319d05aac440ee5f6a4e868e Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Thu, 4 Mar 2021 21:07:00 -0500 Subject: [PATCH 06/32] Remove references to CPPTRAJSRC --- configure | 4 ---- 1 file changed, 4 deletions(-) diff --git a/configure b/configure index 8a0f7f43c4..081daa432d 100755 --- a/configure +++ b/configure @@ -114,7 +114,6 @@ EXE='' # Binary executable suffix REBUILDOPT='' # Can be set to --rebuild and passed to get_library.sh BUILDTESTOPT='silent' # Set to blank to avoid asking about building libraries INSTALL_DAT='install_dat' # Target for installing data directory -CPPTRAJSRC='' # CPPTRAJ source directory COMPERR='cpptrajcfg.compile.err' COMPOUT='cpptrajcfg.compile.out' @@ -2260,7 +2259,6 @@ fi if [ "$WORKDIR" != '.' ] ; then Err "CPPTRAJ configure must be executed from the source directory." fi -CPPTRAJSRC=$CURRENTDIR # Basic checks and directives BasicChecks @@ -2527,7 +2525,6 @@ if [ "$PERFORM_CHECKS" = 'yes' ] ; then RFILE=$CPPTRAJHOME/cpptraj.sh cat > $RFILE < $RFILE < Date: Thu, 4 Mar 2021 21:20:39 -0500 Subject: [PATCH 07/32] Keep CPPTRAJSRC. Useful for unit tests --- configure | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/configure b/configure index 081daa432d..8a0f7f43c4 100755 --- a/configure +++ b/configure @@ -114,6 +114,7 @@ EXE='' # Binary executable suffix REBUILDOPT='' # Can be set to --rebuild and passed to get_library.sh BUILDTESTOPT='silent' # Set to blank to avoid asking about building libraries INSTALL_DAT='install_dat' # Target for installing data directory +CPPTRAJSRC='' # CPPTRAJ source directory COMPERR='cpptrajcfg.compile.err' COMPOUT='cpptrajcfg.compile.out' @@ -2259,6 +2260,7 @@ fi if [ "$WORKDIR" != '.' ] ; then Err "CPPTRAJ configure must be executed from the source directory." fi +CPPTRAJSRC=$CURRENTDIR # Basic checks and directives BasicChecks @@ -2525,6 +2527,7 @@ if [ "$PERFORM_CHECKS" = 'yes' ] ; then RFILE=$CPPTRAJHOME/cpptraj.sh cat > $RFILE < $RFILE < Date: Fri, 5 Mar 2021 08:55:08 -0500 Subject: [PATCH 08/32] Start adding unit tests --- test/MasterTest.sh | 6 +- test/unitTests/CpptrajTest.sh | 9 ++ test/unitTests/Makefile | 32 ++++++ test/unitTests/NameType/UnitTest.sh | 14 +++ test/unitTests/NameType/main.cpp | 147 ++++++++++++++++++++++++++++ test/unitTests/UnitMaster.sh | 90 +++++++++++++++++ 6 files changed, 297 insertions(+), 1 deletion(-) create mode 100755 test/unitTests/CpptrajTest.sh create mode 100644 test/unitTests/Makefile create mode 100755 test/unitTests/NameType/UnitTest.sh create mode 100644 test/unitTests/NameType/main.cpp create mode 100644 test/unitTests/UnitMaster.sh diff --git a/test/MasterTest.sh b/test/MasterTest.sh index 5bc6a4f1ce..5053849e3a 100644 --- a/test/MasterTest.sh +++ b/test/MasterTest.sh @@ -1204,7 +1204,11 @@ if [ -z "$CPPTRAJ_TEST_SETUP" ] ; then ErrMsg "Unknown test invocation. Expected RunTest.sh or CpptrajTest.sh, got $0" exit 1 fi - #echo "DEBUG: CPPTRAJ_TEST_ROOT= $CPPTRAJ_TEST_ROOT $0" + # Special case: this may be invoked from the unitTests directory. + if [ "`basename $CPPTRAJ_TEST_ROOT`" = 'unitTests' ] ; then + CPPTRAJ_TEST_ROOT=`dirname $CPPTRAJ_TEST_ROOT` + fi + echo "DEBUG: CPPTRAJ_TEST_ROOT= $CPPTRAJ_TEST_ROOT $0" # If CPPTRAJ_TEST_OS is not set, try to determine. if [ -z "$CPPTRAJ_TEST_OS" ] ; then export CPPTRAJ_TEST_OS=`uname -s | awk '{print $1}'` diff --git a/test/unitTests/CpptrajTest.sh b/test/unitTests/CpptrajTest.sh new file mode 100755 index 0000000000..f8dc39e6e4 --- /dev/null +++ b/test/unitTests/CpptrajTest.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +if [ ! -f '../MasterTest.sh' ] ; then + echo "Fatal Error: MasterTest.sh not present" > /dev/stderr + exit 1 +fi +CPPTRAJ_TEST_MODE='master' +. ../MasterTest.sh +exit 0 diff --git a/test/unitTests/Makefile b/test/unitTests/Makefile new file mode 100644 index 0000000000..81be8af6cb --- /dev/null +++ b/test/unitTests/Makefile @@ -0,0 +1,32 @@ +# Makefile for unit tests + +test: test.all + +# ----- All unit tests go below ------------------ + +unit.NameType: + cd NameType && ./UnitTest.sh + +# ----- Every unit test should go here ----------- +COMPLETETESTS= \ + unit.NameType + +test.cpptraj: $(COMPLETETESTS) + +# ------------------------------------------------ + +test.complete: CpptrajTest.sh ../MasterTest.sh UnitMaster.sh + @./CpptrajTest.sh --target test.cpptraj $(OPT) + +test.all: + $(MAKE) test.complete summary + +test.showerrors: + $(MAKE) test.complete summary OPT="$(OPT) showerrors" + +summary: CpptrajTest.sh ../MasterTest.sh + @./CpptrajTest.sh summary $(OPT) + +clean: + @echo "Cleaning unit tests." + $(MAKE) test.complete OPT=clean diff --git a/test/unitTests/NameType/UnitTest.sh b/test/unitTests/NameType/UnitTest.sh new file mode 100755 index 0000000000..68f0e8bbf0 --- /dev/null +++ b/test/unitTests/NameType/UnitTest.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +. ../UnitMaster.sh + +CleanFiles Makefile main.o NameType.o a.out CpptrajStdio.o + +UNITSOURCES='NameType.cpp CpptrajStdio.cpp' + +CreateMakefile + +RunMake "NameType class unit test." + +EndTest +exit 0 diff --git a/test/unitTests/NameType/main.cpp b/test/unitTests/NameType/main.cpp new file mode 100644 index 0000000000..d6fcc9d8f1 --- /dev/null +++ b/test/unitTests/NameType/main.cpp @@ -0,0 +1,147 @@ +// Unit test for NameType class +#include +#include +#include +#include +#include "NameType.h" + +static const int Err(const char* msg) { + fprintf(stderr, "Error: %s\n", msg); + return 1; +} + +struct reverseSort { + bool operator() (const NameType& lhs, const NameType& rhs) const { + return ( lhs > rhs ); + } +} reverseSortObj; + +int main() { + // This unit test is primarily for the matching. + NameType name1("CT11"); + // Copy construction + NameType tmp("HA"); + NameType name2(tmp); + // Test assignment + NameType name3; + name3 = name2; + // Test conversion from strings + std::string str4("HA2"); + NameType name4( str4 ); + std::string str5("ZN"); + NameType name5( str5 ); + + // Copy construction + std::vector Nvector; + Nvector.push_back( name3 ); + Nvector.push_back( name5 ); + Nvector.push_back( name4 ); + Nvector.push_back( name1 ); + Nvector.push_back( name2 ); + + // Test that assignment worked. + bool n1n2_eq = (name2 == name3); + if (!n1n2_eq) return Err("'==' operator failed after assignment.\n"); + bool n1n2_ne = (name2 != name3); + if (n1n2_ne) return Err("'!=' operator failed after assignment.\n"); + + n1n2_eq = (name2 == "HA"); + if (!n1n2_eq) return Err("'==' const char* operator failed after assignment.\n"); + n1n2_ne = (name2 != "HA"); + if (n1n2_ne) return Err("'!=' const char* operator failed after assignment.\n"); + + // Sort. Tests the < operator. + std::sort( Nvector.begin(), Nvector.end() ); + + // Test that copy construction/sort worked. + if ( (name1 != Nvector[0]) || + (name2 != Nvector[1]) || + (name3 != Nvector[2]) || + (name4 != Nvector[3]) || + (name5 != Nvector[4]) ) + return Err("Sort/copy construction failed (order is wrong).\n"); + + // Reverse sort. Tests the > operator. + std::sort( Nvector.begin(), Nvector.end(), reverseSortObj ); + + // Test that reverse sort worked. + if ( (name5 != Nvector[0]) || + (name4 != Nvector[1]) || + (name3 != Nvector[2]) || + (name2 != Nvector[3]) || + (name1 != Nvector[4]) ) + return Err("Reverse sort failed (order is wrong).\n"); + + // Write to stdout + for (std::vector::const_iterator it = Nvector.begin(); it != Nvector.end(); ++it) + printf(" '%s'", *(*it)); + printf("\n"); + + // Test that an out of range index is properly caught + char testchar1 = name1[-1]; + char testchar2 = name1[999999]; + if (testchar1 != '\0' || testchar2 != '\0') + return Err("[] operator did not return null char for out of range index.\n"); + + // Test length function + if (name1.len() != 4 || + name2.len() != 2 || + name3.len() != 2 || + name4.len() != 3 || + name5.len() != 2) + return Err("len() function failed.\n"); + + // Test single wildcard matching for name1 'CT11' + bool swc1 = name1.Match("?T11"); + bool swc2 = name1.Match("C?11"); + bool swc3 = name1.Match("CT?1"); + bool swc4 = name1.Match("CT1?"); + bool swc5 = name1.Match("?T1?"); + if (!swc1 || + !swc2 || + !swc3 || + !swc4 || + !swc5) + return Err("Single wildcard matching failed.\n"); + + // Test wildcard matching for name1 'CT11' + bool wc1 = name1.Match("C*"); + bool wc2 = name1.Match("C*1"); + bool wc3 = name1.Match("CT*"); + if (!wc1 || + !wc2 || + !wc3) + return Err("Wildcard matching failed.\n"); + + // Test mixed wildcard matching + bool mwc1 = name1.Match("*1?"); + if (!mwc1) + return Err("Mixed wildcard matching failed.\n"); + + // Check that large name produces a warning + NameType large1("ThisIsALargeName"); + NameType large2( std::string("ThisIsALargeString") ); + + // This should not produce a warning + NameType char5("12345"); + + // Test matching with asterisk in name. + NameType name6("O5*1"); + bool a1wc = name6.Match("O5*"); // Match + bool a2wc = name6.Match("O5\\*1"); // Match + bool a3wc = name6.Match("O5\\*?"); // Match + if (!a1wc || + !a2wc || + !a3wc) + return Err("Matching name with asterisk.\n"); + NameType name7("O541"); + bool a4wc = name7.Match("O5*"); // Match + bool a5wc = name7.Match("O5\\*1"); // No match + bool a6wc = name7.Match("O5\\*?"); // No Match + if (!a4wc || + a5wc || + a6wc) + return Err("Matching name without asterisk.\n"); + + return 0; +} diff --git a/test/unitTests/UnitMaster.sh b/test/unitTests/UnitMaster.sh new file mode 100644 index 0000000000..3cc65804cf --- /dev/null +++ b/test/unitTests/UnitMaster.sh @@ -0,0 +1,90 @@ +# Source this from all unit test scripts +. ../../MasterTest.sh + +# The variable UNITSOURCES will list all cpptraj source files needed by the unit test. + +# Create Makefile +CreateMakefile() { + cat > Makefile <> Makefile <> Makefile <> $CPPTRAJ_ERROR + fi + if [ $? -ne 0 ] ; then + ProgramError "$1" + fi + fi +} + +if [ -z "$CPPTRAJHOME" -o ! -d "$CPPTRAJHOME" ] ; then + echo "Cannot find CPPTRAJ home directory, set CPPTRAJHOME." + exit 1 +fi + +# Determine cpptraj source directory, CPPTRAJ_SRCDIR +if [ -z "$CPPTRAJ_SRCDIR" ] ; then + + CPPTRAJ_SRCDIR=$CPPTRAJHOME/src + echo " CPPTRAJ source directory: $CPPTRAJ_SRCDIR" + if [ ! -d "$CPPTRAJ_SRCDIR" ] ; then + echo "CPPTRAJ source directory not found." + exit 1 + fi + + if [ ! -f "$CPPTRAJ_SRCDIR/main.cpp" ] ; then + echo "CPPTRAJ source directory $CPPTRAJ_SRCDIR appears empty." + exit 1 + fi + export CPPTRAJ_SRCDIR +fi + +# Determine the config.h file, CPPTRAJ_CONFIGH +if [ -z "$CPPTRAJ_CONFIGH" ] ; then + CPPTRAJ_CONFIGH=$CPPTRAJHOME/config.h + echo " CPPTRAJ config.h file: $CPPTRAJ_CONFIGH" + if [ ! -f "$CPPTRAJ_CONFIGH" ] ; then + echo "CPPTRAJ config.h file not found." + exit 1 + fi + export CPPTRAJ_CONFIGH +fi + From 77b3393a47220257c172a69dbfd700a8bc809989 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Fri, 5 Mar 2021 09:00:00 -0500 Subject: [PATCH 09/32] Fix individual unit test invocation --- test/MasterTest.sh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/test/MasterTest.sh b/test/MasterTest.sh index 5053849e3a..c1948931e5 100644 --- a/test/MasterTest.sh +++ b/test/MasterTest.sh @@ -1197,11 +1197,12 @@ if [ -z "$CPPTRAJ_TEST_SETUP" ] ; then #echo "DEBUG: Initial test setup." # MasterTest.sh has not been called yet; set up test environment. export CPPTRAJ_TEST_ROOT=`pwd` - # If invocation is "./RunTest.sh", individual test dir. If "./CpptrajTest.sh", all tests. - if [ "$0" = './RunTest.sh' ] ; then + # If invocation is "./RunTest.sh" or "./UnitTest.sh", individual test dir. + # If "./CpptrajTest.sh", all tests. + if [ "$0" = './RunTest.sh' -o "$0" = './UnitTest.sh' ] ; then CPPTRAJ_TEST_ROOT=`dirname $CPPTRAJ_TEST_ROOT` elif [ "$0" != './CpptrajTest.sh' ] ; then - ErrMsg "Unknown test invocation. Expected RunTest.sh or CpptrajTest.sh, got $0" + ErrMsg "Unknown test invocation. Expected RunTest.sh, UnitTest.sh, or CpptrajTest.sh, got $0" exit 1 fi # Special case: this may be invoked from the unitTests directory. From 4811157bcf6cc8296f8b75d1e69b581f54ea8a84 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Fri, 5 Mar 2021 09:04:48 -0500 Subject: [PATCH 10/32] Start adding results for unit tests that can be tallied by summary --- test/MasterTest.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/MasterTest.sh b/test/MasterTest.sh index c1948931e5..09cdc4daec 100644 --- a/test/MasterTest.sh +++ b/test/MasterTest.sh @@ -553,6 +553,10 @@ EndTest() { elif [ $NUMCOMPARISONS -gt 0 ] ; then echo "All $NUMCOMPARISONS comparisons passed." OUT "All $NUMCOMPARISONS comparisons passed." + elif [ $PROGERROR -eq 0 ] ; then + # If we are here this is likely a unit test. + echo "All $PROGCOUNT executions passed." + OUT "All $PROGCOUNT executions passed." fi if [ $SKIPCOUNT -gt 0 ] ; then echo "$SKIPCOUNT comparisons skipped." From 7e4e97d49c1217c8210d4e4c2ef2d55aa71181d0 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Fri, 5 Mar 2021 09:24:42 -0500 Subject: [PATCH 11/32] Add target for unit tests --- test/Makefile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/Makefile b/test/Makefile index 8fa27ac28f..41fc8a3262 100644 --- a/test/Makefile +++ b/test/Makefile @@ -658,6 +658,9 @@ test.cpptraj: $(COMPLETETESTS) test.showerrors: $(MAKE) test.complete summary OPT="$(OPT) showerrors long" +unittests: + cd unitTests && $(MAKE) test.showerrors OPT="$(OPT)" + summary: CpptrajTest.sh MasterTest.sh @./CpptrajTest.sh summary $(OPT) From 059a05311293a8bf05e0fd6693ccd7e274ea1343 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Fri, 5 Mar 2021 09:25:51 -0500 Subject: [PATCH 12/32] Ensure DIRECTIVES is used in compiling unit test --- test/unitTests/UnitMaster.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/unitTests/UnitMaster.sh b/test/unitTests/UnitMaster.sh index 3cc65804cf..261ee3dc12 100644 --- a/test/unitTests/UnitMaster.sh +++ b/test/unitTests/UnitMaster.sh @@ -20,7 +20,7 @@ EOF cat >> Makefile <> Makefile < Date: Fri, 5 Mar 2021 13:37:53 -0500 Subject: [PATCH 13/32] Move the unit tests to a separate location --- {test/unitTests => unitTests}/CpptrajTest.sh | 0 {test/unitTests => unitTests}/Makefile | 0 {test/unitTests => unitTests}/NameType/UnitTest.sh | 0 {test/unitTests => unitTests}/NameType/main.cpp | 0 {test/unitTests => unitTests}/UnitMaster.sh | 0 5 files changed, 0 insertions(+), 0 deletions(-) rename {test/unitTests => unitTests}/CpptrajTest.sh (100%) rename {test/unitTests => unitTests}/Makefile (100%) rename {test/unitTests => unitTests}/NameType/UnitTest.sh (100%) rename {test/unitTests => unitTests}/NameType/main.cpp (100%) rename {test/unitTests => unitTests}/UnitMaster.sh (100%) diff --git a/test/unitTests/CpptrajTest.sh b/unitTests/CpptrajTest.sh similarity index 100% rename from test/unitTests/CpptrajTest.sh rename to unitTests/CpptrajTest.sh diff --git a/test/unitTests/Makefile b/unitTests/Makefile similarity index 100% rename from test/unitTests/Makefile rename to unitTests/Makefile diff --git a/test/unitTests/NameType/UnitTest.sh b/unitTests/NameType/UnitTest.sh similarity index 100% rename from test/unitTests/NameType/UnitTest.sh rename to unitTests/NameType/UnitTest.sh diff --git a/test/unitTests/NameType/main.cpp b/unitTests/NameType/main.cpp similarity index 100% rename from test/unitTests/NameType/main.cpp rename to unitTests/NameType/main.cpp diff --git a/test/unitTests/UnitMaster.sh b/unitTests/UnitMaster.sh similarity index 100% rename from test/unitTests/UnitMaster.sh rename to unitTests/UnitMaster.sh From 9be6a9b0e20c7237bf42cc40aaf4114978dc2719 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Fri, 5 Mar 2021 13:38:07 -0500 Subject: [PATCH 14/32] Start making this independent from the regular test framework --- unitTests/CpptrajTest.sh | 6 +- unitTests/Makefile | 4 +- unitTests/UnitMaster.sh | 182 +++++++++++++++++++++++++++++++++------ 3 files changed, 161 insertions(+), 31 deletions(-) diff --git a/unitTests/CpptrajTest.sh b/unitTests/CpptrajTest.sh index f8dc39e6e4..32a778a17b 100755 --- a/unitTests/CpptrajTest.sh +++ b/unitTests/CpptrajTest.sh @@ -1,9 +1,9 @@ #!/bin/bash -if [ ! -f '../MasterTest.sh' ] ; then - echo "Fatal Error: MasterTest.sh not present" > /dev/stderr +if [ ! -f 'UnitMaster.sh' ] ; then + echo "Fatal Error: UnitMaster.sh not present" > /dev/stderr exit 1 fi CPPTRAJ_TEST_MODE='master' -. ../MasterTest.sh +. UnitMaster.sh exit 0 diff --git a/unitTests/Makefile b/unitTests/Makefile index 81be8af6cb..88c33b2d93 100644 --- a/unitTests/Makefile +++ b/unitTests/Makefile @@ -15,7 +15,7 @@ test.cpptraj: $(COMPLETETESTS) # ------------------------------------------------ -test.complete: CpptrajTest.sh ../MasterTest.sh UnitMaster.sh +test.complete: CpptrajTest.sh UnitMaster.sh @./CpptrajTest.sh --target test.cpptraj $(OPT) test.all: @@ -24,7 +24,7 @@ test.all: test.showerrors: $(MAKE) test.complete summary OPT="$(OPT) showerrors" -summary: CpptrajTest.sh ../MasterTest.sh +summary: CpptrajTest.sh UnitMaster.sh @./CpptrajTest.sh summary $(OPT) clean: diff --git a/unitTests/UnitMaster.sh b/unitTests/UnitMaster.sh index 261ee3dc12..5f8ee2b74c 100644 --- a/unitTests/UnitMaster.sh +++ b/unitTests/UnitMaster.sh @@ -1,9 +1,66 @@ # Source this from all unit test scripts -. ../../MasterTest.sh # The variable UNITSOURCES will list all cpptraj source files needed by the unit test. -# Create Makefile +# ----- Environment Variables -------------------------------------------------- +# CPPTRAJ_TEST_SETUP : 'yes' if setup is complete +# CPPTRAJ_RM : Command used to remove files +# CPPTRAJ_TEST_RESULTS : File to record individual test results to. +# CPPTRAJ_ERROR : File to direct cpptraj STDERR to. +# CPPTRAJ_TEST_CLEAN : If 1, only cleaning tests; do not run them. + +# ----- Variables local to single test --------------------- +PROGERROR=0 # Total number of program errors this test + +# ============================================================================== +# TestHeader() +# Write test header (working directory) to specified file. If no file +# specified will be written to STDOUT. +TestHeader() { + if [ ! -z "$1" ] ; then + echo "********************************************************************************" > $1 + echo "TEST: $TEST_WORKDIR" >> $1 + else + echo "********************************************************************************" + echo "TEST: $TEST_WORKDIR" + fi +} + +# -------------------------------------- +# ErrMsg() +# Write out error message to stderr prefaced with 'Error:'. +ErrMsg() { + >&2 echo "Error: $*" +} + +# -------------------------------------- +# OUT() +# Write message to CPPTRAJ_TEST_RESULTS +OUT() { + echo "$1" >> $CPPTRAJ_TEST_RESULTS +} + +# ------------------------------------------------------------------------------ +# CleanFiles() ... +# For every arg passed to the function, check for the file or directory and +# remove it. +CleanFiles() { + while [ ! -z "$1" ] ; do + if [ -d "$1" ] ; then + rmdir $1 + elif [ -f "$1" ] ; then + $CPPTRAJ_RM $1 + fi + shift + done + # If only cleaning requested no run needed, exit now + if [ $CPPTRAJ_TEST_CLEAN -eq 1 ] ; then + exit 0 + fi +} + + +# ----- Create Makefile ---------------- CreateMakefile() { cat > Makefile < +ProgramError() { + ErrMsg " $1" + OUT "Error: $1" + ((PROGERROR++)) +} + +# ----- Run make, check result --------- RunMake() { ((PROGCOUNT++)) echo "" @@ -55,36 +120,101 @@ RunMake() { fi } -if [ -z "$CPPTRAJHOME" -o ! -d "$CPPTRAJHOME" ] ; then - echo "Cannot find CPPTRAJ home directory, set CPPTRAJHOME." - exit 1 -fi +# ------------------------------------------------------------------------------ +# EndTest() +# Print a summary of the current tests results. Should be called at the end of +# every test script. +EndTest() { + #echo "DEBUG: EndTest" + echo "" + echo " $PROGERROR out of $PROGCOUNT executions exited with an error." + echo " $PROGERROR out of $PROGCOUNT executions exited with an error." >> $CPPTRAJ_TEST_RESULTS +} -# Determine cpptraj source directory, CPPTRAJ_SRCDIR -if [ -z "$CPPTRAJ_SRCDIR" ] ; then +# ------------------------------------------------------------------------------ +CmdLineOpts() { + CPPTRAJ_TEST_CLEAN=0 # Will be exported + while [ ! -z "$1" ] ; do + case "$1" in + "clean" ) CPPTRAJ_TEST_CLEAN=1 ;; + esac + shift + done + export CPPTRAJ_TEST_CLEAN +} - CPPTRAJ_SRCDIR=$CPPTRAJHOME/src - echo " CPPTRAJ source directory: $CPPTRAJ_SRCDIR" - if [ ! -d "$CPPTRAJ_SRCDIR" ] ; then - echo "CPPTRAJ source directory not found." +# ============================================================================== +# M A I N +# ============================================================================== +if [ -z "$CPPTRAJ_TEST_SETUP" ] ; then + if [ -z "$CPPTRAJHOME" -o ! -d "$CPPTRAJHOME" ] ; then + echo "Cannot find CPPTRAJ home directory, set CPPTRAJHOME." exit 1 fi - if [ ! -f "$CPPTRAJ_SRCDIR/main.cpp" ] ; then - echo "CPPTRAJ source directory $CPPTRAJ_SRCDIR appears empty." - exit 1 + # Determine cpptraj source directory, CPPTRAJ_SRCDIR + if [ -z "$CPPTRAJ_SRCDIR" ] ; then + + CPPTRAJ_SRCDIR=$CPPTRAJHOME/src + echo " CPPTRAJ source directory: $CPPTRAJ_SRCDIR" + if [ ! -d "$CPPTRAJ_SRCDIR" ] ; then + echo "CPPTRAJ source directory not found." + exit 1 + fi + + if [ ! -f "$CPPTRAJ_SRCDIR/main.cpp" ] ; then + echo "CPPTRAJ source directory $CPPTRAJ_SRCDIR appears empty." + exit 1 + fi + export CPPTRAJ_SRCDIR fi - export CPPTRAJ_SRCDIR -fi -# Determine the config.h file, CPPTRAJ_CONFIGH -if [ -z "$CPPTRAJ_CONFIGH" ] ; then - CPPTRAJ_CONFIGH=$CPPTRAJHOME/config.h - echo " CPPTRAJ config.h file: $CPPTRAJ_CONFIGH" - if [ ! -f "$CPPTRAJ_CONFIGH" ] ; then - echo "CPPTRAJ config.h file not found." - exit 1 + # Determine the config.h file, CPPTRAJ_CONFIGH + if [ -z "$CPPTRAJ_CONFIGH" ] ; then + CPPTRAJ_CONFIGH=$CPPTRAJHOME/config.h + echo " CPPTRAJ config.h file: $CPPTRAJ_CONFIGH" + if [ ! -f "$CPPTRAJ_CONFIGH" ] ; then + echo "CPPTRAJ config.h file not found." + exit 1 + fi + export CPPTRAJ_CONFIGH fi - export CPPTRAJ_CONFIGH + + # Ensure required binaries are set up + if [ -z "$CPPTRAJ_RM" ] ; then + # TODO is this being too paranoid? + if [ ! -f '/bin/rm' ] ; then + ErrMsg "Required binary '/bin/rm' not found." + exit 1 + fi + export CPPTRAJ_RM='/bin/rm -f' + fi + + # Set some defaults + export CPPTRAJ_TEST_RESULTS='Test_Results.dat' + export CPPTRAJ_ERROR='' + + # Process command line options + CmdLineOpts $* + + export CPPTRAJ_TEST_SETUP='yes' +fi # END initial setup + +# Clean any existing test results files. +if [ -f "$CPPTRAJ_TEST_RESULTS" ] ; then + $CPPTRAJ_RM $CPPTRAJ_TEST_RESULTS fi +# Determine mode of execution: individual test or multiple tests. +if [ "$CPPTRAJ_TEST_MODE" = 'master' ] ; then + # Executing multiple tests + echo Master Make +else + # Executing single test + echo non-master make + if [ $CPPTRAJ_TEST_CLEAN -eq 0 ] ; then + TEST_WORKDIR=`pwd` + TestHeader + TestHeader "$CPPTRAJ_TEST_RESULTS" + fi +fi From c0d5a1e62d242e7edf18637f0fb17d56f597dada Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Fri, 5 Mar 2021 13:44:59 -0500 Subject: [PATCH 15/32] Add summary and target variables --- unitTests/UnitMaster.sh | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/unitTests/UnitMaster.sh b/unitTests/UnitMaster.sh index 5f8ee2b74c..e64cec90fe 100644 --- a/unitTests/UnitMaster.sh +++ b/unitTests/UnitMaster.sh @@ -11,6 +11,9 @@ # ----- Variables local to single test --------------------- PROGERROR=0 # Total number of program errors this test +# ----- Local setup variables ------------------------------ +SUMMARY=0 # If 1 print summary of CPPTRAJ_TEST_RESULTS only +TARGET="" # Make target if multiple tests being run # ============================================================================== # TestHeader() @@ -137,6 +140,9 @@ CmdLineOpts() { while [ ! -z "$1" ] ; do case "$1" in "clean" ) CPPTRAJ_TEST_CLEAN=1 ;; + "summary" ) SUMMARY=1 ;; + "--target" ) shift ; TARGET=$1 ;; + * ) ErrMsg "Unknown option: $1" ; exit 1 ;; esac shift done @@ -209,6 +215,26 @@ fi if [ "$CPPTRAJ_TEST_MODE" = 'master' ] ; then # Executing multiple tests echo Master Make + # Probably executed via make. + # If summary requested just do that and exit. + if [ $SUMMARY -ne 0 ] ; then + Summary + fi + # Need a Makefile. + if [ ! -f 'Makefile' ] ; then + ErrMsg "test Makefile not found." + exit 1 + fi + Required "make" + if [ -z "$TARGET" ] ; then + # If no target specified, probably not executed via make. + ErrMsg "No test directories specified." + exit 1 + fi + make $TARGET + if [ $? -ne 0 ] ; then + exit 1 + fi else # Executing single test echo non-master make From 985a9f2734e486273ea4f22875c254e61a02be3f Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Fri, 5 Mar 2021 13:58:44 -0500 Subject: [PATCH 16/32] Add Summary function --- unitTests/UnitMaster.sh | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/unitTests/UnitMaster.sh b/unitTests/UnitMaster.sh index e64cec90fe..a86074b8ee 100644 --- a/unitTests/UnitMaster.sh +++ b/unitTests/UnitMaster.sh @@ -134,6 +134,38 @@ EndTest() { echo " $PROGERROR out of $PROGCOUNT executions exited with an error." >> $CPPTRAJ_TEST_RESULTS } +# ------------------------------------------------------------------------------ +# Summary() +# Print a summary of results in all CPPTRAJ_TEST_RESULTS files and exit. +# Optionally print an error summary and/or valgrind summary. +Summary() { + ERR_STATUS=0 + if [ ! -z "$CPPTRAJ_TEST_RESULTS" ] ; then + RESULTSFILES=`ls */$CPPTRAJ_TEST_RESULTS 2> tmp.cpptrajtest.devnull` + rm tmp.cpptrajtest.devnull + if [ ! -z "$RESULTSFILES" ] ; then + cat $RESULTSFILES > $CPPTRAJ_TEST_RESULTS + echo "===================== TEST SUMMARY ======================" + awk 'BEGIN{ + program_exe = 0; # Number of unit test executions + program_err = 0; # Number of unit test failures + }{ + if ($1 == "CPPTRAJ:") + program_exe++; + else if ($5 == "executions" && $6 == "exited") + program_err += $1; + }END{ + if (program_exe > 0) + printf(" %i out of %i program executions completed.\n", + program_exe - program_err, program_exe); + exit program_err; + }' $CPPTRAJ_TEST_RESULTS + ERR_STATUS=$? + fi + fi + exit $ERR_STATUS +} + # ------------------------------------------------------------------------------ CmdLineOpts() { CPPTRAJ_TEST_CLEAN=0 # Will be exported @@ -225,7 +257,7 @@ if [ "$CPPTRAJ_TEST_MODE" = 'master' ] ; then ErrMsg "test Makefile not found." exit 1 fi - Required "make" + #Required "make" if [ -z "$TARGET" ] ; then # If no target specified, probably not executed via make. ErrMsg "No test directories specified." From c65e5fcfe61046910a39593deacd8e6592203288 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Fri, 5 Mar 2021 14:05:15 -0500 Subject: [PATCH 17/32] Make unit tests pass/fail --- unitTests/UnitMaster.sh | 35 +++++++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/unitTests/UnitMaster.sh b/unitTests/UnitMaster.sh index a86074b8ee..71de188c76 100644 --- a/unitTests/UnitMaster.sh +++ b/unitTests/UnitMaster.sh @@ -127,11 +127,24 @@ RunMake() { # EndTest() # Print a summary of the current tests results. Should be called at the end of # every test script. +# Unit tests either pass or fail. EndTest() { #echo "DEBUG: EndTest" + # Sanity check + if [ $PROGCOUNT -gt 1 ] ; then + ErrMsg "Too many executions; got $PROGCOUNT, expected 1." + exit 1 + fi echo "" - echo " $PROGERROR out of $PROGCOUNT executions exited with an error." - echo " $PROGERROR out of $PROGCOUNT executions exited with an error." >> $CPPTRAJ_TEST_RESULTS + if [ $PROGERROR -eq 0 ] ; then + echo " Unit test passed." + echo " Unit test passed." >> $CPPTRAJ_TEST_RESULTS + else + echo " Unit test failed." + echo " Unit test failed." >> $CPPTRAJ_TEST_RESULTS + fi + #echo " $PROGERROR out of $PROGCOUNT executions exited with an error." + #echo " $PROGERROR out of $PROGCOUNT executions exited with an error." >> $CPPTRAJ_TEST_RESULTS } # ------------------------------------------------------------------------------ @@ -147,19 +160,25 @@ Summary() { cat $RESULTSFILES > $CPPTRAJ_TEST_RESULTS echo "===================== TEST SUMMARY ======================" awk 'BEGIN{ - program_exe = 0; # Number of unit test executions - program_err = 0; # Number of unit test failures + program_exe = 0; # Number of unit test executions + program_pass = 0; # Number of unit test pass + program_err = 0; # Number of unit test failures }{ if ($1 == "CPPTRAJ:") program_exe++; - else if ($5 == "executions" && $6 == "exited") - program_err += $1; + else if ($1 == "Unit" && $2 == "test") { + if ($3 == "passed.") + program_pass++; + else if ($3 == "failed.") + program_err++; + } }END{ if (program_exe > 0) - printf(" %i out of %i program executions completed.\n", - program_exe - program_err, program_exe); + printf(" %i out of %i unit tests passed (%i failed).\n", + program_pass, program_exe, program_err); exit program_err; }' $CPPTRAJ_TEST_RESULTS + echo "=========================================================" ERR_STATUS=$? fi fi From 49ac38bd3789d14ffe9dd5b135cfcb148ee5c114 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Fri, 5 Mar 2021 14:13:57 -0500 Subject: [PATCH 18/32] Dont make unit tests rely on CPPTRAJHOME --- unitTests/UnitMaster.sh | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/unitTests/UnitMaster.sh b/unitTests/UnitMaster.sh index 71de188c76..b4ad5861cb 100644 --- a/unitTests/UnitMaster.sh +++ b/unitTests/UnitMaster.sh @@ -204,15 +204,36 @@ CmdLineOpts() { # M A I N # ============================================================================== if [ -z "$CPPTRAJ_TEST_SETUP" ] ; then - if [ -z "$CPPTRAJHOME" -o ! -d "$CPPTRAJHOME" ] ; then - echo "Cannot find CPPTRAJ home directory, set CPPTRAJHOME." + #if [ -z "$CPPTRAJHOME" -o ! -d "$CPPTRAJHOME" ] ; then + # echo "Cannot find CPPTRAJ home directory, set CPPTRAJHOME." + # exit 1 + #fi + # Assume we are in the cpptraj source directory, /unitTests + # or /unitTests/ + CPPTRAJDIR='' + CURRENTDIR=`pwd` + echo "DEBUG : current dir $CURRENTDIR" + if [ "`basename $CURRENTDIR`" = 'unitTests' ] ; then + # This is /unitTests + CPPTRAJDIR=`dirname $CURRENTDIR` + else + ONE_UP=`dirname $CURRENTDIR` + if [ "`basename $ONE_UP`" = 'unitTests' ] ; then + # This is /unitTests/ + CPPTRAJDIR=`dirname $ONE_UP` + else + ErrMsg "Could not determine cpptraj source directory location." + exit 1 + fi + fi + if [ -z "$CPPTRAJDIR" -o ! -d "$CPPTRAJDIR" ] ; then + ErrMsg "Cpptraj source directory $CPPTRAJDIR empty or is not a directory." exit 1 fi - # Determine cpptraj source directory, CPPTRAJ_SRCDIR + # Determine cpptraj source file directory, CPPTRAJ_SRCDIR if [ -z "$CPPTRAJ_SRCDIR" ] ; then - - CPPTRAJ_SRCDIR=$CPPTRAJHOME/src + CPPTRAJ_SRCDIR=$CPPTRAJDIR/src echo " CPPTRAJ source directory: $CPPTRAJ_SRCDIR" if [ ! -d "$CPPTRAJ_SRCDIR" ] ; then echo "CPPTRAJ source directory not found." @@ -228,7 +249,7 @@ if [ -z "$CPPTRAJ_TEST_SETUP" ] ; then # Determine the config.h file, CPPTRAJ_CONFIGH if [ -z "$CPPTRAJ_CONFIGH" ] ; then - CPPTRAJ_CONFIGH=$CPPTRAJHOME/config.h + CPPTRAJ_CONFIGH=$CPPTRAJDIR/config.h echo " CPPTRAJ config.h file: $CPPTRAJ_CONFIGH" if [ ! -f "$CPPTRAJ_CONFIGH" ] ; then echo "CPPTRAJ config.h file not found." From f07925b11e8c77861e0b8dbaf8d37731489a95a6 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Fri, 5 Mar 2021 14:17:13 -0500 Subject: [PATCH 19/32] Have EndTest exit with a status. Fix output. --- unitTests/UnitMaster.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/unitTests/UnitMaster.sh b/unitTests/UnitMaster.sh index b4ad5861cb..b7632e5379 100644 --- a/unitTests/UnitMaster.sh +++ b/unitTests/UnitMaster.sh @@ -145,6 +145,8 @@ EndTest() { fi #echo " $PROGERROR out of $PROGCOUNT executions exited with an error." #echo " $PROGERROR out of $PROGCOUNT executions exited with an error." >> $CPPTRAJ_TEST_RESULTS + echo "" + exit $PROGERROR } # ------------------------------------------------------------------------------ @@ -212,7 +214,7 @@ if [ -z "$CPPTRAJ_TEST_SETUP" ] ; then # or /unitTests/ CPPTRAJDIR='' CURRENTDIR=`pwd` - echo "DEBUG : current dir $CURRENTDIR" + #echo "DEBUG : current dir $CURRENTDIR" if [ "`basename $CURRENTDIR`" = 'unitTests' ] ; then # This is /unitTests CPPTRAJDIR=`dirname $CURRENTDIR` @@ -286,7 +288,6 @@ fi # Determine mode of execution: individual test or multiple tests. if [ "$CPPTRAJ_TEST_MODE" = 'master' ] ; then # Executing multiple tests - echo Master Make # Probably executed via make. # If summary requested just do that and exit. if [ $SUMMARY -ne 0 ] ; then @@ -309,7 +310,6 @@ if [ "$CPPTRAJ_TEST_MODE" = 'master' ] ; then fi else # Executing single test - echo non-master make if [ $CPPTRAJ_TEST_CLEAN -eq 0 ] ; then TEST_WORKDIR=`pwd` TestHeader From 2456c4ef79e6fc7678e1a52cbea128d31d5c6afa Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Fri, 5 Mar 2021 14:17:44 -0500 Subject: [PATCH 20/32] Use EndTest, not exit --- unitTests/NameType/UnitTest.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/unitTests/NameType/UnitTest.sh b/unitTests/NameType/UnitTest.sh index 68f0e8bbf0..47b9599448 100755 --- a/unitTests/NameType/UnitTest.sh +++ b/unitTests/NameType/UnitTest.sh @@ -11,4 +11,3 @@ CreateMakefile RunMake "NameType class unit test." EndTest -exit 0 From 792e3710751320bdb6ddfb648d956c0770934b4a Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Fri, 5 Mar 2021 14:19:37 -0500 Subject: [PATCH 21/32] Fix test rule --- unitTests/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/unitTests/Makefile b/unitTests/Makefile index 88c33b2d93..d750a46017 100644 --- a/unitTests/Makefile +++ b/unitTests/Makefile @@ -5,7 +5,7 @@ test: test.all # ----- All unit tests go below ------------------ unit.NameType: - cd NameType && ./UnitTest.sh + @-cd NameType && ./UnitTest.sh $(OPT) # ----- Every unit test should go here ----------- COMPLETETESTS= \ From 5b2ac63c1f0e01e90c6672fadd6cbd0db1fe60ad Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Fri, 5 Mar 2021 15:18:59 -0500 Subject: [PATCH 22/32] Add ArgList unit test --- unitTests/ArgList/UnitTest.sh | 13 +++++++++++++ unitTests/ArgList/main.cpp | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100755 unitTests/ArgList/UnitTest.sh create mode 100644 unitTests/ArgList/main.cpp diff --git a/unitTests/ArgList/UnitTest.sh b/unitTests/ArgList/UnitTest.sh new file mode 100755 index 0000000000..535d775345 --- /dev/null +++ b/unitTests/ArgList/UnitTest.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +. ../UnitMaster.sh + +CleanFiles Makefile main.o ArgList.o a.out CpptrajStdio.o StringRoutines.o + +UNITSOURCES='ArgList.cpp CpptrajStdio.cpp StringRoutines.cpp' + +CreateMakefile + +RunMake "ArgList class unit test." + +EndTest diff --git a/unitTests/ArgList/main.cpp b/unitTests/ArgList/main.cpp new file mode 100644 index 0000000000..368419086f --- /dev/null +++ b/unitTests/ArgList/main.cpp @@ -0,0 +1,32 @@ +#include +#include +#include "ArgList.h" + +static const int Err(const char* msg) { + fprintf(stderr, "Error: %s\n", msg); + return 1; +} + +const double SMALL = 0.00000000000001; + +bool f_not_equals(double d1, double d2) { + return (fabs(d1 - d2) > SMALL); +} + +int main() { + ArgList a1("This is a test 3.14159 arglist with 4 45 darg 123.323 :12@H="); + + int iarg = a1.getKeyInt("with", -1); + if (iarg != 4) return Err("getKeyInt() failed."); + + iarg = a1.getNextInteger(-1); + if (iarg != 45) return Err("getNextInteger() failed."); + + double darg = a1.getKeyDouble("darg", 0); + if (f_not_equals(darg, 123.323)) return Err("getKeyDouble() failed."); + + darg = a1.getNextDouble(0); + if (f_not_equals(darg, 3.14159)) return Err("getNextDouble() failed."); + + return 0; +} From d431feac157841a080bf14133a55a3b3c052f0be Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Fri, 5 Mar 2021 15:25:46 -0500 Subject: [PATCH 23/32] Add more tests. --- unitTests/ArgList/main.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/unitTests/ArgList/main.cpp b/unitTests/ArgList/main.cpp index 368419086f..4917e4511a 100644 --- a/unitTests/ArgList/main.cpp +++ b/unitTests/ArgList/main.cpp @@ -14,6 +14,7 @@ bool f_not_equals(double d1, double d2) { } int main() { + // 7 6 6 4 1 1 2 3 3 5 ArgList a1("This is a test 3.14159 arglist with 4 45 darg 123.323 :12@H="); int iarg = a1.getKeyInt("with", -1); @@ -28,5 +29,22 @@ int main() { darg = a1.getNextDouble(0); if (f_not_equals(darg, 3.14159)) return Err("getNextDouble() failed."); + std::string sarg = a1.GetMaskNext(); + if (sarg != ":12@H=") return Err("GetMaskNext() failed."); + + sarg = a1.GetStringKey("a"); + if (sarg != "test") return Err("GetStringKey() failed."); + + sarg = a1.GetStringNext(); + if (sarg != "This") return Err("GetStringKey() failed."); + + ArgList r1 = a1.RemainingArgs(); + if (a1.NremainingArgs() > 0) return Err("RemainingArgs() failed (# remaining args)."); + if (r1.Nargs() != 2) return Err("RemainingArgs() failed (# new args)."); + + r1.MarkArg(0); + sarg = r1.GetStringNext(); + if (sarg != "arglist") return Err("MarkArg() failed."); + return 0; } From e91d1462c79281bf1ae495de0a318660efd210ee Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Fri, 5 Mar 2021 15:26:58 -0500 Subject: [PATCH 24/32] Enabled ArgList test --- unitTests/Makefile | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/unitTests/Makefile b/unitTests/Makefile index d750a46017..309ff5356b 100644 --- a/unitTests/Makefile +++ b/unitTests/Makefile @@ -7,9 +7,13 @@ test: test.all unit.NameType: @-cd NameType && ./UnitTest.sh $(OPT) +unit.ArgList: + @-cd ArgList && ./UnitTest.sh $(OPT) + # ----- Every unit test should go here ----------- COMPLETETESTS= \ - unit.NameType + unit.NameType \ + unit.ArgList test.cpptraj: $(COMPLETETESTS) From da232c642d004d95e78061d870e5864dec4def0f Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Fri, 5 Mar 2021 15:28:54 -0500 Subject: [PATCH 25/32] Add top-level rule for unit tests --- Makefile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Makefile b/Makefile index 5829552326..c6665161b7 100644 --- a/Makefile +++ b/Makefile @@ -21,10 +21,14 @@ libstatic: config.h check: config.h cd test && $(MAKE) test.complete summary +unittest: config.h + cd unitTests && $(MAKE) test.complete summary + # Clean up clean: config.h cd src && $(MAKE) clean cd test && $(MAKE) clean + cd unitTests && $(MAKE) clean docs: src/cpptraj.Doxyfile cd src && doxygen cpptraj.Doxyfile From e14aa7ee7d6a8e52e6a86f95a155f2bf68782b74 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Fri, 5 Mar 2021 15:40:55 -0500 Subject: [PATCH 26/32] Do not need CPPTRAJSRC --- configure | 6 ++---- test/MasterTest.sh | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/configure b/configure index 8a0f7f43c4..42d9cb75d3 100755 --- a/configure +++ b/configure @@ -114,7 +114,7 @@ EXE='' # Binary executable suffix REBUILDOPT='' # Can be set to --rebuild and passed to get_library.sh BUILDTESTOPT='silent' # Set to blank to avoid asking about building libraries INSTALL_DAT='install_dat' # Target for installing data directory -CPPTRAJSRC='' # CPPTRAJ source directory +#CPPTRAJSRC='' # CPPTRAJ source directory COMPERR='cpptrajcfg.compile.err' COMPOUT='cpptrajcfg.compile.out' @@ -2260,7 +2260,7 @@ fi if [ "$WORKDIR" != '.' ] ; then Err "CPPTRAJ configure must be executed from the source directory." fi -CPPTRAJSRC=$CURRENTDIR +#CPPTRAJSRC=$CURRENTDIR # Basic checks and directives BasicChecks @@ -2527,7 +2527,6 @@ if [ "$PERFORM_CHECKS" = 'yes' ] ; then RFILE=$CPPTRAJHOME/cpptraj.sh cat > $RFILE < $RFILE < Date: Fri, 5 Mar 2021 15:52:10 -0500 Subject: [PATCH 27/32] Remove now-defunct bundled unit test stuff --- test/MasterTest.sh | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/test/MasterTest.sh b/test/MasterTest.sh index e758e1bd06..5bc6a4f1ce 100644 --- a/test/MasterTest.sh +++ b/test/MasterTest.sh @@ -553,10 +553,6 @@ EndTest() { elif [ $NUMCOMPARISONS -gt 0 ] ; then echo "All $NUMCOMPARISONS comparisons passed." OUT "All $NUMCOMPARISONS comparisons passed." - elif [ $PROGERROR -eq 0 ] ; then - # If we are here this is likely a unit test. - echo "All $PROGCOUNT executions passed." - OUT "All $PROGCOUNT executions passed." fi if [ $SKIPCOUNT -gt 0 ] ; then echo "$SKIPCOUNT comparisons skipped." @@ -1201,18 +1197,13 @@ if [ -z "$CPPTRAJ_TEST_SETUP" ] ; then #echo "DEBUG: Initial test setup." # MasterTest.sh has not been called yet; set up test environment. export CPPTRAJ_TEST_ROOT=`pwd` - # If invocation is "./RunTest.sh" or "./UnitTest.sh", individual test dir. - # If "./CpptrajTest.sh", all tests. - if [ "$0" = './RunTest.sh' -o "$0" = './UnitTest.sh' ] ; then + # If invocation is "./RunTest.sh", individual test dir. If "./CpptrajTest.sh", all tests. + if [ "$0" = './RunTest.sh' ] ; then CPPTRAJ_TEST_ROOT=`dirname $CPPTRAJ_TEST_ROOT` elif [ "$0" != './CpptrajTest.sh' ] ; then - ErrMsg "Unknown test invocation. Expected RunTest.sh, UnitTest.sh, or CpptrajTest.sh, got $0" + ErrMsg "Unknown test invocation. Expected RunTest.sh or CpptrajTest.sh, got $0" exit 1 fi - # Special case: this may be invoked from the unitTests directory. - if [ "`basename $CPPTRAJ_TEST_ROOT`" = 'unitTests' ] ; then - CPPTRAJ_TEST_ROOT=`dirname $CPPTRAJ_TEST_ROOT` - fi #echo "DEBUG: CPPTRAJ_TEST_ROOT= $CPPTRAJ_TEST_ROOT $0" # If CPPTRAJ_TEST_OS is not set, try to determine. if [ -z "$CPPTRAJ_TEST_OS" ] ; then From 8e74ff52be4c2dfb77665c830d04da0d8870d679 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Fri, 5 Mar 2021 15:54:05 -0500 Subject: [PATCH 28/32] Remove defunct unit test target --- test/Makefile | 3 --- 1 file changed, 3 deletions(-) diff --git a/test/Makefile b/test/Makefile index 41fc8a3262..8fa27ac28f 100644 --- a/test/Makefile +++ b/test/Makefile @@ -658,9 +658,6 @@ test.cpptraj: $(COMPLETETESTS) test.showerrors: $(MAKE) test.complete summary OPT="$(OPT) showerrors long" -unittests: - cd unitTests && $(MAKE) test.showerrors OPT="$(OPT)" - summary: CpptrajTest.sh MasterTest.sh @./CpptrajTest.sh summary $(OPT) From 4bb7a8833913e21f5f760161f2471293cbdc7569 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Fri, 5 Mar 2021 15:57:14 -0500 Subject: [PATCH 29/32] Add unit tests to Jenkins --- Jenkinsfile | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/Jenkinsfile b/Jenkinsfile index ddd1c4757b..ee0ac486c7 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -40,6 +40,22 @@ pipeline { } } parallel { + stage("Linux GNU Unit Tests") { + agent { + docker { + image 'ambermd/cpu-build:latest' + alwaysPull true + } + } + + steps { + unstash "source" + sh "./configure --with-netcdf --with-fftw3 gnu" + sh "cd unitTests && make test.all" + } + + post { cleanup { deleteDir() } } + } stage("Linux GNU serial build") { agent { docker { From 4bf2aabae276d5e384874e47e308d58765a8310c Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Fri, 5 Mar 2021 20:57:11 -0500 Subject: [PATCH 30/32] Hail mary - switch from openmpi to mpich to try to resolve package timeouts for GitHub Actions. --- .github/workflows/merge-gate.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/merge-gate.yml b/.github/workflows/merge-gate.yml index 093363f63e..bef6923616 100644 --- a/.github/workflows/merge-gate.yml +++ b/.github/workflows/merge-gate.yml @@ -49,9 +49,8 @@ jobs: libfftw3-dev \ netcdf-bin \ clang \ - openmpi-bin \ - openmpi-common \ - libopenmpi-dev \ + mpich \ + libmpich-dev \ cmake-data \ cmake From e3cd41d4cf5b9ac78e124e701a08a9b233e01360 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Fri, 5 Mar 2021 21:01:01 -0500 Subject: [PATCH 31/32] Another hail mary - revert to openmpi and add apt update --- .github/workflows/merge-gate.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/merge-gate.yml b/.github/workflows/merge-gate.yml index bef6923616..e204216eb6 100644 --- a/.github/workflows/merge-gate.yml +++ b/.github/workflows/merge-gate.yml @@ -41,6 +41,7 @@ jobs: steps: - name: Install prerequisite packages run: | + sudo apt update sudo apt-get install gfortran \ libbz2-dev \ libblas-dev \ @@ -49,8 +50,9 @@ jobs: libfftw3-dev \ netcdf-bin \ clang \ - mpich \ - libmpich-dev \ + openmpi-bin \ + openmpi-common \ + libopenmpi-dev \ cmake-data \ cmake From f2337267a8007184c22bcb0a82380ccf7fe6bf56 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Sat, 6 Mar 2021 06:17:56 -0500 Subject: [PATCH 32/32] Try to fix lgtm --- lgtm.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/lgtm.yml b/lgtm.yml index 54f3baab15..24eedaa2e3 100644 --- a/lgtm.yml +++ b/lgtm.yml @@ -2,6 +2,7 @@ path_classifiers: test: - "src/readline/*" - "src/tng/*" + - "unitTests/*/*" extraction: cpp: prepare: