source: trunk/src/testlib/qtestlog.cpp@ 5

Last change on this file since 5 was 2, checked in by Dmitry A. Kuminov, 16 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

File size: 9.9 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** Contact: Qt Software Information ([email protected])
5**
6** This file is part of the QtTest module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial Usage
10** Licensees holding valid Qt Commercial licenses may use this file in
11** accordance with the Qt Commercial License Agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and Nokia.
14**
15** GNU Lesser General Public License Usage
16** Alternatively, this file may be used under the terms of the GNU Lesser
17** General Public License version 2.1 as published by the Free Software
18** Foundation and appearing in the file LICENSE.LGPL included in the
19** packaging of this file. Please review the following information to
20** ensure the GNU Lesser General Public License version 2.1 requirements
21** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
22**
23** In addition, as a special exception, Nokia gives you certain
24** additional rights. These rights are described in the Nokia Qt LGPL
25** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
26** package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you are unsure which license is appropriate for your use, please
37** contact the sales department at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "QtTest/qtestassert.h"
43
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
50#include <QtCore/qatomic.h>
51#include <QtCore/qbytearray.h>
52
53#include <stdlib.h>
54#include <string.h>
55#include <limits.h>
56
57QT_BEGIN_NAMESPACE
58
59namespace QTest {
60
61 struct IgnoreResultList
62 {
63 inline IgnoreResultList(QtMsgType tp, const char *message)
64 : type(tp), next(0)
65 { msg = qstrdup(message); }
66 inline ~IgnoreResultList()
67 { delete [] msg; }
68
69 static inline void clearList(IgnoreResultList *&list)
70 {
71 while (list) {
72 IgnoreResultList *current = list;
73 list = list->next;
74 delete current;
75 }
76 }
77
78 QtMsgType type;
79 char *msg;
80 IgnoreResultList *next;
81 };
82
83 static IgnoreResultList *ignoreResultList = 0;
84
85 static QTestLog::LogMode logMode = QTestLog::Plain;
86 static int verbosity = 0;
87 static int maxWarnings = 2002;
88
89 static QAbstractTestLogger *testLogger = 0;
90 static const char *outFile = 0;
91
92 static QtMsgHandler oldMessageHandler;
93
94 static bool handleIgnoredMessage(QtMsgType type, const char *msg)
95 {
96 IgnoreResultList *last = 0;
97 IgnoreResultList *list = ignoreResultList;
98 while (list) {
99 if (list->type == type && strcmp(msg, list->msg) == 0) {
100 // remove the item from the list
101 if (last)
102 last->next = list->next;
103 else if (list->next)
104 ignoreResultList = list->next;
105 else
106 ignoreResultList = 0;
107
108 delete list;
109 return true;
110 }
111
112 last = list;
113 list = list->next;
114 }
115 return false;
116 }
117
118 static void messageHandler(QtMsgType type, const char *msg)
119 {
120 static QBasicAtomicInt counter = Q_BASIC_ATOMIC_INITIALIZER(QTest::maxWarnings);
121
122 if (!msg || !QTest::testLogger) {
123 // if this goes wrong, something is seriously broken.
124 qInstallMsgHandler(oldMessageHandler);
125 QTEST_ASSERT(msg);
126 QTEST_ASSERT(QTest::testLogger);
127 }
128
129 if (handleIgnoredMessage(type, msg))
130 // the message is expected, so just swallow it.
131 return;
132
133 if (type != QtFatalMsg) {
134 if (counter <= 0)
135 return;
136
137 if (!counter.deref()) {
138 QTest::testLogger->addMessage(QAbstractTestLogger::QSystem,
139 "Maximum amount of warnings exceeded.");
140 return;
141 }
142 }
143
144 switch (type) {
145 case QtDebugMsg:
146 QTest::testLogger->addMessage(QAbstractTestLogger::QDebug, msg);
147 break;
148 case QtCriticalMsg:
149 QTest::testLogger->addMessage(QAbstractTestLogger::QSystem, msg);
150 break;
151 case QtWarningMsg:
152 QTest::testLogger->addMessage(QAbstractTestLogger::QWarning, msg);
153 break;
154 case QtFatalMsg:
155 QTest::testLogger->addMessage(QAbstractTestLogger::QFatal, msg);
156 /* Right now, we're inside the custom message handler and we're
157 * being qt_message_output in qglobal.cpp. After we return from
158 * this function, it will proceed with calling exit() and abort()
159 * and hence crash. Therefore, we call these logging functions such
160 * that we wrap up nicely, and in particular produce well-formed XML. */
161 QTestResult::addFailure("Received a fatal error.", "Unknown file", 0);
162 QTestLog::leaveTestFunction();
163 QTestLog::stopLogging();
164 break;
165 }
166 }
167
168}
169
170QTestLog::QTestLog()
171{
172}
173
174QTestLog::~QTestLog()
175{
176}
177
178void QTestLog::enterTestFunction(const char* function)
179{
180 QTEST_ASSERT(QTest::testLogger);
181 QTEST_ASSERT(function);
182
183 QTest::testLogger->enterTestFunction(function);
184}
185
186int QTestLog::unhandledIgnoreMessages()
187{
188 int i = 0;
189 QTest::IgnoreResultList *list = QTest::ignoreResultList;
190 while (list) {
191 ++i;
192 list = list->next;
193 }
194 return i;
195}
196
197void QTestLog::leaveTestFunction()
198{
199 QTEST_ASSERT(QTest::testLogger);
200
201 QTest::IgnoreResultList::clearList(QTest::ignoreResultList);
202 QTest::testLogger->leaveTestFunction();
203}
204
205void QTestLog::printUnhandledIgnoreMessages()
206{
207 QTEST_ASSERT(QTest::testLogger);
208
209 char msg[1024];
210 QTest::IgnoreResultList *list = QTest::ignoreResultList;
211 while (list) {
212 QTest::qt_snprintf(msg, 1024, "Did not receive message: \"%s\"", list->msg);
213 QTest::testLogger->addMessage(QAbstractTestLogger::Info, msg);
214
215 list = list->next;
216 }
217}
218
219void QTestLog::addPass(const char *msg)
220{
221 QTEST_ASSERT(QTest::testLogger);
222 QTEST_ASSERT(msg);
223
224 QTest::testLogger->addIncident(QAbstractTestLogger::Pass, msg);
225}
226
227void QTestLog::addFail(const char *msg, const char *file, int line)
228{
229 QTEST_ASSERT(QTest::testLogger);
230
231 QTest::testLogger->addIncident(QAbstractTestLogger::Fail, msg, file, line);
232}
233
234void QTestLog::addXFail(const char *msg, const char *file, int line)
235{
236 QTEST_ASSERT(QTest::testLogger);
237 QTEST_ASSERT(msg);
238 QTEST_ASSERT(file);
239
240 QTest::testLogger->addIncident(QAbstractTestLogger::XFail, msg, file, line);
241}
242
243void QTestLog::addXPass(const char *msg, const char *file, int line)
244{
245 QTEST_ASSERT(QTest::testLogger);
246 QTEST_ASSERT(msg);
247 QTEST_ASSERT(file);
248
249 QTest::testLogger->addIncident(QAbstractTestLogger::XPass, msg, file, line);
250}
251
252void QTestLog::addSkip(const char *msg, QTest::SkipMode /*mode*/,
253 const char *file, int line)
254{
255 QTEST_ASSERT(QTest::testLogger);
256 QTEST_ASSERT(msg);
257 QTEST_ASSERT(file);
258
259 QTest::testLogger->addMessage(QAbstractTestLogger::Skip, msg, file, line);
260}
261
262void QTestLog::addBenchmarkResult(const QBenchmarkResult &result)
263{
264 QTEST_ASSERT(QTest::testLogger);
265 QTest::testLogger->addBenchmarkResult(result);
266}
267
268void QTestLog::startLogging()
269{
270 QTEST_ASSERT(!QTest::testLogger);
271
272 switch (QTest::logMode) {
273 case QTestLog::Plain:
274 QTest::testLogger = new QPlainTestLogger();
275 break;
276 case QTestLog::XML:
277 QTest::testLogger = new QXmlTestLogger(QXmlTestLogger::Complete);
278 break;
279 case QTestLog::LightXML:
280 QTest::testLogger = new QXmlTestLogger(QXmlTestLogger::Light);
281 }
282
283 QTest::testLogger->startLogging();
284
285 QTest::oldMessageHandler = qInstallMsgHandler(QTest::messageHandler);
286}
287
288void QTestLog::stopLogging()
289{
290 qInstallMsgHandler(QTest::oldMessageHandler);
291
292 QTEST_ASSERT(QTest::testLogger);
293 QTest::testLogger->stopLogging();
294 delete QTest::testLogger;
295 QTest::testLogger = 0;
296}
297
298void QTestLog::warn(const char *msg)
299{
300 QTEST_ASSERT(msg);
301
302 QTest::testLogger->addMessage(QAbstractTestLogger::Warn, msg);
303}
304
305void QTestLog::info(const char *msg, const char *file, int line)
306{
307 QTEST_ASSERT(msg);
308
309 if (QTest::testLogger)
310 QTest::testLogger->addMessage(QAbstractTestLogger::Info, msg, file, line);
311}
312
313void QTestLog::setLogMode(LogMode mode)
314{
315 QTest::logMode = mode;
316}
317
318QTestLog::LogMode QTestLog::logMode()
319{
320 return QTest::logMode;
321}
322
323void QTestLog::setVerboseLevel(int level)
324{
325 QTest::verbosity = level;
326}
327
328int QTestLog::verboseLevel()
329{
330 return QTest::verbosity;
331}
332
333void QTestLog::addIgnoreMessage(QtMsgType type, const char *msg)
334{
335 QTest::IgnoreResultList *item = new QTest::IgnoreResultList(type, msg);
336
337 QTest::IgnoreResultList *list = QTest::ignoreResultList;
338 if (!list) {
339 QTest::ignoreResultList = item;
340 return;
341 }
342 while (list->next)
343 list = list->next;
344 list->next = item;
345}
346
347void QTestLog::redirectOutput(const char *fileName)
348{
349 QTEST_ASSERT(fileName);
350
351 QTest::outFile = fileName;
352}
353
354const char *QTestLog::outputFileName()
355{
356 return QTest::outFile;
357}
358
359void QTestLog::setMaxWarnings(int m)
360{
361 QTest::maxWarnings = m <= 0 ? INT_MAX : m + 2;
362}
363
364QT_END_NAMESPACE
Note: See TracBrowser for help on using the repository browser.