File indexing completed on 2024-04-14 03:51:42

0001 /*
0002     This file is part of the KDE libraries
0003     SPDX-FileCopyrightText: 2013 David Faure <faure@kde.org>
0004 
0005     SPDX-License-Identifier: LGPL-2.0-or-later
0006 */
0007 
0008 #include <QDebug>
0009 #include <QFile>
0010 #include <QProcess>
0011 #include <QTest>
0012 
0013 class KCrashTest : public QObject
0014 {
0015     Q_OBJECT
0016 private Q_SLOTS:
0017     void initTestCase()
0018     {
0019         // Don't bring up drkonqi
0020         qputenv("KDE_DEBUG", "1");
0021         // change to the bin dir
0022         QDir::setCurrent(QCoreApplication::applicationDirPath());
0023     }
0024     void testAutoRestart();
0025     void testAutoRestartDirectly();
0026     void testEmergencySave();
0027 };
0028 
0029 static const char s_logFileName[] = "kcrashtest_log";
0030 
0031 static QByteArray readLogFile()
0032 {
0033     QFile logFile(QFile::encodeName(s_logFileName));
0034     if (!logFile.open(QIODevice::ReadOnly)) {
0035         return QByteArray();
0036     }
0037     return logFile.readAll();
0038 }
0039 
0040 static void startCrasher(const QByteArray &flag, const QByteArray &expectedOutput)
0041 {
0042     QFile::remove(QFile::encodeName(s_logFileName));
0043 
0044     QProcess proc;
0045     QString processName;
0046 #ifdef Q_OS_WIN
0047     QVERIFY(QFile::exists("./test_crasher.exe"));
0048     processName = "test_crasher.exe";
0049 #else
0050     QVERIFY(QFile::exists("./test_crasher"));
0051     processName = QStringLiteral("./test_crasher");
0052 #endif
0053     // qDebug() << proc.args();
0054     QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
0055     env.insert(QStringLiteral("ASAN_OPTIONS"), QStringLiteral("handle_segv=0,poison_heap=0")); // Disable ASAN
0056     proc.setProcessEnvironment(env);
0057     proc.setProcessChannelMode(QProcess::ForwardedChannels);
0058     proc.start(processName, QStringList() << flag);
0059     bool ok = proc.waitForFinished();
0060     QVERIFY(ok);
0061 
0062     QByteArray logData;
0063     for (int i = 0; i < 50; ++i) {
0064         logData = readLogFile();
0065         if (logData == expectedOutput) {
0066             return;
0067         }
0068         QTest::qSleep(100);
0069     }
0070     qDebug() << proc.readAllStandardError();
0071     QCOMPARE(QString(logData), QString(expectedOutput));
0072 }
0073 
0074 void KCrashTest::testAutoRestart() // use kdeinit if possible, otherwise directly (ex: on CI)
0075 {
0076     startCrasher("AR", "starting AR\nautorestarted AR\n");
0077 }
0078 
0079 void KCrashTest::testAutoRestartDirectly() // test directly (so a developer can test the CI case)
0080 {
0081     startCrasher("ARD", "starting ARD\nautorestarted ARD\n");
0082 }
0083 
0084 void KCrashTest::testEmergencySave()
0085 {
0086     startCrasher("ES", "starting ES\nsaveFunction called\n");
0087 }
0088 
0089 QTEST_MAIN(KCrashTest)
0090 
0091 #include "kcrashtest.moc"