GCC Code Coverage Report


Directory: ./
File: autotests/client/error.cpp
Date: 2024-01-22 17:25:27
Exec Total Coverage
Lines: 99 99 100.0%
Branches: 123 246 50.0%

Line Branch Exec Source
1 /********************************************************************
2 Copyright 2016 Martin Gräßlin <mgraesslin@kde.org>
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) version 3, or any
8 later version accepted by the membership of KDE e.V. (or its
9 successor approved by the membership of KDE e.V.), which shall
10 act as a proxy defined in Section 6 of version 3 of the license.
11
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public
18 License along with this library. If not, see <http://www.gnu.org/licenses/>.
19 *********************************************************************/
20 #include <QtTest>
21
22 #include "../../src/client/compositor.h"
23 #include "../../src/client/connection_thread.h"
24 #include "../../src/client/event_queue.h"
25 #include "../../src/client/plasmashell.h"
26 #include "../../src/client/registry.h"
27 #include "../../src/client/surface.h"
28 #include "../../src/client/xdg_shell.h"
29
30 #include "../../server/compositor.h"
31 #include "../../server/display.h"
32 #include "../../server/plasma_shell.h"
33 #include "../../server/xdg_shell.h"
34
35 #include "../../tests/globals.h"
36
37 #include <errno.h> // For EPROTO
38 #include <wayland-client-protocol.h>
39
40 1 class ErrorTest : public QObject
41 {
42 Q_OBJECT
43 private Q_SLOTS:
44 void init();
45 void cleanup();
46
47 void testMultipleShellSurfacesForSurface();
48 void testMultiplePlasmaShellSurfacesForSurface();
49
50 private:
51 1 struct {
52 std::unique_ptr<Wrapland::Server::Display> display;
53 Wrapland::Server::globals globals;
54 } server;
55
56 1 Wrapland::Client::ConnectionThread* m_connection = nullptr;
57 1 QThread* m_thread = nullptr;
58 1 Wrapland::Client::EventQueue* m_queue = nullptr;
59 1 Wrapland::Client::Compositor* m_compositor = nullptr;
60 1 Wrapland::Client::XdgShell* m_shell = nullptr;
61 1 Wrapland::Client::PlasmaShell* m_plasmaShell = nullptr;
62 };
63
64 constexpr auto socket_name{"wrapland-test-error-0"};
65
66 2 void ErrorTest::init()
67 {
68 2 server.display = std::make_unique<Wrapland::Server::Display>();
69
2/4
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
2 server.display->set_socket_name(socket_name);
70 2 server.display->start();
71
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 QVERIFY(server.display->running());
72
73 2 server.display->createShm();
74 4 server.globals.compositor
75 4 = std::make_unique<Wrapland::Server::Compositor>(server.display.get());
76 2 server.globals.xdg_shell = std::make_unique<Wrapland::Server::XdgShell>(server.display.get());
77 4 server.globals.plasma_shell
78 4 = std::make_unique<Wrapland::Server::PlasmaShell>(server.display.get());
79
80 // setup connection
81
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 m_connection = new Wrapland::Client::ConnectionThread;
82 2 QSignalSpy connectedSpy(m_connection, &Wrapland::Client::ConnectionThread::establishedChanged);
83
3/6
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 QVERIFY(connectedSpy.isValid());
84
2/4
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
2 m_connection->setSocketName(socket_name);
85
86
2/4
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
2 m_thread = new QThread(this);
87
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 m_connection->moveToThread(m_thread);
88
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 m_thread->start();
89
90
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 m_connection->establishConnection();
91
6/12
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 2 times.
2 QVERIFY(connectedSpy.count() || connectedSpy.wait());
92
2/4
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
2 QCOMPARE(connectedSpy.count(), 1);
93
94
2/4
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
2 m_queue = new Wrapland::Client::EventQueue(this);
95
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 m_queue->setup(m_connection);
96
97
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 Wrapland::Client::Registry registry;
98
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 QSignalSpy interfacesAnnouncedSpy(&registry, &Wrapland::Client::Registry::interfacesAnnounced);
99
3/6
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 QVERIFY(interfacesAnnouncedSpy.isValid());
100
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 registry.setEventQueue(m_queue);
101
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 registry.create(m_connection);
102
3/6
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 QVERIFY(registry.isValid());
103
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 registry.setup();
104
5/10
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 2 times.
2 QVERIFY(interfacesAnnouncedSpy.wait());
105
106
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 m_compositor = registry.createCompositor(
107
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 registry.interface(Wrapland::Client::Registry::Interface::Compositor).name,
108
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 registry.interface(Wrapland::Client::Registry::Interface::Compositor).version,
109 this);
110
2/4
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
2 QVERIFY(m_compositor);
111
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 m_shell = registry.createXdgShell(
112
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 registry.interface(Wrapland::Client::Registry::Interface::XdgShell).name,
113
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 registry.interface(Wrapland::Client::Registry::Interface::XdgShell).version,
114 this);
115
2/4
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
2 QVERIFY(m_shell);
116
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 m_plasmaShell = registry.createPlasmaShell(
117
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 registry.interface(Wrapland::Client::Registry::Interface::PlasmaShell).name,
118
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 registry.interface(Wrapland::Client::Registry::Interface::PlasmaShell).version,
119 this);
120
2/4
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
2 QVERIFY(m_plasmaShell);
121
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 }
122
123 2 void ErrorTest::cleanup()
124 {
125 #define CLEANUP(variable) \
126 if (variable) { \
127 delete variable; \
128 variable = nullptr; \
129 }
130
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
2 CLEANUP(m_plasmaShell)
131
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
2 CLEANUP(m_shell)
132
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
2 CLEANUP(m_compositor)
133
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
2 CLEANUP(m_queue)
134
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (m_connection) {
135 2 m_connection->deleteLater();
136 2 m_connection = nullptr;
137 2 }
138
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (m_thread) {
139 2 m_thread->quit();
140 2 m_thread->wait();
141
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 delete m_thread;
142 2 m_thread = nullptr;
143 2 }
144 #undef CLEANUP
145
146
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 server = {};
147 2 }
148
149 1 void ErrorTest::testMultipleShellSurfacesForSurface()
150 {
151 // this test verifies that creating two ShellSurfaces for the same Surface triggers a protocol
152 // error
153 1 QSignalSpy errorSpy(m_connection, &Wrapland::Client::ConnectionThread::establishedChanged);
154
3/6
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 QVERIFY(errorSpy.isValid());
155
156
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 std::unique_ptr<Wrapland::Client::Surface> surface(m_compositor->createSurface());
157 1 std::unique_ptr<Wrapland::Client::XdgShellToplevel> shellSurface1(
158
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 m_shell->create_toplevel(surface.get()));
159 1 std::unique_ptr<Wrapland::Client::XdgShellToplevel> shellSurface2(
160
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 m_shell->create_toplevel(surface.get()));
161
162
3/6
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 QCOMPARE(m_connection->error(), 0);
163
5/10
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 1 times.
1 QVERIFY(errorSpy.wait());
164
3/6
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 QCOMPARE(m_connection->error(), EPROTO);
165
3/6
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 QVERIFY(m_connection->hasProtocolError());
166
3/6
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
1 QCOMPARE(m_connection->protocolError(), WL_DISPLAY_ERROR_INVALID_OBJECT);
167
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 }
168
169 1 void ErrorTest::testMultiplePlasmaShellSurfacesForSurface()
170 {
171 // this test verifies that creating two ShellSurfaces for the same Surface triggers a protocol
172 // error
173 1 QSignalSpy errorSpy(m_connection, &Wrapland::Client::ConnectionThread::establishedChanged);
174
3/6
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 QVERIFY(errorSpy.isValid());
175 // PlasmaShell is too smart and doesn't allow us to create a second PlasmaShellSurface
176 // thus we need to cheat by creating a surface manually
177
2/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 auto surface = wl_compositor_create_surface(*m_compositor);
178 1 std::unique_ptr<Wrapland::Client::PlasmaShellSurface> shellSurface1(
179
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 m_plasmaShell->createSurface(surface));
180 1 std::unique_ptr<Wrapland::Client::PlasmaShellSurface> shellSurface2(
181
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 m_plasmaShell->createSurface(surface));
182
3/6
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 QCOMPARE(m_connection->error(), 0);
183
5/10
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 1 times.
1 QVERIFY(errorSpy.wait());
184
3/6
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 QCOMPARE(m_connection->error(), EPROTO);
185
3/6
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
1 QVERIFY(m_connection->hasProtocolError());
186
3/6
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
1 QCOMPARE(m_connection->protocolError(), WL_DISPLAY_ERROR_INVALID_OBJECT);
187
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 wl_surface_destroy(surface);
188
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 }
189
190
4/8
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
1 QTEST_GUILESS_MAIN(ErrorTest)
191 #include "error.moc"
192