# - Build satellites that are dependent of main library option(ADD_DISABLED_CTESTS "Add the tests which are disabled due to failed preconditions to the ctest output (this makes ctest return an error if such a test is present)" ON) mark_as_advanced(ADD_DISABLED_CTESTS) # # Enumerate all source code in a "satellite" directory such as tests/, # compile each of them and optionally set them as a test for CTest to # run. They will be linked to the main library created by the project. # # The following suffices must be defined for the opm prefix passed as # parameter: # # _LINKER_FLAGS Necessary flags to link with this library # _TARGET CMake target which creates the library # _LIBRARIES Other dependencies that must also be linked # Synopsis: # opm_compile_satellites (opm satellite excl_all test_regexp) # # Parameters: # opm Prefix of the variable which contain information # about the library these satellites depends on, e.g. # pass "opm-core" if opm-core_TARGET is the name of # the target the builds this library. Variables with # suffixes _TARGET and _LIBRARIES must exist. # # satellite Prefix of variable which contain the names of the # files, e.g. pass "tests" if the files are in the # variable tests_SOURCES. Variables with suffixes # _DATAFILES, _SOURCES and _DIR should exist. This # name is also used as name of the target that builds # all these files. # # excl_all EXCLUDE_FROM_ALL if these targets should not be built by # default, otherwise empty string. # # test_regexp Regular expression which picks the name of a test # out of the filename, or blank if no test should be # setup. # # Example: # opm_compile_satellites (opm-core test "" "^test_([^/]*)$") # macro (opm_compile_satellites opm satellite excl_all test_regexp) # if we are going to build the tests always, then make sure that # the datafiles are present too if (NOT (${excl_all} MATCHES "EXCLUDE_FROM_ALL")) set (_incl_all "ALL") else (NOT (${excl_all} MATCHES "EXCLUDE_FROM_ALL")) set (_incl_all "") endif (NOT (${excl_all} MATCHES "EXCLUDE_FROM_ALL")) # if a set of datafiles has been setup, pull those in add_custom_target (${satellite} ${_incl_all}) if (${satellite}_DATAFILES) add_dependencies (${satellite} ${${satellite}_DATAFILES}) endif (${satellite}_DATAFILES) # compile each of these separately foreach (_sat_FILE IN LISTS ${satellite}_SOURCES) get_filename_component (_sat_NAME "${_sat_FILE}" NAME_WE) add_executable (${_sat_NAME} ${excl_all} ${_sat_FILE}) add_dependencies (${satellite} ${_sat_NAME}) set_target_properties (${_sat_NAME} PROPERTIES LINK_FLAGS "${${opm}_LINKER_FLAGS_STR}" ) if(HAVE_DYNAMIC_BOOST_TEST) set_target_properties (${_sat_NAME} PROPERTIES COMPILE_DEFINITIONS BOOST_TEST_DYN_LINK ) endif() # are we building a test? luckily, the testing framework doesn't # require anything else, so we don't have to figure out where it # should go in the library list if (NOT "${test_regexp}" STREQUAL "") set (_test_lib "${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}") else (NOT "${test_regexp}" STREQUAL "") set (_test_lib "") add_static_analysis_tests(_sat_FILE ${opm}_INCLUDE_DIRS) endif (NOT "${test_regexp}" STREQUAL "") target_link_libraries (${_sat_NAME} ${${opm}_TARGET} ${${opm}_LIBRARIES} ${_test_lib}) if (STRIP_DEBUGGING_SYMBOLS) strip_debug_symbols (${_sat_NAME} _sat_DEBUG) list (APPEND ${satellite}_DEBUG ${_sat_DEBUG}) endif() # variable with regular expression doubles as a flag for # whether tests should be setup or not set(_sat_FANCY) if (NOT "${test_regexp}" STREQUAL "") foreach (_regexp IN ITEMS ${test_regexp}) if ("${_sat_NAME}" MATCHES "${_regexp}") string (REGEX REPLACE "${_regexp}" "\\1" _sat_FANCY "${_sat_NAME}") elseif(NOT _sat_FANCY) set(_sat_FANCY ${_sat_NAME}) endif() endforeach (_regexp) get_target_property (_sat_LOC ${_sat_NAME} LOCATION) # Run tests through mpi-run. Ubuntu 14.04 provided mpi libs will crash # in the MPI_Finalize() call otherwise. if(MPI_FOUND) set(_sat_LOC ${MPIEXEC} ${MPIEXEC_NUMPROC_FLAG} 1 ${_sat_LOC}) endif() if (CMAKE_VERSION VERSION_LESS "2.8.4") add_test ( NAME ${_sat_FANCY} COMMAND ${CMAKE_COMMAND} -E chdir "${PROJECT_BINARY_DIR}/${${satellite}_DIR}" ${_sat_LOC} ) else (CMAKE_VERSION VERSION_LESS "2.8.4") add_test (${_sat_FANCY} ${_sat_LOC}) # run the test in the directory where the data files are set_tests_properties (${_sat_FANCY} PROPERTIES WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/${${satellite}_DIR} ) endif (CMAKE_VERSION VERSION_LESS "2.8.4") if(NOT TARGET test-suite) add_custom_target(test-suite) endif() add_dependencies(test-suite "${_sat_NAME}") endif(NOT "${test_regexp}" STREQUAL "") # if this program on the list of files that should be distributed? # we check by the name of the source file list (FIND ${satellite}_SOURCES_DIST "${_sat_FILE}" _is_util) if (NOT (_is_util EQUAL -1)) install (TARGETS ${_sat_NAME} RUNTIME DESTINATION bin${${opm}_VER_DIR}/ ) endif (NOT (_is_util EQUAL -1)) endforeach (_sat_FILE) endmacro (opm_compile_satellites opm prefix) # Synopsis: # opm_data (satellite target dirname files) # # provides these output variables: # # ${satellite}_INPUT_FILES List of all files that are copied # ${satellite}_DATAFILES Name of target which copies these files # # Example: # # opm_data (tests datafiles "tests/") # macro (opm_data satellite target dirname) # even if there are no datafiles, create the directory so the # satellite programs have a homedir to run in execute_process ( COMMAND ${CMAKE_COMMAND} -E make_directory ${PROJECT_BINARY_DIR}/${dirname} ) # if ever huge test datafiles are necessary, then change this # into "create_symlink" (on UNIX only, apparently) set (make_avail "copy") # provide datafiles as inputs for the tests, by copying them # to a tests/ directory in the output tree (if different) set (${satellite}_INPUT_FILES) if (NOT PROJECT_SOURCE_DIR STREQUAL PROJECT_BINARY_DIR) foreach (input_datafile IN LISTS ${satellite}_DATA) file (RELATIVE_PATH rel_datafile "${PROJECT_SOURCE_DIR}" ${input_datafile}) set (output_datafile "${PROJECT_BINARY_DIR}/${rel_datafile}") add_custom_command ( OUTPUT ${output_datafile} COMMAND ${CMAKE_COMMAND} ARGS -E ${make_avail} ${input_datafile} ${output_datafile} DEPENDS ${input_datafile} VERBATIM ) list (APPEND ${satellite}_INPUT_FILES "${output_datafile}") endforeach (input_datafile) endif(NOT PROJECT_SOURCE_DIR STREQUAL PROJECT_BINARY_DIR) # setup a target which does all the copying set (${satellite}_DATAFILES "${target}") add_custom_target (${${satellite}_DATAFILES} DEPENDS ${${satellite}_INPUT_FILES} COMMENT "Making \"${satellite}\" data available in output tree" ) if(NOT TARGET test-suite) add_custom_target(test-suite) endif() add_dependencies(test-suite ${${satellite}_DATAFILES}) endmacro (opm_data satellite target dirname files) # Add a single unit test (can be orchestrated by the 'ctest' command) # # Synopsis: # opm_add_test(TestName) # # Parameters: # TestName Name of test # ONLY_COMPILE Only build test but do not run it (optional) # DEFAULT_ENABLE_IF Only enable by default if a given condition is true (optional) # ALWAYS_ENABLE Force enabling test even if -DBUILD_TESTING=OFF was set (optional) # EXE_NAME Name of test executable (optional, default: ./bin/${TestName}) # CONDITION Condition to enable test (optional, cmake code) # DEPENDS Targets which the test depends on (optional) # DRIVER The script which supervises the test (optional, default: ${OPM_TEST_DRIVER}) # DRIVER_ARGS The script which supervises the test (optional, default: ${OPM_TEST_DRIVER_ARGS}) # TEST_ARGS Arguments to pass to test's binary (optional, default: empty) # SOURCES Source files for the test (optional, default: ${EXE_NAME}.cpp) # PROCESSORS Number of processors to run test on (optional, default: 1) # TEST_DEPENDS Other tests which must be run before running this test (optional, default: None) # LIBRARIES Libraries to link test against (optional) # WORKING_DIRECTORY Working directory for test (optional, default: ${PROJECT_BINARY_DIR}) # # Example: # # opm_add_test(funky_test # ALWAYS_ENABLE # CONDITION FUNKY_GRID_FOUND # SOURCES tests/MyFunkyTest.cpp # LIBRARIES -lgmp -lm) include(CMakeParseArguments) macro(opm_add_test TestName) cmake_parse_arguments(CURTEST "NO_COMPILE;ONLY_COMPILE;ALWAYS_ENABLE" # flags "EXE_NAME;PROCESSORS;WORKING_DIRECTORY" # one value args "CONDITION;DEFAULT_ENABLE_IF;TEST_DEPENDS;DRIVER;DRIVER_ARGS;DEPENDS;TEST_ARGS;SOURCES;LIBRARIES" # multi-value args ${ARGN}) set(BUILD_TESTING "${BUILD_TESTING}") # set the default values for optional parameters if (NOT CURTEST_EXE_NAME) set(CURTEST_EXE_NAME ${TestName}) endif() # Strip test_ prefix from name if ("${TestName}" MATCHES "^test_([^/]*)$") string (REGEX REPLACE "^test_([^/]*)$" "\\1" _FANCY "${TestName}") else() set(_FANCY ${TestName}) endif() # try to auto-detect the name of the source file if SOURCES are not # explicitly specified. if (NOT CURTEST_SOURCES) set(CURTEST_SOURCES "") set(_SDir "${PROJECT_SOURCE_DIR}") foreach(CURTEST_CANDIDATE "${CURTEST_EXE_NAME}.cpp" "${CURTEST_EXE_NAME}.cc" "tests/${CURTEST_EXE_NAME}.cpp" "tests/${CURTEST_EXE_NAME}.cc") if (EXISTS "${_SDir}/${CURTEST_CANDIDATE}") set(CURTEST_SOURCES "${_SDir}/${CURTEST_CANDIDATE}") endif() endforeach() endif() # the default working directory is the content of # OPM_TEST_DEFAULT_WORKING_DIRECTORY or the source directory if this # is unspecified if (NOT CURTEST_WORKING_DIRECTORY) if (OPM_TEST_DEFAULT_WORKING_DIRECTORY) set(CURTEST_WORKING_DIRECTORY ${OPM_TEST_DEFAULT_WORKING_DIRECTORY}) else() set(CURTEST_WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}) endif() endif() # don't build the tests by _default_ if BUILD_TESTING is false, # i.e., when typing 'make' the tests are not build in that # case. They can still be build using 'make test-suite' and they can # be build and run using 'make check' set(CURTEST_EXCLUDE_FROM_ALL "") if (NOT "AND OR ${CURTEST_DEFAULT_ENABLE_IF}" STREQUAL "AND OR ") if (NOT ${CURTEST_DEFAULT_ENABLE_IF}) set(CURTEST_EXCLUDE_FROM_ALL "EXCLUDE_FROM_ALL") endif() endif() if (NOT BUILD_TESTING AND NOT CURTEST_ALWAYS_ENABLE) set(CURTEST_EXCLUDE_FROM_ALL "EXCLUDE_FROM_ALL") endif() # figure out the test driver script and its arguments. (the variable # for the driver script may be empty. In this case the binary is run # "bare metal".) if (NOT CURTEST_DRIVER) set(CURTEST_DRIVER "${OPM_TEST_DRIVER}") endif() if (NOT CURTEST_DRIVER_ARGS) set(CURTEST_DRIVER_ARGS "${OPM_TEST_DRIVER_ARGS}") endif() # the libraries to link against if (NOT CURTEST_LIBRARIES) SET(CURTEST_LIBRARIES "${${project}_LIBRARIES}") endif() # determine if the test should be completely ignored, i.e., the # CONDITION argument evaluates to false. the "AND OR " is a hack # which is required to prevent CMake from evaluating the condition # in the string. (which might evaluate to an empty string even # though "${CURTEST_CONDITION}" is not empty.) if ("AND OR ${CURTEST_CONDITION}" STREQUAL "AND OR ") set(SKIP_CUR_TEST "0") elseif(${CURTEST_CONDITION}) set(SKIP_CUR_TEST "0") else() set(SKIP_CUR_TEST "1") endif() if (NOT SKIP_CUR_TEST) if (CURTEST_ONLY_COMPILE) # only compile the binary but do not run it as a test add_executable("${CURTEST_EXE_NAME}" ${CURTEST_EXCLUDE_FROM_ALL} ${CURTEST_SOURCES}) target_link_libraries (${CURTEST_EXE_NAME} ${CURTEST_LIBRARIES}) if(TARGET ${project}_prepare) add_dependencies("${CURTEST_EXE_NAME}" ${project}_prepare) endif() if(CURTEST_DEPENDS) add_dependencies("${CURTEST_EXE_NAME}" ${CURTEST_DEPENDS}) endif() else() if (NOT CURTEST_NO_COMPILE) # in addition to being run, the test must be compiled. (the # run-only case occurs if the binary is already compiled by an # earlier test.) add_executable("${CURTEST_EXE_NAME}" ${CURTEST_EXCLUDE_FROM_ALL} ${CURTEST_SOURCES}) if(HAVE_DYNAMIC_BOOST_TEST) set_target_properties (${CURTEST_EXE_NAME} PROPERTIES COMPILE_DEFINITIONS BOOST_TEST_DYN_LINK ) endif() target_link_libraries (${CURTEST_EXE_NAME} ${CURTEST_LIBRARIES}) if(CURTEST_DEPENDS) add_dependencies("${CURTEST_EXE_NAME}" ${CURTEST_DEPENDS}) endif() if(TARGET ${project}_prepare) add_dependencies("${CURTEST_EXE_NAME}" ${project}_prepare) endif() endif() # figure out how the test should be run. if a test driver script # has been specified to supervise the test binary, use it else # run the test binary "naked". if (CURTEST_DRIVER) set(CURTEST_COMMAND ${CURTEST_DRIVER} ${CURTEST_DRIVER_ARGS} ${CURTEST_EXE_NAME} ${CURTEST_TEST_ARGS}) else() set(CURTEST_COMMAND ${PROJECT_BINARY_DIR}/bin/${CURTEST_EXE_NAME}) if (CURTEST_TEST_ARGS) list(APPEND CURTEST_COMMAND ${CURTEST_TEST_ARGS}) endif() endif() add_test(NAME ${_FANCY} WORKING_DIRECTORY "${CURTEST_WORKING_DIRECTORY}" COMMAND ${CURTEST_COMMAND}) # specify the dependencies between the tests if (CURTEST_TEST_DEPENDS) set_tests_properties(${_FANCY} PROPERTIES DEPENDS "${CURTEST_TEST_DEPENDS}") endif() # tell ctest how many cores it should reserve to run the test if (CURTEST_PROCESSORS) set_tests_properties(${_FANCY} PROPERTIES PROCESSORS "${CURTEST_PROCESSORS}") endif() endif() if (NOT CURTEST_NO_COMPILE) if(NOT TARGET test-suite) add_custom_target(test-suite) endif() add_dependencies(test-suite "${CURTEST_EXE_NAME}") endif() else() # test is skipped # the following causes the test to appear as 'skipped' in the # CDash dashboard. it this is removed, the test is just silently # ignored. if (NOT CURTEST_ONLY_COMPILE AND ADD_DISABLED_CTESTS) add_test(${_FANCY} skip_test_dummy) endif() endif() endmacro() # macro to set the default test driver script and the its default # arguments macro(opm_set_test_driver DriverBinary DriverDefaultArgs) set(OPM_TEST_DRIVER "${DriverBinary}") set(OPM_TEST_DRIVER_ARGS "${DriverDefaultArgs}") endmacro() # macro to set the default test driver script and the its default # arguments macro(opm_set_test_default_working_directory Dir) set(OPM_TEST_DEFAULT_WORKING_DIRECTORY "${Dir}") endmacro()