QtBase  v6.3.1
tst_qdbusconnection.cpp
Go to the documentation of this file.
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 "tst_qdbusconnection.h"
31 
32 #include <QTest>
33 #include <QDebug>
34 #include <QProcess>
35 #include <QCoreApplication>
36 #include <QDBusConnection>
37 #include <QDBusReply>
38 #include <QDBusInterface>
39 #include <QDBusConnectionInterface>
40 
41 #ifdef Q_OS_UNIX
42 # include <sys/types.h>
43 # include <signal.h>
44 #endif
45 
47 {
48  path = msg.path();
49  ++callCount;
50  //qDebug() << msg;
51 }
52 
54 {
55  path = msg.path();
56  interface = msg.interface();
57  ++callCount;
58  //qDebug() << msg;
59 }
60 
63 {
64 #ifdef HAS_HOOKSETUPFUNCTION
65 # define QCOMPARE_HOOKCOUNT(n) QCOMPARE(hookCallCount, n); hookCallCount = 0
66 # define QVERIFY_HOOKCALLED() QCOMPARE(hookCallCount, 1); hookCallCount = 0
67  hookSetupFunction();
68 #else
69 # define QCOMPARE_HOOKCOUNT(n) qt_noop()
70 # define QVERIFY_HOOKCALLED() qt_noop()
71 #endif
72 }
73 
74 // called before each testcase
76 {
77  hookCallCount = 0;
78 }
79 
81 {
82  QVERIFY2(!hookCallCount, "Unchecked call");
83 }
84 
85 
86 void tst_QDBusConnection::noConnection()
87 {
88  QDBusConnection con = QDBusConnection::connectToBus("unix:path=/dev/null", "testconnection");
89  QVERIFY(!con.isConnected());
90 
91  // try sending a message. This should fail
92  QDBusMessage msg = QDBusMessage::createMethodCall("org.kde.selftest", "/org/kde/selftest",
93  "org.kde.selftest", "Ping");
94  msg << QLatin1String("ping");
95 
96  QVERIFY(!con.send(msg));
97 
98  QDBusSpy spy;
99  QVERIFY(con.callWithCallback(msg, &spy, SLOT(asyncReply)) == 0);
100 
101  QDBusMessage reply = con.call(msg);
103 
104  QDBusReply<void> voidreply(reply);
105  QVERIFY(!voidreply.isValid());
106 
107  QDBusConnection::disconnectFromBus("testconnection");
108 }
109 
110 void tst_QDBusConnection::sendSignal()
111 {
113 
114  QVERIFY(con.isConnected());
115 
116  QDBusMessage msg = QDBusMessage::createSignal("/org/kde/selftest", "org.kde.selftest",
117  "Ping");
118  msg << QLatin1String("ping");
119 
120  QVERIFY(con.send(msg));
121 }
122 
123 void tst_QDBusConnection::sendSignalToName()
124 {
126  QSKIP("Test requires a QCoreApplication"); // because of the qWait()
127 
128  QDBusSpy spy;
129 
131 
132  con.connect(con.baseService(), "/org/kde/selftest", "org.kde.selftest", "ping", &spy,
133  SLOT(handlePing(QString)));
134 
135  QDBusMessage msg =
136  QDBusMessage::createTargetedSignal(con.baseService(), "/org/kde/selftest",
137  "org.kde.selftest", "ping");
138  msg << QLatin1String("ping");
139 
140  QVERIFY(con.send(msg));
141 
142  QTRY_COMPARE(spy.args.count(), 1);
143  QCOMPARE(spy.args.at(0).toString(), QString("ping"));
144 }
145 
146 void tst_QDBusConnection::sendSignalToOtherName()
147 {
149  QSKIP("Test requires a QCoreApplication"); // because of the qWait()
150 
151  QDBusSpy spy;
152 
154 
155  con.connect(con.baseService(), "/org/kde/selftest", "org.kde.selftest", "ping", &spy,
156  SLOT(handlePing(QString)));
157 
158  QDBusMessage msg =
159  QDBusMessage::createTargetedSignal("some.other.service", "/org/kde/selftest",
160  "org.kde.selftest", "ping");
161  msg << QLatin1String("ping");
162 
163  QVERIFY(con.send(msg));
164 
165  QTest::qWait(1000);
166 
167  QCOMPARE(spy.args.count(), 0);
168 }
169 
170 void tst_QDBusConnection::send()
171 {
173 
174  QVERIFY(con.isConnected());
175 
176  QDBusMessage msg = QDBusMessage::createMethodCall("org.freedesktop.DBus",
177  "/org/freedesktop/DBus", "org.freedesktop.DBus", "ListNames");
178 
179  QDBusMessage reply = con.call(msg);
180 
181  QCOMPARE(reply.arguments().count(), 1);
182  QCOMPARE(reply.arguments().at(0).typeName(), "QStringList");
183  QVERIFY(reply.arguments().at(0).toStringList().contains(con.baseService()));
184 }
185 
186 void tst_QDBusConnection::sendWithGui()
187 {
189  QSKIP("Test requires a QCoreApplication");
190 
192 
193  QVERIFY(con.isConnected());
194 
195  QDBusMessage msg = QDBusMessage::createMethodCall("org.freedesktop.DBus",
196  "/org/freedesktop/DBus", "org.freedesktop.DBus", "ListNames");
197 
199 
200  QCOMPARE(reply.arguments().count(), 1);
201  QCOMPARE(reply.arguments().at(0).typeName(), "QStringList");
202  QVERIFY(reply.arguments().at(0).toStringList().contains(con.baseService()));
203 }
204 
205 void tst_QDBusConnection::sendAsync()
206 {
208  QSKIP("Test requires a QCoreApplication");
209 
211  QVERIFY(con.isConnected());
212 
213  QDBusSpy spy;
214 
215  QDBusMessage msg = QDBusMessage::createMethodCall("org.freedesktop.DBus",
216  "/org/freedesktop/DBus", "org.freedesktop.DBus", "ListNames");
217  QVERIFY(con.callWithCallback(msg, &spy, SLOT(asyncReply(QDBusMessage))));
218 
219  QTRY_COMPARE(spy.args.count(), 1);
220  QCOMPARE(spy.args.value(0).typeName(), "QStringList");
221  QVERIFY(spy.args.at(0).toStringList().contains(con.baseService()));
222 }
223 
224 void tst_QDBusConnection::connect()
225 {
226  QDBusSpy spy;
227 
229 
231  return; // cannot receive signals in this thread without QCoreApplication
232 
233  con.connect(con.baseService(), "/org/kde/selftest", "org.kde.selftest", "ping", &spy,
234  SLOT(handlePing(QString)));
235 
236  QDBusMessage msg = QDBusMessage::createSignal("/org/kde/selftest", "org.kde.selftest",
237  "ping");
238  msg << QLatin1String("ping");
239 
240  QVERIFY(con.send(msg));
241 
242  QTRY_COMPARE(spy.args.count(), 1);
243  QCOMPARE(spy.args.at(0).toString(), QString("ping"));
244 }
245 
246 void tst_QDBusConnection::connectToBus()
247 {
248  {
251 
252  QVERIFY(con.isConnected());
253  QVERIFY(!con.lastError().isValid());
254 
255  QDBusConnection con2("foo");
256  QVERIFY(!con2.isConnected());
257  QVERIFY(con2.lastError().isValid());
258 
259  con2 = con;
260  QVERIFY(con.isConnected());
261  QVERIFY(con2.isConnected());
262  QVERIFY(!con.lastError().isValid());
263  QVERIFY(!con2.lastError().isValid());
264  }
265 
266  {
267  QDBusConnection con("bubu");
268  QVERIFY(con.isConnected());
269  QVERIFY(!con.lastError().isValid());
270  }
271 
273 
274  {
275  QDBusConnection con("bubu");
276  QVERIFY(con.isConnected());
277  QVERIFY(!con.lastError().isValid());
278  }
279 
281 
282  {
283  QDBusConnection con("bubu");
284  QVERIFY(!con.isConnected());
285  QVERIFY(con.lastError().isValid());
286  }
287 
288  QByteArray address = qgetenv("DBUS_SESSION_BUS_ADDRESS");
289  if (!address.isEmpty()) {
291  QVERIFY(con.isConnected());
292  QVERIFY(!con.lastError().isValid());
293 
295  }
296 }
297 
298 void tst_QDBusConnection::connectToPeer()
299 {
300  {
302  "", "newconn");
303  QVERIFY(!con.isConnected());
304  QVERIFY(con.lastError().isValid());
306  }
307 
309 
310  {
312  "unix:abstract=/tmp/dbus-XXXXXXXXXX,guid=00000000000000000000000000000000", "newconn2");
313  QVERIFY(!con.isConnected());
314  QVERIFY(con.lastError().isValid());
316  }
317 
318  {
320  server.address(), "bubu");
321 
322  QVERIFY(con.isConnected());
323  QVERIFY(!con.lastError().isValid());
324 
325  QDBusConnection con2("foo");
326  QVERIFY(!con2.isConnected());
327  QVERIFY(con2.lastError().isValid());
328 
329  con2 = con;
330  QVERIFY(con.isConnected());
331  QVERIFY(con2.isConnected());
332  QVERIFY(!con.lastError().isValid());
333  QVERIFY(!con2.lastError().isValid());
334  }
335 
336  {
337  QDBusConnection con("bubu");
338  QVERIFY(con.isConnected());
339  QVERIFY(!con.lastError().isValid());
340  }
341 
343 
344  {
345  QDBusConnection con("bubu");
346  QVERIFY(con.isConnected());
347  QVERIFY(!con.lastError().isValid());
348  }
349 
351 
352  {
353  QDBusConnection con("bubu");
354  QVERIFY(!con.isConnected());
355  QVERIFY(con.lastError().isValid());
356  }
357 }
358 
359 void tst_QDBusConnection::registerObject_data()
360 {
361  QTest::addColumn<QString>("path");
362 
363  QTest::newRow("/") << "/";
364  QTest::newRow("/p1") << "/p1";
365  QTest::newRow("/p2") << "/p2";
366  QTest::newRow("/p1/q") << "/p1/q";
367  QTest::newRow("/p1/q/r") << "/p1/q/r";
368 }
369 
370 void tst_QDBusConnection::registerObject()
371 {
372  QFETCH(QString, path);
373 
375  QVERIFY(con.isConnected());
376 
377  //QVERIFY(!callMethod(con, path));
378  {
379  // register one object at root:
380  MyObject obj;
381  QVERIFY(con.registerObject(path, &obj, QDBusConnection::ExportAllSlots));
382  QCOMPARE(con.objectRegisteredAt(path), static_cast<QObject *>(&obj));
384  QCOMPARE(obj.path, path);
386  }
387  // make sure it's gone
390 }
391 
392 void tst_QDBusConnection::registerObjectWithInterface_data()
393 {
394  QTest::addColumn<QString>("path");
395  QTest::addColumn<QString>("interface");
396 
397  QTest::newRow("/") << "/" << "org.foo";
398  QTest::newRow("/p1") << "/p1" << "org.foo";
399  QTest::newRow("/p2") << "/p2" << "org.foo";
400  QTest::newRow("/p1/q") << "/p1/q" << "org.foo";
401  QTest::newRow("/p1/q/r") << "/p1/q/r" << "org.foo";
402 
403 }
404 
405 void tst_QDBusConnection::registerObjectWithInterface()
406 {
407  QFETCH(QString, path);
409 
411  QVERIFY(con.isConnected());
412 
413  {
414  // register one object at root:
417  QCOMPARE(con.objectRegisteredAt(path), static_cast<QObject *>(&obj));
419  QCOMPARE(obj.path, path);
420  QCOMPARE(obj.interface, interface);
422  }
423  // make sure it's gone
426 }
427 
428 void tst_QDBusConnection::registerObjectPeer_data()
429 {
430  QTest::addColumn<QString>("path");
431 
432  QTest::newRow("/") << "/";
433  QTest::newRow("/p1") << "/p1";
434  QTest::newRow("/p2") << "/p2";
435  QTest::newRow("/p1/q") << "/p1/q";
436  QTest::newRow("/p1/q/r") << "/p1/q/r";
437 }
438 
439 void tst_QDBusConnection::registerObjectPeer()
440 {
442  QSKIP("Test requires a QCoreApplication");
443 
444  QFETCH(QString, path);
445 
447 
448  QDBusConnection::connectToPeer(server.address(), "beforeFoo");
451 
452  {
454 
457  QVERIFY(con.isConnected());
458 
459  MyObject obj;
461  QCOMPARE(obj.path, path);
463  }
464 
465  QDBusConnection::connectToPeer(server.address(), "afterFoo");
467 
468  {
469  QDBusConnection con("foo");
470  QVERIFY(con.isConnected());
473  }
474 
475  server.unregisterObject();
476 
477  {
478  QDBusConnection con("foo");
479  QVERIFY(con.isConnected());
482  }
483 
484  server.registerObject();
485 
486  {
487  QDBusConnection con("foo");
488  QVERIFY(con.isConnected());
491  }
492 
494 
495  {
496  QDBusConnection con("foo");
497  QVERIFY(!con.isConnected());
499  }
500 
503 }
504 
505 void tst_QDBusConnection::registerObject2()
506 {
508  QVERIFY(con.isConnected());
509 
510  // make sure nothing is using our paths:
511  QVERIFY(!callMethod(con, "/"));
513  QVERIFY(!callMethod(con, "/p1"));
515  QVERIFY(!callMethod(con, "/p2"));
517  QVERIFY(!callMethod(con, "/p1/q"));
519  QVERIFY(!callMethod(con, "/p1/q/r"));
521 
522  {
523  // register one object at root:
524  MyObject obj;
525  QVERIFY(con.registerObject("/", &obj, QDBusConnection::ExportAllSlots));
526  QVERIFY(callMethod(con, "/"));
527  QCOMPARE(obj.path, QString("/"));
529  }
530  // make sure it's gone
531  QVERIFY(!callMethod(con, "/"));
533 
534  {
535  // register one at an element:
536  MyObject obj;
537  QVERIFY(con.registerObject("/p1", &obj, QDBusConnection::ExportAllSlots));
538  QVERIFY(!callMethod(con, "/"));
540  QVERIFY(callMethod(con, "/p1"));
541  QCOMPARE(obj.path, QString("/p1"));
543 
544  // re-register it somewhere else
545  QVERIFY(con.registerObject("/p2", &obj, QDBusConnection::ExportAllSlots));
546  QVERIFY(callMethod(con, "/p1"));
547  QCOMPARE(obj.path, QString("/p1"));
549  QVERIFY(callMethod(con, "/p2"));
550  QCOMPARE(obj.path, QString("/p2"));
552  }
553  // make sure it's gone
554  QVERIFY(!callMethod(con, "/p1"));
556  QVERIFY(!callMethod(con, "/p2"));
558 
559  {
560  // register at a deep path
561  MyObject obj;
562  QVERIFY(con.registerObject("/p1/q/r", &obj, QDBusConnection::ExportAllSlots));
563  QVERIFY(!callMethod(con, "/"));
565  QVERIFY(!callMethod(con, "/p1"));
567  QVERIFY(!callMethod(con, "/p1/q"));
569  QVERIFY(callMethod(con, "/p1/q/r"));
570  QCOMPARE(obj.path, QString("/p1/q/r"));
572  }
573 
574  // make sure it's gone
575  QVERIFY(!callMethod(con, "/p1/q/r"));
577 
578  {
579  MyObject obj;
580  QVERIFY(con.registerObject("/p1/q2", &obj, QDBusConnection::ExportAllSlots));
581  QVERIFY(callMethod(con, "/p1/q2"));
582  QCOMPARE(obj.path, QString("/p1/q2"));
584 
585  // try unregistering
586  con.unregisterObject("/p1/q2");
587  QVERIFY(!callMethod(con, "/p1/q2"));
589 
590  // register it again
591  QVERIFY(con.registerObject("/p1/q2", &obj, QDBusConnection::ExportAllSlots));
592  QVERIFY(callMethod(con, "/p1/q2"));
593  QCOMPARE(obj.path, QString("/p1/q2"));
595 
596  // now try removing things around it:
597  con.unregisterObject("/p2");
598  QVERIFY(callMethod(con, "/p1/q2")); // unrelated object shouldn't affect
600 
601  con.unregisterObject("/p1");
602  QVERIFY(callMethod(con, "/p1/q2")); // unregistering just the parent shouldn't affect it
604 
605  con.unregisterObject("/p1/q2/r");
606  QVERIFY(callMethod(con, "/p1/q2")); // unregistering non-existing child shouldn't affect it either
608 
609  con.unregisterObject("/p1/q");
610  QVERIFY(callMethod(con, "/p1/q2")); // unregistering sibling (before) shouldn't affect
612 
613  con.unregisterObject("/p1/r");
614  QVERIFY(callMethod(con, "/p1/q2")); // unregistering sibling (after) shouldn't affect
616 
617  // now remove it:
618  con.unregisterObject("/p1", QDBusConnection::UnregisterTree);
619  QVERIFY(!callMethod(con, "/p1/q2")); // we removed the full tree
621  }
622 }
623 
624 void tst_QDBusConnection::registerObjectPeer2()
625 {
627  QSKIP("Test requires a QCoreApplication");
628 
633  QVERIFY(con.isConnected());
634 
635  QDBusConnection srv_con = server.connection();
636 
637  // make sure nothing is using our paths:
638  QVERIFY(!callMethodPeer(srv_con, "/"));
640  QVERIFY(!callMethodPeer(srv_con, "/p1"));
642  QVERIFY(!callMethodPeer(srv_con, "/p2"));
644  QVERIFY(!callMethodPeer(srv_con, "/p1/q"));
646  QVERIFY(!callMethodPeer(srv_con, "/p1/q/r"));
648 
649  {
650  // register one object at root:
651  MyObject obj;
652  QVERIFY(con.registerObject("/", &obj, QDBusConnection::ExportAllSlots));
653  QVERIFY(callMethodPeer(srv_con, "/"));
654  QCOMPARE(obj.path, QString("/"));
656  }
657 
658  // make sure it's gone
659  QVERIFY(!callMethodPeer(srv_con, "/"));
661 
662  {
663  // register one at an element:
664  MyObject obj;
665  QVERIFY(con.registerObject("/p1", &obj, QDBusConnection::ExportAllSlots));
666  QVERIFY(!callMethodPeer(srv_con, "/"));
668  QVERIFY(callMethodPeer(srv_con, "/p1"));
669  QCOMPARE(obj.path, QString("/p1"));
671 
672  // re-register it somewhere else
673  QVERIFY(con.registerObject("/p2", &obj, QDBusConnection::ExportAllSlots));
674  QVERIFY(callMethodPeer(srv_con, "/p1"));
675  QCOMPARE(obj.path, QString("/p1"));
677  QVERIFY(callMethodPeer(srv_con, "/p2"));
678  QCOMPARE(obj.path, QString("/p2"));
680  }
681 
682  // make sure it's gone
683  QVERIFY(!callMethodPeer(srv_con, "/p1"));
685  QVERIFY(!callMethodPeer(srv_con, "/p2"));
687 
688  {
689  // register at a deep path
690  MyObject obj;
691  QVERIFY(con.registerObject("/p1/q/r", &obj, QDBusConnection::ExportAllSlots));
692  QVERIFY(!callMethodPeer(srv_con, "/"));
694  QVERIFY(!callMethodPeer(srv_con, "/p1"));
696  QVERIFY(!callMethodPeer(srv_con, "/p1/q"));
698  QVERIFY(callMethodPeer(srv_con, "/p1/q/r"));
699  QCOMPARE(obj.path, QString("/p1/q/r"));
701  }
702 
703  // make sure it's gone
704  QVERIFY(!callMethodPeer(srv_con, "/p1/q/r"));
706 
707  {
708  MyObject obj;
709  QVERIFY(con.registerObject("/p1/q2", &obj, QDBusConnection::ExportAllSlots));
710  QVERIFY(callMethodPeer(srv_con, "/p1/q2"));
711  QCOMPARE(obj.path, QString("/p1/q2"));
713 
714  // try unregistering
715  con.unregisterObject("/p1/q2");
716  QVERIFY(!callMethodPeer(srv_con, "/p1/q2"));
718 
719  // register it again
720  QVERIFY(con.registerObject("/p1/q2", &obj, QDBusConnection::ExportAllSlots));
721  QVERIFY(callMethodPeer(srv_con, "/p1/q2"));
722  QCOMPARE(obj.path, QString("/p1/q2"));
724 
725  // now try removing things around it:
726  con.unregisterObject("/p2");
727  QVERIFY(callMethodPeer(srv_con, "/p1/q2")); // unrelated object shouldn't affect
729 
730  con.unregisterObject("/p1");
731  QVERIFY(callMethodPeer(srv_con, "/p1/q2")); // unregistering just the parent shouldn't affect it
733 
734  con.unregisterObject("/p1/q2/r");
735  QVERIFY(callMethodPeer(srv_con, "/p1/q2")); // unregistering non-existing child shouldn't affect it either
737 
738  con.unregisterObject("/p1/q");
739  QVERIFY(callMethodPeer(srv_con, "/p1/q2")); // unregistering sibling (before) shouldn't affect
741 
742  con.unregisterObject("/p1/r");
743  QVERIFY(callMethodPeer(srv_con, "/p1/q2")); // unregistering sibling (after) shouldn't affect
745 
746  // now remove it:
747  con.unregisterObject("/p1", QDBusConnection::UnregisterTree);
748  QVERIFY(!callMethodPeer(srv_con, "/p1/q2")); // we removed the full tree
750  }
751 
753 }
754 
755 
756 void tst_QDBusConnection::registerQObjectChildren()
757 {
758  // make sure no one is there
760  QVERIFY(!callMethod(con, "/p1"));
762 
763  {
764  MyObject obj, *a, *b, *c, *cc;
765 
766  a = new MyObject(&obj);
767  a->setObjectName("a");
768 
769  b = new MyObject(&obj);
770  b->setObjectName("b");
771 
772  c = new MyObject(&obj);
773  c->setObjectName("c");
774 
775  cc = new MyObject(c);
776  cc->setObjectName("cc");
777 
778  con.registerObject("/p1", &obj, QDBusConnection::ExportAllSlots |
780 
781  // make calls
782  QVERIFY(callMethod(con, "/p1"));
783  QCOMPARE(obj.callCount, 1);
785  QVERIFY(callMethod(con, "/p1/a"));
786  QCOMPARE(a->callCount, 1);
788  QVERIFY(callMethod(con, "/p1/b"));
789  QCOMPARE(b->callCount, 1);
791  QVERIFY(callMethod(con, "/p1/c"));
792  QCOMPARE(c->callCount, 1);
794  QVERIFY(callMethod(con, "/p1/c/cc"));
795  QCOMPARE(cc->callCount, 1);
797 
798  QVERIFY(!callMethod(con, "/p1/d"));
800  QVERIFY(!callMethod(con, "/p1/c/abc"));
802 
803  // pull an object, see if it goes away:
804  delete b;
805  QVERIFY(!callMethod(con, "/p1/b"));
807 
808  delete c;
809  QVERIFY(!callMethod(con, "/p1/c"));
811  QVERIFY(!callMethod(con, "/p1/c/cc"));
813  }
814 
815  QVERIFY(!callMethod(con, "/p1"));
817  QVERIFY(!callMethod(con, "/p1/a"));
819  QVERIFY(!callMethod(con, "/p1/b"));
821  QVERIFY(!callMethod(con, "/p1/c"));
823  QVERIFY(!callMethod(con, "/p1/c/cc"));
825 }
826 
827 void tst_QDBusConnection::registerQObjectChildrenPeer()
828 {
830  QSKIP("Test requires a QCoreApplication");
831 
837  QVERIFY(con.isConnected());
838 
839  QDBusConnection srv_con = server.connection();
840 
841  QVERIFY(!callMethodPeer(srv_con, "/p1"));
843 
844  {
845  MyObject obj, *a, *b, *c, *cc;
846 
847  a = new MyObject(&obj);
848  a->setObjectName("a");
849 
850  b = new MyObject(&obj);
851  b->setObjectName("b");
852 
853  c = new MyObject(&obj);
854  c->setObjectName("c");
855 
856  cc = new MyObject(c);
857  cc->setObjectName("cc");
858 
859  con.registerObject("/p1", &obj, QDBusConnection::ExportAllSlots |
861 
862  // make calls
863  QVERIFY(callMethodPeer(srv_con, "/p1"));
864  QCOMPARE(obj.callCount, 1);
866  QVERIFY(callMethodPeer(srv_con, "/p1/a"));
867  QCOMPARE(a->callCount, 1);
869  QVERIFY(callMethodPeer(srv_con, "/p1/b"));
870  QCOMPARE(b->callCount, 1);
872  QVERIFY(callMethodPeer(srv_con, "/p1/c"));
873  QCOMPARE(c->callCount, 1);
875  QVERIFY(callMethodPeer(srv_con, "/p1/c/cc"));
876  QCOMPARE(cc->callCount, 1);
878 
879  QVERIFY(!callMethodPeer(srv_con, "/p1/d"));
881  QVERIFY(!callMethodPeer(srv_con, "/p1/c/abc"));
883 
884  // pull an object, see if it goes away:
885  delete b;
886  QVERIFY(!callMethodPeer(srv_con, "/p1/b"));
888 
889  delete c;
890  QVERIFY(!callMethodPeer(srv_con, "/p1/c"));
892  QVERIFY(!callMethodPeer(srv_con, "/p1/c/cc"));
894  }
895 
896  QVERIFY(!callMethodPeer(srv_con, "/p1"));
898  QVERIFY(!callMethodPeer(srv_con, "/p1/a"));
900  QVERIFY(!callMethodPeer(srv_con, "/p1/b"));
902  QVERIFY(!callMethodPeer(srv_con, "/p1/c"));
904  QVERIFY(!callMethodPeer(srv_con, "/p1/c/cc"));
906 
908 }
909 
911 {
913  QDBusMessage reply = conn.call(msg, QDBus::Block/*WithGui*/);
914  if (reply.type() != QDBusMessage::ReplyMessage)
915  return false;
916  QTest::qCompare(MyObject::path, path, "MyObject::path", "path", __FILE__, __LINE__);
917  return (MyObject::path == path);
918 }
919 
921 {
923  QDBusMessage reply = conn.call(msg, QDBus::Block/*WithGui*/);
924  if (reply.type() != QDBusMessage::ReplyMessage)
925  return false;
926  QTest::qCompare(MyObjectWithoutInterface::path, path, "MyObjectWithoutInterface::path", "path", __FILE__, __LINE__);
928 }
929 
931 {
934 
935  if (reply.type() != QDBusMessage::ReplyMessage)
936  return false;
937  QTest::qCompare(MyObject::path, path, "MyObject::path", "path", __FILE__, __LINE__);
938  return (MyObject::path == path);
939 }
940 
941 void tst_QDBusConnection::callSelf()
942 {
945  QVERIFY(connection.registerObject("/test", &testObject,
947  QCOMPARE(connection.objectRegisteredAt("/test"), static_cast<QObject *>(&testObject));
948  QVERIFY(connection.registerService(serviceName()));
950  QVERIFY(interface.isValid());
952 
953  interface.call(QDBus::Block, "test0");
954  QCOMPARE(testObject.func, QString("test0"));
956  interface.call(QDBus::Block, "test1", 42);
957  QCOMPARE(testObject.func, QString("test1 42"));
959  QDBusMessage reply = interface.call(QDBus::Block, "test2");
960  QCOMPARE(testObject.func, QString("test2"));
961  QCOMPARE(reply.arguments().value(0).toInt(), 43);
963 
965  QString(), "test3");
966  msg << 44;
967  reply = connection.call(msg);
968  QCOMPARE(reply.arguments().value(0).toInt(), 45);
970 }
971 
972 void tst_QDBusConnection::callSelfByAnotherName_data()
973 {
974  QTest::addColumn<int>("registerMethod");
975  QTest::newRow("connection") << 0;
976  QTest::newRow("connection-interface") << 1;
977  QTest::newRow("direct") << 2;
978 }
979 
980 void tst_QDBusConnection::callSelfByAnotherName()
981 {
983  QSKIP("Test requires a QCoreApplication");
984 
985  static int counter = 0;
987 
989  QVERIFY(con.isConnected());
990 
992  QVERIFY(con.registerObject("/test", &testObject,
994  con.connect("org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus", "NameOwnerChanged",
995  QStringList() << sname << "",
996  QString(), &QTestEventLoop::instance(), SLOT(exitLoop()));
997 
998  // register the name
999  QFETCH(int, registerMethod);
1000  switch (registerMethod) {
1001  case 0:
1002  QVERIFY(con.registerService(sname));
1003  break;
1004 
1005  case 1:
1006  QCOMPARE(con.interface()->registerService(sname).value(), QDBusConnectionInterface::ServiceRegistered);
1007  break;
1008 
1009  case 2: {
1010  // flag is DBUS_NAME_FLAG_DO_NOT_QUEUE = 0x04
1011  // reply is DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER = 1
1012  QDBusReply<uint> reply = con.interface()->call("RequestName", sname, 4u);
1013  QCOMPARE(reply.value(), uint(1));
1014  }
1015  }
1016 
1017  struct Deregisterer {
1019  QString sname;
1020  Deregisterer(const QDBusConnection &con, const QString &sname) : con(con), sname(sname) {}
1021  ~Deregisterer() { con.interface()->unregisterService(sname); }
1022  } deregisterer(con, sname);
1023 
1024  // give the connection a chance to find out that we're good to go
1026  con.disconnect("org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus", "NameOwnerChanged",
1027  QStringList() << sname << "",
1028  QString(), &QTestEventLoop::instance(), SLOT(exitLoop()));
1030 
1031  // make the call
1033  QString(), "test0");
1034  QDBusMessage reply = con.call(msg, QDBus::Block, 1000);
1035 
1038 }
1039 
1040 void tst_QDBusConnection::multipleInterfacesInQObject()
1041 {
1043  QVERIFY(!callMethod(con, "/p1"));
1045 
1046  MyObject obj;
1047  con.registerObject("/p1", &obj, QDBusConnection::ExportAllSlots);
1048 
1049  // check if we can call the BaseObject's interface
1050  QDBusMessage msg = QDBusMessage::createMethodCall(con.baseService(), "/p1",
1051  "local.BaseObject", "anotherMethod");
1054  QCOMPARE(reply.arguments().count(), 0);
1056 }
1057 
1058 void tst_QDBusConnection::connectSignal()
1059 {
1061  QSKIP("Test requires a QCoreApplication");
1062 
1064 
1065  QDBusMessage signal = QDBusMessage::createSignal("/", "org.qtproject.TestCase",
1066  "oneSignal");
1067  signal << "one parameter";
1068 
1069  SignalReceiver recv;
1070  QVERIFY(con.connect(con.baseService(), signal.path(), signal.interface(),
1071  signal.member(), &recv, SLOT(oneSlot(QString))));
1072  QVERIFY(con.send(signal));
1073  QTRY_COMPARE(recv.signalsReceived, 1);
1074  QCOMPARE(recv.argumentReceived, signal.arguments().at(0).toString());
1075 
1076  // disconnect and try with a signature
1077  recv.argumentReceived.clear();
1078  recv.signalsReceived = 0;
1079  QVERIFY(con.disconnect(con.baseService(), signal.path(), signal.interface(),
1080  signal.member(), &recv, SLOT(oneSlot(QString))));
1081  QVERIFY(con.connect(con.baseService(), signal.path(), signal.interface(),
1082  signal.member(), "s", &recv, SLOT(oneSlot(QString))));
1083  QVERIFY(con.send(signal));
1084  QTRY_COMPARE(recv.signalsReceived, 1);
1085  QCOMPARE(recv.argumentReceived, signal.arguments().at(0).toString());
1086 
1087  // confirm that we are, indeed, a unique connection
1088  recv.argumentReceived.clear();
1089  recv.signalsReceived = 0;
1090  QVERIFY(!con.connect(con.baseService(), signal.path(), signal.interface(),
1091  signal.member(), "s", &recv, SLOT(oneSlot(QString))));
1092  QVERIFY(con.send(signal));
1093  QTRY_COMPARE(recv.signalsReceived, 1);
1094  QCOMPARE(recv.argumentReceived, signal.arguments().at(0).toString());
1095 }
1096 
1097 void tst_QDBusConnection::slotsWithLessParameters()
1098 {
1100  QSKIP("Test requires a QCoreApplication");
1101 
1103 
1104  QDBusMessage signal = QDBusMessage::createSignal("/", "org.qtproject.TestCase",
1105  "oneSignal");
1106  signal << "one parameter";
1107 
1108  SignalReceiver recv;
1109  QVERIFY(con.connect(con.baseService(), signal.path(), signal.interface(),
1110  signal.member(), &recv, SLOT(oneSlot())));
1111  QVERIFY(con.send(signal));
1112  QTRY_COMPARE(recv.signalsReceived, 1);
1114 
1115  // disconnect and try with a signature
1116  recv.signalsReceived = 0;
1117  QVERIFY(con.disconnect(con.baseService(), signal.path(), signal.interface(),
1118  signal.member(), &recv, SLOT(oneSlot())));
1119  QVERIFY(con.connect(con.baseService(), signal.path(), signal.interface(),
1120  signal.member(), "s", &recv, SLOT(oneSlot())));
1121  QVERIFY(con.send(signal));
1122  QTRY_COMPARE(recv.signalsReceived, 1);
1124 
1125  // confirm that we are, indeed, a unique connection
1126  recv.signalsReceived = 0;
1127  QVERIFY(!con.connect(con.baseService(), signal.path(), signal.interface(),
1128  signal.member(), "s", &recv, SLOT(oneSlot())));
1129  QVERIFY(con.send(signal));
1130  QTRY_COMPARE(recv.signalsReceived, 1);
1132 }
1133 
1135 {
1137  QDBusMessage msg = QDBusMessage::createMethodCall(con.baseService(), "/test", QString(),
1138  "test0");
1139  con.callWithCallback(msg, this, SLOT(exitLoop()), SLOT(secondCallWithCallback()));
1140 }
1141 
1142 void tst_QDBusConnection::nestedCallWithCallback()
1143 {
1145  QSKIP("Test requires a QCoreApplication");
1146 
1149  QVERIFY(connection.registerObject("/test", &testObject,
1151 
1153  "ThisFunctionDoesntExist");
1154 
1155  SignalReceiver recv;
1156  connection.callWithCallback(msg, &recv, SLOT(exitLoop()), SLOT(secondCallWithCallback()), 10);
1159  QCOMPARE(recv.signalsReceived, 1);
1160  QCOMPARE_HOOKCOUNT(2);
1161 }
1162 
1163 void tst_QDBusConnection::serviceRegistrationRaceCondition()
1164 {
1166  QSKIP("Test requires a QCoreApplication");
1167 
1168  // There was a race condition in the updating of list of name owners in
1169  // Qt D-Bus. When the user connects to a signal coming from a given
1170  // service, we must listen for NameOwnerChanged signals relevant to that
1171  // name and update when the owner changes. However, it's possible that we
1172  // receive in one chunk from the server both the NameOwnerChanged signal
1173  // about the service and the signal we're interested in. Since Qt D-Bus
1174  // posts events in order to handle the incoming signals, the update
1175  // happens too late.
1176 
1177  const QString connectionName = "testConnectionName";
1178  const QString serviceName = "org.example.SecondaryName";
1179 
1182 
1183  // connect to the signal:
1185  session.connect(serviceName, "/", "org.qtproject.TestCase", "oneSignal", &recv, SLOT(countUp()));
1186 
1187  // create a secondary connection and register a name
1189  QDBusConnection::disconnectFromBus(connectionName); // disconnection happens when "connection" goes out of scope
1190  QVERIFY(connection.isConnected());
1191  QVERIFY(connection.registerService(serviceName));
1192 
1193  // send a signal
1194  QDBusMessage msg = QDBusMessage::createSignal("/", "org.qtproject.TestCase", "oneSignal");
1195  connection.send(msg);
1196 
1197  // make a blocking call just to be sure that the buffer was flushed
1198  msg = QDBusMessage::createMethodCall("org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus",
1199  "NameHasOwner");
1200  msg << connectionName;
1201  connection.call(msg); // ignore result
1202 
1203  // Now here's the race condition (more info on task QTBUG-15651):
1204  // the bus has most likely queued three signals for us to work on:
1205  // 1) NameOwnerChanged for the connection we created above
1206  // 2) NameOwnerChanged for the service we registered above
1207  // 3) The "oneSignal" signal we sent
1208  //
1209  // We'll most likely receive all three in one go from the server. We must
1210  // update the owner of serviceName before we start processing the
1211  // "oneSignal" signal.
1212 
1213  QTestEventLoop::instance().connect(&recv, SIGNAL(done()), SLOT(exitLoop()));
1216  QCOMPARE(recv.count, 1);
1217 }
1218 
1219 void tst_QDBusConnection::registerVirtualObject()
1220 {
1222  QVERIFY(con.isConnected());
1223 
1224  QString path = "/tree/node";
1225  QString childPath = "/tree/node/child";
1226  QString childChildPath = "/tree/node/child/another";
1227 
1228  {
1229  // Register VirtualObject that handles child paths. Unregister by going out of scope.
1231  QVERIFY(con.registerVirtualObject(path, &obj, QDBusConnection::SubPath));
1232  QCOMPARE(con.objectRegisteredAt(path), static_cast<QObject *>(&obj));
1233  QCOMPARE(con.objectRegisteredAt(childPath), static_cast<QObject *>(&obj));
1234  QCOMPARE(con.objectRegisteredAt(childChildPath), static_cast<QObject *>(&obj));
1235  }
1236  QCOMPARE(con.objectRegisteredAt(path), static_cast<QObject *>(0));
1237  QCOMPARE(con.objectRegisteredAt(childPath), static_cast<QObject *>(0));
1238 
1239  {
1240  // Register VirtualObject that handles child paths. Unregister by calling unregister.
1242  QVERIFY(con.registerVirtualObject(path, &obj, QDBusConnection::SubPath));
1243  QCOMPARE(con.objectRegisteredAt(path), static_cast<QObject *>(&obj));
1244  QCOMPARE(con.objectRegisteredAt(childPath), static_cast<QObject *>(&obj));
1245  QCOMPARE(con.objectRegisteredAt(childChildPath), static_cast<QObject *>(&obj));
1246  con.unregisterObject(path);
1247  QCOMPARE(con.objectRegisteredAt(path), static_cast<QObject *>(0));
1248  QCOMPARE(con.objectRegisteredAt(childPath), static_cast<QObject *>(0));
1249  }
1250 
1251  {
1252  // Single node has no sub path handling.
1254  QVERIFY(con.registerVirtualObject(path, &obj, QDBusConnection::SingleNode));
1255  QCOMPARE(con.objectRegisteredAt(path), static_cast<QObject *>(&obj));
1256  QCOMPARE(con.objectRegisteredAt(childPath), static_cast<QObject *>(0));
1257  }
1258 
1259  {
1260  // Register VirtualObject that handles child paths. Try to register an object on a child path of that.
1262  QVERIFY(con.registerVirtualObject(path, &obj, QDBusConnection::SubPath));
1263  QCOMPARE(con.objectRegisteredAt(path), static_cast<QObject *>(&obj));
1264 
1265  QObject objectAtSubPath;
1266  QVERIFY(!con.registerObject(path, &objectAtSubPath));
1267  QVERIFY(!con.registerObject(childPath, &objectAtSubPath));
1268  QCOMPARE(con.objectRegisteredAt(childPath), static_cast<QObject *>(&obj));
1269  }
1270 
1271  {
1272  // Register object, make sure no SubPath handling object can be registered on a parent path.
1273  QObject objectAtSubPath;
1274  QVERIFY(con.registerObject(childPath, &objectAtSubPath));
1275  QCOMPARE(con.objectRegisteredAt(childPath), static_cast<QObject *>(&objectAtSubPath));
1276 
1278  QVERIFY(!con.registerVirtualObject(path, &obj, QDBusConnection::SubPath));
1279  QCOMPARE(con.objectRegisteredAt(path), static_cast<QObject *>(0));
1280  }
1281 
1282  {
1283  // Register object, make sure no SubPath handling object can be registered on a parent path.
1284  // (same as above, but deeper)
1285  QObject objectAtSubPath;
1286  QVERIFY(con.registerObject(childChildPath, &objectAtSubPath));
1287  QCOMPARE(con.objectRegisteredAt(childChildPath), static_cast<QObject *>(&objectAtSubPath));
1288 
1290  QVERIFY(!con.registerVirtualObject(path, &obj, QDBusConnection::SubPath));
1291  QCOMPARE(con.objectRegisteredAt(path), static_cast<QObject *>(0));
1292  }
1293 
1294  QCOMPARE(con.objectRegisteredAt(path), static_cast<QObject *>(0));
1295  QCOMPARE(con.objectRegisteredAt(childPath), static_cast<QObject *>(0));
1296  QCOMPARE(con.objectRegisteredAt(childChildPath), static_cast<QObject *>(0));
1297 }
1298 
1299 void tst_QDBusConnection::callVirtualObject()
1300 {
1302  QSKIP("Test requires a QCoreApplication");
1303 
1305  QVERIFY(con.isConnected());
1306 
1308 
1309  QString path = "/tree/node";
1310  QString childPath = "/tree/node/child";
1311 
1312  // register one object at root:
1314  QVERIFY(con.registerVirtualObject(path, &obj, QDBusConnection::SubPath));
1315  obj.callCount = 0;
1316  obj.replyArguments << 42 << 47u;
1317 
1318  QObject::connect(&obj, SIGNAL(messageReceived(QDBusMessage)), &QTestEventLoop::instance(), SLOT(exitLoop()));
1319 
1320  QDBusMessage message = QDBusMessage::createMethodCall(con.baseService(), path, QString(), "hello");
1322 
1326 
1327  QCOMPARE(obj.callCount, 1);
1328  QCOMPARE(obj.lastMessage.service(), con2.baseService());
1329  QCOMPARE(obj.lastMessage.interface(), QString());
1330  QCOMPARE(obj.lastMessage.path(), path);
1331  reply.waitForFinished();
1332  QVERIFY(reply.isValid());
1333  QCOMPARE(reply.reply().arguments(), obj.replyArguments);
1334 
1335  // call sub path
1336  QDBusMessage childMessage = QDBusMessage::createMethodCall(con.baseService(), childPath, QString(), "helloChild");
1337  obj.replyArguments.clear();
1338  obj.replyArguments << 99;
1339  QDBusPendingCall childReply = con2.asyncCall(childMessage);
1340 
1344 
1345  QCOMPARE(obj.callCount, 2);
1346  QCOMPARE(obj.lastMessage.service(), con2.baseService());
1347  QCOMPARE(obj.lastMessage.interface(), QString());
1348  QCOMPARE(obj.lastMessage.path(), childPath);
1349 
1350  childReply.waitForFinished();
1351  QVERIFY(childReply.isValid());
1352  QCOMPARE(childReply.reply().arguments(), obj.replyArguments);
1353 
1354  // let the call fail by having the virtual object return false
1355  obj.success = false;
1356  QDBusMessage errorMessage = QDBusMessage::createMethodCall(con.baseService(), childPath, QString(), "someFunc");
1357  QDBusPendingCall errorReply = con2.asyncCall(errorMessage);
1358 
1362  QTest::qWait(100);
1363  QVERIFY(errorReply.isError());
1364  QCOMPARE(errorReply.reply().errorName(), QString("org.freedesktop.DBus.Error.UnknownObject"));
1365 
1367 }
1368 
1369 void tst_QDBusConnection::callVirtualObjectLocal()
1370 {
1372  QVERIFY(con.isConnected());
1373 
1374  QString path = "/tree/node";
1375  QString childPath = "/tree/node/child";
1376 
1377  // register one object at root:
1379  QVERIFY(con.registerVirtualObject(path, &obj, QDBusConnection::SubPath));
1380  obj.callCount = 0;
1381  obj.replyArguments << 42 << 47u;
1382 
1383  QDBusMessage message = QDBusMessage::createMethodCall(con.baseService(), path, QString(), "hello");
1384  QDBusMessage reply = con.call(message, QDBus::Block, 5000);
1385  QCOMPARE(obj.callCount, 1);
1386  QCOMPARE(obj.lastMessage.service(), con.baseService());
1387  QCOMPARE(obj.lastMessage.interface(), QString());
1388  QCOMPARE(obj.lastMessage.path(), path);
1389  QCOMPARE(obj.replyArguments, reply.arguments());
1391 
1392  obj.replyArguments << QString("alien abduction");
1393  QDBusMessage subPathMessage = QDBusMessage::createMethodCall(con.baseService(), childPath, QString(), "hello");
1394  QDBusMessage subPathReply = con.call(subPathMessage , QDBus::Block, 5000);
1395  QCOMPARE(obj.callCount, 2);
1396  QCOMPARE(obj.lastMessage.service(), con.baseService());
1397  QCOMPARE(obj.lastMessage.interface(), QString());
1398  QCOMPARE(obj.lastMessage.path(), childPath);
1399  QCOMPARE(obj.replyArguments, subPathReply.arguments());
1401 }
1402 
1403 void tst_QDBusConnection::pendingCallWhenDisconnected()
1404 {
1405 #if !QT_CONFIG(process)
1406  QSKIP("Test requires QProcess");
1407 #else
1409  QSKIP("Test requires a QCoreApplication");
1410 
1411  QProcess daemon;
1412  daemon.start("dbus-daemon", QStringList() << "--session" << "--nofork" << "--print-address");
1413  QVERIFY2(daemon.waitForReadyRead(2000),
1414  "Daemon didn't print its address in time; error: \"" + daemon.errorString().toLocal8Bit() +
1415  "\"; stderr:\n" + daemon.readAllStandardError());
1416 
1417  QString address = QString::fromLocal8Bit(daemon.readAll().trimmed());
1419  QVERIFY2(con.isConnected(), (con.lastError().name() + ": " + con.lastError().message()).toLocal8Bit());
1420 
1421  // confirm we're connected and we're alone in this bus
1422  QCOMPARE(con.baseService(), QString(":1.0"));
1423 
1424  // kill the bus
1425  daemon.terminate();
1426  daemon.waitForFinished();
1427 
1428  // send something, which we should get an error with
1429  QDBusMessage message = QDBusMessage::createMethodCall("org.freedesktop.DBus", "/", QString(), "ListNames");
1430  QDBusPendingCall reply = con.asyncCall(message);
1431 
1432  reply.waitForFinished();
1433  QVERIFY(!con.isConnected());
1435  QVERIFY(reply.isError());
1437 #endif
1438 }
1439 
1443 
1444 #ifndef tst_QDBusConnection
1446 #endif
const char msg[]
Definition: arch.cpp:46
QDBusConnection connection() const
[0]
Definition: myobject.h:58
static QString path
void method(const QDBusMessage &msg)
void method(const QDBusMessage &msg)
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:85
static QCoreApplication * instance()
static void processEvents(QEventLoop::ProcessEventsFlags flags=QEventLoop::AllEvents)
The QDBusConnection class represents a connection to the D-Bus bus daemon.
static QDBusConnection connectToPeer(const QString &address, const QString &name)
QDBusConnectionInterface * interface() const
static QDBusConnection connectToBus(BusType type, const QString &name)
QDBusMessage call(const QDBusMessage &message, QDBus::CallMode mode=QDBus::Block, int timeout=-1) const
bool connect(const QString &service, const QString &path, const QString &interface, const QString &name, QObject *receiver, const char *slot)
static QDBusConnection sessionBus()
static void disconnectFromPeer(const QString &name)
static void disconnectFromBus(const QString &name)
QString baseService() const
QDBusPendingCall asyncCall(const QDBusMessage &message, int timeout=-1) const
QDBusReply< bool > isServiceRegistered(const QString &serviceName) const
@ Disconnected
Definition: qdbuserror.h:75
The QDBusInterface class is a proxy for interfaces on remote objects.
The QDBusMessage class represents one message sent or received over the D-Bus bus.
Definition: qdbusmessage.h:58
static QDBusMessage createSignal(const QString &path, const QString &interface, const QString &name)
QString errorName() const
QList< QVariant > arguments() const
static QDBusMessage createTargetedSignal(const QString &service, const QString &path, const QString &interface, const QString &name)
static QDBusMessage createMethodCall(const QString &destination, const QString &path, const QString &interface, const QString &method)
The QDBusPendingCall class refers to one pending asynchronous call.
QDBusMessage reply() const
The QDBusReply class stores the reply for a method call to a remote object.
Definition: qdbusreply.h:60
The QDBusServer class provides peer-to-peer communication between processes on the same computer.
Definition: qdbusserver.h:57
The QLatin1String class provides a thin wrapper around an US-ASCII/Latin-1 encoded string literal.
Definition: qstring.h:84
const_reference at(qsizetype i) const noexcept
Definition: qlist.h:457
T value(qsizetype i) const
Definition: qlist.h:676
qsizetype count() const noexcept
Definition: qlist.h:415
bool isFinished() const
NetworkError error() const
The QObject class is the base class of all Qt objects.
Definition: qobject.h:125
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
Definition: qobject.cpp:2772
void setObjectName(const QString &name)
Definition: qobject.cpp:1261
The QString class provides a Unicode character string.
Definition: qstring.h:388
static QString fromLocal8Bit(QByteArrayView ba)
Definition: qstring.cpp:5563
void clear()
Definition: qstring.h:1240
static QString number(int, int base=10)
Definition: qstring.cpp:7538
void enterLoop(int secs)
static QTestEventLoop & instance()
QString serviceName() const
bool callMethodPeer(const QDBusConnection &conn, const QString &path)
bool callMethod(const QDBusConnection &conn, const QString &path)
auto signal
QSignalSpy spy(myCustomObject, SIGNAL(mySignal(int, QString, double)))
[0]
QCOMPARE(spy.count(), 1)
@ BlockWithGui
Q_TESTLIB_EXPORT QTestData & newRow(const char *dataTag)
Definition: qtestcase.cpp:2658
bool qCompare(QString const &t1, QLatin1String const &t2, const char *actual, const char *expected, const char *file, int line)
Definition: qtest.h:411
Q_CORE_EXPORT void qWait(int ms)
#define QString()
Definition: parse-defines.h:51
QList< QString > QStringList
Definition: qcontainerfwd.h:64
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char const char return DBusMessage return DBusMessage const char return DBusMessage dbus_bool_t return DBusMessage dbus_uint32_t return DBusMessage return DBusPendingCall DBusPendingCall return DBusPendingCall return dbus_int32_t return DBusServer * server
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char * interface
DBusConnection * connection
QT_BEGIN_NAMESPACE bool done
unsigned int uint
Definition: qglobal.h:334
#define SLOT(a)
Definition: qobjectdefs.h:87
#define SIGNAL(a)
Definition: qobjectdefs.h:88
GLenum GLuint GLenum GLsizei const GLchar * message
Definition: qopengl.h:270
GLboolean GLboolean GLboolean b
GLboolean GLboolean GLboolean GLboolean a
[7]
GLbitfield GLuint64 timeout
[4]
GLuint counter
GLhandleARB obj
[2]
Definition: qopenglext.h:4164
const GLubyte * c
Definition: qopenglext.h:12701
GLuint GLuint64EXT address
Definition: qopenglext.h:11428
GLsizei const GLchar *const * path
Definition: qopenglext.h:4283
#define QTEST_MAIN(TestObject)
Definition: qtest.h:664
#define QSKIP(statement,...)
Definition: qtestcase.h:222
#define QFETCH(Type, name)
Definition: qtestcase.h:230
#define QTRY_COMPARE(expr, expected)
Definition: qtestcase.h:214
#define QVERIFY(statement)
Definition: qtestcase.h:64
#define QVERIFY2(statement, description)
Definition: qtestcase.h:76
QNetworkReply * reply
void testObject()
[11]
#define QVERIFY_HOOKCALLED()
#define QCOMPARE_HOOKCOUNT(n)