diff options
Diffstat (limited to 'tests/auto')
9 files changed, 183 insertions, 30 deletions
diff --git a/tests/auto/cmake/mockplugins/.cmake.conf b/tests/auto/cmake/mockplugins/.cmake.conf index be788d10f8e..846c4f3b923 100644 --- a/tests/auto/cmake/mockplugins/.cmake.conf +++ b/tests/auto/cmake/mockplugins/.cmake.conf @@ -1 +1 @@ -set(QT_REPO_MODULE_VERSION "6.11.0") +set(QT_REPO_MODULE_VERSION "6.12.0") diff --git a/tests/auto/cmake/test_generating_cpp_exports/.cmake.conf b/tests/auto/cmake/test_generating_cpp_exports/.cmake.conf index be788d10f8e..846c4f3b923 100644 --- a/tests/auto/cmake/test_generating_cpp_exports/.cmake.conf +++ b/tests/auto/cmake/test_generating_cpp_exports/.cmake.conf @@ -1 +1 @@ -set(QT_REPO_MODULE_VERSION "6.11.0") +set(QT_REPO_MODULE_VERSION "6.12.0") diff --git a/tests/auto/cmake/test_static_resources/.cmake.conf b/tests/auto/cmake/test_static_resources/.cmake.conf index be788d10f8e..846c4f3b923 100644 --- a/tests/auto/cmake/test_static_resources/.cmake.conf +++ b/tests/auto/cmake/test_static_resources/.cmake.conf @@ -1 +1 @@ -set(QT_REPO_MODULE_VERSION "6.11.0") +set(QT_REPO_MODULE_VERSION "6.12.0") diff --git a/tests/auto/corelib/thread/qreadwritelock/tst_qreadwritelock.cpp b/tests/auto/corelib/thread/qreadwritelock/tst_qreadwritelock.cpp index 86dfa5faffc..4c089091f8d 100644 --- a/tests/auto/corelib/thread/qreadwritelock/tst_qreadwritelock.cpp +++ b/tests/auto/corelib/thread/qreadwritelock/tst_qreadwritelock.cpp @@ -57,6 +57,7 @@ private slots: void multipleReadersLoop(); void multipleWritersLoop(); void multipleReadersWritersLoop(); + void heavyLoadLocks(); void countingTest(); void limitedReaders(); void deleteOnUnlock(); @@ -603,6 +604,111 @@ public: } }; +class HeavyLoadLockThread : public QThread +{ +public: + QReadWriteLock &testRwlock; + const qsizetype iterations; + const int numThreads; + inline HeavyLoadLockThread(QReadWriteLock &l, qsizetype iters, int numThreads, QVector<QAtomicInt *> &counters): + testRwlock(l), + iterations(iters), + numThreads(numThreads), + counters(counters) + { } + +private: + QVector<QAtomicInt *> &counters; + QAtomicInt *getCounter(qsizetype index) + { + QReadLocker locker(&testRwlock); + /* + The index is increased monotonically, so the index + being requested should be always within or at the end of the + counters vector. + */ + Q_ASSERT(index <= counters.size()); + if (counters.size() <= index || counters[index] == nullptr) { + locker.unlock(); + QWriteLocker wlocker(&testRwlock); + if (counters.size() <= index) + counters.resize(index + 1, nullptr); + if (counters[index] == nullptr) + counters[index] = new QAtomicInt(0); + return counters[index]; + } + return counters[index]; + } + void releaseCounter(qsizetype index) + { + QWriteLocker locker(&testRwlock); + delete counters[index]; + counters[index] = nullptr; + } + +public: + void run() override + { + for (qsizetype i = 0; i < iterations; ++i) { + QAtomicInt *counter = getCounter(i); + /* + Here each counter is accessed by each thread + and increaed only once. As a result, when the + counter reaches numThreads, i.e. the fetched + value before the increment is numThreads-1, + we know all threads have accessed this counter + and we can delete it safely. + */ + int prev = counter->fetchAndAddRelaxed(1); + if (prev == numThreads - 1) { +#ifdef QT_BUILDING_UNDER_TSAN + /* + Under TSAN, deleting and freeing an object + will trigger a write operation on the memory + of the object. Since we used fetchAndAddRelaxed + to update the counter, TSAN will report a data + race when deleting the counter here. To avoid + the false positive, we simply reset the counter + to 0 here, with ordered semantics to establish + the sequence to ensure the the free-ing option + happens after all fetchAndAddRelaxed operations + in other threads. + + When not building under TSAN, deleting the counter + will not result in any data read or written to the + memory region of the counter, so no data race will + happen. + */ + counter->fetchAndStoreOrdered(0); +#endif + releaseCounter(i); + } + } + } +}; + +/* + Multiple threads racing acquiring and releasing + locks on the same indices. +*/ + +void tst_QReadWriteLock::heavyLoadLocks() +{ + constexpr qsizetype iterations = 65536 * 4; + constexpr int numThreads = 8; + QVector<QAtomicInt *> counters; + QReadWriteLock testLock; + std::array<std::unique_ptr<HeavyLoadLockThread>, numThreads> threads; + for (auto &thread : threads) + thread = std::make_unique<HeavyLoadLockThread>(testLock, iterations, numThreads, counters); + for (auto &thread : threads) + thread->start(); + for (auto &thread : threads) + thread->wait(); + QVERIFY(counters.size() == iterations); + for (qsizetype i = 0; i < iterations; ++i) + QVERIFY(counters[i] == nullptr); +} /* A writer acquires a read-lock, a reader locks diff --git a/tests/auto/network/access/qhttp2connection/tst_qhttp2connection.cpp b/tests/auto/network/access/qhttp2connection/tst_qhttp2connection.cpp index 417655c31d9..22aa9d44262 100644 --- a/tests/auto/network/access/qhttp2connection/tst_qhttp2connection.cpp +++ b/tests/auto/network/access/qhttp2connection/tst_qhttp2connection.cpp @@ -21,6 +21,8 @@ class tst_QHttp2Connection : public QObject private slots: void construct(); void constructStream(); + void streamConfiguration_data(); + void streamConfiguration(); void testSETTINGSFrame(); void maxHeaderTableSize(); void testPING(); @@ -204,6 +206,59 @@ void tst_QHttp2Connection::constructStream() QCOMPARE(stream->isUploadingDATA(), false); } +void tst_QHttp2Connection::streamConfiguration_data() +{ + QTest::addColumn<bool>("useDownloadBuffer"); + + QTest::addRow("useDownloadBuffer=true") << true; + QTest::addRow("useDownloadBuffer=false") << false; +} + +void tst_QHttp2Connection::streamConfiguration() +{ + QFETCH(const bool, useDownloadBuffer); + + auto [client, server] = makeFakeConnectedSockets(); + auto *clientConnection = makeHttp2Connection(client.get(), {}, Client); + auto *serverConnection = makeHttp2Connection(server.get(), {}, Server); + + QHttp2Stream::Configuration config; + config.useDownloadBuffer = useDownloadBuffer; + + QHttp2Stream *clientStream = clientConnection->createStream(config).unwrap(); + QVERIFY(clientStream); + QCOMPARE(clientStream->configuration().useDownloadBuffer, useDownloadBuffer); + QVERIFY(waitForSettingsExchange(clientConnection, serverConnection)); + + QSignalSpy newIncomingStreamSpy{ serverConnection, &QHttp2Connection::newIncomingStream }; + QSignalSpy clientDataReceivedSpy{ clientStream, &QHttp2Stream::dataReceived }; + + HPack::HttpHeader headers = getRequiredHeaders(); + clientStream->sendHEADERS(headers, false); + + QVERIFY(newIncomingStreamSpy.wait()); + auto *serverStream = newIncomingStreamSpy.front().front().value<QHttp2Stream *>(); + QVERIFY(serverStream); + + const HPack::HttpHeader responseHeaders{ { ":status", "200" } }; + serverStream->sendHEADERS(responseHeaders, false); + + const QByteArray testData = "Hello World"_ba.repeated(100); + serverStream->sendDATA(testData, true); + + QVERIFY(clientDataReceivedSpy.wait()); + QCOMPARE(clientDataReceivedSpy.count(), 1); + + const QByteArray receivedData = clientDataReceivedSpy.front().front().value<QByteArray>(); + QCOMPARE(receivedData, testData); + + if (useDownloadBuffer) { + QCOMPARE(clientStream->downloadBuffer().byteAmount(), testData.size()); + } else { + QVERIFY(clientStream->downloadBuffer().isEmpty()); + } +} + void tst_QHttp2Connection::testSETTINGSFrame() { constexpr qint32 PrefaceLength = 24; diff --git a/tests/auto/tools/rcc/data/legal/rcc_legal.cpp b/tests/auto/tools/rcc/data/legal/rcc_legal.cpp index 248ab2e3b48..96f87d192e7 100644 --- a/tests/auto/tools/rcc/data/legal/rcc_legal.cpp +++ b/tests/auto/tools/rcc/data/legal/rcc_legal.cpp @@ -3,7 +3,7 @@ ** Copyright (C) 2024 Intel Corporation. ** SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only ** -** Created by: The Resource Compiler for Qt version 6.11.0 +** Created by: The Resource Compiler for Qt version 6.12.0 ** ** WARNING! All changes made in this file will be lost! *****************************************************************************/ diff --git a/tests/auto/widgets/dialogs/qwizard/tst_qwizard.cpp b/tests/auto/widgets/dialogs/qwizard/tst_qwizard.cpp index 560c725fd3f..2c14a408804 100644 --- a/tests/auto/widgets/dialogs/qwizard/tst_qwizard.cpp +++ b/tests/auto/widgets/dialogs/qwizard/tst_qwizard.cpp @@ -449,12 +449,12 @@ void tst_QWizard::setPixmap() int newWidth = 1240; wizard.resize(newWidth, 720); QCOMPARE(wizard.width(), oldWidth); - wizard.setBannerSizePolicy(QWizard::BannerSizePolicy::Stretch); + wizard.setBannerStretchPolicy(QWizard::BannerStretchPolicy::Stretch); wizard.resize(newWidth, 720); QCOMPARE(wizard.width(), newWidth); - wizard.setBannerSizePolicy(QWizard::BannerSizePolicy::NoStretch); + wizard.setBannerStretchPolicy(QWizard::BannerStretchPolicy::NoStretch); QCOMPARE(wizard.width(), oldWidth); - wizard.setBannerSizePolicy(QWizard::BannerSizePolicy::Stretch); + wizard.setBannerStretchPolicy(QWizard::BannerStretchPolicy::Stretch); wizard.resize(newWidth, 720); QCOMPARE(wizard.width(), newWidth); } diff --git a/tests/auto/widgets/kernel/qwidget/BLACKLIST b/tests/auto/widgets/kernel/qwidget/BLACKLIST index 9651c1480c8..12da5b423ab 100644 --- a/tests/auto/widgets/kernel/qwidget/BLACKLIST +++ b/tests/auto/widgets/kernel/qwidget/BLACKLIST @@ -4,11 +4,6 @@ osx macos arm [render_systemClip] osx -[multipleToplevelFocusCheck] -centos -opensuse-leap -ubuntu -sles-15 # QTBUG-87668 [showMinimizedKeepsFocus] android diff --git a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp index e3d172c60c0..359a0946474 100644 --- a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp +++ b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp @@ -6931,9 +6931,13 @@ class TopLevelFocusCheck: public QWidget Q_OBJECT public: QLineEdit* edit; - explicit TopLevelFocusCheck(QWidget *parent = nullptr) + explicit TopLevelFocusCheck(const QString &name, QWidget *parent = nullptr) : QWidget(parent), edit(new QLineEdit(this)) { + const QString title = QLatin1String(QTest::currentTestFunction()) + "_"_L1 + name; + setWindowTitle(title); + setObjectName(title); + edit->setObjectName(QString("%1_edit"_L1).arg(title)); edit->hide(); edit->installEventFilter(this); } @@ -6943,7 +6947,7 @@ public slots: { edit->show(); edit->setFocus(Qt::OtherFocusReason); - QCoreApplication::processEvents(); + QVERIFY(QTest::qWaitForWindowFocused(edit)); } bool eventFilter(QObject *obj, QEvent *event) override { @@ -6963,49 +6967,42 @@ void tst_QWidget::multipleToplevelFocusCheck() if (!QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::WindowActivation)) QSKIP("Window activation is not supported"); - TopLevelFocusCheck w1; - TopLevelFocusCheck w2; + TopLevelFocusCheck w1("Widget-1"_L1); + TopLevelFocusCheck w2("Widget-2"_L1); - const QString title = QLatin1String(QTest::currentTestFunction()); - w1.setWindowTitle(title + QLatin1String("_W1")); w1.move(m_availableTopLeft + QPoint(20, 20)); w1.resize(200, 200); w1.show(); QVERIFY(QTest::qWaitForWindowExposed(&w1)); - w2.setWindowTitle(title + QLatin1String("_W2")); w2.move(w1.frameGeometry().topRight() + QPoint(20, 0)); w2.resize(200,200); w2.show(); QVERIFY(QTest::qWaitForWindowExposed(&w2)); w1.activateWindow(); - QApplicationPrivate::setActiveWindow(&w1); QVERIFY(QTest::qWaitForWindowActive(&w1)); - QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&w1)); + QTRY_COMPARE(QApplication::activeWindow(), &w1); QTest::mouseDClick(&w1, Qt::LeftButton); - QTRY_COMPARE(QApplication::focusWidget(), static_cast<QWidget *>(w1.edit)); + QTRY_COMPARE(QApplication::focusWidget(), w1.edit); w2.activateWindow(); - QApplicationPrivate::setActiveWindow(&w2); QVERIFY(QTest::qWaitForWindowActive(&w2)); - QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&w2)); + QTRY_COMPARE(QApplication::activeWindow(), &w2); QTest::mouseClick(&w2, Qt::LeftButton); QTRY_COMPARE(QApplication::focusWidget(), nullptr); QTest::mouseDClick(&w2, Qt::LeftButton); - QTRY_COMPARE(QApplication::focusWidget(), static_cast<QWidget *>(w2.edit)); + QTRY_COMPARE(QApplication::focusWidget(), w2.edit); w1.activateWindow(); - QApplicationPrivate::setActiveWindow(&w1); QVERIFY(QTest::qWaitForWindowActive(&w1)); - QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&w1)); + QTRY_COMPARE(QApplication::activeWindow(), &w1); QTest::mouseDClick(&w1, Qt::LeftButton); - QTRY_COMPARE(QApplication::focusWidget(), static_cast<QWidget *>(w1.edit)); + QTRY_COMPARE(QApplication::focusWidget(), w1.edit); w2.activateWindow(); - QApplicationPrivate::setActiveWindow(&w2); QVERIFY(QTest::qWaitForWindowActive(&w2)); - QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&w2)); + QTRY_COMPARE(QApplication::activeWindow(), &w2); QTest::mouseClick(&w2, Qt::LeftButton); QTRY_COMPARE(QApplication::focusWidget(), nullptr); } |
