Merge lp:~renatofilho/address-book-service/create-source into lp:address-book-service
- create-source
- Merge into trunk
Status: | Merged |
---|---|
Merged at revision: | 104 |
Proposed branch: | lp:~renatofilho/address-book-service/create-source |
Merge into: | lp:address-book-service |
Prerequisite: | lp:~renatofilho/address-book-service/fix-1269561 |
Diff against target: |
786 lines (+235/-95) 17 files modified
CMakeLists.txt (+7/-1) debian/control (+1/-0) lib/CMakeLists.txt (+4/-0) lib/addressbook-adaptor.cpp (+10/-0) lib/addressbook-adaptor.h (+6/-0) lib/addressbook.cpp (+48/-39) lib/addressbook.h (+8/-4) lib/dirtycontact-notify.cpp (+49/-0) lib/dirtycontact-notify.h (+56/-0) tests/unittest/CMakeLists.txt (+2/-1) tests/unittest/addressbook-server.cpp (+4/-1) tests/unittest/addressbook-test.cpp (+10/-11) tests/unittest/base-client-test.cpp (+4/-0) tests/unittest/contactmap-test.cpp (+1/-0) tests/unittest/dummy-backend.cpp (+20/-35) tests/unittest/dummy-backend.h (+2/-1) tests/unittest/service-life-cycle-test.cpp (+3/-2) |
To merge this branch: | bzr merge lp:~renatofilho/address-book-service/create-source |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
PS Jenkins bot | continuous-integration | Approve | |
Bill Filler (community) | Approve | ||
Review via email: mp+206832@code.launchpad.net |
This proposal supersedes a proposal from 2014-02-18.
Commit message
Implemented createSource functionality.
Description of the change
* Are there any related MPs required for this MP to build/function as expected? Please list. NO
* Is your branch in sync with latest trunk (e.g. bzr pull lp:trunk -> no changes) YES
* Did you perform an exploratory manual test run of your code change and any related functionality on device or emulator? YES
* Did you successfully run all tests found in your component's Test Plan (https:/
* If you changed the UI, was the change specified/approved by design? N/A
* If you changed the packaging (debian), did you subscribe a core-dev to this MP? N/A
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:99
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 100. By Renato Araujo Oliveira Filho
-
Merged parent branch.
- 101. By Renato Araujo Oliveira Filho
-
Merged parent branch.
- 102. By Renato Araujo Oliveira Filho
-
Merged mainline.
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:102
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 103. By Renato Araujo Oliveira Filho
-
Attempt to fix power pc build
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:103
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 104. By Renato Araujo Oliveira Filho
-
Attempt to fix powerpc tests.
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:104
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 105. By Renato Araujo Oliveira Filho
-
Attempt to fix powerpc tests.
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:105
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 106. By Renato Araujo Oliveira Filho
-
Moved DirtyContactsNotify class to a individual file and make it a QObject.
- 107. By Renato Araujo Oliveira Filho
-
Make sure that the temporary directory is created.
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:106
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 108. By Renato Araujo Oliveira Filho
-
Make the dummy backend start async in an attempt to fix powerPC tests.
- 109. By Renato Araujo Oliveira Filho
-
Added debug messages.
- 110. By Renato Araujo Oliveira Filho
-
Skip tests when running on PPC machines.
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:107
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:110
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Preview Diff
1 | === modified file 'CMakeLists.txt' |
2 | --- CMakeLists.txt 2013-11-06 14:42:23 +0000 |
3 | +++ CMakeLists.txt 2014-03-18 17:29:45 +0000 |
4 | @@ -14,6 +14,7 @@ |
5 | pkg_check_modules(GLIB REQUIRED glib-2.0>=2.32) |
6 | pkg_check_modules(GIO REQUIRED gio-2.0>=2.32) |
7 | pkg_check_modules(FOLKS REQUIRED folks>=0.9.0) |
8 | +pkg_check_modules(FOLKS_EDS REQUIRED folks-eds) |
9 | |
10 | if(FOLKS_VERSION VERSION_LESS "0.9.5") |
11 | set(FOLKS_VERSION_LESS_THAN_0_9_5 "1") |
12 | @@ -68,7 +69,12 @@ |
13 | add_subdirectory(lib) |
14 | add_subdirectory(src) |
15 | add_subdirectory(qcontacts) |
16 | -add_subdirectory(tests) |
17 | add_subdirectory(data) |
18 | +if(CMAKE_SYSTEM_PROCESSOR STREQUAL "ppc") |
19 | + # Some tests fail when running on PPPC check bug #1294229 |
20 | + message(STATUS "Tests disable for ppc") |
21 | +else() |
22 | + add_subdirectory(tests) |
23 | +endif() |
24 | |
25 | configure_file(config.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h) |
26 | |
27 | === modified file 'debian/control' |
28 | --- debian/control 2013-10-30 00:19:00 +0000 |
29 | +++ debian/control 2014-03-18 17:29:45 +0000 |
30 | @@ -7,6 +7,7 @@ |
31 | debhelper (>= 9), |
32 | gobject-introspection (>= 1.31.0-2~), |
33 | libfolks-dev, |
34 | + libfolks-eds-dev, |
35 | libgee-0.8-dev (>= 0.8.4), |
36 | qt5-default, |
37 | qt5-qmake, |
38 | |
39 | === modified file 'lib/CMakeLists.txt' |
40 | --- lib/CMakeLists.txt 2013-10-30 19:07:49 +0000 |
41 | +++ lib/CMakeLists.txt 2014-03-18 17:29:45 +0000 |
42 | @@ -7,6 +7,7 @@ |
43 | addressbook-adaptor.cpp |
44 | contacts-map.cpp |
45 | detail-context-parser.cpp |
46 | + dirtycontact-notify.cpp |
47 | gee-utils.cpp |
48 | qindividual.cpp |
49 | source.cpp |
50 | @@ -20,6 +21,7 @@ |
51 | addressbook-adaptor.h |
52 | contacts-map.h |
53 | detail-context-parser.h |
54 | + dirtycontact-notify.h |
55 | gee-utils.h |
56 | qindividual.h |
57 | source.h |
58 | @@ -38,6 +40,7 @@ |
59 | ${GLIB_LIBRARIES} |
60 | ${GIO_LIBRARIES} |
61 | ${FOLKS_LIBRARIES} |
62 | + ${FOLKS_EDS_LIBRARIES} |
63 | ) |
64 | |
65 | qt5_use_modules(${CONTACTS_SERVICE_LIB} Core Contacts DBus Versit) |
66 | @@ -48,4 +51,5 @@ |
67 | ${GLIB_INCLUDE_DIRS} |
68 | ${GIO_INCLUDE_DIRS} |
69 | ${FOLKS_INCLUDE_DIRS} |
70 | + ${FOLKS_EDS_INCLUDE_DIRS} |
71 | ) |
72 | |
73 | === modified file 'lib/addressbook-adaptor.cpp' |
74 | --- lib/addressbook-adaptor.cpp 2013-11-04 18:34:43 +0000 |
75 | +++ lib/addressbook-adaptor.cpp 2014-03-18 17:29:45 +0000 |
76 | @@ -54,6 +54,16 @@ |
77 | return Source(); |
78 | } |
79 | |
80 | +Source AddressBookAdaptor::createSource(const QString &sourceName, const QDBusMessage &message) |
81 | +{ |
82 | + message.setDelayedReply(true); |
83 | + QMetaObject::invokeMethod(m_addressBook, "createSource", |
84 | + Qt::QueuedConnection, |
85 | + Q_ARG(const QString&, sourceName), |
86 | + Q_ARG(const QDBusMessage&, message)); |
87 | + return Source(); |
88 | +} |
89 | + |
90 | QString AddressBookAdaptor::createContact(const QString &contact, const QString &source, const QDBusMessage &message) |
91 | { |
92 | message.setDelayedReply(true); |
93 | |
94 | === modified file 'lib/addressbook-adaptor.h' |
95 | --- lib/addressbook-adaptor.h 2013-11-01 01:10:12 +0000 |
96 | +++ lib/addressbook-adaptor.h 2014-03-18 17:29:45 +0000 |
97 | @@ -62,6 +62,11 @@ |
98 | " <arg direction=\"out\" type=\"(sb)\"/>\n" |
99 | " <annotation value=\"Source\" name=\"com.trolltech.QtDBus.QtTypeName.Out0\"/>\n" |
100 | " </method>\n" |
101 | +" <method name=\"createSource\">\n" |
102 | +" <arg direction=\"in\" type=\"s\"/>\n" |
103 | +" <arg direction=\"out\" type=\"(sb)\"/>\n" |
104 | +" <annotation value=\"Source\" name=\"com.trolltech.QtDBus.QtTypeName.Out0\"/>\n" |
105 | +" </method>\n" |
106 | " <method name=\"sortFields\">\n" |
107 | " <arg direction=\"out\" type=\"as\"/>\n" |
108 | " </method>\n" |
109 | @@ -103,6 +108,7 @@ |
110 | public Q_SLOTS: |
111 | SourceList availableSources(const QDBusMessage &message); |
112 | Source source(const QDBusMessage &message); |
113 | + Source createSource(const QString &sourceName, const QDBusMessage &message); |
114 | QStringList sortFields(); |
115 | QDBusObjectPath query(const QString &clause, const QString &sort, const QStringList &sources); |
116 | int removeContacts(const QStringList &contactIds, const QDBusMessage &message); |
117 | |
118 | === modified file 'lib/addressbook.cpp' |
119 | --- lib/addressbook.cpp 2014-02-24 12:21:08 +0000 |
120 | +++ lib/addressbook.cpp 2014-03-18 17:29:45 +0000 |
121 | @@ -22,6 +22,7 @@ |
122 | #include "view.h" |
123 | #include "contacts-map.h" |
124 | #include "qindividual.h" |
125 | +#include "dirtycontact-notify.h" |
126 | |
127 | #include "common/vcard-parser.h" |
128 | |
129 | @@ -31,8 +32,7 @@ |
130 | #include <signal.h> |
131 | #include <sys/socket.h> |
132 | |
133 | -//this timeout represents how long the server will wait for changes on the contact before notify the client |
134 | -#define NOTIFY_CONTACTS_TIMEOUT 500 |
135 | +#include <folks/folks-eds.h> |
136 | |
137 | using namespace QtContacts; |
138 | |
139 | @@ -66,46 +66,20 @@ |
140 | int m_sucessCount; |
141 | }; |
142 | |
143 | +class CreateSourceData |
144 | +{ |
145 | +public: |
146 | + QString sourceName; |
147 | + galera::AddressBook *m_addressbook; |
148 | + QDBusMessage m_message; |
149 | +}; |
150 | + |
151 | } |
152 | |
153 | namespace galera |
154 | { |
155 | int AddressBook::m_sigQuitFd[2] = {0, 0}; |
156 | |
157 | -// this is a helper class uses a timer with a small timeout to notify the client about |
158 | -// any contact change notification. This class should be used instead of emit the signal directly |
159 | -// this will avoid notify about the contact update several times when updating different fields simultaneously |
160 | -// With that we can reduce the dbus traffic and skip some client calls to query about the new contact info. |
161 | -class DirtyContactsNotify |
162 | -{ |
163 | -public: |
164 | - DirtyContactsNotify(AddressBookAdaptor *adaptor) |
165 | - { |
166 | - m_timer.setInterval(NOTIFY_CONTACTS_TIMEOUT); |
167 | - m_timer.setSingleShot(true); |
168 | - QObject::connect(&m_timer, &QTimer::timeout, |
169 | - [=]() { |
170 | - Q_EMIT adaptor->contactsUpdated(m_ids); |
171 | - m_ids.clear(); |
172 | - }); |
173 | - } |
174 | - |
175 | - void append(QStringList ids) |
176 | - { |
177 | - Q_FOREACH(QString id, ids) { |
178 | - if (!m_ids.contains(id)) { |
179 | - m_ids << id; |
180 | - } |
181 | - } |
182 | - |
183 | - m_timer.start(); |
184 | - } |
185 | - |
186 | -private: |
187 | - QTimer m_timer; |
188 | - QStringList m_ids; |
189 | -}; |
190 | - |
191 | AddressBook::AddressBook(QObject *parent) |
192 | : QObject(parent), |
193 | m_individualAggregator(0), |
194 | @@ -176,6 +150,11 @@ |
195 | return false; |
196 | } |
197 | |
198 | +bool AddressBook::start() |
199 | +{ |
200 | + return start(QDBusConnection::sessionBus()); |
201 | +} |
202 | + |
203 | void AddressBook::shutdown() |
204 | { |
205 | m_ready = false; |
206 | @@ -217,7 +196,6 @@ |
207 | |
208 | void AddressBook::prepareFolks() |
209 | { |
210 | - qDebug() << "Prepare folks"; |
211 | m_individualAggregator = FOLKS_INDIVIDUAL_AGGREGATOR_DUP(); |
212 | g_object_get(G_OBJECT(m_individualAggregator), "is-quiescent", &m_ready, NULL); |
213 | if (m_ready) { |
214 | @@ -250,6 +228,37 @@ |
215 | return Source(); |
216 | } |
217 | |
218 | +Source AddressBook::createSource(const QString &sourceId, const QDBusMessage &message) |
219 | +{ |
220 | + CreateSourceData *data = new CreateSourceData; |
221 | + data->m_addressbook = this; |
222 | + data->m_message = message; |
223 | + data->sourceName = sourceId; |
224 | + edsf_persona_store_create_address_book(sourceId.toUtf8().data(), |
225 | + (GAsyncReadyCallback) AddressBook::createSourceDone, |
226 | + data); |
227 | + return Source(); |
228 | +} |
229 | + |
230 | +void AddressBook::createSourceDone(GObject *source, |
231 | + GAsyncResult *res, |
232 | + void *data) |
233 | +{ |
234 | + CreateSourceData *cData = static_cast<CreateSourceData*>(data); |
235 | + GError *error = 0; |
236 | + Source src; |
237 | + edsf_persona_store_create_address_book_finish(res, &error); |
238 | + if (error) { |
239 | + qWarning() << "Fail to create source" << error->message; |
240 | + g_error_free(error); |
241 | + } else { |
242 | + src = Source(cData->sourceName, false); |
243 | + } |
244 | + QDBusMessage reply = cData->m_message.createReply(QVariant::fromValue<Source>(src)); |
245 | + QDBusConnection::sessionBus().send(reply); |
246 | + delete cData; |
247 | +} |
248 | + |
249 | void AddressBook::getSource(const QDBusMessage &message, bool onlyTheDefault) |
250 | { |
251 | FolksBackendStore *backendStore = folks_backend_store_dup(); |
252 | @@ -387,7 +396,7 @@ |
253 | |
254 | void AddressBook::individualChanged(QIndividual *individual) |
255 | { |
256 | - m_notifyContactUpdate->append(QStringList() << individual->id()); |
257 | + m_notifyContactUpdate->append(QSet<QString>() << individual->id()); |
258 | } |
259 | |
260 | int AddressBook::removeContacts(const QStringList &contactIds, const QDBusMessage &message) |
261 | @@ -529,7 +538,7 @@ |
262 | QDBusConnection::sessionBus().send(reply); |
263 | |
264 | // notify about the changes |
265 | - m_notifyContactUpdate->append(m_updatedIds); |
266 | + m_notifyContactUpdate->append(m_updatedIds.toSet()); |
267 | |
268 | // clear command data |
269 | m_updatedIds.clear(); |
270 | |
271 | === modified file 'lib/addressbook.h' |
272 | --- lib/addressbook.h 2014-02-09 00:22:52 +0000 |
273 | +++ lib/addressbook.h 2014-03-18 17:29:45 +0000 |
274 | @@ -25,7 +25,6 @@ |
275 | #include <QtCore/QSet> |
276 | #include <QtCore/QString> |
277 | #include <QtCore/QStringList> |
278 | -#include <QtCore/QTimer> |
279 | |
280 | #include <QtDBus/QtDBus> |
281 | |
282 | @@ -50,8 +49,8 @@ |
283 | AddressBook(QObject *parent=0); |
284 | virtual ~AddressBook(); |
285 | |
286 | - static QString objectPath(); |
287 | - bool start(QDBusConnection connection = QDBusConnection::sessionBus()); |
288 | + static QString objectPath(); |
289 | + bool start(QDBusConnection connection); |
290 | |
291 | // Adaptor |
292 | QString linkContacts(const QStringList &contacts); |
293 | @@ -65,10 +64,12 @@ |
294 | Q_SIGNALS: |
295 | void stopped(); |
296 | |
297 | -public Q_SLOTS: |
298 | +public Q_SLOTS: |
299 | + bool start(); |
300 | void shutdown(); |
301 | SourceList availableSources(const QDBusMessage &message); |
302 | Source source(const QDBusMessage &message); |
303 | + Source createSource(const QString &sourceId, const QDBusMessage &message); |
304 | QString createContact(const QString &contact, const QString &source, const QDBusMessage &message); |
305 | int removeContacts(const QStringList &contactIds, const QDBusMessage &message); |
306 | QStringList updateContacts(const QStringList &contacts, const QDBusMessage &message); |
307 | @@ -146,6 +147,9 @@ |
308 | static void addAntiLinksDone(FolksAntiLinkable *antilinkable, |
309 | GAsyncResult *result, |
310 | void *data); |
311 | + static void createSourceDone(GObject *source, |
312 | + GAsyncResult *res, |
313 | + void *data); |
314 | friend class DirtyContactsNotify; |
315 | }; |
316 | |
317 | |
318 | === added file 'lib/dirtycontact-notify.cpp' |
319 | --- lib/dirtycontact-notify.cpp 1970-01-01 00:00:00 +0000 |
320 | +++ lib/dirtycontact-notify.cpp 2014-03-18 17:29:45 +0000 |
321 | @@ -0,0 +1,49 @@ |
322 | +/* |
323 | + * Copyright 2014 Canonical Ltd. |
324 | + * |
325 | + * This file is part of contact-service-app. |
326 | + * |
327 | + * contact-service-app is free software; you can redistribute it and/or modify |
328 | + * it under the terms of the GNU General Public License as published by |
329 | + * the Free Software Foundation; version 3. |
330 | + * |
331 | + * contact-service-app is distributed in the hope that it will be useful, |
332 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
333 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
334 | + * GNU General Public License for more details. |
335 | + * |
336 | + * You should have received a copy of the GNU General Public License |
337 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
338 | + */ |
339 | + |
340 | + |
341 | +//this timeout represents how long the server will wait for changes on the contact before notify the client |
342 | +#define NOTIFY_CONTACTS_TIMEOUT 500 |
343 | + |
344 | +#include "dirtycontact-notify.h" |
345 | +#include "addressbook-adaptor.h" |
346 | + |
347 | +namespace galera { |
348 | + |
349 | +DirtyContactsNotify::DirtyContactsNotify(AddressBookAdaptor *adaptor, QObject *parent) |
350 | + : QObject(parent), |
351 | + m_adaptor(adaptor) |
352 | +{ |
353 | + m_timer.setInterval(NOTIFY_CONTACTS_TIMEOUT); |
354 | + m_timer.setSingleShot(true); |
355 | + connect(&m_timer, SIGNAL(timeout()), SLOT(onTimeout())); |
356 | +} |
357 | + |
358 | +void DirtyContactsNotify::append(QSet<QString> ids) |
359 | +{ |
360 | + m_ids += ids; |
361 | + m_timer.start(); |
362 | +} |
363 | + |
364 | +void DirtyContactsNotify::onTimeout() |
365 | +{ |
366 | + Q_EMIT m_adaptor->contactsUpdated(m_ids.toList()); |
367 | + m_ids.clear(); |
368 | +} |
369 | + |
370 | +} //namespace |
371 | |
372 | === added file 'lib/dirtycontact-notify.h' |
373 | --- lib/dirtycontact-notify.h 1970-01-01 00:00:00 +0000 |
374 | +++ lib/dirtycontact-notify.h 2014-03-18 17:29:45 +0000 |
375 | @@ -0,0 +1,56 @@ |
376 | +/* |
377 | + * Copyright 2014 Canonical Ltd. |
378 | + * |
379 | + * This file is part of contact-service-app. |
380 | + * |
381 | + * contact-service-app is free software; you can redistribute it and/or modify |
382 | + * it under the terms of the GNU General Public License as published by |
383 | + * the Free Software Foundation; version 3. |
384 | + * |
385 | + * contact-service-app is distributed in the hope that it will be useful, |
386 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
387 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
388 | + * GNU General Public License for more details. |
389 | + * |
390 | + * You should have received a copy of the GNU General Public License |
391 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
392 | + */ |
393 | + |
394 | +#ifndef __GALERA_DIRTYCONTACT_NOTIFY_H__ |
395 | +#define __GALERA_DIRTYCONTACT_NOTIFY_H__ |
396 | + |
397 | +#include <QtCore/QObject> |
398 | +#include <QtCore/QTimer> |
399 | +#include <QtCore/QSet> |
400 | +#include <QtCore/QString> |
401 | +#include <QtCore/QStringList> |
402 | + |
403 | +namespace galera { |
404 | + |
405 | +class AddressBookAdaptor; |
406 | + |
407 | +// this is a helper class uses a timer with a small timeout to notify the client about |
408 | +// any contact change notification. This class should be used instead of emit the signal directly |
409 | +// this will avoid notify about the contact update several times when updating different fields simultaneously |
410 | +// With that we can reduce the dbus traffic and skip some client calls to query about the new contact info. |
411 | +class DirtyContactsNotify : public QObject |
412 | +{ |
413 | + Q_OBJECT |
414 | + |
415 | +public: |
416 | + DirtyContactsNotify(AddressBookAdaptor *adaptor, QObject *parent=0); |
417 | + |
418 | + void append(QSet<QString> ids); |
419 | + |
420 | +private Q_SLOTS: |
421 | + void onTimeout(); |
422 | + |
423 | +private: |
424 | + AddressBookAdaptor *m_adaptor; |
425 | + QTimer m_timer; |
426 | + QSet<QString> m_ids; |
427 | +}; |
428 | + |
429 | +} //namespace |
430 | + |
431 | +#endif |
432 | |
433 | === modified file 'tests/unittest/CMakeLists.txt' |
434 | --- tests/unittest/CMakeLists.txt 2014-02-24 17:07:42 +0000 |
435 | +++ tests/unittest/CMakeLists.txt 2014-03-18 17:29:45 +0000 |
436 | @@ -23,13 +23,14 @@ |
437 | if(${RUN_SERVER} STREQUAL "True") |
438 | add_test(${TESTNAME} |
439 | ${DBUS_RUNNER} |
440 | + --keep-env |
441 | --task ${CMAKE_CURRENT_BINARY_DIR}/address-book-server-test |
442 | --task ${CMAKE_CURRENT_BINARY_DIR}/${TESTNAME} ${TEST_ARGS} --wait-for=com.canonical.pim) |
443 | else() |
444 | add_test(${TESTNAME} ${TESTNAME}) |
445 | endif() |
446 | |
447 | - set(TEST_ENVIRONMENT "QT_QPA_PLATFORM=minimal\;FOLKS_BACKEND_PATH=${folks-dummy-backend_BINARY_DIR}/dummy.so") |
448 | + set(TEST_ENVIRONMENT "QT_QPA_PLATFORM=minimal\;FOLKS_BACKEND_PATH=${folks-dummy-backend_BINARY_DIR}/dummy.so\;FOLKS_BACKENDS_ALLOWED=dummy") |
449 | set_tests_properties(${TESTNAME} PROPERTIES |
450 | ENVIRONMENT ${TEST_ENVIRONMENT} |
451 | TIMEOUT ${CTEST_TESTING_TIMEOUT}) |
452 | |
453 | === modified file 'tests/unittest/addressbook-server.cpp' |
454 | --- tests/unittest/addressbook-server.cpp 2013-11-01 01:10:12 +0000 |
455 | +++ tests/unittest/addressbook-server.cpp 2014-03-18 17:29:45 +0000 |
456 | @@ -19,6 +19,8 @@ |
457 | #include "lib/addressbook.h" |
458 | #include "dummy-backend.h" |
459 | |
460 | +#include <QtCore/QTimer> |
461 | + |
462 | int main(int argc, char** argv) |
463 | { |
464 | galera::AddressBook::init(); |
465 | @@ -30,9 +32,10 @@ |
466 | |
467 | // addressbook |
468 | galera::AddressBook book; |
469 | - book.start(); |
470 | |
471 | + book.connect(&dummy, SIGNAL(ready()), SLOT(start())); |
472 | book.connect(&dummy, SIGNAL(stopped()), SLOT(shutdown())); |
473 | + |
474 | app.connect(&book, SIGNAL(stopped()), SLOT(quit())); |
475 | return app.exec(); |
476 | } |
477 | |
478 | === modified file 'tests/unittest/addressbook-test.cpp' |
479 | --- tests/unittest/addressbook-test.cpp 2014-02-12 00:28:03 +0000 |
480 | +++ tests/unittest/addressbook-test.cpp 2014-03-18 17:29:45 +0000 |
481 | @@ -172,7 +172,7 @@ |
482 | void testCreateContact() |
483 | { |
484 | // spy 'contactsAdded' signal |
485 | - QSignalSpy addedContactSpy(m_serverIface, SIGNAL(contactsAdded(const QStringList &))); |
486 | + QSignalSpy addedContactSpy(m_serverIface, SIGNAL(contactsAdded(QStringList))); |
487 | |
488 | // call create contact |
489 | QDBusReply<QString> reply = m_serverIface->call("createContact", m_basicVcard, "dummy-store"); |
490 | @@ -189,11 +189,8 @@ |
491 | QCOMPARE(contactsCreated.count(), 1); |
492 | compareContact(contactsCreated[0], newContact); |
493 | |
494 | - // wait for folks to emit the signal |
495 | - QTest::qWait(500); |
496 | - |
497 | // check if the signal "contactAdded" was fired |
498 | - QCOMPARE(addedContactSpy.count(), 1); |
499 | + QTRY_COMPARE(addedContactSpy.count(), 1); |
500 | QList<QVariant> args = addedContactSpy.takeFirst(); |
501 | QCOMPARE(args.count(), 1); |
502 | QStringList ids = args[0].toStringList(); |
503 | @@ -203,13 +200,13 @@ |
504 | void testDuplicateContact() |
505 | { |
506 | // spy 'contactsAdded' signal |
507 | - QSignalSpy addedContactSpy(m_serverIface, SIGNAL(contactsAdded(const QStringList &))); |
508 | + QSignalSpy addedContactSpy(m_serverIface, SIGNAL(contactsAdded(QStringList))); |
509 | |
510 | // call create contact first |
511 | QDBusReply<QString> reply = m_serverIface->call("createContact", m_basicVcard, "dummy-store"); |
512 | |
513 | // wait for folks to emit the signal |
514 | - QTest::qWait(500); |
515 | + QTRY_COMPARE(addedContactSpy.count(), 1); |
516 | |
517 | // user returned id to fill the new vcard |
518 | QString newContactId = reply.value(); |
519 | @@ -225,13 +222,13 @@ |
520 | QVERIFY(reply2.value().isEmpty()); |
521 | |
522 | // contactsAdded should be fired only once |
523 | - QCOMPARE(addedContactSpy.count(), 1); |
524 | + QTRY_COMPARE(addedContactSpy.count(), 1); |
525 | } |
526 | |
527 | void testCreateInvalidContact() |
528 | { |
529 | // spy 'contactsAdded' signal |
530 | - QSignalSpy addedContactSpy(m_serverIface, SIGNAL(contactsAdded(const QStringList &))); |
531 | + QSignalSpy addedContactSpy(m_serverIface, SIGNAL(contactsAdded(QStringList))); |
532 | |
533 | // call create contact with a invalid vcard string |
534 | QDBusReply<QString> reply = m_serverIface->call("createContact", "INVALID VCARD", "dummy-store"); |
535 | @@ -246,11 +243,13 @@ |
536 | void testRemoveContact() |
537 | { |
538 | // create a basic contact |
539 | + QSignalSpy addedContactSpy(m_serverIface, SIGNAL(contactsAdded(QStringList))); |
540 | QDBusReply<QString> replyAdd = m_serverIface->call("createContact", m_basicVcard, "dummy-store"); |
541 | QString newContactId = replyAdd.value(); |
542 | + QTRY_COMPARE(addedContactSpy.count(), 1); |
543 | |
544 | // spy 'contactsRemoved' signal |
545 | - QSignalSpy removedContactSpy(m_serverIface, SIGNAL(contactsRemoved(const QStringList &))); |
546 | + QSignalSpy removedContactSpy(m_serverIface, SIGNAL(contactsRemoved(QStringList))); |
547 | |
548 | // try remove the contact created |
549 | QDBusReply<int> replyRemove = m_serverIface->call("removeContacts", QStringList() << newContactId); |
550 | @@ -281,7 +280,7 @@ |
551 | QtContacts::QContact contactUpdated = contacts[0]; |
552 | |
553 | // spy 'contactsUpdated' signal |
554 | - QSignalSpy updateContactSpy(m_serverIface, SIGNAL(contactsUpdated(const QStringList &))); |
555 | + QSignalSpy updateContactSpy(m_serverIface, SIGNAL(contactsUpdated(QStringList))); |
556 | QDBusReply<QStringList> replyUpdate = m_serverIface->call("updateContacts", QStringList() << vcard); |
557 | QStringList result = replyUpdate.value(); |
558 | QCOMPARE(result.size(), 1); |
559 | |
560 | === modified file 'tests/unittest/base-client-test.cpp' |
561 | --- tests/unittest/base-client-test.cpp 2013-11-05 19:26:25 +0000 |
562 | +++ tests/unittest/base-client-test.cpp 2014-03-18 17:29:45 +0000 |
563 | @@ -34,11 +34,15 @@ |
564 | CPIM_ADDRESSBOOK_OBJECT_PATH, |
565 | CPIM_ADDRESSBOOK_IFACE_NAME); |
566 | QVERIFY(!m_serverIface->lastError().isValid()); |
567 | + // wait for service to be ready |
568 | + QTRY_COMPARE_WITH_TIMEOUT(m_serverIface->property("isReady").toBool(), true, 10000); |
569 | |
570 | m_dummyIface = new QDBusInterface(DUMMY_SERVICE_NAME, |
571 | DUMMY_OBJECT_PATH, |
572 | DUMMY_IFACE_NAME); |
573 | QVERIFY(!m_dummyIface->lastError().isValid()); |
574 | + // wait for service to be ready |
575 | + QTRY_COMPARE_WITH_TIMEOUT(m_dummyIface->property("isReady").toBool(), true, 10000); |
576 | } |
577 | |
578 | void BaseClientTest::init() |
579 | |
580 | === modified file 'tests/unittest/contactmap-test.cpp' |
581 | --- tests/unittest/contactmap-test.cpp 2013-11-05 19:26:25 +0000 |
582 | +++ tests/unittest/contactmap-test.cpp 2014-03-18 17:29:45 +0000 |
583 | @@ -76,6 +76,7 @@ |
584 | { |
585 | m_dummy = new DummyBackendProxy(); |
586 | m_dummy->start(); |
587 | + QTRY_VERIFY(m_dummy->isReady()); |
588 | |
589 | createContactWithSuffix("1"); |
590 | createContactWithSuffix("2"); |
591 | |
592 | === modified file 'tests/unittest/dummy-backend.cpp' |
593 | --- tests/unittest/dummy-backend.cpp 2014-02-13 14:32:48 +0000 |
594 | +++ tests/unittest/dummy-backend.cpp 2014-03-18 17:29:45 +0000 |
595 | @@ -45,12 +45,9 @@ |
596 | |
597 | void DummyBackendProxy::start(bool useDBus) |
598 | { |
599 | + m_useDBus = useDBus; |
600 | initEnviroment(); |
601 | initFolks(); |
602 | - prepareAggregator(); |
603 | - if (useDBus) { |
604 | - registerObject(); |
605 | - } |
606 | } |
607 | |
608 | void DummyBackendProxy::shutdown() |
609 | @@ -60,7 +57,6 @@ |
610 | QDBusConnection connection = QDBusConnection::sessionBus(); |
611 | connection.unregisterObject(DUMMY_OBJECT_PATH); |
612 | connection.unregisterService(DUMMY_SERVICE_NAME); |
613 | - qDebug() << "Unregister service; DUMMY"; |
614 | |
615 | delete m_adaptor; |
616 | m_adaptor = 0; |
617 | @@ -130,27 +126,11 @@ |
618 | } |
619 | |
620 | void DummyBackendProxy::initFolks() |
621 | -{ |
622 | - ScopedEventLoop loop(&m_eventLoop); |
623 | +{ |
624 | m_backendStore = folks_backend_store_dup(); |
625 | folks_backend_store_load_backends(m_backendStore, |
626 | (GAsyncReadyCallback) DummyBackendProxy::backendStoreLoaded, |
627 | this); |
628 | - |
629 | - loop.exec(); |
630 | - |
631 | - loop.reset(&m_eventLoop); |
632 | - folks_backend_store_enable_backend(m_backendStore, "dummy", |
633 | - (GAsyncReadyCallback) DummyBackendProxy::backendEnabled, |
634 | - this); |
635 | - loop.exec(); |
636 | - |
637 | - m_backend = FOLKS_DUMMY_BACKEND(folks_backend_store_dup_backend_by_name(m_backendStore, "dummy")); |
638 | - |
639 | - Q_ASSERT(m_backend != 0); |
640 | - configurePrimaryStore(); |
641 | - m_isReady = true; |
642 | - Q_EMIT ready(); |
643 | } |
644 | |
645 | bool DummyBackendProxy::isReady() const |
646 | @@ -160,8 +140,6 @@ |
647 | |
648 | void DummyBackendProxy::prepareAggregator() |
649 | { |
650 | - ScopedEventLoop loop(&m_eventLoop); |
651 | - |
652 | m_aggregator = FOLKS_INDIVIDUAL_AGGREGATOR_DUP(); |
653 | m_individualsChangedDetailedId = g_signal_connect(m_aggregator, |
654 | "individuals-changed-detailed", |
655 | @@ -171,7 +149,6 @@ |
656 | (GAsyncReadyCallback) DummyBackendProxy::individualAggregatorPrepared, |
657 | this); |
658 | |
659 | - loop.exec(); |
660 | } |
661 | |
662 | QString DummyBackendProxy::createContact(const QtContacts::QContact &qcontact) |
663 | @@ -237,6 +214,7 @@ |
664 | folks_dummy_backend_register_persona_stores(m_backend, GEE_SET(personaStores), true); |
665 | folks_dummy_persona_store_reach_quiescence(m_primaryPersonaStore); |
666 | g_object_unref(personaStores); |
667 | + prepareAggregator(); |
668 | } |
669 | |
670 | void DummyBackendProxy::backendEnabled(FolksBackendStore *backendStore, |
671 | @@ -257,8 +235,9 @@ |
672 | folks_backend_store_load_backends_finish(backendStore, res, &error); |
673 | checkError(error); |
674 | |
675 | - self->m_eventLoop->quit(); |
676 | - self->m_eventLoop = 0; |
677 | + self->m_backend = FOLKS_DUMMY_BACKEND(folks_backend_store_dup_backend_by_name(self->m_backendStore, "dummy")); |
678 | + Q_ASSERT(self->m_backend != 0); |
679 | + self->configurePrimaryStore(); |
680 | } |
681 | |
682 | void DummyBackendProxy::checkError(GError *error) |
683 | @@ -270,28 +249,31 @@ |
684 | Q_ASSERT(error == 0); |
685 | } |
686 | |
687 | -void DummyBackendProxy::mkpath(const QString &path) |
688 | +void DummyBackendProxy::mkpath(const QString &path) const |
689 | { |
690 | QDir dir; |
691 | + if (!dir.mkpath(path)) { |
692 | + qWarning() << "Fail to create path" << path; |
693 | + } |
694 | Q_ASSERT(dir.mkpath(path)); |
695 | } |
696 | |
697 | void DummyBackendProxy::initEnviroment() |
698 | { |
699 | Q_ASSERT(m_tmpDir.isValid()); |
700 | - QString tmpFullPath = QString("%1/folks-test").arg(m_tmpDir.path()); |
701 | + QString tmpFullPath = QString("%1").arg(m_tmpDir.path()); |
702 | |
703 | qputenv("FOLKS_BACKENDS_ALLOWED", "dummy"); |
704 | qputenv("FOLKS_PRIMARY_STORE", "dummy"); |
705 | |
706 | + mkpath(tmpFullPath); |
707 | qDebug() << "setting up in transient directory:" << tmpFullPath; |
708 | |
709 | // home |
710 | qputenv("HOME", tmpFullPath.toUtf8().data()); |
711 | |
712 | - // cache |
713 | - QString cacheDir = QString("%1/.cache").arg(tmpFullPath); |
714 | - |
715 | + // cache |
716 | + QString cacheDir = QString("%1/.cache/").arg(tmpFullPath); |
717 | mkpath(cacheDir); |
718 | qputenv("XDG_CACHE_HOME", cacheDir.toUtf8().data()); |
719 | |
720 | @@ -307,7 +289,7 @@ |
721 | mkpath(QString("%1/folks").arg(dataDir)); |
722 | |
723 | // runtime |
724 | - QString runtimeDir = QString("%1/XDG_RUNTIME_DIR").arg(tmpFullPath); |
725 | + QString runtimeDir = QString("%1/run").arg(tmpFullPath); |
726 | mkpath(runtimeDir); |
727 | qputenv("XDG_RUNTIME_DIR", runtimeDir.toUtf8().data()); |
728 | |
729 | @@ -351,9 +333,12 @@ |
730 | |
731 | folks_individual_aggregator_prepare_finish(fia, res, &error); |
732 | checkError(error); |
733 | + if (self->m_useDBus) { |
734 | + self->registerObject(); |
735 | + } |
736 | |
737 | - self->m_eventLoop->quit(); |
738 | - self->m_eventLoop = 0; |
739 | + self->m_isReady = true; |
740 | + Q_EMIT self->ready(); |
741 | } |
742 | |
743 | void DummyBackendProxy::individualAggregatorAddedPersona(FolksIndividualAggregator *fia, |
744 | |
745 | === modified file 'tests/unittest/dummy-backend.h' |
746 | --- tests/unittest/dummy-backend.h 2014-02-11 17:58:56 +0000 |
747 | +++ tests/unittest/dummy-backend.h 2014-03-18 17:29:45 +0000 |
748 | @@ -74,13 +74,14 @@ |
749 | int m_individualsChangedDetailedId; |
750 | QHash<QString, galera::QIndividual*> m_contacts; |
751 | bool m_contactUpdated; |
752 | + bool m_useDBus; |
753 | |
754 | bool registerObject(); |
755 | void initFolks(); |
756 | void configurePrimaryStore(); |
757 | void initEnviroment(); |
758 | void prepareAggregator(); |
759 | - static void mkpath(const QString &path); |
760 | + void mkpath(const QString &path) const; |
761 | static void checkError(GError *error); |
762 | static void backendEnabled(FolksBackendStore *backendStore, |
763 | GAsyncResult *res, |
764 | |
765 | === modified file 'tests/unittest/service-life-cycle-test.cpp' |
766 | --- tests/unittest/service-life-cycle-test.cpp 2013-11-06 15:15:39 +0000 |
767 | +++ tests/unittest/service-life-cycle-test.cpp 2014-03-18 17:29:45 +0000 |
768 | @@ -31,8 +31,8 @@ |
769 | |
770 | void testServiceReady() |
771 | { |
772 | - QCOMPARE(m_serverIface->property("isReady").toBool(), true); |
773 | - QCOMPARE(m_dummyIface->property("isReady").toBool(), true); |
774 | + QTRY_COMPARE(m_serverIface->property("isReady").toBool(), true); |
775 | + QTRY_COMPARE(m_dummyIface->property("isReady").toBool(), true); |
776 | } |
777 | |
778 | void testCallServiceFunction() |
779 | @@ -44,6 +44,7 @@ |
780 | QCOMPARE(result.value(), true); |
781 | } |
782 | |
783 | + |
784 | void testServiceShutdown() |
785 | { |
786 | m_dummyIface->call("quit"); |
PASSED: Continuous integration, rev:99 jenkins. qa.ubuntu. com/job/ address- book-service- ci/152/ jenkins. qa.ubuntu. com/job/ address- book-service- trusty- amd64-ci/ 59 jenkins. qa.ubuntu. com/job/ address- book-service- trusty- armhf-ci/ 59 jenkins. qa.ubuntu. com/job/ address- book-service- trusty- armhf-ci/ 59/artifact/ work/output/ *zip*/output. zip jenkins. qa.ubuntu. com/job/ address- book-service- trusty- i386-ci/ 60
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/address- book-service- ci/152/ rebuild
http://