1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Copyright (C) 2016 Intel Corporation.
5** Contact: https://www.qt.io/licensing/
6**
7** This file is part of the test suite of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:GPL-EXCEPT$
10** Commercial License Usage
11** Licensees holding valid commercial Qt licenses may use this file in
12** accordance with the commercial license agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and The Qt Company. For licensing terms
15** and conditions see https://www.qt.io/terms-conditions. For further
16** information use the contact form at https://www.qt.io/contact-us.
17**
18** GNU General Public License Usage
19** Alternatively, this file may be used under the terms of the GNU
20** General Public License version 3 as published by the Free Software
21** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
22** included in the packaging of this file. Please review the following
23** information to ensure the GNU General Public License requirements will
24** be met: https://www.gnu.org/licenses/gpl-3.0.html.
25**
26** $QT_END_LICENSE$
27**
28****************************************************************************/
29
30#include <QtDBus/QDBusServiceWatcher>
31#include <QtDBus>
32#include <QtTest>
33
34class tst_QDBusServiceWatcher: public QObject
35{
36 Q_OBJECT
37 int testCounter;
38public:
39 tst_QDBusServiceWatcher();
40
41private slots:
42 void initTestCase();
43 void watchForCreation_data();
44 void watchForCreation();
45 void watchForDisappearance_data();
46 void watchForDisappearance();
47 void watchForDisappearanceUniqueConnection();
48 void watchForOwnerChange_data();
49 void watchForOwnerChange();
50 void modeChange_data();
51 void modeChange();
52 void disconnectedConnection();
53 void setConnection_data();
54 void setConnection();
55
56private:
57 QString generateServiceName();
58};
59
60tst_QDBusServiceWatcher::tst_QDBusServiceWatcher()
61 : testCounter(0)
62{
63}
64
65void tst_QDBusServiceWatcher::initTestCase()
66{
67 QDBusConnection con = QDBusConnection::sessionBus();
68 QVERIFY(con.isConnected());
69}
70
71QString tst_QDBusServiceWatcher::generateServiceName() {
72 return "com.example.TestService" + QString::number(testCounter++);
73}
74
75void tst_QDBusServiceWatcher::watchForCreation_data()
76{
77 QTest::addColumn<QString>(name: "watchedName");
78 QTest::addColumn<QString>(name: "registeredName");
79
80 //com.example.TestService5 matches com.example.TestService5
81 QString name = generateServiceName();
82 QTest::newRow(dataTag: "normal") << name << name;
83
84 //com.example* matches com.example.TestService5
85 name = generateServiceName();
86 QTest::newRow(dataTag: "wildcard") << "com.example*" << name;
87
88 //com.example.TestService5* matches com.example.TestService5
89 name = generateServiceName();
90 QTest::newRow(dataTag: "wildcard_exact") << name+"*" << name;
91
92 //com.example.TestService5* matches com.example.TestService5.Foo
93 name = generateServiceName();
94 QTest::newRow(dataTag: "wildcard_subdomain") << name+"*" << name + ".Foo";
95
96 //com.example.TestService5* matches com.example.TestService5.Foo.Bar
97 name = generateServiceName();
98 QTest::newRow(dataTag: "wildcard_subsubdomain") << name+"*" << name + ".Foo.Bar";
99}
100
101void tst_QDBusServiceWatcher::watchForCreation()
102{
103 QFETCH(QString, watchedName);
104 QFETCH(QString, registeredName);
105
106 QDBusConnection con = QDBusConnection::sessionBus();
107 QVERIFY(con.isConnected());
108
109 QDBusServiceWatcher watcher(watchedName, con, QDBusServiceWatcher::WatchForRegistration);
110
111 QSignalSpy spyR(&watcher, SIGNAL(serviceRegistered(QString)));
112 QSignalSpy spyU(&watcher, SIGNAL(serviceUnregistered(QString)));
113 QSignalSpy spyO(&watcher, SIGNAL(serviceOwnerChanged(QString,QString,QString)));
114 QTestEventLoop::instance().connect(asender: &watcher, SIGNAL(serviceRegistered(QString)), SLOT(exitLoop()));
115
116 // register a name
117 QVERIFY(con.registerService(registeredName));
118
119 QTestEventLoop::instance().enterLoop(secs: 1);
120 QVERIFY(!QTestEventLoop::instance().timeout());
121
122 QCOMPARE(spyR.count(), 1);
123 QCOMPARE(spyR.at(0).at(0).toString(), registeredName);
124
125 QCOMPARE(spyU.count(), 0);
126
127 QCOMPARE(spyO.count(), 1);
128 QCOMPARE(spyO.at(0).at(0).toString(), registeredName);
129 QVERIFY(spyO.at(0).at(1).toString().isEmpty());
130 QCOMPARE(spyO.at(0).at(2).toString(), con.baseService());
131
132 spyR.clear();
133 spyU.clear();
134 spyO.clear();
135
136 // unregister it:
137 con.unregisterService(serviceName: registeredName);
138
139 // and register again
140 QVERIFY(con.registerService(registeredName));
141
142 QTestEventLoop::instance().enterLoop(secs: 1);
143 QVERIFY(!QTestEventLoop::instance().timeout());
144
145 QCOMPARE(spyR.count(), 1);
146 QCOMPARE(spyR.at(0).at(0).toString(), registeredName);
147
148 QCOMPARE(spyU.count(), 0);
149
150 QCOMPARE(spyO.count(), 1);
151 QCOMPARE(spyO.at(0).at(0).toString(), registeredName);
152 QVERIFY(spyO.at(0).at(1).toString().isEmpty());
153 QCOMPARE(spyO.at(0).at(2).toString(), con.baseService());
154}
155
156void tst_QDBusServiceWatcher::watchForDisappearance_data()
157{
158 tst_QDBusServiceWatcher::watchForCreation_data();
159}
160
161void tst_QDBusServiceWatcher::watchForDisappearance()
162{
163 QFETCH(QString, watchedName);
164 QFETCH(QString, registeredName);
165
166 QDBusConnection con = QDBusConnection::sessionBus();
167 QVERIFY(con.isConnected());
168
169 QDBusServiceWatcher watcher(watchedName, con, QDBusServiceWatcher::WatchForUnregistration);
170 watcher.setObjectName("watcher for disappearance");
171
172 QSignalSpy spyR(&watcher, SIGNAL(serviceRegistered(QString)));
173 QSignalSpy spyU(&watcher, SIGNAL(serviceUnregistered(QString)));
174 QSignalSpy spyO(&watcher, SIGNAL(serviceOwnerChanged(QString,QString,QString)));
175 QTestEventLoop::instance().connect(asender: &watcher, SIGNAL(serviceUnregistered(QString)), SLOT(exitLoop()));
176
177 // register a name
178 QVERIFY(con.registerService(registeredName));
179
180 // unregister it:
181 con.unregisterService(serviceName: registeredName);
182
183 QTestEventLoop::instance().enterLoop(secs: 1);
184 QVERIFY(!QTestEventLoop::instance().timeout());
185
186 QCOMPARE(spyR.count(), 0);
187
188 QCOMPARE(spyU.count(), 1);
189 QCOMPARE(spyU.at(0).at(0).toString(), registeredName);
190
191 QCOMPARE(spyO.count(), 1);
192 QCOMPARE(spyO.at(0).at(0).toString(), registeredName);
193 QCOMPARE(spyO.at(0).at(1).toString(), con.baseService());
194 QVERIFY(spyO.at(0).at(2).toString().isEmpty());
195}
196
197void tst_QDBusServiceWatcher::watchForDisappearanceUniqueConnection()
198{
199 QDBusConnection con = QDBusConnection::sessionBus();
200 QVERIFY(con.isConnected());
201
202 // second connection
203 QString watchedName = QDBusConnection::connectToBus(type: QDBusConnection::SessionBus, name: "session2").baseService();
204 QVERIFY(!watchedName.isEmpty());
205
206 QDBusServiceWatcher watcher(watchedName, con, QDBusServiceWatcher::WatchForUnregistration);
207 watcher.setObjectName("watcher for disappearance");
208
209 QSignalSpy spyR(&watcher, SIGNAL(serviceRegistered(QString)));
210 QSignalSpy spyU(&watcher, SIGNAL(serviceUnregistered(QString)));
211 QSignalSpy spyO(&watcher, SIGNAL(serviceOwnerChanged(QString,QString,QString)));
212 QTestEventLoop::instance().connect(asender: &watcher, SIGNAL(serviceUnregistered(QString)), SLOT(exitLoop()));
213
214 // unregister it:
215 QDBusConnection::disconnectFromBus(name: "session2");
216
217 QTestEventLoop::instance().enterLoop(secs: 1);
218 QVERIFY(!QTestEventLoop::instance().timeout());
219
220 QCOMPARE(spyR.count(), 0);
221
222 QCOMPARE(spyU.count(), 1);
223 QCOMPARE(spyU.at(0).at(0).toString(), watchedName);
224
225 QCOMPARE(spyO.count(), 1);
226 QCOMPARE(spyO.at(0).at(0).toString(), watchedName);
227 QCOMPARE(spyO.at(0).at(1).toString(), watchedName);
228 QVERIFY(spyO.at(0).at(2).toString().isEmpty());
229}
230
231void tst_QDBusServiceWatcher::watchForOwnerChange_data()
232{
233 watchForCreation_data();
234}
235
236void tst_QDBusServiceWatcher::watchForOwnerChange()
237{
238 QFETCH(QString, watchedName);
239 QFETCH(QString, registeredName);
240
241 QDBusConnection con = QDBusConnection::sessionBus();
242 QVERIFY(con.isConnected());
243
244 QDBusServiceWatcher watcher(watchedName, con, QDBusServiceWatcher::WatchForOwnerChange);
245
246 QSignalSpy spyR(&watcher, SIGNAL(serviceRegistered(QString)));
247 QSignalSpy spyU(&watcher, SIGNAL(serviceUnregistered(QString)));
248 QSignalSpy spyO(&watcher, SIGNAL(serviceOwnerChanged(QString,QString,QString)));
249 QTestEventLoop::instance().connect(asender: &watcher, SIGNAL(serviceRegistered(QString)), SLOT(exitLoop()));
250
251 // register a name
252 QVERIFY(con.registerService(registeredName));
253
254 QTestEventLoop::instance().enterLoop(secs: 1);
255 QVERIFY(!QTestEventLoop::instance().timeout());
256
257 QCOMPARE(spyR.count(), 1);
258 QCOMPARE(spyR.at(0).at(0).toString(), registeredName);
259
260 QCOMPARE(spyU.count(), 0);
261
262 QCOMPARE(spyO.count(), 1);
263 QCOMPARE(spyO.at(0).at(0).toString(), registeredName);
264 QVERIFY(spyO.at(0).at(1).toString().isEmpty());
265 QCOMPARE(spyO.at(0).at(2).toString(), con.baseService());
266
267 spyR.clear();
268 spyU.clear();
269 spyO.clear();
270
271 // unregister it:
272 con.unregisterService(serviceName: registeredName);
273
274 // and register again
275 QVERIFY(con.registerService(registeredName));
276
277 QTestEventLoop::instance().enterLoop(secs: 1);
278 QVERIFY(!QTestEventLoop::instance().timeout());
279
280 QCOMPARE(spyR.count(), 1);
281 QCOMPARE(spyR.at(0).at(0).toString(), registeredName);
282
283 QCOMPARE(spyU.count(), 1);
284 QCOMPARE(spyU.at(0).at(0).toString(), registeredName);
285
286 QCOMPARE(spyO.count(), 2);
287 QCOMPARE(spyO.at(0).at(0).toString(), registeredName);
288 QCOMPARE(spyO.at(0).at(1).toString(), con.baseService());
289 QVERIFY(spyO.at(0).at(2).toString().isEmpty());
290 QCOMPARE(spyO.at(1).at(0).toString(), registeredName);
291 QVERIFY(spyO.at(1).at(1).toString().isEmpty());
292 QCOMPARE(spyO.at(1).at(2).toString(), con.baseService());
293}
294
295void tst_QDBusServiceWatcher::modeChange_data()
296{
297 watchForCreation_data();
298}
299
300void tst_QDBusServiceWatcher::modeChange()
301{
302 QFETCH(QString, watchedName);
303 QFETCH(QString, registeredName);
304
305 QDBusConnection con = QDBusConnection::sessionBus();
306 QVERIFY(con.isConnected());
307
308 QDBusServiceWatcher watcher(watchedName, con, QDBusServiceWatcher::WatchForRegistration);
309
310 QSignalSpy spyR(&watcher, SIGNAL(serviceRegistered(QString)));
311 QSignalSpy spyU(&watcher, SIGNAL(serviceUnregistered(QString)));
312 QSignalSpy spyO(&watcher, SIGNAL(serviceOwnerChanged(QString,QString,QString)));
313 QTestEventLoop::instance().connect(asender: &watcher, SIGNAL(serviceRegistered(QString)), SLOT(exitLoop()));
314
315 // register a name
316 QVERIFY(con.registerService(registeredName));
317
318 QTestEventLoop::instance().enterLoop(secs: 1);
319 QVERIFY(!QTestEventLoop::instance().timeout());
320
321 QCOMPARE(spyR.count(), 1);
322 QCOMPARE(spyR.at(0).at(0).toString(), registeredName);
323
324 QCOMPARE(spyU.count(), 0);
325
326 QCOMPARE(spyO.count(), 1);
327 QCOMPARE(spyO.at(0).at(0).toString(), registeredName);
328 QVERIFY(spyO.at(0).at(1).toString().isEmpty());
329 QCOMPARE(spyO.at(0).at(2).toString(), con.baseService());
330
331 spyR.clear();
332 spyU.clear();
333 spyO.clear();
334
335 watcher.setWatchMode(QDBusServiceWatcher::WatchForUnregistration);
336
337 // unregister it:
338 con.unregisterService(serviceName: registeredName);
339
340 QTestEventLoop::instance().connect(asender: &watcher, SIGNAL(serviceUnregistered(QString)), SLOT(exitLoop()));
341 QTestEventLoop::instance().enterLoop(secs: 1);
342 QVERIFY(!QTestEventLoop::instance().timeout());
343
344 QCOMPARE(spyR.count(), 0);
345
346 QCOMPARE(spyU.count(), 1);
347 QCOMPARE(spyU.at(0).at(0).toString(), registeredName);
348
349 QCOMPARE(spyO.count(), 1);
350 QCOMPARE(spyO.at(0).at(0).toString(), registeredName);
351 QCOMPARE(spyO.at(0).at(1).toString(), con.baseService());
352 QVERIFY(spyO.at(0).at(2).toString().isEmpty());
353}
354
355void tst_QDBusServiceWatcher::disconnectedConnection()
356{
357 QDBusConnection con("");
358 QVERIFY(!con.isConnected());
359
360 QDBusServiceWatcher watcher(generateServiceName(), con, QDBusServiceWatcher::WatchForRegistration);
361 watcher.addWatchedService(newService: "com.example.somethingelse");
362 watcher.addWatchedService(newService: "org.freedesktop.DBus");
363
364 watcher.setWatchMode(QDBusServiceWatcher::WatchForUnregistration);
365 watcher.setWatchMode(QDBusServiceWatcher::WatchForOwnerChange);
366
367 watcher.setWatchedServices(QStringList());
368}
369
370void tst_QDBusServiceWatcher::setConnection_data()
371{
372 QTest::addColumn<QString>(name: "serviceName");
373 QTest::newRow(dataTag: "normal") << generateServiceName();
374}
375
376void tst_QDBusServiceWatcher::setConnection()
377{
378 QFETCH(QString, serviceName);
379 // begin with a disconnected connection
380 QDBusConnection con("");
381 QVERIFY(!con.isConnected());
382
383 QDBusServiceWatcher watcher(serviceName, con, QDBusServiceWatcher::WatchForRegistration);
384
385 QSignalSpy spyR(&watcher, SIGNAL(serviceRegistered(QString)));
386 QSignalSpy spyU(&watcher, SIGNAL(serviceUnregistered(QString)));
387 QTestEventLoop::instance().connect(asender: &watcher, SIGNAL(serviceOwnerChanged(QString,QString,QString)), SLOT(exitLoop()));
388
389 // move to the session bus
390 con = QDBusConnection::sessionBus();
391 QVERIFY(con.isConnected());
392 watcher.setConnection(con);
393
394 // register a name
395 QVERIFY(con.registerService(serviceName));
396
397 QTestEventLoop::instance().enterLoop(secs: 1);
398 QVERIFY(!QTestEventLoop::instance().timeout());
399
400 QCOMPARE(spyR.count(), 1);
401 QCOMPARE(spyR.at(0).at(0).toString(), serviceName);
402 QCOMPARE(spyU.count(), 0);
403
404 // is the system bus available?
405 if (!QDBusConnection::systemBus().isConnected())
406 return;
407
408 // connect to the system bus and ask to watch that base service
409 QString watchedName = QDBusConnection::connectToBus(type: QDBusConnection::SystemBus, name: "system2").baseService();
410 watcher.setWatchedServices(QStringList() << watchedName);
411 watcher.setWatchMode(QDBusServiceWatcher::WatchForUnregistration);
412
413 // move to the system bus
414 watcher.setConnection(QDBusConnection::systemBus());
415 spyR.clear();
416 spyU.clear();
417
418 QDBusConnection::disconnectFromBus(name: "system2");
419
420 QTestEventLoop::instance().enterLoop(secs: 1);
421 QVERIFY(!QTestEventLoop::instance().timeout());
422
423 QCOMPARE(spyR.count(), 0);
424
425 QCOMPARE(spyU.count(), 1);
426 QCOMPARE(spyU.at(0).at(0).toString(), watchedName);
427}
428
429QTEST_MAIN(tst_QDBusServiceWatcher)
430#include "tst_qdbusservicewatcher.moc"
431

source code of qtbase/tests/auto/dbus/qdbusservicewatcher/tst_qdbusservicewatcher.cpp