1 /****************************************************************************
3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the QtTest module of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** No Commercial Usage
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
16 ** GNU Lesser General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU Lesser
18 ** General Public License version 2.1 as published by the Free Software
19 ** Foundation and appearing in the file LICENSE.LGPL included in the
20 ** packaging of this file. Please review the following information to
21 ** ensure the GNU Lesser General Public License version 2.1 requirements
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 ** In addition, as a special exception, Nokia gives you certain additional
25 ** rights. These rights are described in the Nokia Qt LGPL Exception
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
40 ****************************************************************************/
42 #include "QtTest/qtestassert.h"
44 #include "QtTest/private/qtestlog_p.h"
45 #include "QtTest/private/qtestresult_p.h"
46 #include "QtTest/private/qabstracttestlogger_p.h"
47 #include "QtTest/private/qplaintestlogger_p.h"
48 #include "QtTest/private/qxmltestlogger_p.h"
49 #include <QtCore/qatomic.h>
50 #include <QtCore/qbytearray.h>
57 #include "qtestlogger_p.h"
63 struct IgnoreResultList
65 inline IgnoreResultList(QtMsgType tp
, const char *message
)
67 { msg
= qstrdup(message
); }
68 inline ~IgnoreResultList()
71 static inline void clearList(IgnoreResultList
*&list
)
74 IgnoreResultList
*current
= list
;
82 IgnoreResultList
*next
;
85 static IgnoreResultList
*ignoreResultList
= 0;
87 static QTestLog::LogMode logMode
= QTestLog::Plain
;
88 static QTestLog::FlushMode flushMode
= QTestLog::NoFlush
;
89 static int verbosity
= 0;
90 static int maxWarnings
= 2002;
92 static QAbstractTestLogger
*testLogger
= 0;
93 static const char *outFile
= 0;
95 static QtMsgHandler oldMessageHandler
;
97 static bool handleIgnoredMessage(QtMsgType type
, const char *msg
)
99 IgnoreResultList
*last
= 0;
100 IgnoreResultList
*list
= ignoreResultList
;
102 if (list
->type
== type
&& strcmp(msg
, list
->msg
) == 0) {
103 // remove the item from the list
105 last
->next
= list
->next
;
107 ignoreResultList
= list
->next
;
109 ignoreResultList
= 0;
121 static void messageHandler(QtMsgType type
, const char *msg
)
123 static QBasicAtomicInt counter
= Q_BASIC_ATOMIC_INITIALIZER(QTest::maxWarnings
);
125 if (!msg
|| !QTest::testLogger
) {
126 // if this goes wrong, something is seriously broken.
127 qInstallMsgHandler(oldMessageHandler
);
129 QTEST_ASSERT(QTest::testLogger
);
132 if (handleIgnoredMessage(type
, msg
))
133 // the message is expected, so just swallow it.
136 if (type
!= QtFatalMsg
) {
140 if (!counter
.deref()) {
141 QTest::testLogger
->addMessage(QAbstractTestLogger::QSystem
,
142 "Maximum amount of warnings exceeded. Use -maxwarnings to override.");
149 QTest::testLogger
->addMessage(QAbstractTestLogger::QDebug
, msg
);
152 QTest::testLogger
->addMessage(QAbstractTestLogger::QSystem
, msg
);
155 QTest::testLogger
->addMessage(QAbstractTestLogger::QWarning
, msg
);
158 QTest::testLogger
->addMessage(QAbstractTestLogger::QFatal
, msg
);
159 /* Right now, we're inside the custom message handler and we're
160 * being qt_message_output in qglobal.cpp. After we return from
161 * this function, it will proceed with calling exit() and abort()
162 * and hence crash. Therefore, we call these logging functions such
163 * that we wrap up nicely, and in particular produce well-formed XML. */
164 QTestResult::addFailure("Received a fatal error.", "Unknown file", 0);
165 QTestLog::leaveTestFunction();
166 QTestLog::stopLogging();
177 QTestLog::~QTestLog()
181 void QTestLog::enterTestFunction(const char* function
)
183 QTEST_ASSERT(QTest::testLogger
);
184 QTEST_ASSERT(function
);
186 QTest::testLogger
->enterTestFunction(function
);
189 int QTestLog::unhandledIgnoreMessages()
192 QTest::IgnoreResultList
*list
= QTest::ignoreResultList
;
200 void QTestLog::leaveTestFunction()
202 QTEST_ASSERT(QTest::testLogger
);
204 QTest::IgnoreResultList::clearList(QTest::ignoreResultList
);
205 QTest::testLogger
->leaveTestFunction();
208 void QTestLog::printUnhandledIgnoreMessages()
210 QTEST_ASSERT(QTest::testLogger
);
213 QTest::IgnoreResultList
*list
= QTest::ignoreResultList
;
215 QTest::qt_snprintf(msg
, 1024, "Did not receive message: \"%s\"", list
->msg
);
216 QTest::testLogger
->addMessage(QAbstractTestLogger::Info
, msg
);
222 void QTestLog::addPass(const char *msg
)
224 QTEST_ASSERT(QTest::testLogger
);
227 QTest::testLogger
->addIncident(QAbstractTestLogger::Pass
, msg
);
230 void QTestLog::addFail(const char *msg
, const char *file
, int line
)
232 QTEST_ASSERT(QTest::testLogger
);
234 QTest::testLogger
->addIncident(QAbstractTestLogger::Fail
, msg
, file
, line
);
237 void QTestLog::addXFail(const char *msg
, const char *file
, int line
)
239 QTEST_ASSERT(QTest::testLogger
);
243 QTest::testLogger
->addIncident(QAbstractTestLogger::XFail
, msg
, file
, line
);
246 void QTestLog::addXPass(const char *msg
, const char *file
, int line
)
248 QTEST_ASSERT(QTest::testLogger
);
252 QTest::testLogger
->addIncident(QAbstractTestLogger::XPass
, msg
, file
, line
);
255 void QTestLog::addSkip(const char *msg
, QTest::SkipMode
/*mode*/,
256 const char *file
, int line
)
258 QTEST_ASSERT(QTest::testLogger
);
262 QTest::testLogger
->addMessage(QAbstractTestLogger::Skip
, msg
, file
, line
);
265 void QTestLog::addBenchmarkResult(const QBenchmarkResult
&result
)
267 QTEST_ASSERT(QTest::testLogger
);
268 QTest::testLogger
->addBenchmarkResult(result
);
271 void QTestLog::startLogging()
273 QTEST_ASSERT(!QTest::testLogger
);
275 switch (QTest::logMode
) {
276 case QTestLog::Plain
:
277 QTest::testLogger
= new QPlainTestLogger
;
280 if(QTest::flushMode
== QTestLog::FLushOn
)
281 QTest::testLogger
= new QXmlTestLogger(QXmlTestLogger::Complete
);
283 QTest::testLogger
= new QTestLogger(QTestLogger::TLF_XML
);
285 }case QTestLog::LightXML
:{
286 if(QTest::flushMode
== QTestLog::FLushOn
)
287 QTest::testLogger
= new QXmlTestLogger(QXmlTestLogger::Light
);
289 QTest::testLogger
= new QTestLogger(QTestLogger::TLF_LightXml
);
291 }case QTestLog::XunitXML
:
292 QTest::testLogger
= new QTestLogger(QTestLogger::TLF_XunitXml
);
295 QTest::testLogger
->startLogging();
297 QTest::oldMessageHandler
= qInstallMsgHandler(QTest::messageHandler
);
300 void QTestLog::stopLogging()
302 qInstallMsgHandler(QTest::oldMessageHandler
);
304 QTEST_ASSERT(QTest::testLogger
);
305 QTest::testLogger
->stopLogging();
306 delete QTest::testLogger
;
307 QTest::testLogger
= 0;
310 void QTestLog::warn(const char *msg
)
312 QTEST_ASSERT(QTest::testLogger
);
315 QTest::testLogger
->addMessage(QAbstractTestLogger::Warn
, msg
);
318 void QTestLog::info(const char *msg
, const char *file
, int line
)
322 if (QTest::testLogger
)
323 QTest::testLogger
->addMessage(QAbstractTestLogger::Info
, msg
, file
, line
);
326 void QTestLog::setLogMode(LogMode mode
)
328 QTest::logMode
= mode
;
331 QTestLog::LogMode
QTestLog::logMode()
333 return QTest::logMode
;
336 void QTestLog::setVerboseLevel(int level
)
338 QTest::verbosity
= level
;
341 int QTestLog::verboseLevel()
343 return QTest::verbosity
;
346 void QTestLog::addIgnoreMessage(QtMsgType type
, const char *msg
)
348 QTest::IgnoreResultList
*item
= new QTest::IgnoreResultList(type
, msg
);
350 QTest::IgnoreResultList
*list
= QTest::ignoreResultList
;
352 QTest::ignoreResultList
= item
;
360 void QTestLog::redirectOutput(const char *fileName
)
362 QTEST_ASSERT(fileName
);
364 QTest::outFile
= fileName
;
367 const char *QTestLog::outputFileName()
369 return QTest::outFile
;
372 void QTestLog::setMaxWarnings(int m
)
374 QTest::maxWarnings
= m
<= 0 ? INT_MAX
: m
+ 2;
377 void QTestLog::setFlushMode(FlushMode mode
)
379 QTest::flushMode
= mode
;