diff options
Diffstat (limited to 'tests/auto/corelib')
4 files changed, 161 insertions, 6 deletions
diff --git a/tests/auto/corelib/global/qflags/tst_qflags.cpp b/tests/auto/corelib/global/qflags/tst_qflags.cpp index 7dd1a1be01..2f1b56629a 100644 --- a/tests/auto/corelib/global/qflags/tst_qflags.cpp +++ b/tests/auto/corelib/global/qflags/tst_qflags.cpp @@ -290,6 +290,18 @@ void tst_QFlags::testSetFlags() btn.setFlag(Qt::LeftButton, false); QVERIFY(!btn.testFlag(Qt::LeftButton)); QVERIFY(!btn.testFlag(Qt::MidButton)); + + MyStrictFlags flags; + flags.setFlag(MyStrictEnum::StrictOne); + flags.setFlag(MyStrictEnum::StrictTwo, true); + QVERIFY(flags.testFlag(MyStrictEnum::StrictOne)); + QVERIFY(flags.testFlag(MyStrictEnum::StrictTwo)); + QVERIFY(!flags.testFlag(MyStrictEnum::StrictFour)); + + flags.setFlag(MyStrictEnum::StrictTwo, false); + QVERIFY(flags.testFlag(MyStrictEnum::StrictOne)); + QVERIFY(!flags.testFlag(MyStrictEnum::StrictTwo)); + QVERIFY(!flags.testFlag(MyStrictEnum::StrictFour)); } // (statically) check QTypeInfo for QFlags instantiations: diff --git a/tests/auto/corelib/io/qloggingregistry/tst_qloggingregistry.cpp b/tests/auto/corelib/io/qloggingregistry/tst_qloggingregistry.cpp index 1643eed3d2..15c63d4acd 100644 --- a/tests/auto/corelib/io/qloggingregistry/tst_qloggingregistry.cpp +++ b/tests/auto/corelib/io/qloggingregistry/tst_qloggingregistry.cpp @@ -197,10 +197,22 @@ private slots: // Check whether QT_LOGGING_CONF is picked up from environment // - qputenv("QT_LOGGING_CONF", QFINDTESTDATA("qtlogging.ini").toLocal8Bit()); + Q_ASSERT(!qApp); // Rules should not require an app to resolve - QLoggingRegistry registry; - registry.init(); + qputenv("QT_LOGGING_RULES", "qt.foo.bar=true"); + QLoggingCategory qtEnabledByLoggingRule("qt.foo.bar"); + QCOMPARE(qtEnabledByLoggingRule.isDebugEnabled(), true); + QLoggingCategory qtDisabledByDefault("qt.foo.baz"); + QCOMPARE(qtDisabledByDefault.isDebugEnabled(), false); + + QLoggingRegistry ®istry = *QLoggingRegistry::instance(); + QCOMPARE(registry.ruleSets[QLoggingRegistry::ApiRules].size(), 0); + QCOMPARE(registry.ruleSets[QLoggingRegistry::ConfigRules].size(), 0); + QCOMPARE(registry.ruleSets[QLoggingRegistry::EnvironmentRules].size(), 1); + + qunsetenv("QT_LOGGING_RULES"); + qputenv("QT_LOGGING_CONF", QFINDTESTDATA("qtlogging.ini").toLocal8Bit()); + registry.initalizeRules(); QCOMPARE(registry.ruleSets[QLoggingRegistry::ApiRules].size(), 0); QCOMPARE(registry.ruleSets[QLoggingRegistry::ConfigRules].size(), 0); @@ -208,7 +220,7 @@ private slots: // check that QT_LOGGING_RULES take precedence qputenv("QT_LOGGING_RULES", "Digia.*=true"); - registry.init(); + registry.initalizeRules(); QCOMPARE(registry.ruleSets[QLoggingRegistry::EnvironmentRules].size(), 2); QCOMPARE(registry.ruleSets[QLoggingRegistry::EnvironmentRules].at(1).enabled, true); } @@ -234,7 +246,7 @@ private slots: file.close(); QLoggingRegistry registry; - registry.init(); + registry.initalizeRules(); QCOMPARE(registry.ruleSets[QLoggingRegistry::ConfigRules].size(), 1); // remove file again @@ -300,6 +312,6 @@ private slots: } }; -QTEST_MAIN(tst_QLoggingRegistry) +QTEST_APPLESS_MAIN(tst_QLoggingRegistry) #include "tst_qloggingregistry.moc" diff --git a/tests/auto/corelib/thread/qsemaphore/tst_qsemaphore.cpp b/tests/auto/corelib/thread/qsemaphore/tst_qsemaphore.cpp index ba470a77c9..a67ecc2471 100644 --- a/tests/auto/corelib/thread/qsemaphore/tst_qsemaphore.cpp +++ b/tests/auto/corelib/thread/qsemaphore/tst_qsemaphore.cpp @@ -41,6 +41,8 @@ private slots: void tryAcquireWithTimeout_data(); void tryAcquireWithTimeout(); void tryAcquireWithTimeoutStarvation(); + void tryAcquireWithTimeoutForever_data(); + void tryAcquireWithTimeoutForever(); void producerConsumer(); void raii(); }; @@ -156,21 +158,25 @@ void tst_QSemaphore::tryAcquire() semaphore.release(); QCOMPARE(semaphore.available(), 1); QVERIFY(!semaphore.tryAcquire(2)); + QVERIFY(!semaphore.tryAcquire(2, 0)); QCOMPARE(semaphore.available(), 1); semaphore.release(); QCOMPARE(semaphore.available(), 2); QVERIFY(!semaphore.tryAcquire(3)); + QVERIFY(!semaphore.tryAcquire(3, 0)); QCOMPARE(semaphore.available(), 2); semaphore.release(10); QCOMPARE(semaphore.available(), 12); QVERIFY(!semaphore.tryAcquire(100)); + QVERIFY(!semaphore.tryAcquire(100, 0)); QCOMPARE(semaphore.available(), 12); semaphore.release(10); QCOMPARE(semaphore.available(), 22); QVERIFY(!semaphore.tryAcquire(100)); + QVERIFY(!semaphore.tryAcquire(100, 0)); QCOMPARE(semaphore.available(), 22); QVERIFY(semaphore.tryAcquire()); @@ -179,23 +185,38 @@ void tst_QSemaphore::tryAcquire() QVERIFY(semaphore.tryAcquire()); QCOMPARE(semaphore.available(), 20); + semaphore.release(2); + QVERIFY(semaphore.tryAcquire(1, 0)); + QCOMPARE(semaphore.available(), 21); + + QVERIFY(semaphore.tryAcquire(1, 0)); + QCOMPARE(semaphore.available(), 20); + QVERIFY(semaphore.tryAcquire(10)); QCOMPARE(semaphore.available(), 10); + semaphore.release(10); + QVERIFY(semaphore.tryAcquire(10, 0)); + QCOMPARE(semaphore.available(), 10); + QVERIFY(semaphore.tryAcquire(10)); QCOMPARE(semaphore.available(), 0); // should not be able to acquire more QVERIFY(!semaphore.tryAcquire()); + QVERIFY(!semaphore.tryAcquire(1, 0)); QCOMPARE(semaphore.available(), 0); QVERIFY(!semaphore.tryAcquire()); + QVERIFY(!semaphore.tryAcquire(1, 0)); QCOMPARE(semaphore.available(), 0); QVERIFY(!semaphore.tryAcquire(10)); + QVERIFY(!semaphore.tryAcquire(10, 0)); QCOMPARE(semaphore.available(), 0); QVERIFY(!semaphore.tryAcquire(10)); + QVERIFY(!semaphore.tryAcquire(10, 0)); QCOMPARE(semaphore.available(), 0); } @@ -345,6 +366,48 @@ void tst_QSemaphore::tryAcquireWithTimeoutStarvation() QVERIFY(consumer.wait()); } +void tst_QSemaphore::tryAcquireWithTimeoutForever_data() +{ + QTest::addColumn<int>("timeout"); + QTest::newRow("-1") << -1; + + // tryAcquire is documented to take any negative value as "forever" + QTest::newRow("INT_MIN") << INT_MIN; +} + +void tst_QSemaphore::tryAcquireWithTimeoutForever() +{ + enum { WaitTime = 1000 }; + struct Thread : public QThread { + QSemaphore sem; + + void run() override + { + QTest::qWait(WaitTime); + sem.release(2); + } + }; + + QFETCH(int, timeout); + Thread t; + + // sanity check it works if we can immediately acquire + t.sem.release(11); + QVERIFY(t.sem.tryAcquire(1, timeout)); + QVERIFY(t.sem.tryAcquire(10, timeout)); + + // verify that we do wait for at least WaitTime if we can't acquire immediately + QElapsedTimer timer; + timer.start(); + t.start(); + QVERIFY(t.sem.tryAcquire(1, timeout)); + QVERIFY(timer.elapsed() >= WaitTime); + + QVERIFY(t.wait()); + + QCOMPARE(t.sem.available(), 1); +} + const char alphabet[] = "ACGTH"; const int AlphabetSize = sizeof(alphabet) - 1; diff --git a/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp b/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp index 094c6ed0a5..1092216fb7 100644 --- a/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp +++ b/tests/auto/corelib/thread/qthreadpool/tst_qthreadpool.cpp @@ -95,6 +95,7 @@ private slots: void stackSize(); void stressTest(); void takeAllAndIncreaseMaxThreadCount(); + void waitForDoneAfterTake(); private: QMutex m_functionTestMutex; @@ -1267,5 +1268,72 @@ void tst_QThreadPool::takeAllAndIncreaseMaxThreadCount() { delete task3; } +void tst_QThreadPool::waitForDoneAfterTake() +{ + class Task : public QRunnable + { + public: + Task(QSemaphore *mainBarrier, QSemaphore *threadBarrier) + : m_mainBarrier(mainBarrier) + , m_threadBarrier(threadBarrier) + {} + + void run() + { + m_mainBarrier->release(); + m_threadBarrier->acquire(); + } + + private: + QSemaphore *m_mainBarrier = nullptr; + QSemaphore *m_threadBarrier = nullptr; + }; + + int threadCount = 4; + + // Blocks the main thread from releasing the threadBarrier before all run() functions have started + QSemaphore mainBarrier; + // Blocks the tasks from completing their run function + QSemaphore threadBarrier; + + QThreadPool manager; + manager.setMaxThreadCount(threadCount); + + // Fill all the threads with runnables that wait for the threadBarrier + for (int i = 0; i < threadCount; i++) { + auto *task = new Task(&mainBarrier, &threadBarrier); + manager.start(task); + } + + QVERIFY(manager.activeThreadCount() == manager.maxThreadCount()); + + // Add runnables that are immediately removed from the pool queue. + // This sets the queue elements to nullptr in QThreadPool and we want to test that + // the threads keep going through the queue after encountering a nullptr. + for (int i = 0; i < threadCount; i++) { + QRunnable *runnable = createTask(emptyFunct); + manager.start(runnable); + QVERIFY(manager.tryTake(runnable)); + } + + // Add another runnable that will not be removed + manager.start(createTask(emptyFunct)); + + // Wait for the first runnables to start + mainBarrier.acquire(threadCount); + + QVERIFY(mainBarrier.available() == 0); + QVERIFY(threadBarrier.available() == 0); + + // Release runnables that are waiting and expect all runnables to complete + threadBarrier.release(threadCount); + + // Using qFatal instead of QVERIFY to force exit if threads are still running after timeout. + // Otherwise, QCoreApplication will still wait for the stale threads and never exit the test. + if (!manager.waitForDone(5 * 60 * 1000)) + qFatal("waitForDone returned false. Aborting to stop background threads."); + +} + QTEST_MAIN(tst_QThreadPool); #include "tst_qthreadpool.moc" |