Merge lp:~charlesk/keeper/add-keeper-dbusmock-template into lp:keeper
- add-keeper-dbusmock-template
- Merge into trunk
Status: | Merged |
---|---|
Merged at revision: | 43 |
Proposed branch: | lp:~charlesk/keeper/add-keeper-dbusmock-template |
Merge into: | lp:keeper |
Prerequisite: | lp:~charlesk/keeper/add-tar-creator |
Diff against target: |
1086 lines (+944/-9) 13 files modified
debian/control (+4/-0) src/qdbus-stubs/CMakeLists.txt (+11/-1) src/qdbus-stubs/com.canonical.keeper.User.xml (+1/-1) tests/CMakeLists.txt (+29/-1) tests/com_canonical_keeper.py (+435/-0) tests/dbusmock/CMakeLists.txt (+62/-0) tests/dbusmock/fake-backup-helper.cpp (+63/-0) tests/dbusmock/fake-backup-helper.h (+38/-0) tests/dbusmock/keeper-template-test.cpp (+285/-0) tests/surface/CMakeLists.txt (+1/-0) tests/unit/helper/CMakeLists.txt (+0/-2) tests/utils/CMakeLists.txt (+11/-4) tests/utils/main.cpp (+4/-0) |
To merge this branch: | bzr merge lp:~charlesk/keeper/add-keeper-dbusmock-template |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Xavi Garcia (community) | Approve | ||
Marcus Tomlinson | Pending | ||
Unity API Team | Pending | ||
Review via email:
|
Commit message
add a keeper dbusmock for testing/prototyping
Description of the change
Add a keeper dbusmock for testing/
Supported bits:
com.canonical.
com.canonical.
com.canonical.
com.canonical.
com.canonical.
com.canonical.
com.canonical.
Example use in tests/dbusmock/
Coming next:
com.canonical.
com.canonical.
com.canonical.
- 109. By Charles Kerr
-
in keeper-
template- test, add test to check return values of com.canonical. keeper. User.RestoreCho ices() - 110. By Charles Kerr
-
in keeper-
template- test, add test to check User.StartBackup() throws EINVAL if one of the uuids isn't a valid backup choice - 111. By Charles Kerr
-
in keeper-
template- test, add test to check User.StartRestore() throws EINVAL if one of the uuids isn't a valid restore choice - 112. By Charles Kerr
-
in keeper-
template- test, add test to check User.State() returns an empty set when we have no tasks queued - 113. By Charles Kerr
-
in keeper-
template- test, test User.StartBackup(), Helper. StartBackup( ), and User.State() by adding a task that performs a backup - 114. By Charles Kerr
-
in keeper mock's helper_
backup_ worker( ), better error handling when recv() returns 0 - 115. By Charles Kerr
-
sync with lp:~charlesk/keeper/add-tar-creator
- 116. By Charles Kerr
-
sync with lp:~charlesk/keeper/add-tar-creator
- 117. By Charles Kerr
-
fix threading issues in the keeper dbusmock template
- 118. By Charles Kerr
-
tweak the error messages a little
- 119. By Charles Kerr
-
make the template's python3-gi dependencies explicit in debian/control
- 120. By Charles Kerr
-
more keeper dbusmock tepmlate tweaking
- 121. By Charles Kerr
-
make the env messages terser in the folder-helper fake
- 122. By Charles Kerr
-
rename folder-helper.cpp as fake-folder-
helper. cpp - 123. By Charles Kerr
-
sync with trunk
- 124. By Charles Kerr
-
add flake8 to debian build dep
- 125. By Charles Kerr
-
add testing methods to the mock service to let devs add choices and to see the results of a backup run
- 126. By Charles Kerr
-
add tests to run the dbusmock template through a full backup session
- 127. By Charles Kerr
-
sync with trunk
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Xavi Garcia (xavi-garcia-mena) wrote : | # |
- 128. By Charles Kerr
-
when the last task finishes, clear the remaining_tasks list
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Charles Kerr (charlesk) wrote : | # |
Answers inline
- 129. By Charles Kerr
-
sync with trunk
- 130. By Charles Kerr
-
fix FTBFS by making implicit internal library dependency chain explicit
- 131. By Charles Kerr
-
fix whitespace test
- 132. By Charles Kerr
-
sync keeper-
template- test with r128 changes - 133. By Charles Kerr
-
fix typo in parsing input arguments to mock_add_
backup_ choice( ) and mock_add_ restore_ choice( ) - 134. By Charles Kerr
-
when launching a backup helper, set the correct working directory
- 135. By Charles Kerr
-
sync with trunk
- 136. By Charles Kerr
-
fix FileNotFound cwd bug in keeper-
template- test reported by Marcus
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Xavi Garcia (xavi-garcia-mena) wrote : | # |
Looks good to me, thanks!
Preview Diff
1 | === modified file 'debian/control' |
2 | --- debian/control 2016-07-05 21:09:03 +0000 |
3 | +++ debian/control 2016-07-21 10:16:32 +0000 |
4 | @@ -28,6 +28,10 @@ |
5 | libdbustest1-dev, |
6 | libqtdbusmock1-dev (>= 0.4), |
7 | libqtdbustest1-dev, |
8 | +# for the dbusmock template: |
9 | + python3-gi, |
10 | + gir1.2-glib-2.0 (>= 1.32), |
11 | + flake8, |
12 | Standards-Version: 3.9.5 |
13 | Homepage: https://launchpad.net/keeper |
14 | # If you aren't a member of ~indicator-applet-developers but need to upload |
15 | |
16 | === modified file 'src/qdbus-stubs/CMakeLists.txt' |
17 | --- src/qdbus-stubs/CMakeLists.txt 2016-07-07 13:59:14 +0000 |
18 | +++ src/qdbus-stubs/CMakeLists.txt 2016-07-21 10:16:32 +0000 |
19 | @@ -115,9 +115,19 @@ |
20 | # |
21 | # |
22 | |
23 | +set( |
24 | + STUBS_LIB |
25 | + qdbus-stubs |
26 | +) |
27 | + |
28 | add_library( |
29 | - qdbus-stubs |
30 | + ${STUBS_LIB} |
31 | STATIC |
32 | ${interface_files} |
33 | ${adaptor_files} |
34 | ) |
35 | + |
36 | +target_link_libraries( |
37 | + ${STUBS_LIB} |
38 | + backup-helper |
39 | +) |
40 | |
41 | === modified file 'src/qdbus-stubs/com.canonical.keeper.User.xml' |
42 | --- src/qdbus-stubs/com.canonical.keeper.User.xml 2016-06-27 18:49:17 +0000 |
43 | +++ src/qdbus-stubs/com.canonical.keeper.User.xml 2016-07-21 10:16:32 +0000 |
44 | @@ -72,7 +72,7 @@ |
45 | <doc:para>Provides state information so the user interface can show |
46 | the progress of backup or restore tasks.</doc:para> |
47 | <doc:para>State is a map of opaque backup keys to property maps, |
48 | - which will contain a 'display-name' string and 'action' int |
49 | + which will contain a 'display-name' string and 'action' int32 |
50 | whose possible values are queued(0), saving(1), |
51 | restoring(2), complete(3), stopped(4)</doc:para> |
52 | <doc:para>Some property maps may also have an 'item' string |
53 | |
54 | === modified file 'tests/CMakeLists.txt' |
55 | --- tests/CMakeLists.txt 2016-07-01 15:17:06 +0000 |
56 | +++ tests/CMakeLists.txt 2016-07-21 10:16:32 +0000 |
57 | @@ -1,11 +1,38 @@ |
58 | +### |
59 | +### Build Google Test and Google Mock |
60 | +### |
61 | + |
62 | # We add -g so we get debug info for the gtest stack frames with gdb. |
63 | -# The warnings are suppressed so we get a noise-free build for gtest and gmock. |
64 | +# We add -w to supress warnings when compiling this external source code. |
65 | set(old_cxx_flags ${CMAKE_CXX_FLAGS}) |
66 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -w") |
67 | find_package(GMock REQUIRED) |
68 | find_package(Qt5Test REQUIRED) |
69 | set(CMAKE_CXX_FLAGS ${old_cxx_flags}) |
70 | |
71 | +### |
72 | +### Service DBusMock |
73 | +### |
74 | + |
75 | +set(SERVICE_TEMPLATE_FILE "${CMAKE_CURRENT_SOURCE_DIR}/com_canonical_keeper.py") |
76 | +add_definitions(-DSERVICE_TEMPLATE_FILE="${SERVICE_TEMPLATE_FILE}") |
77 | + |
78 | +# get the python3 package directory |
79 | +execute_process ( |
80 | + COMMAND python3 -c "from distutils import sysconfig; print(sysconfig.get_python_lib())" |
81 | + COMMAND sed -r -e "s|/usr/(local/)?||g" |
82 | + OUTPUT_VARIABLE PYTHON_PACKAGE_DIR OUTPUT_STRIP_TRAILING_WHITESPACE |
83 | +) |
84 | + |
85 | +install( |
86 | + FILES ${SERVICE_TEMPLATE_FILE} |
87 | + DESTINATION "${PYTHON_PACKAGE_DIR}/dbusmock/templates/" |
88 | +) |
89 | + |
90 | +### |
91 | +### The Tests |
92 | +### |
93 | + |
94 | pkg_check_modules(TEST_DEPENDENCIES |
95 | libqtdbustest-1 REQUIRED |
96 | libqtdbusmock-1 REQUIRED |
97 | @@ -22,5 +49,6 @@ |
98 | ) |
99 | |
100 | add_subdirectory(surface) |
101 | +add_subdirectory(dbusmock) |
102 | add_subdirectory(unit) |
103 | add_subdirectory(utils) |
104 | |
105 | === added file 'tests/com_canonical_keeper.py' |
106 | --- tests/com_canonical_keeper.py 1970-01-01 00:00:00 +0000 |
107 | +++ tests/com_canonical_keeper.py 2016-07-21 10:16:32 +0000 |
108 | @@ -0,0 +1,435 @@ |
109 | +import copy |
110 | +import dbus |
111 | +import dbus.service |
112 | +import os |
113 | +import socket |
114 | +import subprocess |
115 | +import sys |
116 | +from dbusmock import OBJECT_MANAGER_IFACE, mockobject |
117 | +from gi.repository import GLib |
118 | + |
119 | +'''com.canonical.keeper mock template |
120 | +''' |
121 | + |
122 | +# This program is free software; you can redistribute it and/or modify it under |
123 | +# the terms of the GNU Lesser General Public License as published by the Free |
124 | +# Software Foundation; either version 3 of the License, or (at your option) any |
125 | +# later version. See http://www.gnu.org/copyleft/lgpl.html for the full text |
126 | +# of the license. |
127 | + |
128 | +__author__ = 'Charles Kerr' |
129 | +__email__ = 'charles.kerr@canonical.com' |
130 | +__copyright__ = '(c) 2016 Canonical Ltd.' |
131 | +__license__ = 'LGPL 3+' |
132 | + |
133 | +SERVICE_PATH = '/com/canonical/keeper' |
134 | +SERVICE_IFACE = 'com.canonical.keeper' |
135 | +USER_PATH = '/com/canonical/keeper/user' |
136 | +USER_IFACE = 'com.canonical.keeper.User' |
137 | +HELPER_PATH = '/com/canonical/keeper/helper' |
138 | +HELPER_IFACE = 'com.canonical.keeper.Helper' |
139 | +MOCK_IFACE = 'com.canonical.keeper.Mock' |
140 | + |
141 | +# magic keys used by dbusmock |
142 | +BUS_NAME = 'com.canonical.keeper' |
143 | +MAIN_IFACE = SERVICE_IFACE |
144 | +MAIN_OBJ = SERVICE_PATH |
145 | +SYSTEM_BUS = False |
146 | + |
147 | +ACTION_QUEUED = 0 |
148 | +ACTION_SAVING = 1 |
149 | +ACTION_RESTORING = 2 |
150 | +ACTION_COMPLETE = 3 |
151 | +ACTION_STOPPED = 4 |
152 | + |
153 | +KEY_CTIME = 'ctime' |
154 | +KEY_BLOB = 'blob-data' |
155 | +KEY_HELPER = 'helper-exec' |
156 | +KEY_ICON = 'icon' |
157 | +KEY_NAME = 'display-name' |
158 | +KEY_SIZE = 'size' |
159 | +KEY_SUBTYPE = 'subtype' |
160 | +KEY_TYPE = 'type' |
161 | +KEY_UUID = 'uuid' |
162 | + |
163 | +TYPE_APP = 'application' |
164 | +TYPE_FOLDER = 'folder' |
165 | +TYPE_SYSTEM = 'system-data' |
166 | + |
167 | +# |
168 | +# Utils |
169 | +# |
170 | + |
171 | + |
172 | +def badarg(msg): |
173 | + raise dbus.exceptions.DBusException( |
174 | + msg, |
175 | + name='org.freedesktop.DBus.Error.InvalidArgs' |
176 | + ) |
177 | + |
178 | + |
179 | +def fail(msg): |
180 | + raise dbus.exceptions.DBusException( |
181 | + msg, |
182 | + name='org.freedesktop.DBus.Error.Failed' |
183 | + ) |
184 | + |
185 | + |
186 | +def fail_if_busy(): |
187 | + user = mockobject.objects[USER_PATH] |
188 | + if user.all_tasks: |
189 | + fail("can't do that while service is busy") |
190 | + |
191 | + |
192 | +# |
193 | +# User Obj |
194 | +# |
195 | + |
196 | + |
197 | +def user_get_backup_choices(user): |
198 | + return dbus.Dictionary( |
199 | + user.backup_choices, |
200 | + signature='sa{sv}', |
201 | + variant_level=1 |
202 | + ) |
203 | + |
204 | + |
205 | +def user_get_restore_choices(user): |
206 | + return dbus.Dictionary( |
207 | + user.restore_choices, |
208 | + signature='sa{sv}', |
209 | + variant_level=1 |
210 | + ) |
211 | + |
212 | + |
213 | +def user_start_next_task(user): |
214 | + if not user.remaining_tasks: |
215 | + user.log('last task finished') |
216 | + user.all_tasks = [] |
217 | + user.current_task = None |
218 | + user.log('setting user.current_task to None') |
219 | + user.update_state_property(user) |
220 | + |
221 | + else: |
222 | + uuid = user.remaining_tasks.pop(0) |
223 | + user.current_task = uuid |
224 | + user.update_state_property(user) |
225 | + |
226 | + # find the helper to run |
227 | + choice = user.backup_choices.get(uuid) |
228 | + if not choice: |
229 | + choice = user.restore_choices.get(uuid) |
230 | + helper_exec = choice.get(KEY_HELPER) |
231 | + |
232 | + # build the env that we'll pass to the helper |
233 | + henv = {} |
234 | + henv['QDBUS_DEBUG'] = '1' |
235 | + henv['G_DBUS_DEBUG'] = 'call,message,signal,return' |
236 | + for key in ['DBUS_SESSION_BUS_ADDRESS', 'DBUS_SYSTEM_BUS_ADDRESS']: |
237 | + val = os.environ.get(key, None) |
238 | + if val: |
239 | + henv[key] = val |
240 | + |
241 | + # set the working directory for folder backups |
242 | + helper_cwd = os.getcwd() |
243 | + if choice.get(KEY_TYPE) == TYPE_FOLDER: |
244 | + helper_cwd = choice.get(KEY_SUBTYPE) |
245 | + |
246 | + # spawn the helper |
247 | + user.log('starting %s for %s, env %s' % (helper_exec, uuid, henv)) |
248 | + subprocess.Popen( |
249 | + [helper_exec, HELPER_PATH], |
250 | + env=henv, stdout=sys.stdout, stderr=sys.stderr, |
251 | + cwd=helper_cwd, |
252 | + shell=helper_exec.endswith('.sh') |
253 | + ) |
254 | + |
255 | + |
256 | +def user_start_backup(user, uuids): |
257 | + |
258 | + # sanity checks |
259 | + fail_if_busy() |
260 | + for uuid in uuids: |
261 | + if uuid not in user.backup_choices: |
262 | + badarg('uuid %s is not a valid backup choice' % (uuid)) |
263 | + |
264 | + user.all_tasks = uuids |
265 | + user.remaining_tasks = copy.copy(uuids) |
266 | + user.start_next_task(user) |
267 | + |
268 | + |
269 | +def user_start_restore(user, uuids): |
270 | + |
271 | + # sanity checks |
272 | + fail_if_busy() |
273 | + for uuid in uuids: |
274 | + if uuid not in user.restore_choices: |
275 | + badarg('uuid %s is not a valid backup choice' % (uuid)) |
276 | + |
277 | + user.all_tasks = uuids |
278 | + user.remaining_tasks = copy.copy(uuids) |
279 | + user.start_next_task() |
280 | + |
281 | + |
282 | +def user_cancel(user): |
283 | + # FIXME |
284 | + pass |
285 | + |
286 | + |
287 | +def user_build_state(user): |
288 | + """Returns a generated state dictionary. |
289 | + |
290 | + State is a map of opaque backup keys to property maps, |
291 | + which will contain a 'display-name' string and 'action' int |
292 | + whose possible values are queued(0), saving(1), |
293 | + restoring(2), complete(3), and stopped(4). |
294 | + |
295 | + Some property maps may also have an 'item' string |
296 | + and a 'percent-done' double [0..1.0]. |
297 | + For example if these are set to (1, "Photos", 0.36), |
298 | + the user interface could show "Backing up Photos (36%)". |
299 | + Clients should gracefully handle missing properties; |
300 | + eg a missing percent-done could instead show |
301 | + "Backing up Photos". |
302 | + |
303 | + A failed task's property map may also contain an 'error' |
304 | + string if set by the backup helpers. |
305 | + """ |
306 | + |
307 | + tasks_states = {} |
308 | + for uuid in user.all_tasks: |
309 | + task_state = {} |
310 | + |
311 | + # get the task's action |
312 | + if uuid == user.current_task: |
313 | + if uuid in user.backup_choices: |
314 | + action = ACTION_SAVING |
315 | + else: |
316 | + action = ACTION_RESTORING |
317 | + elif uuid in user.remaining_tasks: |
318 | + action = ACTION_QUEUED |
319 | + else: # FIXME: 'ACTION_STOPPED' not handled yet |
320 | + action = ACTION_COMPLETE |
321 | + task_state['action'] = dbus.Int32(action) |
322 | + |
323 | + # get the task's display-name |
324 | + choice = user.backup_choices.get(uuid, None) |
325 | + if not choice: |
326 | + choice = user.restore_choices.get(uuid, None) |
327 | + if not choice: |
328 | + fail("couldn't find a choice for uuid %s" % (uuid)) |
329 | + display_name = choice.get(KEY_NAME, None) |
330 | + task_state[KEY_NAME] = dbus.String(display_name) |
331 | + |
332 | + # FIXME: use a real percentage here |
333 | + if action == ACTION_COMPLETE: |
334 | + percent_done = dbus.Double(1.0) |
335 | + elif action == ACTION_SAVING or action == ACTION_RESTORING: |
336 | + percent_done = dbus.Double(0.5) |
337 | + else: |
338 | + percent_done = dbus.Double(0.0) |
339 | + task_state['percent-done'] = percent_done |
340 | + |
341 | + tasks_states[uuid] = dbus.Dictionary(task_state) |
342 | + |
343 | + return dbus.Dictionary( |
344 | + tasks_states, |
345 | + signature='sa{sv}', |
346 | + variant_level=1 |
347 | + ) |
348 | + |
349 | + |
350 | +def user_update_state_property(user): |
351 | + old_state = user.Get(USER_IFACE, 'State') |
352 | + new_state = user.build_state(user) |
353 | + if old_state != new_state: |
354 | + user.Set(USER_IFACE, 'State', new_state) |
355 | + |
356 | + |
357 | +# |
358 | +# Helper Obj |
359 | +# |
360 | + |
361 | +class HelperWork: |
362 | + chunks = None |
363 | + n_bytes = None |
364 | + n_left = None |
365 | + sock = None |
366 | + uuid = None |
367 | + |
368 | + |
369 | +def helper_periodic_func(helper): |
370 | + |
371 | + if not helper.work: |
372 | + fail("bug: helper_periodic_func called w/o helper.work") |
373 | + |
374 | + # try to read a bit |
375 | + chunk = helper.work.sock.recv(4096*2) |
376 | + if len(chunk): |
377 | + helper.work.chunks.append(chunk) |
378 | + helper.work.n_left -= len(chunk) |
379 | + helper.log('got %s bytes; %s left' % (len(chunk), helper.work.n_left)) |
380 | + |
381 | + # cleanup if done |
382 | + done = helper.work.n_left <= 0 |
383 | + if done: |
384 | + helper.work.sock.shutdown(socket.SHUT_RDWR) |
385 | + helper.work.sock.close() |
386 | + user = mockobject.objects[USER_PATH] |
387 | + user.backup_data[helper.work.uuid] = b''.join(helper.work.chunks) |
388 | + user.log( |
389 | + 'backup %s done; %s bytes' % |
390 | + (helper.work.uuid, len(user.backup_data[helper.work.uuid])) |
391 | + ) |
392 | + user.start_next_task(user) |
393 | + helper.work = None |
394 | + |
395 | + if len(chunk) or done: |
396 | + user = mockobject.objects[USER_PATH] |
397 | + user.update_state_property(user) |
398 | + |
399 | + return not done |
400 | + |
401 | + |
402 | +def helper_start_backup(helper, n_bytes): |
403 | + |
404 | + helper.log("got start_backup request for %s bytes" % (n_bytes)) |
405 | + if helper.work: |
406 | + fail("can't start a new backup while one's already active") |
407 | + |
408 | + parent, child = socket.socketpair() |
409 | + |
410 | + # set up helper's workarea |
411 | + work = HelperWork() |
412 | + work.chunks = [] |
413 | + work.n_bytes = n_bytes |
414 | + work.n_left = n_bytes |
415 | + work.sock = parent |
416 | + work.uuid = mockobject.objects[USER_PATH].current_task |
417 | + helper.work = work |
418 | + |
419 | + # start checking periodically |
420 | + GLib.timeout_add(10, helper.periodic_func, helper) |
421 | + return dbus.types.UnixFd(child.fileno()) |
422 | + |
423 | + |
424 | +def helper_start_restore(helper): |
425 | + helper.parent, child = socket.socketpair() |
426 | + return child |
427 | + |
428 | + |
429 | +# |
430 | +# Controlling the mock |
431 | +# |
432 | + |
433 | + |
434 | +def mock_add_backup_choice(mock, uuid, props): |
435 | + |
436 | + keys = [KEY_NAME, KEY_TYPE, KEY_SUBTYPE, KEY_ICON, KEY_HELPER] |
437 | + if set(keys) != set(props.keys()): |
438 | + badarg('need props: %s got %s' % (keys, props.keys())) |
439 | + |
440 | + user = mockobject.objects[USER_PATH] |
441 | + user.backup_choices[uuid] = dbus.Dictionary( |
442 | + props, |
443 | + signature='sv', |
444 | + variant_level=1 |
445 | + ) |
446 | + |
447 | + |
448 | +def mock_add_restore_choice(mock, uuid, props): |
449 | + |
450 | + keys = [KEY_NAME, KEY_TYPE, KEY_SUBTYPE, KEY_ICON, KEY_HELPER, |
451 | + KEY_SIZE, KEY_CTIME, KEY_BLOB] |
452 | + if set(keys) != set(props.keys()): |
453 | + badarg('need props: %s got %s' % (keys, props.keys())) |
454 | + |
455 | + user = mockobject.objects[USER_PATH] |
456 | + user.restore_choices[uuid] = dbus.Dictionary( |
457 | + props, |
458 | + signature='sv', |
459 | + variant_level=1 |
460 | + ) |
461 | + |
462 | + |
463 | +def mock_get_backup_data(mock, uuid): |
464 | + blob = mockobject.objects[USER_PATH].backup_data[uuid] |
465 | + mock.log('returning %s byte blob for uuid %s' % (len(blob), uuid)) |
466 | + return blob |
467 | + |
468 | + |
469 | +# |
470 | +# |
471 | +# |
472 | + |
473 | +def load(main, parameters): |
474 | + |
475 | + main.log('Keeper template paramers: "' + str(parameters) + '"') |
476 | + |
477 | + # com.canonical.keeper.User |
478 | + path = USER_PATH |
479 | + main.AddObject(path, USER_IFACE, {}, []) |
480 | + o = mockobject.objects[path] |
481 | + o.get_backup_choices = user_get_backup_choices |
482 | + o.start_backup = user_start_backup |
483 | + o.get_restore_choices = user_get_restore_choices |
484 | + o.start_restore = user_start_restore |
485 | + o.cancel = user_cancel |
486 | + o.build_state = user_build_state |
487 | + o.update_state_property = user_update_state_property |
488 | + o.start_next_task = user_start_next_task |
489 | + o.all_tasks = [] |
490 | + o.remaining_tasks = [] |
491 | + o.backup_data = {} |
492 | + o.backup_choices = parameters.get('backup-choices', {}) |
493 | + o.restore_choices = parameters.get('restore-choices', {}) |
494 | + o.current_task = None |
495 | + o.defined_types = [TYPE_APP, TYPE_SYSTEM, TYPE_FOLDER] |
496 | + o.AddMethods(USER_IFACE, [ |
497 | + ('GetBackupChoices', '', 'a{sa{sv}}', |
498 | + 'ret = self.get_backup_choices(self)'), |
499 | + ('StartBackup', 'as', '', |
500 | + 'self.start_backup(self, args[0])'), |
501 | + ('GetRestoreChoices', '', 'a{sa{sv}}', |
502 | + 'ret = self.get_restore_choices(self)'), |
503 | + ('StartRestore', 'as', '', |
504 | + 'self.start_restore(self, args[0])'), |
505 | + ('Cancel', '', '', |
506 | + 'self.cancel(self)'), |
507 | + ]) |
508 | + o.AddProperty(USER_IFACE, "State", o.build_state(o)) |
509 | + |
510 | + # com.canonical.keeper.Helper |
511 | + path = HELPER_PATH |
512 | + main.AddObject(path, HELPER_IFACE, {}, []) |
513 | + o = mockobject.objects[path] |
514 | + o.start_backup = helper_start_backup |
515 | + o.start_restore = helper_start_restore |
516 | + o.periodic_func = helper_periodic_func |
517 | + o.work = None |
518 | + o.AddMethods(HELPER_IFACE, [ |
519 | + ('StartBackup', 't', 'h', |
520 | + 'ret = self.start_backup(self, args[0])'), |
521 | + ('StartRestore', '', 'h', |
522 | + 'ret = self.start_restore(self)') |
523 | + ]) |
524 | + |
525 | + # com.canonical.keeper.Mock |
526 | + o = main |
527 | + o.add_backup_choice = mock_add_backup_choice |
528 | + o.add_restore_choice = mock_add_restore_choice |
529 | + o.get_backup_data = mock_get_backup_data |
530 | + o.AddMethods(MOCK_IFACE, [ |
531 | + ('AddBackupChoice', 'sa{sv}', '', |
532 | + 'self.add_backup_choice(self, args[0], args[1])'), |
533 | + ('AddRestoreChoice', 'sa{sv}', '', |
534 | + 'self.add_restore_choice(self, args[0], args[1])'), |
535 | + ('GetBackupData', 's', 'ay', |
536 | + 'ret = self.get_backup_data(self, args[0])') |
537 | + ]) |
538 | + o.EmitSignal( |
539 | + OBJECT_MANAGER_IFACE, |
540 | + 'InterfacesAdded', |
541 | + 'oa{sa{sv}}', |
542 | + [SERVICE_PATH, {MOCK_IFACE: {}}] |
543 | + ) |
544 | |
545 | === added directory 'tests/dbusmock' |
546 | === added file 'tests/dbusmock/CMakeLists.txt' |
547 | --- tests/dbusmock/CMakeLists.txt 1970-01-01 00:00:00 +0000 |
548 | +++ tests/dbusmock/CMakeLists.txt 2016-07-21 10:16:32 +0000 |
549 | @@ -0,0 +1,62 @@ |
550 | + |
551 | +include_directories( |
552 | + ${CMAKE_SOURCE_DIR}/src |
553 | + ${CMAKE_BINARY_DIR}/src |
554 | +) |
555 | + |
556 | +set( |
557 | + LINK_LIBS |
558 | + qdbus-stubs |
559 | + ${TEST_DEPENDENCIES_LDFLAGS} |
560 | + test-utils |
561 | + Qt5::Core |
562 | + Qt5::DBus |
563 | + Qt5::Network |
564 | + ${GTEST_LIBRARIES} |
565 | + ${GMOCK_LIBRARIES} |
566 | +) |
567 | + |
568 | +### |
569 | +### |
570 | + |
571 | +set( |
572 | + BACKUP_HELPER |
573 | + fake-backup-helper |
574 | +) |
575 | + |
576 | +add_executable( |
577 | + ${BACKUP_HELPER} |
578 | + fake-backup-helper.cpp |
579 | +) |
580 | +target_link_libraries( |
581 | + ${BACKUP_HELPER} |
582 | + ${LINK_LIBS} |
583 | +) |
584 | + |
585 | +### |
586 | +### |
587 | + |
588 | +set( |
589 | + TEST_NAME |
590 | + keeper-template-test |
591 | +) |
592 | + |
593 | +add_executable( |
594 | + ${TEST_NAME} |
595 | + keeper-template-test.cpp |
596 | +) |
597 | + |
598 | +set_property( |
599 | + SOURCE keeper-template-test.cpp |
600 | + PROPERTIES APPEND_STRING PROPERTY COMPILE_DEFINITIONS FAKE_BACKUP_HELPER_EXEC=\"${CMAKE_CURRENT_BINARY_DIR}/${BACKUP_HELPER}\" |
601 | +) |
602 | + |
603 | +target_link_libraries( |
604 | + ${TEST_NAME} |
605 | + ${LINK_LIBS} |
606 | +) |
607 | + |
608 | +add_test( |
609 | + ${TEST_NAME} |
610 | + ${TEST_NAME} |
611 | +) |
612 | |
613 | === added file 'tests/dbusmock/fake-backup-helper.cpp' |
614 | --- tests/dbusmock/fake-backup-helper.cpp 1970-01-01 00:00:00 +0000 |
615 | +++ tests/dbusmock/fake-backup-helper.cpp 2016-07-21 10:16:32 +0000 |
616 | @@ -0,0 +1,63 @@ |
617 | +/* |
618 | + * Copyright (C) 2016 Canonical, Ltd. |
619 | + * |
620 | + * This program is free software: you can redistribute it and/or modify it |
621 | + * under the terms of the GNU General Public License version 3, as published |
622 | + * by the Free Software Foundation. |
623 | + * |
624 | + * This program is distributed in the hope that it will be useful, but |
625 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
626 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
627 | + * PURPOSE. See the GNU General Public License for more details. |
628 | + * |
629 | + * You should have received a copy of the GNU General Public License along |
630 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
631 | + * |
632 | + * Authors: |
633 | + * Charles Kerr <charles.kerr@canonical.com> |
634 | + */ |
635 | + |
636 | +#include "fake-backup-helper.h" |
637 | + |
638 | +#include <qdbus-stubs/dbus-types.h> |
639 | +#include <qdbus-stubs/keeper_helper_interface.h> |
640 | + |
641 | +#include <QCoreApplication> |
642 | +#include <QDebug> |
643 | +#include <QDBusConnection> |
644 | +#include <QDBusInterface> |
645 | +#include <QDBusReply> |
646 | +#include <QProcessEnvironment> |
647 | +#include <QLocalSocket> |
648 | + |
649 | +int |
650 | +main(int argc, char **argv) |
651 | +{ |
652 | + QCoreApplication app(argc, argv); |
653 | + |
654 | + const auto blob = QByteArray(FAKE_BACKUP_HELPER_PAYLOAD); |
655 | + |
656 | + // dump the inputs to stdout |
657 | + qDebug() << "argc:" << argc; |
658 | + for(int i=0; i<argc; ++i) |
659 | + qDebug() << "argv[" << i << "] is" << argv[i]; |
660 | + const auto env = QProcessEnvironment::systemEnvironment(); |
661 | + for(const auto& key : env.keys()) |
662 | + qDebug() << "env" << qPrintable(key) << "is" << qPrintable(env.value(key)); |
663 | + |
664 | + // ask the service for a socket |
665 | + auto conn = QDBusConnection::connectToBus(QDBusConnection::SessionBus, DBusTypes::KEEPER_SERVICE); |
666 | + const auto object_path = QString::fromUtf8(argv[1]); |
667 | + DBusInterfaceKeeperHelper helper_iface (DBusTypes::KEEPER_SERVICE, object_path, conn); |
668 | + QDBusReply<QDBusUnixFileDescriptor> reply = helper_iface.call("StartBackup", blob.size()); |
669 | + const auto ufd = reply.value(); |
670 | + Q_ASSERT(reply.isValid()); |
671 | + |
672 | + // write the blob |
673 | + QLocalSocket sock; |
674 | + sock.setSocketDescriptor(ufd.fileDescriptor()); |
675 | + qDebug() << "wrote" << sock.write(blob) << "bytes"; |
676 | + sock.flush(); |
677 | + |
678 | + return EXIT_SUCCESS; |
679 | +} |
680 | |
681 | === added file 'tests/dbusmock/fake-backup-helper.h' |
682 | --- tests/dbusmock/fake-backup-helper.h 1970-01-01 00:00:00 +0000 |
683 | +++ tests/dbusmock/fake-backup-helper.h 2016-07-21 10:16:32 +0000 |
684 | @@ -0,0 +1,38 @@ |
685 | +/* |
686 | + * Copyright (C) 2016 Canonical, Ltd. |
687 | + * |
688 | + * This program is free software: you can redistribute it and/or modify it |
689 | + * under the terms of the GNU General Public License version 3, as published |
690 | + * by the Free Software Foundation. |
691 | + * |
692 | + * This program is distributed in the hope that it will be useful, but |
693 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
694 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
695 | + * PURPOSE. See the GNU General Public License for more details. |
696 | + * |
697 | + * You should have received a copy of the GNU General Public License along |
698 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
699 | + * |
700 | + * Authors: |
701 | + * Charles Kerr <charles.kerr@canonical.com> |
702 | + */ |
703 | + |
704 | +#pragma once |
705 | + |
706 | +static const char* FAKE_BACKUP_HELPER_PAYLOAD = R"( |
707 | + Oh mmm I know a place |
708 | + Ain't nobody cryin' |
709 | + Ain't nobody worried |
710 | + Ain't no smilin' faces |
711 | + Mmm, no no |
712 | + Lyin' to the races |
713 | + Help me, come on, come on |
714 | + Somebody, help me now (I'll take you there) |
715 | + Help me, ya'all (I'll take you there) |
716 | + Help me now (I'll take you there) |
717 | + Oh! (I'll take you there) |
718 | + Oh! Oh! Mercy! (I'll take you there) |
719 | + Oh, let me take you there (I'll take you there) |
720 | + Oh-oh! Let me take you there! (I'll take you there) |
721 | + Play your, play your piano now |
722 | +)"; |
723 | |
724 | === added file 'tests/dbusmock/keeper-template-test.cpp' |
725 | --- tests/dbusmock/keeper-template-test.cpp 1970-01-01 00:00:00 +0000 |
726 | +++ tests/dbusmock/keeper-template-test.cpp 2016-07-21 10:16:32 +0000 |
727 | @@ -0,0 +1,285 @@ |
728 | +/* |
729 | + * Copyright 2016 Canonical Ltd. |
730 | + * |
731 | + * This program is free software: you can redistribute it and/or modify it |
732 | + * under the terms of the GNU General Public License version 3, as published |
733 | + * by the Free Software Foundation. |
734 | + * |
735 | + * This program is distributed in the hope that it will be useful, but |
736 | + * WITHOUT ANY WARRANTY; without even the implied warranties of |
737 | + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
738 | + * PURPOSE. See the GNU General Public License for more details. |
739 | + * |
740 | + * You should have received a copy of the GNU General Public License along |
741 | + * with this program. If not, see <http://www.gnu.org/licenses/>. |
742 | + * |
743 | + * Authors: |
744 | + * Charles Kerr <charles.kerr@canonical.com> |
745 | + */ |
746 | + |
747 | +#include "fake-backup-helper.h" |
748 | + |
749 | +#include "qdbus-stubs/dbus-types.h" |
750 | +#include "qdbus-stubs/keeper_interface.h" |
751 | +#include "qdbus-stubs/keeper_user_interface.h" |
752 | + |
753 | +#include <gtest/gtest.h> |
754 | + |
755 | +#include <libqtdbusmock/DBusMock.h> |
756 | +#include <libqtdbustest/DBusTestRunner.h> |
757 | + |
758 | +#include <QDBusConnection> |
759 | +#include <QDebug> |
760 | +#include <QString> |
761 | +#include <QThread> |
762 | +#include <QUuid> |
763 | +#include <QVariant> |
764 | + |
765 | +#include <memory> |
766 | + |
767 | +#define KEY_ACTION "action" |
768 | +#define KEY_CTIME "ctime" |
769 | +#define KEY_BLOB "blob-data" |
770 | +#define KEY_HELPER "helper-exec" |
771 | +#define KEY_ICON "icon" |
772 | +#define KEY_NAME "display-name" |
773 | +#define KEY_PERCENT "percent-done" |
774 | +#define KEY_SIZE "size" |
775 | +#define KEY_SUBTYPE "subtype" |
776 | +#define KEY_TYPE "type" |
777 | +#define KEY_UUID "uuid" |
778 | + |
779 | +// FIXME: this should go in a shared header |
780 | +enum |
781 | +{ |
782 | + ACTION_QUEUED = 0, |
783 | + ACTION_SAVING = 1, |
784 | + ACTION_RESTORING = 2, |
785 | + ACTION_IDLE = 3 |
786 | +}; |
787 | + |
788 | +using namespace QtDBusMock; |
789 | +using namespace QtDBusTest; |
790 | + |
791 | + |
792 | +class KeeperTemplateTest : public ::testing::Test |
793 | +{ |
794 | +protected: |
795 | + |
796 | + virtual void SetUp() override |
797 | + { |
798 | + test_runner_.reset(new DBusTestRunner{}); |
799 | + |
800 | + dbus_mock_.reset(new DBusMock(*test_runner_)); |
801 | + dbus_mock_->registerTemplate( |
802 | + DBusTypes::KEEPER_SERVICE, |
803 | + SERVICE_TEMPLATE_FILE, |
804 | + QDBusConnection::SessionBus |
805 | + ); |
806 | + |
807 | + test_runner_->startServices(); |
808 | + auto conn = connection(); |
809 | + qDebug() << "session bus is" << qPrintable(conn.name()); |
810 | + |
811 | + keeper_iface_.reset( |
812 | + new DBusInterfaceKeeper( |
813 | + DBusTypes::KEEPER_SERVICE, |
814 | + DBusTypes::KEEPER_SERVICE_PATH, |
815 | + conn |
816 | + ) |
817 | + ); |
818 | + ASSERT_TRUE(keeper_iface_->isValid()) << qPrintable(conn.lastError().message()); |
819 | + |
820 | + user_iface_.reset( |
821 | + new DBusInterfaceKeeperUser( |
822 | + DBusTypes::KEEPER_SERVICE, |
823 | + DBusTypes::KEEPER_USER_PATH, |
824 | + conn |
825 | + ) |
826 | + ); |
827 | + ASSERT_TRUE(user_iface_->isValid()) << qPrintable(conn.lastError().message()); |
828 | + |
829 | + mock_iface_.reset( |
830 | + new QDBusInterface( |
831 | + DBusTypes::KEEPER_SERVICE, |
832 | + DBusTypes::KEEPER_SERVICE_PATH, |
833 | + QStringLiteral("com.canonical.keeper.Mock"), |
834 | + conn |
835 | + ) |
836 | + ); |
837 | + ASSERT_TRUE(mock_iface_->isValid()) << qPrintable(conn.lastError().message()); |
838 | + } |
839 | + |
840 | + virtual void TearDown() override |
841 | + { |
842 | + user_iface_.reset(); |
843 | + keeper_iface_.reset(); |
844 | + dbus_mock_.reset(); |
845 | + test_runner_.reset(); |
846 | + } |
847 | + |
848 | + const QDBusConnection& connection() |
849 | + { |
850 | + return test_runner_->sessionConnection(); |
851 | + } |
852 | + |
853 | + std::unique_ptr<DBusTestRunner> test_runner_; |
854 | + std::unique_ptr<DBusMock> dbus_mock_; |
855 | + std::unique_ptr<DBusInterfaceKeeper> keeper_iface_; |
856 | + std::unique_ptr<DBusInterfaceKeeperUser> user_iface_; |
857 | + std::unique_ptr<QDBusInterface> mock_iface_; |
858 | + |
859 | + void EXPECT_EVENTUALLY(std::function<bool()>&& test, qint64 timeout_msec=5000) |
860 | + { |
861 | + QElapsedTimer timer; |
862 | + timer.start(); |
863 | + bool passed; |
864 | + do { |
865 | + passed = test(); |
866 | + if (!passed) |
867 | + QThread::msleep(100); |
868 | + } while (!passed && !timer.hasExpired(timeout_msec)); |
869 | + EXPECT_TRUE(passed); |
870 | + } |
871 | + |
872 | + void wait_for_backup_to_finish() |
873 | + { |
874 | + EXPECT_EVENTUALLY([this]{return !user_iface_->state().isEmpty();}); // backup running |
875 | + EXPECT_EVENTUALLY([this]{return user_iface_->state().isEmpty();}); // backup finished |
876 | + } |
877 | +}; |
878 | + |
879 | + |
880 | +/*** |
881 | +**** Quick surface-level tests |
882 | +***/ |
883 | + |
884 | + |
885 | +// test that the dbusmock scaffolding starts up and exits ok |
886 | +TEST_F(KeeperTemplateTest, HelloWorld) |
887 | +{ |
888 | +} |
889 | + |
890 | + |
891 | +// test GetBackupChoices() returns what we give to AddBackupChoice() |
892 | +TEST_F(KeeperTemplateTest, BackupChoices) |
893 | +{ |
894 | + // build a backup choice |
895 | + const auto uuid = QUuid::createUuid().toString(); |
896 | + const QMap<QString,QVariant> props { |
897 | + { KEY_NAME, QStringLiteral("some-name") }, |
898 | + { KEY_TYPE, QStringLiteral("some-type") }, |
899 | + { KEY_SUBTYPE, QStringLiteral("some-subtype") }, |
900 | + { KEY_ICON, QStringLiteral("some-icon") }, |
901 | + { KEY_HELPER, QString::fromUtf8(FAKE_BACKUP_HELPER_EXEC) } |
902 | + }; |
903 | + |
904 | + // add it |
905 | + auto msg = mock_iface_->call(QStringLiteral("AddBackupChoice"), uuid, props); |
906 | + EXPECT_NE(QDBusMessage::ErrorMessage, msg.type()) << qPrintable(msg.errorMessage()); |
907 | + |
908 | + // ask for a list of backup choices |
909 | + QDBusReply<QVariantDictMap> choices = user_iface_->call("GetBackupChoices"); |
910 | + EXPECT_TRUE(choices.isValid()) << qPrintable(choices.error().message()); |
911 | + |
912 | + // check the results |
913 | + const auto expected_choices = QVariantDictMap{{uuid, props}}; |
914 | + ASSERT_EQ(expected_choices, choices); |
915 | +} |
916 | + |
917 | + |
918 | +// test that StartBackup() fails if we pass an invalid arg |
919 | +TEST_F(KeeperTemplateTest, StartBackupWithInvalidArg) |
920 | +{ |
921 | + const auto invalid_uuid = QUuid::createUuid().toString(); |
922 | + |
923 | + QDBusReply<void> reply = user_iface_->call("StartBackup", QStringList{invalid_uuid}); |
924 | + EXPECT_FALSE(reply.isValid()); |
925 | + EXPECT_EQ(QDBusError::InvalidArgs, reply.error().type()); |
926 | +} |
927 | + |
928 | + |
929 | +// test GetRestoreChoices() returns what we give to AddRestoreChoice() |
930 | +TEST_F(KeeperTemplateTest, RestoreChoices) |
931 | +{ |
932 | + // build a restore choice |
933 | + const auto uuid = QUuid::createUuid().toString(); |
934 | + const auto blob = QUuid::createUuid().toByteArray(); |
935 | + const QMap<QString,QVariant> props { |
936 | + { KEY_NAME, QStringLiteral("some-name") }, |
937 | + { KEY_TYPE, QStringLiteral("some-type") }, |
938 | + { KEY_SUBTYPE, QStringLiteral("some-subtype") }, |
939 | + { KEY_ICON, QStringLiteral("some-icon") }, |
940 | + { KEY_HELPER, QString::fromUtf8("/dev/null") }, |
941 | + { KEY_SIZE, quint64(blob.size()) }, |
942 | + { KEY_CTIME, quint64(time(nullptr)) }, |
943 | + { KEY_BLOB, blob } |
944 | + }; |
945 | + |
946 | + // add it |
947 | + auto msg = mock_iface_->call(QStringLiteral("AddRestoreChoice"), uuid, props); |
948 | + EXPECT_NE(QDBusMessage::ErrorMessage, msg.type()) << qPrintable(msg.errorMessage()); |
949 | + |
950 | + // ask for a list of restore choices |
951 | + QDBusReply<QVariantDictMap> choices = user_iface_->call("GetRestoreChoices"); |
952 | + EXPECT_TRUE(choices.isValid()) << qPrintable(choices.error().message()); |
953 | + |
954 | + // check the results |
955 | + const auto expected_choices = QVariantDictMap{{uuid, props}}; |
956 | + ASSERT_EQ(expected_choices, choices); |
957 | +} |
958 | + |
959 | + |
960 | +// test that StartRestore() fails if we pass an invalid arg |
961 | +TEST_F(KeeperTemplateTest, StartRestoreWithInvalidArg) |
962 | +{ |
963 | + const auto invalid_uuid = QUuid::createUuid().toString(); |
964 | + |
965 | + QDBusReply<void> reply = user_iface_->call("StartRestore", QStringList{invalid_uuid}); |
966 | + EXPECT_FALSE(reply.isValid()); |
967 | + EXPECT_EQ(QDBusError::InvalidArgs, reply.error().type()); |
968 | +} |
969 | + |
970 | + |
971 | +// test that Status() returns empty if we haven't done anything yet |
972 | +TEST_F(KeeperTemplateTest, TestEmptyStatus) |
973 | +{ |
974 | + EXPECT_TRUE(user_iface_->state().isEmpty()); |
975 | +} |
976 | + |
977 | + |
978 | +/*** |
979 | +**** Make a real backup |
980 | +***/ |
981 | + |
982 | +TEST_F(KeeperTemplateTest, BackupRun) |
983 | +{ |
984 | + QTemporaryDir sandbox; |
985 | + |
986 | + // build a backup choice |
987 | + const auto uuid = QUuid::createUuid().toString(); |
988 | + const QMap<QString,QVariant> props { |
989 | + { KEY_NAME, QStringLiteral("Music") }, |
990 | + { KEY_TYPE, QStringLiteral("folder") }, |
991 | + { KEY_SUBTYPE, sandbox.path() }, |
992 | + { KEY_ICON, QStringLiteral("music-icon") }, |
993 | + { KEY_HELPER, QString::fromUtf8(FAKE_BACKUP_HELPER_EXEC) } |
994 | + }; |
995 | + |
996 | + // add it |
997 | + auto msg = mock_iface_->call(QStringLiteral("AddBackupChoice"), uuid, props); |
998 | + EXPECT_NE(QDBusMessage::ErrorMessage, msg.type()) << qPrintable(msg.errorMessage()); |
999 | + |
1000 | + // start the backup |
1001 | + QDBusReply<void> reply = user_iface_->call("StartBackup", QStringList{uuid}); |
1002 | + EXPECT_TRUE(reply.isValid()) << qPrintable(reply.error().message()); |
1003 | + wait_for_backup_to_finish(); |
1004 | + |
1005 | + // ask keeper for the blob |
1006 | + QDBusReply<QByteArray> blob = mock_iface_->call(QStringLiteral("GetBackupData"), uuid); |
1007 | + EXPECT_TRUE(reply.isValid()) << qPrintable(reply.error().message()); |
1008 | + |
1009 | + // check the results |
1010 | + const auto expected_blob = QByteArray(FAKE_BACKUP_HELPER_PAYLOAD); |
1011 | + ASSERT_EQ(expected_blob, blob); |
1012 | +} |
1013 | |
1014 | === modified file 'tests/surface/CMakeLists.txt' |
1015 | --- tests/surface/CMakeLists.txt 2016-06-25 18:46:42 +0000 |
1016 | +++ tests/surface/CMakeLists.txt 2016-07-21 10:16:32 +0000 |
1017 | @@ -1,4 +1,5 @@ |
1018 | add_test(cppcheck cppcheck --enable=all -USCHEMA_DIR --error-exitcode=2 --inline-suppr -I${CMAKE_SOURCE_DIR}/src ${CMAKE_SOURCE_DIR}/src ${CMAKE_SOURCE_DIR}/tests) |
1019 | +add_test(flake8 flake8 ${SERVICE_TEMPLATE_FILE}) |
1020 | |
1021 | add_subdirectory(copyright) |
1022 | add_subdirectory(whitespace) |
1023 | |
1024 | === modified file 'tests/unit/helper/CMakeLists.txt' |
1025 | --- tests/unit/helper/CMakeLists.txt 2016-07-15 14:13:54 +0000 |
1026 | +++ tests/unit/helper/CMakeLists.txt 2016-07-21 10:16:32 +0000 |
1027 | @@ -1,5 +1,3 @@ |
1028 | -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") |
1029 | - |
1030 | add_definitions ( -DCMAKE_SOURCE_DIR="${CMAKE_CURRENT_SOURCE_DIR}" ) |
1031 | add_definitions ( -DCMAKE_BINARY_DIR="${CMAKE_CURRENT_BINARY_DIR}" ) |
1032 | |
1033 | |
1034 | === modified file 'tests/utils/CMakeLists.txt' |
1035 | --- tests/utils/CMakeLists.txt 2016-07-11 17:04:16 +0000 |
1036 | +++ tests/utils/CMakeLists.txt 2016-07-21 10:16:32 +0000 |
1037 | @@ -1,9 +1,16 @@ |
1038 | |
1039 | -include_directories("${CMAKE_SOURCE_DIR}/src") |
1040 | -include_directories(${CMAKE_CURRENT_BINARY_DIR}) |
1041 | +include_directories( |
1042 | + ${CMAKE_SOURCE_DIR}/src |
1043 | + ${CMAKE_CURRENT_BINARY_DIR} |
1044 | +) |
1045 | + |
1046 | +set( |
1047 | + LIB_NAME |
1048 | + test-utils |
1049 | +) |
1050 | |
1051 | add_library( |
1052 | - test-utils |
1053 | + ${LIB_NAME} |
1054 | STATIC |
1055 | main.cpp |
1056 | dummy-file.cpp |
1057 | @@ -11,6 +18,6 @@ |
1058 | ) |
1059 | |
1060 | qt5_use_modules( |
1061 | - test-utils |
1062 | + ${LIB_NAME} |
1063 | Core |
1064 | ) |
1065 | |
1066 | === modified file 'tests/utils/main.cpp' |
1067 | --- tests/utils/main.cpp 2016-07-01 18:02:27 +0000 |
1068 | +++ tests/utils/main.cpp 2016-07-21 10:16:32 +0000 |
1069 | @@ -17,6 +17,8 @@ |
1070 | * Pete Woods <pete.woods@canonical.com> |
1071 | */ |
1072 | |
1073 | +#include "qdbus-stubs/dbus-types.h" |
1074 | + |
1075 | #include <libqtdbusmock/DBusMock.h> |
1076 | |
1077 | #include <gtest/gtest.h> |
1078 | @@ -51,6 +53,8 @@ |
1079 | |
1080 | QCoreApplication application(argc, argv); |
1081 | DBusMock::registerMetaTypes(); |
1082 | + DBusTypes::registerMetaTypes(); |
1083 | + |
1084 | ::testing::InitGoogleTest(&argc, argv); |
1085 | |
1086 | Runner runner; |
Thanks Charles.
I'm not very familiar with this kind of code defining mocks in python but I haven't seen anything weird. Just a couple of questions to understand the code better.