summaryrefslogtreecommitdiffstats
path: root/src/testlib/qtestcase.cpp
diff options
context:
space:
mode:
authorAlexandru Croitor <alexandru.croitor@qt.io>2019-10-14 17:46:16 +0200
committerAlexandru Croitor <alexandru.croitor@qt.io>2019-10-14 17:46:34 +0200
commit440286655e0ca271506cf7cc02ad0dbf4baef9ca (patch)
tree896fa81adb8b14a69355a3a6cf64d06ec8173c9a /src/testlib/qtestcase.cpp
parent1e27ad1697187549151657ba187928e439300db7 (diff)
parente164d61ca8263fc4b46fdd916e1ea77c7dd2b735 (diff)
Merge remote-tracking branch 'origin/dev' into wip/cmake
Diffstat (limited to 'src/testlib/qtestcase.cpp')
-rw-r--r--src/testlib/qtestcase.cpp92
1 files changed, 63 insertions, 29 deletions
diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp
index 839f556430..7f5725a60c 100644
--- a/src/testlib/qtestcase.cpp
+++ b/src/testlib/qtestcase.cpp
@@ -58,8 +58,8 @@
#include <QtCore/qdiriterator.h>
#include <QtCore/qtemporarydir.h>
#include <QtCore/qthread.h>
-#include <QtCore/qwaitcondition.h>
-#include <QtCore/qmutex.h>
+#include <QtCore/private/qlocking_p.h>
+#include <QtCore/private/qwaitcondition_p.h>
#include <QtCore/qtestsupport_core.h>
@@ -85,6 +85,9 @@
#include <cmath>
#include <numeric>
#include <algorithm>
+#include <condition_variable>
+#include <mutex>
+#include <chrono>
#include <stdarg.h>
#include <stdio.h>
@@ -406,7 +409,7 @@ int Q_TESTLIB_EXPORT defaultKeyDelay()
return keyDelay;
}
#if QT_CONFIG(thread)
-static int defaultTimeout()
+static std::chrono::milliseconds defaultTimeout()
{
if (timeout == -1) {
bool ok = false;
@@ -415,7 +418,7 @@ static int defaultTimeout()
if (!ok || timeout <= 0)
timeout = 5*60*1000;
}
- return timeout;
+ return std::chrono::milliseconds{timeout};
}
#endif
@@ -1008,53 +1011,81 @@ void TestMethods::invokeTestOnData(int index) const
class WatchDog : public QThread
{
+ enum Expectation {
+ ThreadStart,
+ TestFunctionStart,
+ TestFunctionEnd,
+ ThreadEnd,
+ };
+
+ bool waitFor(std::unique_lock<QtPrivate::mutex> &m, Expectation e) {
+ auto expectationChanged = [this, e] { return expecting != e; };
+ switch (e) {
+ case TestFunctionEnd:
+ return waitCondition.wait_for(m, defaultTimeout(), expectationChanged);
+ case ThreadStart:
+ case ThreadEnd:
+ case TestFunctionStart:
+ waitCondition.wait(m, expectationChanged);
+ return true;
+ }
+ Q_UNREACHABLE();
+ return false;
+ }
+
public:
WatchDog()
{
- QMutexLocker locker(&mutex);
- timeout.storeRelaxed(-1);
+ auto locker = qt_unique_lock(mutex);
+ expecting = ThreadStart;
start();
- waitCondition.wait(&mutex);
+ waitFor(locker, ThreadStart);
}
~WatchDog() {
{
- QMutexLocker locker(&mutex);
- timeout.storeRelaxed(0);
- waitCondition.wakeAll();
+ const auto locker = qt_scoped_lock(mutex);
+ expecting = ThreadEnd;
+ waitCondition.notify_all();
}
wait();
}
void beginTest() {
- QMutexLocker locker(&mutex);
- timeout.storeRelaxed(defaultTimeout());
- waitCondition.wakeAll();
+ const auto locker = qt_scoped_lock(mutex);
+ expecting = TestFunctionEnd;
+ waitCondition.notify_all();
}
void testFinished() {
- QMutexLocker locker(&mutex);
- timeout.storeRelaxed(-1);
- waitCondition.wakeAll();
+ const auto locker = qt_scoped_lock(mutex);
+ expecting = TestFunctionStart;
+ waitCondition.notify_all();
}
void run() override {
- QMutexLocker locker(&mutex);
- waitCondition.wakeAll();
+ auto locker = qt_unique_lock(mutex);
+ expecting = TestFunctionStart;
+ waitCondition.notify_all();
while (true) {
- int t = timeout.loadRelaxed();
- if (!t)
- break;
- if (Q_UNLIKELY(!waitCondition.wait(&mutex, t))) {
- stackTrace();
- qFatal("Test function timed out");
+ switch (expecting) {
+ case ThreadEnd:
+ return;
+ case ThreadStart:
+ Q_UNREACHABLE();
+ case TestFunctionStart:
+ case TestFunctionEnd:
+ if (Q_UNLIKELY(!waitFor(locker, expecting))) {
+ stackTrace();
+ qFatal("Test function timed out");
+ }
}
}
}
private:
- QBasicAtomicInt timeout;
- QMutex mutex;
- QWaitCondition waitCondition;
+ QtPrivate::mutex mutex;
+ QtPrivate::condition_variable waitCondition;
+ Expectation expecting;
};
#else // !QT_CONFIG(thread)
@@ -2790,8 +2821,11 @@ template <> Q_TESTLIB_EXPORT char *QTest::toString<char>(const char &t)
*/
char *QTest::toString(const char *str)
{
- if (!str)
- return nullptr;
+ if (!str) {
+ char *msg = new char[1];
+ *msg = '\0';
+ return msg;
+ }
char *msg = new char[strlen(str) + 1];
return qstrcpy(msg, str);
}