Mir

Merge lp:~alan-griffiths/mir/rework-test_client_library.cpp into lp:mir

Proposed by Alan Griffiths
Status: Work in progress
Proposed branch: lp:~alan-griffiths/mir/rework-test_client_library.cpp
Merge into: lp:mir
Diff against target: 1922 lines (+768/-1050)
3 files modified
tests/acceptance-tests/CMakeLists.txt (+1/-0)
tests/acceptance-tests/test_client_library.cpp (+641/-1050)
tests/acceptance-tests/test_client_library_threads.cpp (+126/-0)
To merge this branch: bzr merge lp:~alan-griffiths/mir/rework-test_client_library.cpp
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Needs Fixing
Kevin DuBois (community) Approve
Review via email: mp+221216@code.launchpad.net

Commit message

tests: Move (most of) client library tests into a single process

Description of the change

tests: Move (most of) client library tests into a single process

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
1672. By Alan Griffiths

Add missing file

1673. By Alan Griffiths

Simplify signal/thread tests in test_client_library_threads.cpp

1674. By Alan Griffiths

Simplify signal/thread tests in test_client_library_threads.cpp

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

"/home/phablet/mir-testrunner/mir_install_packages.sh: line 10: apt-app-repository: command not found"

WTF?!

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

It isn't obvious why copying HandleNoSignals from one file to another might cause this failure. Triggering rebuild to see if it is consistent.

1675. By Alan Griffiths

merge lp:~mir-team/mir/development-branch

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

> It isn't obvious why copying HandleNoSignals from one file to another might
> cause this failure. Triggering rebuild to see if it is consistent.

Hmm. Seems consistent but is CNR on my desktop.

Tweaking the code in the hope of seeing something illuminating.

1676. By Alan Griffiths

Tweak test_client_library_threads.cpp in the hope of stumbling over what CI fails on

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Kevin DuBois (kdub) wrote :

The build timeout should have been increased to 3h (although why it takes 2+h to build is another matter). retriggering

Revision history for this message
Kevin DuBois (kdub) wrote :

looks okay to me (a few places could use some spacing cleanups, but not enough to block). Tests look much nicer and less intimidating to write.

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

> > It isn't obvious why copying HandleNoSignals from one file to another might
> > cause this failure. Triggering rebuild to see if it is consistent.
>
> Hmm. Seems consistent but is CNR on my desktop.
>
> Tweaking the code in the hope of seeing something illuminating.

Didn't help. Trying not changing that test *at all* on lp:~alan-griffiths/mir/rework-test_client_library.cpp-mk2.

Unmerged revisions

1676. By Alan Griffiths

Tweak test_client_library_threads.cpp in the hope of stumbling over what CI fails on

1675. By Alan Griffiths

merge lp:~mir-team/mir/development-branch

1674. By Alan Griffiths

Simplify signal/thread tests in test_client_library_threads.cpp

1673. By Alan Griffiths

Simplify signal/thread tests in test_client_library_threads.cpp

1672. By Alan Griffiths

Add missing file

1671. By Alan Griffiths

Tidy up remaining tests

1670. By Alan Griffiths

Tidy up some tests

1669. By Alan Griffiths

