/**************************************************************************** ** ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the test suite of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and Digia. For licensing terms and ** conditions see http://qt.digia.com/licensing. For further information ** use the contact form at http://qt.digia.com/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Digia gives you certain additional ** rights. These rights are described in the Digia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 3.0 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU General Public License version 3.0 requirements will be ** met: http://www.gnu.org/copyleft/gpl.html. ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include #include #include #include #undef protected #define protected public #include #include QT_LOG_CATEGORY(TST_LOG, "tst.log") QT_LOG_CATEGORY(TST_LOG1, "tst.log1") QT_LOG_CATEGORY(Nokia_Brisbane_Office_com, "Nokia.Brisbane.Office.com") QT_LOG_CATEGORY(Nokia_Tampere_Office_com, "Nokia.Tampere.Office.com") QT_LOG_CATEGORY(Nokia_Ulm_Office_com, "Nokia.Ulm.Office.com") QT_USE_NAMESPACE QtMessageHandler oldMessageHandler; QString logMessage; bool multithreadtest = false; QStringList threadtest; QMutex threadmutex; bool usedefaultformat = false; QByteArray qMyMessageFormatString(QtMsgType type, const QMessageLogContext &context, const QString &str) { QByteArray message; if (!usedefaultformat) { message.append(context.category); switch (type) { case QtDebugMsg: message.append(".debug"); break; case QtWarningMsg: message.append(".warning"); break; case QtCriticalMsg:message.append(".critical"); break; case QtFatalMsg: message.append(".fatal"); break; } message.append(": "); message.append(qPrintable(str)); message.append('\n'); } else { message.append(qPrintable(str)); message.append('\n'); } return message; } static void myCustomMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg) { QMutexLocker locker(&threadmutex); logMessage = qMyMessageFormatString(type, context, msg); if (multithreadtest) threadtest.append(logMessage); } class CfgFile { public: CfgFile() { } void addKey(const QString &key, bool val){ //old key values gets updated _values.insert(key, (val ? "true" : "false")); if (!_configitemEntryOrder.contains(key)) _configitemEntryOrder.append(key); } void addKey(const QString &key, const QString &val){ //old key values gets updated _values.insert(key, val); if (!_configitemEntryOrder.contains(key)) _configitemEntryOrder.append(key); } QByteArray array() { QString ret; QTextStream out(&ret); for (int a = 0; a < _configitemEntryOrder.count(); a++) { out << _configitemEntryOrder[a] << " = " << _values.value(_configitemEntryOrder[a]) << endl; } out.flush(); return ret.toLatin1(); } void clear() { _values.clear(); _configitemEntryOrder.clear(); } private: QMap _values; QStringList _configitemEntryOrder; }; static CfgFile cfg1; static CfgFile cfg2; class LogThread : public QThread { Q_OBJECT public: LogThread(const QString &logtext, CfgFile *cfgFile) : _logtext(logtext), _cfgFile(cfgFile) {} protected: void run() { for (int i = 0; i < 2000; i++){ _cfgFile->addKey("Nokia*", true); QByteArray arr = _cfgFile->array(); qSetLoggingRules(arr); qCDebug(Nokia_Brisbane_Office_com) << "Brisbane " << _logtext << " :true"; _cfgFile->addKey("Nokia*", false); arr = _cfgFile->array(); qSetLoggingRules(arr); qCDebug(Nokia_Brisbane_Office_com) << "Brisbane " << _logtext << " :false"; _cfgFile->addKey("Nokia*", true); arr = _cfgFile->array(); qSetLoggingRules(arr); qCDebug(Nokia_Ulm_Office_com) << "Ulm " << _logtext << " :true"; _cfgFile->addKey("Nokia*", false); arr = _cfgFile->array(); qSetLoggingRules(arr); qCDebug(Nokia_Ulm_Office_com) << "Ulm " << _logtext << " :false"; _cfgFile->addKey("Nokia*", true); arr = _cfgFile->array(); qSetLoggingRules(arr); qCDebug(Nokia_Tampere_Office_com) << "Tampere " << _logtext << " :true"; _cfgFile->addKey("Nokia*", false); arr = _cfgFile->array(); qSetLoggingRules(arr); qCDebug(Nokia_Tampere_Office_com) << "Tampere " << _logtext << " :false"; } } public: QString _logtext; CfgFile *_cfgFile; }; inline QString cleanLogLine(QString& qstring) { QString buf = qstring.replace("../", ""); buf = buf.replace("qlog/", ""); QString ret; for (int i = 0; i < buf.length(); i++) { if (buf[i] >= '!' && buf[i] <= 'z') ret += buf[i]; } return ret; } //QTLOGGER_USE_NAMESPACE class tst_QLogger : public QObject { Q_OBJECT private: CfgFile *_configFile; QStringList logEntries; private slots: void initTestCase() { qputenv ("QT_MESSAGE_PATTERN", QString("%{category}: %{type},%{message}").toLatin1()); oldMessageHandler = qInstallMessageHandler(myCustomMessageHandler); //create QLog config file _configFile = new CfgFile(); } //Check the Debug, Warning and critical without having category active. should be active. void checkNoCategoryLogActive() { //check default debug QString buf = QString::fromLatin1("default.debug: Check default Debug with no log active"); qDebug() << "Check default Debug with no log active"; QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); //check default warning buf = QString::fromLatin1("default.warning: Check default Warning with no log active"); qWarning() << "Check default Warning with no log active"; QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); //check default critical buf = QString::fromLatin1("default.critical: Check default Critical with no log active"); qCritical() << "Check default Critical with no log active"; QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); //check category debug logMessage = "should not change"; buf = logMessage; qCDebug(TST_LOG) << "Check category Debug with no log active"; QCOMPARE(logMessage, buf); //check default warning buf = QString::fromLatin1("tst.log.warning: Check category Warning with no log active"); qCWarning(TST_LOG) << "Check category Warning with no log active"; QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); //check default critical buf = QString::fromLatin1("tst.log.critical: Check category Critical with no log active"); qCCritical(TST_LOG) << "Check category Critical with no log active"; QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); } void writeCategoryLogs() { usedefaultformat = false; //activate TST_LOG category logMessage = ""; _configFile->addKey("tst.log", true); qSetLoggingRules(_configFile->array()); QString buf = QString::fromLatin1("tst.log.debug: Check for default messagePattern"); qCDebug(TST_LOG) << "Check for default messagePattern"; QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); //activate TST_LOG category with default enabled function info _configFile->addKey("tst.log1", true); qSetLoggingRules(_configFile->array()); qCDebug(TST_LOG) << "1"; buf = QString::fromLatin1("tst.log.debug: 1"); QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); //wite out all different types qCDebug(TST_LOG) << "DebugType"; buf = QString::fromLatin1("tst.log.debug: DebugType"); QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); qCWarning(TST_LOG) << "WarningType"; buf = QString::fromLatin1("tst.log.warning: WarningType"); QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); qCCritical(TST_LOG) << "CriticalType"; buf = QString::fromLatin1("tst.log.critical: CriticalType"); QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); } void checkLegacyLogs() { logMessage = ""; qDebug() << "DefaultDebug"; QString buf = QString::fromLatin1("default.debug: DefaultDebug"); QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); //default Debug off by default, warning and critical are on qWarning() << "DefaultWarning"; buf = QString::fromLatin1("default.warning: DefaultWarning"); QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); qCritical() << "DefaultCritical"; buf = QString::fromLatin1("default.critical: DefaultCritical"); QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); //enable default debug _configFile->addKey("default.debug", true); qSetLoggingRules(_configFile->array()); qDebug() << "DefaultDebug1"; buf = QString::fromLatin1("default.debug: DefaultDebug1"); QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); qWarning() << "DefaultWarning1"; buf = QString::fromLatin1("default.warning: DefaultWarning1"); QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); qCritical() << "DefaultCritical1"; buf = QString::fromLatin1("default.critical: DefaultCritical1"); QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); //disable qWarning _configFile->addKey("default.warning", false); qSetLoggingRules(_configFile->array()); qDebug() << "DefaultDebug2"; buf = QString::fromLatin1("default.debug: DefaultDebug2"); QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); logMessage = "no change"; qWarning() << "DefaultWarning2"; buf = QString::fromLatin1("no change"); QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); qCritical() << "DefaultCritical2"; buf = QString::fromLatin1("default.critical: DefaultCritical2"); QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); //disable qCritical _configFile->addKey("default.critical", false); _configFile->addKey("default.debug", false); qSetLoggingRules(_configFile->array()); logMessage = "no change"; qDebug() << "DefaultDebug3"; buf = QString::fromLatin1("no change"); QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); qWarning() << "DefaultWarning3"; QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); qCritical() << "DefaultCritical3"; QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); //enable default logs _configFile->addKey("default.critical", true); _configFile->addKey("default.warning", true); _configFile->addKey("default.debug", true); qSetLoggingRules(_configFile->array()); //ensure all are on qDebug() << "DefaultDebug4"; buf = QString::fromLatin1("default.debug: DefaultDebug4"); QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); qWarning() << "DefaultWarning4"; buf = QString::fromLatin1("default.warning: DefaultWarning4"); QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); qCritical() << "DefaultCritical4"; buf = QString::fromLatin1("default.critical: DefaultCritical4"); QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); //disable default log _configFile->addKey("default", false); qSetLoggingRules(_configFile->array()); //ensure all are off logMessage = "no change"; buf = QString::fromLatin1("no change"); qDebug() << "DefaultDebug5"; QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); qWarning() << "DefaultWarning5"; QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); qCritical() << "DefaultCritical5"; QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); } void checkLegacyMessageLogger() { usedefaultformat = true; //This should just not crash. QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO).debug() << "checkLegacyMessageLogger1"; QCOMPARE(cleanLogLine(logMessage), QString("checkLegacyMessageLogger1")); QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO).warning() << "checkLegacyMessageLogger2"; QCOMPARE(cleanLogLine(logMessage), QString("checkLegacyMessageLogger2")); QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO).critical() << "checkLegacyMessageLogger3"; QCOMPARE(cleanLogLine(logMessage), QString("checkLegacyMessageLogger3")); usedefaultformat = false; } void checkFiltering() { //enable default logs _configFile->clear(); _configFile->addKey("Nokia.Brisbane.Office.com", false); _configFile->addKey("Nokia.Tampere.Office.com", false); _configFile->addKey("Nokia.Ulm.Office.com", false); _configFile->addKey("MessagePattern", QString("%{category}: %{message}")); qSetLoggingRules(_configFile->array()); logMessage = "no change"; QString buf = QString::fromLatin1("no change"); qCDebug(Nokia_Brisbane_Office_com) << "Nokia.Brisbane.Office.com 1"; qCDebug(Nokia_Tampere_Office_com) << "Nokia.Tampere.Office.com 1"; qCDebug(Nokia_Ulm_Office_com) << "Nokia.Ulm.Office.com 1"; QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); _configFile->addKey("Nokia.Brisbane.Office.com", true); _configFile->addKey("Nokia.Tampere.Office.com", true); _configFile->addKey("Nokia.Ulm.Office.com", true); qSetLoggingRules(_configFile->array()); qCDebug(Nokia_Brisbane_Office_com) << "Nokia.Brisbane.Office.com 2"; buf = QString::fromLatin1("Nokia.Brisbane.Office.com.debug: Nokia.Brisbane.Office.com 2"); QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); qCDebug(Nokia_Tampere_Office_com) << "Nokia.Tampere.Office.com 2"; buf = QString::fromLatin1("Nokia.Tampere.Office.com.debug: Nokia.Tampere.Office.com 2"); QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); qCDebug(Nokia_Ulm_Office_com) << "Nokia.Ulm.Office.com 2"; buf = QString::fromLatin1("Nokia.Ulm.Office.com.debug: Nokia.Ulm.Office.com 2"); QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); //Check right filter _configFile->addKey("Nokia.Brisbane.Office.com", false); _configFile->addKey("Nokia.Tampere.Office.com", false); _configFile->addKey("Nokia.Ulm.Office.com", false); _configFile->addKey("*Office.com*", true); qSetLoggingRules(_configFile->array()); qCDebug(Nokia_Brisbane_Office_com) << "Nokia.Brisbane.Office.com 3"; buf = QString::fromLatin1("Nokia.Brisbane.Office.com.debug: Nokia.Brisbane.Office.com 3"); QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); qCDebug(Nokia_Tampere_Office_com) << "Nokia.Tampere.Office.com 3"; buf = QString::fromLatin1("Nokia.Tampere.Office.com.debug: Nokia.Tampere.Office.com 3"); QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); qCDebug(Nokia_Ulm_Office_com) << "Nokia.Ulm.Office.com 3"; buf = QString::fromLatin1("Nokia.Ulm.Office.com.debug: Nokia.Ulm.Office.com 3"); QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); //Check left filter _configFile->addKey("*Office.com*", false); _configFile->addKey("*Office.com.debug", true); qSetLoggingRules(_configFile->array()); qCDebug(Nokia_Brisbane_Office_com) << "Debug: Nokia.Brisbane.Office.com 4"; buf = QString::fromLatin1("Nokia.Brisbane.Office.com.debug: Debug: Nokia.Brisbane.Office.com 4"); QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); logMessage = "no change"; buf = QString::fromLatin1("no change"); qCWarning(Nokia_Tampere_Office_com) << "Warning: Nokia.Tampere.Office.com 4"; qCCritical(Nokia_Ulm_Office_com) << "Critical: Nokia.Ulm.Office.com 4"; QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); //Check right filter _configFile->addKey("*Office.com.debug", false); _configFile->addKey("Nokia.*", true); qSetLoggingRules(_configFile->array()); qCDebug(Nokia_Brisbane_Office_com) << "Debug: Nokia.Brisbane.Office.com 5"; buf = QString::fromLatin1("Nokia.Brisbane.Office.com.debug: Debug: Nokia.Brisbane.Office.com 5"); QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); qCWarning(Nokia_Tampere_Office_com) << "Warning: Nokia.Tampere.Office.com 5"; buf = QString::fromLatin1("Nokia.Tampere.Office.com.warning: Warning: Nokia.Tampere.Office.com 5"); QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); qCCritical(Nokia_Ulm_Office_com) << "Critical: Nokia.Ulm.Office.com 5"; buf = QString::fromLatin1("Nokia.Ulm.Office.com.critical: Critical: Nokia.Ulm.Office.com 5"); QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); //Check mid filter _configFile->addKey("Nokia.*", false); qSetLoggingRules(_configFile->array()); logMessage = "no change"; buf = QString::fromLatin1("no change"); qCDebug(Nokia_Brisbane_Office_com) << "Debug: Nokia.Brisbane.Office.com 6"; qCWarning(Nokia_Tampere_Office_com) << "Warning: Nokia.Tampere.Office.com 6"; qCCritical(Nokia_Ulm_Office_com) << "Critical: Nokia.Ulm.Office.com 6"; QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); _configFile->addKey("*.Office.*", true); qSetLoggingRules(_configFile->array()); qCDebug(Nokia_Brisbane_Office_com) << "Debug: Nokia.Brisbane.Office.com 7"; buf = QString::fromLatin1("Nokia.Brisbane.Office.com.debug: Debug: Nokia.Brisbane.Office.com 7"); QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); qCWarning(Nokia_Tampere_Office_com) << "Warning: Nokia.Tampere.Office.com 7"; buf = QString::fromLatin1("Nokia.Tampere.Office.com.warning: Warning: Nokia.Tampere.Office.com 7"); QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); qCCritical(Nokia_Ulm_Office_com) << "Critical: Nokia.Ulm.Office.com 7"; buf = QString::fromLatin1("Nokia.Ulm.Office.com.critical: Critical: Nokia.Ulm.Office.com 7"); QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); } void checkLogWithCategoryObject() { _configFile->clear(); _configFile->addKey("LoggingCategoryObject", true); QLoggingCategory *pcategorybject = 0; qSetLoggingRules(_configFile->array()); { QLoggingCategory mycategoryobject("LoggingCategoryObject"); pcategorybject = &mycategoryobject; logMessage = "no change"; QString buf = QString::fromLatin1("LoggingCategoryObject.debug: My Category Object"); qCDebug(mycategoryobject) << "My Category Object"; QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); buf = QString::fromLatin1("LoggingCategoryObject.warning: My Category Object"); qCWarning(mycategoryobject) << "My Category Object"; QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); buf = QString::fromLatin1("LoggingCategoryObject.critical: My Category Object"); qCCritical(mycategoryobject) << "My Category Object"; QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); QLoggingCategory mycategoryobject2("LoggingCategoryObject"); buf = QString::fromLatin1("LoggingCategoryObject.debug: My Category Object"); qCDebug(mycategoryobject) << "My Category Object"; QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); buf = QString::fromLatin1("LoggingCategoryObject.warning: My Category Object"); qCWarning(mycategoryobject) << "My Category Object"; QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); buf = QString::fromLatin1("LoggingCategoryObject.critical: My Category Object"); qCCritical(mycategoryobject) << "My Category Object"; QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); } //check if mycategoryobject still registered. QLoggingPrivate *logger = qtLoggerInstance(); QVERIFY(!logger->_registeredCategories.contains(pcategorybject)); } void checkEmptyCategoryName() { QLoggingCategory mycategoryobject(""); logMessage = "no change"; QString buf = QString::fromLatin1("no change"); qCDebug(mycategoryobject) << "My Category Object"; QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); QLoggingCategory mycategoryobject1(0); buf = QString::fromLatin1("no change"); qCDebug(mycategoryobject1) << "My Category Object"; QCOMPARE(cleanLogLine(logMessage), cleanLogLine(buf)); } void checkMultithreading() { multithreadtest = true; //init two cfgconf files fone for each thread cfg1.addKey("Nokia*", true); cfg2.addKey("Nokia*", true); QByteArray arr = cfg1.array(); qSetLoggingRules(arr); LogThread thgread1(QString("from Thread 1"), &cfg1); LogThread thgread2(QString("from Thread 2"), &cfg2); //Writing out stuff from 2 different threads into the same LOG_CFG2 thgread1.start(); thgread2.start(); thgread1.wait(); thgread2.wait(); //Check if each log line is complete QStringList compareagainst; QString buf = QString::fromLatin1("Nokia.Brisbane.Office.com.debug: Brisbane \"from Thread 1\" :true"); compareagainst.append(cleanLogLine(buf)); buf = QString::fromLatin1("Nokia.Tampere.Office.com.debug: Tampere \"from Thread 1\" :true"); compareagainst.append(cleanLogLine(buf)); buf = QString::fromLatin1("Nokia.Ulm.Office.com.debug: Ulm \"from Thread 1\" :true"); compareagainst.append(cleanLogLine(buf)); buf = QString::fromLatin1("Nokia.Brisbane.Office.com.debug: Brisbane \"from Thread 1\" :false"); compareagainst.append(cleanLogLine(buf)); buf = QString::fromLatin1("Nokia.Tampere.Office.com.debug: Tampere \"from Thread 1\" :false"); compareagainst.append(cleanLogLine(buf)); buf = QString::fromLatin1("Nokia.Ulm.Office.com.debug: Ulm \"from Thread 1\" :false"); compareagainst.append(cleanLogLine(buf)); buf = QString::fromLatin1("Nokia.Brisbane.Office.com.debug: Brisbane \"from Thread 2\" :true"); compareagainst.append(cleanLogLine(buf)); buf = QString::fromLatin1("Nokia.Tampere.Office.com.debug: Tampere \"from Thread 2\" :true"); compareagainst.append(cleanLogLine(buf)); buf = QString::fromLatin1("Nokia.Ulm.Office.com.debug: Ulm \"from Thread 2\" :true"); compareagainst.append(cleanLogLine(buf)); buf = QString::fromLatin1("Nokia.Brisbane.Office.com.debug: Brisbane \"from Thread 2\" :false"); compareagainst.append(cleanLogLine(buf)); buf = QString::fromLatin1("Nokia.Tampere.Office.com.debug: Tampere \"from Thread 2\" :false"); compareagainst.append(cleanLogLine(buf)); buf = QString::fromLatin1("Nokia.Ulm.Office.com.debug: Ulm \"from Thread 2\" :false"); compareagainst.append(cleanLogLine(buf)); for (int i = 0; i < threadtest.count(); i++) { if (!compareagainst.contains(cleanLogLine(threadtest[i]))){ fprintf(stdout, "%s\r\n", threadtest[i].toLatin1().constData()); QVERIFY2(false, "Multithread log is not complete!"); } } } void cleanupTestCase() { delete _configFile; qInstallMessageHandler(oldMessageHandler); } }; QTEST_MAIN(tst_QLogger) #include "tst_qlogger.moc"