summaryrefslogtreecommitdiffstats
path: root/cmake/QtTestHelpers.cmake
diff options
context:
space:
mode:
Diffstat (limited to 'cmake/QtTestHelpers.cmake')
-rw-r--r--cmake/QtTestHelpers.cmake183
1 files changed, 153 insertions, 30 deletions
diff --git a/cmake/QtTestHelpers.cmake b/cmake/QtTestHelpers.cmake
index 967d8ff99b..62ee91296f 100644
--- a/cmake/QtTestHelpers.cmake
+++ b/cmake/QtTestHelpers.cmake
@@ -31,11 +31,13 @@ function(qt_internal_add_benchmark target)
)
if(NOT arg_OUTPUT_DIRECTORY)
- set(arg_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")
+ if(CMAKE_RUNTIME_OUTPUT_DIRECTORY)
+ set(arg_OUTPUT_DIRECTORY "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}")
+ else()
+ set(arg_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")
+ endif()
endif()
- qt_internal_library_deprecation_level(deprecation_define)
-
qt_internal_add_executable(${target}
NO_INSTALL # we don't install benchmarks
NO_UNITY_BUILD # excluded by default
@@ -214,6 +216,7 @@ function(qt_internal_get_test_arg_definitions optional_args single_value_args mu
MANUAL
NO_BATCH
NO_INSTALL
+ BUNDLE_ANDROID_OPENSSL_LIBS
PARENT_SCOPE
)
set(${single_value_args}
@@ -246,7 +249,6 @@ function(qt_internal_add_test_to_batch batch_name name)
# Lazy-init the test batch
if(NOT TARGET ${target})
- qt_internal_library_deprecation_level(deprecation_define)
qt_internal_add_executable(${target}
${exceptions_text}
${gui_text}
@@ -314,6 +316,34 @@ function(qt_internal_add_test_to_batch batch_name name)
list(PREPEND batched_test_list ${name})
set_property(GLOBAL PROPERTY _qt_batched_test_list_property ${batched_test_list})
+ # Test batching produces single executable which can result in one source file being added
+ # multiple times (with different definitions) to one translation unit. This is not supported by
+ # CMake so instead we try to detect such situation and rename file every time it's added
+ # to the build more than once. This avoids filenames collisions in one translation unit.
+ get_property(batched_test_sources_list GLOBAL PROPERTY _qt_batched_test_sources_list_property)
+ if(NOT batched_test_sources_list)
+ set_property(GLOBAL PROPERTY _qt_batched_test_sources_list_property "")
+ set(batched_test_sources_list "")
+ endif()
+ foreach(source ${arg_SOURCES})
+ set(source_path ${source})
+ if(${source} IN_LIST batched_test_sources_list)
+ set(new_filename ${name}.cpp)
+ configure_file(${source} ${new_filename})
+ set(source_path ${CMAKE_CURRENT_BINARY_DIR}/${new_filename})
+ set(skip_automoc ON)
+ list(APPEND arg_SOURCES ${source_path})
+ else()
+ set(skip_automoc OFF)
+ list(APPEND batched_test_sources_list ${source})
+ endif()
+ set_source_files_properties(${source_path}
+ TARGET_DIRECTORY ${target} PROPERTIES
+ SKIP_AUTOMOC ${skip_automoc}
+ COMPILE_DEFINITIONS "BATCHED_TEST_NAME=\"${name}\";${arg_DEFINES}")
+ endforeach()
+ set_property(GLOBAL PROPERTY _qt_batched_test_sources_list_property ${batched_test_sources_list})
+
# Merge the current test with the rest of the batch
qt_internal_extend_target(${target}
INCLUDE_DIRECTORIES ${arg_INCLUDE_DIRECTORIES}
@@ -329,15 +359,6 @@ function(qt_internal_add_test_to_batch batch_name name)
NO_UNITY_BUILD # Tests should not be built using UNITY_BUILD
)
- foreach(source ${arg_SOURCES})
- # We define the test name which is later used to launch this test using
- # commandline parameters. Target directory is that of the target test_batch,
- # otherwise the batch won't honor our choices of compile definitions.
- set_source_files_properties(${source}
- TARGET_DIRECTORY ${target}
- PROPERTIES COMPILE_DEFINITIONS
- "BATCHED_TEST_NAME=\"${name}\";${arg_DEFINES}" )
- endforeach()
set(${batch_name} ${target} PARENT_SCOPE)
# Add a dummy target so that new tests don't have problems with a nonexistent
@@ -457,8 +478,12 @@ function(qt_internal_add_test name)
endif()
endif()
- if (NOT arg_OUTPUT_DIRECTORY)
- set(arg_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")
+ if(NOT arg_OUTPUT_DIRECTORY)
+ if(CMAKE_RUNTIME_OUTPUT_DIRECTORY)
+ set(arg_OUTPUT_DIRECTORY "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}")
+ else()
+ set(arg_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")
+ endif()
endif()
set(private_includes
@@ -485,7 +510,6 @@ function(qt_internal_add_test name)
list(APPEND private_includes ${arg_INCLUDE_DIRECTORIES})
qt_internal_prepare_test_target_flags(version_arg exceptions_text gui_text ${ARGN})
- qt_internal_library_deprecation_level(deprecation_define)
qt_internal_add_executable("${name}"
${exceptions_text}
@@ -538,12 +562,14 @@ function(qt_internal_add_test name)
LIBRARIES ${QT_CMAKE_EXPORT_NAMESPACE}::QuickTest
)
- qt_internal_extend_target("${name}" CONDITION arg_QMLTEST AND NOT ANDROID
+ qt_internal_extend_target("${name}"
+ CONDITION arg_QMLTEST AND NOT ANDROID AND NOT QT_FORCE_BUILTIN_TESTDATA
DEFINES
QUICK_TEST_SOURCE_DIR="${CMAKE_CURRENT_SOURCE_DIR}"
)
- qt_internal_extend_target("${name}" CONDITION arg_QMLTEST AND ANDROID
+ qt_internal_extend_target("${name}"
+ CONDITION arg_QMLTEST AND (ANDROID OR QT_FORCE_BUILTIN_TESTDATA)
DEFINES
QUICK_TEST_SOURCE_DIR=":/"
)
@@ -554,6 +580,11 @@ function(qt_internal_add_test name)
)
set_target_properties(${name} PROPERTIES _qt_is_test_executable TRUE)
set_target_properties(${name} PROPERTIES _qt_is_manual_test ${arg_MANUAL})
+
+ set(blacklist_file "${CMAKE_CURRENT_SOURCE_DIR}/BLACKLIST")
+ if(EXISTS ${blacklist_file})
+ _qt_internal_expose_source_file_to_ide("${name}" ${blacklist_file})
+ endif()
endif()
foreach(path IN LISTS arg_QML_IMPORTPATH)
@@ -579,7 +610,43 @@ function(qt_internal_add_test name)
endif()
if (ANDROID)
- qt_internal_android_test_arguments("${name}" test_executable extra_test_args)
+ # Pass 95% of the timeout to allow the test runner time to do any cleanup
+ # before being killed.
+ set(percentage "95")
+ qt_internal_get_android_test_timeout("${arg_TIMEOUT}" "${percentage}" android_timeout)
+
+ if(arg_BUNDLE_ANDROID_OPENSSL_LIBS)
+ if(EXISTS "${OPENSSL_ROOT_DIR}/${CMAKE_ANDROID_ARCH_ABI}/libcrypto_3.so")
+ message(STATUS "Looking for OpenSSL in ${OPENSSL_ROOT_DIR}")
+ set_property(TARGET ${name} APPEND PROPERTY QT_ANDROID_EXTRA_LIBS
+ "${OPENSSL_ROOT_DIR}/${CMAKE_ANDROID_ARCH_ABI}/libcrypto_3.so"
+ "${OPENSSL_ROOT_DIR}/${CMAKE_ANDROID_ARCH_ABI}/libssl_3.so")
+ elseif(QT_USE_VCPKG AND DEFINED ENV{VCPKG_ROOT})
+ message(STATUS "Looking for OpenSSL in $ENV{VCPKG_ROOT}")
+ if (CMAKE_ANDROID_ARCH_ABI MATCHES "arm64-v8a")
+ set(coin_vcpkg_target_triplet "arm64-android-dynamic")
+ elseif(CMAKE_ANDROID_ARCH_ABI MATCHES "armeabi-v7a")
+ set(coin_vcpkg_target_triplet "arm-neon-android-dynamic")
+ elseif(CMAKE_ANDROID_ARCH_ABI MATCHES "x86_64")
+ set(coin_vcpkg_target_triplet "x64-android-dynamic")
+ elseif(CMAKE_ANDROID_ARCH_ABI MATCHES "x86")
+ set(coin_vcpkg_target_triplet "x86-android-dynamic")
+ endif()
+ if(EXISTS "$ENV{VCPKG_ROOT}/installed/${coin_vcpkg_target_triplet}/lib/libcrypto.so")
+ message(STATUS "Found OpenSSL in $ENV{VCPKG_ROOT}/installed/${coin_vcpkg_target_triplet}/lib")
+ set_property(TARGET ${name} APPEND PROPERTY QT_ANDROID_EXTRA_LIBS
+ "$ENV{VCPKG_ROOT}/installed/${coin_vcpkg_target_triplet}/lib/libcrypto.so"
+ "$ENV{VCPKG_ROOT}/installed/${coin_vcpkg_target_triplet}/lib/libssl.so")
+ endif()
+ else()
+ message(STATUS "The argument BUNDLE_ANDROID_OPENSSL_LIBS is set "
+ "but OPENSSL_ROOT_DIR parameter is not set. "
+ "Test should bundle OpenSSL libraries but they are not found. "
+ "This is fine if OpenSSL was built statically.")
+ endif()
+ endif()
+ qt_internal_android_test_arguments(
+ "${name}" "${android_timeout}" test_executable extra_test_args)
set(test_working_dir "${CMAKE_CURRENT_BINARY_DIR}")
elseif(QNX)
set(test_working_dir "")
@@ -602,14 +669,21 @@ function(qt_internal_add_test name)
list(APPEND extra_test_args "--browser_args=\"--password-store=basic\"")
list(APPEND extra_test_args "--kill_exit")
- # We always want to enable asyncify for tests, as some of them use exec
+ # Tests may require asyncify if they use exec(). Enable asyncify for
+ # batched tests since this is the configuration used on the CI system.
# Optimize for size (-Os), since asyncify tends to make the resulting
# binary very large
- target_link_options("${name}" PRIVATE "SHELL:-s ASYNCIFY" "-Os")
+ if(batch_current_test)
+ target_link_options("${name}" PRIVATE "SHELL:-s ASYNCIFY" "-Os")
+ endif()
# This tells cmake to run the tests with this script, since wasm files can't be
# executed directly
- set_property(TARGET "${name}" PROPERTY CROSSCOMPILING_EMULATOR "emrun")
+ if (CMAKE_HOST_WIN32)
+ set_property(TARGET "${name}" PROPERTY CROSSCOMPILING_EMULATOR "emrun.bat")
+ else()
+ set_property(TARGET "${name}" PROPERTY CROSSCOMPILING_EMULATOR "emrun")
+ endif()
else()
if(arg_QMLTEST AND NOT arg_SOURCES)
set(test_working_dir "${CMAKE_CURRENT_SOURCE_DIR}")
@@ -670,6 +744,14 @@ function(qt_internal_add_test name)
set_tests_properties(${testname} PROPERTIES TIMEOUT ${arg_TIMEOUT})
endif()
+ if(ANDROID AND NOT CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows")
+ # Set timeout signal and some time for androidtestrunner to do cleanup
+ set_tests_properties(${testname} PROPERTIES
+ TIMEOUT_SIGNAL_NAME "SIGINT"
+ TIMEOUT_SIGNAL_GRACE_PERIOD 10.0
+ )
+ endif()
+
# Add a ${target}/check makefile target, to more easily test one test.
set(test_config_options "")
@@ -690,7 +772,7 @@ function(qt_internal_add_test name)
endif()
endif()
- if(ANDROID OR IOS OR WASM OR INTEGRITY OR arg_BUILTIN_TESTDATA)
+ if(ANDROID OR IOS OR WASM OR INTEGRITY OR arg_BUILTIN_TESTDATA OR QT_FORCE_BUILTIN_TESTDATA)
set(builtin_testdata TRUE)
endif()
@@ -744,15 +826,27 @@ function(qt_internal_add_test name)
endif()
endif()
else()
- # Install test data
- file(RELATIVE_PATH relative_path_to_test_project
- "${QT_TOP_LEVEL_SOURCE_DIR}"
- "${CMAKE_CURRENT_SOURCE_DIR}")
- qt_path_join(testdata_install_dir ${QT_INSTALL_DIR}
- "${relative_path_to_test_project}")
- if (testdata_install_dir)
+ # Install test data, when tests are built in-tree or as standalone tests, but not as a
+ # single standalone test, which is checked by the existence of the QT_TOP_LEVEL_SOURCE_DIR
+ # variable.
+ # TODO: Shouldn't we also handle the single standalone test case?
+ # TODO: Does installing even makes sense, given where QFINDTESTDATA looks for installed
+ # test data, and where we end up installing it? See QTBUG-117098.
+ if(QT_TOP_LEVEL_SOURCE_DIR)
foreach(testdata IN LISTS arg_TESTDATA)
set(testdata "${CMAKE_CURRENT_SOURCE_DIR}/${testdata}")
+
+ # Get the relative source dir for each test data entry, because it might contain a
+ # subdirectory.
+ file(RELATIVE_PATH relative_path_to_test_project
+ "${QT_TOP_LEVEL_SOURCE_DIR}"
+ "${testdata}")
+ get_filename_component(relative_path_to_test_project
+ "${relative_path_to_test_project}" DIRECTORY)
+
+ qt_path_join(testdata_install_dir ${QT_INSTALL_DIR}
+ "${relative_path_to_test_project}")
+
if (IS_DIRECTORY "${testdata}")
qt_install(
DIRECTORY "${testdata}"
@@ -769,6 +863,35 @@ function(qt_internal_add_test name)
qt_internal_add_test_finalizers("${name}")
endfunction()
+# Given an optional test timeout value (specified via qt_internal_add_test's TIMEOUT option)
+# returns a percentage of the final timeout to be passed to the androidtestrunner executable.
+#
+# When the optional timeout is empty, default to cmake's defaults for getting the timeout.
+function(qt_internal_get_android_test_timeout input_timeout percentage output_timeout_var)
+ set(actual_timeout "${input_timeout}")
+ if(NOT actual_timeout)
+ # we have coin ci timeout set use that to avoid having the emulator killed
+ # so we can at least get some logs from the android test runner.
+ set(coin_timeout $ENV{COIN_COMMAND_OUTPUT_TIMEOUT})
+ if(coin_timeout)
+ set(actual_timeout "${coin_timeout}")
+ elseif(DART_TESTING_TIMEOUT)
+ # Related: https://gitlab.kitware.com/cmake/cmake/-/issues/20450
+ set(actual_timeout "${DART_TESTING_TIMEOUT}")
+ elseif(CTEST_TEST_TIMEOUT)
+ set(actual_timeout "${CTEST_TEST_TIMEOUT}")
+ else()
+ # Default DART_TESTING_TIMEOUT is 25 minutes, specified in seconds
+ # https://github.com/Kitware/CMake/blob/master/Modules/CTest.cmake#L167C16-L167C16
+ set(actual_timeout "1500")
+ endif()
+ endif()
+
+ math(EXPR calculated_timeout "${actual_timeout} * ${percentage} / 100")
+
+ set(${output_timeout_var} "${calculated_timeout}" PARENT_SCOPE)
+endfunction()
+
# This function adds test with specified NAME and wraps given test COMMAND with standalone cmake
# script.
#