diff options
Diffstat (limited to 'tests/auto/concurrent/qtconcurrentthreadengine/tst_qtconcurrentthreadengine.cpp')
-rw-r--r-- | tests/auto/concurrent/qtconcurrentthreadengine/tst_qtconcurrentthreadengine.cpp | 221 |
1 files changed, 58 insertions, 163 deletions
diff --git a/tests/auto/concurrent/qtconcurrentthreadengine/tst_qtconcurrentthreadengine.cpp b/tests/auto/concurrent/qtconcurrentthreadengine/tst_qtconcurrentthreadengine.cpp index e192dad3bd..0151b13693 100644 --- a/tests/auto/concurrent/qtconcurrentthreadengine/tst_qtconcurrentthreadengine.cpp +++ b/tests/auto/concurrent/qtconcurrentthreadengine/tst_qtconcurrentthreadengine.cpp @@ -1,35 +1,14 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +#undef QT_NO_FOREACH // this file contains unported legacy Q_FOREACH uses + #include <qtconcurrentthreadengine.h> #include <qexception.h> #include <QThread> #include <QElapsedTimer> -#include <QtTest/QtTest> +#include <QTest> +#include <QSet> using namespace QtConcurrent; @@ -56,7 +35,7 @@ class PrintUser : public ThreadEngine<void> { public: PrintUser() : ThreadEngine(QThreadPool::globalInstance()) {} - ThreadFunctionResult threadFunction() + ThreadFunctionResult threadFunction() override { QTest::qSleep(50); QTest::qSleep(100); @@ -66,16 +45,9 @@ public: void tst_QtConcurrentThreadEngine::runDirectly() { - { - PrintUser engine; - engine.startSingleThreaded(); - engine.startBlocking(); - } - { - PrintUser *engine = new PrintUser(); - QFuture<void> f = engine->startAsynchronously(); - f.waitForFinished(); - } + PrintUser *engine = new PrintUser(); + QFuture<void> f = engine->startAsynchronously(); + f.waitForFinished(); } class StringResultUser : public ThreadEngine<QString> @@ -86,18 +58,18 @@ public: : ThreadEngine(QThreadPool::globalInstance()) , done(false) { } - bool shouldStartThread() + bool shouldStartThread() override { return !done; } - ThreadFunctionResult threadFunction() + ThreadFunctionResult threadFunction() override { done = true; return ThreadFinished; } - QString *result() + QString *result() override { foo = "Foo"; return &foo; @@ -108,8 +80,10 @@ public: void tst_QtConcurrentThreadEngine::result() { - StringResultUser engine; - QCOMPARE(*engine.startBlocking(), QString("Foo")); + // ThreadEngine will delete 'engine' when it finishes + auto engine = new StringResultUser(); + auto future = engine->startAsynchronously(); + QCOMPARE(future.result(), QString("Foo")); } class VoidResultUser : public ThreadEngine<void> @@ -117,18 +91,18 @@ class VoidResultUser : public ThreadEngine<void> public: VoidResultUser() : ThreadEngine(QThreadPool::globalInstance()) {} - bool shouldStartThread() + bool shouldStartThread() override { return !done; } - ThreadFunctionResult threadFunction() + ThreadFunctionResult threadFunction() override { done = true; return ThreadFinished; } - void *result() + void *result() override { return 0; } @@ -137,17 +111,9 @@ public: void tst_QtConcurrentThreadEngine::runThroughStarter() { - { - ThreadEngineStarter<QString> starter = startThreadEngine(new StringResultUser()); - QFuture<QString> f = starter.startAsynchronously(); - QCOMPARE(f.result(), QString("Foo")); - } - - { - ThreadEngineStarter<QString> starter = startThreadEngine(new StringResultUser()); - QString str = starter.startBlocking(); - QCOMPARE(str, QString("Foo")); - } + ThreadEngineStarter<QString> starter = startThreadEngine(new StringResultUser()); + QFuture<QString> f = starter.startAsynchronously(); + QCOMPARE(f.result(), QString("Foo")); } class CancelUser : public ThreadEngine<void> @@ -155,12 +121,12 @@ class CancelUser : public ThreadEngine<void> public: CancelUser() : ThreadEngine(QThreadPool::globalInstance()) {} - void *result() + void *result() override { return 0; } - ThreadFunctionResult threadFunction() + ThreadFunctionResult threadFunction() override { while (this->isCanceled() == false) { @@ -198,12 +164,12 @@ public: finishing = false; } - bool shouldStartThread() + bool shouldStartThread() override { return !finishing; } - ThreadFunctionResult threadFunction() + ThreadFunctionResult threadFunction() override { forever { const int local = count.loadRelaxed(); @@ -233,12 +199,6 @@ void tst_QtConcurrentThreadEngine::throttle() f.waitForFinished(); QCOMPARE(count.loadRelaxed(), 0); } - - for (int i = 0; i < repeats; ++i) { - ThrottleAlwaysUser t; - t.startBlocking(); - QCOMPARE(count.loadRelaxed(), 0); - } } QSet<QThread *> threads; @@ -253,12 +213,12 @@ public: finishing = finishImmediately; } - bool shouldStartThread() + bool shouldStartThread() override { return !finishing; } - ThreadFunctionResult threadFunction() + ThreadFunctionResult threadFunction() override { { QMutexLocker lock(&mutex); @@ -274,40 +234,21 @@ public: void tst_QtConcurrentThreadEngine::threadCount() { - //QTBUG-23333: This test is unstable - const int repeats = 10; for (int i = 0; i < repeats; ++i) { - ThreadCountUser t; - t.startBlocking(); - int count = threads.count(); - int count_expected = QThreadPool::globalInstance()->maxThreadCount() + 1; // +1 for the main thread. - if (count != count_expected) - QEXPECT_FAIL("", "QTBUG-23333", Abort); - QCOMPARE(count, count_expected); - (new ThreadCountUser())->startAsynchronously().waitForFinished(); - count = threads.count(); - count_expected = QThreadPool::globalInstance()->maxThreadCount(); - if (count != count_expected) - QEXPECT_FAIL("", "QTBUG-23333", Abort); - QCOMPARE(count, count_expected); + const auto count = threads.size(); + const auto maxThreadCount = QThreadPool::globalInstance()->maxThreadCount(); + QVERIFY(count <= maxThreadCount); + QVERIFY(!threads.contains(QThread::currentThread())); } // Set the finish flag immediately, this should give us one thread only. for (int i = 0; i < repeats; ++i) { - ThreadCountUser t(true /*finishImmediately*/); - t.startBlocking(); - int count = threads.count(); - if (count != 1) - QEXPECT_FAIL("", "QTBUG-23333", Abort); - QCOMPARE(count, 1); - (new ThreadCountUser(true /*finishImmediately*/))->startAsynchronously().waitForFinished(); - count = threads.count(); - if (count != 1) - QEXPECT_FAIL("", "QTBUG-23333", Abort); + const auto count = threads.size(); QCOMPARE(count, 1); + QVERIFY(!threads.contains(QThread::currentThread())); } } @@ -315,12 +256,12 @@ class MultipleResultsUser : public ThreadEngine<int> { public: MultipleResultsUser() : ThreadEngine(QThreadPool::globalInstance()) {} - bool shouldStartThread() + bool shouldStartThread() override { return false; } - ThreadFunctionResult threadFunction() + ThreadFunctionResult threadFunction() override { for (int i = 0; i < 10; ++i) this->reportResult(&i); @@ -333,7 +274,7 @@ void tst_QtConcurrentThreadEngine::multipleResults() { MultipleResultsUser *engine = new MultipleResultsUser(); QFuture<int> f = engine->startAsynchronously(); - QCOMPARE(f.results().count() , 10); + QCOMPARE(f.results().size() , 10); QCOMPARE(f.resultAt(0), 0); QCOMPARE(f.resultAt(5), 5); QCOMPARE(f.resultAt(9), 9); @@ -344,17 +285,17 @@ void tst_QtConcurrentThreadEngine::multipleResults() class NoThreadsUser : public ThreadEngine<void> { public: - bool shouldStartThread() + bool shouldStartThread() override { return false; } - ThreadFunctionResult threadFunction() + ThreadFunctionResult threadFunction() override { return ThreadFinished; } - void *result() + void *result() override { return 0; } @@ -385,8 +326,8 @@ class SlowUser : public ThreadEngine<void> { public: SlowUser() : ThreadEngine(QThreadPool::globalInstance()) {} - bool shouldStartThread() { return false; } - ThreadFunctionResult threadFunction() { QTest::qSleep(sleepTime); return ThreadFinished; } + bool shouldStartThread() override { return false; } + ThreadFunctionResult threadFunction() override { QTest::qSleep(sleepTime); return ThreadFinished; } }; void tst_QtConcurrentThreadEngine::cancelQueuedSlowUser() @@ -415,13 +356,13 @@ void tst_QtConcurrentThreadEngine::cancelQueuedSlowUser() class QtConcurrentExceptionThrower : public ThreadEngine<void> { public: - QtConcurrentExceptionThrower(QThread *blockThread = 0) + QtConcurrentExceptionThrower(QThread *blockThread = nullptr) : ThreadEngine(QThreadPool::globalInstance()) { this->blockThread = blockThread; } - ThreadFunctionResult threadFunction() + ThreadFunctionResult threadFunction() override { QTest::qSleep(50); throw QException(); @@ -430,16 +371,16 @@ public: QThread *blockThread; }; -class UnrelatedExceptionThrower : public ThreadEngine<void> +class IntExceptionThrower : public ThreadEngine<void> { public: - UnrelatedExceptionThrower(QThread *blockThread = 0) + IntExceptionThrower(QThread *blockThread = nullptr) : ThreadEngine(QThreadPool::globalInstance()) { this->blockThread = blockThread; } - ThreadFunctionResult threadFunction() + ThreadFunctionResult threadFunction() override { QTest::qSleep(50); throw int(); @@ -450,7 +391,6 @@ public: void tst_QtConcurrentThreadEngine::exceptions() { - // Asynchronous mode: { bool caught = false; try { @@ -463,65 +403,20 @@ void tst_QtConcurrentThreadEngine::exceptions() QVERIFY2(caught, "did not get exception"); } - // Blocking mode: - // test throwing the exception from a worker thread. - { - bool caught = false; - try { - QtConcurrentExceptionThrower e(QThread::currentThread()); - e.startBlocking(); - } catch (const QException &) { - caught = true; - } - QVERIFY2(caught, "did not get exception"); - } - - // test throwing the exception from the main thread (different code path) { bool caught = false; try { - QtConcurrentExceptionThrower e(0); - e.startBlocking(); - } catch (const QException &) { - caught = true; - } - QVERIFY2(caught, "did not get exception"); - } - - // Asynchronous mode: - { - bool caught = false; - try { - UnrelatedExceptionThrower *e = new UnrelatedExceptionThrower(); + IntExceptionThrower *e = new IntExceptionThrower(); QFuture<void> f = e->startAsynchronously(); f.waitForFinished(); - } catch (const QUnhandledException &) { - caught = true; - } - QVERIFY2(caught, "did not get exception"); - } - - // Blocking mode: - // test throwing the exception from a worker thread. - { - bool caught = false; - try { - UnrelatedExceptionThrower e(QThread::currentThread()); - e.startBlocking(); - } catch (const QUnhandledException &) { - caught = true; - } - QVERIFY2(caught, "did not get exception"); - } - - // test throwing the exception from the main thread (different code path) - { - bool caught = false; - try { - UnrelatedExceptionThrower e(0); - e.startBlocking(); - } catch (const QUnhandledException &) { - caught = true; + } catch (const QUnhandledException &ex) { + // Make sure the exception info is not lost + try { + if (ex.exception()) + std::rethrow_exception(ex.exception()); + } catch (int) { + caught = true; + } } QVERIFY2(caught, "did not get exception"); } |