File indexing completed on 2024-04-21 05:46:12
0001 /* 0002 SPDX-FileCopyrightText: 2007 Nicolas Ternisien <nicolas.ternisien@gmail.com> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include <QList> 0008 #include <QSignalSpy> 0009 #include <QStringList> 0010 #include <QTest> 0011 #include <QThread> 0012 0013 #include "testUtil.h" 0014 0015 #include "analyzer.h" 0016 #include "globals.h" 0017 0018 #include "logFile.h" 0019 #include "logLevel.h" 0020 #include "logViewModel.h" 0021 #include "logViewWidget.h" 0022 0023 #include "ksystemlogConfig.h" 0024 0025 #include "ksystemlog_debug.h" 0026 0027 class SystemAnalyzerTest : public QObject 0028 { 0029 Q_OBJECT 0030 0031 private Q_SLOTS: 0032 0033 void initTestCase(); 0034 0035 void testMultipleLines(); 0036 void testOneLine(); 0037 void testTwoLines(); 0038 void testStrangeLines(); 0039 0040 void testDeleteProcessIdentifier(); 0041 void testMaxLines(); 0042 void testRemoveDuplicates(); 0043 0044 private: 0045 void compareWithMinTime(const QList<LogLine *> &lines, const QDateTime &minTime); 0046 0047 private: 0048 TestUtil testUtil; 0049 }; 0050 0051 void SystemAnalyzerTest::initTestCase() 0052 { 0053 testUtil.registerLogModeFactories(); 0054 } 0055 0056 void SystemAnalyzerTest::testOneLine() 0057 { 0058 LogViewModel *model = nullptr; 0059 0060 Analyzer *systemAnalyzer = testUtil.createAnalyzer(QStringLiteral("systemLogMode"), &model); 0061 QVERIFY(systemAnalyzer); 0062 QVERIFY(model); 0063 0064 QVector<LogFile> const logFiles = testUtil.createLogFiles(QStringLiteral(":/testFiles/default/one-line.log")); 0065 0066 systemAnalyzer->setLogFiles(logFiles); 0067 0068 systemAnalyzer->watchLogFiles(true); 0069 0070 QCOMPARE(model->itemCount(), 1); 0071 QCOMPARE(model->isEmpty(), false); 0072 0073 QList<LogLine *> const logLines = model->logLines(); 0074 0075 QStringList const items = QStringList() << QStringLiteral("localhost") << QStringLiteral("kernel") 0076 << QStringLiteral("[11663.656000] eth1: no IPv6 routers present"); 0077 0078 const int year = QDate::currentDate().year(); 0079 testUtil.testLine(logLines.at(0), 0080 logFiles.at(0).url().toLocalFile(), 0081 logFiles.at(0).defaultLogLevel(), 0082 QDateTime(QDate(year, 8, 21), QTime(22, 52, 44)), 0083 items 0084 0085 ); 0086 0087 testUtil.destroyReader(systemAnalyzer); 0088 } 0089 0090 void SystemAnalyzerTest::testTwoLines() 0091 { 0092 LogViewModel *model = nullptr; 0093 0094 Analyzer *systemAnalyzer = testUtil.createAnalyzer(QStringLiteral("systemLogMode"), &model); 0095 QVERIFY(systemAnalyzer); 0096 QVERIFY(model); 0097 0098 // Specifical configuration 0099 KSystemLogConfig::setMaxLines(1000); 0100 0101 QVector<LogFile> const logFiles = testUtil.createLogFiles(QStringLiteral(":/testFiles/default/two-lines.log")); 0102 0103 systemAnalyzer->setLogFiles(logFiles); 0104 0105 systemAnalyzer->watchLogFiles(true); 0106 0107 QCOMPARE(model->itemCount(), 2); 0108 QCOMPARE(model->isEmpty(), false); 0109 0110 testUtil.destroyReader(systemAnalyzer); 0111 } 0112 0113 void SystemAnalyzerTest::testMultipleLines() 0114 { 0115 LogViewModel *model = nullptr; 0116 0117 Analyzer *systemAnalyzer = testUtil.createAnalyzer(QStringLiteral("systemLogMode"), &model); 0118 QVERIFY(systemAnalyzer); 0119 QVERIFY(model); 0120 0121 // Specifical configuration 0122 KSystemLogConfig::setMaxLines(1000); 0123 0124 QVector<LogFile> const logFiles = testUtil.createLogFiles(QStringLiteral(":/testFiles/system/system.log")); 0125 LogFile const logFile = logFiles.at(0); 0126 0127 systemAnalyzer->setLogFiles(logFiles); 0128 0129 QSignalSpy stateSpy(systemAnalyzer, &Analyzer::logUpdated); 0130 QList<QVariant> arguments; 0131 0132 // Each watching relaunch a reading 0133 systemAnalyzer->watchLogFiles(true); 0134 0135 // Assert that the model has been updated 0136 QCOMPARE(model->itemCount(), 24); 0137 0138 // Assert that the logUpdated signal emits the right count 0139 QCOMPARE(stateSpy.count(), 1); 0140 arguments = stateSpy.takeFirst(); 0141 QCOMPARE(arguments.at(0).toInt(), 24); 0142 0143 // Each watching relaunch a reading 0144 systemAnalyzer->watchLogFiles(true); 0145 0146 // Assert that the model has been updated 0147 QCOMPARE(model->itemCount(), 48); 0148 0149 // Assert that the logUpdated signal emits the right count 0150 QCOMPARE(stateSpy.count(), 1); 0151 arguments = stateSpy.takeFirst(); 0152 QCOMPARE(arguments.at(0).toInt(), 24); 0153 0154 QStringList addedLines; 0155 addedLines << QStringLiteral("Aug 18 17:04:28 localhost test: Test line 1"); 0156 addedLines << QStringLiteral("Aug 18 17:04:30 localhost test: Test line 2"); 0157 0158 testUtil.addLogLines(logFile.url().toLocalFile(), addedLines); 0159 0160 // Assert that the model has been updated 0161 QCOMPARE(model->itemCount(), 50); 0162 0163 // Assert that the logUpdated signal emits the right count 0164 QCOMPARE(stateSpy.count(), 1); 0165 arguments = stateSpy.takeFirst(); 0166 QCOMPARE(arguments.at(0).toInt(), 2); 0167 0168 testUtil.destroyReader(systemAnalyzer); 0169 } 0170 0171 void SystemAnalyzerTest::testStrangeLines() 0172 { 0173 LogViewModel *model = nullptr; 0174 0175 Analyzer *systemAnalyzer = testUtil.createAnalyzer(QStringLiteral("systemLogMode"), &model); 0176 QVERIFY(systemAnalyzer); 0177 QVERIFY(model); 0178 0179 // Specifical configuration 0180 KSystemLogConfig::setMaxLines(1000); 0181 KSystemLogConfig::setDeleteProcessIdentifier(false); 0182 0183 QVector<LogFile> const logFiles = testUtil.createLogFiles(QStringLiteral(":/testFiles/system/strange-lines.log")); 0184 0185 systemAnalyzer->setLogFiles(logFiles); 0186 0187 systemAnalyzer->watchLogFiles(true); 0188 0189 QCOMPARE(model->itemCount(), 8); 0190 0191 // i18n("undefined") 0192 QString const undefined = QLatin1String(""); 0193 0194 QStringList items; 0195 0196 QSKIP("This test/code is broken"); 0197 const int year = QDate::currentDate().year(); 0198 0199 // Classical log line 0200 items = QStringList() << QStringLiteral("localhost") << QStringLiteral("kernel") << QStringLiteral("Kernel panic"); 0201 testUtil.testLine(model->logLines().at(0), 0202 logFiles.at(0).url().toLocalFile(), 0203 logFiles.at(0).defaultLogLevel(), 0204 QDateTime(QDate(year, 8, 10), QTime(17, 04, 28)), 0205 items); 0206 0207 //-- MARK -- log line 0208 items = QStringList() << QStringLiteral("localhost") << QStringLiteral("syslog") << QStringLiteral("-- MARK --"); 0209 testUtil.testLine(model->logLines().at(1), 0210 logFiles.at(0).url().toLocalFile(), 0211 logFiles.at(0).defaultLogLevel(), 0212 QDateTime(QDate(year, 8, 11), QTime(13, 49, 38)), 0213 items); 0214 0215 // Last message repeated n time log line 0216 items = QStringList() << QStringLiteral("localhost") << QStringLiteral("syslog") << QStringLiteral("last message repeated 4 times"); 0217 testUtil.testLine(model->logLines().at(2), 0218 logFiles.at(0).url().toLocalFile(), 0219 logFiles.at(0).defaultLogLevel(), 0220 QDateTime(QDate(year, 8, 12), QTime(18, 10, 32)), 0221 items); 0222 0223 //"Aug 13 17:04:28 testprocess: Say ouhou " -> No host name 0224 items = QStringList() << undefined << QStringLiteral("testprocess") << QStringLiteral("Say ouhou "); 0225 testUtil.testLine(model->logLines().at(3), 0226 logFiles.at(0).url().toLocalFile(), 0227 logFiles.at(0).defaultLogLevel(), 0228 QDateTime(QDate(year, 8, 13), QTime(17, 04, 28)), 0229 items); 0230 0231 //"Aug 14 17:04:28 localhost kernel say ouhou" -> No process name and not a syslog message 0232 items = QStringList() << QStringLiteral("localhost") << undefined << QStringLiteral("kernel say ouhou"); 0233 testUtil.testLine(model->logLines().at(4), 0234 logFiles.at(0).url().toLocalFile(), 0235 logFiles.at(0).defaultLogLevel(), 0236 QDateTime(QDate(year, 8, 14), QTime(17, 04, 28)), 0237 items); 0238 0239 //"Aug 15 22:39:01 localhost /USR/SBIN/CRON[9433]: (root) CMD ( [ -d /var/lib/php5 ] && find 0240 /// var/lib/php5/ -type f -cmin +$(/usr/lib/php5/maxlifetime) -print0 | xargs -r -0 rm)" -> Long log line 0241 items = QStringList() << QStringLiteral("localhost") << QStringLiteral("/USR/SBIN/CRON[9433]") 0242 << QStringLiteral( 0243 "(root) CMD ( [ -d /var/lib/php5 ] && find /var/lib/php5/ -type f -cmin " 0244 "+$(/usr/lib/php5/maxlifetime) -print0 | xargs -r -0 rm)"); 0245 testUtil.testLine(model->logLines().at(5), 0246 logFiles.at(0).url().toLocalFile(), 0247 logFiles.at(0).defaultLogLevel(), 0248 QDateTime(QDate(year, 8, 15), QTime(22, 39, 01)), 0249 items); 0250 0251 //"blablalbla" -> Invalid line 0252 items = QStringList() << undefined << undefined << QLatin1String(""); 0253 QCOMPARE(model->logLines().at(6)->logItems(), items); 0254 0255 //"" -> Empty line 0256 items = QStringList() << undefined << undefined << QStringLiteral("blablalbla"); 0257 QCOMPARE(model->logLines().at(7)->logItems(), items); 0258 0259 testUtil.destroyReader(systemAnalyzer); 0260 } 0261 0262 void SystemAnalyzerTest::testDeleteProcessIdentifier() 0263 { 0264 LogViewModel *model = nullptr; 0265 0266 Analyzer *systemAnalyzer = testUtil.createAnalyzer(QStringLiteral("systemLogMode"), &model); 0267 QVERIFY(systemAnalyzer); 0268 QVERIFY(model); 0269 0270 // Specifical configuration 0271 KSystemLogConfig::setMaxLines(1000); 0272 KSystemLogConfig::setDeleteProcessIdentifier(true); 0273 0274 QVector<LogFile> const logFiles = testUtil.createLogFiles(QStringLiteral(":/testFiles/system/delete-process-identifier.log")); 0275 0276 systemAnalyzer->setLogFiles(logFiles); 0277 0278 systemAnalyzer->watchLogFiles(true); 0279 0280 QCOMPARE(model->itemCount(), 2); 0281 0282 QStringList items; 0283 0284 // Cron log line 0285 items = QStringList() << QStringLiteral("localhost") << QStringLiteral("/USR/SBIN/CRON") << QStringLiteral("Hello"); 0286 QCOMPARE(model->logLines().at(0)->logItems(), items); 0287 0288 //"f" process 0289 items = QStringList() << QStringLiteral("localhost") << QStringLiteral("f") << QStringLiteral("Ola"); 0290 QCOMPARE(model->logLines().at(1)->logItems(), items); 0291 0292 testUtil.destroyReader(systemAnalyzer); 0293 } 0294 0295 void SystemAnalyzerTest::testMaxLines() 0296 { 0297 LogViewModel *model = nullptr; 0298 0299 Analyzer *systemAnalyzer = testUtil.createAnalyzer(QStringLiteral("systemLogMode"), &model); 0300 QVERIFY(systemAnalyzer); 0301 QVERIFY(model); 0302 0303 // Specifical configuration 0304 KSystemLogConfig::setMaxLines(5); 0305 0306 QVector<LogFile> const logFiles = testUtil.createLogFiles(QStringLiteral(":/testFiles/system/max-lines.log")); 0307 LogFile const logFile = logFiles.at(0); 0308 0309 systemAnalyzer->setLogFiles(logFiles); 0310 0311 systemAnalyzer->watchLogFiles(true); 0312 0313 QCOMPARE(model->itemCount(), 5); 0314 0315 // Asserts that there is no line before the oldest one's time 0316 compareWithMinTime(model->logLines(), QDateTime(QDate(2007, 8, 18), QTime(11, 0, 0))); 0317 0318 QStringList addedLines; 0319 0320 addedLines << QStringLiteral("Aug 18 10:00:00 localhost test: Line 8"); 0321 testUtil.addLogLines(logFile.url().toLocalFile(), addedLines); 0322 0323 QCOMPARE(model->itemCount(), 5); 0324 compareWithMinTime(model->logLines(), QDateTime(QDate(2007, 8, 18), QTime(11, 0, 0))); 0325 0326 // Specifical configuration 0327 KSystemLogConfig::setMaxLines(6); 0328 0329 addedLines.clear(); 0330 addedLines << QStringLiteral("Aug 18 10:00:00 localhost test: Line 9"); 0331 addedLines << QStringLiteral("Aug 18 19:00:00 localhost test: Line 10"); 0332 testUtil.addLogLines(logFile.url().toLocalFile(), addedLines); 0333 0334 QCOMPARE(model->itemCount(), 6); 0335 compareWithMinTime(model->logLines(), QDateTime(QDate(2007, 8, 18), QTime(11, 0, 0))); 0336 0337 addedLines.clear(); 0338 addedLines << QStringLiteral("Aug 18 20:00:00 localhost test: Line 11"); 0339 addedLines << QStringLiteral("Aug 18 21:00:00 localhost test: Line 12"); 0340 testUtil.addLogLines(logFile.url().toLocalFile(), addedLines); 0341 0342 QCOMPARE(model->itemCount(), 6); 0343 compareWithMinTime(model->logLines(), QDateTime(QDate(2007, 8, 18), QTime(13, 0, 0))); 0344 0345 testUtil.destroyReader(systemAnalyzer); 0346 } 0347 0348 void SystemAnalyzerTest::compareWithMinTime(const QList<LogLine *> &logLines, const QDateTime &minTime) 0349 { 0350 qCDebug(KSYSTEMLOG) << "Min time : " << minTime.toString(); 0351 0352 for (LogLine *logLine : logLines) { 0353 if (logLine->time() < minTime) { 0354 QFAIL(QString::fromLatin1("The line '%1' has a lesser time than the required min time (%2)") 0355 .arg(logLine->logItems().join(QLatin1Char(' ')), logLine->time().toString()) 0356 .toUtf8() 0357 .constData()); 0358 } 0359 } 0360 } 0361 0362 void SystemAnalyzerTest::testRemoveDuplicates() 0363 { 0364 LogViewModel *model = nullptr; 0365 0366 Analyzer *systemAnalyzer = testUtil.createAnalyzer(QStringLiteral("systemLogMode"), &model); 0367 QVERIFY(systemAnalyzer); 0368 QVERIFY(model); 0369 0370 // Specifical configuration 0371 KSystemLogConfig::setMaxLines(1000); 0372 KSystemLogConfig::setDeleteDuplicatedLines(true); 0373 0374 QVector<LogFile> const logFiles = testUtil.createLogFiles(QStringLiteral(":/testFiles/system/duplicate-lines.log")); 0375 0376 systemAnalyzer->setLogFiles(logFiles); 0377 0378 systemAnalyzer->watchLogFiles(true); 0379 0380 QCOMPARE(model->itemCount(), 5); 0381 } 0382 0383 QTEST_MAIN(SystemAnalyzerTest) 0384 0385 #include "systemAnalyzerTest.moc"