Merge lp:~saviq/unity8/wrap-qmltestrunner into lp:unity8

Proposed by Michał Sawicz
Status: Work in progress
Proposed branch: lp:~saviq/unity8/wrap-qmltestrunner
Merge into: lp:unity8
Diff against target: 252 lines (+138/-17)
5 files modified
cmake/modules/QmlTest.cmake (+36/-14)
tests/CMakeLists.txt (+1/-1)
tests/plugins/LightDM/CMakeLists.txt (+0/-2)
tests/qmltests/CMakeLists.txt (+7/-0)
tools/qmltest_wrapper.py (+94/-0)
To merge this branch: bzr merge lp:~saviq/unity8/wrap-qmltestrunner
Reviewer Review Type Date Requested Status
Michael Zanetti Pending
Review via email: mp+217972@code.launchpad.net

Commit message

Enable autopkgtest for graphical QML tests.

To post a comment you must log in.
lp:~saviq/unity8/wrap-qmltestrunner updated
873. By Michał Sawicz

Fix timeout handling.

874. By Michał Sawicz

Disable lightdm dbus test for now.

Unmerged revisions

874. By Michał Sawicz

Disable lightdm dbus test for now.

873. By Michał Sawicz

Fix timeout handling.

872. By Michał Sawicz

Make wrapper executable.

871. By Michał Sawicz

Refactor how qmltestrunner and qmlscene paths are determined to allow overriding.

870. By Michał Sawicz

