@@ -55,6 +55,55 @@ function(add_qml_test PATH COMPONENT_NAME)
5555endfunction()
5656
5757
58+# add_qml_test_data(path component_name
59+# [...]
60+# )
61+#
62+# Install file called ${component_name} (or ${component_name}.qml) under
63+# ${path}.
64+
65+function(add_qml_test_data PATH COMPONENT_NAME)
66+ cmake_parse_arguments(TEST "" "DESTINATION" "" ${ARGN})
67+
68+ set(filename "${CMAKE_CURRENT_SOURCE_DIR}/${PATH}/${COMPONENT_NAME}")
69+
70+ if (IS_DIRECTORY "${filename}")
71+ # As a convenience, allow specifying a directory and we will install
72+ # all files in the dir. We do it this way rather than passing
73+ # DIRECTORY to install() because we want to process any qml files.
74+ file(GLOB subfiles RELATIVE "${filename}" "${filename}/*")
75+ foreach(subfile ${subfiles})
76+ add_qml_test_data("${PATH}/${COMPONENT_NAME}" "${subfile}")
77+ endforeach()
78+ return()
79+ endif()
80+
81+ if (NOT EXISTS "${filename}")
82+ set(filename "${filename}.qml")
83+ set(COMPONENT_NAME "${COMPONENT_NAME}.qml")
84+ endif()
85+
86+ if ("${filename}" MATCHES "\\.qml$")
87+ file(READ "${filename}" contents)
88+ string(REGEX REPLACE "(\"[./]*)/qml(/|\")" "\\1\\2" contents "${contents}")
89+ # this is for (at least) cardcreatortest which pulls in an architecture-specific
90+ # import into the plugins directory (which is a 'qml' once installed).
91+ string(REGEX REPLACE "(import \"[./]*)/plugins(/|\")" "\\1/qml\\2" contents "${contents}")
92+ set(filename "${CMAKE_CURRENT_BINARY_DIR}/${PATH}/${COMPONENT_NAME}")
93+ file(WRITE "${filename}" "${contents}")
94+ endif()
95+
96+ if (TEST_DESTINATION)
97+ set(DESTINATION "${TEST_DESTINATION}")
98+ else()
99+ file(RELATIVE_PATH relcurpath "${CMAKE_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}")
100+ set(DESTINATION "${SHELL_APP_DIR}/${relcurpath}/${PATH}")
101+ endif()
102+
103+ install(FILES "${filename}" DESTINATION "${DESTINATION}")
104+endfunction()
105+
106+
58107# add_qml_unittest(path component_name
59108# [...]
60109# )
@@ -71,6 +120,10 @@ function(add_qml_unittest PATH COMPONENT_NAME)
71120 ${ARGN}
72121 ARGS -input ${CMAKE_CURRENT_SOURCE_DIR}/${PATH}/tst_${COMPONENT_NAME}.qml ${QMLTEST_ARGS}
73122 )
123+
124+ if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${PATH}/tst_${COMPONENT_NAME}.qml")
125+ add_qml_test_data("${PATH}" "tst_${COMPONENT_NAME}.qml")
126+ endif()
74127endfunction()
75128
76129
@@ -91,6 +144,10 @@ function(add_manual_qml_test PATH COMPONENT_NAME)
91144 ${ARGN}
92145 ARGS ${CMAKE_CURRENT_SOURCE_DIR}/${PATH}/tst_${COMPONENT_NAME}.qml ${QMLTEST_ARGS}
93146 )
147+
148+ if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${PATH}/tst_${COMPONENT_NAME}.qml")
149+ add_qml_test_data("${PATH}" "tst_${COMPONENT_NAME}.qml")
150+ endif()
94151endfunction()
95152
96153
@@ -108,8 +165,7 @@ endfunction()
108165#
109166# Logging options in the standard form of "-o filename,format"
110167# 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.
168+# XUnitXML files will be stored in current binary dir.
113169#
114170# Three targets will be created:
115171# - test${component_name} - Runs the test
@@ -122,14 +178,8 @@ function(add_executable_test COMPONENT_NAME TARGET)
122178 cmake_parse_arguments(QMLTEST "${QMLTEST_OPTIONS}" "${QMLTEST_SINGLE}" "${QMLTEST_MULTI}" ${ARGN})
123179 mangle_arguments()
124180
125− if(ARTIFACTS_DIR)
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)
129− else()
130− file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
131− set(file_logger -o ${CMAKE_CURRENT_BINARY_DIR}/test${COMPONENT_NAME}.xml,xunitxml)
132− endif()
181+ file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
182+ set(file_logger -o ${CMAKE_CURRENT_BINARY_DIR}/test${COMPONENT_NAME}.xml,xunitxml)
133183
134184 bake_arguments("${QMLTEST_ARG_PREFIX}" args ${iterations} ${file_logger} ${STDOUT_LOGGER})
135185
@@ -207,8 +257,124 @@ function(add_manual_test COMPONENT_NAME TARGET)
207257endfunction()
208258
209259
260+# add_meta_test(target)
261+#
262+# Adds a test target that will run one of our "meta" test targets, like
263+# xvfbuitests. This script will run the specified suite of tests on an
264+# installed system.
265+
266+function(add_meta_test TARGET_NAME)
267+ cmake_parse_arguments(TEST "" "" "DEPENDS" ${ARGN})
268+
269+ add_custom_target(${TARGET_NAME})
270+
271+ set(filename "${CMAKE_BINARY_DIR}/tests/scripts/${TARGET_NAME}.sh")
272+ file(WRITE "${filename}" "#!/usr/bin/parallel --shebang --no-notice\n\n")
273+
274+ add_meta_dependencies(${TARGET_NAME} DEPENDS ${TEST_DEPENDS})
275+ # else we will write the rest of the script as we add cmake targets
276+
277+ install(FILES "${filename}"
278+ PERMISSIONS OWNER_EXECUTE OWNER_READ OWNER_WRITE
279+ GROUP_EXECUTE GROUP_READ
280+ WORLD_EXECUTE WORLD_READ
281+ DESTINATION "${SHELL_PRIVATE_LIBDIR}/tests/scripts"
282+ )
283+endfunction()
284+
285+
210286################### INTERNAL ####################
211287
288+function(install_test_script TARGET_NAME)
289+ cmake_parse_arguments(TEST "" "" "COMMAND;ENVIRONMENT" ${ARGN})
290+
291+ # Now write the above test into a shell script that we can run on an
292+ # installed system.
293+ set(script "#!/bin/sh\n\nset -x\n\n")
294+ foreach(ONE_ENV ${TEST_ENVIRONMENT})
295+ set(script "${script}export ${ONE_ENV}\n")
296+ endforeach()
297+ set(script "${script}export UNITY_TESTING_DATADIR=\"${CMAKE_INSTALL_PREFIX}/${SHELL_APP_DIR}\"\n")
298+ set(script "${script}export UNITY_TESTING_LIBDIR=\"${CMAKE_INSTALL_PREFIX}/${SHELL_PRIVATE_LIBDIR}\"\n")
299+ set(script "${script}\n")
300+ set(script "${script}XML_ARGS=\n")
301+ set(script "${script}if [ -n \"\$ARTIFACTS_DIR\" ]; then\n")
302+ set(script "${script} XML_ARGS=\"@XML_ARGS@\"\n")
303+ set(script "${script} mkdir -p \"@XML_DIR@\"\n")
304+ set(script "${script} touch \"@XML_FILE@\"\n")
305+ set(script "${script}fi\n")
306+ set(script "${script}\n")
307+ foreach(ONE_CMD ${TEST_COMMAND})
308+ set(script "${script}'${ONE_CMD}' ")
309+ endforeach()
310+
311+ set(filename "${CMAKE_BINARY_DIR}/tests/scripts/${TARGET_NAME}.sh")
312+
313+ # Generate script to file then read it back to resolve any generator
314+ # expressions before we try to replace paths.
315+ file(GENERATE
316+ OUTPUT "${filename}"
317+ CONTENT "${script}"
318+ )
319+
320+ # Do replacement at install time to save needless work and to make sure
321+ # we are modifying file after generate step above (which doesn't happen
322+ # immediately). We can't use a custom-defined function or macro here...
323+ # So instead we use a giant ugly code block.
324+
325+ # START OF CODE BLOCK --------------------------------------------------
326+ install(CODE "
327+ file(READ \"${filename}\" replacestr)
328+
329+ # Now some replacements...
330+ # tests like to write xml output to our builddir; we don't need that, but we do want them in ARTIFACTS_DIR
331+ string(REGEX MATCH \"( '--parameter')? '-o'( '--parameter')? '[^']*,xunitxml' \" xmlargs \"\${replacestr}\")
332+ string(REGEX REPLACE \"( '--parameter')? '-o'( '--parameter')? '[^']*,xunitxml' \" \" \\\$XML_ARGS \" replacestr \"\${replacestr}\")
333+ string(REGEX REPLACE \"'[^']*/tests/\" \"'\\\$ARTIFACTS_DIR/tests/\" xmlargs \"\${xmlargs}\")
334+ string(REGEX REPLACE \".*'([^']*),xunitxml'.*\" \"\\\\1\" xmlfile \"\${xmlargs}\")
335+ string(REGEX REPLACE \"(.*)/[^/]*\" \"\\\\1\" xmldir \"\${xmlfile}\")
336+ string(REGEX REPLACE \"'\" \"\" xmlargs \"\${xmlargs}\") # strip single quotes
337+ string(REGEX REPLACE \"@XML_ARGS@\" \"\${xmlargs}\" replacestr \"\${replacestr}\")
338+ string(REGEX REPLACE \"@XML_DIR@\" \"\${xmldir}\" replacestr \"\${replacestr}\")
339+ string(REGEX REPLACE \"@XML_FILE@\" \"\${xmlfile}\" replacestr \"\${replacestr}\")
340+ # replace build/source roots with their install paths
341+ string(REPLACE \"${CMAKE_BINARY_DIR}/libs\" \"${CMAKE_INSTALL_PREFIX}/${SHELL_PRIVATE_LIBDIR}\" replacestr \"\${replacestr}\")
342+ string(REPLACE \"${CMAKE_BINARY_DIR}/plugins\" \"${CMAKE_INSTALL_PREFIX}/${SHELL_INSTALL_QML}\" replacestr \"\${replacestr}\")
343+ string(REPLACE \"${CMAKE_BINARY_DIR}/tests/libs\" \"${CMAKE_INSTALL_PREFIX}/${SHELL_PRIVATE_LIBDIR}/tests/libs\" replacestr \"\${replacestr}\")
344+ string(REPLACE \"${CMAKE_BINARY_DIR}/tests/mocks\" \"${CMAKE_INSTALL_PREFIX}/${SHELL_INSTALL_QML}/mocks\" replacestr \"\${replacestr}\")
345+ string(REPLACE \"${CMAKE_BINARY_DIR}/tests/plugins\" \"${CMAKE_INSTALL_PREFIX}/${SHELL_PRIVATE_LIBDIR}/tests/plugins\" replacestr \"\${replacestr}\")
346+ string(REPLACE \"${CMAKE_BINARY_DIR}/tests/qmltests\" \"${CMAKE_INSTALL_PREFIX}/${SHELL_PRIVATE_LIBDIR}/tests/qmltests\" replacestr \"\${replacestr}\")
347+ string(REPLACE \"${CMAKE_BINARY_DIR}/tests/uqmlscene\" \"${CMAKE_INSTALL_PREFIX}/${SHELL_PRIVATE_LIBDIR}\" replacestr \"\${replacestr}\")
348+ string(REPLACE \"${CMAKE_BINARY_DIR}/tests/utils/modules\" \"${CMAKE_INSTALL_PREFIX}/${SHELL_INSTALL_QML}/utils\" replacestr \"\${replacestr}\")
349+ string(REPLACE \"${CMAKE_SOURCE_DIR}/tests/plugins\" \"${CMAKE_INSTALL_PREFIX}/${SHELL_APP_DIR}/tests/plugins\" replacestr \"\${replacestr}\")
350+ string(REPLACE \"${CMAKE_SOURCE_DIR}/tests/qmltests\" \"${CMAKE_INSTALL_PREFIX}/${SHELL_APP_DIR}/tests/qmltests\" replacestr \"\${replacestr}\")
351+
352+ file(WRITE \"${filename}\" \"\${replacestr}\")
353+ ")
354+ # END OF CODE BLOCK --------------------------------------------------
355+
356+ install(FILES "${filename}"
357+ PERMISSIONS OWNER_EXECUTE OWNER_READ OWNER_WRITE
358+ GROUP_EXECUTE GROUP_READ
359+ WORLD_EXECUTE WORLD_READ
360+ DESTINATION "${SHELL_PRIVATE_LIBDIR}/tests/scripts"
361+ )
362+endfunction()
363+
364+function(add_meta_dependencies UPSTREAM_TARGET)
365+ cmake_parse_arguments(TEST "" "" "DEPENDS" ${ARGN})
366+
367+ foreach(depend ${TEST_DEPENDS})
368+ add_dependencies(${UPSTREAM_TARGET} ${depend})
369+
370+ # add depend to the meta test script that we will install on system
371+ set(filename "${CMAKE_BINARY_DIR}/tests/scripts/${UPSTREAM_TARGET}.sh")
372+ if (EXISTS "${filename}")
373+ file(APPEND "${filename}" "${CMAKE_INSTALL_PREFIX}/${SHELL_PRIVATE_LIBDIR}/tests/scripts/${depend}.sh\n")
374+ endif()
375+ endforeach()
376+endfunction()
377+
212378# add_qmltest_target(target_name target
213379# COMMAND test_exe [arg1 [...]] # execute this test with arguments
214380# [...] # see above for available arguments:
@@ -231,6 +397,11 @@ function(add_qmltest_target TARGET_NAME TARGET)
231397 DEPENDS ${TARGET} ${QMLTEST_DEPENDS}
232398 )
233399
400+ install_test_script(${TARGET_NAME}
401+ ENVIRONMENT ${QMLTEST_ENVIRONMENT}
402+ COMMAND ${QMLTEST_COMMAND}
403+ )
404+
234405 if(QMLTEST_ADD_TEST)
235406 add_test(
236407 NAME ${TARGET_NAME}
@@ -248,7 +419,7 @@ function(add_qmltest_target TARGET_NAME TARGET)
248419 endif()
249420
250421 foreach(UPSTREAM_TARGET ${QMLTEST_TARGETS})
251− add_dependencies(${UPSTREAM_TARGET} ${TARGET_NAME})
422+ add_meta_dependencies(${UPSTREAM_TARGET} DEPENDS ${TARGET_NAME})
252423 endforeach()
253424endfunction()
254425