summaryrefslogtreecommitdiffstats
path: root/tests/auto/dbus
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@intel.com>2016-06-02 10:46:36 -0300
committerTony Sarajärvi <tony.sarajarvi@qt.io>2016-06-06 11:39:53 +0000
commitf8b5142e3068d210393e7e4544c2e63577a313ac (patch)
tree6f4c10a70c4b953ecf6ab29584adaad188f614fa /tests/auto/dbus
parentd5ac97e36fb35761576f25c84372d5c477189a0f (diff)
Fix race condition in tst_QDBusConnection::pendingCallWhenDisconnected
The test sent a message and hoped that the "delete server" would cause the server object in the QDBusConnectionManager thread be deleted before it could receive and process the message. That's racy, because on some CI machines, it did and then sent back an error reply indicating the object sought was not found. Instead, let's use a child process that we can kill to make it exit at the right time. I've chosen to use dbus-daemon itself, because that lets us test the actual conditions that triggered the original bug: the daemon getting killed during a desktop session shutdown on Linux. Change-Id: I87e17314d8b24ae983b1fffd1454483aea87c921 Reviewed-by: Tony Sarajärvi <tony.sarajarvi@qt.io>
Diffstat (limited to 'tests/auto/dbus')
-rw-r--r--tests/auto/dbus/qdbusconnection/tst_qdbusconnection.cpp39
1 files changed, 30 insertions, 9 deletions
diff --git a/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.cpp b/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.cpp
index 9b16cf74a5..8dc94d3e07 100644
--- a/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.cpp
+++ b/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.cpp
@@ -40,6 +40,11 @@
#include <QtTest/QtTest>
#include <QtDBus/QtDBus>
+#ifdef Q_OS_UNIX
+# include <sys/types.h>
+# include <signal.h>
+#endif
+
void MyObject::method(const QDBusMessage &msg)
{
path = msg.path();
@@ -1357,23 +1362,39 @@ void tst_QDBusConnection::callVirtualObjectLocal()
void tst_QDBusConnection::pendingCallWhenDisconnected()
{
+#ifdef QT_NO_PROCESS
+ QSKIP("Test requires QProcess");
+#else
if (!QCoreApplication::instance())
QSKIP("Test requires a QCoreApplication");
- QDBusServer *server = new QDBusServer;
- QDBusConnection con = QDBusConnection::connectToPeer(server->address(), "disconnect");
- QTestEventLoop::instance().enterLoop(2);
- QVERIFY(con.isConnected());
- QDBusMessage message = QDBusMessage::createMethodCall("", "/", QString(), "method");
- QDBusPendingCall reply = con.asyncCall(message);
+ QProcess daemon;
+ daemon.start("dbus-daemon", QStringList() << "--session" << "--nofork" << "--print-address");
+ QVERIFY2(daemon.waitForReadyRead(2000),
+ "Daemon didn't print its address in time; error: \"" + daemon.errorString().toLocal8Bit() +
+ "\"; stderr:\n" + daemon.readAllStandardError());
- delete server;
+ QString address = QString::fromLocal8Bit(daemon.readAll().trimmed());
+ QDBusConnection con = QDBusConnection::connectToBus(address, "disconnect");
+ QVERIFY2(con.isConnected(), (con.lastError().name() + ": " + con.lastError().message()).toLocal8Bit());
- QTestEventLoop::instance().enterLoop(2);
+ // confirm we're connected and we're alone in this bus
+ QCOMPARE(con.baseService(), QString(":1.0"));
+
+ // kill the bus
+ daemon.terminate();
+ daemon.waitForFinished();
+
+ // send something, which we should get an error with
+ QDBusMessage message = QDBusMessage::createMethodCall("org.freedesktop.DBus", "/", QString(), "ListNames");
+ QDBusPendingCall reply = con.asyncCall(message);
+
+ reply.waitForFinished();
QVERIFY(!con.isConnected());
QVERIFY(reply.isFinished());
QVERIFY(reply.isError());
- QVERIFY(reply.error().type() == QDBusError::Disconnected);
+ QCOMPARE(reply.error().type(), QDBusError::Disconnected);
+#endif
}
QString MyObject::path;