Introduce qmltest_wrapper.py to record a vido of failed qmltest output.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'cmake/modules/QmlTest.cmake'
--- cmake/modules/QmlTest.cmake 2014-04-29 15:17:21 +0000
+++ cmake/modules/QmlTest.cmake 2014-05-01 21:22:23 +0000
@@ -19,13 +19,31 @@
19# qmltest_DEFAULT_IMPORT_PATHS19# qmltest_DEFAULT_IMPORT_PATHS
20# qmltest_DEFAULT_PROPERTIES20# qmltest_DEFAULT_PROPERTIES
2121
22find_program(qmltestrunner_exe qmltestrunner)22if(NOT TARGET qmltestrunner)
2323 find_program(qmltestrunner_exe qmltestrunner)
24if(NOT qmltestrunner_exe)24
25 msg(FATAL_ERROR "Could not locate qmltestrunner.")25 if(NOT qmltestrunner_exe)
26endif()26 msg(FATAL_ERROR "Could not locate qmltestrunner.")
2727 endif()
28set(qmlscene_exe ${CMAKE_BINARY_DIR}/tests/uqmlscene/uqmlscene)28
29 add_executable(qmltestrunner IMPORTED)
30 set_target_properties(qmltestrunner PROPERTIES IMPORTED_LOCATION ${qmltestrunner_exe})
31endif()
32
33if(NOT TARGET qmlscene)
34 find_program(qmlscene_exe qmlscene)
35
36 if(NOT qmlscene_exe)
37 msg(FATAL_ERROR "Could not locate qmlscene.")
38 endif()
39
40 add_executable(qmlscene IMPORTED)
41 set_target_properties(qmlscene PROPERTIES IMPORTED_LOCATION ${qmlscene_exe})
42endif()
43
44if(NOT DEFINED ARTIFACTS_DIR)
45 set(ARTIFACTS_DIR ${CMAKE_BINARY_DIR})
46endif()
2947
30macro(add_manual_qml_test SUBPATH COMPONENT_NAME)48macro(add_manual_qml_test SUBPATH COMPONENT_NAME)
31 set(options NO_ADD_TEST NO_TARGETS)49 set(options NO_ADD_TEST NO_TARGETS)
@@ -33,6 +51,8 @@
3351
34 cmake_parse_arguments(qmltest "${options}" "" "${multi_value_keywords}" ${ARGN})52 cmake_parse_arguments(qmltest "${options}" "" "${multi_value_keywords}" ${ARGN})
3553
54 get_target_property(qmlscene_executable qmlscene LOCATION)
55
36 set(qmlscene_TARGET try${COMPONENT_NAME})56 set(qmlscene_TARGET try${COMPONENT_NAME})
37 set(qmltest_FILE ${SUBPATH}/tst_${COMPONENT_NAME})57 set(qmltest_FILE ${SUBPATH}/tst_${COMPONENT_NAME})
3858
@@ -51,7 +71,7 @@
5171
52 set(qmlscene_command72 set(qmlscene_command
53 env ${qmltest_ENVIRONMENT}73 env ${qmltest_ENVIRONMENT}
54 ${qmlscene_exe} ${CMAKE_CURRENT_SOURCE_DIR}/${qmltest_FILE}.qml74 ${qmlscene_executable} ${CMAKE_CURRENT_SOURCE_DIR}/${qmltest_FILE}.qml
55 ${qmlscene_imports}75 ${qmlscene_imports}
56 )76 )
57 add_custom_target(${qmlscene_TARGET} ${qmlscene_command})77 add_custom_target(${qmlscene_TARGET} ${qmlscene_command})
@@ -76,6 +96,8 @@
76 set(qmltest_xvfb_TARGET xvfbtest${COMPONENT_NAME})96 set(qmltest_xvfb_TARGET xvfbtest${COMPONENT_NAME})
77 set(qmltest_FILE ${SUBPATH}/tst_${COMPONENT_NAME})97 set(qmltest_FILE ${SUBPATH}/tst_${COMPONENT_NAME})
7898
99 get_target_property(qmltestrunner_executable qmltestrunner LOCATION)
100
79 set(qmltestrunner_imports "")101 set(qmltestrunner_imports "")
80 if(NOT "${qmltest_IMPORT_PATHS}" STREQUAL "")102 if(NOT "${qmltest_IMPORT_PATHS}" STREQUAL "")
81 foreach(IMPORT_PATH ${qmltest_IMPORT_PATHS})103 foreach(IMPORT_PATH ${qmltest_IMPORT_PATHS})
@@ -104,10 +126,10 @@
104126
105 set(qmltest_command127 set(qmltest_command
106 env ${qmltest_ENVIRONMENT}128 env ${qmltest_ENVIRONMENT}
107 ${qmltestrunner_exe} -input ${CMAKE_CURRENT_SOURCE_DIR}/${qmltest_FILE}.qml129 ${qmltestrunner_executable} -input ${CMAKE_CURRENT_SOURCE_DIR}/${qmltest_FILE}.qml
108 ${qmltestrunner_imports}130 ${qmltestrunner_imports}
109 ${ITERATIONS_STRING}131 ${ITERATIONS_STRING}
110 -o ${CMAKE_BINARY_DIR}/${qmltest_TARGET}.xml,xunitxml132 -o ${ARTIFACTS_DIR}/${qmltest_TARGET}.xml,xunitxml
111 -o -,txt133 -o -,txt
112 ${function_ARGS}134 ${function_ARGS}
113 )135 )
@@ -119,9 +141,9 @@
119 set(qmltest_xvfb_command141 set(qmltest_xvfb_command
120 env ${qmltest_ENVIRONMENT} ${LD_PRELOAD_PATH}142 env ${qmltest_ENVIRONMENT} ${LD_PRELOAD_PATH}
121 xvfb-run --server-args "-screen 0 1024x768x24" --auto-servernum143 xvfb-run --server-args "-screen 0 1024x768x24" --auto-servernum
122 ${qmltestrunner_exe} -input ${CMAKE_CURRENT_SOURCE_DIR}/${qmltest_FILE}.qml144 ${qmltestrunner_executable} -input ${CMAKE_CURRENT_SOURCE_DIR}/${qmltest_FILE}.qml
123 ${qmltestrunner_imports}145 ${qmltestrunner_imports}
124 -o ${CMAKE_BINARY_DIR}/${qmltest_TARGET}.xml,xunitxml146 -o ${ARTIFACTS_DIR}/${qmltest_TARGET}.xml,xunitxml
125 -o -,txt147 -o -,txt
126 ${function_ARGS}148 ${function_ARGS}
127 )149 )
@@ -135,7 +157,7 @@
135 set(testCommand157 set(testCommand
136 LD_LIBRARY_PATH=${LD_PATH}158 LD_LIBRARY_PATH=${LD_PATH}
137 ${CMAKE_CURRENT_BINARY_DIR}/${CLASS_NAME}TestExec159 ${CMAKE_CURRENT_BINARY_DIR}/${CLASS_NAME}TestExec
138 -o ${CMAKE_BINARY_DIR}/${CLASSNAME}Test.xml,xunitxml160 -o ${ARTIFACTS_DIR}/${CLASSNAME}Test.xml,xunitxml
139 -o -,txt)161 -o -,txt)
140162
141 add_qmltest_target(test${CLASS_NAME} "${testCommand}" FALSE TRUE)163 add_qmltest_target(test${CLASS_NAME} "${testCommand}" FALSE TRUE)
@@ -151,7 +173,7 @@
151 LD_LIBRARY_PATH=${LD_PATH}173 LD_LIBRARY_PATH=${LD_PATH}
152 xvfb-run --server-args "-screen 0 1024x768x24" --auto-servernum174 xvfb-run --server-args "-screen 0 1024x768x24" --auto-servernum
153 ${CMAKE_CURRENT_BINARY_DIR}/${CLASS_NAME}TestExec175 ${CMAKE_CURRENT_BINARY_DIR}/${CLASS_NAME}TestExec
154 -o ${CMAKE_BINARY_DIR}/${CLASS_NAME}Test.xml,xunitxml176 -o ${ARTIFACTS_DIR}/${CLASS_NAME}Test.xml,xunitxml
155 -o -,txt)177 -o -,txt)
156178
157 add_qmltest_target(xvfbtest${CLASS_NAME} "${xvfbtestCommand}" FALSE TRUE)179 add_qmltest_target(xvfbtest${CLASS_NAME} "${xvfbtestCommand}" FALSE TRUE)
158180
=== modified file 'tests/CMakeLists.txt'
--- tests/CMakeLists.txt 2014-03-18 12:46:07 +0000
+++ tests/CMakeLists.txt 2014-05-01 21:22:23 +0000
@@ -7,9 +7,9 @@
7add_custom_target(qmltests)7add_custom_target(qmltests)
8add_dependencies(qmltests qmlunittests qmluitests)8add_dependencies(qmltests qmlunittests qmluitests)
99
10add_subdirectory(uqmlscene)
10add_subdirectory(qmltests)11add_subdirectory(qmltests)
11add_subdirectory(mocks)12add_subdirectory(mocks)
12add_subdirectory(whitespace)13add_subdirectory(whitespace)
13add_subdirectory(plugins)14add_subdirectory(plugins)
14add_subdirectory(utils)15add_subdirectory(utils)
15add_subdirectory(uqmlscene)
1616
=== modified file 'tests/plugins/LightDM/CMakeLists.txt'
--- tests/plugins/LightDM/CMakeLists.txt 2014-01-14 21:01:28 +0000
+++ tests/plugins/LightDM/CMakeLists.txt 2014-05-01 21:22:23 +0000
@@ -21,5 +21,3 @@
2121
22add_custom_target(testLightDMDBus dbus-launch env QML2_IMPORT_PATH=${CMAKE_BINARY_DIR}/tests/mocks LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/LightDM/full ${CMAKE_CURRENT_BINARY_DIR}/test-lightdm-dbus)22add_custom_target(testLightDMDBus dbus-launch env QML2_IMPORT_PATH=${CMAKE_BINARY_DIR}/tests/mocks LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/LightDM/full ${CMAKE_CURRENT_BINARY_DIR}/test-lightdm-dbus)
23add_dependencies(testLightDMDBus test-lightdm-dbus)23add_dependencies(testLightDMDBus test-lightdm-dbus)
24
25add_dependencies(qmluitests testLightDMDBus)
2624
=== modified file 'tests/qmltests/CMakeLists.txt'
--- tests/qmltests/CMakeLists.txt 2014-04-22 08:51:33 +0000
+++ tests/qmltests/CMakeLists.txt 2014-05-01 21:22:23 +0000
@@ -1,3 +1,10 @@
1add_executable(qmlscene ALIAS uqmlscene)
2
3if(DEFINED QMLTESTRUNNER_EXECUTABLE)
4 add_executable(qmltestrunner IMPORTED)
5 set_target_properties(qmltestrunner PROPERTIES IMPORTED_LOCATION "${QMLTESTRUNNER_EXECUTABLE}")
6endif()
7
1# add_qml_test macro8# add_qml_test macro
2include(QmlTest)9include(QmlTest)
310
411
=== added file 'tools/qmltest_wrapper.py'
--- tools/qmltest_wrapper.py 1970-01-01 00:00:00 +0000
+++ tools/qmltest_wrapper.py 2014-05-01 21:22:23 +0000
@@ -0,0 +1,94 @@
1#!/usr/bin/python3
2
3import os
4import sys
5import subprocess
6import shutil
7import tempfile
8
9ENCODE_LIMIT=120
10GRACE_TIME=5
11
12recordmydesktop_args = [
13 "recordmydesktop",
14 "--quick-subsampling",
15 "--fps=60",
16 "--no-sound",
17 "--overwrite",
18]
19
20if __name__ == "__main__":
21 """
22 This script wraps qmltestrunner, recording the screen as the test runs
23 with recordmydesktop. Maximum encoding time is {0}s, the process is
24 interrupted after that time. If the test succeeds, recording is aborted
25 and no video produced.
26 Output video file name is derived from the first logger option in the
27 "-o /file/path,format" format with *absolute* paths, the file is saved
28 next to the test log file with the extension ".ogv", falling back to
29 "qmltest.ogv" in the current directory.
30 """
31
32 argv = sys.argv.copy()
33 argv[0] = "qmltestrunner"
34
35 outfile = os.path.join(os.curdir, "qmltest.ogv")
36 returncode = 0
37
38 try:
39 for logger in (argv[k+1] for k, v in enumerate(argv) if v == "-o"):
40 log = logger.split(',')[0]
41 if os.path.isabs(log):
42 outfile = "{0}.ogv".format(os.path.splitext(log)[0])
43 break
44 except IndexError as err:
45 raise ValueError("Missing logger definition:\n{0}".format(argv)) from err
46
47
48 with tempfile.TemporaryDirectory() as tmpdir:
49 # create a temporary file and close it to let recordmydesktop overwrite it
50 tmpfd, tmpname = tempfile.mkstemp(dir=tmpdir, suffix=".ogv")
51 os.close(tmpfd)
52 recordmydesktop_args.extend(["--workdir={0}".format(tmpdir),
53 "--output={0}".format(tmpname)])
54
55 with subprocess.Popen(recordmydesktop_args, stdout=subprocess.PIPE,
56 stderr=subprocess.PIPE, universal_newlines=True) as recorder:
57 try:
58 subprocess.check_call(argv)
59 except subprocess.CalledProcessError as err:
60 # store the exit code to return
61 returncode = err.returncode
62
63 # stop recording, give 60 seconds to encode
64 recorder.terminate()
65 try:
66 recorder.wait(ENCODE_LIMIT)
67 except subprocess.TimeoutExpired:
68 print("===== Recorder took too long to encode, recording will be incomplete =====")
69 recorder.terminate()
70 try:
71 recorder.wait(GRACE_TIME)
72 except subprocess.TimeoutExpired:
73 pass
74 if recorder.returncode is 0:
75 # only store the file if recorder exited cleanly
76 shutil.move(tmpname, outfile)
77 else:
78 # abort the recording, test passed
79 recorder.send_signal(subprocess.signal.SIGABRT)
80 try:
81 recorder.wait(GRACE_TIME)
82 except subprocess.TimeoutExpired:
83 pass
84 finally:
85 recorder.poll()
86 # kill the recording if still running
87 if recorder.returncode is None:
88 recorder.kill()
89 print("===== Had to kill recorder =====")
90 elif recorder.returncode is not 0:
91 # only print recorder output if terminated successfully
92 print("===== Recorder error =====\nSTDOUT:\n{0}\n\nSTDERR:\n{1}".format(*recorder.communicate()))
93
94 sys.exit(returncode)
0\ No newline at end of file95\ No newline at end of file

Subscribers

People subscribed via source and target branches