KWin
Loading...
Searching...
No Matches
test_client_machine.cpp
Go to the documentation of this file.
1/*
2 KWin - the KDE window manager
3 This file is part of the KDE project.
4
5 SPDX-FileCopyrightText: 2013 Martin Gräßlin <mgraesslin@kde.org>
6
7 SPDX-License-Identifier: GPL-2.0-or-later
8*/
9#include "testutils.h"
10// KWin
11#include "client_machine.h"
12#include "utils/xcbutils.h"
13// Qt
14#include <QApplication>
15#include <QLoggingCategory>
16#include <QSignalSpy>
17#include <QTest>
18#include <private/qtx11extras_p.h>
19// xcb
20#include <xcb/xcb.h>
21// system
22#include <netdb.h>
23#include <sys/socket.h>
24#include <sys/types.h>
25#include <unistd.h>
26
27Q_LOGGING_CATEGORY(KWIN_CORE, "kwin_core")
28
29using namespace KWin;
30
31class TestClientMachine : public QObject
32{
33 Q_OBJECT
34private Q_SLOTS:
35 void initTestCase();
36 void cleanupTestCase();
37 void hostName_data();
38 void hostName();
39 void emptyHostName();
40
41private:
42 void setClientMachineProperty(xcb_window_t window, const QString &hostname);
43 QString m_hostName;
44 QString m_fqdn;
45};
46
47void TestClientMachine::setClientMachineProperty(xcb_window_t window, const QString &hostname)
48{
49 xcb_change_property(connection(), XCB_PROP_MODE_REPLACE, window,
50 XCB_ATOM_WM_CLIENT_MACHINE, XCB_ATOM_STRING, 8,
51 hostname.length(), hostname.toLocal8Bit().constData());
52}
53
54void TestClientMachine::initTestCase()
55{
56#ifdef HOST_NAME_MAX
57 char hostnamebuf[HOST_NAME_MAX];
58#else
59 char hostnamebuf[256];
60#endif
61 if (gethostname(hostnamebuf, sizeof hostnamebuf) >= 0) {
62 hostnamebuf[sizeof(hostnamebuf) - 1] = 0;
63 m_hostName = hostnamebuf;
64 }
65 addrinfo *res;
66 addrinfo addressHints;
67 memset(&addressHints, 0, sizeof(addressHints));
68 addressHints.ai_family = PF_UNSPEC;
69 addressHints.ai_socktype = SOCK_STREAM;
70 addressHints.ai_flags |= AI_CANONNAME;
71 if (getaddrinfo(m_hostName.toLocal8Bit().constData(), nullptr, &addressHints, &res) == 0) {
72 if (res->ai_canonname) {
73 m_fqdn = QString::fromLocal8Bit(res->ai_canonname);
74 }
75 }
76 freeaddrinfo(res);
77
78 qApp->setProperty("x11RootWindow", QVariant::fromValue<quint32>(QX11Info::appRootWindow()));
79 qApp->setProperty("x11Connection", QVariant::fromValue<void *>(QX11Info::connection()));
80}
81
82void TestClientMachine::cleanupTestCase()
83{
84}
85
86void TestClientMachine::hostName_data()
87{
88 QTest::addColumn<QString>("hostName");
89 QTest::addColumn<QString>("expectedHost");
90 QTest::addColumn<bool>("local");
91
92 QTest::newRow("empty") << QString() << QStringLiteral("localhost") << true;
93 QTest::newRow("localhost") << QStringLiteral("localhost") << QStringLiteral("localhost") << true;
94 QTest::newRow("hostname") << m_hostName << m_hostName << true;
95 QTest::newRow("HOSTNAME") << m_hostName.toUpper() << m_hostName.toUpper() << true;
96 QString cutted(m_hostName);
97 cutted.remove(0, 1);
98 QTest::newRow("ostname") << cutted << cutted << false;
99 QString domain("random.name.not.exist.tld");
100 QTest::newRow("domain") << domain << domain << false;
101 QTest::newRow("fqdn") << m_fqdn << m_fqdn << true;
102 QTest::newRow("FQDN") << m_fqdn.toUpper() << m_fqdn.toUpper() << true;
103 cutted = m_fqdn;
104 cutted.remove(0, 1);
105 QTest::newRow("qdn") << cutted << cutted << false;
106}
107
108void TestClientMachine::hostName()
109{
110 const QRect geometry(0, 0, 10, 10);
111 const uint32_t values[] = {true};
112 Xcb::Window window(geometry, XCB_WINDOW_CLASS_INPUT_ONLY, XCB_CW_OVERRIDE_REDIRECT, values);
113 QFETCH(QString, hostName);
114 QFETCH(bool, local);
115 setClientMachineProperty(window, hostName);
116
117 ClientMachine clientMachine;
118 QSignalSpy spy(&clientMachine, &ClientMachine::localhostChanged);
119 clientMachine.resolve(window, XCB_WINDOW_NONE);
120 QTEST(clientMachine.hostName(), "expectedHost");
121
122 int i = 0;
123 while (clientMachine.isResolving() && i++ < 50) {
124 // name is being resolved in an external thread, so let's wait a little bit
125 QTest::qWait(250);
126 }
127
128 QCOMPARE(clientMachine.isLocal(), local);
129 QCOMPARE(spy.isEmpty(), !local);
130}
131
132void TestClientMachine::emptyHostName()
133{
134 const QRect geometry(0, 0, 10, 10);
135 const uint32_t values[] = {true};
136 Xcb::Window window(geometry, XCB_WINDOW_CLASS_INPUT_ONLY, XCB_CW_OVERRIDE_REDIRECT, values);
137 ClientMachine clientMachine;
138 QSignalSpy spy(&clientMachine, &ClientMachine::localhostChanged);
139 clientMachine.resolve(window, XCB_WINDOW_NONE);
140 QCOMPARE(clientMachine.hostName(), ClientMachine::localhost());
141 QVERIFY(clientMachine.isLocal());
142 // should be local
143 QCOMPARE(spy.isEmpty(), false);
144}
145
146Q_CONSTRUCTOR_FUNCTION(forceXcb)
148#include "test_client_machine.moc"
bool isResolving() const
void resolve(xcb_window_t window, xcb_window_t clientLeader)
const QString & hostName() const
static QString localhost()
KWIN_EXPORT xcb_connection_t * connection()
Definition xcb.h:19
QTEST_MAIN(OnScreenNotificationTest)