Browse Source

GoogleTest: Add DISCOVERY_EXTRA_ARGS to gtest_discover_tests()

Fixes: #26261
Co-authored-by: Craig Scott <[email protected]>
Cedric Martineau 1 year ago
parent
commit
2dcba446e2

+ 6 - 0
Help/release/dev/GoogleTest-DISCOVERY_EXTRA_ARGS.rst

@@ -0,0 +1,6 @@
+GoogleTest-DISCOVERY_EXTRA_ARGS
+-------------------------------
+
+* The :command:`gtest_discover_tests` command gained a new
+  ``DISCOVERY_EXTRA_ARGS`` keyword.  It allows extra arguments to be
+  appended to the command line when querying for the list of tests.

+ 9 - 0
Modules/GoogleTest.cmake

@@ -166,6 +166,7 @@ same as the Google Test name (i.e. ``suite.testcase``); see also
                          [DISCOVERY_TIMEOUT seconds]
                          [XML_OUTPUT_DIR dir]
                          [DISCOVERY_MODE <POST_BUILD|PRE_TEST>]
+                         [DISCOVERY_EXTRA_ARGS args...]
     )
 
   .. versionadded:: 3.10
@@ -300,6 +301,11 @@ same as the Google Test name (i.e. ``suite.testcase``); see also
     for globally selecting a preferred test discovery behavior without having
     to modify each call site.
 
+  ``DISCOVERY_EXTRA_ARGS args...``
+    .. versionadded:: 3.31
+
+    Any extra arguments to pass on the command line for the discovery command.
+
   .. versionadded:: 3.29
     The :prop_tgt:`TEST_LAUNCHER` target property is honored during test
     discovery and test execution.
@@ -546,6 +552,7 @@ function(gtest_discover_tests target)
   )
   set(multiValueArgs
     EXTRA_ARGS
+    DISCOVERY_EXTRA_ARGS
     PROPERTIES
     TEST_FILTER
   )
@@ -670,6 +677,7 @@ function(gtest_discover_tests target)
               -D "TEST_LIST=${arg_TEST_LIST}"
               -D "CTEST_FILE=${ctest_tests_file}"
               -D "TEST_DISCOVERY_TIMEOUT=${arg_DISCOVERY_TIMEOUT}"
+              -D "TEST_DISCOVERY_EXTRA_ARGS=${arg_DISCOVERY_EXTRA_ARGS}"
               -D "TEST_XML_OUTPUT_DIR=${arg_XML_OUTPUT_DIR}"
               -P "${CMAKE_ROOT}/Modules/GoogleTestAddTests.cmake"
       VERBATIM
@@ -712,6 +720,7 @@ function(gtest_discover_tests target)
       "      TEST_LIST"              " [==[${arg_TEST_LIST}]==]"                   "\n"
       "      CTEST_FILE"             " [==[${ctest_tests_file}]==]"                "\n"
       "      TEST_DISCOVERY_TIMEOUT" " [==[${arg_DISCOVERY_TIMEOUT}]==]"           "\n"
+      "      TEST_DISCOVERY_EXTRA_ARGS [==[${arg_DISCOVERY_EXTRA_ARGS}]==]"        "\n"
       "      TEST_XML_OUTPUT_DIR"    " [==[${arg_XML_OUTPUT_DIR}]==]"              "\n"
       "    )"                                                                      "\n"
       "  endif()"                                                                  "\n"

+ 10 - 1
Modules/GoogleTestAddTests.cmake

@@ -83,6 +83,7 @@ function(gtest_discover_tests_impl)
     # way to avoid problems with preserving empty list values and escaping.
     TEST_FILTER
     TEST_EXTRA_ARGS
+    TEST_DISCOVERY_EXTRA_ARGS
     TEST_PROPERTIES
     TEST_EXECUTOR
   )
@@ -121,9 +122,16 @@ function(gtest_discover_tests_impl)
       "  Path: '${arg_TEST_EXECUTABLE}'"
     )
   endif()
+
+  set(discovery_extra_args "")
+  if(NOT "${arg_TEST_DISCOVERY_EXTRA_ARGS}" STREQUAL "")
+    list(JOIN arg_TEST_DISCOVERY_EXTRA_ARGS "]==] [==[" discovery_extra_args)
+    set(discovery_extra_args "[==[${discovery_extra_args}]==]")
+  endif()
+
   cmake_language(EVAL CODE
     "execute_process(
-      COMMAND ${launcherArgs} [==[${arg_TEST_EXECUTABLE}]==] --gtest_list_tests ${filter}
+      COMMAND ${launcherArgs} [==[${arg_TEST_EXECUTABLE}]==] --gtest_list_tests ${filter} ${discovery_extra_args}
       WORKING_DIRECTORY [==[${arg_TEST_WORKING_DIR}]==]
       TIMEOUT ${arg_TEST_DISCOVERY_TIMEOUT}
       OUTPUT_VARIABLE output
@@ -286,6 +294,7 @@ if(CMAKE_SCRIPT_MODE_FILE)
     TEST_DISCOVERY_TIMEOUT ${TEST_DISCOVERY_TIMEOUT}
     TEST_XML_OUTPUT_DIR ${TEST_XML_OUTPUT_DIR}
     TEST_EXTRA_ARGS "${TEST_EXTRA_ARGS}"
+    TEST_DISCOVERY_EXTRA_ARGS "${TEST_DISCOVERY_EXTRA_ARGS}"
     TEST_PROPERTIES "${TEST_PROPERTIES}"
   )
 endif()