Move (most of) client library tests into a single process

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'tests/acceptance-tests/CMakeLists.txt'
2--- tests/acceptance-tests/CMakeLists.txt 2014-05-29 15:51:54 +0000
3+++ tests/acceptance-tests/CMakeLists.txt 2014-06-02 13:37:17 +0000
4@@ -16,6 +16,7 @@
5 server_configuration_wrapping.cpp
6 clients.cpp
7 test_client_library.cpp
8+ test_client_library_threads.cpp
9 test_custom_input_dispatcher.cpp
10 test_surfaceloop.cpp
11 test_test_framework.cpp
12
13=== modified file 'tests/acceptance-tests/test_client_library.cpp'
14--- tests/acceptance-tests/test_client_library.cpp 2014-05-23 03:34:02 +0000
15+++ tests/acceptance-tests/test_client_library.cpp 2014-06-02 13:37:17 +0000
16@@ -1,5 +1,5 @@
17 /*
18- * Copyright © 2012 Canonical Ltd.
19+ * Copyright © 2012-2014 Canonical Ltd.
20 *
21 * This program is free software: you can redistribute it and/or modify
22 * it under the terms of the GNU General Public License version 3 as
23@@ -16,10 +16,12 @@
24 * Authored by: Thomas Guest <thomas.guest@canonical.com>
25 */
26
27-#include "mir_test_framework/display_server_test_fixture.h"
28-
29 #include "mir_toolkit/mir_client_library.h"
30 #include "mir_toolkit/mir_client_library_debug.h"
31+
32+#include "mir_test_framework/stubbed_server_configuration.h"
33+#include "mir_test_framework/in_process_server.h"
34+
35 #include "src/client/client_buffer.h"
36
37 #include "mir/frontend/connector.h"
38@@ -35,6 +37,7 @@
39 #endif
40
41 #include <gtest/gtest.h>
42+#include <gmock/gmock.h>
43 #include <chrono>
44 #include <thread>
45 #include <cstring>
46@@ -48,47 +51,40 @@
47 namespace mf = mir::frontend;
48 namespace mc = mir::compositor;
49 namespace mcl = mir::client;
50-namespace mtf = mir_test_framework;
51-
52-namespace
53-{
54- char const* const mir_test_socket = mtf::test_socket_file().c_str();
55-}
56-
57-namespace mir
58-{
59-namespace
60-{
61-struct ClientConfigCommon : TestingClientConfiguration
62-{
63- ClientConfigCommon()
64- : connection(0)
65- , surface(0),
66- buffers(0)
67- {
68- }
69+
70+namespace
71+{
72+struct ClientLibrary : mir_test_framework::InProcessServer
73+{
74+ mir_test_framework::StubbedServerConfiguration server_configuration;
75+ mir::DefaultServerConfiguration& server_config() override { return server_configuration; }
76+
77+ std::set<MirSurface*> surfaces;
78+ MirConnection* connection = nullptr;
79+ MirSurface* surface = nullptr;
80+ int buffers = 0;
81
82 static void connection_callback(MirConnection * connection, void * context)
83 {
84- ClientConfigCommon * config = reinterpret_cast<ClientConfigCommon *>(context);
85- config->connection = connection;
86+ ClientLibrary * config = reinterpret_cast<ClientLibrary *>(context);
87+ config->connected(connection);
88 }
89
90 static void create_surface_callback(MirSurface * surface, void * context)
91 {
92- ClientConfigCommon * config = reinterpret_cast<ClientConfigCommon *>(context);
93+ ClientLibrary * config = reinterpret_cast<ClientLibrary *>(context);
94 config->surface_created(surface);
95 }
96
97 static void next_buffer_callback(MirSurface * surface, void * context)
98 {
99- ClientConfigCommon * config = reinterpret_cast<ClientConfigCommon *>(context);
100+ ClientLibrary * config = reinterpret_cast<ClientLibrary *>(context);
101 config->next_buffer(surface);
102 }
103
104 static void release_surface_callback(MirSurface * surface, void * context)
105 {
106- ClientConfigCommon * config = reinterpret_cast<ClientConfigCommon *>(context);
107+ ClientLibrary * config = reinterpret_cast<ClientLibrary *>(context);
108 config->surface_released(surface);
109 }
110
111@@ -99,6 +95,7 @@
112
113 virtual void surface_created(MirSurface * new_surface)
114 {
115+ surfaces.insert(new_surface);
116 surface = new_surface;
117 }
118
119@@ -107,1055 +104,649 @@
120 ++buffers;
121 }
122
123- virtual void surface_released(MirSurface * /*released_surface*/)
124+ void surface_released(MirSurface * old_surface)
125 {
126+ surfaces.erase(old_surface);
127 surface = NULL;
128 }
129
130- MirConnection* connection;
131- MirSurface* surface;
132- int buffers;
133+ MirSurface* any_surface()
134+ {
135+ return *surfaces.begin();
136+ }
137+
138+ size_t current_surface_count()
139+ {
140+ return surfaces.size();
141+ }
142+
143+ MirEvent last_event{};
144+ MirSurface* last_event_surface = nullptr;
145+
146+ static void event_callback(MirSurface* surface, MirEvent const* event,
147+ void* ctx)
148+ {
149+ ClientLibrary* self = static_cast<ClientLibrary*>(ctx);
150+ self->last_event = *event;
151+ self->last_event_surface = surface;
152+ }
153+
154+ static void nosey_thread(MirSurface *surf)
155+ {
156+ for (int i = 0; i < 10; i++)
157+ {
158+ mir_wait_for_one(mir_surface_set_state(surf,
159+ mir_surface_state_maximized));
160+ mir_wait_for_one(mir_surface_set_type(surf,
161+ mir_surface_type_normal));
162+ mir_wait_for_one(mir_surface_set_state(surf,
163+ mir_surface_state_restored));
164+ mir_wait_for_one(mir_surface_set_type(surf,
165+ mir_surface_type_utility));
166+ mir_wait_for_one(mir_surface_set_state(surf,
167+ mir_surface_state_fullscreen));
168+ mir_wait_for_one(mir_surface_set_type(surf,
169+ mir_surface_type_dialog));
170+ mir_wait_for_one(mir_surface_set_state(surf,
171+ mir_surface_state_minimized));
172+ }
173+ }
174 };
175 }
176
177-TEST_F(DefaultDisplayServerTestFixture, client_library_connects_and_disconnects)
178-{
179- struct ClientConfig : ClientConfigCommon
180- {
181- void exec()
182- {
183- MirWaitHandle* wh =
184- mir_connect(mir_test_socket, __PRETTY_FUNCTION__, connection_callback, this);
185- EXPECT_TRUE(wh != NULL);
186- mir_wait_for(wh);
187- ASSERT_TRUE(connection != NULL);
188- EXPECT_TRUE(mir_connection_is_valid(connection));
189- EXPECT_STREQ(mir_connection_get_error_message(connection), "");
190-
191- mir_connection_release(connection);
192- }
193- } client_config;
194-
195- launch_client_process(client_config);
196-}
197-
198-TEST_F(DefaultDisplayServerTestFixture, synchronous_connection)
199-{
200- struct ClientConfig : ClientConfigCommon
201- {
202- void exec()
203- {
204- connection = NULL;
205- connection = mir_connect_sync(mir_test_socket,
206- __PRETTY_FUNCTION__);
207-
208- ASSERT_TRUE(connection);
209- EXPECT_TRUE(mir_connection_is_valid(connection));
210- EXPECT_STREQ(mir_connection_get_error_message(connection), "");
211-
212- mir_connection_release(connection);
213- }
214- } client_config;
215-
216- launch_client_process(client_config);
217-}
218-
219-TEST_F(DefaultDisplayServerTestFixture, client_library_creates_surface)
220-{
221- struct ClientConfig : ClientConfigCommon
222- {
223- void exec()
224- {
225-
226- mir_wait_for(mir_connect(mir_test_socket, __PRETTY_FUNCTION__, connection_callback, this));
227-
228- ASSERT_TRUE(connection != NULL);
229- EXPECT_TRUE(mir_connection_is_valid(connection));
230- EXPECT_STREQ(mir_connection_get_error_message(connection), "");
231-
232- MirSurfaceParameters const request_params =
233- {
234- __PRETTY_FUNCTION__,
235- 640, 480,
236- mir_pixel_format_abgr_8888,
237- mir_buffer_usage_hardware,
238- mir_display_output_id_invalid
239- };
240-
241- mir_wait_for(mir_connection_create_surface(connection, &request_params, create_surface_callback, this));
242-
243- ASSERT_TRUE(surface != NULL);
244- EXPECT_TRUE(mir_surface_is_valid(surface));
245- EXPECT_STREQ(mir_surface_get_error_message(surface), "");
246-
247- MirSurfaceParameters response_params;
248- mir_surface_get_parameters(surface, &response_params);
249- EXPECT_EQ(request_params.width, response_params.width);
250- EXPECT_EQ(request_params.height, response_params.height);
251- EXPECT_EQ(request_params.pixel_format, response_params.pixel_format);
252- EXPECT_EQ(request_params.buffer_usage, response_params.buffer_usage);
253-
254-
255- mir_wait_for(mir_surface_release( surface, release_surface_callback, this));
256-
257- ASSERT_TRUE(surface == NULL);
258-
259- surface = mir_connection_create_surface_sync(connection, &request_params);
260-
261- ASSERT_TRUE(surface != NULL);
262- EXPECT_TRUE(mir_surface_is_valid(surface));
263- EXPECT_STREQ(mir_surface_get_error_message(surface), "");
264-
265- mir_surface_get_parameters(surface, &response_params);
266- EXPECT_EQ(request_params.width, response_params.width);
267- EXPECT_EQ(request_params.height, response_params.height);
268- EXPECT_EQ(request_params.pixel_format,
269- response_params.pixel_format);
270- EXPECT_EQ(request_params.buffer_usage,
271- response_params.buffer_usage);
272-
273- mir_surface_release_sync(surface);
274-
275- mir_connection_release(connection);
276- }
277- } client_config;
278-
279- launch_client_process(client_config);
280-}
281-
282-TEST_F(DefaultDisplayServerTestFixture, surface_types)
283-{
284- struct ClientConfig : ClientConfigCommon
285- {
286- void exec()
287- {
288-
289- mir_wait_for(mir_connect(mir_test_socket, __PRETTY_FUNCTION__, connection_callback, this));
290-
291- ASSERT_TRUE(connection != NULL);
292- EXPECT_TRUE(mir_connection_is_valid(connection));
293- EXPECT_STREQ(mir_connection_get_error_message(connection), "");
294-
295- MirSurfaceParameters const request_params =
296- {
297- __PRETTY_FUNCTION__,
298- 640, 480,
299- mir_pixel_format_abgr_8888,
300- mir_buffer_usage_hardware,
301- mir_display_output_id_invalid
302- };
303-
304- mir_wait_for(mir_connection_create_surface(connection, &request_params, create_surface_callback, this));
305-
306- ASSERT_TRUE(surface != NULL);
307- EXPECT_TRUE(mir_surface_is_valid(surface));
308- EXPECT_STREQ(mir_surface_get_error_message(surface), "");
309-
310- EXPECT_EQ(mir_surface_type_normal,
311- mir_surface_get_type(surface));
312-
313- mir_wait_for(mir_surface_set_type(surface,
314- mir_surface_type_freestyle));
315- EXPECT_EQ(mir_surface_type_freestyle,
316- mir_surface_get_type(surface));
317-
318- mir_wait_for(mir_surface_set_type(surface,
319- static_cast<MirSurfaceType>(999)));
320- EXPECT_EQ(mir_surface_type_freestyle,
321- mir_surface_get_type(surface));
322-
323- mir_wait_for(mir_surface_set_type(surface,
324- mir_surface_type_dialog));
325- EXPECT_EQ(mir_surface_type_dialog,
326- mir_surface_get_type(surface));
327-
328- mir_wait_for(mir_surface_set_type(surface,
329- static_cast<MirSurfaceType>(888)));
330- EXPECT_EQ(mir_surface_type_dialog,
331- mir_surface_get_type(surface));
332-
333- // Stress-test synchronization logic with some flooding
334- for (int i = 0; i < 100; i++)
335- {
336- mir_surface_set_type(surface, mir_surface_type_normal);
337- mir_surface_set_type(surface, mir_surface_type_utility);
338- mir_surface_set_type(surface, mir_surface_type_dialog);
339- mir_surface_set_type(surface, mir_surface_type_overlay);
340- mir_surface_set_type(surface, mir_surface_type_freestyle);
341- mir_wait_for(mir_surface_set_type(surface,
342- mir_surface_type_popover));
343- ASSERT_EQ(mir_surface_type_popover,
344- mir_surface_get_type(surface));
345- }
346-
347- mir_wait_for(mir_surface_release(surface, release_surface_callback,
348- this));
349-
350- mir_connection_release(connection);
351- }
352- } client_config;
353-
354- launch_client_process(client_config);
355-}
356-
357-TEST_F(DefaultDisplayServerTestFixture, client_can_set_surface_state)
358-{
359- struct ClientConfig : ClientConfigCommon
360- {
361- void exec()
362- {
363- connection = mir_connect_sync(mir_test_socket, __PRETTY_FUNCTION__);
364- ASSERT_TRUE(connection != NULL);
365- EXPECT_TRUE(mir_connection_is_valid(connection));
366- EXPECT_STREQ(mir_connection_get_error_message(connection), "");
367-
368- MirSurfaceParameters const request_params =
369- {
370- __PRETTY_FUNCTION__,
371- 640, 480,
372- mir_pixel_format_abgr_8888,
373- mir_buffer_usage_hardware,
374- mir_display_output_id_invalid
375- };
376-
377- surface = mir_connection_create_surface_sync(connection,
378- &request_params);
379- ASSERT_TRUE(surface != NULL);
380- EXPECT_TRUE(mir_surface_is_valid(surface));
381- EXPECT_STREQ(mir_surface_get_error_message(surface), "");
382-
383- EXPECT_EQ(mir_surface_state_restored,
384- mir_surface_get_state(surface));
385-
386- mir_wait_for(mir_surface_set_state(surface,
387- mir_surface_state_fullscreen));
388- EXPECT_EQ(mir_surface_state_fullscreen,
389- mir_surface_get_state(surface));
390-
391- mir_wait_for(mir_surface_set_state(surface,
392- static_cast<MirSurfaceState>(999)));
393- EXPECT_EQ(mir_surface_state_fullscreen,
394- mir_surface_get_state(surface));
395-
396- mir_wait_for(mir_surface_set_state(surface,
397- mir_surface_state_minimized));
398- EXPECT_EQ(mir_surface_state_minimized,
399- mir_surface_get_state(surface));
400-
401- mir_wait_for(mir_surface_set_state(surface,
402- static_cast<MirSurfaceState>(888)));
403- EXPECT_EQ(mir_surface_state_minimized,
404- mir_surface_get_state(surface));
405-
406- // Stress-test synchronization logic with some flooding
407- for (int i = 0; i < 100; i++)
408- {
409- mir_surface_set_state(surface, mir_surface_state_maximized);
410- mir_surface_set_state(surface, mir_surface_state_restored);
411- mir_wait_for(mir_surface_set_state(surface,
412- mir_surface_state_fullscreen));
413- ASSERT_EQ(mir_surface_state_fullscreen,
414- mir_surface_get_state(surface));
415- }
416-
417- mir_surface_release_sync(surface);
418- mir_connection_release(connection);
419- }
420- } client_config;
421-
422- launch_client_process(client_config);
423-}
424-
425-TEST_F(DefaultDisplayServerTestFixture, client_receives_surface_state_events)
426-{
427- struct ClientConfig : ClientConfigCommon
428- {
429- static void event_callback(MirSurface* surface, MirEvent const* event,
430- void* ctx)
431- {
432- ClientConfig* self = static_cast<ClientConfig*>(ctx);
433- self->last_event = *event;
434- self->last_event_surface = surface;
435- }
436-
437- void exec()
438- {
439- connection = mir_connect_sync(mir_test_socket, __PRETTY_FUNCTION__);
440- ASSERT_TRUE(connection != NULL);
441- ASSERT_TRUE(mir_connection_is_valid(connection));
442-
443- MirSurfaceParameters const request_params =
444- {
445- __PRETTY_FUNCTION__,
446- 640, 480,
447- mir_pixel_format_abgr_8888,
448- mir_buffer_usage_hardware,
449- mir_display_output_id_invalid
450- };
451-
452- memset(&last_event, 0, sizeof last_event);
453- last_event_surface = nullptr;
454-
455- MirEventDelegate delegate{&event_callback, this};
456- MirSurface* other_surface =
457- mir_connection_create_surface_sync(connection, &request_params);
458- ASSERT_TRUE(other_surface != NULL);
459- ASSERT_TRUE(mir_surface_is_valid(other_surface));
460- mir_surface_set_event_handler(other_surface, nullptr);
461-
462- surface =
463- mir_connection_create_surface_sync(connection, &request_params);
464- ASSERT_TRUE(surface != NULL);
465- ASSERT_TRUE(mir_surface_is_valid(surface));
466-
467- mir_surface_set_event_handler(surface, &delegate);
468-
469- int surface_id = mir_debug_surface_id(surface);
470-
471- mir_wait_for(mir_surface_set_state(surface,
472- mir_surface_state_fullscreen));
473- mir_wait_for(mir_surface_set_state(other_surface,
474- mir_surface_state_minimized));
475- EXPECT_EQ(surface, last_event_surface);
476- EXPECT_EQ(mir_event_type_surface, last_event.type);
477- EXPECT_EQ(surface_id, last_event.surface.id);
478- EXPECT_EQ(mir_surface_attrib_state, last_event.surface.attrib);
479- EXPECT_EQ(mir_surface_state_fullscreen, last_event.surface.value);
480-
481- mir_wait_for(mir_surface_set_state(surface,
482- static_cast<MirSurfaceState>(999)));
483- EXPECT_EQ(surface, last_event_surface);
484- EXPECT_EQ(mir_event_type_surface, last_event.type);
485- EXPECT_EQ(surface_id, last_event.surface.id);
486- EXPECT_EQ(mir_surface_attrib_state, last_event.surface.attrib);
487- EXPECT_EQ(mir_surface_state_fullscreen, last_event.surface.value);
488-
489- memset(&last_event, 0, sizeof last_event);
490- last_event_surface = nullptr;
491-
492- mir_wait_for(mir_surface_set_state(surface,
493- mir_surface_state_minimized));
494- EXPECT_EQ(surface, last_event_surface);
495- EXPECT_EQ(mir_event_type_surface, last_event.type);
496- EXPECT_EQ(surface_id, last_event.surface.id);
497- EXPECT_EQ(mir_surface_attrib_state, last_event.surface.attrib);
498- EXPECT_EQ(mir_surface_state_minimized, last_event.surface.value);
499-
500- memset(&last_event, 0, sizeof last_event);
501- last_event_surface = nullptr;
502-
503- mir_wait_for(mir_surface_set_state(surface,
504- static_cast<MirSurfaceState>(777)));
505- mir_wait_for(mir_surface_set_state(other_surface,
506- mir_surface_state_maximized));
507- EXPECT_EQ(0, last_event_surface);
508- EXPECT_EQ(0, last_event.type);
509- EXPECT_EQ(0, last_event.surface.id);
510- EXPECT_EQ(0, last_event.surface.attrib);
511- EXPECT_EQ(0, last_event.surface.value);
512-
513- mir_surface_release_sync(surface);
514- mir_surface_release_sync(other_surface);
515- mir_connection_release(connection);
516- }
517-
518- MirEvent last_event;
519- MirSurface* last_event_surface;
520- } client_config;
521-
522- launch_client_process(client_config);
523-}
524-
525-TEST_F(DefaultDisplayServerTestFixture, client_receives_surface_dpi_value)
526-{
527- struct ClientConfig : ClientConfigCommon
528- {
529- void exec()
530- {
531- connection = mir_connect_sync(mir_test_socket, __PRETTY_FUNCTION__);
532- ASSERT_TRUE(connection != NULL);
533- ASSERT_TRUE(mir_connection_is_valid(connection));
534-
535- MirSurfaceParameters const request_params =
536- {
537- __PRETTY_FUNCTION__,
538- 640, 480,
539- mir_pixel_format_abgr_8888,
540- mir_buffer_usage_hardware,
541- mir_display_output_id_invalid
542- };
543-
544- surface =
545- mir_connection_create_surface_sync(connection, &request_params);
546- ASSERT_TRUE(surface != NULL);
547- ASSERT_TRUE(mir_surface_is_valid(surface));
548-
549- // Expect zero (not wired up to detect the physical display yet)
550- EXPECT_EQ(0, mir_surface_get_dpi(surface));
551-
552- mir_surface_release_sync(surface);
553- mir_connection_release(connection);
554- }
555- } client_config;
556-
557- launch_client_process(client_config);
558+using namespace testing;
559+
560+TEST_F(ClientLibrary, client_library_connects_and_disconnects)
561+{
562+ MirWaitHandle* wh = mir_connect(new_connection().c_str(), __PRETTY_FUNCTION__, connection_callback, this);
563+ EXPECT_THAT(wh, NotNull());
564+ mir_wait_for(wh);
565+
566+ ASSERT_THAT(connection, NotNull());
567+ EXPECT_TRUE(mir_connection_is_valid(connection));
568+ EXPECT_THAT(mir_connection_get_error_message(connection), StrEq(""));
569+
570+ mir_connection_release(connection);
571+}
572+
573+TEST_F(ClientLibrary, synchronous_connection)
574+{
575+ connection = mir_connect_sync(new_connection().c_str(), __PRETTY_FUNCTION__);
576+
577+ EXPECT_THAT(connection, NotNull());
578+ EXPECT_TRUE(mir_connection_is_valid(connection));
579+ EXPECT_THAT(mir_connection_get_error_message(connection), StrEq(""));
580+
581+ mir_connection_release(connection);
582+}
583+
584+TEST_F(ClientLibrary, creates_surface)
585+{
586+ mir_wait_for(mir_connect(new_connection().c_str(), __PRETTY_FUNCTION__, connection_callback, this));
587+
588+ MirSurfaceParameters const request_params =
589+ {
590+ __PRETTY_FUNCTION__,
591+ 640, 480,
592+ mir_pixel_format_abgr_8888,
593+ mir_buffer_usage_hardware,
594+ mir_display_output_id_invalid
595+ };
596+
597+ mir_wait_for(mir_connection_create_surface(connection, &request_params, create_surface_callback, this));
598+
599+ ASSERT_THAT(surface, NotNull());
600+ EXPECT_TRUE(mir_surface_is_valid(surface));
601+ EXPECT_THAT(mir_surface_get_error_message(surface), StrEq(""));
602+
603+ MirSurfaceParameters response_params;
604+ mir_surface_get_parameters(surface, &response_params);
605+ EXPECT_EQ(request_params.width, response_params.width);
606+ EXPECT_EQ(request_params.height, response_params.height);
607+ EXPECT_EQ(request_params.pixel_format, response_params.pixel_format);
608+ EXPECT_EQ(request_params.buffer_usage, response_params.buffer_usage);
609+
610+ mir_wait_for(mir_surface_release( surface, release_surface_callback, this));
611+
612+ ASSERT_THAT(surface, IsNull());
613+
614+ surface = mir_connection_create_surface_sync(connection, &request_params);
615+
616+ ASSERT_THAT(surface, NotNull());
617+ EXPECT_TRUE(mir_surface_is_valid(surface));
618+ EXPECT_THAT(mir_surface_get_error_message(surface), StrEq(""));
619+
620+ mir_surface_get_parameters(surface, &response_params);
621+ EXPECT_THAT(response_params.width, Eq(request_params.width));
622+ EXPECT_THAT(response_params.height, Eq(request_params.height));
623+ EXPECT_THAT(response_params.pixel_format, Eq(request_params.pixel_format));
624+ EXPECT_THAT(response_params.buffer_usage, Eq(request_params.buffer_usage));
625+
626+ mir_surface_release_sync(surface);
627+ mir_connection_release(connection);
628+}
629+
630+TEST_F(ClientLibrary, can_set_surface_types)
631+{
632+ mir_wait_for(mir_connect(new_connection().c_str(), __PRETTY_FUNCTION__, connection_callback, this));
633+
634+ MirSurfaceParameters const request_params =
635+ {
636+ __PRETTY_FUNCTION__,
637+ 640, 480,
638+ mir_pixel_format_abgr_8888,
639+ mir_buffer_usage_hardware,
640+ mir_display_output_id_invalid
641+ };
642+
643+ mir_wait_for(mir_connection_create_surface(connection, &request_params, create_surface_callback, this));
644+
645+ EXPECT_THAT(mir_surface_get_type(surface), Eq(mir_surface_type_normal));
646+
647+ mir_wait_for(mir_surface_set_type(surface, mir_surface_type_freestyle));
648+ EXPECT_THAT(mir_surface_get_type(surface), Eq(mir_surface_type_freestyle));
649+
650+ mir_wait_for(mir_surface_set_type(surface, static_cast<MirSurfaceType>(999)));
651+ EXPECT_THAT(mir_surface_get_type(surface), Eq(mir_surface_type_freestyle));
652+
653+ mir_wait_for(mir_surface_set_type(surface, mir_surface_type_dialog));
654+ EXPECT_THAT(mir_surface_get_type(surface), Eq(mir_surface_type_dialog));
655+
656+ mir_wait_for(mir_surface_set_type(surface, static_cast<MirSurfaceType>(888)));
657+ EXPECT_THAT(mir_surface_get_type(surface), Eq(mir_surface_type_dialog));
658+
659+ // Stress-test synchronization logic with some flooding
660+ for (int i = 0; i < 100; i++)
661+ {
662+ mir_surface_set_type(surface, mir_surface_type_normal);
663+ mir_surface_set_type(surface, mir_surface_type_utility);
664+ mir_surface_set_type(surface, mir_surface_type_dialog);
665+ mir_surface_set_type(surface, mir_surface_type_overlay);
666+ mir_surface_set_type(surface, mir_surface_type_freestyle);
667+ mir_wait_for(mir_surface_set_type(surface, mir_surface_type_popover));
668+ ASSERT_THAT(mir_surface_get_type(surface), Eq(mir_surface_type_popover));
669+ }
670+
671+ mir_wait_for(mir_surface_release(surface, release_surface_callback, this));
672+ mir_connection_release(connection);
673+}
674+
675+TEST_F(ClientLibrary, can_set_surface_state)
676+{
677+ connection = mir_connect_sync(new_connection().c_str(), __PRETTY_FUNCTION__);
678+
679+ MirSurfaceParameters const request_params =
680+ {
681+ __PRETTY_FUNCTION__,
682+ 640, 480,
683+ mir_pixel_format_abgr_8888,
684+ mir_buffer_usage_hardware,
685+ mir_display_output_id_invalid
686+ };
687+
688+ surface = mir_connection_create_surface_sync(connection, &request_params);
689+
690+ EXPECT_THAT(mir_surface_get_state(surface), Eq(mir_surface_state_restored));
691+
692+ mir_wait_for(mir_surface_set_state(surface, mir_surface_state_fullscreen));
693+ EXPECT_THAT(mir_surface_get_state(surface), Eq(mir_surface_state_fullscreen));
694+
695+ mir_wait_for(mir_surface_set_state(surface, static_cast<MirSurfaceState>(999)));
696+ EXPECT_THAT(mir_surface_get_state(surface), Eq(mir_surface_state_fullscreen));
697+
698+ mir_wait_for(mir_surface_set_state(surface, mir_surface_state_minimized));
699+ EXPECT_THAT(mir_surface_get_state(surface), Eq(mir_surface_state_minimized));
700+
701+ mir_wait_for(mir_surface_set_state(surface, static_cast<MirSurfaceState>(888)));
702+ EXPECT_THAT(mir_surface_get_state(surface), Eq(mir_surface_state_minimized));
703+
704+ // Stress-test synchronization logic with some flooding
705+ for (int i = 0; i < 100; i++)
706+ {
707+ mir_surface_set_state(surface, mir_surface_state_maximized);
708+ mir_surface_set_state(surface, mir_surface_state_restored);
709+ mir_wait_for(mir_surface_set_state(surface, mir_surface_state_fullscreen));
710+ ASSERT_THAT(mir_surface_get_state(surface), Eq(mir_surface_state_fullscreen));
711+ }
712+
713+ mir_surface_release_sync(surface);
714+ mir_connection_release(connection);
715+}
716+
717+TEST_F(ClientLibrary, receives_surface_state_events)
718+{
719+ connection = mir_connect_sync(new_connection().c_str(), __PRETTY_FUNCTION__);
720+
721+ MirSurfaceParameters const request_params =
722+ {
723+ __PRETTY_FUNCTION__,
724+ 640, 480,
725+ mir_pixel_format_abgr_8888,
726+ mir_buffer_usage_hardware,
727+ mir_display_output_id_invalid
728+ };
729+
730+ MirEventDelegate delegate{&event_callback, this};
731+ MirSurface* other_surface = mir_connection_create_surface_sync(connection, &request_params);
732+ ASSERT_TRUE(mir_surface_is_valid(other_surface));
733+
734+ mir_surface_set_event_handler(other_surface, nullptr);
735+
736+ surface = mir_connection_create_surface_sync(connection, &request_params);
737+ ASSERT_TRUE(mir_surface_is_valid(surface));
738+
739+ mir_surface_set_event_handler(surface, &delegate);
740+
741+ int surface_id = mir_debug_surface_id(surface);
742+
743+ mir_wait_for(mir_surface_set_state(surface, mir_surface_state_fullscreen));
744+ mir_wait_for(mir_surface_set_state(other_surface, mir_surface_state_minimized));
745+ EXPECT_THAT(last_event_surface, Eq(surface));
746+ EXPECT_THAT(last_event.type, Eq(mir_event_type_surface));
747+ EXPECT_THAT(last_event.surface.id, Eq(surface_id));
748+ EXPECT_THAT(last_event.surface.attrib, Eq(mir_surface_attrib_state));
749+ EXPECT_THAT(last_event.surface.value, Eq(mir_surface_state_fullscreen));
750+
751+ mir_wait_for(mir_surface_set_state(surface, static_cast<MirSurfaceState>(999)));
752+ EXPECT_THAT(last_event_surface, Eq(surface));
753+ EXPECT_THAT(last_event.type, Eq(mir_event_type_surface));
754+ EXPECT_THAT(last_event.surface.id, Eq(surface_id));
755+ EXPECT_THAT(last_event.surface.attrib, Eq(mir_surface_attrib_state));
756+ EXPECT_THAT(last_event.surface.value, Eq(mir_surface_state_fullscreen));
757+
758+ memset(&last_event, 0, sizeof last_event);
759+ last_event_surface = nullptr;
760+
761+ mir_wait_for(mir_surface_set_state(surface, mir_surface_state_minimized));
762+ EXPECT_THAT(last_event_surface, Eq(surface));
763+ EXPECT_THAT(last_event.type, Eq(mir_event_type_surface));
764+ EXPECT_THAT(last_event.surface.id, Eq(surface_id));
765+ EXPECT_THAT(last_event.surface.attrib, Eq(mir_surface_attrib_state));
766+ EXPECT_THAT(last_event.surface.value, Eq(mir_surface_state_minimized));
767+
768+ memset(&last_event, 0, sizeof last_event);
769+ last_event_surface = nullptr;
770+
771+ mir_wait_for(mir_surface_set_state(surface, static_cast<MirSurfaceState>(777)));
772+ mir_wait_for(mir_surface_set_state(other_surface, mir_surface_state_maximized));
773+ EXPECT_THAT(last_event_surface, IsNull());
774+ EXPECT_THAT(last_event.type, Eq(0));
775+ EXPECT_THAT(last_event.surface.id, Eq(0));
776+ EXPECT_THAT(last_event.surface.attrib, Eq(0));
777+ EXPECT_THAT(last_event.surface.value, Eq(0));
778+
779+ mir_surface_release_sync(surface);
780+ mir_surface_release_sync(other_surface);
781+ mir_connection_release(connection);
782+}
783+
784+TEST_F(ClientLibrary, receives_surface_dpi_value)
785+{
786+ connection = mir_connect_sync(new_connection().c_str(), __PRETTY_FUNCTION__);
787+
788+ MirSurfaceParameters const request_params =
789+ {
790+ __PRETTY_FUNCTION__,
791+ 640, 480,
792+ mir_pixel_format_abgr_8888,
793+ mir_buffer_usage_hardware,
794+ mir_display_output_id_invalid
795+ };
796+
797+ surface = mir_connection_create_surface_sync(connection, &request_params);
798+
799+ // Expect zero (not wired up to detect the physical display yet)
800+ EXPECT_THAT(mir_surface_get_dpi(surface), Eq(0));
801+
802+ mir_surface_release_sync(surface);
803+ mir_connection_release(connection);
804 }
805
806 #ifndef ANDROID
807-TEST_F(DefaultDisplayServerTestFixture, surface_scanout_flag_toggles)
808+TEST_F(ClientLibrary, surface_scanout_flag_toggles)
809 {
810- struct ClientConfig : ClientConfigCommon
811+ connection = mir_connect_sync(new_connection().c_str(), __PRETTY_FUNCTION__);
812+
813+ MirSurfaceParameters parm =
814 {
815- void exec()
816- {
817- connection = mir_connect_sync(mir_test_socket, __PRETTY_FUNCTION__);
818- ASSERT_TRUE(connection != NULL);
819- EXPECT_TRUE(mir_connection_is_valid(connection));
820- EXPECT_STREQ(mir_connection_get_error_message(connection), "");
821-
822- MirSurfaceParameters parm =
823- {
824- __PRETTY_FUNCTION__,
825- 1280, 1024,
826- mir_pixel_format_abgr_8888,
827- mir_buffer_usage_hardware,
828- mir_display_output_id_invalid
829- };
830-
831- surface = mir_connection_create_surface_sync(connection, &parm);
832- ASSERT_TRUE(mir_surface_is_valid(surface));
833- MirNativeBuffer *native;
834- mir_surface_get_current_buffer(surface, &native);
835- EXPECT_TRUE(native->flags & mir_buffer_flag_can_scanout);
836- mir_surface_swap_buffers_sync(surface);
837- EXPECT_TRUE(native->flags & mir_buffer_flag_can_scanout);
838- mir_surface_release_sync(surface);
839-
840- parm.width = 100;
841- parm.height = 100;
842-
843- surface = mir_connection_create_surface_sync(connection, &parm);
844- ASSERT_TRUE(mir_surface_is_valid(surface));
845- mir_surface_get_current_buffer(surface, &native);
846- EXPECT_FALSE(native->flags & mir_buffer_flag_can_scanout);
847- mir_surface_swap_buffers_sync(surface);
848- EXPECT_FALSE(native->flags & mir_buffer_flag_can_scanout);
849- mir_surface_release_sync(surface);
850-
851- parm.width = 800;
852- parm.height = 600;
853- parm.buffer_usage = mir_buffer_usage_software;
854-
855- surface = mir_connection_create_surface_sync(connection, &parm);
856- ASSERT_TRUE(mir_surface_is_valid(surface));
857- mir_surface_get_current_buffer(surface, &native);
858- EXPECT_FALSE(native->flags & mir_buffer_flag_can_scanout);
859- mir_surface_swap_buffers_sync(surface);
860- EXPECT_FALSE(native->flags & mir_buffer_flag_can_scanout);
861- mir_surface_release_sync(surface);
862-
863- parm.buffer_usage = mir_buffer_usage_hardware;
864-
865- surface = mir_connection_create_surface_sync(connection, &parm);
866- ASSERT_TRUE(mir_surface_is_valid(surface));
867- mir_surface_get_current_buffer(surface, &native);
868- EXPECT_TRUE(native->flags & mir_buffer_flag_can_scanout);
869- mir_surface_swap_buffers_sync(surface);
870- EXPECT_TRUE(native->flags & mir_buffer_flag_can_scanout);
871- mir_surface_release_sync(surface);
872-
873- mir_connection_release(connection);
874- }
875-
876- // this test relies on gbm drivers, use real graphics always
877- bool use_real_graphics(mir::options::Option const&) override
878- {
879- return true;
880- }
881- } client_config;
882-
883- launch_client_process(client_config);
884+ __PRETTY_FUNCTION__,
885+ 1280, 1024,
886+ mir_pixel_format_abgr_8888,
887+ mir_buffer_usage_hardware,
888+ mir_display_output_id_invalid
889+ };
890+
891+ surface = mir_connection_create_surface_sync(connection, &parm);
892+
893+ MirNativeBuffer *native;
894+ mir_surface_get_current_buffer(surface, &native);
895+ EXPECT_TRUE(native->flags & mir_buffer_flag_can_scanout);
896+ mir_surface_swap_buffers_sync(surface);
897+ EXPECT_TRUE(native->flags & mir_buffer_flag_can_scanout);
898+ mir_surface_release_sync(surface);
899+
900+ parm.width = 100;
901+ parm.height = 100;
902+
903+ surface = mir_connection_create_surface_sync(connection, &parm);
904+ mir_surface_get_current_buffer(surface, &native);
905+ EXPECT_FALSE(native->flags & mir_buffer_flag_can_scanout);
906+ mir_surface_swap_buffers_sync(surface);
907+ EXPECT_FALSE(native->flags & mir_buffer_flag_can_scanout);
908+ mir_surface_release_sync(surface);
909+
910+ parm.width = 800;
911+ parm.height = 600;
912+ parm.buffer_usage = mir_buffer_usage_software;
913+
914+ surface = mir_connection_create_surface_sync(connection, &parm);
915+ mir_surface_get_current_buffer(surface, &native);
916+ EXPECT_FALSE(native->flags & mir_buffer_flag_can_scanout);
917+ mir_surface_swap_buffers_sync(surface);
918+ EXPECT_FALSE(native->flags & mir_buffer_flag_can_scanout);
919+ mir_surface_release_sync(surface);
920+
921+ parm.buffer_usage = mir_buffer_usage_hardware;
922+
923+ surface = mir_connection_create_surface_sync(connection, &parm);
924+ mir_surface_get_current_buffer(surface, &native);
925+ EXPECT_TRUE(native->flags & mir_buffer_flag_can_scanout);
926+ mir_surface_swap_buffers_sync(surface);
927+ EXPECT_TRUE(native->flags & mir_buffer_flag_can_scanout);
928+ mir_surface_release_sync(surface);
929+
930+ mir_connection_release(connection);
931 }
932 #endif
933
934 #ifdef ANDROID
935 // Mir's Android test infrastructure isn't quite ready for this yet.
936-TEST_F(DefaultDisplayServerTestFixture, DISABLED_client_gets_buffer_dimensions)
937+TEST_F(ClientLibrary, DISABLED_gets_buffer_dimensions)
938 #else
939-TEST_F(DefaultDisplayServerTestFixture, client_gets_buffer_dimensions)
940+TEST_F(ClientLibrary, gets_buffer_dimensions)
941 #endif
942 {
943- struct ClientConfig : ClientConfigCommon
944- {
945- void exec()
946- {
947- connection = mir_connect_sync(mir_test_socket, __PRETTY_FUNCTION__);
948- ASSERT_TRUE(connection != NULL);
949- ASSERT_TRUE(mir_connection_is_valid(connection));
950-
951- MirSurfaceParameters parm =
952- {
953- __PRETTY_FUNCTION__,
954- 0, 0,
955- mir_pixel_format_abgr_8888,
956- mir_buffer_usage_hardware,
957- mir_display_output_id_invalid
958- };
959-
960- struct {int width, height;} const sizes[] =
961- {
962- {12, 34},
963- {56, 78},
964- {90, 21},
965- };
966-
967- for (auto const& size : sizes)
968- {
969- parm.width = size.width;
970- parm.height = size.height;
971-
972- surface = mir_connection_create_surface_sync(connection, &parm);
973- ASSERT_TRUE(surface != NULL);
974- ASSERT_TRUE(mir_surface_is_valid(surface));
975-
976- MirNativeBuffer *native = NULL;
977- mir_surface_get_current_buffer(surface, &native);
978- ASSERT_TRUE(native != NULL);
979- EXPECT_EQ(parm.width, native->width);
980- EXPECT_EQ(parm.height, native->height);
981-
982- mir_surface_swap_buffers_sync(surface);
983- mir_surface_get_current_buffer(surface, &native);
984- ASSERT_TRUE(native != NULL);
985- EXPECT_EQ(parm.width, native->width);
986- EXPECT_EQ(parm.height, native->height);
987-
988- mir_surface_release_sync(surface);
989- }
990-
991- mir_connection_release(connection);
992- }
993-
994- bool use_real_graphics(mir::options::Option const&) override
995- {
996- return true;
997- }
998- } client_config;
999-
1000- launch_client_process(client_config);
1001+ connection = mir_connect_sync(new_connection().c_str(), __PRETTY_FUNCTION__);
1002+
1003+ MirSurfaceParameters parm =
1004+ {
1005+ __PRETTY_FUNCTION__,
1006+ 0, 0,
1007+ mir_pixel_format_abgr_8888,
1008+ mir_buffer_usage_hardware,
1009+ mir_display_output_id_invalid
1010+ };
1011+
1012+ struct {int width, height;} const sizes[] =
1013+ {
1014+ {12, 34},
1015+ {56, 78},
1016+ {90, 21},
1017+ };
1018+
1019+ for (auto const& size : sizes)
1020+ {
1021+ parm.width = size.width;
1022+ parm.height = size.height;
1023+
1024+ surface = mir_connection_create_surface_sync(connection, &parm);
1025+
1026+ MirNativeBuffer *native = NULL;
1027+ mir_surface_get_current_buffer(surface, &native);
1028+ ASSERT_THAT(native, NotNull());
1029+ EXPECT_THAT(native->width, Eq(parm.width));
1030+ ASSERT_THAT(native->height, Eq(parm.height));
1031+
1032+ mir_surface_swap_buffers_sync(surface);
1033+ mir_surface_get_current_buffer(surface, &native);
1034+ ASSERT_THAT(native, NotNull());
1035+ EXPECT_THAT(native->width, Eq(parm.width));
1036+ ASSERT_THAT(native->height, Eq(parm.height));
1037+
1038+ mir_surface_release_sync(surface);
1039+ }
1040+
1041+ mir_connection_release(connection);
1042 }
1043
1044-TEST_F(DefaultDisplayServerTestFixture, client_library_creates_multiple_surfaces)
1045+TEST_F(ClientLibrary, creates_multiple_surfaces)
1046 {
1047 int const n_surfaces = 13;
1048-
1049- struct ClientConfig : ClientConfigCommon
1050- {
1051- ClientConfig(int n_surfaces) : n_surfaces(n_surfaces)
1052- {
1053- }
1054-
1055- void surface_created(MirSurface * new_surface)
1056- {
1057- surfaces.insert(new_surface);
1058- }
1059-
1060- void surface_released(MirSurface * surface)
1061- {
1062- surfaces.erase(surface);
1063- }
1064-
1065- MirSurface * any_surface()
1066- {
1067- return *surfaces.begin();
1068- }
1069-
1070- size_t current_surface_count()
1071- {
1072- return surfaces.size();
1073- }
1074-
1075- void exec()
1076- {
1077- mir_wait_for(mir_connect(mir_test_socket, __PRETTY_FUNCTION__, connection_callback, this));
1078-
1079- ASSERT_TRUE(connection != NULL);
1080- EXPECT_TRUE(mir_connection_is_valid(connection));
1081- EXPECT_STREQ(mir_connection_get_error_message(connection), "");
1082-
1083- for (int i = 0; i != n_surfaces; ++i)
1084- {
1085- old_surface_count = current_surface_count();
1086-
1087- MirSurfaceParameters const request_params =
1088- {
1089- __PRETTY_FUNCTION__,
1090- 640, 480,
1091- mir_pixel_format_abgr_8888,
1092- mir_buffer_usage_hardware,
1093- mir_display_output_id_invalid
1094- };
1095-
1096- mir_wait_for(mir_connection_create_surface(connection, &request_params, create_surface_callback, this));
1097-
1098- ASSERT_EQ(old_surface_count + 1, current_surface_count());
1099- }
1100- for (int i = 0; i != n_surfaces; ++i)
1101- {
1102- old_surface_count = current_surface_count();
1103-
1104- ASSERT_NE(old_surface_count, 0u);
1105-
1106- MirSurface * surface = any_surface();
1107- mir_wait_for(mir_surface_release( surface, release_surface_callback, this));
1108-
1109- ASSERT_EQ(old_surface_count - 1, current_surface_count());
1110- }
1111-
1112- mir_connection_release(connection);
1113- }
1114-
1115- int n_surfaces;
1116- std::set<MirSurface *> surfaces;
1117- size_t old_surface_count;
1118- } client_config(n_surfaces);
1119-
1120- launch_client_process(client_config);
1121-}
1122-
1123-TEST_F(DefaultDisplayServerTestFixture, client_library_accesses_and_advances_buffers)
1124-{
1125- struct ClientConfig : ClientConfigCommon
1126- {
1127- void exec()
1128- {
1129-
1130- mir_wait_for(mir_connect(mir_test_socket, __PRETTY_FUNCTION__, connection_callback, this));
1131-
1132- ASSERT_TRUE(connection != NULL);
1133- EXPECT_TRUE(mir_connection_is_valid(connection));
1134- EXPECT_STREQ("", mir_connection_get_error_message(connection));
1135-
1136- MirSurfaceParameters const request_params =
1137- {
1138- __PRETTY_FUNCTION__,
1139- 640, 480,
1140- mir_pixel_format_abgr_8888,
1141- mir_buffer_usage_hardware,
1142- mir_display_output_id_invalid
1143- };
1144-
1145- mir_wait_for(mir_connection_create_surface(connection, &request_params, create_surface_callback, this));
1146- ASSERT_TRUE(surface != NULL);
1147-
1148- buffers = 0;
1149- mir_wait_for(mir_surface_swap_buffers(surface, next_buffer_callback, this));
1150- EXPECT_EQ(buffers, 1);
1151-
1152- mir_wait_for(mir_surface_release( surface, release_surface_callback, this));
1153-
1154- ASSERT_TRUE(surface == NULL);
1155-
1156- mir_connection_release(connection);
1157- }
1158- } client_config;
1159-
1160- launch_client_process(client_config);
1161-}
1162-
1163-TEST_F(DefaultDisplayServerTestFixture, fully_synchronous_client)
1164-{
1165- struct ClientConfig : ClientConfigCommon
1166- {
1167- void exec()
1168- {
1169- connection = mir_connect_sync(mir_test_socket,
1170- __PRETTY_FUNCTION__);
1171-
1172- ASSERT_TRUE(connection != NULL);
1173- EXPECT_TRUE(mir_connection_is_valid(connection));
1174- EXPECT_STREQ("", mir_connection_get_error_message(connection));
1175-
1176- MirSurfaceParameters const request_params =
1177- {
1178- __PRETTY_FUNCTION__,
1179- 640, 480,
1180- mir_pixel_format_abgr_8888,
1181- mir_buffer_usage_software,
1182- mir_display_output_id_invalid
1183- };
1184-
1185- surface = mir_connection_create_surface_sync(connection, &request_params);
1186- ASSERT_TRUE(surface != NULL);
1187- EXPECT_TRUE(mir_surface_is_valid(surface));
1188- EXPECT_STREQ(mir_surface_get_error_message(surface), "");
1189-
1190- mir_surface_swap_buffers_sync(surface);
1191- EXPECT_TRUE(mir_surface_is_valid(surface));
1192- EXPECT_STREQ(mir_surface_get_error_message(surface), "");
1193-
1194- mir_surface_release_sync(surface);
1195-
1196- EXPECT_TRUE(mir_connection_is_valid(connection));
1197- EXPECT_STREQ("", mir_connection_get_error_message(connection));
1198- mir_connection_release(connection);
1199- }
1200- } client_config;
1201-
1202- launch_client_process(client_config);
1203-}
1204-
1205-TEST_F(DefaultDisplayServerTestFixture, highly_threaded_client)
1206-{
1207- struct ClientConfig : ClientConfigCommon
1208- {
1209- static void nosey_thread(MirSurface *surf)
1210- {
1211- for (int i = 0; i < 10; i++)
1212- {
1213- mir_wait_for_one(mir_surface_set_state(surf,
1214- mir_surface_state_maximized));
1215- mir_wait_for_one(mir_surface_set_type(surf,
1216- mir_surface_type_normal));
1217- mir_wait_for_one(mir_surface_set_state(surf,
1218- mir_surface_state_restored));
1219- mir_wait_for_one(mir_surface_set_type(surf,
1220- mir_surface_type_utility));
1221- mir_wait_for_one(mir_surface_set_state(surf,
1222- mir_surface_state_fullscreen));
1223- mir_wait_for_one(mir_surface_set_type(surf,
1224- mir_surface_type_dialog));
1225- mir_wait_for_one(mir_surface_set_state(surf,
1226- mir_surface_state_minimized));
1227- }
1228- }
1229-
1230- void exec()
1231- {
1232- connection = mir_connect_sync(mir_test_socket,
1233- __PRETTY_FUNCTION__);
1234-
1235- ASSERT_TRUE(connection != NULL);
1236- EXPECT_TRUE(mir_connection_is_valid(connection));
1237- EXPECT_STREQ("", mir_connection_get_error_message(connection));
1238-
1239- MirSurfaceParameters const request_params =
1240- {
1241- __PRETTY_FUNCTION__,
1242- 640, 480,
1243- mir_pixel_format_abgr_8888,
1244- mir_buffer_usage_software,
1245- mir_display_output_id_invalid
1246- };
1247-
1248- surface = mir_connection_create_surface_sync(connection,
1249- &request_params);
1250- ASSERT_TRUE(surface != NULL);
1251- EXPECT_TRUE(mir_surface_is_valid(surface));
1252- EXPECT_STREQ(mir_surface_get_error_message(surface), "");
1253-
1254- std::thread a(nosey_thread, surface);
1255- std::thread b(nosey_thread, surface);
1256- std::thread c(nosey_thread, surface);
1257-
1258- a.join();
1259- b.join();
1260- c.join();
1261-
1262- EXPECT_EQ(mir_surface_type_dialog,
1263- mir_surface_get_type(surface));
1264- EXPECT_EQ(mir_surface_state_minimized,
1265- mir_surface_get_state(surface));
1266-
1267- mir_surface_release_sync(surface);
1268-
1269- EXPECT_TRUE(mir_connection_is_valid(connection));
1270- EXPECT_STREQ("", mir_connection_get_error_message(connection));
1271- mir_connection_release(connection);
1272- }
1273- } client_config;
1274-
1275- launch_client_process(client_config);
1276-}
1277-
1278-TEST_F(DefaultDisplayServerTestFixture, client_library_accesses_platform_package)
1279-{
1280- struct ClientConfig : ClientConfigCommon
1281- {
1282- void exec()
1283- {
1284- mir_wait_for(mir_connect(mir_test_socket, __PRETTY_FUNCTION__, connection_callback, this));
1285- ASSERT_TRUE(connection != NULL);
1286-
1287- MirPlatformPackage platform_package;
1288- platform_package.data_items = -1;
1289- platform_package.fd_items = -1;
1290-
1291- mir_connection_get_platform(connection, &platform_package);
1292- EXPECT_GE(0, platform_package.data_items);
1293- EXPECT_GE(0, platform_package.fd_items);
1294-
1295- mir_connection_release(connection);
1296- }
1297- } client_config;
1298-
1299- launch_client_process(client_config);
1300-}
1301-
1302-TEST_F(DefaultDisplayServerTestFixture, client_library_accesses_display_info)
1303-{
1304- struct ClientConfig : ClientConfigCommon
1305- {
1306- void exec()
1307- {
1308- mir_wait_for(mir_connect(mir_test_socket, __PRETTY_FUNCTION__, connection_callback, this));
1309- ASSERT_TRUE(connection != NULL);
1310-
1311- auto configuration = mir_connection_create_display_config(connection);
1312- ASSERT_NE(nullptr, configuration);
1313- ASSERT_GT(configuration->num_outputs, 0u);
1314- ASSERT_NE(nullptr, configuration->outputs);
1315- for (auto i=0u; i < configuration->num_outputs; i++)
1316- {
1317- MirDisplayOutput* disp = &configuration->outputs[i];
1318- ASSERT_NE(nullptr, disp);
1319- EXPECT_GE(disp->num_modes, disp->current_mode);
1320- EXPECT_GE(disp->num_output_formats, disp->current_format);
1321- }
1322-
1323- mir_display_config_destroy(configuration);
1324- mir_connection_release(connection);
1325- }
1326- } client_config;
1327-
1328- launch_client_process(client_config);
1329-}
1330-
1331-TEST_F(DefaultDisplayServerTestFixture, connect_errors_handled)
1332-{
1333- struct ClientConfig : ClientConfigCommon
1334- {
1335- void exec()
1336- {
1337- mir_wait_for(mir_connect("garbage", __PRETTY_FUNCTION__, connection_callback, this));
1338- ASSERT_TRUE(connection != NULL);
1339-
1340- char const* error = mir_connection_get_error_message(connection);
1341-
1342- if (std::strcmp("connect: No such file or directory", error) &&
1343- std::strcmp("Can't find MIR server", error) &&
1344- std::strcmp("Failed to connect to server socket", error))
1345- {
1346- FAIL() << error;
1347- }
1348- }
1349-
1350- //we are testing the connect function itself, without getting to the
1351- // point where drivers are used, so force using production config
1352- bool use_real_graphics(mir::options::Option const&) override
1353- {
1354- return true;
1355- }
1356- } client_config;
1357-
1358- launch_client_process(client_config);
1359-}
1360-
1361-TEST_F(DefaultDisplayServerTestFixture, connect_errors_dont_blow_up)
1362-{
1363- struct ClientConfig : ClientConfigCommon
1364- {
1365- void exec()
1366- {
1367- mir_wait_for(mir_connect("garbage", __PRETTY_FUNCTION__, connection_callback, this));
1368-
1369- MirSurfaceParameters const request_params =
1370- {
1371- __PRETTY_FUNCTION__,
1372- 640, 480,
1373- mir_pixel_format_abgr_8888,
1374- mir_buffer_usage_hardware,
1375- mir_display_output_id_invalid
1376- };
1377-
1378- mir_wait_for(mir_connection_create_surface(connection, &request_params, create_surface_callback, this));
1379+ size_t old_surface_count = 0;
1380+
1381+ mir_wait_for(mir_connect(new_connection().c_str(), __PRETTY_FUNCTION__, connection_callback, this));
1382+
1383+ for (int i = 0; i != n_surfaces; ++i)
1384+ {
1385+ old_surface_count = current_surface_count();
1386+
1387+ MirSurfaceParameters const request_params =
1388+ {
1389+ __PRETTY_FUNCTION__,
1390+ 640, 480,
1391+ mir_pixel_format_abgr_8888,
1392+ mir_buffer_usage_hardware,
1393+ mir_display_output_id_invalid
1394+ };
1395+
1396+ mir_wait_for(mir_connection_create_surface(connection, &request_params, create_surface_callback, this));
1397+
1398+ ASSERT_THAT(current_surface_count(), Eq(old_surface_count + 1));
1399+ }
1400+ for (int i = 0; i != n_surfaces; ++i)
1401+ {
1402+ old_surface_count = current_surface_count();
1403+
1404+ ASSERT_THAT(old_surface_count, Ne(0u));
1405+
1406+ MirSurface * surface = any_surface();
1407+ mir_wait_for(mir_surface_release( surface, release_surface_callback, this));
1408+
1409+ ASSERT_THAT(current_surface_count(), Eq(old_surface_count - 1));
1410+ }
1411+
1412+ mir_connection_release(connection);
1413+}
1414+
1415+TEST_F(ClientLibrary, client_library_accesses_and_advances_buffers)
1416+{
1417+ mir_wait_for(mir_connect(new_connection().c_str(), __PRETTY_FUNCTION__, connection_callback, this));
1418+
1419+ MirSurfaceParameters const request_params =
1420+ {
1421+ __PRETTY_FUNCTION__,
1422+ 640, 480,
1423+ mir_pixel_format_abgr_8888,
1424+ mir_buffer_usage_hardware,
1425+ mir_display_output_id_invalid
1426+ };
1427+
1428+ mir_wait_for(mir_connection_create_surface(connection, &request_params, create_surface_callback, this));
1429+
1430+ buffers = 0;
1431+ mir_wait_for(mir_surface_swap_buffers(surface, next_buffer_callback, this));
1432+ EXPECT_THAT(buffers, Eq(1));
1433+
1434+ mir_wait_for(mir_surface_release(surface, release_surface_callback, this));
1435+
1436+ ASSERT_THAT(surface, IsNull());
1437+
1438+ mir_connection_release(connection);
1439+}
1440+
1441+TEST_F(ClientLibrary, fully_synchronous_client)
1442+{
1443+ connection = mir_connect_sync(new_connection().c_str(), __PRETTY_FUNCTION__);
1444+
1445+ MirSurfaceParameters const request_params =
1446+ {
1447+ __PRETTY_FUNCTION__,
1448+ 640, 480,
1449+ mir_pixel_format_abgr_8888,
1450+ mir_buffer_usage_software,
1451+ mir_display_output_id_invalid
1452+ };
1453+
1454+ surface = mir_connection_create_surface_sync(connection, &request_params);
1455+
1456+ mir_surface_swap_buffers_sync(surface);
1457+ EXPECT_TRUE(mir_surface_is_valid(surface));
1458+ EXPECT_STREQ(mir_surface_get_error_message(surface), "");
1459+
1460+ mir_surface_release_sync(surface);
1461+
1462+ EXPECT_TRUE(mir_connection_is_valid(connection));
1463+ EXPECT_STREQ("", mir_connection_get_error_message(connection));
1464+ mir_connection_release(connection);
1465+}
1466+
1467+TEST_F(ClientLibrary, highly_threaded_client)
1468+{
1469+ connection = mir_connect_sync(new_connection().c_str(), __PRETTY_FUNCTION__);
1470+
1471+ MirSurfaceParameters const request_params =
1472+ {
1473+ __PRETTY_FUNCTION__,
1474+ 640, 480,
1475+ mir_pixel_format_abgr_8888,
1476+ mir_buffer_usage_software,
1477+ mir_display_output_id_invalid
1478+ };
1479+
1480+ surface = mir_connection_create_surface_sync(connection, &request_params);
1481+
1482+ std::thread a(nosey_thread, surface);
1483+ std::thread b(nosey_thread, surface);
1484+ std::thread c(nosey_thread, surface);
1485+
1486+ a.join();
1487+ b.join();
1488+ c.join();
1489+
1490+ EXPECT_THAT(mir_surface_get_type(surface), Eq(mir_surface_type_dialog));
1491+ EXPECT_THAT(mir_surface_get_type(surface), Eq(mir_surface_state_minimized));
1492+
1493+ mir_surface_release_sync(surface);
1494+
1495+ EXPECT_TRUE(mir_connection_is_valid(connection));
1496+ EXPECT_THAT(mir_connection_get_error_message(connection), StrEq(""));
1497+ mir_connection_release(connection);
1498+}
1499+
1500+TEST_F(ClientLibrary, accesses_platform_package)
1501+{
1502+ mir_wait_for(mir_connect(new_connection().c_str(), __PRETTY_FUNCTION__, connection_callback, this));
1503+
1504+ MirPlatformPackage platform_package;
1505+ platform_package.data_items = -1;
1506+ platform_package.fd_items = -1;
1507+
1508+ mir_connection_get_platform(connection, &platform_package);
1509+ EXPECT_GE(0, platform_package.data_items);
1510+ EXPECT_GE(0, platform_package.fd_items);
1511+
1512+ mir_connection_release(connection);
1513+}
1514+
1515+TEST_F(ClientLibrary, accesses_display_info)
1516+{
1517+ mir_wait_for(mir_connect(new_connection().c_str(), __PRETTY_FUNCTION__, connection_callback, this));
1518+
1519+ auto configuration = mir_connection_create_display_config(connection);
1520+ ASSERT_THAT(configuration, NotNull());
1521+ ASSERT_GT(configuration->num_outputs, 0u);
1522+ ASSERT_THAT(configuration->outputs, NotNull());
1523+ for (auto i=0u; i < configuration->num_outputs; i++)
1524+ {
1525+ MirDisplayOutput* disp = &configuration->outputs[i];
1526+ ASSERT_THAT(disp, NotNull());
1527+ EXPECT_GE(disp->num_modes, disp->current_mode);
1528+ EXPECT_GE(disp->num_output_formats, disp->current_format);
1529+ }
1530+
1531+ mir_display_config_destroy(configuration);
1532+ mir_connection_release(connection);
1533+}
1534+
1535+TEST_F(ClientLibrary, connect_errors_handled)
1536+{
1537+ mir_wait_for(mir_connect("garbage", __PRETTY_FUNCTION__, connection_callback, this));
1538+ ASSERT_THAT(connection, NotNull());
1539+
1540+ char const* error = mir_connection_get_error_message(connection);
1541+
1542+ if (std::strcmp("connect: No such file or directory", error) &&
1543+ std::strcmp("Can't find MIR server", error) &&
1544+ std::strcmp("Failed to connect to server socket", error))
1545+ {
1546+ FAIL() << error;
1547+ }
1548+}
1549+
1550+TEST_F(ClientLibrary, connect_errors_dont_blow_up)
1551+{
1552+ mir_wait_for(mir_connect("garbage", __PRETTY_FUNCTION__, connection_callback, this));
1553+
1554+ MirSurfaceParameters const request_params =
1555+ {
1556+ __PRETTY_FUNCTION__,
1557+ 640, 480,
1558+ mir_pixel_format_abgr_8888,
1559+ mir_buffer_usage_hardware,
1560+ mir_display_output_id_invalid
1561+ };
1562+
1563+ mir_wait_for(mir_connection_create_surface(connection, &request_params, create_surface_callback, this));
1564 // TODO surface_create needs to fail safe too. After that is done we should add the following:
1565 // TODO mir_wait_for(mir_surface_swap_buffers(surface, next_buffer_callback, this));
1566 // TODO mir_wait_for(mir_surface_release( surface, release_surface_callback, this));
1567
1568- mir_connection_release(connection);
1569- }
1570-
1571- //we are testing the connect function itself, without getting to the
1572- // point where drivers are used, so force using production config
1573- bool use_real_graphics(mir::options::Option const&) override
1574- {
1575- return true;
1576- }
1577- } client_config;
1578-
1579- launch_client_process(client_config);
1580-}
1581-
1582-bool signalled;
1583-static void SIGIO_handler(int /*signo*/)
1584-{
1585- signalled = true;
1586-}
1587-
1588-TEST_F(DefaultDisplayServerTestFixture, ClientLibraryThreadsHandleNoSignals)
1589-{
1590- struct ClientConfig : ClientConfigCommon
1591- {
1592- void exec()
1593- {
1594- signalled = false;
1595-
1596- sigset_t sigset;
1597- sigemptyset(&sigset);
1598- struct sigaction act;
1599- act.sa_handler = &SIGIO_handler;
1600- act.sa_mask = sigset;
1601- act.sa_flags = 0;
1602- act.sa_restorer = nullptr;
1603- if (sigaction(SIGIO, &act, NULL))
1604- FAIL() << "Failed to set SIGIO action";
1605-
1606- MirConnection* conn = NULL;
1607- conn = mir_connect_sync(mir_test_socket, __PRETTY_FUNCTION__);
1608-
1609- sigaddset(&sigset, SIGIO);
1610- pthread_sigmask(SIG_BLOCK, &sigset, NULL);
1611-
1612- // SIGIO should be blocked
1613- if (kill(getpid(), SIGIO))
1614- FAIL() << "Failed to send SIGIO signal";
1615-
1616- // Make a roundtrip to the server to ensure the SIGIO has time to be handled
1617- MirSurfaceParameters const request_params =
1618- {
1619- __PRETTY_FUNCTION__,
1620- 640, 480,
1621- mir_pixel_format_abgr_8888,
1622- mir_buffer_usage_software,
1623- mir_display_output_id_invalid
1624- };
1625-
1626- surface = mir_connection_create_surface_sync(conn, &request_params);
1627-
1628- mir_connection_release(conn);
1629-
1630- EXPECT_FALSE(signalled);
1631- }
1632- } client_config;
1633-
1634- launch_client_process(client_config);
1635-}
1636-
1637-TEST_F(DefaultDisplayServerTestFixture, ClientLibraryDoesNotInterfereWithClientSignalHandling)
1638-{
1639- struct ClientConfig : ClientConfigCommon
1640- {
1641- void exec()
1642- {
1643- signalled = false;
1644-
1645- sigset_t sigset;
1646- sigemptyset(&sigset);
1647- struct sigaction act;
1648- act.sa_handler = &SIGIO_handler;
1649- act.sa_mask = sigset;
1650- act.sa_flags = 0;
1651- act.sa_restorer = nullptr;
1652- if (sigaction(SIGIO, &act, NULL))
1653- FAIL() << "Failed to set SIGIO action";
1654-
1655- MirConnection* conn = NULL;
1656- conn = mir_connect_sync(mir_test_socket, __PRETTY_FUNCTION__);
1657-
1658- // We should receieve SIGIO
1659- if (kill(getpid(), SIGIO))
1660- FAIL() << "Failed to send SIGIO signal";
1661-
1662- mir_connection_release(conn);
1663-
1664- EXPECT_TRUE(signalled);
1665- }
1666- } client_config;
1667-
1668- launch_client_process(client_config);
1669-}
1670-
1671-TEST_F(DefaultDisplayServerTestFixture, MultiSurfaceClientTracksBufferFdsCorrectly)
1672-{
1673- struct ClientConfig : ClientConfigCommon
1674- {
1675- void exec()
1676- {
1677-
1678- mir_wait_for(mir_connect(mir_test_socket, __PRETTY_FUNCTION__, connection_callback, this));
1679-
1680- ASSERT_TRUE(connection != NULL);
1681- EXPECT_TRUE(mir_connection_is_valid(connection));
1682- EXPECT_STREQ("", mir_connection_get_error_message(connection));
1683-
1684- MirSurfaceParameters const request_params =
1685- {
1686- __PRETTY_FUNCTION__,
1687- 640, 480,
1688- mir_pixel_format_abgr_8888,
1689- mir_buffer_usage_hardware,
1690- mir_display_output_id_invalid
1691- };
1692-
1693- surf_one = mir_connection_create_surface_sync(connection, &request_params);
1694- surf_two = mir_connection_create_surface_sync(connection, &request_params);
1695-
1696- ASSERT_TRUE(surf_one != NULL);
1697- ASSERT_TRUE(surf_two != NULL);
1698-
1699- buffers = 0;
1700-
1701- while (buffers < 1024)
1702- {
1703- mir_surface_swap_buffers_sync(surf_one);
1704- mir_surface_swap_buffers_sync(surf_two);
1705-
1706- buffers++;
1707- }
1708-
1709- /* We should not have any stray fds hanging around.
1710- Test this by trying to open a new one */
1711- int canary_fd;
1712- canary_fd = open("/dev/null", O_RDONLY);
1713-
1714- ASSERT_TRUE(canary_fd > 0) << "Failed to open canary file descriptor: "<< strerror(errno);
1715- EXPECT_TRUE(canary_fd < 1024);
1716-
1717- close(canary_fd);
1718-
1719- mir_wait_for(mir_surface_release(surf_one, release_surface_callback, this));
1720- mir_wait_for(mir_surface_release(surf_two, release_surface_callback, this));
1721-
1722- ASSERT_TRUE(surf_one == NULL);
1723- ASSERT_TRUE(surf_two == NULL);
1724-
1725- mir_connection_release(connection);
1726- }
1727-
1728- virtual void surface_released (MirSurface* surf)
1729- {
1730- if (surf == surf_one)
1731- surf_one = NULL;
1732- if (surf == surf_two)
1733- surf_two = NULL;
1734- }
1735-
1736- MirSurface* surf_one;
1737- MirSurface* surf_two;
1738- } client_config;
1739-
1740- launch_client_process(client_config);
1741-}
1742-
1743+ mir_connection_release(connection);
1744+}
1745+
1746+TEST_F(ClientLibrary, MultiSurfaceClientTracksBufferFdsCorrectly)
1747+{
1748+ mir_wait_for(mir_connect(new_connection().c_str(), __PRETTY_FUNCTION__, connection_callback, this));
1749+
1750+ MirSurfaceParameters const request_params =
1751+ {
1752+ __PRETTY_FUNCTION__,
1753+ 640, 480,
1754+ mir_pixel_format_abgr_8888,
1755+ mir_buffer_usage_hardware,
1756+ mir_display_output_id_invalid
1757+ };
1758+
1759+ MirSurface* surf_one = mir_connection_create_surface_sync(connection, &request_params);
1760+ MirSurface* surf_two = mir_connection_create_surface_sync(connection, &request_params);
1761+
1762+ ASSERT_THAT(surf_one, NotNull());
1763+ ASSERT_THAT(surf_two, NotNull());
1764+
1765+ buffers = 0;
1766+
1767+ while (buffers < 1024)
1768+ {
1769+ mir_surface_swap_buffers_sync(surf_one);
1770+ mir_surface_swap_buffers_sync(surf_two);
1771+
1772+ buffers++;
1773+ }
1774+
1775+ /* We should not have any stray fds hanging around.
1776+ Test this by trying to open a new one */
1777+ int canary_fd;
1778+ canary_fd = open("/dev/null", O_RDONLY);
1779+
1780+ ASSERT_THAT(canary_fd, Gt(0)) << "Failed to open canary file descriptor: "<< strerror(errno);
1781+ EXPECT_THAT(canary_fd, Lt(1024));
1782+
1783+ close(canary_fd);
1784+
1785+ mir_wait_for(mir_surface_release(surf_one, release_surface_callback, this));
1786+ mir_wait_for(mir_surface_release(surf_two, release_surface_callback, this));
1787+
1788+ ASSERT_THAT(current_surface_count(), testing::Eq(0));
1789+
1790+ mir_connection_release(connection);
1791 }
1792
1793=== added file 'tests/acceptance-tests/test_client_library_threads.cpp'
1794--- tests/acceptance-tests/test_client_library_threads.cpp 1970-01-01 00:00:00 +0000
1795+++ tests/acceptance-tests/test_client_library_threads.cpp 2014-06-02 13:37:17 +0000
1796@@ -0,0 +1,126 @@
1797+/*
1798+ * Copyright © 2012 Canonical Ltd.
1799+ *
1800+ * This program is free software: you can redistribute it and/or modify
1801+ * it under the terms of the GNU General Public License version 3 as
1802+ * published by the Free Software Foundation.
1803+ *
1804+ * This program is distributed in the hope that it will be useful,
1805+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1806+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1807+ * GNU General Public License for more details.
1808+ *
1809+ * You should have received a copy of the GNU General Public License
1810+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1811+ *
1812+ * Authored by: Thomas Guest <thomas.guest@canonical.com>
1813+ */
1814+
1815+#include "mir_test_framework/display_server_test_fixture.h"
1816+
1817+#include "mir_toolkit/mir_client_library.h"
1818+#include "mir_toolkit/mir_client_library_debug.h"
1819+
1820+#include <gtest/gtest.h>
1821+
1822+#include <sys/types.h>
1823+#include <sys/stat.h>
1824+
1825+namespace mtf = mir_test_framework;
1826+
1827+namespace
1828+{
1829+ char const* const mir_test_socket = mtf::test_socket_file().c_str();
1830+
1831+bool signalled;
1832+extern "C" void SIGIO_handler(int /*signo*/)
1833+{
1834+ signalled = true;
1835+}
1836+}
1837+
1838+namespace mir
1839+{
1840+using ClientLibraryThreads = DefaultDisplayServerTestFixture;
1841+
1842+TEST_F(ClientLibraryThreads, HandleNoSignals)
1843+{
1844+ struct ClientConfig : TestingClientConfiguration
1845+ {
1846+ void exec()
1847+ {
1848+ signalled = false;
1849+
1850+ sigset_t sigset;
1851+ sigemptyset(&sigset);
1852+ struct sigaction act;
1853+ act.sa_handler = &SIGIO_handler;
1854+ act.sa_mask = sigset;
1855+ act.sa_flags = 0;
1856+ act.sa_restorer = nullptr;
1857+ if (sigaction(SIGIO, &act, NULL))
1858+ FAIL() << "Failed to set SIGIO action";
1859+
1860+ MirConnection* conn = mir_connect_sync(mir_test_socket, __PRETTY_FUNCTION__);
1861+
1862+ sigaddset(&sigset, SIGIO);
1863+ pthread_sigmask(SIG_BLOCK, &sigset, NULL);
1864+
1865+ // SIGIO should be blocked
1866+ if (kill(getpid(), SIGIO))
1867+ FAIL() << "Failed to send SIGIO signal";
1868+
1869+ // Make a roundtrip to the server to ensure the SIGIO has time to be handled
1870+ MirSurfaceParameters const request_params =
1871+ {
1872+ __PRETTY_FUNCTION__,
1873+ 640, 480,
1874+ mir_pixel_format_abgr_8888,
1875+ mir_buffer_usage_software,
1876+ mir_display_output_id_invalid
1877+ };
1878+
1879+ mir_connection_create_surface_sync(conn, &request_params);
1880+
1881+ mir_connection_release(conn);
1882+
1883+ EXPECT_FALSE(signalled);
1884+ }
1885+ } client_config;
1886+
1887+ launch_client_process(client_config);
1888+}
1889+
1890+TEST_F(ClientLibraryThreads, DoNotInterfereWithClientSignalHandling)
1891+{
1892+ struct ClientConfig : TestingClientConfiguration
1893+ {
1894+ void exec()
1895+ {
1896+ signalled = false;
1897+
1898+ sigset_t sigset;
1899+ sigemptyset(&sigset);
1900+ struct sigaction act;
1901+ act.sa_handler = &SIGIO_handler;
1902+ act.sa_mask = sigset;
1903+ act.sa_flags = 0;
1904+ act.sa_restorer = nullptr;
1905+ if (sigaction(SIGIO, &act, NULL))
1906+ FAIL() << "Failed to set SIGIO action";
1907+
1908+ MirConnection* conn = mir_connect_sync(mir_test_socket, __PRETTY_FUNCTION__);
1909+
1910+ // We should receieve SIGIO
1911+ if (kill(getpid(), SIGIO))
1912+ FAIL() << "Failed to send SIGIO signal";
1913+
1914+ mir_connection_release(conn);
1915+
1916+ EXPECT_TRUE(signalled);
1917+ }
1918+ } client_config;
1919+
1920+ launch_client_process(client_config);
1921+}
1922+}

Subscribers

People subscribed via source and target branches