/**************************************************************************** ** ** 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 #include #include #include // redefine qDebug & Co because we don't want to use QtLogger if test application starts up. #if defined(qDebug) # undef qDebug #endif #define qDebug QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO).debug #if defined(qWarning) # undef qWarning #endif #define qWarning QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO).warning #if defined(qCritical) # undef qCritical #endif #define qCritical QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO).critical QT_LOG_CATEGORY(My_Category_A, "My.Category.A") QT_LOG_CATEGORY(My_Category_B, "My.Category.B") QT_LOG_CATEGORY(My_Category_C, "My.Category.C") #define LOGRULEFILE "./myLogRules.txt" QT_USE_NAMESPACE QtMessageHandler oldMessageHandler; bool logReceived = false; QMutex threadmutex; QByteArray qMyMessageFormatString(QtMsgType /*type*/, const QMessageLogContext &/*context*/, const QString &str) { QByteArray message; { message.append(qPrintable(str)); message.append('\n'); } return message; } static void myCustomMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg) { QMutexLocker locker(&threadmutex); QString logmsg = qMyMessageFormatString(type, context, msg); if (logmsg.indexOf("My_Category") >= 0) { logReceived = true; } else oldMessageHandler(type, context, msg); } class LogRules { public: LogRules() { } 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); } 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; }; class LogThread : public QThread { public: LogThread() {} protected: void run(); }; void LogThread::run() { qCDebug(My_Category_A) << "My_Category_A"; qCDebug(My_Category_B) << "My_Category_B"; qCDebug(My_Category_C) << "My_Category_C"; qCWarning(My_Category_A) << "My_Category_A"; qCWarning(My_Category_B) << "My_Category_B"; qCWarning(My_Category_C) << "My_Category_C"; qCCritical(My_Category_A) << "My_Category_A"; qCCritical(My_Category_B) << "My_Category_B"; qCCritical(My_Category_C) << "My_Category_C"; } LogRules logRules; class WriteFileThread : public QThread { public: WriteFileThread() {} protected: void run() { if (QFile::exists(LOGRULEFILE)) QFile::remove(LOGRULEFILE); QFile file(LOGRULEFILE); if (file.open(QIODevice::WriteOnly)) file.write(logRules.array()); } }; class tst_QLogger : public QObject { Q_OBJECT private: QStringList logEntries; private slots: void initTestCase() { oldMessageHandler = qInstallMessageHandler(myCustomMessageHandler); //prepare for testcase log with NOT callin qSetLoggingRules & Co //Only the QT_LOGGING_CONFIG environment variable should activate the logging //qDebug & co are redefined to avoid creating the QLogger private instance uncontrolled. QByteArray ba; ba.append(LOGRULEFILE); qputenv("QT_LOGGING_CONFIG", ba); //create log rules logRules.addKey("My.Category.*", true); pFileWriter = new WriteFileThread(); writeLogRuleFile(); //Make sure the rule file exists otherwise QtLogger will not be active QTRY_VERIFY(QFile::exists(LOGRULEFILE)); } void createQtLoggerFromThread() { logReceived = false; LogThread thread; //QtLogger private was created not in the main thread. thread.start(); thread.wait(); //Make sure that message handler was called => logger private instance is created QTRY_VERIFY(logReceived); } void checkFileWatcherTrigger() { //Now logger exist QLoggingPrivate *logger = qtLoggerInstance(); QTRY_VERIFY(logger->_configFileWatcher); //Check filewriter trigger QSignalSpy spy(logger, SIGNAL(configurationChanged())); logRules.addKey("My.Category.*", false); pFileWriter = new WriteFileThread(); writeLogRuleFile(); QTRY_VERIFY(spy.count() > 0); //Check filewriter trigger again spy.clear(); logRules.addKey("My.Category.*", true); pFileWriter = new WriteFileThread(); writeLogRuleFile(); QTRY_VERIFY(spy.count() > 0); } void cleanupTestCase() { qInstallMessageHandler(oldMessageHandler); if (QFile::exists(LOGRULEFILE)) QFile::remove(LOGRULEFILE); delete pFileWriter; } private: void writeLogRuleFile() { pFileWriter->start(); pFileWriter->wait(); } WriteFileThread *pFileWriter; }; QTEST_MAIN(tst_QLogger) #include "tst_qloggerenvar.moc"