+ 6 - 0
Tests/RunCMake/GoogleTest/GoogleTest-discovery-check-test-list-extra-args.cmake

@@ -0,0 +1,6 @@
+list(LENGTH test_list_extra_args_TESTS LIST_SIZE)
+set(EXPECTED_SIZE 4)
+if(NOT LIST_SIZE EQUAL ${EXPECTED_SIZE})
+  message("TEST_LIST should have ${EXPECTED_SIZE} elements but it has ${LIST_SIZE}")
+  message("The unexpected list: [${test_list_extra_args_TESTS}]")
+endif()

+ 15 - 0
Tests/RunCMake/GoogleTest/GoogleTestDiscoveryTestListExtraArgs.cmake

@@ -0,0 +1,15 @@
+enable_language(CXX)
+include(GoogleTest)
+
+enable_testing()
+
+include(xcode_sign_adhoc.cmake)
+
+add_executable(test_list_extra_args test_list_extra_args.cpp)
+xcode_sign_adhoc(test_list_extra_args)
+gtest_discover_tests(
+    test_list_extra_args
+    DISCOVERY_EXTRA_ARGS "how now" "" "\"brown\" cow"
+)
+set_property(DIRECTORY APPEND PROPERTY TEST_INCLUDE_FILES
+  ${CMAKE_CURRENT_SOURCE_DIR}/GoogleTest-discovery-check-test-list-extra-args.cmake)

+ 27 - 0
Tests/RunCMake/GoogleTest/RunCMakeTest.cmake

@@ -355,6 +355,32 @@ function(run_GoogleTest_discovery_test_list_scoped DISCOVERY_MODE)
   )
 endfunction()
 
+function(run_GoogleTest_discovery_test_list_extra_args DISCOVERY_MODE)
+  # Use a single build tree for a few tests without cleaning.
+  set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/GoogleTest-discovery-test-list-extra-args-build)
+  set(RunCMake_TEST_NO_CLEAN 1)
+  if(NOT RunCMake_GENERATOR_IS_MULTI_CONFIG)
+    set(RunCMake_TEST_OPTIONS -DCMAKE_BUILD_TYPE=Debug)
+  endif()
+  file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+  file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+
+  run_cmake_with_options(GoogleTestDiscoveryTestListExtraArgs -DCMAKE_GTEST_DISCOVER_TESTS_DISCOVERY_MODE=${DISCOVERY_MODE})
+
+  run_cmake_command(GoogleTest-discovery-test-list-extra-args-build
+    ${CMAKE_COMMAND}
+    --build .
+    --config Debug
+    --target test_list_extra_args
+  )
+
+  run_cmake_command(GoogleTest-discovery-test-list-extra-args-test
+    ${CMAKE_CTEST_COMMAND}
+    -C Debug
+    --no-label-summary
+  )
+endfunction()
+
 foreach(DISCOVERY_MODE POST_BUILD PRE_TEST)
   message(STATUS "Testing ${DISCOVERY_MODE} discovery mode via CMAKE_GTEST_DISCOVER_TESTS_DISCOVERY_MODE global override...")
   run_GoogleTest(${DISCOVERY_MODE})
@@ -367,6 +393,7 @@ foreach(DISCOVERY_MODE POST_BUILD PRE_TEST)
   run_GoogleTest_discovery_arg_change(${DISCOVERY_MODE})
   run_GoogleTest_discovery_test_list(${DISCOVERY_MODE})
   run_GoogleTest_discovery_test_list_scoped(${DISCOVERY_MODE})
+  run_GoogleTest_discovery_test_list_extra_args(${DISCOVERY_MODE})
   run_GoogleTest_discovery_flush_script(${DISCOVERY_MODE})
 endforeach()
 

+ 22 - 0
Tests/RunCMake/GoogleTest/test_list_extra_args.cpp

@@ -0,0 +1,22 @@
+#include <iostream>
+#include <string>
+
+int main(int argc, char** argv)
+{
+  // Note: This test doesn't actually depend on Google Test as such;
+  // it only requires that we produce output in the expected format when
+  // invoked with --gtest_list_tests. Thus, we fake that here. This allows us
+  // to test the module without actually needing Google Test.
+
+  // Simple test of DISCOVERY_EXTRA_ARGS
+  if (argc > 4 && std::string(argv[1]) == "--gtest_list_tests" &&
+      std::string(argv[2]) == "how now" && std::string(argv[3]) == "" &&
+      std::string(argv[4]) == "\"brown\" cow") {
+    std::cout << "test_list_test/test.\n";
+    std::cout << "  case/0  # GetParam() = 'one'\n";
+    std::cout << "  case/1  # GetParam() = 'two'\n";
+    std::cout << "  case/2  # GetParam() = 'three'\n";
+    std::cout << "  case/3  # GetParam() = 'four'\n";
+  }
+  return 0;
+}