diff options
author | Thiago Macieira <thiago.macieira@nokia.com> | 2010-02-24 19:04:23 (GMT) |
---|---|---|
committer | Thiago Macieira <thiago.macieira@nokia.com> | 2010-02-24 19:04:23 (GMT) |
commit | bf5e8a646071abae8bd2111ff75b1eae52874fed (patch) | |
tree | dfac8755a0e5fc1fba14b206851ede95561b71cd | |
parent | 43a80c98d4eb281594da14160683b73470574b7e (diff) | |
download | Qt-bf5e8a646071abae8bd2111ff75b1eae52874fed.zip Qt-bf5e8a646071abae8bd2111ff75b1eae52874fed.tar.gz Qt-bf5e8a646071abae8bd2111ff75b1eae52874fed.tar.bz2 |
Autotest: add a test for QDBusPendingCallWatcher use in threads
I'm satisfied that the finished() signal won't be emitted until the
event loop is run, or waitForFinished() is called.
However, I'm not fully convinced that there isn't a race condition if
you try to waitForFinished() right away. Needs more investigation.
-rw-r--r-- | tests/auto/qdbuspendingcall/tst_qdbuspendingcall.cpp | 57 |
1 files changed, 56 insertions, 1 deletions
diff --git a/tests/auto/qdbuspendingcall/tst_qdbuspendingcall.cpp b/tests/auto/qdbuspendingcall/tst_qdbuspendingcall.cpp index 7208383..54426ce 100644 --- a/tests/auto/qdbuspendingcall/tst_qdbuspendingcall.cpp +++ b/tests/auto/qdbuspendingcall/tst_qdbuspendingcall.cpp @@ -41,6 +41,7 @@ #include <QtCore/QObject> #include <QtCore/QVariant> #include <QtCore/QList> +#include <QtCore/QThread> #include <QtCore/QVector> #include <QtTest/QtTest> #ifndef QT_NO_DBUS @@ -90,6 +91,7 @@ private Q_SLOTS: void watcher(); void watcher_error(); void watcher_waitForFinished(); + void watcher_waitForFinished_threaded(); void watcher_waitForFinished_alreadyFinished(); void watcher_waitForFinished_alreadyFinished_eventLoop(); void watcher_waitForFinished_error(); @@ -124,7 +126,10 @@ void tst_QDBusPendingCall::finished(QDBusPendingCallWatcher *call) slotCalled = FinishCalled; ++callCount; watchArgument = call; - QTestEventLoop::instance().exitLoop(); + if (QThread::currentThread() == thread()) + QTestEventLoop::instance().exitLoop(); + else + QMetaObject::invokeMethod(&QTestEventLoop::instance(), "exitLoop", Qt::QueuedConnection); } void tst_QDBusPendingCall::callback(const QStringList &list) @@ -377,6 +382,56 @@ void tst_QDBusPendingCall::watcher_waitForFinished() QVERIFY(args2.at(0).toStringList().contains(conn.baseService())); } +void tst_QDBusPendingCall::watcher_waitForFinished_threaded() +{ + callCount = 0; + watchArgument = 0; + slotCalled = 0; + + class WorkerThread: public QThread { + public: + tst_QDBusPendingCall *tst; + WorkerThread(tst_QDBusPendingCall *tst) : tst(tst) {} + void run() + { + QDBusPendingCall ac = tst->sendMessage(); +// QVERIFY(!ac.isFinished()); +// QVERIFY(!ac.isError()); +// QVERIFY(ac.reply().type() == QDBusMessage::InvalidMessage); + + QDBusPendingCallWatcher watch(ac); + tst->connect(&watch, SIGNAL(finished(QDBusPendingCallWatcher*)), + SLOT(finished(QDBusPendingCallWatcher*)), Qt::DirectConnection); + + QTest::qSleep(100); // don't process events in this thread + +// QVERIFY(!ac.isFinished()); +// QVERIFY(!ac.isError()); +// QVERIFY(ac.reply().type() == QDBusMessage::InvalidMessage); + QCOMPARE(tst->callCount, 0); + QCOMPARE(tst->slotCalled, 0); + + watch.waitForFinished(); + QVERIFY(ac.isFinished()); + QVERIFY(!ac.isError()); + + QCOMPARE(tst->callCount, 1); + QCOMPARE(tst->slotCalled, (int)FinishCalled); + QCOMPARE(tst->watchArgument, &watch); + QVERIFY(!watch.isError()); + + const QVariantList args2 = ac.reply().arguments(); + QVERIFY(!args2.isEmpty()); + QVERIFY(args2.at(0).toStringList().contains(tst->conn.baseService())); + } + } thread(this); + QTestEventLoop::instance().connect(&thread, SIGNAL(finished()), SLOT(exitLoop())); + thread.start(); + QTestEventLoop::instance().enterLoop(1000); + QVERIFY(!thread.isRunning()); + QVERIFY(!QTestEventLoop::instance().timeout()); +} + void tst_QDBusPendingCall::watcher_waitForFinished_alreadyFinished() { QDBusPendingCall ac = sendMessage(); |