diff options
Diffstat (limited to 'src/corelib/kernel/qtestsupport_core.cpp')
-rw-r--r-- | src/corelib/kernel/qtestsupport_core.cpp | 165 |
1 files changed, 89 insertions, 76 deletions
diff --git a/src/corelib/kernel/qtestsupport_core.cpp b/src/corelib/kernel/qtestsupport_core.cpp index f5b6ed18cd..2ac44bb13d 100644 --- a/src/corelib/kernel/qtestsupport_core.cpp +++ b/src/corelib/kernel/qtestsupport_core.cpp @@ -1,99 +1,103 @@ -/**************************************************************************** -** -** Copyright (C) 2018 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** 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 Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** 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-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include "qtestsupport_core.h" -#ifdef Q_OS_WIN -#include <qt_windows.h> -#endif +#include <thread> + +using namespace std::chrono_literals; QT_BEGIN_NAMESPACE /*! - Sleeps for \a ms milliseconds, blocking execution of the - test. qSleep() will not do any event processing and leave your test - unresponsive. Network communication might time out while - sleeping. Use \l {QTest::qWait()} to do non-blocking sleeping. + \overload + + Sleeps for \a ms milliseconds, blocking execution of the test. + + Equivalent to calling: + \code + QTest::qSleep(std::chrono::milliseconds{ms}); + \endcode +*/ +void QTest::qSleep(int ms) +{ + QTest::qSleep(std::chrono::milliseconds{ms}); +} + +/*! + \since 6.7 - \a ms must be greater than 0. + Sleeps for \a msecs, blocking execution of the test. - \b {Note:} The qSleep() function calls either \c nanosleep() on - unix or \c Sleep() on windows, so the accuracy of time spent in - qSleep() depends on the operating system. + This method will not do any event processing and will leave your test + unresponsive. Network communication might time out while sleeping. + Use \l {QTest::qWait()} to do non-blocking sleeping. + + \a msecs must be greater than 0ms. + + \note Starting from Qt 6.7, this function is implemented using + \c {std::this_thread::sleep_for}, so the accuracy of time spent depends + on the Standard Library implementation. Before Qt 6.7 this function called + either \c nanosleep() on Unix or \c Sleep() on Windows, so the accuracy of + time spent in this function depended on the operating system. Example: \snippet code/src_qtestlib_qtestcase.cpp 23 \sa {QTest::qWait()} */ -Q_CORE_EXPORT void QTest::qSleep(int ms) +void QTest::qSleep(std::chrono::milliseconds msecs) { - Q_ASSERT(ms > 0); - -#if defined(Q_OS_WIN) - Sleep(uint(ms)); -#else - struct timespec ts = { time_t(ms / 1000), (ms % 1000) * 1000 * 1000 }; - nanosleep(&ts, nullptr); -#endif + Q_ASSERT(msecs > 0ms); + std::this_thread::sleep_for(msecs); } /*! \fn template <typename Functor> bool QTest::qWaitFor(Functor predicate, int timeout) + \since 5.10 + \overload + Waits for \a timeout milliseconds or until the \a predicate returns true. - Returns \c true if the \a predicate returned true at any point, otherwise returns \c false. + This is equivalent to calling: + \code + qWaitFor(predicate, QDeadlineTimer(timeout)); + \endcode +*/ + +/*! \fn template <typename Functor> bool QTest::qWaitFor(Functor predicate, QDeadlineTimer deadline) + \since 6.7 + + Waits until \a deadline has expired, or until \a predicate returns true, whichever + happens first. + + Returns \c true if \a predicate returned true at any point, otherwise returns \c false. Example: - \snippet code/src_corelib_kernel_qtestsupport_core_snippet.cpp 0 + \snippet code/src_corelib_kernel_qtestsupport_core.cpp 2 The code above will wait for the object to become ready, for a maximum of three seconds. - - \since 5.10 */ +/*! + \overload -/*! \fn void QTest::qWait(int ms) + Waits for \a msecs. Equivalent to calling: + \code + QTest::qWait(std::chrono::milliseconds{msecs}); + \endcode +*/ +Q_CORE_EXPORT void QTest::qWait(int msecs) +{ + qWait(std::chrono::milliseconds{msecs}); +} - Waits for \a ms milliseconds. While waiting, events will be processed and +/*! + \since 6.7 + + Waits for \a msecs. While waiting, events will be processed and your test will stay responsive to user interface events or network communication. Example: @@ -105,25 +109,34 @@ Q_CORE_EXPORT void QTest::qSleep(int ms) \sa QTest::qSleep(), QSignalSpy::wait() */ -Q_CORE_EXPORT void QTest::qWait(int ms) +Q_CORE_EXPORT void QTest::qWait(std::chrono::milliseconds msecs) { - // Ideally this method would be implemented in terms of qWaitFor, with - // a predicate that always returns false, but due to a compiler bug in - // GCC 6 we can't do that. + // Ideally this method would be implemented in terms of qWaitFor(), with a + // predicate that always returns false, but qWaitFor() uses the 1-arg overload + // of processEvents(), which doesn't handle events posted in this round of event + // processing, which, together with the 10ms qSleep() after every processEvents(), + // lead to a 10x slow-down in some webengine tests. Q_ASSERT(QCoreApplication::instance()); - QDeadlineTimer timer(ms, Qt::PreciseTimer); - int remaining = ms; + using namespace std::chrono; + + QDeadlineTimer deadline(msecs, Qt::PreciseTimer); + do { - QCoreApplication::processEvents(QEventLoop::AllEvents, remaining); + QCoreApplication::processEvents(QEventLoop::AllEvents, deadline); QCoreApplication::sendPostedEvents(nullptr, QEvent::DeferredDelete); - remaining = timer.remainingTime(); - if (remaining <= 0) + + // If dealine is Forever, processEvents() has already looped forever + if (deadline.isForever()) break; - QTest::qSleep(qMin(10, remaining)); - remaining = timer.remainingTime(); - } while (remaining > 0); + + msecs = ceil<milliseconds>(deadline.remainingTimeAsDuration()); + if (msecs == 0ms) + break; + + QTest::qSleep(std::min(10ms, msecs)); + } while (!deadline.hasExpired()); } QT_END_NAMESPACE |