summaryrefslogtreecommitdiffstats
path: root/cmake
diff options
context:
space:
mode:
authorAlexey Edelev <alexey.edelev@qt.io>2020-12-08 15:40:43 +0100
committerAlexey Edelev <alexey.edelev@qt.io>2020-12-11 13:39:26 +0100
commit5b41787c1a6ff8834aa85c06a99b689842a9eb8c (patch)
treed835cf77da014f8b9dafac0b61e07a7fb40cd920 /cmake
parent2e952a22f0b211a132f44d53efb21c1fa24b534f (diff)
CMake: Use test wrapper to run android tests
Refactor test adding procedure. It's expected that for each new platform we prepare test executable and arguments first and then pass them to common test adding section. Rename '_qt_internal_wrap_test' to 'qt_internal_create_command_script' Rework paramerters handling of 'qt_internal_create_command_script', make them named. Add 'qt_internal_create_test_script' to add tests and wrap them using 'qt_internal_create_command_script'. Amends f19266bd02a01d4b7b277ea769c4c17727b1e661 Fixes: QTBUG-88053 Change-Id: I812f4a295005bf3a85cdcb5b8c41180f8249dc96 Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io> (cherry picked from commit d5bafc80cd38202464576f3e0b38de645bb2dc64)
Diffstat (limited to 'cmake')
-rw-r--r--cmake/QtPlatformAndroid.cmake22
-rw-r--r--cmake/QtTestHelpers.cmake224
2 files changed, 168 insertions, 78 deletions
diff --git a/cmake/QtPlatformAndroid.cmake b/cmake/QtPlatformAndroid.cmake
index f9d1835dd3..517b442873 100644
--- a/cmake/QtPlatformAndroid.cmake
+++ b/cmake/QtPlatformAndroid.cmake
@@ -125,10 +125,10 @@ define_property(TARGET
"This variable points to the path of the deployment settings JSON file, which holds properties required by androiddeployqt to package the Android app."
)
-# Add a test for Android which will be run by the android test runner tool
-function(qt_internal_android_add_test target)
+# Returns test execution arguments for Android targets
+function(qt_internal_android_test_arguments target out_test_runner out_test_arguments)
+ set(${out_test_runner} "${QT_HOST_PATH}/bin/androidtestrunner" PARENT_SCOPE)
set(deployment_tool "${QT_HOST_PATH}/bin/androiddeployqt")
- set(test_runner "${QT_HOST_PATH}/bin/androidtestrunner")
get_target_property(deployment_file ${target} QT_ANDROID_DEPLOYMENT_SETTINGS_FILE)
if (NOT deployment_file)
@@ -138,13 +138,13 @@ function(qt_internal_android_add_test target)
set(target_binary_dir "$<TARGET_PROPERTY:${target},BINARY_DIR>")
set(apk_dir "${target_binary_dir}/android-build")
- add_test(NAME "${target}"
- COMMAND "${test_runner}"
- --path "${apk_dir}"
- --adb "${ANDROID_SDK_ROOT}/platform-tools/adb"
- --skip-install-root
- --make "${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR} --target ${target}_make_apk"
- --apk "${apk_dir}/${target}.apk"
- --verbose
+ set(${out_test_arguments}
+ "--path" "${apk_dir}"
+ "--adb" "${ANDROID_SDK_ROOT}/platform-tools/adb"
+ "--skip-install-root"
+ "--make" "${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR} --target ${target}_make_apk"
+ "--apk" "${apk_dir}/${target}.apk"
+ "--verbose"
+ PARENT_SCOPE
)
endfunction()
diff --git a/cmake/QtTestHelpers.cmake b/cmake/QtTestHelpers.cmake
index c43a9aa7a9..061452dd40 100644
--- a/cmake/QtTestHelpers.cmake
+++ b/cmake/QtTestHelpers.cmake
@@ -296,7 +296,8 @@ function(qt_internal_add_test name)
string(REPLACE ";" "\;" plugin_paths_joined "${plugin_paths_joined}")
if (ANDROID)
- qt_internal_android_add_test("${name}")
+ qt_internal_android_test_arguments("${name}" test_executable extra_test_args)
+ set(test_working_dir "${CMAKE_CURRENT_BINARY_DIR}")
else()
if(arg_QMLTEST AND NOT arg_SOURCES)
set(test_working_dir "${CMAKE_CURRENT_SOURCE_DIR}")
@@ -316,20 +317,31 @@ function(qt_internal_add_test name)
#TODO: Should we replace this by TESTARGS environment variable?
list(APPEND extra_test_args "-o" "${name}.xml,xml" "-o" "-,txt")
endif()
+ endif()
- if(arg_NO_WRAPPER OR QT_NO_TEST_WRAPPERS)
- add_test(NAME "${name}" COMMAND ${test_executable} ${extra_test_args}
- WORKING_DIRECTORY "${test_working_dir}")
- else()
- _qt_internal_wrap_test("${name}" "${test_executable}" "${extra_test_args}" "${test_working_dir}"
- ENVIRONMENT "QT_TEST_RUNNING_IN_CTEST" 1
- "PATH" "${test_env_path}"
- "QT_PLUGIN_PATH" "${plugin_paths_joined}")
- endif()
+ if(arg_NO_WRAPPER OR QT_NO_TEST_WRAPPERS)
+ add_test(NAME "${name}" COMMAND ${test_executable} ${extra_test_args}
+ WORKING_DIRECTORY "${test_working_dir}")
+ set_property(TEST "${name}" APPEND PROPERTY
+ ENVIRONMENT "PATH=${test_env_path}"
+ "QT_TEST_RUNNING_IN_CTEST=1"
+ "QT_PLUGIN_PATH=${plugin_paths_joined}"
+ )
+ else()
+ set(test_wrapper_file "${CMAKE_CURRENT_BINARY_DIR}/${name}Wrapper$<CONFIG>.cmake")
+ qt_internal_create_test_script(NAME "${name}"
+ COMMAND "${test_executable}"
+ ARGS "${extra_test_args}"
+ WORKING_DIRECTORY "${test_working_dir}"
+ OUTPUT_FILE "${test_wrapper_file}"
+ ENVIRONMENT "QT_TEST_RUNNING_IN_CTEST" 1
+ "PATH" "${test_env_path}"
+ "QT_PLUGIN_PATH" "${plugin_paths_joined}"
+ )
+ endif()
- if (arg_QT_TEST_SERVER_LIST)
- qt_internal_setup_docker_test_fixture(${name} ${arg_QT_TEST_SERVER_LIST})
- endif()
+ if(arg_QT_TEST_SERVER_LIST AND NOT ANDROID)
+ qt_internal_setup_docker_test_fixture(${name} ${arg_QT_TEST_SERVER_LIST})
endif()
set_tests_properties("${name}" PROPERTIES RUN_SERIAL "${arg_RUN_SERIAL}" LABELS "${label}")
@@ -338,23 +350,13 @@ function(qt_internal_add_test name)
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()
-
- if(ANDROID OR arg_NO_WRAPPER OR QT_NO_TEST_WRAPPERS)
- set_property(TEST "${name}" APPEND PROPERTY ENVIRONMENT
- "PATH=${test_env_path}"
- "QT_TEST_RUNNING_IN_CTEST=1"
- "QT_PLUGIN_PATH=${plugin_paths_joined}"
- )
+ 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()
if(ANDROID OR IOS OR WINRT)
@@ -414,10 +416,115 @@ function(qt_internal_add_test name)
endfunction()
-# This function wraps test with cmake script, that makes possible standalone run with external
+# This function adds test with specified NAME and wraps given test COMMAND with standalone cmake
+# script.
+#
+# NAME must be compatible with add_test function, since it's propagated as is.
+# COMMAND might be either target or path to executable. When test is called either by ctest or
+# directly by 'cmake -P path/to/scriptWrapper.cmake', COMMAND will be executed in specified
+# WORKING_DIRECTORY with arguments specified in ARGS.
+#
+# See also qt_internal_create_command_script for details.
+function(qt_internal_create_test_script)
+ #This style of parsing keeps ';' in ENVIRONMENT variables
+ cmake_parse_arguments(PARSE_ARGV 0 arg
+ ""
+ "NAME;COMMAND;OUTPUT_FILE;WORKING_DIRECTORY"
+ "ARGS;ENVIRONMENT;PRE_RUN;POST_RUN"
+ )
+
+ if(NOT arg_COMMAND)
+ message(FATAL_ERROR "qt_internal_create_test_script: Test COMMAND is not specified")
+ endif()
+
+ if(NOT arg_NAME)
+ message(FATAL_ERROR "qt_internal_create_test_script: Test NAME is not specified")
+ endif()
+
+ if(NOT arg_OUTPUT_FILE)
+ message(FATAL_ERROR "qt_internal_create_test_script: Test Wrapper OUTPUT_FILE\
+is not specified")
+ endif()
+
+ if(arg_PRE_RUN)
+ message(WARNING "qt_internal_create_test_script: PRE_RUN is not acceptable argument\
+for this function. Will be ignored")
+ endif()
+
+ if(arg_POST_RUN)
+ message(WARNING "qt_internal_create_test_script: POST_RUN is not acceptable argument\
+for this function. Will be ignored")
+ endif()
+
+ if(arg_ARGS)
+ set(command_args ${arg_ARGS})# Avoid "${arg_ARGS}" usage and let cmake expand string to
+ # semicolon-separated list
+ qt_internal_wrap_command_arguments(command_args)
+ endif()
+
+ if(TARGET ${arg_COMMAND})
+ set(executable_file "$<TARGET_FILE:${arg_COMMAND}>")
+ else()
+ set(executable_file "${arg_COMMAND}")
+ endif()
+
+ add_test(NAME "${arg_NAME}" COMMAND "${CMAKE_COMMAND}" "-P" "${arg_OUTPUT_FILE}"
+ WORKING_DIRECTORY "${arg_WORKING_DIRECTORY}")
+
+ # If crosscompiling is enabled, we should avoid run cmake in emulator environment.
+ # Prepend emulator to test command in generated cmake script instead. Keep in mind that
+ # CROSSCOMPILING_EMULATOR don't check if actual cross compilation is configured,
+ # emulator is prepended independently.
+ if(CMAKE_CROSSCOMPILING)
+ get_test_property(${arg_NAME} CROSSCOMPILING_EMULATOR crosscompiling_emulator)
+ if(NOT crosscompiling_emulator)
+ set(crosscompiling_emulator "")
+ else()
+ qt_internal_wrap_command_arguments(crosscompiling_emulator)
+ endif()
+ endif()
+
+ qt_internal_create_command_script(COMMAND "${crosscompiling_emulator} \${env_test_runner} \
+\"${executable_file}\" \${env_test_args} ${command_args}"
+ OUTPUT_FILE "${arg_OUTPUT_FILE}"
+ WORKING_DIRECTORY "${arg_WORKING_DIRECTORY}"
+ ENVIRONMENT ${arg_ENVIRONMENT}
+ PRE_RUN "separate_arguments(env_test_args NATIVE_COMMAND \
+\"\$ENV{TESTARGS}\")"
+ "separate_arguments(env_test_runner NATIVE_COMMAND \
+\"\$ENV{TESTRUNNER}\")"
+ )
+endfunction()
+
+# This function wraps COMMAND with cmake script, that makes possible standalone run with external
# arguments.
-function(_qt_internal_wrap_test name test_executable extra_test_args test_working_dir)
- cmake_parse_arguments(PARSE_ARGV 4 arg "" "" "ENVIRONMENT")
+#
+# Generated wrapper will be written to OUTPUT_FILE.
+# If WORKING_DIRECTORY is not set COMMAND will be executed in CMAKE_CURRENT_BINARY_DIR.
+# Variables from ENVIRONMENT will be set before COMMAND execution.
+# PRE_RUN and POST_RUN arguments may contain extra cmake code that supposed to be executed before
+# and after COMMAND, respectively. Both arguments accept a list of cmake script language
+# constructions. Each item of the list will be concantinated into single string with '\n' sepatator.
+function(qt_internal_create_command_script)
+ #This style of parsing keeps ';' in ENVIRONMENT variables
+ cmake_parse_arguments(PARSE_ARGV 0 arg
+ ""
+ "OUTPUT_FILE;WORKING_DIRECTORY"
+ "COMMAND;ENVIRONMENT;PRE_RUN;POST_RUN"
+ )
+
+ if(NOT arg_COMMAND)
+ message(FATAL_ERROR "qt_internal_create_command_script: COMMAND is not specified")
+ endif()
+
+ if(NOT arg_OUTPUT_FILE)
+ message(FATAL_ERROR "qt_internal_create_command_script: Wrapper OUTPUT_FILE\
+is not specified")
+ endif()
+
+ if(NOT arg_WORKING_DIRECTORY)
+ set(arg_WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")
+ endif()
set(environment_extras)
set(skipNext false)
@@ -450,53 +557,36 @@ function(_qt_internal_wrap_test name test_executable extra_test_args test_workin
#Escaping environment variables before expand them by file GENERATE
string(REPLACE "\\" "\\\\" environment_extras "${environment_extras}")
- set(test_wrapper_name "${CMAKE_CURRENT_BINARY_DIR}/${name}Wrapper$<CONFIG>.cmake")
- add_test(NAME "${name}" COMMAND "${CMAKE_COMMAND}" "-P" "${test_wrapper_name}"
- WORKING_DIRECTORY "${test_working_dir}")
-
- if(TARGET ${test_executable})
- set(test_executable_file "$<TARGET_FILE:${test_executable}>")
- else()
- set(test_executable_file "${test_executable}")
- endif()
-
- # If crosscompiling is enabled, we should avoid run cmake in emulator environment.
- # Prepend emulator to test command in generated cmake script instead. Keep in mind that
- # CROSSCOMPILING_EMULATOR don't check if actual cross compilation is configured,
- # emulator is prepended independently.
- if(CMAKE_CROSSCOMPILING)
- get_test_property(${name} CROSSCOMPILING_EMULATOR crosscompiling_emulator)
- if(NOT crosscompiling_emulator)
- set(crosscompiling_emulator "")
- else()
- qt_internal_wrap_command_arguments(crosscompiling_emulator)
- endif()
- endif()
-
if(WIN32)
# It's necessary to call actual test inside 'cmd.exe', because 'execute_process' uses
# SW_HIDE to avoid showing a console window, it affects other GUI as well.
# See https://gitlab.kitware.com/cmake/cmake/-/issues/17690 for details.
- set(extra_test_runner "cmd /c")
+ set(extra_runner "cmd /c")
endif()
- qt_internal_wrap_command_arguments(extra_test_args)
+ if(arg_PRE_RUN)
+ string(JOIN "\n" pre_run ${arg_PRE_RUN})
+ endif()
- file(GENERATE OUTPUT "${test_wrapper_name}" CONTENT
+ if(arg_POST_RUN)
+ string(JOIN "\n" post_run ${arg_POST_RUN})
+ endif()
+
+ file(GENERATE OUTPUT "${arg_OUTPUT_FILE}" CONTENT
"#!${CMAKE_COMMAND} -P
-# Qt generated test wrapper for ${name}
+# Qt generated command wrapper
${environment_extras}
-separate_arguments(test_args NATIVE_COMMAND \"\$ENV{TESTARGS}\")
-separate_arguments(test_runner NATIVE_COMMAND \"\$ENV{TESTRUNNER}\")
-execute_process(COMMAND ${crosscompiling_emulator} ${extra_test_runner} \${test_runner} \
-\"${test_executable_file}\" \${test_args} ${extra_test_args} \
-WORKING_DIRECTORY \"${test_working_dir}\" \
-RESULT_VARIABLE result)
+${pre_run}
+execute_process(COMMAND ${extra_runner} ${arg_COMMAND}
+ WORKING_DIRECTORY \"${arg_WORKING_DIRECTORY}\"
+ RESULT_VARIABLE result
+)
+${post_run}
if(NOT result EQUAL 0)
message(FATAL_ERROR)
endif()"
-)
+ )
endfunction()
# This function creates an executable for use as a helper program with tests. Some