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

Last change on this file since 561 was 561, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.6.1 sources.

File size: 10.6 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the QtTest module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
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.
23**
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.
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 have questions regarding the use of this file, please contact
37** Nokia 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#include <QtCore/qatomic.h>
50#include <QtCore/qbytearray.h>
51
52#include <stdlib.h>
53#include <string.h>
54#include <limits.h>
55
56
57#include "qtestlogger_p.h"
58
59QT_BEGIN_NAMESPACE
60
61namespace QTest {
62
63 struct IgnoreResultList
64 {
65 inline IgnoreResultList(QtMsgType tp, const char *message)
66 : type(tp), next(0)
67 { msg = qstrdup(message); }
68 inline ~IgnoreResultList()
69 { delete [] msg; }
70
71 static inline void clearList(IgnoreResultList *&list)
72 {
73 while (list) {
74 IgnoreResultList *current = list;
75 list = list->next;
76 delete current;
77 }
78 }
79
80 QtMsgType type;
81 char *msg;
82 IgnoreResultList *next;
83 };
84
85 static IgnoreResultList *ignoreResultList = 0;
86
87 static QTestLog::LogMode logMode = QTestLog::Plain;
88 static QTestLog::FlushMode flushMode = QTestLog::NoFlush;
89 static int verbosity = 0;
90 static int maxWarnings = 2002;
91
92 static QAbstractTestLogger *testLogger = 0;
93 static const char *outFile = 0;
94
95 static QtMsgHandler oldMessageHandler;
96
97 static bool handleIgnoredMessage(QtMsgType type, const char *msg)
98 {
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;
110
111 delete list;
112 return true;
113 }
114
115 last = list;
116 list = list->next;
117 }
118 return false;
119 }
120
121 static void messageHandler(QtMsgType type, const char *msg)
122 {
123 static QBasicAtomicInt counter = Q_BASIC_ATOMIC_INITIALIZER(QTest::maxWarnings);
124
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);
130 }
131
132 if (handleIgnoredMessage(type, msg))
133 // the message is expected, so just swallow it.
134 return;
135
136 if (type != QtFatalMsg) {
137 if (counter <= 0)
138 return;
139
140 if (!counter.deref()) {
141 QTest::testLogger->addMessage(QAbstractTestLogger::QSystem,
142 "Maximum amount of warnings exceeded. Use -maxwarnings to override.");
143 return;
144 }
145 }
146
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;
168 }
169 }
170
171}
172
173QTestLog::QTestLog()
174{
175}
176
177QTestLog::~QTestLog()
178{
179}
180
181void QTestLog::enterTestFunction(const char* function)
182{
183 QTEST_ASSERT(QTest::testLogger);
184 QTEST_ASSERT(function);
185
186 QTest::testLogger->enterTestFunction(function);
187}
188
189int QTestLog::unhandledIgnoreMessages()
190{
191 int i = 0;
192 QTest::IgnoreResultList *list = QTest::ignoreResultList;
193 while (list) {
194 ++i;
195 list = list->next;
196 }
197 return i;
198}
199
200void QTestLog::leaveTestFunction()
201{
202 QTEST_ASSERT(QTest::testLogger);
203
204 QTest::IgnoreResultList::clearList(QTest::ignoreResultList);
205 QTest::testLogger->leaveTestFunction();
206}
207
208void QTestLog::printUnhandledIgnoreMessages()
209{
210 QTEST_ASSERT(QTest::testLogger);
211
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);
217
218 list = list->next;
219 }
220}
221
222void QTestLog::addPass(const char *msg)
223{
224 QTEST_ASSERT(QTest::testLogger);
225 QTEST_ASSERT(msg);
226
227 QTest::testLogger->addIncident(QAbstractTestLogger::Pass, msg);
228}
229
230void QTestLog::addFail(const char *msg, const char *file, int line)
231{
232 QTEST_ASSERT(QTest::testLogger);
233
234 QTest::testLogger->addIncident(QAbstractTestLogger::Fail, msg, file, line);
235}
236
237void QTestLog::addXFail(const char *msg, const char *file, int line)
238{
239 QTEST_ASSERT(QTest::testLogger);
240 QTEST_ASSERT(msg);
241 QTEST_ASSERT(file);
242
243 QTest::testLogger->addIncident(QAbstractTestLogger::XFail, msg, file, line);
244}
245
246void QTestLog::addXPass(const char *msg, const char *file, int line)
247{
248 QTEST_ASSERT(QTest::testLogger);
249 QTEST_ASSERT(msg);
250 QTEST_ASSERT(file);
251
252 QTest::testLogger->addIncident(QAbstractTestLogger::XPass, msg, file, line);
253}
254
255void QTestLog::addSkip(const char *msg, QTest::SkipMode /*mode*/,
256 const char *file, int line)
257{
258 QTEST_ASSERT(QTest::testLogger);
259 QTEST_ASSERT(msg);
260 QTEST_ASSERT(file);
261
262 QTest::testLogger->addMessage(QAbstractTestLogger::Skip, msg, file, line);
263}
264
265void QTestLog::addBenchmarkResult(const QBenchmarkResult &result)
266{
267 QTEST_ASSERT(QTest::testLogger);
268 QTest::testLogger->addBenchmarkResult(result);
269}
270
271void QTestLog::startLogging()
272{
273 QTEST_ASSERT(!QTest::testLogger);
274
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);
293 }
294
295 QTest::testLogger->startLogging();
296
297 QTest::oldMessageHandler = qInstallMsgHandler(QTest::messageHandler);
298}
299
300void QTestLog::stopLogging()
301{
302 qInstallMsgHandler(QTest::oldMessageHandler);
303
304 QTEST_ASSERT(QTest::testLogger);
305 QTest::testLogger->stopLogging();
306 delete QTest::testLogger;
307 QTest::testLogger = 0;
308}
309
310void QTestLog::warn(const char *msg)
311{
312 QTEST_ASSERT(QTest::testLogger);
313 QTEST_ASSERT(msg);
314
315 QTest::testLogger->addMessage(QAbstractTestLogger::Warn, msg);
316}
317
318void QTestLog::info(const char *msg, const char *file, int line)
319{
320 QTEST_ASSERT(msg);
321
322 if (QTest::testLogger)
323 QTest::testLogger->addMessage(QAbstractTestLogger::Info, msg, file, line);
324}
325
326void QTestLog::setLogMode(LogMode mode)
327{
328 QTest::logMode = mode;
329}
330
331QTestLog::LogMode QTestLog::logMode()
332{
333 return QTest::logMode;
334}
335
336void QTestLog::setVerboseLevel(int level)
337{
338 QTest::verbosity = level;
339}
340
341int QTestLog::verboseLevel()
342{
343 return QTest::verbosity;
344}
345
346void QTestLog::addIgnoreMessage(QtMsgType type, const char *msg)
347{
348 QTest::IgnoreResultList *item = new QTest::IgnoreResultList(type, msg);
349
350 QTest::IgnoreResultList *list = QTest::ignoreResultList;
351 if (!list) {
352 QTest::ignoreResultList = item;
353 return;
354 }
355 while (list->next)
356 list = list->next;
357 list->next = item;
358}
359
360void QTestLog::redirectOutput(const char *fileName)
361{
362 QTEST_ASSERT(fileName);
363
364 QTest::outFile = fileName;
365}
366
367const char *QTestLog::outputFileName()
368{
369 return QTest::outFile;
370}
371
372void QTestLog::setMaxWarnings(int m)
373{
374 QTest::maxWarnings = m <= 0 ? INT_MAX : m + 2;
375}
376
377void QTestLog::setFlushMode(FlushMode mode)
378{
379 QTest::flushMode = mode;
380}
381
382QT_END_NAMESPACE
Note: See TracBrowser for help on using the repository browser.