Don't try to mmap past EOF
[qt-netbsd.git] / src / testlib / qtestlog.cpp
blobda695dc693053491f28ebd81a61fc1c26c7c1e9e
1 /****************************************************************************
2 **
3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
6 **
7 ** This file is part of the QtTest module of the Qt Toolkit.
8 **
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
14 ** this package.
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.
38 ** $QT_END_LICENSE$
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>
52 #include <stdlib.h>
53 #include <string.h>
54 #include <limits.h>
57 #include "qtestlogger_p.h"
59 QT_BEGIN_NAMESPACE
61 namespace QTest {
63 struct IgnoreResultList
65 inline IgnoreResultList(QtMsgType tp, const char *message)
66 : type(tp), next(0)
67 { msg = qstrdup(message); }
68 inline ~IgnoreResultList()
69 { delete [] msg; }
71 static inline void clearList(IgnoreResultList *&list)
73 while (list) {
74 IgnoreResultList *current = list;
75 list = list->next;
76 delete current;
80 QtMsgType type;
81 char *msg;
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;
101 while (list) {
102 if (list->type == type && strcmp(msg, list->msg) == 0) {
103 // remove the item from the list
104 if (last)
105 last->next = list->next;
106 else if (list->next)
107 ignoreResultList = list->next;
108 else
109 ignoreResultList = 0;
111 delete list;
112 return true;
115 last = list;
116 list = list->next;
118 return false;
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);
128 QTEST_ASSERT(msg);
129 QTEST_ASSERT(QTest::testLogger);
132 if (handleIgnoredMessage(type, msg))
133 // the message is expected, so just swallow it.
134 return;
136 if (type != QtFatalMsg) {
137 if (counter <= 0)
138 return;
140 if (!counter.deref()) {
141 QTest::testLogger->addMessage(QAbstractTestLogger::QSystem,
142 "Maximum amount of warnings exceeded. Use -maxwarnings to override.");
143 return;
147 switch (type) {
148 case QtDebugMsg:
149 QTest::testLogger->addMessage(QAbstractTestLogger::QDebug, msg);
150 break;
151 case QtCriticalMsg:
152 QTest::testLogger->addMessage(QAbstractTestLogger::QSystem, msg);
153 break;
154 case QtWarningMsg:
155 QTest::testLogger->addMessage(QAbstractTestLogger::QWarning, msg);
156 break;
157 case QtFatalMsg:
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();
167 break;
173 QTestLog::QTestLog()
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()
191 int i = 0;
192 QTest::IgnoreResultList *list = QTest::ignoreResultList;
193 while (list) {
194 ++i;
195 list = list->next;
197 return i;
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);
212 char msg[1024];
213 QTest::IgnoreResultList *list = QTest::ignoreResultList;
214 while (list) {
215 QTest::qt_snprintf(msg, 1024, "Did not receive message: \"%s\"", list->msg);
216 QTest::testLogger->addMessage(QAbstractTestLogger::Info, msg);
218 list = list->next;
222 void QTestLog::addPass(const char *msg)
224 QTEST_ASSERT(QTest::testLogger);
225 QTEST_ASSERT(msg);
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);
240 QTEST_ASSERT(msg);
241 QTEST_ASSERT(file);
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);
249 QTEST_ASSERT(msg);
250 QTEST_ASSERT(file);
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);
259 QTEST_ASSERT(msg);
260 QTEST_ASSERT(file);
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;
278 break;
279 case QTestLog::XML:{
280 if(QTest::flushMode == QTestLog::FLushOn)
281 QTest::testLogger = new QXmlTestLogger(QXmlTestLogger::Complete);
282 else
283 QTest::testLogger = new QTestLogger(QTestLogger::TLF_XML);
284 break;
285 }case QTestLog::LightXML:{
286 if(QTest::flushMode == QTestLog::FLushOn)
287 QTest::testLogger = new QXmlTestLogger(QXmlTestLogger::Light);
288 else
289 QTest::testLogger = new QTestLogger(QTestLogger::TLF_LightXml);
290 break;
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);
313 QTEST_ASSERT(msg);
315 QTest::testLogger->addMessage(QAbstractTestLogger::Warn, msg);
318 void QTestLog::info(const char *msg, const char *file, int line)
320 QTEST_ASSERT(msg);
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;
351 if (!list) {
352 QTest::ignoreResultList = item;
353 return;
355 while (list->next)
356 list = list->next;
357 list->next = 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;
382 QT_END_NAMESPACE