summaryrefslogtreecommitdiffstats
path: root/tests/auto/dbus
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@intel.com>2013-03-13 11:56:08 -0700
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-03-19 07:03:17 +0100
commitd2a98df9bcb113d9ef8ea0e7c1472875372706c7 (patch)
treea3c89ef0227a25bff5775ccbdad681f39274fd4c /tests/auto/dbus
parentd1b4857d1718ef50dba64c8700253fed5d187ab2 (diff)
Make sure that signal disconnects don't disconnect too much
There has been a latent bug forever in QtDBus that would make a signal disconnect actually disconnect too much. The reason is that disconnectNotify() is called every time a signal is disconnected from a receiver, but that doesn't mean it was the last connection. This test checks whether disconnecting from voidSignal() to our test receiver will also disconnect from exitLoop(). If it does, we'll get a timeout. I could have implemented it with two receivers, but in the buggy case, it would always fail first in the timeout verification. Change-Id: I5766d8a38594eb25e65b304913251303660fad41 Reviewed-by: Frederik Gladhorn <frederik.gladhorn@digia.com>
Diffstat (limited to 'tests/auto/dbus')
-rw-r--r--tests/auto/dbus/qdbusabstractinterface/tst_qdbusabstractinterface.cpp90
1 files changed, 90 insertions, 0 deletions
diff --git a/tests/auto/dbus/qdbusabstractinterface/tst_qdbusabstractinterface.cpp b/tests/auto/dbus/qdbusabstractinterface/tst_qdbusabstractinterface.cpp
index 89b91558ff..786592d018 100644
--- a/tests/auto/dbus/qdbusabstractinterface/tst_qdbusabstractinterface.cpp
+++ b/tests/auto/dbus/qdbusabstractinterface/tst_qdbusabstractinterface.cpp
@@ -159,6 +159,11 @@ private slots:
void followSignal();
+ void connectDisconnect_data();
+ void connectDisconnect();
+ void connectDisconnectPeer_data();
+ void connectDisconnectPeer();
+
void createErrors_data();
void createErrors();
@@ -196,6 +201,15 @@ private:
QProcess proc;
};
+class SignalReceiver : public QObject
+{
+ Q_OBJECT
+public:
+ int callCount;
+ SignalReceiver() : callCount(0) {}
+public slots:
+ void receive() { ++callCount; }
+};
tst_QDBusAbstractInterface::tst_QDBusAbstractInterface()
{
@@ -1022,6 +1036,82 @@ void tst_QDBusAbstractInterface::followSignal()
con.interface()->unregisterService(serviceToFollow);
}
+void tst_QDBusAbstractInterface::connectDisconnect_data()
+{
+ QTest::addColumn<int>("connectCount");
+ QTest::addColumn<int>("disconnectCount");
+
+ // we don't actually need multiple disconnects
+ // QObject::disconnect() disconnects all matching rules
+ // we'd have to use QMetaObject::disconnectOne if we wanted just one
+ QTest::newRow("null") << 0 << 0;
+ QTest::newRow("connect-disconnect") << 1 << 1;
+ QTest::newRow("connect-twice") << 2 << 0;
+ QTest::newRow("connect-twice-disconnect") << 2 << 1;
+}
+
+void tst_QDBusAbstractInterface::connectDisconnect()
+{
+ QFETCH(int, connectCount);
+ QFETCH(int, disconnectCount);
+
+ Pinger p = getPinger();
+ QVERIFY2(p, "Not connected to D-Bus");
+
+ // connect the exitLoop slot first
+ // if the disconnect() below does something weird, we'll get a timeout
+ QTestEventLoop::instance().connect(p.data(), SIGNAL(voidSignal()), SLOT(exitLoop()));
+
+ SignalReceiver sr;
+ for (int i = 0; i < connectCount; ++i)
+ sr.connect(p.data(), SIGNAL(voidSignal()), SLOT(receive()));
+ if (disconnectCount)
+ QObject::disconnect(p.data(), SIGNAL(voidSignal()), &sr, SLOT(receive()));
+
+ emit targetObj.voidSignal();
+ QTestEventLoop::instance().enterLoop(2);
+ QVERIFY(!QTestEventLoop::instance().timeout());
+
+ if (disconnectCount != 0)
+ QCOMPARE(sr.callCount, 0);
+ else
+ QCOMPARE(sr.callCount, connectCount);
+}
+
+void tst_QDBusAbstractInterface::connectDisconnectPeer_data()
+{
+ connectDisconnect_data();
+}
+
+void tst_QDBusAbstractInterface::connectDisconnectPeer()
+{
+ QFETCH(int, connectCount);
+ QFETCH(int, disconnectCount);
+
+ Pinger p = getPingerPeer();
+ QVERIFY2(p, "Not connected to D-Bus");
+
+ // connect the exitLoop slot first
+ // if the disconnect() below does something weird, we'll get a timeout
+ QTestEventLoop::instance().connect(p.data(), SIGNAL(voidSignal()), SLOT(exitLoop()));
+
+ SignalReceiver sr;
+ for (int i = 0; i < connectCount; ++i)
+ sr.connect(p.data(), SIGNAL(voidSignal()), SLOT(receive()));
+ if (disconnectCount)
+ QObject::disconnect(p.data(), SIGNAL(voidSignal()), &sr, SLOT(receive()));
+
+ QDBusMessage req = QDBusMessage::createMethodCall(serviceName, objectPath, interfaceName, "voidSignal");
+ QVERIFY(QDBusConnection::sessionBus().send(req));
+ QTestEventLoop::instance().enterLoop(2);
+ QVERIFY(!QTestEventLoop::instance().timeout());
+
+ if (disconnectCount != 0)
+ QCOMPARE(sr.callCount, 0);
+ else
+ QCOMPARE(sr.callCount, connectCount);
+}
+
void tst_QDBusAbstractInterface::createErrors_data()
{
QTest::addColumn<QString>("service");