summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorIevgenii Meshcheriakov <ievgenii.meshcheriakov@qt.io>2023-05-02 15:25:51 +0200
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2023-05-11 17:58:24 +0000
commitff580c2014d260732ab5f21e14a9845ebcee1302 (patch)
tree868aa3b1a8f5374f776571ecac1d325b4c38e152 /tests
parenta22899fe27400d5748f5ee7c2b9f2d106e9156ea (diff)
QDBusConnectionPrivate: Fix handling of queued messages
Handle any queued messages before attempting to dispatch any newly received messages. This ensures that messages are processed in the order they were sent. Add a regression test for this bug using code adapted from the bug report by Pascal Weisser. Because of the nature of the bug, this new test does not always fail even when compiled with affected versions of Qt though. Fixes: QTBUG-105457 Change-Id: I2725f3450ad537d63d6660e21645ac2c578e1768 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> (cherry picked from commit 859ef056331a94fb0b1e4b41f596ff78539dfd8b) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
Diffstat (limited to 'tests')
-rw-r--r--tests/auto/dbus/CMakeLists.txt1
-rw-r--r--tests/auto/dbus/qdbusconnection_signalorder/CMakeLists.txt13
-rw-r--r--tests/auto/dbus/qdbusconnection_signalorder/tst_qdbusconnection_signalorder.cpp103
3 files changed, 117 insertions, 0 deletions
diff --git a/tests/auto/dbus/CMakeLists.txt b/tests/auto/dbus/CMakeLists.txt
index 6ca0eb050e..d67877a0b3 100644
--- a/tests/auto/dbus/CMakeLists.txt
+++ b/tests/auto/dbus/CMakeLists.txt
@@ -6,6 +6,7 @@ add_subdirectory(qdbusconnection)
add_subdirectory(qdbusconnection_no_app)
add_subdirectory(qdbusconnection_no_bus)
add_subdirectory(qdbusconnection_no_libdbus)
+add_subdirectory(qdbusconnection_signalorder)
add_subdirectory(qdbusconnection_spyhook)
add_subdirectory(qdbuscontext)
add_subdirectory(qdbuslocalcalls)
diff --git a/tests/auto/dbus/qdbusconnection_signalorder/CMakeLists.txt b/tests/auto/dbus/qdbusconnection_signalorder/CMakeLists.txt
new file mode 100644
index 0000000000..32dda2f3f3
--- /dev/null
+++ b/tests/auto/dbus/qdbusconnection_signalorder/CMakeLists.txt
@@ -0,0 +1,13 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+#####################################################################
+## tst_qdbusconnection_signalorder Test:
+#####################################################################
+
+qt_internal_add_test(tst_qdbusconnection_signalorder
+ SOURCES
+ tst_qdbusconnection_signalorder.cpp
+ LIBRARIES
+ Qt::DBus
+)
diff --git a/tests/auto/dbus/qdbusconnection_signalorder/tst_qdbusconnection_signalorder.cpp b/tests/auto/dbus/qdbusconnection_signalorder/tst_qdbusconnection_signalorder.cpp
new file mode 100644
index 0000000000..dd21ecec5f
--- /dev/null
+++ b/tests/auto/dbus/qdbusconnection_signalorder/tst_qdbusconnection_signalorder.cpp
@@ -0,0 +1,103 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#include <QCoreApplication>
+#include <QDBusConnection>
+#include <QDBusMessage>
+#include <QObject>
+#include <QTest>
+#include <QTimer>
+
+using namespace Qt::StringLiterals;
+
+static constexpr int MAX_TEST_DURATION_MS = 10000;
+static constexpr int NUM_MESSAGES = 20;
+
+class SignalReceiver : public QObject
+{
+ Q_OBJECT
+public:
+ explicit SignalReceiver(QDBusConnection &connection, const QString &serviceName);
+
+ int nextValue() const { return m_nextValue; }
+ bool inOrder() const { return m_inOrder; }
+
+Q_SIGNALS:
+ void testSignal(int);
+ void done();
+
+private Q_SLOTS:
+ void testSlot(int number);
+
+private:
+ int m_nextValue = 0;
+ bool m_inOrder = true;
+};
+
+SignalReceiver::SignalReceiver(QDBusConnection &connection, const QString &serviceName)
+{
+ connection.connect(serviceName, "/", {}, "testSignal", this, SLOT(testSlot(int)));
+}
+
+void SignalReceiver::testSlot(int number)
+{
+ if (m_nextValue != number) {
+ m_inOrder = false;
+ qWarning("Message out of sequence, expected: %d, received: %d", m_nextValue, number);
+ }
+
+ m_nextValue++;
+
+ if (m_nextValue == NUM_MESSAGES) {
+ Q_EMIT done();
+ }
+}
+
+class tst_QDBusConnection_SignalOrder : public QObject
+{
+ Q_OBJECT
+private Q_SLOTS:
+ void signalOrder();
+};
+
+// This is a regression test for QTBUG-105457. The bug is a race condition,
+// so it cannot be reliably triggered at each test execution.
+void tst_QDBusConnection_SignalOrder::signalOrder()
+{
+ int argc = 1;
+ static char appName[] = "tst_qdbusconnection_signalorder";
+ char *argv[] = { appName, 0 };
+ QCoreApplication app(argc, argv);
+
+ const QString serviceName =
+ u"org.qtproject.tst_dbusconnection_signalorder_%1"_s.arg(app.applicationPid());
+
+ auto connection = QDBusConnection::sessionBus();
+
+ QVERIFY(connection.isConnected());
+ QVERIFY(connection.registerService(serviceName));
+
+ // Limit the test execution time in case if something goes wrong inside
+ // the signal receiver.
+ QTimer::singleShot(MAX_TEST_DURATION_MS, &app, &QCoreApplication::quit);
+
+ SignalReceiver signalReceiver(connection, serviceName);
+ connect(&signalReceiver, &SignalReceiver::done, &app, &QCoreApplication::quit);
+
+ QVERIFY(connection.registerObject("/", &signalReceiver, QDBusConnection::ExportAllSlots));
+
+ for (int i = 0; i < NUM_MESSAGES; i++) {
+ auto testSignal = QDBusMessage::createSignal("/", serviceName, "testSignal");
+ testSignal << i;
+ QVERIFY(connection.send(testSignal));
+ }
+
+ app.exec();
+
+ QVERIFY(signalReceiver.inOrder());
+ QCOMPARE(signalReceiver.nextValue(), NUM_MESSAGES);
+}
+
+QTEST_APPLESS_MAIN(tst_QDBusConnection_SignalOrder)
+
+#include "tst_qdbusconnection_signalorder.moc"