File indexing completed on 2024-05-05 05:30:27
0001 /* 0002 SPDX-FileCopyrightText: 2014 Martin Gräßlin <mgraesslin@kde.org> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 // own 0007 #include <config-kscreenlocker.h> 0008 // KF 0009 #include <KLibexec> 0010 // Qt 0011 #include <QProcess> 0012 #include <QSignalSpy> 0013 #include <QTest> 0014 // system 0015 #include <signal.h> 0016 0017 Q_DECLARE_METATYPE(QProcess::ExitStatus) 0018 0019 class KillTest : public QObject 0020 { 0021 Q_OBJECT 0022 private Q_SLOTS: 0023 void testKill_data(); 0024 void testKill(); 0025 void testImmediateKill_data(); 0026 void testImmediateKill(); 0027 }; 0028 0029 void KillTest::testKill_data() 0030 { 0031 QTest::addColumn<int>("signal"); 0032 QTest::addColumn<bool>("expectedQuit"); 0033 QTest::addColumn<QProcess::ExitStatus>("exitStatus"); 0034 0035 QTest::newRow("SIGHUP") << SIGHUP << true << QProcess::CrashExit; 0036 QTest::newRow("SIGINT") << SIGINT << true << QProcess::CrashExit; 0037 QTest::newRow("SIGQUIT") << SIGQUIT << true << QProcess::CrashExit; 0038 QTest::newRow("SIGILL") << SIGILL << true << QProcess::CrashExit; 0039 QTest::newRow("SIGTRAP") << SIGTRAP << true << QProcess::CrashExit; 0040 QTest::newRow("SIGABRT") << SIGABRT << true << QProcess::CrashExit; 0041 QTest::newRow("SIGIOT") << SIGIOT << true << QProcess::CrashExit; 0042 QTest::newRow("SIGBUS") << SIGBUS << true << QProcess::CrashExit; 0043 QTest::newRow("SIGFPE") << SIGFPE << true << QProcess::CrashExit; 0044 QTest::newRow("SIGKILL") << SIGKILL << true << QProcess::CrashExit; 0045 QTest::newRow("SIGUSR1") << SIGUSR1 << false << QProcess::CrashExit; 0046 QTest::newRow("SIGSEGV") << SIGSEGV << true << QProcess::CrashExit; 0047 QTest::newRow("SIGUSR2") << SIGUSR2 << true << QProcess::CrashExit; 0048 QTest::newRow("SIGPIPE") << SIGPIPE << true << QProcess::CrashExit; 0049 QTest::newRow("SIGALRM") << SIGALRM << true << QProcess::CrashExit; 0050 QTest::newRow("SIGTERM") << SIGTERM << true << QProcess::NormalExit; 0051 // ignore 0052 // QTest::newRow("SIGCHLD") << SIGCHLD; 0053 // QTest::newRow("SIGCONT") << SIGCONT; 0054 // QTest::newRow("SIGSTOP") << SIGSTOP; 0055 // QTest::newRow("SIGTSTP") << SIGTSTP; 0056 // QTest::newRow("SIGTTIN") << SIGTTIN; 0057 // QTest::newRow("SIGTTOU") << SIGTTOU; 0058 // QTest::newRow("SIGURG") << SIGURG; 0059 // QTest::newRow("SIGXCPU") << SIGXCPU; 0060 // QTest::newRow("SIGXFSZ") << SIGXFSZ; 0061 // QTest::newRow("SIGVTALRM") << SIGVTALRM; 0062 // QTest::newRow("SIGPROF") << SIGPROF; 0063 // QTest::newRow("SIGWINCH") << SIGWINCH; 0064 // QTest::newRow("SIGIO") << SIGIO; 0065 // QTest::newRow("SIGPWR") << SIGPWR; 0066 QTest::newRow("SIGSYS") << SIGSYS << true << QProcess::CrashExit; 0067 #ifdef Q_OS_LINUX 0068 #ifdef SIGUNUSED 0069 QTest::newRow("SIGUNUSED") << SIGUNUSED << true << QProcess::CrashExit; 0070 #endif 0071 #ifdef SIGSTKFLT 0072 QTest::newRow("SIGSTKFLT") << SIGSTKFLT << true << QProcess::CrashExit; 0073 #endif 0074 #endif 0075 } 0076 0077 void KillTest::testKill() 0078 { 0079 QProcess greeter(this); 0080 QSignalSpy spy(&greeter, &QProcess::readyReadStandardOutput); 0081 0082 greeter.setReadChannel(QProcess::StandardOutput); 0083 greeter.start(KLibexec::path(KSCREENLOCKER_GREET_BIN_REL), QStringList({QStringLiteral("--testing")})); 0084 0085 // Wait for the "locked at" message as an indication that the greeter is ready 0086 spy.wait(5000); 0087 QCOMPARE(spy.count(), 1); 0088 0089 QVERIFY(greeter.readAllStandardOutput().contains(QByteArrayLiteral("Locked at"))); 0090 0091 // now kill 0092 QFETCH(int, signal); 0093 kill(greeter.processId(), signal); 0094 0095 QFETCH(bool, expectedQuit); 0096 QCOMPARE(greeter.waitForFinished(3000), expectedQuit); 0097 if (greeter.state() == QProcess::Running) { 0098 greeter.terminate(); 0099 QVERIFY(greeter.waitForFinished()); 0100 } else { 0101 QFETCH(QProcess::ExitStatus, exitStatus); 0102 QCOMPARE(greeter.exitStatus(), exitStatus); 0103 0104 if (greeter.exitStatus() == QProcess::NormalExit) { 0105 // exit code is only valid for NormalExit 0106 QCOMPARE(greeter.exitCode(), 1); 0107 } 0108 } 0109 } 0110 0111 void KillTest::testImmediateKill_data() 0112 { 0113 QTest::addColumn<int>("signal"); 0114 0115 QTest::newRow("SIGHUP") << SIGHUP; 0116 QTest::newRow("SIGINT") << SIGINT; 0117 QTest::newRow("SIGQUIT") << SIGQUIT; 0118 QTest::newRow("SIGILL") << SIGILL; 0119 QTest::newRow("SIGTRAP") << SIGTRAP; 0120 QTest::newRow("SIGABRT") << SIGABRT; 0121 QTest::newRow("SIGIOT") << SIGIOT; 0122 QTest::newRow("SIGBUS") << SIGBUS; 0123 QTest::newRow("SIGFPE") << SIGFPE; 0124 QTest::newRow("SIGKILL") << SIGKILL; 0125 QTest::newRow("SIGUSR1") << SIGUSR1; 0126 QTest::newRow("SIGSEGV") << SIGSEGV; 0127 QTest::newRow("SIGUSR2") << SIGUSR2; 0128 QTest::newRow("SIGPIPE") << SIGPIPE; 0129 QTest::newRow("SIGALRM") << SIGALRM; 0130 QTest::newRow("SIGTERM") << SIGTERM; 0131 // ignore 0132 // QTest::newRow("SIGCHLD") << SIGCHLD; 0133 // QTest::newRow("SIGCONT") << SIGCONT; 0134 // QTest::newRow("SIGSTOP") << SIGSTOP; 0135 // QTest::newRow("SIGTSTP") << SIGTSTP; 0136 // QTest::newRow("SIGTTIN") << SIGTTIN; 0137 // QTest::newRow("SIGTTOU") << SIGTTOU; 0138 // QTest::newRow("SIGURG") << SIGURG; 0139 // QTest::newRow("SIGXCPU") << SIGXCPU; 0140 // QTest::newRow("SIGXFSZ") << SIGXFSZ; 0141 // QTest::newRow("SIGVTALRM") << SIGVTALRM; 0142 // QTest::newRow("SIGPROF") << SIGPROF; 0143 // QTest::newRow("SIGWINCH") << SIGWINCH; 0144 // QTest::newRow("SIGIO") << SIGIO; 0145 // QTest::newRow("SIGPWR") << SIGPWR; 0146 QTest::newRow("SIGSYS") << SIGSYS; 0147 #ifdef Q_OS_LINUX 0148 #ifdef SIGSTKFLT 0149 QTest::newRow("SIGSTKFLT") << SIGSTKFLT; 0150 #endif 0151 #ifdef SIGUNUSED 0152 QTest::newRow("SIGUNUSED") << SIGUNUSED; 0153 #endif 0154 #endif 0155 } 0156 0157 void KillTest::testImmediateKill() 0158 { 0159 // this test ensures that the greeter indicates crashexit when a signal is sent to the greeter 0160 // before it had time to properly setup 0161 QProcess greeter(this); 0162 greeter.start(KLibexec::path(KSCREENLOCKER_GREET_BIN_REL), QStringList({QStringLiteral("--testing")})); 0163 QVERIFY(greeter.waitForStarted()); 0164 0165 // now kill 0166 QFETCH(int, signal); 0167 kill(greeter.processId(), signal); 0168 0169 QVERIFY(greeter.waitForFinished()); 0170 QCOMPARE(greeter.exitStatus(), QProcess::CrashExit); 0171 } 0172 0173 QTEST_MAIN(KillTest) 0174 #include "killtest.moc"