@@ -1,218 +1,312 @@
1−# add_qml_test(path component_name [NO_ADD_TEST] [NO_TARGETS]
1+# If you need to override the qmlscene or qmltestrunner executables,
2−# [TARGETS target1 [target2 [...]]]
2+# create the corresponding executable target.
3−# [IMPORT_PATHS import_path1 [import_path2 [...]]
3+
4−# [PROPERTIES prop1 value1 [prop2 value2 [...]]])
4+# These functions respect the global STDOUT_LOGGER and ARTIFACTS_DIR variables.
6+# You can use those with cmake_parse_arguments
7+# if you need to wrap and mangle arguments.
8+set(QMLTEST_OPTIONS ADD_TEST CACHE INTERNAL "")
9+set(QMLTEST_SINGLE ITERATIONS ARG_PREFIX CACHE INTERNAL "")
10+set(QMLTEST_MULTI ARGS ENVIRONMENT DEPENDS IMPORT_PATHS TARGETS CACHE INTERNAL "")
12+# import_executables(name1 [name2 [...]]
13+# [OPTIONAL] # continue when not found
6−# NO_ADD_TEST will prevent adding the test to the "test" target
16+# This will find the named executables and import them
7−# NO_TARGETS will prevent adding the test to any targets
17+# to an imported target of the same name.
8−# TARGETS lists the targets the test should be added to
18+
9−# IMPORT_PATHS will pass those paths to qmltestrunner as "-import" arguments
19+function(import_executables)
10−# PROPERTIES will be set on the target and test target. See CMake's set_target_properties()
20+ cmake_parse_arguments(QMLTEST "OPTIONAL" "" "" ${ARGN})
22+ foreach(NAME ${QMLTEST_UNPARSED_ARGUMENTS})
23+ if(NOT TARGET ${NAME})
24+ add_executable(${NAME} IMPORTED GLOBAL)
25+ find_program(${NAME}_exe ${NAME})
27+ if(NOT QMLTEST_OPTIONAL AND NOT ${NAME}_exe)
28+ message(FATAL_ERROR "Could not locate ${NAME}.")
29+ elseif(NOT ${NAME}_exe)
30+ message(STATUS "Could not locate ${NAME}, skipping.")
32+ set_target_properties(${NAME} PROPERTIES IMPORTED_LOCATION ${${NAME}_exe})
39+# add_qml_test(path component_name
12−# Two targets will be created:
43+# Add test targets for ${component_name} under ${path}. It's assumed
13−# - testComponentName - Runs the test with qmltestrunner
44+# that the test file is named ${path}/tst_${component_name}.qml.
14−# - tryComponentName - Runs the test with uqmlscene, for manual interaction
45+#
15−# - gdbtestComponentName - Runs the test with qmltestrunner under gdb
46+# This function wraps add_manual_qml_test and add_qml_unittest,
47+# see below for available arguments.
49+function(add_qml_test PATH COMPONENT_NAME)
50+ cmake_parse_arguments(QMLTEST "${QMLTEST_OPTIONS}" "${QMLTEST_SINGLE}" "${QMLTEST_MULTI}" ${ARGN})
53+ add_qml_unittest(${ARGV})
54+ add_manual_qml_test(${ARGV})
58+# add_qml_unittest(path component_name
62+# Add test targets for ${component_name} under ${path}. It's assumed
63+# that the test file is named ${path}/tst_${component_name}.qml.
65+# This function wraps add_executable_test, see below for available arguments.
67+function(add_qml_unittest PATH COMPONENT_NAME)
68+ import_executables(qmltestrunner)
70+ add_executable_test(${COMPONENT_NAME} qmltestrunner
72+ ARGS -input ${CMAKE_CURRENT_SOURCE_DIR}/${PATH}/tst_${COMPONENT_NAME}.qml ${QMLTEST_ARGS}
77+# add_manual_qml_test(path component_name
81+# Add manual test targets for ${component_name} under ${path}. It's assumed
82+# that the test file is named ${path}/tst_${component_name}.qml.
17−# To change/set a default value for the whole test suite, prior to calling add_qml_test, set:
84+# This function wraps add_manual_test, see below for available arguments.
18−# qmltest_DEFAULT_NO_ADD_TEST (default: FALSE)
85+
19−# qmltest_DEFAULT_TARGETS
86+function(add_manual_qml_test PATH COMPONENT_NAME)
20−# qmltest_DEFAULT_IMPORT_PATHS
87+ import_executables(qmlscene)
21−# qmltest_DEFAULT_PROPERTIES
88+ cmake_parse_arguments(QMLTEST "${QMLTEST_OPTIONS}" "${QMLTEST_SINGLE}" "${QMLTEST_MULTI}" ${ARGN})
23−find_program(qmltestrunner_exe qmltestrunner)
90+ add_manual_test(${COMPONENT_NAME} qmlscene
25−if(NOT qmltestrunner_exe)
92+ ARGS ${CMAKE_CURRENT_SOURCE_DIR}/${PATH}/tst_${COMPONENT_NAME}.qml ${QMLTEST_ARGS}
26− msg(FATAL_ERROR "Could not locate qmltestrunner.")
93+ )
97+# add_executable_test(target component_name
98+# [...] # see doc for add_manual_qml_test for common arguments
99+# [ADD_TEST] # whether to add to the "test" target
100+# [ARG_PREFIX arg_prefix] # prefix logging arguments with this string
101+# [ARGS] arg1 [arg2 [...]] # pass these arguments to the test executable
102+# [TARGETS target1 [target2 [...]]] # make the listed targets depend on this test
103+# # if a corresponding xvfbtarget1, xvfbtarget2 etc. exists,
104+# # this test running under xvfb will be added as a dependency
106+# [ITERATIONS count] # run this test as a benchmark for ${count} iterations
109+# Logging options in the standard form of "-o filename,format"
110+# will be appended to the arguments list, prefixed with ARG_PREFIX.
111+# XUnitXML files will be stored in current binary dir or under
112+# ARTIFACTS_DIR, if set.
114+# Three targets will be created:
115+# - test${component_name} - Runs the test
116+# - xvfbtest${component_name} - Runs the test under xvfb
117+# - gdbtest${component_name} - Runs the test under gdb
119+function(add_executable_test COMPONENT_NAME TARGET)
120+ import_executables(gdb xvfb-run OPTIONAL)
122+ cmake_parse_arguments(QMLTEST "${QMLTEST_OPTIONS}" "${QMLTEST_SINGLE}" "${QMLTEST_MULTI}" ${ARGN})
126+ file(RELATIVE_PATH path ${CMAKE_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR})
127+ file(MAKE_DIRECTORY ${ARTIFACTS_DIR}/${path})
128+ set(file_logger -o ${ARTIFACTS_DIR}/${path}/test${COMPONENT_NAME}.xml,xunitxml)
130+ set(file_logger -o ${CMAKE_CURRENT_BINARY_DIR}/test${COMPONENT_NAME}.xml,xunitxml)
29−set(qmlscene_exe ${CMAKE_BINARY_DIR}/tests/uqmlscene/uqmlscene)
133+ bake_arguments("${QMLTEST_ARG_PREFIX}" args ${iterations} ${file_logger} ${STDOUT_LOGGER})
31−set(test_env LC_ALL=C UNITY_TESTING=1)
135+ set(qmltest_command
32−
136+ $<TARGET_FILE:${TARGET}>
33−macro(add_manual_qml_test SUBPATH COMPONENT_NAME)
137+ ${QMLTEST_ARGS}
34− set(options NO_ADD_TEST NO_TARGETS)
138+ ${args}
35− set(multi_value_keywords IMPORT_PATHS TARGETS PROPERTIES ENVIRONMENT)
139+ )
37− cmake_parse_arguments(qmltest "${options}" "" "${multi_value_keywords}" ${ARGN})
141+ add_qmltest_target(test${COMPONENT_NAME} ${TARGET}
38− cmake_parse_arguments(qmltest_default "${options}" "" "${multi_value_keywords}" ${qmltest_DEFAULT_PROPERTIES})
142+ COMMAND ${qmltest_command}
40− set(qmlscene_TARGET try${COMPONENT_NAME})
144+ ENVIRONMENT QML2_IMPORT_PATH=${imports} ${QMLTEST_ENVIRONMENT}
41− set(qmltest_FILE ${SUBPATH}/tst_${COMPONENT_NAME})
145+ ${add_test}
43− set(qmlscene_imports "")
147+ )
44− if(NOT "${qmltest_IMPORT_PATHS}" STREQUAL "")
148+
45− foreach(IMPORT_PATH ${qmltest_IMPORT_PATHS})
149+ if(TARGET xvfb-run)
46− list(APPEND qmlscene_imports "-I")
150+ add_qmltest_target(xvfbtest${COMPONENT_NAME} ${TARGET}
47− list(APPEND qmlscene_imports ${IMPORT_PATH})
151+ COMMAND $<TARGET_FILE:xvfb-run> --server-args "-screen 0 1024x768x24" --auto-servernum ${qmltest_command}
48− endforeach(IMPORT_PATH)
152+ ${depends}
49− elseif(NOT "${qmltest_DEFAULT_IMPORT_PATHS}" STREQUAL "")
153+ ENVIRONMENT QML2_IMPORT_PATH=${imports} ${QMLTEST_ENVIRONMENT} LD_PRELOAD=/usr/lib/${CMAKE_LIBRARY_ARCHITECTURE}/mesa/libGL.so.1
50− foreach(IMPORT_PATH ${qmltest_DEFAULT_IMPORT_PATHS})
154+ TARGETS ${xvfb_targets}
51− list(APPEND qmlscene_imports "-I")
155+ )
52− list(APPEND qmlscene_imports ${IMPORT_PATH})
53− endforeach(IMPORT_PATH)
56− if("${qmltest_ENVIRONMENT}" STREQUAL "")
158+ if(TARGET gdb)
57− set(qmltest_ENVIRONMENT "${qmltest_default_ENVIRONMENT}")
159+ add_qmltest_target(gdbtest${COMPONENT_NAME} ${TARGET}
160+ COMMAND $<TARGET_FILE:gdb> -ex run -args ${qmltest_command}
162+ ENVIRONMENT QML2_IMPORT_PATH=${imports} ${QMLTEST_ENVIRONMENT}
168+# add_manual_test(target component_name
169+# [DEPENDS target1 [target2 [...]]] # make this test depend on the specified targets
170+# [IMPORT_PATHS import_path1 [import_path2 [...]] # use these QML import paths
171+# # (they're searched first to last)
172+# [ENVIRONMENT var1=value1 [var2=value2 [...]]] # set these environment variables
175+# Two targets will be created:
176+# - try${component_name} - Runs the test for manual interaction
177+# - gdbtry${component_name} - Runs the test under gdb
179+function(add_manual_test COMPONENT_NAME TARGET)
180+ import_executables(gdb OPTIONAL)
182+ cmake_parse_arguments(QMLTEST "${QMLTEST_OPTIONS}" "${QMLTEST_SINGLE}" "${QMLTEST_MULTI}" ${ARGN})
185+ bake_arguments("${QMLTEST_ARG_PREFIX}" args -qmljsdebugger=port:3768)
188+ $<TARGET_FILE:${TARGET}>
60− set(qmlscene_command
193+ add_qmltest_target(try${COMPONENT_NAME} ${TARGET}
61− env ${test_env} ${qmltest_ENVIRONMENT}
194+ COMMAND ${qmltry_command}
62− ${qmlscene_exe} -qmljsdebugger=port:3768 ${CMAKE_CURRENT_SOURCE_DIR}/${qmltest_FILE}.qml
195+ ${depends}
63− ${qmlscene_imports}
196+ ENVIRONMENT QML2_IMPORT_PATH=${imports} ${QMLTEST_ENVIRONMENT}
65− add_custom_target(${qmlscene_TARGET} ${qmlscene_command})
198+
67−endmacro(add_manual_qml_test)
200+ add_qmltest_target(gdbtry${COMPONENT_NAME} ${TARGET}
68−
201+ COMMAND $<TARGET_FILE:gdb> -ex run -args ${qmltry_command}
69−macro(add_qml_benchmark SUBPATH COMPONENT_NAME ITERATIONS)
202+ ${depends}
70− add_qml_test_internal(${SUBPATH} ${COMPONENT_NAME} ${ITERATIONS} ${ARGN})
203+ ENVIRONMENT QML2_IMPORT_PATH=${imports} ${QMLTEST_ENVIRONMENT}
71−endmacro(add_qml_benchmark)
204+ )
73−macro(add_qml_test SUBPATH COMPONENT_NAME)
74− add_qml_test_internal(${SUBPATH} ${COMPONENT_NAME} 0 ${ARGN})
75−endmacro(add_qml_test)
77−macro(add_qml_test_internal SUBPATH COMPONENT_NAME ITERATIONS)
78− set(options NO_ADD_TEST NO_TARGETS)
79− set(multi_value_keywords IMPORT_PATHS TARGETS PROPERTIES ENVIRONMENT)
81− cmake_parse_arguments(qmltest "${options}" "" "${multi_value_keywords}" ${ARGN})
82− cmake_parse_arguments(qmltest_default "${options}" "" "${multi_value_keywords}" ${qmltest_DEFAULT_PROPERTIES})
84− set(qmltest_TARGET test${COMPONENT_NAME})
85− set(qmltest_gdb_TARGET gdbtest${COMPONENT_NAME})
86− set(qmltest_xvfb_TARGET xvfbtest${COMPONENT_NAME})
87− set(qmltest_FILE ${SUBPATH}/tst_${COMPONENT_NAME})
89− set(qmltestrunner_imports "")
90− if(NOT "${qmltest_IMPORT_PATHS}" STREQUAL "")
91− foreach(IMPORT_PATH ${qmltest_IMPORT_PATHS})
92− list(APPEND qmltestrunner_imports "-import")
93− list(APPEND qmltestrunner_imports ${IMPORT_PATH})
94− endforeach(IMPORT_PATH)
95− elseif(NOT "${qmltest_DEFAULT_IMPORT_PATHS}" STREQUAL "")
96− foreach(IMPORT_PATH ${qmltest_DEFAULT_IMPORT_PATHS})
97− list(APPEND qmltestrunner_imports "-import")
98− list(APPEND qmltestrunner_imports ${IMPORT_PATH})
99− endforeach(IMPORT_PATH)
209+################### INTERNAL ####################
211+# add_qmltest_target(target_name target
212+# COMMAND test_exe [arg1 [...]] # execute this test with arguments
213+# [...] # see above for available arguments:
214+# # ADD_TEST, ENVIRONMENT, DEPENDS and TARGETS
217+function(add_qmltest_target TARGET_NAME TARGET)
218+ cmake_parse_arguments(QMLTEST "${QMLTEST_OPTIONS}" "${QMLTEST_SINGLE}" "COMMAND;${QMLTEST_MULTI}" ${ARGN})
221+ # Additional arguments
102 string(TOLOWER "${CMAKE_GENERATOR}" cmake_generator_lower)
222 string(TOLOWER "${CMAKE_GENERATOR}" cmake_generator_lower)
103 if(cmake_generator_lower STREQUAL "unix makefiles")
223 if(cmake_generator_lower STREQUAL "unix makefiles")
104− set(function_ARGS $(FUNCTION))
224+ set(function "$(FUNCTION)")
106− set(function_ARGS "")
109− if (${ITERATIONS} GREATER 0)
227+ add_custom_target(${TARGET_NAME}
110− set(ITERATIONS_STRING "-iterations" ${ITERATIONS})
228+ env ${QMLTEST_ENVIRONMENT}
111− else()
229+ ${QMLTEST_COMMAND} ${function}
112− set(ITERATIONS_STRING "")
230+ DEPENDS ${TARGET} ${QMLTEST_DEPENDS}
233+ if(QMLTEST_ADD_TEST)
236+ COMMAND ${QMLTEST_COMMAND}
239+ foreach(ENV ${QMLTEST_ENVIRONMENT})
240+ set_property(TEST ${TARGET_NAME} APPEND PROPERTY ENVIRONMENT ${ENV})
243+ set_property(TEST ${TARGET_NAME} APPEND PROPERTY DEPENDS ${TARGET})
244+ foreach(DEPEND ${DEPENDS})
245+ set_property(TEST ${TARGET_NAME} APPEND PROPERTY DEPENDS ${DEPEND})
115− if("${qmltest_ENVIRONMENT}" STREQUAL "")
249+ foreach(UPSTREAM_TARGET ${QMLTEST_TARGETS})
116− set(qmltest_ENVIRONMENT "${qmltest_default_ENVIRONMENT}")
250+ add_dependencies(${UPSTREAM_TARGET} ${TARGET_NAME})
255+# mangle_arguments(${ARGN})
257+# Verify there were no unparsed arguments and
258+# mangle the known ones for further processing.
260+macro(mangle_arguments)
261+ if(QMLTEST_UNPARSED_ARGUMENTS)
262+ message(FATAL_ERROR "Unexpected arguments: ${QMLTEST_UNPARSED_ARGUMENTS}")
119− set(qmltest_command
265+ if(QMLTEST_ADD_TEST)
120− env ${test_env} ${qmltest_ENVIRONMENT}
266+ set(add_test ADD_TEST)
121− ${qmltestrunner_exe} -input ${CMAKE_CURRENT_SOURCE_DIR}/${qmltest_FILE}.qml
122− ${qmltestrunner_imports}
123− ${ITERATIONS_STRING}
124− -o ${CMAKE_BINARY_DIR}/${qmltest_TARGET}.xml,xunitxml
128− find_program(DPKG dpkg-architecture)
130− exec_program(${DPKG} ARGS "-qDEB_BUILD_MULTIARCH" OUTPUT_VARIABLE ARCH_TRIPLET )
131− set(LD_PRELOAD_PATH "LD_PRELOAD=/usr/lib/${ARCH_TRIPLET}/mesa/libGL.so.1")
133− set(qmltest_xvfb_command
134− env ${test_env} ${qmltest_ENVIRONMENT} ${LD_PRELOAD_PATH}
135− xvfb-run --server-args "-screen 0 1024x768x24" --auto-servernum
136− ${qmltestrunner_exe} -input ${CMAKE_CURRENT_SOURCE_DIR}/${qmltest_FILE}.qml
137− ${qmltestrunner_imports}
138− -o ${CMAKE_BINARY_DIR}/${qmltest_TARGET}.xml,xunitxml
143− set(qmltest_gdb_command
269+ if(QMLTEST_IMPORT_PATHS)
144− env ${test_env} ${qmltest_ENVIRONMENT} ${LD_PRELOAD_PATH}
270+ string(REPLACE ";" ":" imports "${QMLTEST_IMPORT_PATHS}")
145− gdb -e ${qmltestrunner_exe} -ex \"run -input ${CMAKE_CURRENT_SOURCE_DIR}/${qmltest_FILE}.qml ${qmltestrunner_imports} ${ITERATIONS_STRING}\"
271+ endif()
148− add_qmltest_target(${qmltest_TARGET} "${qmltest_command}" TRUE ${qmltest_NO_ADD_TEST})
273+ if(QMLTEST_ITERATIONS)
149− add_qmltest_target(${qmltest_xvfb_TARGET} "${qmltest_xvfb_command}" ${qmltest_NO_TARGETS} TRUE)
274+ set(iterations -iterations ${QMLTEST_ITERATIONS})
150− add_qmltest_target(${qmltest_gdb_TARGET} "${qmltest_gdb_command}" TRUE TRUE)
151− add_manual_qml_test(${SUBPATH} ${COMPONENT_NAME} ${ARGN})
152−endmacro(add_qml_test_internal)
154−macro(add_binary_qml_test CLASS_NAME LD_PATH DEPS ENVVAR)
157− LD_LIBRARY_PATH=${LD_PATH}
160− -t ${CMAKE_CURRENT_BINARY_DIR}/${CLASS_NAME}TestExec
161− -p -o -p ${CMAKE_BINARY_DIR}/test${CLASS_NAME}.xml,xunitxml
164− add_qmltest_target(test${CLASS_NAME} "${testCommand}" FALSE TRUE)
165− add_dependencies(test${CLASS_NAME} ${CLASS_NAME}TestExec ${DEPS})
167− find_program( HAVE_GCC gcc )
168− if (NOT ${HAVE_GCC} STREQUAL "")
169− exec_program( gcc ARGS "-dumpmachine" OUTPUT_VARIABLE ARCH_TRIPLET )
170− set(LD_PRELOAD_PATH "LD_PRELOAD=/usr/lib/${ARCH_TRIPLET}/mesa/libGL.so.1")
172− set(xvfbtestCommand
276+
173− ${LD_PRELOAD_PATH}
277+ if(QMLTEST_DEPENDS)
174− ${ENVVAR}
278+ set(depends DEPENDS ${QMLTEST_DEPENDS})
175− LD_LIBRARY_PATH=${LD_PATH}
176− xvfb-run --server-args "-screen 0 1024x768x24" --auto-servernum
179− -t ${CMAKE_CURRENT_BINARY_DIR}/${CLASS_NAME}TestExec
180− -p -o -p ${CMAKE_BINARY_DIR}/test${CLASS_NAME}.xml,xunitxml
183− add_qmltest_target(xvfbtest${CLASS_NAME} "${xvfbtestCommand}" FALSE TRUE)
184− add_dependencies(qmluitests xvfbtest${CLASS_NAME})
185−endmacro(add_binary_qml_test)
187−macro(add_qmltest_target qmltest_TARGET qmltest_command qmltest_NO_TARGETS qmltest_NO_ADD_TEST)
188− add_custom_target(${qmltest_TARGET} ${qmltest_command})
190− if(NOT "${qmltest_PROPERTIES}" STREQUAL "")
191− set_target_properties(${qmltest_TARGET} PROPERTIES ${qmltest_PROPERTIES})
192− elseif(NOT "${qmltest_DEFAULT_PROPERTIES}" STREQUAL "")
193− set_target_properties(${qmltest_TARGET} PROPERTIES ${qmltest_DEFAULT_PROPERTIES})
196− if("${qmltest_NO_ADD_TEST}" STREQUAL FALSE AND NOT "${qmltest_DEFAULT_NO_ADD_TEST}" STREQUAL "TRUE")
281+ if(QMLTEST_TARGETS)
197− add_test(${qmltest_TARGET} ${qmltest_command})
282+ set(targets TARGETS ${QMLTEST_TARGETS})
199− if(NOT "${qmltest_UNPARSED_ARGUMENTS}" STREQUAL "")
285+ set(xvfb_targets "")
200− set_tests_properties(${qmltest_TARGET} PROPERTIES ${qmltest_PROPERTIES})
286+ foreach(target ${QMLTEST_TARGETS})
201− elseif(NOT "${qmltest_DEFAULT_PROPERTIES}" STREQUAL "")
287+ if(TARGET xvfb${target})
202− set_tests_properties(${qmltest_TARGET} PROPERTIES ${qmltest_DEFAULT_PROPERTIES})
288+ list(APPEND xvfb_targets xvfb${target})
204− endif("${qmltest_NO_ADD_TEST}" STREQUAL FALSE AND NOT "${qmltest_DEFAULT_NO_ADD_TEST}" STREQUAL "TRUE")
206− if("${qmltest_NO_TARGETS}" STREQUAL "FALSE")
207− if(NOT "${qmltest_TARGETS}" STREQUAL "")
208− foreach(TARGET ${qmltest_TARGETS})
209− add_dependencies(${TARGET} ${qmltest_TARGET})
210− endforeach(TARGET)
290+ endforeach()
211− elseif(NOT "${qmltest_DEFAULT_TARGETS}" STREQUAL "")
291+ set(xvfb_targets "${xvfb_targets}" PARENT_SCOPE)
212− foreach(TARGET ${qmltest_DEFAULT_TARGETS})
292+endmacro()
213− add_dependencies(${TARGET} ${qmltest_TARGET})
293+
216− endif("${qmltest_NO_TARGETS}" STREQUAL "FALSE")
218−endmacro(add_qmltest_target)
295+# bake_arguments(prefix output
299+# If set, add the argument prefix before every passed
300+# argument and store the result in ${OUTPUT} variable.
302+function(bake_arguments PREFIX OUTPUT)
306+ foreach(arg ${ARGN})
307+ list(APPEND args ${PREFIX})
308+ list(APPEND args ${arg})
311+ set(${OUTPUT} "${args}" PARENT_SCOPE)