diff options
author | Jason McDonald <jason.mcdonald@nokia.com> | 2011-09-02 19:08:21 +1000 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2011-09-23 00:34:23 +0200 |
commit | 51589e834e086de93a121a1c628c3492d88a15a7 (patch) | |
tree | 6d1506f12c3dc9eb37d8471e8e0b1d1a821c2cac /src/testlib/qtestlog.cpp | |
parent | 157fc88f90c42c6ff1b47b1bad018565fe63f626 (diff) |
Allow tests to log to multiple destinations
Each destination and the format of output to write there is specified by
adding "-o filename,format" to the command-line. The special filename
"-" indicates that the log output is written to the standard output
stream, though standard output can be used as a destination at most
once.
The old-style testlib output options are still supported, but can only
be used to specify one logging destination, as before.
If no logging options are given on the command-line, a plain text log
will go to the console, as before.
To log to the console in plain text and to the file "test_output" in
xunit format, one would invoke a test in the following way:
tst_foo -o test_output,xunitxml -o -,txt
This commit also enhances the selftests to test with multiple loggers,
but negative tests (e.g. bad combinations of command-line options) are
left for future task QTBUG-21567.
Task-number: QTBUG-20615
Change-Id: If91e752bc7001657e15e427aba9d25ab0a29a0b0
Reviewed-on: http://codereview.qt-project.org/4125
Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com>
Reviewed-by: Rohan McGovern <rohan.mcgovern@nokia.com>
Diffstat (limited to 'src/testlib/qtestlog.cpp')
-rw-r--r-- | src/testlib/qtestlog.cpp | 192 |
1 files changed, 139 insertions, 53 deletions
diff --git a/src/testlib/qtestlog.cpp b/src/testlib/qtestlog.cpp index d53b00ca7f..f3b416d3d1 100644 --- a/src/testlib/qtestlog.cpp +++ b/src/testlib/qtestlog.cpp @@ -82,12 +82,103 @@ namespace QTest { static IgnoreResultList *ignoreResultList = 0; - static QTestLog::LogMode logMode = QTestLog::Plain; + struct LoggerList + { + QAbstractTestLogger *logger; + LoggerList *next; + }; + + class TestLoggers + { + public: + static void addLogger(QAbstractTestLogger *logger) + { + LoggerList *l = new LoggerList; + l->logger = logger; + l->next = loggers; + loggers = l; + } + + static void destroyLoggers() + { + while (loggers) { + LoggerList *l = loggers; + loggers = loggers->next; + delete l->logger; + delete l; + } + } + +#define FOREACH_LOGGER(operation) \ + LoggerList *l = loggers; \ + while (l) { \ + QAbstractTestLogger *logger = l->logger; \ + Q_UNUSED(logger); \ + operation; \ + l = l->next; \ + } + + static void startLogging() + { + FOREACH_LOGGER(logger->startLogging()); + } + + static void stopLogging() + { + FOREACH_LOGGER(logger->stopLogging()); + } + + static void enterTestFunction(const char *function) + { + FOREACH_LOGGER(logger->enterTestFunction(function)); + } + + static void leaveTestFunction() + { + FOREACH_LOGGER(logger->leaveTestFunction()); + } + + static void addIncident(QAbstractTestLogger::IncidentTypes type, const char *description, + const char *file = 0, int line = 0) + { + FOREACH_LOGGER(logger->addIncident(type, description, file, line)); + } + + static void addBenchmarkResult(const QBenchmarkResult &result) + { + FOREACH_LOGGER(logger->addBenchmarkResult(result)); + } + + static void addMessage(QAbstractTestLogger::MessageTypes type, const char *message, + const char *file = 0, int line = 0) + { + FOREACH_LOGGER(logger->addMessage(type, message, file, line)); + } + + static void outputString(const char *msg) + { + FOREACH_LOGGER(logger->outputString(msg)); + } + + static int loggerCount() + { + int count = 0; + FOREACH_LOGGER(++count); + return count; + } + + private: + static LoggerList *loggers; + }; + +#undef FOREACH_LOGGER + + LoggerList *TestLoggers::loggers = 0; + static bool loggerUsingStdout = false; + static int verbosity = 0; static int maxWarnings = 2002; - static QAbstractTestLogger *testLogger = 0; - static QtMsgHandler oldMessageHandler; static bool handleIgnoredMessage(QtMsgType type, const char *msg) @@ -118,11 +209,11 @@ namespace QTest { { static QBasicAtomicInt counter = Q_BASIC_ATOMIC_INITIALIZER(QTest::maxWarnings); - if (!msg || !QTest::testLogger) { + if (!msg || QTest::TestLoggers::loggerCount() == 0) { // if this goes wrong, something is seriously broken. qInstallMsgHandler(oldMessageHandler); QTEST_ASSERT(msg); - QTEST_ASSERT(QTest::testLogger); + QTEST_ASSERT(QTest::TestLoggers::loggerCount() != 0); } if (handleIgnoredMessage(type, msg)) @@ -134,7 +225,7 @@ namespace QTest { return; if (!counter.deref()) { - QTest::testLogger->addMessage(QAbstractTestLogger::QSystem, + QTest::TestLoggers::addMessage(QAbstractTestLogger::QSystem, "Maximum amount of warnings exceeded. Use -maxwarnings to override."); return; } @@ -142,16 +233,16 @@ namespace QTest { switch (type) { case QtDebugMsg: - QTest::testLogger->addMessage(QAbstractTestLogger::QDebug, msg); + QTest::TestLoggers::addMessage(QAbstractTestLogger::QDebug, msg); break; case QtCriticalMsg: - QTest::testLogger->addMessage(QAbstractTestLogger::QSystem, msg); + QTest::TestLoggers::addMessage(QAbstractTestLogger::QSystem, msg); break; case QtWarningMsg: - QTest::testLogger->addMessage(QAbstractTestLogger::QWarning, msg); + QTest::TestLoggers::addMessage(QAbstractTestLogger::QWarning, msg); break; case QtFatalMsg: - QTest::testLogger->addMessage(QAbstractTestLogger::QFatal, msg); + QTest::TestLoggers::addMessage(QAbstractTestLogger::QFatal, msg); /* Right now, we're inside the custom message handler and we're * being qt_message_output in qglobal.cpp. After we return from * this function, it will proceed with calling exit() and abort() @@ -167,10 +258,9 @@ namespace QTest { void QTestLog::enterTestFunction(const char* function) { - QTEST_ASSERT(QTest::testLogger); QTEST_ASSERT(function); - QTest::testLogger->enterTestFunction(function); + QTest::TestLoggers::enterTestFunction(function); } int QTestLog::unhandledIgnoreMessages() @@ -186,21 +276,17 @@ int QTestLog::unhandledIgnoreMessages() void QTestLog::leaveTestFunction() { - QTEST_ASSERT(QTest::testLogger); - QTest::IgnoreResultList::clearList(QTest::ignoreResultList); - QTest::testLogger->leaveTestFunction(); + QTest::TestLoggers::leaveTestFunction(); } void QTestLog::printUnhandledIgnoreMessages() { - QTEST_ASSERT(QTest::testLogger); - char msg[1024]; QTest::IgnoreResultList *list = QTest::ignoreResultList; while (list) { QTest::qt_snprintf(msg, 1024, "Did not receive message: \"%s\"", list->msg); - QTest::testLogger->addMessage(QAbstractTestLogger::Info, msg); + QTest::TestLoggers::addMessage(QAbstractTestLogger::Info, msg); list = list->next; } @@ -208,110 +294,110 @@ void QTestLog::printUnhandledIgnoreMessages() void QTestLog::addPass(const char *msg) { - QTEST_ASSERT(QTest::testLogger); QTEST_ASSERT(msg); - QTest::testLogger->addIncident(QAbstractTestLogger::Pass, msg); + QTest::TestLoggers::addIncident(QAbstractTestLogger::Pass, msg); } void QTestLog::addFail(const char *msg, const char *file, int line) { - QTEST_ASSERT(QTest::testLogger); QTEST_ASSERT(msg); - QTest::testLogger->addIncident(QAbstractTestLogger::Fail, msg, file, line); + QTest::TestLoggers::addIncident(QAbstractTestLogger::Fail, msg, file, line); } void QTestLog::addXFail(const char *msg, const char *file, int line) { - QTEST_ASSERT(QTest::testLogger); QTEST_ASSERT(msg); QTEST_ASSERT(file); - QTest::testLogger->addIncident(QAbstractTestLogger::XFail, msg, file, line); + QTest::TestLoggers::addIncident(QAbstractTestLogger::XFail, msg, file, line); } void QTestLog::addXPass(const char *msg, const char *file, int line) { - QTEST_ASSERT(QTest::testLogger); QTEST_ASSERT(msg); QTEST_ASSERT(file); - QTest::testLogger->addIncident(QAbstractTestLogger::XPass, msg, file, line); + QTest::TestLoggers::addIncident(QAbstractTestLogger::XPass, msg, file, line); } void QTestLog::addSkip(const char *msg, const char *file, int line) { - QTEST_ASSERT(QTest::testLogger); QTEST_ASSERT(msg); QTEST_ASSERT(file); - QTest::testLogger->addMessage(QAbstractTestLogger::Skip, msg, file, line); + QTest::TestLoggers::addMessage(QAbstractTestLogger::Skip, msg, file, line); } void QTestLog::addBenchmarkResult(const QBenchmarkResult &result) { - QTEST_ASSERT(QTest::testLogger); - QTest::testLogger->addBenchmarkResult(result); + QTest::TestLoggers::addBenchmarkResult(result); } void QTestLog::startLogging() { - QTEST_ASSERT(QTest::testLogger); - QTest::testLogger->startLogging(); + QTest::TestLoggers::startLogging(); QTest::oldMessageHandler = qInstallMsgHandler(QTest::messageHandler); } void QTestLog::stopLogging() { qInstallMsgHandler(QTest::oldMessageHandler); - - QTEST_ASSERT(QTest::testLogger); - QTest::testLogger->stopLogging(); - delete QTest::testLogger; - QTest::testLogger = 0; + QTest::TestLoggers::stopLogging(); + QTest::TestLoggers::destroyLoggers(); + QTest::loggerUsingStdout = false; } -void QTestLog::initLogger(LogMode mode, const char *filename) +void QTestLog::addLogger(LogMode mode, const char *filename) { - QTest::logMode = mode; + if (filename && strcmp(filename, "-") == 0) + filename = 0; + if (!filename) + QTest::loggerUsingStdout = true; + QAbstractTestLogger *logger = 0; switch (mode) { case QTestLog::Plain: - QTest::testLogger = new QPlainTestLogger(filename); + logger = new QPlainTestLogger(filename); break; case QTestLog::XML: - QTest::testLogger = new QXmlTestLogger(QXmlTestLogger::Complete, filename); + logger = new QXmlTestLogger(QXmlTestLogger::Complete, filename); break; case QTestLog::LightXML: - QTest::testLogger = new QXmlTestLogger(QXmlTestLogger::Light, filename); + logger = new QXmlTestLogger(QXmlTestLogger::Light, filename); break; case QTestLog::XunitXML: - QTest::testLogger = new QXunitTestLogger(filename); + logger = new QXunitTestLogger(filename); break; } - QTEST_ASSERT(QTest::testLogger); + QTEST_ASSERT(logger); + QTest::TestLoggers::addLogger(logger); } -void QTestLog::warn(const char *msg) +int QTestLog::loggerCount() { - QTEST_ASSERT(QTest::testLogger); - QTEST_ASSERT(msg); + return QTest::TestLoggers::loggerCount(); +} - QTest::testLogger->addMessage(QAbstractTestLogger::Warn, msg); +bool QTestLog::loggerUsingStdout() +{ + return QTest::loggerUsingStdout; } -void QTestLog::info(const char *msg, const char *file, int line) +void QTestLog::warn(const char *msg) { QTEST_ASSERT(msg); - if (QTest::testLogger) - QTest::testLogger->addMessage(QAbstractTestLogger::Info, msg, file, line); + if (QTest::TestLoggers::loggerCount() > 0) + QTest::TestLoggers::addMessage(QAbstractTestLogger::Warn, msg); } -QTestLog::LogMode QTestLog::logMode() +void QTestLog::info(const char *msg, const char *file, int line) { - return QTest::logMode; + QTEST_ASSERT(msg); + + QTest::TestLoggers::addMessage(QAbstractTestLogger::Info, msg, file, line); } void QTestLog::setVerboseLevel(int level) |