File indexing completed on 2024-11-10 04:56:21
0001 /* 0002 SPDX-FileCopyrightText: 2014 Martin Gräßlin <mgraesslin@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0005 */ 0006 // Qt 0007 #include <QSignalSpy> 0008 #include <QTest> 0009 // WaylandServer 0010 #include "wayland/clientconnection.h" 0011 #include "wayland/display.h" 0012 // Wayland 0013 #include <wayland-server.h> 0014 // system 0015 #include <sys/socket.h> 0016 #include <sys/types.h> 0017 #include <unistd.h> 0018 0019 using namespace KWin; 0020 0021 class TestWaylandServerDisplay : public QObject 0022 { 0023 Q_OBJECT 0024 private Q_SLOTS: 0025 void testSocketName(); 0026 void testStartStop(); 0027 void testClientConnection(); 0028 void testConnectNoSocket(); 0029 void testAutoSocketName(); 0030 }; 0031 0032 void TestWaylandServerDisplay::testSocketName() 0033 { 0034 KWin::Display display; 0035 QSignalSpy changedSpy(&display, &KWin::Display::socketNamesChanged); 0036 QCOMPARE(display.socketNames(), QStringList()); 0037 const QString testSName = QStringLiteral("fooBar"); 0038 display.addSocketName(testSName); 0039 QCOMPARE(display.socketNames(), QStringList{testSName}); 0040 QCOMPARE(changedSpy.count(), 1); 0041 0042 // changing to same name again should not emit signal 0043 display.addSocketName(testSName); 0044 QCOMPARE(changedSpy.count(), 1); 0045 } 0046 0047 void TestWaylandServerDisplay::testStartStop() 0048 { 0049 const QString testSocketName = QStringLiteral("kwin-wayland-server-display-test-0"); 0050 QDir runtimeDir(qgetenv("XDG_RUNTIME_DIR")); 0051 QVERIFY(runtimeDir.exists()); 0052 QVERIFY(!runtimeDir.exists(testSocketName)); 0053 0054 std::unique_ptr<KWin::Display> display(new KWin::Display); 0055 QSignalSpy runningSpy(display.get(), &KWin::Display::runningChanged); 0056 display->addSocketName(testSocketName); 0057 QVERIFY(!display->isRunning()); 0058 display->start(); 0059 // QVERIFY(runningSpy.wait()); 0060 QCOMPARE(runningSpy.count(), 1); 0061 QVERIFY(runningSpy.first().first().toBool()); 0062 QVERIFY(display->isRunning()); 0063 QVERIFY(runtimeDir.exists(testSocketName)); 0064 0065 display.reset(); 0066 QVERIFY(!runtimeDir.exists(testSocketName)); 0067 } 0068 0069 void TestWaylandServerDisplay::testClientConnection() 0070 { 0071 KWin::Display display; 0072 display.addSocketName(QStringLiteral("kwin-wayland-server-display-test-client-connection")); 0073 display.start(); 0074 QSignalSpy connectedSpy(&display, &KWin::Display::clientConnected); 0075 QSignalSpy disconnectedSpy(&display, &KWin::Display::clientDisconnected); 0076 0077 int sv[2]; 0078 QVERIFY(socketpair(AF_UNIX, SOCK_STREAM, 0, sv) >= 0); 0079 0080 auto client = wl_client_create(display, sv[0]); 0081 QVERIFY(client); 0082 0083 QVERIFY(connectedSpy.isEmpty()); 0084 QVERIFY(display.connections().isEmpty()); 0085 ClientConnection *connection = display.getConnection(client); 0086 QVERIFY(connection); 0087 QCOMPARE(connection->client(), client); 0088 if (getuid() == 0) { 0089 QEXPECT_FAIL("", "Please don't run test as root", Continue); 0090 } 0091 QVERIFY(connection->userId() != 0); 0092 if (getgid() == 0) { 0093 QEXPECT_FAIL("", "Please don't run test as root", Continue); 0094 } 0095 QVERIFY(connection->groupId() != 0); 0096 QVERIFY(connection->processId() != 0); 0097 QCOMPARE(connection->display(), &display); 0098 QCOMPARE(connection->executablePath(), QCoreApplication::applicationFilePath()); 0099 QCOMPARE((wl_client *)*connection, client); 0100 const ClientConnection &constRef = *connection; 0101 QCOMPARE((wl_client *)constRef, client); 0102 QCOMPARE(connectedSpy.count(), 1); 0103 QCOMPARE(connectedSpy.first().first().value<ClientConnection *>(), connection); 0104 QCOMPARE(display.connections().count(), 1); 0105 QCOMPARE(display.connections().first(), connection); 0106 0107 QCOMPARE(connection, display.getConnection(client)); 0108 QCOMPARE(connectedSpy.count(), 1); 0109 0110 // create a second client 0111 int sv2[2]; 0112 QVERIFY(socketpair(AF_UNIX, SOCK_STREAM, 0, sv2) >= 0); 0113 auto client2 = display.createClient(sv2[0]); 0114 QVERIFY(client2); 0115 ClientConnection *connection2 = display.getConnection(client2->client()); 0116 QVERIFY(connection2); 0117 QCOMPARE(connection2, client2); 0118 QCOMPARE(connectedSpy.count(), 2); 0119 QCOMPARE(connectedSpy.first().first().value<ClientConnection *>(), connection); 0120 QCOMPARE(connectedSpy.last().first().value<ClientConnection *>(), connection2); 0121 QCOMPARE(connectedSpy.last().first().value<ClientConnection *>(), client2); 0122 QCOMPARE(display.connections().count(), 2); 0123 QCOMPARE(display.connections().first(), connection); 0124 QCOMPARE(display.connections().last(), connection2); 0125 QCOMPARE(display.connections().last(), client2); 0126 0127 // and destroy 0128 QVERIFY(disconnectedSpy.isEmpty()); 0129 wl_client_destroy(client); 0130 QCOMPARE(disconnectedSpy.count(), 1); 0131 QSignalSpy clientDestroyedSpy(client2, &QObject::destroyed); 0132 client2->destroy(); 0133 QCOMPARE(clientDestroyedSpy.count(), 1); 0134 QCOMPARE(disconnectedSpy.count(), 2); 0135 close(sv[0]); 0136 close(sv[1]); 0137 close(sv2[0]); 0138 close(sv2[1]); 0139 QVERIFY(display.connections().isEmpty()); 0140 } 0141 0142 void TestWaylandServerDisplay::testConnectNoSocket() 0143 { 0144 KWin::Display display; 0145 display.start(); 0146 QVERIFY(display.isRunning()); 0147 0148 // let's try connecting a client 0149 int sv[2]; 0150 QVERIFY(socketpair(AF_UNIX, SOCK_STREAM, 0, sv) >= 0); 0151 auto client = display.createClient(sv[0]); 0152 QVERIFY(client); 0153 0154 wl_client_destroy(client->client()); 0155 close(sv[0]); 0156 close(sv[1]); 0157 } 0158 0159 void TestWaylandServerDisplay::testAutoSocketName() 0160 { 0161 QTemporaryDir runtimeDir; 0162 QVERIFY(runtimeDir.isValid()); 0163 QVERIFY(qputenv("XDG_RUNTIME_DIR", runtimeDir.path().toUtf8())); 0164 0165 KWin::Display display0; 0166 QSignalSpy socketNameChangedSpy0(&display0, &KWin::Display::socketNamesChanged); 0167 QVERIFY(socketNameChangedSpy0.isValid()); 0168 QVERIFY(display0.addSocketName()); 0169 display0.start(); 0170 QVERIFY(display0.isRunning()); 0171 QCOMPARE(socketNameChangedSpy0.count(), 1); 0172 0173 KWin::Display display1; 0174 QSignalSpy socketNameChangedSpy1(&display1, &KWin::Display::socketNamesChanged); 0175 QVERIFY(socketNameChangedSpy1.isValid()); 0176 QVERIFY(display1.addSocketName()); 0177 display1.start(); 0178 QVERIFY(display1.isRunning()); 0179 QCOMPARE(socketNameChangedSpy1.count(), 1); 0180 } 0181 0182 QTEST_GUILESS_MAIN(TestWaylandServerDisplay) 0183 #include "test_display.moc"