if (BUILD_TESTING)
add_subdirectory(src/external/gmock-1.6.0)
endif (BUILD_TESTING)
+set(MEMORYCHECK_SUPPRESSIONS_FILE ${CMAKE_SOURCE_DIR}/cmake/legacy_and_external.supp)
find_package(Doxygen)
fi
CC=gcc-${CompilerVersion} CXX=g++-${CompilerVersion} cmake -D GMX_DOUBLE=${GMX_DOUBLE} -D GMX_MPI=${GMX_MPI} -D GMX_OPENMP=${GMX_OPENMP} -DGMX_DEFAULT_SUFFIX=off -DCMAKE_BUILD_TYPE=Debug . &&
make &&
-ctest -D ExperimentalTest -V
+ctest -D ExperimentalMemCheck -L GTest -V #TODO parse valgrind output and show on website
+ctest -D ExperimentalTest -LE GTest -V #TODO valgrind should be run for integration tests but with leak-check=no
--- /dev/null
+# This suppression file is used to run the C++ Unit Tests
+# All problems in external libraries are excluded
+# Memory leaks in the legacy code are excluded
+# Other problems besides memory leaks should NOT be excluded for legacy code
+
+{
+ libz
+ Memcheck:Cond
+ fun:inflateReset2
+ fun:inflateInit2_
+}
+
+{
+ gmx_fio_open1
+ Memcheck:Leak
+ fun:calloc
+ fun:save_calloc
+ fun:gmx_fio_open
+}
+
+{
+ gmx_fio_open2
+ Memcheck:Leak
+ fun:malloc
+ fun:strdup
+ fun:gmx_fio_open
+}
+
+{
+ gmx_fio_open3
+ Memcheck:Leak
+ fun:calloc
+ fun:save_calloc
+ fun:gmx_fio_make_dummy
+ fun:gmx_fio_insert
+ fun:gmx_fio_open
+}
+
+{
+ put_symtab1
+ Memcheck:Leak
+ fun:malloc
+ fun:strdup
+ fun:enter_buf
+ fun:put_symtab
+}
+
+{
+ put_symtab2
+ Memcheck:Leak
+ fun:calloc
+ fun:save_calloc
+ fun:new_symbuf
+ fun:enter_buf
+ fun:put_symtab
+}
+
+{
+ tMPI_init_once
+ Memcheck:Leak
+ fun:malloc
+ fun:tMPI_Malloc
+ fun:tMPI_Thread_mutex_init_once
+ fun:tMPI_Thread_mutex_lock
+}
+
+{
+ get_w_conf
+ Memcheck:Leak
+ fun:calloc
+ fun:save_calloc
+ fun:get_w_conf
+}
+
+{
+ read_tps_conf
+ Memcheck:Leak
+ fun:calloc
+ fun:save_calloc
+ fun:read_tps_conf
+}
+
std::auto_ptr<AnalysisDataHandle> handle(new AnalysisDataHandle(this));
_impl->_handles.push_back(handle.get());
+ size_t oldSize = _impl->_pending.size();
_impl->_pending.resize(2 * _impl->_handles.size() - 1);
Impl::FrameList::iterator i;
- for (i = _impl->_pending.begin(); i != _impl->_pending.end(); ++i)
+ for (i = _impl->_pending.begin() + oldSize; i != _impl->_pending.end(); ++i)
{
*i = new AnalysisDataFrame();
(*i)->allocate(columnCount());
/** Frees memory allocated for the selection scanner. */
void
_gmx_sel_free_lexer(yyscan_t scanner);
+/** Sets the error reporter object for the selection scanner. */
+void
+_gmx_sel_set_lexer_error_reporter(yyscan_t scanner,
+ gmx::MessageStringCollector *errors);
/** Returns true if the scanner is interactive. */
bool
#include "gromacs/fatalerror/errorcodes.h"
#include "gromacs/fatalerror/exceptions.h"
+#include "gromacs/fatalerror/gmxassert.h"
#include "gromacs/fatalerror/messagestringcollector.h"
#include "gromacs/selection/selmethod.h"
GMX_THROW(gmx::InternalError("Lexer initialization failed"));
}
- gmx::MessageStringCollector *errors = new gmx::MessageStringCollector;
-
snew(state, 1);
state->sc = sc;
- state->errors = errors;
+ state->errors = NULL;
state->bGroups = bGroups;
state->grps = grps;
state->nexpsel = (maxnr > 0 ? sc->sel.size() + maxnr : -1);
_gmx_sel_yylex_destroy(scanner);
}
+void
+_gmx_sel_set_lexer_error_reporter(yyscan_t scanner,
+ gmx::MessageStringCollector *errors)
+{
+ gmx_sel_lexer_t *state = _gmx_sel_yyget_extra(scanner);
+ state->errors = errors;
+}
+
bool
_gmx_sel_is_lexer_interactive(yyscan_t scanner)
{
_gmx_sel_lexer_error_reporter(yyscan_t scanner)
{
gmx_sel_lexer_t *state = _gmx_sel_yyget_extra(scanner);
+ GMX_RELEASE_ASSERT(state->errors != NULL, "Error reporter not set");
return state->errors;
}
std::vector<Selection *> *output)
{
gmx_ana_selcollection_t *sc = &_sc;
- MessageStringCollector *errors = _gmx_sel_lexer_error_reporter(scanner);
GMX_ASSERT(sc == _gmx_sel_lexer_selcollection(scanner),
"Incorrectly initialized lexer");
+ MessageStringCollector errors;
+ _gmx_sel_set_lexer_error_reporter(scanner, &errors);
+
int oldCount = sc->sel.size();
int bOk = !_gmx_sel_yybparse(scanner);
_gmx_sel_free_lexer(scanner);
if (maxnr > 0 && nr != maxnr)
{
bOk = false;
- errors->append("Too few selections provided");
+ errors.append("Too few selections provided");
}
if (bOk)
}
}
- if (!bOk || !errors->isEmpty())
+ if (!bOk || !errors.isEmpty())
{
- GMX_ASSERT(!bOk && !errors->isEmpty(), "Inconsistent error reporting");
- GMX_THROW(InvalidInputError(errors->toString()));
+ GMX_ASSERT(!bOk && !errors.isEmpty(), "Inconsistent error reporting");
+ GMX_THROW(InvalidInputError(errors.toString()));
}
}
{
_impl->runParser(scanner, -1, output);
}
- catch (std::exception &)
+ catch (...)
{
ffclose(fp);
throw;
include_directories(${GTEST_INCLUDE_DIRS})
list(APPEND COMMON_SOURCES refdata.cpp)
set(TESTUTILS_HAVE_REFDATA TRUE)
+ add_definitions(-DTESTUTILS_HAVE_REFDATA)
endif ()
add_library(testutils STATIC ${COMMON_SOURCES})
set(TESTUTILS_LIBS testutils)
target_link_libraries(testutils libgromacs)
-if (GMX_USE_GTEST AND LIBXML2_FOUND)
+if (TESTUTILS_HAVE_REFDATA)
list(APPEND TESTUTILS_LIBS ${GTEST_LIBRARIES} ${LIBXML2_LIBRARIES})
target_link_libraries(testutils ${GTEST_LIBRARIES} ${LIBXML2_LIBRARIES})
endif ()
set_target_properties(${EXENAME} PROPERTIES COMPILE_DEFINITIONS ${DEFS})
add_test(NAME ${NAME}
COMMAND ${EXENAME} --gtest_output=xml:${CMAKE_BINARY_DIR}/Testing/Temporary/${EXENAME}.xml)
+ set_tests_properties(${NAME} PROPERTIES LABELS "GTest")
endif ()
endfunction ()
set_target_properties(${EXENAME} PROPERTIES COMPILE_DEFINITIONS ${DEFS})
add_test(NAME ${NAME}
COMMAND ${EXENAME} --gtest_output=xml:${CMAKE_BINARY_DIR}/Testing/Temporary/${EXENAME}.xml)
+ set_tests_properties(${NAME} PROPERTIES LABELS "GTest")
endif ()
endfunction ()
}
}
*argc = newi;
+#ifdef TESTUTILS_HAVE_REFDATA
+ internal::addGlobalReferenceDataEnvironment();
+#endif
return 0;
}
#include "refdata-impl.h"
+namespace
+{
+
+class TestReferenceDataEnvironment : public ::testing::Environment
+{
+ public:
+ virtual void TearDown()
+ {
+ xmlCleanupParser();
+ }
+};
+
+} // namespace
+
namespace gmx
{
namespace test
{
+namespace internal
+{
+
+void addGlobalReferenceDataEnvironment()
+{
+ ::testing::AddGlobalTestEnvironment(new TestReferenceDataEnvironment);
+}
+
+} // namespace internal
+
/********************************************************************
* TestReferenceData::Impl
*/
* can be used to change it.
* Recognized command-line arguments are removed from the list.
*
- * Also creates the directory for storing the reference data.
- *
* This function is automatically called by test_main_gtest.cpp and
* test_main_gmock.cpp.
*/
int initReferenceData(int *argc, char **argv);
+namespace internal
+{
+
+/*! \internal \brief
+ * Adds a global test teardown method for freeing libxml2 internal data.
+ *
+ * This method is called by initReferenceData(), and should not be called
+ * directly.
+ * It adds a global test environment object that calls xmlCleanupParser() at
+ * the end of all tests. This makes memory reports from valgrind cleaner since
+ * otherwise they show the memory as "still reachable".
+ */
+void addGlobalReferenceDataEnvironment();
+
+} // namespace internal
+
+
class TestReferenceChecker;
/*! \libinternal \brief