summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Faure <[email protected]>2025-03-26 12:03:02 +0100
committerDavid Faure <[email protected]>2025-04-02 15:41:17 +0100
commitb4d6892ba5a745c1836daf34c850d13ef61e7ae0 (patch)
tree8a86a501b6ca6b76e349c2818360e83c92c4a6ee
parente2790a6758be18add2bcab42cc7dfebdd74daae1 (diff)
QTestLib: fix crashes when using qDebug()s from threads with -junitxml
Other test loggers just output things immediately, but the junit test logger appends messages to a vector, so this needs to be mutex-protected. In case of qDebug()s from long-running threads, we also need to protect creation/destruction of systemOutputElement and systemErrorElement -- and in case of qFatal(), currentTestCase. Pick-to: 6.9 6.8 6.5 Change-Id: If35055fc232276a778951ebbfeaccd185b04f46b Reviewed-by: Edward Welbourne <[email protected]> Reviewed-by: Jason McDonald <[email protected]>
-rw-r--r--src/testlib/qjunittestlogger.cpp21
-rw-r--r--src/testlib/qjunittestlogger_p.h4
2 files changed, 17 insertions, 8 deletions
diff --git a/src/testlib/qjunittestlogger.cpp b/src/testlib/qjunittestlogger.cpp
index 2ba6e71bb98..ef4f1561c15 100644
--- a/src/testlib/qjunittestlogger.cpp
+++ b/src/testlib/qjunittestlogger.cpp
@@ -130,14 +130,17 @@ void QJUnitTestLogger::enterTestFunction(const char *function)
void QJUnitTestLogger::enterTestCase(const char *name)
{
- currentTestCase = new QTestElement(QTest::LET_TestCase);
- currentTestCase->addAttribute(QTest::AI_Name, name);
- currentTestCase->addAttribute(QTest::AI_Classname, QTestResult::currentTestObjectName());
- listOfTestcases.push_back(currentTestCase);
-
- Q_ASSERT(!systemOutputElement && !systemErrorElement);
- systemOutputElement = new QTestElement(QTest::LET_SystemOutput);
- systemErrorElement = new QTestElement(QTest::LET_SystemError);
+ {
+ QMutexLocker locker(&mutex);
+ currentTestCase = new QTestElement(QTest::LET_TestCase);
+ currentTestCase->addAttribute(QTest::AI_Name, name);
+ currentTestCase->addAttribute(QTest::AI_Classname, QTestResult::currentTestObjectName());
+ listOfTestcases.push_back(currentTestCase);
+
+ Q_ASSERT(!systemOutputElement && !systemErrorElement);
+ systemOutputElement = new QTestElement(QTest::LET_SystemOutput);
+ systemErrorElement = new QTestElement(QTest::LET_SystemError);
+ }
// The element will be deleted when the suite is deleted
@@ -174,6 +177,7 @@ void QJUnitTestLogger::leaveTestFunction()
void QJUnitTestLogger::leaveTestCase()
{
+ QMutexLocker locker(&mutex);
currentTestCase->addAttribute(QTest::AI_Time,
toSecondsFormat(elapsedTestCaseSeconds() * 1000).constData());
@@ -257,6 +261,7 @@ void QJUnitTestLogger::addMessage(MessageTypes type, const QString &message, con
Q_UNUSED(file);
Q_UNUSED(line);
+ QMutexLocker locker(&mutex);
if (type == QFatal) {
addFailure(QTest::LET_Error, "qfatal", message);
return;
diff --git a/src/testlib/qjunittestlogger_p.h b/src/testlib/qjunittestlogger_p.h
index 6a7ff316152..6c4c7d71f2a 100644
--- a/src/testlib/qjunittestlogger_p.h
+++ b/src/testlib/qjunittestlogger_p.h
@@ -19,6 +19,7 @@
#include <QtTest/private/qabstracttestlogger_p.h>
#include <QtTest/private/qtestelementattribute_p.h>
+#include <QtCore/qmutex.h>
#include <vector>
@@ -61,6 +62,9 @@ class QJUnitTestLogger : public QAbstractTestLogger
QTestElement *systemOutputElement = nullptr;
QTestElement *systemErrorElement = nullptr;
QTestJUnitStreamer *logFormatter = nullptr;
+ // protects currentTestCase, systemOutputElement and systemErrorElement
+ // in case of qDebug()/qWarning() etc. from threads
+ QMutex mutex;
int testCounter = 0;
int failureCounter = 0;