diff options
author | Brad King <brad.king@kitware.com> | 2020-03-30 17:26:20 (GMT) |
---|---|---|
committer | Kitware Robot <kwrobot@kitware.com> | 2020-03-30 17:26:49 (GMT) |
commit | cfa3a2342f01ada6278bccf4c151b0e1e88798c4 (patch) | |
tree | ef66407117ebe4d12b9cec638657b2a07cc8795e /Modules | |
parent | e20146b429afb12950a20adef83c73d36a74e558 (diff) | |
parent | 3b4838b57fc70bd64b29044ccbdf582f14a0574d (diff) | |
download | CMake-cfa3a2342f01ada6278bccf4c151b0e1e88798c4.zip CMake-cfa3a2342f01ada6278bccf4c151b0e1e88798c4.tar.gz CMake-cfa3a2342f01ada6278bccf4c151b0e1e88798c4.tar.bz2 |
Merge topic 'gtest_discover_tests_cross_compile_support'
3b4838b57f GoogleTest: Add tests for MultiConfig discovery in PRE_TEST mode
1ba4cb565e GoogleTest: Parameterize tests to check PRE_TEST/POST_BUILD discovery mode
75e82a13db GoogleTest: Add new DISCOVERY_MODE option to gtest_discover_tests
889a7146ff GoogleTestAddTests: Refactor into callable method
Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !4078
Diffstat (limited to 'Modules')
-rw-r--r-- | Modules/GoogleTest.cmake | 133 | ||||
-rw-r--r-- | Modules/GoogleTestAddTests.cmake | 220 |
2 files changed, 229 insertions, 124 deletions
diff --git a/Modules/GoogleTest.cmake b/Modules/GoogleTest.cmake index 1d4398e..975ce6c 100644 --- a/Modules/GoogleTest.cmake +++ b/Modules/GoogleTest.cmake @@ -152,6 +152,7 @@ same as the Google Test name (i.e. ``suite.testcase``); see also [TEST_LIST var] [DISCOVERY_TIMEOUT seconds] [XML_OUTPUT_DIR dir] + [DISCOVERY_MODE <POST_BUILD|PRE_TEST>] ) ``gtest_discover_tests`` sets up a post-build command on the test executable @@ -244,6 +245,22 @@ same as the Google Test name (i.e. ``suite.testcase``); see also ``EXTRA_ARGS --gtest_output=xml`` to avoid race conditions writing the XML result output when using parallel test execution. + ``DISCOVERY_MODE`` + Provides greater control over when ``gtest_discover_tests``performs test + discovery. By default, ``POST_BUILD`` sets up a post-build command + to perform test discovery at build time. In certain scenarios, like + cross-compiling, this ``POST_BUILD`` behavior is not desirable. + By contrast, ``PRE_TEST`` delays test discovery until just prior to test + execution. This way test discovery occurs in the target environment + where the test has a better chance at finding appropriate runtime + dependencies. + + ``DISCOVERY_MODE`` defaults to the value of the + ``CMAKE_GTEST_DISCOVER_TESTS_DISCOVERY_MODE`` variable if it is not + passed when calling ``gtest_discover_tests``. This provides a mechanism + for globally selecting a preferred test discovery behavior without having + to modify each call site. + #]=======================================================================] # Save project's policies @@ -376,11 +393,12 @@ function(gtest_add_tests) endfunction() #------------------------------------------------------------------------------ + function(gtest_discover_tests TARGET) cmake_parse_arguments( "" "NO_PRETTY_TYPES;NO_PRETTY_VALUES" - "TEST_PREFIX;TEST_SUFFIX;WORKING_DIRECTORY;TEST_LIST;DISCOVERY_TIMEOUT;XML_OUTPUT_DIR" + "TEST_PREFIX;TEST_SUFFIX;WORKING_DIRECTORY;TEST_LIST;DISCOVERY_TIMEOUT;XML_OUTPUT_DIR;DISCOVERY_MODE" "EXTRA_ARGS;PROPERTIES" ${ARGN} ) @@ -394,6 +412,12 @@ function(gtest_discover_tests TARGET) if(NOT _DISCOVERY_TIMEOUT) set(_DISCOVERY_TIMEOUT 5) endif() + if(NOT _DISCOVERY_MODE) + if(NOT CMAKE_GTEST_DISCOVER_TESTS_DISCOVERY_MODE) + set(CMAKE_GTEST_DISCOVER_TESTS_DISCOVERY_MODE "POST_BUILD") + endif() + set(_DISCOVERY_MODE ${CMAKE_GTEST_DISCOVER_TESTS_DISCOVERY_MODE}) + endif() get_property( has_counter @@ -425,35 +449,86 @@ function(gtest_discover_tests TARGET) TARGET ${TARGET} PROPERTY CROSSCOMPILING_EMULATOR ) - add_custom_command( - TARGET ${TARGET} POST_BUILD - BYPRODUCTS "${ctest_tests_file}" - COMMAND "${CMAKE_COMMAND}" - -D "TEST_TARGET=${TARGET}" - -D "TEST_EXECUTABLE=$<TARGET_FILE:${TARGET}>" - -D "TEST_EXECUTOR=${crosscompiling_emulator}" - -D "TEST_WORKING_DIR=${_WORKING_DIRECTORY}" - -D "TEST_EXTRA_ARGS=${_EXTRA_ARGS}" - -D "TEST_PROPERTIES=${_PROPERTIES}" - -D "TEST_PREFIX=${_TEST_PREFIX}" - -D "TEST_SUFFIX=${_TEST_SUFFIX}" - -D "NO_PRETTY_TYPES=${_NO_PRETTY_TYPES}" - -D "NO_PRETTY_VALUES=${_NO_PRETTY_VALUES}" - -D "TEST_LIST=${_TEST_LIST}" - -D "CTEST_FILE=${ctest_tests_file}" - -D "TEST_DISCOVERY_TIMEOUT=${_DISCOVERY_TIMEOUT}" - -D "TEST_XML_OUTPUT_DIR=${_XML_OUTPUT_DIR}" - -P "${_GOOGLETEST_DISCOVER_TESTS_SCRIPT}" - VERBATIM - ) - file(WRITE "${ctest_include_file}" - "if(EXISTS \"${ctest_tests_file}\")\n" - " include(\"${ctest_tests_file}\")\n" - "else()\n" - " add_test(${TARGET}_NOT_BUILT ${TARGET}_NOT_BUILT)\n" - "endif()\n" - ) + if(_DISCOVERY_MODE STREQUAL "POST_BUILD") + add_custom_command( + TARGET ${TARGET} POST_BUILD + BYPRODUCTS "${ctest_tests_file}" + COMMAND "${CMAKE_COMMAND}" + -D "TEST_TARGET=${TARGET}" + -D "TEST_EXECUTABLE=$<TARGET_FILE:${TARGET}>" + -D "TEST_EXECUTOR=${crosscompiling_emulator}" + -D "TEST_WORKING_DIR=${_WORKING_DIRECTORY}" + -D "TEST_EXTRA_ARGS=${_EXTRA_ARGS}" + -D "TEST_PROPERTIES=${_PROPERTIES}" + -D "TEST_PREFIX=${_TEST_PREFIX}" + -D "TEST_SUFFIX=${_TEST_SUFFIX}" + -D "NO_PRETTY_TYPES=${_NO_PRETTY_TYPES}" + -D "NO_PRETTY_VALUES=${_NO_PRETTY_VALUES}" + -D "TEST_LIST=${_TEST_LIST}" + -D "CTEST_FILE=${ctest_tests_file}" + -D "TEST_DISCOVERY_TIMEOUT=${_DISCOVERY_TIMEOUT}" + -D "TEST_XML_OUTPUT_DIR=${_XML_OUTPUT_DIR}" + -P "${_GOOGLETEST_DISCOVER_TESTS_SCRIPT}" + VERBATIM + ) + + file(WRITE "${ctest_include_file}" + "if(EXISTS \"${ctest_tests_file}\")\n" + " include(\"${ctest_tests_file}\")\n" + "else()\n" + " add_test(${TARGET}_NOT_BUILT ${TARGET}_NOT_BUILT)\n" + "endif()\n" + ) + elseif(_DISCOVERY_MODE STREQUAL "PRE_TEST") + + get_property(GENERATOR_IS_MULTI_CONFIG GLOBAL + PROPERTY GENERATOR_IS_MULTI_CONFIG + ) + + if(GENERATOR_IS_MULTI_CONFIG) + set(ctest_tests_file "${ctest_file_base}_tests-$<CONFIG>.cmake") + endif() + + string(CONCAT ctest_include_content + "if(EXISTS \"$<TARGET_FILE:${TARGET}>\")" "\n" + " if(\"$<TARGET_FILE:${TARGET}>\" IS_NEWER_THAN \"${ctest_tests_file}\")" "\n" + " include(GoogleTestAddTests)" "\n" + " gtest_discover_tests_impl(" "\n" + " TEST_EXECUTABLE" " [==[" "$<TARGET_FILE:${TARGET}>" "]==]" "\n" + " TEST_EXECUTOR" " [==[" "${crosscompiling_emulator}" "]==]" "\n" + " TEST_WORKING_DIR" " [==[" "${_WORKING_DIRECTORY}" "]==]" "\n" + " TEST_EXTRA_ARGS" " [==[" "${_EXTRA_ARGS}" "]==]" "\n" + " TEST_PROPERTIES" " [==[" "${_PROPERTIES}" "]==]" "\n" + " TEST_PREFIX" " [==[" "${_TEST_PREFIX}" "]==]" "\n" + " TEST_SUFFIX" " [==[" "${_TEST_SUFFIX}" "]==]" "\n" + " NO_PRETTY_TYPES" " [==[" "${_NO_PRETTY_TYPES}" "]==]" "\n" + " NO_PRETTY_VALUES" " [==[" "${_NO_PRETTY_VALUES}" "]==]" "\n" + " TEST_LIST" " [==[" "${_TEST_LIST}" "]==]" "\n" + " CTEST_FILE" " [==[" "${ctest_tests_file}" "]==]" "\n" + " TEST_DISCOVERY_TIMEOUT" " [==[" "${_DISCOVERY_TIMEOUT}" "]==]" "\n" + " TEST_XML_OUTPUT_DIR" " [==[" "${_XML_OUTPUT_DIR}" "]==]" "\n" + " )" "\n" + " endif()" "\n" + " include(\"${ctest_tests_file}\")" "\n" + "else()" "\n" + " add_test(${TARGET}_NOT_BUILT ${TARGET}_NOT_BUILT)" "\n" + "endif()" "\n" + ) + + if(GENERATOR_IS_MULTI_CONFIG) + foreach(_config ${CMAKE_CONFIGURATION_TYPES}) + file(GENERATE OUTPUT "${ctest_file_base}_include-${_config}.cmake" CONTENT "${ctest_include_content}" CONDITION $<CONFIG:${_config}>) + endforeach() + file(WRITE "${ctest_include_file}" "include(\"${ctest_file_base}_include-\${CTEST_CONFIGURATION_TYPE}.cmake\")") + else() + file(GENERATE OUTPUT "${ctest_file_base}_include.cmake" CONTENT "${ctest_include_content}") + file(WRITE "${ctest_include_file}" "include(\"${ctest_file_base}_include.cmake\")") + endif() + + else() + message(SEND_ERROR "Unknown DISCOVERY_MODE: ${_DISCOVERY_MODE}") + endif() # Add discovered tests to directory TEST_INCLUDE_FILES set_property(DIRECTORY diff --git a/Modules/GoogleTestAddTests.cmake b/Modules/GoogleTestAddTests.cmake index 753319f..65af4c2 100644 --- a/Modules/GoogleTestAddTests.cmake +++ b/Modules/GoogleTestAddTests.cmake @@ -3,21 +3,12 @@ cmake_minimum_required(VERSION ${CMAKE_VERSION}) -set(prefix "${TEST_PREFIX}") -set(suffix "${TEST_SUFFIX}") -set(extra_args ${TEST_EXTRA_ARGS}) -set(properties ${TEST_PROPERTIES}) -set(script) -set(suite) -set(tests) -set(tests_buffer) - -# Overwrite possibly existing ${CTEST_FILE} with empty file +# Overwrite possibly existing ${_CTEST_FILE} with empty file set(flush_tests_MODE WRITE) -# Flushes script to ${CTEST_FILE} +# Flushes script to ${_CTEST_FILE} macro(flush_script) - file(${flush_tests_MODE} "${CTEST_FILE}" "${script}") + file(${flush_tests_MODE} "${_CTEST_FILE}" "${script}") set(flush_tests_MODE APPEND) set(script "") @@ -48,98 +39,137 @@ macro(add_command NAME) unset(_script_len) endmacro() -# Run test executable to get list of available tests -if(NOT EXISTS "${TEST_EXECUTABLE}") - message(FATAL_ERROR - "Specified test executable does not exist.\n" - " Path: '${TEST_EXECUTABLE}'" +function(gtest_discover_tests_impl) + + cmake_parse_arguments( + "" + "" + "NO_PRETTY_TYPES;NO_PRETTY_VALUES;TEST_EXECUTABLE;TEST_EXECUTOR;TEST_WORKING_DIR;TEST_PREFIX;TEST_SUFFIX;TEST_LIST;CTEST_FILE;TEST_DISCOVERY_TIMEOUT;TEST_XML_OUTPUT_DIR" + "TEST_EXTRA_ARGS;TEST_PROPERTIES" + ${ARGN} ) -endif() -execute_process( - COMMAND ${TEST_EXECUTOR} "${TEST_EXECUTABLE}" --gtest_list_tests - WORKING_DIRECTORY "${TEST_WORKING_DIR}" - TIMEOUT ${TEST_DISCOVERY_TIMEOUT} - OUTPUT_VARIABLE output - RESULT_VARIABLE result -) -if(NOT ${result} EQUAL 0) - string(REPLACE "\n" "\n " output "${output}") - message(FATAL_ERROR - "Error running test executable.\n" - " Path: '${TEST_EXECUTABLE}'\n" - " Result: ${result}\n" - " Output:\n" - " ${output}\n" + + set(prefix "${_TEST_PREFIX}") + set(suffix "${_TEST_SUFFIX}") + set(extra_args ${_TEST_EXTRA_ARGS}) + set(properties ${_TEST_PROPERTIES}) + set(script) + set(suite) + set(tests) + set(tests_buffer) + + # Run test executable to get list of available tests + if(NOT EXISTS "${_TEST_EXECUTABLE}") + message(FATAL_ERROR + "Specified test executable does not exist.\n" + " Path: '${_TEST_EXECUTABLE}'" + ) + endif() + execute_process( + COMMAND ${_TEST_EXECUTOR} "${_TEST_EXECUTABLE}" --gtest_list_tests + WORKING_DIRECTORY "${_TEST_WORKING_DIR}" + TIMEOUT ${_TEST_DISCOVERY_TIMEOUT} + OUTPUT_VARIABLE output + RESULT_VARIABLE result ) -endif() + if(NOT ${result} EQUAL 0) + string(REPLACE "\n" "\n " output "${output}") + message(FATAL_ERROR + "Error running test executable.\n" + " Path: '${_TEST_EXECUTABLE}'\n" + " Result: ${result}\n" + " Output:\n" + " ${output}\n" + ) + endif() -string(REPLACE "\n" ";" output "${output}") - -# Parse output -foreach(line ${output}) - # Skip header - if(NOT line MATCHES "gtest_main\\.cc") - # Do we have a module name or a test name? - if(NOT line MATCHES "^ ") - # Module; remove trailing '.' to get just the name... - string(REGEX REPLACE "\\.( *#.*)?" "" suite "${line}") - if(line MATCHES "#" AND NOT NO_PRETTY_TYPES) - string(REGEX REPLACE "/[0-9]\\.+ +#.*= +" "/" pretty_suite "${line}") - else() - set(pretty_suite "${suite}") - endif() - string(REGEX REPLACE "^DISABLED_" "" pretty_suite "${pretty_suite}") - else() - # Test name; strip spaces and comments to get just the name... - string(REGEX REPLACE " +" "" test "${line}") - if(test MATCHES "#" AND NOT NO_PRETTY_VALUES) - string(REGEX REPLACE "/[0-9]+#GetParam..=" "/" pretty_test "${test}") - else() - string(REGEX REPLACE "#.*" "" pretty_test "${test}") - endif() - string(REGEX REPLACE "^DISABLED_" "" pretty_test "${pretty_test}") - string(REGEX REPLACE "#.*" "" test "${test}") - if(NOT TEST_XML_OUTPUT_DIR STREQUAL "") - set(TEST_XML_OUTPUT_PARAM "--gtest_output=xml:${TEST_XML_OUTPUT_DIR}/${prefix}${pretty_suite}.${pretty_test}${suffix}.xml") + string(REPLACE "\n" ";" output "${output}") + + # Parse output + foreach(line ${output}) + # Skip header + if(NOT line MATCHES "gtest_main\\.cc") + # Do we have a module name or a test name? + if(NOT line MATCHES "^ ") + # Module; remove trailing '.' to get just the name... + string(REGEX REPLACE "\\.( *#.*)?" "" suite "${line}") + if(line MATCHES "#" AND NOT _NO_PRETTY_TYPES) + string(REGEX REPLACE "/[0-9]\\.+ +#.*= +" "/" pretty_suite "${line}") + else() + set(pretty_suite "${suite}") + endif() + string(REGEX REPLACE "^DISABLED_" "" pretty_suite "${pretty_suite}") else() - unset(TEST_XML_OUTPUT_PARAM) - endif() - # ...and add to script - add_command(add_test - "${prefix}${pretty_suite}.${pretty_test}${suffix}" - ${TEST_EXECUTOR} - "${TEST_EXECUTABLE}" - "--gtest_filter=${suite}.${test}" - "--gtest_also_run_disabled_tests" - ${TEST_XML_OUTPUT_PARAM} - ${extra_args} - ) - if(suite MATCHES "^DISABLED" OR test MATCHES "^DISABLED") + # Test name; strip spaces and comments to get just the name... + string(REGEX REPLACE " +" "" test "${line}") + if(test MATCHES "#" AND NOT _NO_PRETTY_VALUES) + string(REGEX REPLACE "/[0-9]+#GetParam..=" "/" pretty_test "${test}") + else() + string(REGEX REPLACE "#.*" "" pretty_test "${test}") + endif() + string(REGEX REPLACE "^DISABLED_" "" pretty_test "${pretty_test}") + string(REGEX REPLACE "#.*" "" test "${test}") + if(NOT "${_TEST_XML_OUTPUT_DIR}" STREQUAL "") + set(TEST_XML_OUTPUT_PARAM "--gtest_output=xml:${_TEST_XML_OUTPUT_DIR}/${prefix}${pretty_suite}.${pretty_test}${suffix}.xml") + else() + unset(TEST_XML_OUTPUT_PARAM) + endif() + # ...and add to script + add_command(add_test + "${prefix}${pretty_suite}.${pretty_test}${suffix}" + ${_TEST_EXECUTOR} + "${_TEST_EXECUTABLE}" + "--gtest_filter=${suite}.${test}" + "--gtest_also_run_disabled_tests" + ${TEST_XML_OUTPUT_PARAM} + ${extra_args} + ) + if(suite MATCHES "^DISABLED" OR test MATCHES "^DISABLED") + add_command(set_tests_properties + "${prefix}${pretty_suite}.${pretty_test}${suffix}" + PROPERTIES DISABLED TRUE + ) + endif() add_command(set_tests_properties "${prefix}${pretty_suite}.${pretty_test}${suffix}" - PROPERTIES DISABLED TRUE + PROPERTIES + WORKING_DIRECTORY "${_TEST_WORKING_DIR}" + ${properties} ) - endif() - add_command(set_tests_properties - "${prefix}${pretty_suite}.${pretty_test}${suffix}" - PROPERTIES - WORKING_DIRECTORY "${TEST_WORKING_DIR}" - ${properties} - ) - list(APPEND tests_buffer "${prefix}${pretty_suite}.${pretty_test}${suffix}") - list(LENGTH tests_buffer tests_buffer_length) - if(${tests_buffer_length} GREATER "250") - flush_tests_buffer() + list(APPEND tests_buffer "${prefix}${pretty_suite}.${pretty_test}${suffix}") + list(LENGTH tests_buffer tests_buffer_length) + if(${tests_buffer_length} GREATER "250") + flush_tests_buffer() + endif() endif() endif() - endif() -endforeach() + endforeach() + + + # Create a list of all discovered tests, which users may use to e.g. set + # properties on the tests + flush_tests_buffer() + add_command(set ${_TEST_LIST} ${tests}) + # Write CTest script + flush_script() -# Create a list of all discovered tests, which users may use to e.g. set -# properties on the tests -flush_tests_buffer() -add_command(set ${TEST_LIST} ${tests}) +endfunction() -# Write CTest script -flush_script() +if(CMAKE_SCRIPT_MODE_FILE) + gtest_discover_tests_impl( + NO_PRETTY_TYPES ${NO_PRETTY_TYPES} + NO_PRETTY_VALUES ${NO_PRETTY_VALUES} + TEST_EXECUTABLE ${TEST_EXECUTABLE} + TEST_EXECUTOR ${TEST_EXECUTOR} + TEST_WORKING_DIR ${TEST_WORKING_DIR} + TEST_PREFIX ${TEST_PREFIX} + TEST_SUFFIX ${TEST_SUFFIX} + TEST_LIST ${TEST_LIST} + CTEST_FILE ${CTEST_FILE} + TEST_DISCOVERY_TIMEOUT ${TEST_DISCOVERY_TIMEOUT} + TEST_XML_OUTPUT_DIR ${TEST_XML_OUTPUT_DIR} + TEST_EXTRA_ARGS ${TEST_EXTRA_ARGS} + TEST_PROPERTIES ${TEST_PROPERTIES} + ) +endif() |