diff options
Diffstat (limited to 'tests/auto/corelib/thread')
-rw-r--r-- | tests/auto/corelib/thread/CMakeLists.txt | 24 | ||||
-rw-r--r-- | tests/auto/corelib/thread/qfuture/CMakeLists.txt | 1 | ||||
-rw-r--r-- | tests/auto/corelib/thread/qfuture/tst_qfuture.cpp | 28 | ||||
-rw-r--r-- | tests/auto/corelib/thread/qresultstore/CMakeLists.txt | 1 | ||||
-rw-r--r-- | tests/auto/corelib/thread/qresultstore/tst_qresultstore.cpp | 33 | ||||
-rw-r--r-- | tests/auto/corelib/thread/qthread/tst_qthread.cpp | 74 |
6 files changed, 113 insertions, 48 deletions
diff --git a/tests/auto/corelib/thread/CMakeLists.txt b/tests/auto/corelib/thread/CMakeLists.txt index 68110b652b..d25d0205f5 100644 --- a/tests/auto/corelib/thread/CMakeLists.txt +++ b/tests/auto/corelib/thread/CMakeLists.txt @@ -17,11 +17,20 @@ if(QT_FEATURE_thread) add_subdirectory(qatomicint) add_subdirectory(qatomicinteger) add_subdirectory(qatomicpointer) - add_subdirectory(qresultstore) - if(QT_FEATURE_concurrent AND NOT INTEGRITY) - add_subdirectory(qfuture) + if(QT_FEATURE_future) + if(QT_FEATURE_concurrent AND NOT INTEGRITY) + add_subdirectory(qfuture) + endif() + add_subdirectory(qresultstore) + add_subdirectory(qfuturesynchronizer) + if(NOT INTEGRITY) + add_subdirectory(qpromise) + endif() + # QTBUG-87431 + if(TARGET Qt::Concurrent AND NOT INTEGRITY) + add_subdirectory(qfuturewatcher) + endif() endif() - add_subdirectory(qfuturesynchronizer) add_subdirectory(qmutex) add_subdirectory(qmutexlocker) add_subdirectory(qreadlocker) @@ -36,12 +45,5 @@ if(QT_FEATURE_thread) add_subdirectory(qthreadstorage) add_subdirectory(qwaitcondition) add_subdirectory(qwritelocker) - if(NOT INTEGRITY) - add_subdirectory(qpromise) - endif() endif() -# QTBUG-87431 -if(TARGET Qt::Concurrent AND NOT INTEGRITY) - add_subdirectory(qfuturewatcher) -endif() diff --git a/tests/auto/corelib/thread/qfuture/CMakeLists.txt b/tests/auto/corelib/thread/qfuture/CMakeLists.txt index aa989f3df1..ba5730d5cf 100644 --- a/tests/auto/corelib/thread/qfuture/CMakeLists.txt +++ b/tests/auto/corelib/thread/qfuture/CMakeLists.txt @@ -16,6 +16,7 @@ qt_internal_add_test(tst_qfuture tst_qfuture.cpp LIBRARIES Qt::CorePrivate + Qt::TestPrivate ) qt_internal_extend_target(tst_qfuture CONDITION MSVC diff --git a/tests/auto/corelib/thread/qfuture/tst_qfuture.cpp b/tests/auto/corelib/thread/qfuture/tst_qfuture.cpp index 3fc796514d..4cb29c514a 100644 --- a/tests/auto/corelib/thread/qfuture/tst_qfuture.cpp +++ b/tests/auto/corelib/thread/qfuture/tst_qfuture.cpp @@ -17,6 +17,7 @@ #include <private/qobject_p.h> #include <QTest> +#include <QtTest/private/qcomparisontesthelper_p.h> #include <qfuture.h> #include <qfuturewatcher.h> #include <qresultstore.h> @@ -161,6 +162,7 @@ class tst_QFuture: public QObject { Q_OBJECT private slots: + void compareCompiles(); void resultStore(); void future(); void futureToVoid(); @@ -273,6 +275,12 @@ private: QtPrivate::ResultStoreBase &store; }; +void tst_QFuture::compareCompiles() +{ + QTestPrivate::testEqualityOperatorsCompile<QFuture<int>::const_iterator>(); + QTestPrivate::testEqualityOperatorsCompile<QFuture<QString>::const_iterator>(); +} + void tst_QFuture::resultStore() { int int0 = 0; @@ -1359,16 +1367,16 @@ void tst_QFuture::iterators() QFuture<int>::const_iterator i1 = f.begin(), i2 = i1 + 1; QFuture<int>::const_iterator c1 = i1, c2 = c1 + 1; - QCOMPARE(i1, i1); - QCOMPARE(i1, c1); - QCOMPARE(c1, i1); - QCOMPARE(c1, c1); - QCOMPARE(i2, i2); - QCOMPARE(i2, c2); - QCOMPARE(c2, i2); - QCOMPARE(c2, c2); - QCOMPARE(1 + i1, i1 + 1); - QCOMPARE(1 + c1, c1 + 1); + QT_TEST_EQUALITY_OPS(i1, i1, true); + QT_TEST_EQUALITY_OPS(i1, c1, true); + QT_TEST_EQUALITY_OPS(c1, i1, true); + QT_TEST_EQUALITY_OPS(c1, c1, true); + QT_TEST_EQUALITY_OPS(i2, i2, true); + QT_TEST_EQUALITY_OPS(i2, c2, true); + QT_TEST_EQUALITY_OPS(c2, i2, true); + QT_TEST_EQUALITY_OPS(c2, c2, true); + QT_TEST_EQUALITY_OPS(1 + i1, i1 + 1, true); + QT_TEST_EQUALITY_OPS(1 + c1, c1 + 1, true); QVERIFY(i1 != i2); QVERIFY(i1 != c2); diff --git a/tests/auto/corelib/thread/qresultstore/CMakeLists.txt b/tests/auto/corelib/thread/qresultstore/CMakeLists.txt index 0f9d8d9e52..5abfc14ac6 100644 --- a/tests/auto/corelib/thread/qresultstore/CMakeLists.txt +++ b/tests/auto/corelib/thread/qresultstore/CMakeLists.txt @@ -16,4 +16,5 @@ qt_internal_add_test(tst_qresultstore tst_qresultstore.cpp LIBRARIES Qt::CorePrivate + Qt::TestPrivate ) diff --git a/tests/auto/corelib/thread/qresultstore/tst_qresultstore.cpp b/tests/auto/corelib/thread/qresultstore/tst_qresultstore.cpp index 265b2cd1f6..722184a72a 100644 --- a/tests/auto/corelib/thread/qresultstore/tst_qresultstore.cpp +++ b/tests/auto/corelib/thread/qresultstore/tst_qresultstore.cpp @@ -2,7 +2,7 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <QTest> - +#include <QtTest/private/qcomparisontesthelper_p.h> #include <qresultstore.h> using namespace QtPrivate; @@ -23,6 +23,7 @@ class tst_QtConcurrentResultStore : public QObject public slots: void init(); private slots: + void compareCompiles(); void construction(); void iterators(); void addResult(); @@ -52,6 +53,11 @@ void tst_QtConcurrentResultStore::init() vec1 = QList<int> { 4, 5 }; } +void tst_QtConcurrentResultStore::compareCompiles() +{ + QTestPrivate::testEqualityOperatorsCompile<ResultIteratorBase>(); +} + void tst_QtConcurrentResultStore::construction() { ResultStoreBase store; @@ -74,17 +80,20 @@ void tst_QtConcurrentResultStore::iterators() storebase.addResult(1, &int1); // ResultStoreBase does not take ownership, only ResultStore<> does. ResultIteratorBase it = storebase.begin(); QCOMPARE(it.resultIndex(), 0); - QCOMPARE(it, storebase.begin()); + QT_TEST_EQUALITY_OPS(it, storebase.begin(), true); QVERIFY(it != storebase.end()); ++it; QCOMPARE(it.resultIndex(), 1); QVERIFY(it != storebase.begin()); QVERIFY(it != storebase.end()); + QT_TEST_EQUALITY_OPS(it, storebase.begin(), false); + QT_TEST_EQUALITY_OPS(it, storebase.end(), false); ++it; QVERIFY(it != storebase.begin()); QCOMPARE(it, storebase.end()); + QT_TEST_EQUALITY_OPS(it, storebase.end(), true); } } @@ -147,8 +156,8 @@ void tst_QtConcurrentResultStore::addResults() store.addResults(-1, &vec1); ResultIteratorBase it = store.begin(); QCOMPARE(it.resultIndex(), 0); - QCOMPARE(it, store.begin()); - QVERIFY(it != store.end()); + QT_TEST_EQUALITY_OPS(it, store.begin(), true); + QT_TEST_EQUALITY_OPS(it, store.end(), false); ++it; QCOMPARE(it.resultIndex(), 1); @@ -162,7 +171,7 @@ void tst_QtConcurrentResultStore::addResults() QCOMPARE(it.resultIndex(), 3); ++it; - QCOMPARE(it, store.end()); + QT_TEST_EQUALITY_OPS(it, store.end(), true); QList<int> empty; const auto countBefore = store.count(); @@ -184,22 +193,22 @@ void tst_QtConcurrentResultStore::resultIndex() ResultIteratorBase it = store.begin(); QCOMPARE(it.resultIndex(), 0); - QVERIFY(it == store.begin()); - QVERIFY(it != store.end()); + QT_TEST_EQUALITY_OPS(it, store.begin(), true); + QT_TEST_EQUALITY_OPS(it, store.end(), false); ++it; QCOMPARE(it.resultIndex(), 1); - QVERIFY(it != store.begin()); - QVERIFY(it != store.end()); + QT_TEST_EQUALITY_OPS(it, store.begin(), false); + QT_TEST_EQUALITY_OPS(it, store.end(), false); ++it; QCOMPARE(it.resultIndex(), 2); - QVERIFY(it != store.end()); + QT_TEST_EQUALITY_OPS(it, store.end(), false); ++it; QCOMPARE(it.resultIndex(), 3); - QVERIFY(it != store.end()); + QT_TEST_EQUALITY_OPS(it, store.end(), false); ++it; - QVERIFY(it == store.end()); + QT_TEST_EQUALITY_OPS(it, store.end(), true); QCOMPARE(store.resultAt(0).value<int>(), int0); QCOMPARE(store.resultAt(1).value<int>(), vec0[0]); diff --git a/tests/auto/corelib/thread/qthread/tst_qthread.cpp b/tests/auto/corelib/thread/qthread/tst_qthread.cpp index b163235d81..18c8d5fbd5 100644 --- a/tests/auto/corelib/thread/qthread/tst_qthread.cpp +++ b/tests/auto/corelib/thread/qthread/tst_qthread.cpp @@ -1299,8 +1299,16 @@ public: } void registerSocketNotifier(QSocketNotifier *) override {} void unregisterSocketNotifier(QSocketNotifier *) override {} - void registerTimer(Qt::TimerId, Duration, Qt::TimerType, QObject *) override {} - bool unregisterTimer(Qt::TimerId) override { return false; } + void registerTimer(Qt::TimerId id, Duration, Qt::TimerType, QObject *) override + { + if (registeredTimerId <= Qt::TimerId::Invalid) + registeredTimerId = id; + } + bool unregisterTimer(Qt::TimerId id) override + { + Qt::TimerId oldId = std::exchange(registeredTimerId, Qt::TimerId::Invalid); + return id == oldId; + } bool unregisterTimers(QObject *) override { return false; } QList<TimerInfoV2> timersForObject(QObject *) const override { return {}; } Duration remainingTime(Qt::TimerId) const override { return 0s; } @@ -1313,25 +1321,47 @@ public: #endif QBasicAtomicInt visited; // bool + Qt::TimerId registeredTimerId = Qt::TimerId::Invalid; }; -class ThreadObj : public QObject +struct ThreadLocalContent { - Q_OBJECT -public slots: - void visit() { - emit visited(); + static inline const QMetaObject *atStart; + static inline const QMetaObject *atEnd; + QSemaphore *sem; + QBasicTimer timer; + + ThreadLocalContent(QObject *obj, QSemaphore *sem) + : sem(sem) + { + ensureEventDispatcher(); + atStart = QAbstractEventDispatcher::instance()->metaObject(); + timer.start(10s, obj); + } + ~ThreadLocalContent() + { + ensureEventDispatcher(); + atEnd = QAbstractEventDispatcher::instance()->metaObject(); + timer.stop(); + sem->release(); + } + + void ensureEventDispatcher() + { + // QEventLoop's constructor has a call to QThreadData::ensureEventDispatcher() + QEventLoop dummy; } -signals: - void visited(); }; void tst_QThread::customEventDispatcher() { + ThreadLocalContent::atStart = ThreadLocalContent::atEnd = nullptr; + QThread thr; // there should be no ED yet QVERIFY(!thr.eventDispatcher()); DummyEventDispatcher *ed = new DummyEventDispatcher; + QPointer<DummyEventDispatcher> weak_ed(ed); thr.setEventDispatcher(ed); // the new ED should be set QCOMPARE(thr.eventDispatcher(), ed); @@ -1340,25 +1370,39 @@ void tst_QThread::customEventDispatcher() thr.start(); // start() should not overwrite the ED QCOMPARE(thr.eventDispatcher(), ed); + QVERIFY(!weak_ed.isNull()); - ThreadObj obj; + QObject obj; obj.moveToThread(&thr); // move was successful? QCOMPARE(obj.thread(), &thr); - QEventLoop loop; - connect(&obj, SIGNAL(visited()), &loop, SLOT(quit()), Qt::QueuedConnection); - QMetaObject::invokeMethod(&obj, "visit", Qt::QueuedConnection); - loop.exec(); + + QSemaphore threadLocalSemaphore; + QMetaObject::invokeMethod(&obj, [&]() { +#ifndef Q_OS_WIN + // On Windows, the thread_locals are unsequenced between DLLs, so this + // could run after QThreadPrivate::finish() + static thread_local +#endif + ThreadLocalContent d(&obj, &threadLocalSemaphore); + }, Qt::BlockingQueuedConnection); + // test that the ED has really been used QVERIFY(ed->visited.loadRelaxed()); + // and it's ours + QCOMPARE(ThreadLocalContent::atStart->className(), "DummyEventDispatcher"); - QPointer<DummyEventDispatcher> weak_ed(ed); QVERIFY(!weak_ed.isNull()); thr.quit(); + // wait for thread to be stopped QVERIFY(thr.wait(30000)); + QVERIFY(threadLocalSemaphore.tryAcquire(1, 30s)); + // test that ED has been deleted QVERIFY(weak_ed.isNull()); + // test that ED was ours + QCOMPARE(ThreadLocalContent::atEnd->className(), "DummyEventDispatcher"); } class Job : public QObject |