summaryrefslogtreecommitdiffstats
path: root/tests/auto/qdbusconnection
diff options
context:
space:
mode:
authorFrederik Gladhorn <frederik.gladhorn@nokia.com>2011-05-22 19:36:10 (GMT)
committerFrederik Gladhorn <frederik.gladhorn@nokia.com>2011-07-04 11:44:14 (GMT)
commitb07919b3de8cff3e44b7271062372b14bcda5b83 (patch)
treefb6e9c5ebbade0756b85819b59eb3efcf0ee242d /tests/auto/qdbusconnection
parentcee1f6454a7b52a52795590e2f793c0cd4e15ce1 (diff)
downloadQt-b07919b3de8cff3e44b7271062372b14bcda5b83.zip
Qt-b07919b3de8cff3e44b7271062372b14bcda5b83.tar.gz
Qt-b07919b3de8cff3e44b7271062372b14bcda5b83.tar.bz2
Add DBus VirtualObject to handle multiple paths.
When a virtual object is registered with the SubPath option it will handle all dbus calls to itself and all child paths. It needs to reimplement handleMessage for that purpose. Introspection needs to be implemented manually in the introspect function. Reviewed-by: Thiago Macieira <thiago.macieira@nokia.com>
Diffstat (limited to 'tests/auto/qdbusconnection')
-rw-r--r--tests/auto/qdbusconnection/tst_qdbusconnection.cpp202
1 files changed, 201 insertions, 1 deletions
diff --git a/tests/auto/qdbusconnection/tst_qdbusconnection.cpp b/tests/auto/qdbusconnection/tst_qdbusconnection.cpp
index e06e3a8..6490bfe 100644
--- a/tests/auto/qdbusconnection/tst_qdbusconnection.cpp
+++ b/tests/auto/qdbusconnection/tst_qdbusconnection.cpp
@@ -113,6 +113,10 @@ private slots:
void serviceRegistrationRaceCondition();
+ void registerVirtualObject();
+ void callVirtualObject();
+ void callVirtualObjectLocal();
+
public:
QString serviceName() const { return "com.trolltech.Qt.Autotests.QDBusConnection"; }
bool callMethod(const QDBusConnection &conn, const QString &path);
@@ -823,7 +827,6 @@ bool tst_QDBusConnection::callMethod(const QDBusConnection &conn, const QString
{
QDBusMessage msg = QDBusMessage::createMethodCall(conn.baseService(), path, "", "method");
QDBusMessage reply = conn.call(msg, QDBus::Block/*WithGui*/);
-
if (reply.type() != QDBusMessage::ReplyMessage)
return false;
if (MyObject::path == path) {
@@ -1098,6 +1101,203 @@ void tst_QDBusConnection::serviceRegistrationRaceCondition()
QCOMPARE(recv.count, 1);
}
+class VirtualObject: public QDBusVirtualObject
+{
+ Q_OBJECT
+public:
+ VirtualObject() :success(true) {}
+
+ QString introspect(const QString &path) const
+ {
+ return QString();
+ }
+
+ bool handleMessage(const QDBusMessage &message, const QDBusConnection &connection) {
+ ++callCount;
+ lastMessage = message;
+
+ if (success) {
+ QDBusMessage reply = message.createReply(replyArguments);
+ connection.send(reply);
+ }
+ emit messageReceived(message);
+ return success;
+ }
+signals:
+ void messageReceived(const QDBusMessage &message) const;
+
+public:
+ mutable QDBusMessage lastMessage;
+ QVariantList replyArguments;
+ mutable int callCount;
+ bool success;
+};
+
+
+void tst_QDBusConnection::registerVirtualObject()
+{
+ QDBusConnection con = QDBusConnection::sessionBus();
+ QVERIFY(con.isConnected());
+
+ QString path = "/tree/node";
+ QString childPath = "/tree/node/child";
+ QString childChildPath = "/tree/node/child/another";
+
+ {
+ // Register VirtualObject that handles child paths. Unregister by going out of scope.
+ VirtualObject obj;
+ QVERIFY(con.registerVirtualObject(path, &obj, QDBusConnection::SubPath));
+ QCOMPARE(con.objectRegisteredAt(path), static_cast<QObject *>(&obj));
+ QCOMPARE(con.objectRegisteredAt(childPath), static_cast<QObject *>(&obj));
+ QCOMPARE(con.objectRegisteredAt(childChildPath), static_cast<QObject *>(&obj));
+ }
+ QCOMPARE(con.objectRegisteredAt(path), static_cast<QObject *>(0));
+ QCOMPARE(con.objectRegisteredAt(childPath), static_cast<QObject *>(0));
+
+ {
+ // Register VirtualObject that handles child paths. Unregister by calling unregister.
+ VirtualObject obj;
+ QVERIFY(con.registerVirtualObject(path, &obj, QDBusConnection::SubPath));
+ QCOMPARE(con.objectRegisteredAt(path), static_cast<QObject *>(&obj));
+ QCOMPARE(con.objectRegisteredAt(childPath), static_cast<QObject *>(&obj));
+ QCOMPARE(con.objectRegisteredAt(childChildPath), static_cast<QObject *>(&obj));
+ con.unregisterObject(path);
+ QCOMPARE(con.objectRegisteredAt(path), static_cast<QObject *>(0));
+ QCOMPARE(con.objectRegisteredAt(childPath), static_cast<QObject *>(0));
+ }
+
+ {
+ // Single node has no sub path handling.
+ VirtualObject obj;
+ QVERIFY(con.registerVirtualObject(path, &obj, QDBusConnection::SingleNode));
+ QCOMPARE(con.objectRegisteredAt(path), static_cast<QObject *>(&obj));
+ QCOMPARE(con.objectRegisteredAt(childPath), static_cast<QObject *>(0));
+ }
+
+ {
+ // Register VirtualObject that handles child paths. Try to register an object on a child path of that.
+ VirtualObject obj;
+ QVERIFY(con.registerVirtualObject(path, &obj, QDBusConnection::SubPath));
+ QCOMPARE(con.objectRegisteredAt(path), static_cast<QObject *>(&obj));
+
+ QObject objectAtSubPath;
+ QVERIFY(!con.registerObject(path, &objectAtSubPath));
+ QVERIFY(!con.registerObject(childPath, &objectAtSubPath));
+ QCOMPARE(con.objectRegisteredAt(childPath), static_cast<QObject *>(&obj));
+ }
+
+ {
+ // Register object, make sure no SubPath handling object can be registered on a parent path.
+ QObject objectAtSubPath;
+ QVERIFY(con.registerObject(childPath, &objectAtSubPath));
+ QCOMPARE(con.objectRegisteredAt(childPath), static_cast<QObject *>(&objectAtSubPath));
+
+ VirtualObject obj;
+ QVERIFY(!con.registerVirtualObject(path, &obj, QDBusConnection::SubPath));
+ QCOMPARE(con.objectRegisteredAt(path), static_cast<QObject *>(0));
+ }
+ QCOMPARE(con.objectRegisteredAt(path), static_cast<QObject *>(0));
+ QCOMPARE(con.objectRegisteredAt(childPath), static_cast<QObject *>(0));
+ QCOMPARE(con.objectRegisteredAt(childChildPath), static_cast<QObject *>(0));
+}
+
+void tst_QDBusConnection::callVirtualObject()
+{
+ QDBusConnection con = QDBusConnection::sessionBus();
+ QVERIFY(con.isConnected());
+
+ QDBusConnection con2 = QDBusConnection::connectToBus(QDBusConnection::SessionBus, "con2");
+
+ QString path = "/tree/node";
+ QString childPath = "/tree/node/child";
+
+ // register one object at root:
+ VirtualObject obj;
+ QVERIFY(con.registerVirtualObject(path, &obj, QDBusConnection::SubPath));
+ obj.callCount = 0;
+ obj.replyArguments << 42 << 47u;
+
+ QObject::connect(&obj, SIGNAL(messageReceived(QDBusMessage)), &QTestEventLoop::instance(), SLOT(exitLoop()));
+
+ QDBusMessage message = QDBusMessage::createMethodCall(con.baseService(), path, QString(), "hello");
+ QDBusPendingCall reply = con2.asyncCall(message);
+
+ QTestEventLoop::instance().enterLoop(5);
+ QVERIFY(!QTestEventLoop::instance().timeout());
+
+ QCOMPARE(obj.callCount, 1);
+ QCOMPARE(obj.lastMessage.service(), con2.baseService());
+ QCOMPARE(obj.lastMessage.interface(), QString());
+ QCOMPARE(obj.lastMessage.path(), path);
+ reply.waitForFinished();
+ QVERIFY(reply.isValid());
+ QCOMPARE(reply.reply().arguments(), obj.replyArguments);
+
+ // call sub path
+ QDBusMessage childMessage = QDBusMessage::createMethodCall(con.baseService(), childPath, QString(), "helloChild");
+ obj.replyArguments.clear();
+ obj.replyArguments << 99;
+ QDBusPendingCall childReply = con2.asyncCall(childMessage);
+
+ QTestEventLoop::instance().enterLoop(5);
+ QVERIFY(!QTestEventLoop::instance().timeout());
+
+ QCOMPARE(obj.callCount, 2);
+ QCOMPARE(obj.lastMessage.service(), con2.baseService());
+ QCOMPARE(obj.lastMessage.interface(), QString());
+ QCOMPARE(obj.lastMessage.path(), childPath);
+
+ childReply.waitForFinished();
+ QVERIFY(childReply.isValid());
+ QCOMPARE(childReply.reply().arguments(), obj.replyArguments);
+
+ // let the call fail by having the virtual object return false
+ obj.success = false;
+ QDBusMessage errorMessage = QDBusMessage::createMethodCall(con.baseService(), childPath, QString(), "someFunc");
+ QDBusPendingCall errorReply = con2.asyncCall(errorMessage);
+
+ QTestEventLoop::instance().enterLoop(5);
+ QVERIFY(!QTestEventLoop::instance().timeout());
+ QTest::qWait(100);
+ QVERIFY(errorReply.isError());
+ qDebug() << errorReply.reply().arguments();
+ QCOMPARE(errorReply.reply().errorName(), QString("org.freedesktop.DBus.Error.UnknownObject"));
+
+ QDBusConnection::disconnectFromBus("con2");
+}
+
+void tst_QDBusConnection::callVirtualObjectLocal()
+{
+ QDBusConnection con = QDBusConnection::sessionBus();
+ QVERIFY(con.isConnected());
+
+ QString path = "/tree/node";
+ QString childPath = "/tree/node/child";
+
+ // register one object at root:
+ VirtualObject obj;
+ QVERIFY(con.registerVirtualObject(path, &obj, QDBusConnection::SubPath));
+ obj.callCount = 0;
+ obj.replyArguments << 42 << 47u;
+
+ QDBusMessage message = QDBusMessage::createMethodCall(con.baseService(), path, QString(), "hello");
+ QDBusMessage reply = con.call(message, QDBus::Block, 5000);
+ QCOMPARE(obj.callCount, 1);
+ QCOMPARE(obj.lastMessage.service(), con.baseService());
+ QCOMPARE(obj.lastMessage.interface(), QString());
+ QCOMPARE(obj.lastMessage.path(), path);
+ QCOMPARE(obj.replyArguments, reply.arguments());
+
+ obj.replyArguments << QString("alien abduction");
+ QDBusMessage subPathMessage = QDBusMessage::createMethodCall(con.baseService(), childPath, QString(), "hello");
+ QDBusMessage subPathReply = con.call(subPathMessage , QDBus::Block, 5000);
+ QCOMPARE(obj.callCount, 2);
+ QCOMPARE(obj.lastMessage.service(), con.baseService());
+ QCOMPARE(obj.lastMessage.interface(), QString());
+ QCOMPARE(obj.lastMessage.path(), childPath);
+ QCOMPARE(obj.replyArguments, subPathReply.arguments());
+}
+
QString MyObject::path;
QTEST_MAIN(tst_QDBusConnection)