File indexing completed on 2024-05-12 17:00:09

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 <QtTest>
0012 // system
0013 #include <signal.h>
0014 
0015 Q_DECLARE_METATYPE(QProcess::ExitStatus)
0016 
0017 class KillTest : public QObject
0018 {
0019     Q_OBJECT
0020 private Q_SLOTS:
0021     void testKill_data();
0022     void testKill();
0023     void testImmediateKill_data();
0024     void testImmediateKill();
0025 };
0026 
0027 void KillTest::testKill_data()
0028 {
0029     QTest::addColumn<int>("signal");
0030     QTest::addColumn<bool>("expectedQuit");
0031     QTest::addColumn<QProcess::ExitStatus>("exitStatus");
0032 
0033     QTest::newRow("SIGHUP") << SIGHUP << true << QProcess::CrashExit;
0034     QTest::newRow("SIGINT") << SIGINT << true << QProcess::CrashExit;
0035     QTest::newRow("SIGQUIT") << SIGQUIT << true << QProcess::CrashExit;
0036     QTest::newRow("SIGILL") << SIGILL << true << QProcess::CrashExit;
0037     QTest::newRow("SIGTRAP") << SIGTRAP << true << QProcess::CrashExit;
0038     QTest::newRow("SIGABRT") << SIGABRT << true << QProcess::CrashExit;
0039     QTest::newRow("SIGIOT") << SIGIOT << true << QProcess::CrashExit;
0040     QTest::newRow("SIGBUS") << SIGBUS << true << QProcess::CrashExit;
0041     QTest::newRow("SIGFPE") << SIGFPE << true << QProcess::CrashExit;
0042     QTest::newRow("SIGKILL") << SIGKILL << true << QProcess::CrashExit;
0043     QTest::newRow("SIGUSR1") << SIGUSR1 << false << QProcess::CrashExit;
0044     QTest::newRow("SIGSEGV") << SIGSEGV << true << QProcess::CrashExit;
0045     QTest::newRow("SIGUSR2") << SIGUSR2 << true << QProcess::CrashExit;
0046     QTest::newRow("SIGPIPE") << SIGPIPE << true << QProcess::CrashExit;
0047     QTest::newRow("SIGALRM") << SIGALRM << true << QProcess::CrashExit;
0048     QTest::newRow("SIGTERM") << SIGTERM << true << QProcess::NormalExit;
0049     // ignore
0050     // QTest::newRow("SIGCHLD")   << SIGCHLD;
0051     // QTest::newRow("SIGCONT")   << SIGCONT;
0052     // QTest::newRow("SIGSTOP")   << SIGSTOP;
0053     // QTest::newRow("SIGTSTP")   << SIGTSTP;
0054     // QTest::newRow("SIGTTIN")   << SIGTTIN;
0055     // QTest::newRow("SIGTTOU")   << SIGTTOU;
0056     // QTest::newRow("SIGURG")    << SIGURG;
0057     // QTest::newRow("SIGXCPU")   << SIGXCPU;
0058     // QTest::newRow("SIGXFSZ")   << SIGXFSZ;
0059     // QTest::newRow("SIGVTALRM") << SIGVTALRM;
0060     // QTest::newRow("SIGPROF")   << SIGPROF;
0061     // QTest::newRow("SIGWINCH")  << SIGWINCH;
0062     // QTest::newRow("SIGIO")     << SIGIO;
0063     // QTest::newRow("SIGPWR")    << SIGPWR;
0064     QTest::newRow("SIGSYS") << SIGSYS << true << QProcess::CrashExit;
0065 #ifdef Q_OS_LINUX
0066 #ifdef SIGUNUSED
0067     QTest::newRow("SIGUNUSED") << SIGUNUSED << true << QProcess::CrashExit;
0068 #endif
0069 #ifdef SIGSTKFLT
0070     QTest::newRow("SIGSTKFLT") << SIGSTKFLT << true << QProcess::CrashExit;
0071 #endif
0072 #endif
0073 }
0074 
0075 void KillTest::testKill()
0076 {
0077     QProcess greeter(this);
0078     greeter.setReadChannel(QProcess::StandardOutput);
0079     greeter.start(KLibexec::path(KSCREENLOCKER_GREET_BIN_REL), QStringList({QStringLiteral("--testing")}));
0080     QVERIFY(greeter.waitForStarted());
0081 
0082     // wait some time till it's really set up
0083     QTest::qSleep(5000);
0084 
0085     // now kill
0086     QFETCH(int, signal);
0087     kill(greeter.processId(), signal);
0088 
0089     QFETCH(bool, expectedQuit);
0090     QCOMPARE(greeter.waitForFinished(1000), expectedQuit);
0091     if (greeter.state() == QProcess::Running) {
0092         greeter.terminate();
0093         QVERIFY(greeter.waitForFinished());
0094     } else {
0095         QFETCH(QProcess::ExitStatus, exitStatus);
0096         QCOMPARE(greeter.exitStatus(), exitStatus);
0097 
0098         if (greeter.exitStatus() == QProcess::NormalExit) {
0099             // exit code is only valid for NormalExit
0100             QCOMPARE(greeter.exitCode(), 1);
0101         }
0102     }
0103 }
0104 
0105 void KillTest::testImmediateKill_data()
0106 {
0107     QTest::addColumn<int>("signal");
0108 
0109     QTest::newRow("SIGHUP") << SIGHUP;
0110     QTest::newRow("SIGINT") << SIGINT;
0111     QTest::newRow("SIGQUIT") << SIGQUIT;
0112     QTest::newRow("SIGILL") << SIGILL;
0113     QTest::newRow("SIGTRAP") << SIGTRAP;
0114     QTest::newRow("SIGABRT") << SIGABRT;
0115     QTest::newRow("SIGIOT") << SIGIOT;
0116     QTest::newRow("SIGBUS") << SIGBUS;
0117     QTest::newRow("SIGFPE") << SIGFPE;
0118     QTest::newRow("SIGKILL") << SIGKILL;
0119     QTest::newRow("SIGUSR1") << SIGUSR1;
0120     QTest::newRow("SIGSEGV") << SIGSEGV;
0121     QTest::newRow("SIGUSR2") << SIGUSR2;
0122     QTest::newRow("SIGPIPE") << SIGPIPE;
0123     QTest::newRow("SIGALRM") << SIGALRM;
0124     QTest::newRow("SIGTERM") << SIGTERM;
0125     // ignore
0126     // QTest::newRow("SIGCHLD")   << SIGCHLD;
0127     // QTest::newRow("SIGCONT")   << SIGCONT;
0128     // QTest::newRow("SIGSTOP")   << SIGSTOP;
0129     // QTest::newRow("SIGTSTP")   << SIGTSTP;
0130     // QTest::newRow("SIGTTIN")   << SIGTTIN;
0131     // QTest::newRow("SIGTTOU")   << SIGTTOU;
0132     // QTest::newRow("SIGURG")    << SIGURG;
0133     // QTest::newRow("SIGXCPU")   << SIGXCPU;
0134     // QTest::newRow("SIGXFSZ")   << SIGXFSZ;
0135     // QTest::newRow("SIGVTALRM") << SIGVTALRM;
0136     // QTest::newRow("SIGPROF")   << SIGPROF;
0137     // QTest::newRow("SIGWINCH")  << SIGWINCH;
0138     // QTest::newRow("SIGIO")     << SIGIO;
0139     // QTest::newRow("SIGPWR")    << SIGPWR;
0140     QTest::newRow("SIGSYS") << SIGSYS;
0141 #ifdef Q_OS_LINUX
0142 #ifdef SIGSTKFLT
0143     QTest::newRow("SIGSTKFLT") << SIGSTKFLT;
0144 #endif
0145 #ifdef SIGUNUSED
0146     QTest::newRow("SIGUNUSED") << SIGUNUSED;
0147 #endif
0148 #endif
0149 }
0150 
0151 void KillTest::testImmediateKill()
0152 {
0153     // this test ensures that the greeter indicates crashexit when a signal is sent to the greeter
0154     // before it had time to properly setup
0155     QProcess greeter(this);
0156     greeter.start(KLibexec::path(KSCREENLOCKER_GREET_BIN_REL), QStringList({QStringLiteral("--testing")}));
0157     QVERIFY(greeter.waitForStarted());
0158 
0159     // now kill
0160     QFETCH(int, signal);
0161     kill(greeter.processId(), signal);
0162 
0163     QVERIFY(greeter.waitForFinished());
0164     QCOMPARE(greeter.exitStatus(), QProcess::CrashExit);
0165 }
0166 
0167 QTEST_MAIN(KillTest)
0168 #include "killtest.moc"