diff options
Diffstat (limited to 'cmake/QtTestHelpers.cmake')
-rw-r--r-- | cmake/QtTestHelpers.cmake | 340 |
1 files changed, 340 insertions, 0 deletions
diff --git a/cmake/QtTestHelpers.cmake b/cmake/QtTestHelpers.cmake new file mode 100644 index 0000000000..a7d6d9d849 --- /dev/null +++ b/cmake/QtTestHelpers.cmake @@ -0,0 +1,340 @@ +# Simple wrapper around qt_add_executable for benchmarks which insure that +# the binary is built under ${CMAKE_CURRENT_BINARY_DIR} and never installed. +# See qt_add_executable() for more details. +function(qt_add_benchmark target) + + qt_parse_all_arguments(arg "qt_add_benchmark" + "${__qt_add_executable_optional_args}" + "${__qt_add_executable_single_args}" + "${__qt_add_executable_multi_args}" + ${ARGN} + ) + + qt_remove_args(exec_args + ARGS_TO_REMOVE + ${target} + OUTPUT_DIRECTORY + INSTALL_DIRECTORY + ALL_ARGS + "${__qt_add_executable_optional_args}" + "${__qt_add_executable_single_args}" + "${__qt_add_executable_multi_args}" + ARGS + ${ARGV} + ) + + if(NOT arg_OUTPUT_DIRECTORY) + set(arg_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") + endif() + + qt_add_executable(${target} + NO_INSTALL # we don't install benchmarks + OUTPUT_DIRECTORY "${arg_OUTPUT_DIRECTORY}" # avoid polluting bin directory + ${exec_args} + ) + +endfunction() + +# Simple wrapper around qt_add_executable for manual tests which insure that +# the binary is built under ${CMAKE_CURRENT_BINARY_DIR} and never installed. +# See qt_add_executable() for more details. +function(qt_add_manual_test target) + + qt_parse_all_arguments(arg "qt_add_manual_test" + "${__qt_add_executable_optional_args}" + "${__qt_add_executable_single_args}" + "${__qt_add_executable_multi_args}" + ${ARGN} + ) + + qt_remove_args(exec_args + ARGS_TO_REMOVE + ${target} + OUTPUT_DIRECTORY + INSTALL_DIRECTORY + ALL_ARGS + "${__qt_add_executable_optional_args}" + "${__qt_add_executable_single_args}" + "${__qt_add_executable_multi_args}" + ARGS + ${ARGV} + ) + + if(NOT arg_OUTPUT_DIRECTORY) + set(arg_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") + endif() + + qt_add_executable(${target} + NO_INSTALL # we don't install benchmarks + OUTPUT_DIRECTORY "${arg_OUTPUT_DIRECTORY}" # avoid polluting bin directory + ${exec_args} + ) + +endfunction() + + +# This function creates a CMake test target with the specified name for use with CTest. +function(qt_add_test name) + qt_parse_all_arguments(arg "qt_add_test" + "RUN_SERIAL;EXCEPTIONS;GUI;QMLTEST;CATCH;LOWDPI" + "OUTPUT_DIRECTORY;WORKING_DIRECTORY;TIMEOUT;VERSION" + "QML_IMPORTPATH;TESTDATA;${__default_private_args};${__default_public_args}" ${ARGN} + ) + + if (NOT arg_OUTPUT_DIRECTORY) + set(arg_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") + endif() + + if (${arg_EXCEPTIONS}) + set(exceptions_text "EXCEPTIONS") + endif() + + if (${arg_GUI}) + set(gui_text "GUI") + endif() + + if (arg_VERSION) + set(version_arg VERSION "${arg_VERSION}") + endif() + + # Handle cases where we have a qml test without source files + if (arg_SOURCES) + set(private_includes + "${CMAKE_CURRENT_SOURCE_DIR}" + "${CMAKE_CURRENT_BINARY_DIR}" + "$<BUILD_INTERFACE:${QT_BUILD_DIR}/include>" + ${arg_INCLUDE_DIRECTORIES} + ) + + qt_add_executable("${name}" + ${exceptions_text} + ${gui_text} + ${version_arg} + NO_INSTALL + OUTPUT_DIRECTORY "${arg_OUTPUT_DIRECTORY}" + SOURCES "${arg_SOURCES}" + INCLUDE_DIRECTORIES + ${private_includes} + DEFINES + QT_TESTCASE_BUILDDIR="${CMAKE_CURRENT_BINARY_DIR}" + QT_TESTCASE_SOURCEDIR="${CMAKE_CURRENT_SOURCE_DIR}" + ${arg_DEFINES} + PUBLIC_LIBRARIES ${QT_CMAKE_EXPORT_NAMESPACE}::Core ${QT_CMAKE_EXPORT_NAMESPACE}::Test ${arg_PUBLIC_LIBRARIES} + LIBRARIES ${arg_LIBRARIES} + COMPILE_OPTIONS ${arg_COMPILE_OPTIONS} + LINK_OPTIONS ${arg_LINK_OPTIONS} + MOC_OPTIONS ${arg_MOC_OPTIONS} + ENABLE_AUTOGEN_TOOLS ${arg_ENABLE_AUTOGEN_TOOLS} + DISABLE_AUTOGEN_TOOLS ${arg_DISABLE_AUTOGEN_TOOLS} + ) + + # Tests should not be bundles on macOS even if arg_GUI is true, because some tests make + # assumptions about the location of helper processes, and those paths would be different + # if a test is built as a bundle. + set_property(TARGET "${name}" PROPERTY MACOSX_BUNDLE FALSE) + # The same goes for WIN32_EXECUTABLE, but because it will detach from the console window + # and not print anything. + set_property(TARGET "${name}" PROPERTY WIN32_EXECUTABLE FALSE) + + # QMLTest specifics + + qt_extend_target("${name}" CONDITION arg_QMLTEST + PUBLIC_LIBRARIES ${QT_CMAKE_EXPORT_NAMESPACE}::QuickTest + ) + + qt_extend_target("${name}" CONDITION arg_QMLTEST AND NOT ANDROID + DEFINES + QUICK_TEST_SOURCE_DIR="${CMAKE_CURRENT_SOURCE_DIR}" + ) + + qt_extend_target("${name}" CONDITION arg_QMLTEST AND ANDROID + DEFINES + QUICK_TEST_SOURCE_DIR=":/" + ) + endif() + + foreach(path IN LISTS arg_QML_IMPORTPATH) + list(APPEND extra_test_args "-import" "${path}") + endforeach() + + # Generate a label in the form tests/auto/foo/bar/tst_baz + # and use it also for XML output + file(RELATIVE_PATH label "${PROJECT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/${name}") + + if (arg_LOWDPI) + target_compile_definitions("${name}" PUBLIC TESTCASE_LOWDPI) + if (MACOS) + set_property(TARGET "${name}" PROPERTY MACOSX_BUNDLE_INFO_PLIST "${QT_MKSPECS_DIR}/macx-clang/Info.plist.disable_highdpi") + set_property(TARGET "${name}" PROPERTY PROPERTY MACOSX_BUNDLE TRUE) + endif() + endif() + + if (ANDROID) + qt_android_add_test("${name}") + else() + if(arg_QMLTEST AND NOT arg_SOURCES) + set(test_working_dir "${CMAKE_CURRENT_SOURCE_DIR}") + set(test_executable ${QT_CMAKE_EXPORT_NAMESPACE}::qmltestrunner) + else() + if (arg_WORKING_DIRECTORY) + set(test_working_dir "${arg_WORKING_DIRECTORY}") + elseif(arg_OUTPUT_DIRECTORY) + set(test_working_dir "${arg_OUTPUT_DIRECTORY}") + else() + set(test_working_dir "${CMAKE_CURRENT_BINARY_DIR}") + endif() + set(test_executable "${name}") + endif() + + if (NOT arg_CATCH) + list(APPEND test_outputs "-o" "${name}.xml,xml" "-o" "-,txt") + endif() + + add_test(NAME "${name}" COMMAND ${test_executable} ${extra_test_args} ${test_outputs} WORKING_DIRECTORY "${test_working_dir}") + endif() + set_tests_properties("${name}" PROPERTIES RUN_SERIAL "${arg_RUN_SERIAL}" LABELS "${label}") + if (arg_TIMEOUT) + set_tests_properties(${name} PROPERTIES TIMEOUT ${arg_TIMEOUT}) + endif() + + # Add a ${target}/check makefile target, to more easily test one test. + if(TEST "${name}") + add_custom_target("${name}_check" + VERBATIM + COMMENT "Running ${CMAKE_CTEST_COMMAND} -V -R \"^${name}$\"" + COMMAND "${CMAKE_CTEST_COMMAND}" -V -R "^${name}$" + ) + if(TARGET "${name}") + add_dependencies("${name}_check" "${name}") + endif() + endif() + + # Get path to <qt_relocatable_install_prefix>/bin, as well as CMAKE_INSTALL_PREFIX/bin, then + # prepend them to the PATH environment variable. + # It's needed on Windows to find the shared libraries and plugins. + # qt_relocatable_install_prefix is dynamically computed from the location of where the Qt CMake + # package is found. + # The regular CMAKE_INSTALL_PREFIX can be different for example when building standalone tests. + # Any given CMAKE_INSTALL_PREFIX takes priority over qt_relocatable_install_prefix for the + # PATH environment variable. + set(install_prefixes "${CMAKE_INSTALL_PREFIX}") + if(QT_BUILD_INTERNALS_RELOCATABLE_INSTALL_PREFIX) + list(APPEND install_prefixes "${QT_BUILD_INTERNALS_RELOCATABLE_INSTALL_PREFIX}") + endif() + + set(test_env_path "PATH=${CMAKE_CURRENT_BINARY_DIR}") + foreach(install_prefix ${install_prefixes}) + set(test_env_path "${test_env_path}${QT_PATH_SEPARATOR}${install_prefix}/${INSTALL_BINDIR}") + endforeach() + set(test_env_path "${test_env_path}${QT_PATH_SEPARATOR}$ENV{PATH}") + string(REPLACE ";" "\;" test_env_path "${test_env_path}") + set_property(TEST "${name}" APPEND PROPERTY ENVIRONMENT "${test_env_path}") + set_property(TEST "${name}" APPEND PROPERTY ENVIRONMENT "QT_TEST_RUNNING_IN_CTEST=1") + + # Add the install prefix to list of plugin paths when doing a prefix build + if(NOT QT_INSTALL_DIR) + foreach(install_prefix ${install_prefixes}) + list(APPEND plugin_paths "${install_prefix}/${INSTALL_PLUGINSDIR}") + endforeach() + endif() + + #TODO: Collect all paths from known repositories when performing a super + # build. + list(APPEND plugin_paths "${PROJECT_BINARY_DIR}/${INSTALL_PLUGINSDIR}") + list(JOIN plugin_paths "${QT_PATH_SEPARATOR}" plugin_paths_joined) + set_property(TEST "${name}" APPEND PROPERTY ENVIRONMENT "QT_PLUGIN_PATH=${plugin_paths_joined}") + + if(ANDROID OR IOS OR WINRT) + set(builtin_testdata TRUE) + endif() + + if(builtin_testdata) + # Safe guard against qml only tests, no source files == no target + if (TARGET "${name}") + target_compile_definitions("${name}" PRIVATE BUILTIN_TESTDATA) + + foreach(testdata IN LISTS arg_TESTDATA) + list(APPEND builtin_files ${testdata}) + endforeach() + + set(blacklist_path "BLACKLIST") + if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${blacklist_path}") + list(APPEND builtin_files ${blacklist_path}) + endif() + + list(REMOVE_DUPLICATES builtin_files) + + # Skip Qt quick compiler when embedding test resources + foreach(file IN LISTS builtin_files) + set_source_files_properties(${file} + PROPERTIES QT_SKIP_QUICKCOMPILER TRUE + ) + endforeach() + + if (builtin_files) + qt_add_resource(${name} "${name}_testdata_builtin" + PREFIX "/" + FILES ${builtin_files} + BASE ${CMAKE_CURRENT_SOURCE_DIR}) + 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}") + foreach(testdata IN LISTS arg_TESTDATA) + set(testdata "${CMAKE_CURRENT_SOURCE_DIR}/${testdata}") + if (IS_DIRECTORY "${testdata}") + qt_install( + DIRECTORY "${testdata}" + DESTINATION "${testdata_install_dir}") + else() + qt_install( + FILES "${testdata}" + DESTINATION "${testdata_install_dir}") + endif() + endforeach() + endif() + +endfunction() + + +# This function creates an executable for use as a helper program with tests. Some +# tests launch separate programs to test certain input/output behavior. +# Specify OVERRIDE_OUTPUT_DIRECTORY if you dont' want to place the helper in the parent directory, +# in which case you should specify OUTPUT_DIRECTORY "/foo/bar" manually. +function(qt_add_test_helper name) + + set(qt_add_test_helper_optional_args + "OVERRIDE_OUTPUT_DIRECTORY" + ) + + qt_parse_all_arguments(arg "qt_add_test_helper" + "${qt_add_test_helper_optional_args};${__qt_add_executable_optional_args}" + "${__qt_add_executable_single_args}" + "${__qt_add_executable_multi_args}" + ${ARGN}) + + qt_remove_args(forward_args + ARGS_TO_REMOVE + "${name}" + ${qt_add_test_helper_optional_args} + ALL_ARGS + ${qt_add_test_helper_optional_args} + ${__qt_add_executable_optional_args} + ${__qt_add_executable_single_args} + ${__qt_add_executable_multi_args} + ARGS + ${ARGV} + ) + + set(extra_args_to_pass) + if(NOT arg_OVERRIDE_OUTPUT_DIRECTORY) + set(extra_args_to_pass OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/..") + endif() + + qt_add_executable("${name}" NO_INSTALL ${extra_args_to_pass} ${forward_args}) +endfunction() |