util/tests/auto/qdbusconnection/tst_qdbusconnection.cpp
changeset 7 f7bc934e204c
equal deleted inserted replaced
3:41300fa6a67c 7:f7bc934e204c
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the test suite of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 #include <qcoreapplication.h>
       
    42 #include <qdebug.h>
       
    43 
       
    44 #include <QtTest/QtTest>
       
    45 #include <QtDBus/QtDBus>
       
    46 
       
    47 class BaseObject: public QObject
       
    48 {
       
    49     Q_OBJECT
       
    50     Q_CLASSINFO("D-Bus Interface", "local.BaseObject")
       
    51 public:
       
    52     BaseObject(QObject *parent = 0) : QObject(parent) { }
       
    53 public slots:
       
    54     void anotherMethod() { }
       
    55 };
       
    56 
       
    57 class MyObject: public BaseObject
       
    58 {
       
    59     Q_OBJECT
       
    60 public slots:
       
    61     void method(const QDBusMessage &msg);
       
    62 
       
    63 public:
       
    64     static QString path;
       
    65     int callCount;
       
    66     MyObject(QObject *parent = 0) : BaseObject(parent), callCount(0) {}
       
    67 };
       
    68 
       
    69 void MyObject::method(const QDBusMessage &msg)
       
    70 {
       
    71     path = msg.path();
       
    72     ++callCount;
       
    73     //qDebug() << msg;
       
    74 }
       
    75 
       
    76 class tst_QDBusConnection: public QObject
       
    77 {
       
    78     Q_OBJECT
       
    79 
       
    80     int signalsReceived;
       
    81 public slots:
       
    82     void oneSlot() { ++signalsReceived; }
       
    83     void exitLoop() { ++signalsReceived; QTestEventLoop::instance().exitLoop(); }
       
    84     void secondCallWithCallback();
       
    85 
       
    86 private slots:
       
    87     void noConnection();
       
    88     void connectToBus();
       
    89     void connect();
       
    90     void send();
       
    91     void sendWithGui();
       
    92     void sendAsync();
       
    93     void sendSignal();
       
    94 
       
    95     void registerObject_data();
       
    96     void registerObject();
       
    97     void registerObject2();
       
    98 
       
    99     void registerQObjectChildren();
       
   100 
       
   101     void callSelf();
       
   102     void callSelfByAnotherName_data();
       
   103     void callSelfByAnotherName();
       
   104     void multipleInterfacesInQObject();
       
   105 
       
   106     void slotsWithLessParameters();
       
   107     void nestedCallWithCallback();
       
   108 
       
   109 public:
       
   110     QString serviceName() const { return "com.trolltech.Qt.Autotests.QDBusConnection"; }
       
   111     bool callMethod(const QDBusConnection &conn, const QString &path);
       
   112 };
       
   113 
       
   114 class QDBusSpy: public QObject
       
   115 {
       
   116     Q_OBJECT
       
   117 public slots:
       
   118     void handlePing(const QString &str) { args.clear(); args << str; }
       
   119     void asyncReply(const QDBusMessage &msg) { args = msg.arguments(); }
       
   120 
       
   121 public:
       
   122     QList<QVariant> args;
       
   123 };
       
   124 
       
   125 void tst_QDBusConnection::noConnection()
       
   126 {
       
   127     QDBusConnection con = QDBusConnection::connectToBus("unix:path=/dev/null", "testconnection");
       
   128     QVERIFY(!con.isConnected());
       
   129 
       
   130     // try sending a message. This should fail
       
   131     QDBusMessage msg = QDBusMessage::createMethodCall("org.kde.selftest", "/org/kde/selftest",
       
   132                                                       "org.kde.selftest", "Ping");
       
   133     msg << QLatin1String("ping");
       
   134 
       
   135     QVERIFY(!con.send(msg));
       
   136 
       
   137     QDBusSpy spy;
       
   138     QVERIFY(con.callWithCallback(msg, &spy, SLOT(asyncReply)) == 0);
       
   139 
       
   140     QDBusMessage reply = con.call(msg);
       
   141     QVERIFY(reply.type() == QDBusMessage::ErrorMessage);
       
   142 
       
   143     QDBusReply<void> voidreply(reply);
       
   144     QVERIFY(!voidreply.isValid());
       
   145 
       
   146     QDBusConnection::disconnectFromBus("testconnection");
       
   147 }
       
   148 
       
   149 void tst_QDBusConnection::sendSignal()
       
   150 {
       
   151     QDBusConnection con = QDBusConnection::sessionBus();
       
   152 
       
   153     QVERIFY(con.isConnected());
       
   154 
       
   155     QDBusMessage msg = QDBusMessage::createSignal("/org/kde/selftest", "org.kde.selftest",
       
   156                                                   "Ping");
       
   157     msg << QLatin1String("ping");
       
   158 
       
   159     QVERIFY(con.send(msg));
       
   160 
       
   161     QTest::qWait(1000);
       
   162 }
       
   163 
       
   164 void tst_QDBusConnection::send()
       
   165 {
       
   166     QDBusConnection con = QDBusConnection::sessionBus();
       
   167 
       
   168     QVERIFY(con.isConnected());
       
   169 
       
   170     QDBusMessage msg = QDBusMessage::createMethodCall("org.freedesktop.DBus",
       
   171         "/org/freedesktop/DBus", "org.freedesktop.DBus", "ListNames");
       
   172 
       
   173     QDBusMessage reply = con.call(msg);
       
   174 
       
   175     QCOMPARE(reply.arguments().count(), 1);
       
   176     QCOMPARE(reply.arguments().at(0).typeName(), "QStringList");
       
   177     QVERIFY(reply.arguments().at(0).toStringList().contains(con.baseService()));
       
   178 }
       
   179 
       
   180 void tst_QDBusConnection::sendWithGui()
       
   181 {
       
   182     QDBusConnection con = QDBusConnection::sessionBus();
       
   183 
       
   184     QVERIFY(con.isConnected());
       
   185 
       
   186     QDBusMessage msg = QDBusMessage::createMethodCall("org.freedesktop.DBus",
       
   187         "/org/freedesktop/DBus", "org.freedesktop.DBus", "ListNames");
       
   188 
       
   189     QDBusMessage reply = con.call(msg, QDBus::BlockWithGui);
       
   190 
       
   191     QCOMPARE(reply.arguments().count(), 1);
       
   192     QCOMPARE(reply.arguments().at(0).typeName(), "QStringList");
       
   193     QVERIFY(reply.arguments().at(0).toStringList().contains(con.baseService()));
       
   194 }
       
   195 
       
   196 void tst_QDBusConnection::sendAsync()
       
   197 {
       
   198     QDBusConnection con = QDBusConnection::sessionBus();
       
   199     QVERIFY(con.isConnected());
       
   200 
       
   201     QDBusSpy spy;
       
   202 
       
   203     QDBusMessage msg = QDBusMessage::createMethodCall("org.freedesktop.DBus",
       
   204             "/org/freedesktop/DBus", "org.freedesktop.DBus", "ListNames");
       
   205     QVERIFY(con.callWithCallback(msg, &spy, SLOT(asyncReply(QDBusMessage))));
       
   206 
       
   207     QTest::qWait(1000);
       
   208 
       
   209     QCOMPARE(spy.args.value(0).typeName(), "QStringList");
       
   210     QVERIFY(spy.args.at(0).toStringList().contains(con.baseService()));
       
   211 }
       
   212 
       
   213 void tst_QDBusConnection::connect()
       
   214 {
       
   215     QDBusSpy spy;
       
   216 
       
   217     QDBusConnection con = QDBusConnection::sessionBus();
       
   218 
       
   219     con.connect(con.baseService(), "/org/kde/selftest", "org.kde.selftest", "ping", &spy,
       
   220                  SLOT(handlePing(QString)));
       
   221 
       
   222     QDBusMessage msg = QDBusMessage::createSignal("/org/kde/selftest", "org.kde.selftest",
       
   223                                                   "ping");
       
   224     msg << QLatin1String("ping");
       
   225 
       
   226     QVERIFY(con.send(msg));
       
   227 
       
   228     QTest::qWait(1000);
       
   229 
       
   230     QCOMPARE(spy.args.count(), 1);
       
   231     QCOMPARE(spy.args.at(0).toString(), QString("ping"));
       
   232 }
       
   233 
       
   234 void tst_QDBusConnection::connectToBus()
       
   235 {
       
   236     {
       
   237         QDBusConnection con = QDBusConnection::connectToBus(
       
   238                 QDBusConnection::SessionBus, "bubu");
       
   239 
       
   240         QVERIFY(con.isConnected());
       
   241         QVERIFY(!con.lastError().isValid());
       
   242 
       
   243         QDBusConnection con2("foo");
       
   244         QVERIFY(!con2.isConnected());
       
   245         QVERIFY(!con2.lastError().isValid());
       
   246 
       
   247         con2 = con;
       
   248         QVERIFY(con.isConnected());
       
   249         QVERIFY(con2.isConnected());
       
   250         QVERIFY(!con.lastError().isValid());
       
   251         QVERIFY(!con2.lastError().isValid());
       
   252     }
       
   253 
       
   254     {
       
   255         QDBusConnection con("bubu");
       
   256         QVERIFY(con.isConnected());
       
   257         QVERIFY(!con.lastError().isValid());
       
   258     }
       
   259 
       
   260     QDBusConnection::disconnectFromBus("bubu");
       
   261 
       
   262     {
       
   263         QDBusConnection con("bubu");
       
   264         QVERIFY(!con.isConnected());
       
   265         QVERIFY(!con.lastError().isValid());
       
   266     }
       
   267 
       
   268     QByteArray address = qgetenv("DBUS_SESSION_BUS_ADDRESS");
       
   269     if (!address.isEmpty()) {
       
   270         QDBusConnection con = QDBusConnection::connectToBus(address, "newconn");
       
   271         QVERIFY(con.isConnected());
       
   272         QVERIFY(!con.lastError().isValid());
       
   273 
       
   274         QDBusConnection::disconnectFromBus("newconn");
       
   275     }
       
   276 }
       
   277 
       
   278 void tst_QDBusConnection::registerObject_data()
       
   279 {
       
   280     QTest::addColumn<QString>("path");
       
   281 
       
   282     QTest::newRow("/") << "/";
       
   283     QTest::newRow("/p1") << "/p1";
       
   284     QTest::newRow("/p2") << "/p2";
       
   285     QTest::newRow("/p1/q") << "/p1/q";
       
   286     QTest::newRow("/p1/q/r") << "/p1/q/r";
       
   287 }
       
   288 
       
   289 void tst_QDBusConnection::registerObject()
       
   290 {
       
   291     QFETCH(QString, path);
       
   292 
       
   293     QDBusConnection con = QDBusConnection::sessionBus();
       
   294     QVERIFY(con.isConnected());
       
   295 
       
   296     //QVERIFY(!callMethod(con, path));
       
   297     {
       
   298         // register one object at root:
       
   299         MyObject obj;
       
   300         QVERIFY(con.registerObject(path, &obj, QDBusConnection::ExportAllSlots));
       
   301         QCOMPARE(con.objectRegisteredAt(path), &obj);
       
   302         QVERIFY(callMethod(con, path));
       
   303         QCOMPARE(obj.path, path);
       
   304     }
       
   305     // make sure it's gone
       
   306     QVERIFY(!callMethod(con, path));
       
   307 }
       
   308 
       
   309 void tst_QDBusConnection::registerObject2()
       
   310 {
       
   311     QDBusConnection con = QDBusConnection::sessionBus();
       
   312     QVERIFY(con.isConnected());
       
   313 
       
   314     // make sure nothing is using our paths:
       
   315      QVERIFY(!callMethod(con, "/"));
       
   316      QVERIFY(!callMethod(con, "/p1"));
       
   317      QVERIFY(!callMethod(con, "/p2"));
       
   318      QVERIFY(!callMethod(con, "/p1/q"));
       
   319      QVERIFY(!callMethod(con, "/p1/q/r"));
       
   320 
       
   321     {
       
   322         // register one object at root:
       
   323         MyObject obj;
       
   324         QVERIFY(con.registerObject("/", &obj, QDBusConnection::ExportAllSlots));
       
   325         QVERIFY(callMethod(con, "/"));
       
   326         qDebug() << obj.path;
       
   327         QCOMPARE(obj.path, QString("/"));
       
   328     }
       
   329     // make sure it's gone
       
   330     QVERIFY(!callMethod(con, "/"));
       
   331 
       
   332     {
       
   333         // register one at an element:
       
   334         MyObject obj;
       
   335         QVERIFY(con.registerObject("/p1", &obj, QDBusConnection::ExportAllSlots));
       
   336         QVERIFY(!callMethod(con, "/"));
       
   337         QVERIFY(callMethod(con, "/p1"));
       
   338         qDebug() << obj.path;
       
   339         QCOMPARE(obj.path, QString("/p1"));
       
   340 
       
   341         // re-register it somewhere else
       
   342         QVERIFY(con.registerObject("/p2", &obj, QDBusConnection::ExportAllSlots));
       
   343         QVERIFY(callMethod(con, "/p1"));
       
   344         QCOMPARE(obj.path, QString("/p1"));
       
   345         QVERIFY(callMethod(con, "/p2"));
       
   346         QCOMPARE(obj.path, QString("/p2"));
       
   347     }
       
   348     // make sure it's gone
       
   349     QVERIFY(!callMethod(con, "/p1"));
       
   350     QVERIFY(!callMethod(con, "/p2"));
       
   351 
       
   352     {
       
   353         // register at a deep path
       
   354         MyObject obj;
       
   355         QVERIFY(con.registerObject("/p1/q/r", &obj, QDBusConnection::ExportAllSlots));
       
   356         QVERIFY(!callMethod(con, "/"));
       
   357         QVERIFY(!callMethod(con, "/p1"));
       
   358         QVERIFY(!callMethod(con, "/p1/q"));
       
   359         QVERIFY(callMethod(con, "/p1/q/r"));
       
   360         QCOMPARE(obj.path, QString("/p1/q/r"));
       
   361     }
       
   362     // make sure it's gone
       
   363     QVERIFY(!callMethod(con, "/p1/q/r"));
       
   364 
       
   365     {
       
   366         MyObject obj;
       
   367         QVERIFY(con.registerObject("/p1/q2", &obj, QDBusConnection::ExportAllSlots));
       
   368         QVERIFY(callMethod(con, "/p1/q2"));
       
   369         QCOMPARE(obj.path, QString("/p1/q2"));
       
   370 
       
   371         // try unregistering
       
   372         con.unregisterObject("/p1/q2");
       
   373         QVERIFY(!callMethod(con, "/p1/q2"));
       
   374 
       
   375         // register it again
       
   376         QVERIFY(con.registerObject("/p1/q2", &obj, QDBusConnection::ExportAllSlots));
       
   377         QVERIFY(callMethod(con, "/p1/q2"));
       
   378         QCOMPARE(obj.path, QString("/p1/q2"));
       
   379 
       
   380         // now try removing things around it:
       
   381         con.unregisterObject("/p2");
       
   382         QVERIFY(callMethod(con, "/p1/q2")); // unrelated object shouldn't affect
       
   383 
       
   384         con.unregisterObject("/p1");
       
   385         QVERIFY(callMethod(con, "/p1/q2")); // unregistering just the parent shouldn't affect it
       
   386 
       
   387         con.unregisterObject("/p1/q2/r");
       
   388         QVERIFY(callMethod(con, "/p1/q2")); // unregistering non-existing child shouldn't affect it either
       
   389 
       
   390         con.unregisterObject("/p1/q");
       
   391         QVERIFY(callMethod(con, "/p1/q2")); // unregistering sibling (before) shouldn't affect
       
   392 
       
   393         con.unregisterObject("/p1/r");
       
   394         QVERIFY(callMethod(con, "/p1/q2")); // unregistering sibling (after) shouldn't affect
       
   395 
       
   396         // now remove it:
       
   397         con.unregisterObject("/p1", QDBusConnection::UnregisterTree);
       
   398         QVERIFY(!callMethod(con, "/p1/q2")); // we removed the full tree
       
   399     }
       
   400 }
       
   401 
       
   402 void tst_QDBusConnection::registerQObjectChildren()
       
   403 {
       
   404     // make sure no one is there
       
   405     QDBusConnection con = QDBusConnection::sessionBus();
       
   406     QVERIFY(!callMethod(con, "/p1"));
       
   407 
       
   408     {
       
   409         MyObject obj, *a, *b, *c, *cc;
       
   410 
       
   411         a = new MyObject(&obj);
       
   412         a->setObjectName("a");
       
   413 
       
   414         b = new MyObject(&obj);
       
   415         b->setObjectName("b");
       
   416 
       
   417         c = new MyObject(&obj);
       
   418         c->setObjectName("c");
       
   419 
       
   420         cc = new MyObject(c);
       
   421         cc->setObjectName("cc");
       
   422 
       
   423         con.registerObject("/p1", &obj, QDBusConnection::ExportAllSlots |
       
   424                            QDBusConnection::ExportChildObjects);
       
   425 
       
   426         // make calls
       
   427         QVERIFY(callMethod(con, "/p1"));
       
   428         QCOMPARE(obj.callCount, 1);
       
   429         QVERIFY(callMethod(con, "/p1/a"));
       
   430         QCOMPARE(a->callCount, 1);
       
   431         QVERIFY(callMethod(con, "/p1/b"));
       
   432         QCOMPARE(b->callCount, 1);
       
   433         QVERIFY(callMethod(con, "/p1/c"));
       
   434         QCOMPARE(c->callCount, 1);
       
   435         QVERIFY(callMethod(con, "/p1/c/cc"));
       
   436         QCOMPARE(cc->callCount, 1);
       
   437 
       
   438         QVERIFY(!callMethod(con, "/p1/d"));
       
   439         QVERIFY(!callMethod(con, "/p1/c/abc"));
       
   440 
       
   441         // pull an object, see if it goes away:
       
   442         delete b;
       
   443         QVERIFY(!callMethod(con, "/p1/b"));
       
   444 
       
   445         delete c;
       
   446         QVERIFY(!callMethod(con, "/p1/c"));
       
   447         QVERIFY(!callMethod(con, "/p1/c/cc"));
       
   448     }
       
   449 
       
   450     QVERIFY(!callMethod(con, "/p1"));
       
   451     QVERIFY(!callMethod(con, "/p1/a"));
       
   452     QVERIFY(!callMethod(con, "/p1/b"));
       
   453     QVERIFY(!callMethod(con, "/p1/c"));
       
   454     QVERIFY(!callMethod(con, "/p1/c/cc"));
       
   455 }
       
   456 
       
   457 bool tst_QDBusConnection::callMethod(const QDBusConnection &conn, const QString &path)
       
   458 {
       
   459     QDBusMessage msg = QDBusMessage::createMethodCall(conn.baseService(), path, "", "method");
       
   460     QDBusMessage reply = conn.call(msg, QDBus::Block/*WithGui*/);
       
   461 
       
   462     if (reply.type() != QDBusMessage::ReplyMessage)
       
   463         return false;
       
   464     if (MyObject::path == path) {
       
   465         QTest::compare_helper(true, "COMPARE()", __FILE__, __LINE__);
       
   466     } else {
       
   467         QTest::compare_helper(false, "Compared values are not the same",
       
   468                               QTest::toString(MyObject::path), QTest::toString(path),
       
   469                               "MyObject::path", "path", __FILE__, __LINE__);
       
   470         return false;
       
   471     }
       
   472 
       
   473     return true;
       
   474 }
       
   475 
       
   476 class TestObject : public QObject
       
   477 {
       
   478 Q_OBJECT
       
   479 public:
       
   480     TestObject(QObject *parent = 0) : QObject(parent) {}
       
   481     ~TestObject() {}
       
   482 
       
   483     QString func;
       
   484 
       
   485 public slots:
       
   486     void test0() { func = "test0"; }
       
   487     void test1(int i) { func = "test1 " + QString::number(i); }
       
   488     int test2() { func = "test2"; return 43; }
       
   489     int test3(int i) { func = "test2"; return i + 1; }
       
   490 };
       
   491 
       
   492 void tst_QDBusConnection::callSelf()
       
   493 {
       
   494     TestObject testObject;
       
   495     QDBusConnection connection = QDBusConnection::sessionBus();
       
   496     QVERIFY(connection.registerObject("/test", &testObject,
       
   497             QDBusConnection::ExportAllContents));
       
   498     QCOMPARE(connection.objectRegisteredAt("/test"), &testObject);
       
   499     QVERIFY(connection.registerService(serviceName()));
       
   500     QDBusInterface interface(serviceName(), "/test");
       
   501     QVERIFY(interface.isValid());
       
   502 
       
   503     interface.call(QDBus::Block, "test0");
       
   504     QCOMPARE(testObject.func, QString("test0"));
       
   505     interface.call(QDBus::Block, "test1", 42);
       
   506     QCOMPARE(testObject.func, QString("test1 42"));
       
   507     QDBusMessage reply = interface.call(QDBus::Block, "test2");
       
   508     QCOMPARE(testObject.func, QString("test2"));
       
   509     QCOMPARE(reply.arguments().value(0).toInt(), 43);
       
   510 
       
   511     QDBusMessage msg = QDBusMessage::createMethodCall(serviceName(), "/test",
       
   512                                                       QString(), "test3");
       
   513     msg << 44;
       
   514     reply = connection.call(msg);
       
   515     QCOMPARE(reply.arguments().value(0).toInt(), 45);
       
   516 }
       
   517 
       
   518 void tst_QDBusConnection::callSelfByAnotherName_data()
       
   519 {
       
   520     QTest::addColumn<int>("registerMethod");
       
   521     QTest::newRow("connection") << 0;
       
   522     QTest::newRow("connection-interface") << 1;
       
   523     QTest::newRow("direct") << 2;
       
   524 }
       
   525 
       
   526 void tst_QDBusConnection::callSelfByAnotherName()
       
   527 {
       
   528     static int counter = 0;
       
   529     QString sname = serviceName() + QString::number(counter++);
       
   530 
       
   531     QDBusConnection con = QDBusConnection::sessionBus();
       
   532     QVERIFY(con.isConnected());
       
   533 
       
   534     TestObject testObject;
       
   535     QVERIFY(con.registerObject("/test", &testObject,
       
   536             QDBusConnection::ExportAllContents));
       
   537     con.connect("org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus", "NameOwnerChanged",
       
   538                 QStringList() << sname << "",
       
   539                 QString(), &QTestEventLoop::instance(), SLOT(exitLoop()));
       
   540 
       
   541     // register the name
       
   542     QFETCH(int, registerMethod);
       
   543     switch (registerMethod) {
       
   544     case 0:
       
   545         QVERIFY(con.registerService(sname));
       
   546         break;
       
   547 
       
   548     case 1:
       
   549         QVERIFY(con.interface()->registerService(sname).value() == QDBusConnectionInterface::ServiceRegistered);
       
   550         break;
       
   551 
       
   552     case 2: {
       
   553             // flag is DBUS_NAME_FLAG_DO_NOT_QUEUE = 0x04
       
   554             // reply is DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER = 1
       
   555             QDBusReply<uint> reply = con.interface()->call("RequestName", sname, 4u);
       
   556             QVERIFY(reply.value() == 1);
       
   557         }
       
   558     }
       
   559 
       
   560     struct Deregisterer {
       
   561         QDBusConnection con;
       
   562         QString sname;
       
   563         Deregisterer(const QDBusConnection &con, const QString &sname) : con(con), sname(sname) {}
       
   564         ~Deregisterer() { con.interface()->unregisterService(sname); }
       
   565     } deregisterer(con, sname);
       
   566 
       
   567     // give the connection a chance to find out that we're good to go
       
   568     QTestEventLoop::instance().enterLoop(2);
       
   569     con.disconnect("org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus", "NameOwnerChanged",
       
   570                  QStringList() << sname << "",
       
   571                  QString(), &QTestEventLoop::instance(), SLOT(exitLoop()));
       
   572     QVERIFY(!QTestEventLoop::instance().timeout());
       
   573 
       
   574     // make the call
       
   575     QDBusMessage msg = QDBusMessage::createMethodCall(sname, "/test",
       
   576                                                       QString(), "test0");
       
   577     QDBusMessage reply = con.call(msg, QDBus::Block, 1000);
       
   578 
       
   579     QVERIFY(reply.type() == QDBusMessage::ReplyMessage);
       
   580 }
       
   581 
       
   582 void tst_QDBusConnection::multipleInterfacesInQObject()
       
   583 {
       
   584     QDBusConnection con = QDBusConnection::sessionBus();
       
   585     QVERIFY(!callMethod(con, "/p1"));
       
   586 
       
   587     MyObject obj;
       
   588     con.registerObject("/p1", &obj, QDBusConnection::ExportAllSlots);
       
   589 
       
   590     // check if we can call the BaseObject's interface
       
   591     QDBusMessage msg = QDBusMessage::createMethodCall(con.baseService(), "/p1",
       
   592                                                       "local.BaseObject", "anotherMethod");
       
   593     QDBusMessage reply = con.call(msg, QDBus::Block);
       
   594     QCOMPARE(reply.type(), QDBusMessage::ReplyMessage);
       
   595     QVERIFY(reply.arguments().count() == 0);
       
   596 }
       
   597 
       
   598 void tst_QDBusConnection::slotsWithLessParameters()
       
   599 {
       
   600     QDBusConnection con = QDBusConnection::sessionBus();
       
   601 
       
   602     QDBusMessage signal = QDBusMessage::createSignal("/", "com.trolltech.TestCase",
       
   603                                                      "oneSignal");
       
   604     signal << "one parameter";
       
   605 
       
   606     signalsReceived = 0;
       
   607     QVERIFY(con.connect(con.baseService(), signal.path(), signal.interface(),
       
   608                         signal.member(), this, SLOT(oneSlot())));
       
   609     QVERIFY(con.send(signal));
       
   610     QTest::qWait(100);
       
   611     QCOMPARE(signalsReceived, 1);
       
   612 
       
   613     // disconnect and try with a signature
       
   614     signalsReceived = 0;
       
   615     QVERIFY(con.disconnect(con.baseService(), signal.path(), signal.interface(),
       
   616                            signal.member(), this, SLOT(oneSlot())));
       
   617     QVERIFY(con.connect(con.baseService(), signal.path(), signal.interface(),
       
   618                         signal.member(), "s", this, SLOT(oneSlot())));
       
   619     QVERIFY(con.send(signal));
       
   620     QTest::qWait(100);
       
   621     QCOMPARE(signalsReceived, 1);
       
   622 }
       
   623 
       
   624 void tst_QDBusConnection::secondCallWithCallback()
       
   625 {
       
   626     qDebug("Hello");
       
   627     QDBusConnection con = QDBusConnection::sessionBus();
       
   628     QDBusMessage msg = QDBusMessage::createMethodCall(con.baseService(), "/test", QString(),
       
   629                                                       "test0");
       
   630     con.callWithCallback(msg, this, SLOT(exitLoop()), SLOT(secondCallWithCallback()));
       
   631 }
       
   632 
       
   633 void tst_QDBusConnection::nestedCallWithCallback()
       
   634 {
       
   635     TestObject testObject;
       
   636     QDBusConnection connection = QDBusConnection::sessionBus();
       
   637     QVERIFY(connection.registerObject("/test", &testObject,
       
   638             QDBusConnection::ExportAllContents));
       
   639 
       
   640     QDBusMessage msg = QDBusMessage::createMethodCall(connection.baseService(), "/test", QString(),
       
   641                                                       "ThisFunctionDoesntExist");
       
   642     signalsReceived = 0;
       
   643 
       
   644     connection.callWithCallback(msg, this, SLOT(exitLoop()), SLOT(secondCallWithCallback()), 10);
       
   645     QTestEventLoop::instance().enterLoop(15);
       
   646     QVERIFY(!QTestEventLoop::instance().timeout());
       
   647     QCOMPARE(signalsReceived, 1);
       
   648 }
       
   649 
       
   650 QString MyObject::path;
       
   651 QTEST_MAIN(tst_QDBusConnection)
       
   652 
       
   653 #include "tst_qdbusconnection.moc"
       
   654