Mir

Merge lp:~albaguirre/mir/tidy-up-client-cursor-tests into lp:mir

Proposed by Alberto Aguirre
Status: Merged
Approved by: Alberto Aguirre
Approved revision: no longer in the source branch.
Merged at revision: 4144
Proposed branch: lp:~albaguirre/mir/tidy-up-client-cursor-tests
Merge into: lp:mir
Diff against target: 811 lines (+322/-250)
1 file modified
tests/acceptance-tests/test_client_cursor_api.cpp (+322/-250)
To merge this branch: bzr merge lp:~albaguirre/mir/tidy-up-client-cursor-tests
Reviewer Review Type Date Requested Status
Brandon Schaefer (community) Approve
Mir CI Bot continuous-integration Approve
Review via email: mp+322153@code.launchpad.net

Commit message

Tidy up client cursor api tests.

To post a comment you must log in.
Revision history for this message
Mir CI Bot (mir-ci-bot) wrote :

PASSED: Continuous integration, rev:4143
https://mir-jenkins.ubuntu.com/job/mir-ci/3342/
Executed test runs:
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-mir/4514
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-0-fetch/4632
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=vivid+overlay/4621
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial/4621
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial+overlay/4621
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-1-sourcepkg/release=zesty/4621
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=zesty/4545
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=clang,platform=mesa,release=zesty/4545/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial+overlay/4545
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=xenial+overlay/4545/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=zesty/4545
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=amd64,compiler=gcc,platform=mesa,release=zesty/4545/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=android,release=vivid+overlay/4545
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=cross-armhf,compiler=gcc,platform=android,release=vivid+overlay/4545/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=android,release=vivid+overlay/4545
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=android,release=vivid+overlay/4545/artifact/output/*zip*/output.zip
    SUCCESS: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial+overlay/4545
        deb: https://mir-jenkins.ubuntu.com/job/build-2-binpkg-mir/arch=i386,compiler=gcc,platform=mesa,release=xenial+overlay/4545/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://mir-jenkins.ubuntu.com/job/mir-ci/3342/rebuild

review: Approve (continuous-integration)
Revision history for this message
Brandon Schaefer (brandontschaefer) wrote :

lgtm

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'tests/acceptance-tests/test_client_cursor_api.cpp'
2--- tests/acceptance-tests/test_client_cursor_api.cpp 2017-03-29 15:59:49 +0000
3+++ tests/acceptance-tests/test_client_cursor_api.cpp 2017-04-06 20:26:19 +0000
4@@ -54,10 +54,12 @@
5 namespace mtd = mt::doubles;
6 namespace mtf = mir_test_framework;
7
8+using namespace testing;
9+using namespace std::chrono_literals;
10+
11 namespace
12 {
13
14-std::chrono::seconds const timeout{5};
15 class MockSurfaceObserver : public msc::SurfaceObserver
16 {
17 public:
18@@ -118,7 +120,7 @@
19 {
20 if (name == "none")
21 return nullptr;
22-
23+
24 return std::make_shared<NamedCursorImage>(name);
25 }
26 };
27@@ -141,92 +143,204 @@
28 return cursor_is_named(arg, name);
29 }
30
31+struct WindowReadyHandler
32+{
33+ static void callback(MirWindow*, MirEvent const* event, void* context)
34+ {
35+ auto handler = reinterpret_cast<WindowReadyHandler *>(context);
36+ handler->handle_event(event);
37+ }
38+
39+ void handle_event(MirEvent const* event)
40+ {
41+ auto type = mir_event_get_type(event);
42+ if (type != mir_event_type_window)
43+ return;
44+
45+ auto window_event = mir_event_get_window_event(event);
46+ auto const attrib = mir_window_event_get_attribute(window_event);
47+ auto const value = mir_window_event_get_attribute_value(window_event);
48+
49+ if (attrib == mir_window_attrib_visibility && value == mir_window_visibility_exposed)
50+ {
51+ window_exposed = true;
52+ }
53+
54+ if (attrib == mir_window_attrib_focus && value == mir_window_focus_state_focused)
55+ {
56+ window_focused = true;
57+ }
58+
59+ if (window_exposed && window_focused)
60+ window_focused_and_exposed.raise();
61+ }
62+
63+ void wait_for_window_to_become_focused_and_exposed()
64+ {
65+ if (!window_focused_and_exposed.wait_for(30s))
66+ throw std::runtime_error("Timed out waiting for window to be focused and exposed");
67+ }
68+
69+ bool window_exposed{false};
70+ bool window_focused{false};
71+ mir::test::Signal window_focused_and_exposed;
72+};
73+
74+MirWindow *make_window(MirConnection *connection, std::string const& client_name)
75+{
76+ auto spec = mir_create_normal_window_spec(connection, 1, 1);
77+ mir_window_spec_set_pixel_format(spec, mir_pixel_format_abgr_8888);
78+ mir_window_spec_set_name(spec, client_name.c_str());
79+
80+ WindowReadyHandler event_handler;
81+ mir_window_spec_set_event_handler(spec, WindowReadyHandler::callback, &event_handler);
82+
83+ auto const window = mir_create_window_sync(spec);
84+ mir_window_spec_release(spec);
85+
86+ mir_buffer_stream_swap_buffers_sync(mir_window_get_buffer_stream(window));
87+
88+ event_handler.wait_for_window_to_become_focused_and_exposed();
89+ mir_window_set_event_handler(window, nullptr, nullptr);
90+
91+ return window;
92+}
93+
94+#pragma GCC diagnostic push
95+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
96+struct MirSurfaceDeleter
97+{
98+ void operator()(MirRenderSurface *surface) { mir_render_surface_release(surface); }
99+};
100+
101+using RenderSurface = std::unique_ptr<MirRenderSurface, MirSurfaceDeleter>;
102+#pragma GCC diagnostic pop
103+
104 struct CursorClient
105 {
106 CursorClient(std::string const& connect_string, std::string const& client_name)
107- : connect_string{connect_string}, client_name{client_name}
108+ : connection(mir_connect_sync(connect_string.c_str(), client_name.c_str())),
109+ window(make_window(connection, client_name))
110 {
111 }
112
113 virtual ~CursorClient()
114 {
115- teardown.raise();
116- if (client_thread.joinable())
117- client_thread.join();
118- }
119-
120- void run()
121- {
122- mir::test::Signal setup_done;
123-
124- client_thread = std::thread{
125- [this,&setup_done]
126- {
127- connection =
128- mir_connect_sync(connect_string.c_str(), client_name.c_str());
129-
130- auto spec = mir_create_normal_window_spec(connection, 1, 1);
131- mir_window_spec_set_pixel_format(spec, mir_pixel_format_abgr_8888);
132- mir_window_spec_set_name(spec, client_name.c_str());
133- auto const window = mir_create_window_sync(spec);
134- mir_window_spec_release(spec);
135-
136- mir_buffer_stream_swap_buffers_sync(
137- mir_window_get_buffer_stream(window));
138-
139- wait_for_surface_to_become_focused_and_exposed(window);
140-
141- setup_cursor(window);
142-
143- setup_done.raise();
144-
145- teardown.wait_for(std::chrono::seconds{10});
146- mir_window_release_sync(window);
147- mir_connection_release(connection);
148- }};
149-
150- setup_done.wait_for(std::chrono::seconds{5});
151- }
152-
153- virtual void setup_cursor(MirWindow*)
154- {
155- }
156-
157- void wait_for_surface_to_become_focused_and_exposed(MirWindow* window)
158- {
159- bool success = mt::spin_wait_for_condition_or_timeout(
160- [window]
161- {
162- return mir_window_get_visibility(window) == mir_window_visibility_exposed &&
163- mir_window_get_focus_state(window) == mir_window_focus_state_focused;
164- },
165- std::chrono::seconds{5});
166-
167- if (!success)
168- throw std::runtime_error("Timeout waiting for window to become focused and exposed");
169- }
170-
171- std::string const connect_string;
172- std::string const client_name;
173-
174- MirConnection* connection;
175-
176- std::thread client_thread;
177- mir::test::Signal teardown;
178+ if (window)
179+ mir_window_release_sync(window);
180+ if (connection)
181+ mir_connection_release(connection);
182+ }
183+
184+ RenderSurface make_surface()
185+ {
186+#pragma GCC diagnostic push
187+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
188+ RenderSurface surface{mir_connection_create_render_surface_sync(connection, 24, 24)};
189+ return surface;
190+#pragma GCC diagnostic pop
191+ }
192+
193+
194+ virtual void configure_cursor() = 0;
195+
196+ MirConnection* connection{nullptr};
197+ MirWindow *window{nullptr};
198+
199+ int const hotspot_x{1};
200+ int const hotspot_y{1};
201+
202+};
203+
204+struct CursorWindowSpec
205+{
206+#pragma GCC diagnostic push
207+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
208+ CursorWindowSpec(MirConnection *connection, RenderSurface const& surface, int hotspot_x, int hotspot_y)
209+ : spec(mir_create_window_spec(connection))
210+ {
211+ mir_window_spec_set_cursor_render_surface(spec, surface.get(), hotspot_x, hotspot_y);
212+ }
213+#pragma GCC diagnostic pop
214+
215+ ~CursorWindowSpec()
216+ {
217+ mir_window_spec_release(spec);
218+ }
219+
220+ void apply(MirWindow *window)
221+ {
222+ mir_window_apply_spec(window, spec);
223+ }
224+ MirWindowSpec * const spec;
225+};
226+
227+struct BufferStream
228+{
229+ BufferStream(MirConnection *connection)
230+ : stream_owned{true},
231+ stream{mir_connection_create_buffer_stream_sync(connection, 24, 24, mir_pixel_format_argb_8888,mir_buffer_usage_software)}
232+ {}
233+
234+#pragma GCC diagnostic push
235+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
236+ BufferStream(RenderSurface const& surface)
237+ : stream_owned(false),
238+ stream{mir_render_surface_get_buffer_stream(surface.get(), 24, 24, mir_pixel_format_argb_8888)}
239+ {}
240+#pragma GCC diagnostic pop
241+
242+ ~BufferStream()
243+ {
244+ if (stream_owned)
245+ mir_buffer_stream_release_sync(stream);
246+ }
247+
248+ void swap_buffers()
249+ {
250+ mir_buffer_stream_swap_buffers_sync(stream);
251+ }
252+
253+ bool stream_owned;
254+ MirBufferStream *stream;
255+};
256+
257+struct CursorConfiguration
258+{
259+#pragma GCC diagnostic push
260+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
261+ CursorConfiguration(std::string const& name)
262+ : conf(mir_cursor_configuration_from_name(name.c_str())) {}
263+ CursorConfiguration(const char * name)
264+ : conf(mir_cursor_configuration_from_name(name)) {}
265+ CursorConfiguration(RenderSurface const& surface, int hotspot_x, int hotspot_y)
266+ : conf(mir_cursor_configuration_from_render_surface(surface.get(), hotspot_x, hotspot_y)) {}
267+ CursorConfiguration(BufferStream const& stream, int hotspot_x, int hotspot_y)
268+ : conf(mir_cursor_configuration_from_buffer_stream(stream.stream, hotspot_x, hotspot_y)) {}
269+#pragma GCC diagnostic pop
270+
271+ ~CursorConfiguration()
272+ {
273+ if (conf)
274+ mir_cursor_configuration_destroy(conf);
275+ }
276+
277+ void apply(MirWindow *window)
278+ {
279+ mir_window_configure_cursor(window, conf);
280+ }
281+
282+ MirCursorConfiguration * conf;
283 };
284
285 struct DisabledCursorClient : CursorClient
286 {
287 using CursorClient::CursorClient;
288
289- void setup_cursor(MirWindow* window) override
290+ void configure_cursor() override
291 {
292-#pragma GCC diagnostic push
293-#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
294- auto conf = mir_cursor_configuration_from_name(mir_disabled_cursor_name);
295-#pragma GCC diagnostic pop
296- mir_window_configure_cursor(window, conf);
297- mir_cursor_configuration_destroy(conf);
298+ CursorConfiguration conf{mir_disabled_cursor_name};
299+ conf.apply(window);
300 }
301 };
302
303@@ -241,30 +355,92 @@
304 {
305 }
306
307- void setup_cursor(MirWindow* window) override
308+ void configure_cursor() override
309 {
310-#pragma GCC diagnostic push
311-#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
312- auto conf = mir_cursor_configuration_from_name(cursor_name.c_str());
313-#pragma GCC diagnostic pop
314- mir_window_configure_cursor(window, conf);
315- mir_cursor_configuration_destroy(conf);
316+ CursorConfiguration conf{cursor_name};
317+ conf.apply(window);
318 }
319
320 std::string const cursor_name;
321 };
322
323-struct TestClientCursorAPI : mtf::HeadlessInProcessServer
324+struct ChangingCursorClient : NamedCursorClient
325+{
326+ using NamedCursorClient::NamedCursorClient;
327+
328+ void configure_cursor() override
329+ {
330+ CursorConfiguration conf1{cursor_name};
331+ CursorConfiguration conf2{mir_disabled_cursor_name};
332+
333+ conf1.apply(window);
334+ conf2.apply(window);
335+ }
336+};
337+
338+struct BufferStreamClient : CursorClient
339+{
340+ using CursorClient::CursorClient;
341+
342+ void configure_cursor() override
343+ {
344+ BufferStream stream{connection};
345+ CursorConfiguration conf{stream, hotspot_x, hotspot_y};
346+
347+ stream.swap_buffers();
348+ conf.apply(window);
349+ stream.swap_buffers();
350+ stream.swap_buffers();
351+ }
352+};
353+
354+struct SurfaceCursorConfigClient : CursorClient
355+{
356+ using CursorClient::CursorClient;
357+
358+ void configure_cursor() override
359+ {
360+ auto surface = make_surface();
361+ BufferStream stream{surface};
362+ CursorConfiguration conf{surface, hotspot_x, hotspot_y};
363+ stream.swap_buffers();
364+
365+ conf.apply(window);
366+
367+ stream.swap_buffers();
368+ stream.swap_buffers();
369+ }
370+};
371+
372+struct SurfaceCursorClient : CursorClient
373+{
374+ using CursorClient::CursorClient;
375+ void configure_cursor() override
376+ {
377+ auto surface = make_surface();
378+ BufferStream stream{surface};
379+
380+ stream.swap_buffers();
381+
382+ CursorWindowSpec spec{connection, surface, hotspot_x, hotspot_y};
383+ spec.apply(window);
384+
385+ stream.swap_buffers();
386+ stream.swap_buffers();
387+ }
388+};
389+
390+struct ClientCursor : mtf::HeadlessInProcessServer
391 {
392 // mtf::add_fake_input_device needs this library to be loaded each test, for the tests
393 mtf::TemporaryEnvironmentValue input_lib{"MIR_SERVER_PLATFORM_INPUT_LIB", mtf::server_platform("input-stub.so").c_str()};
394- ::testing::NiceMock<MockCursor> cursor;
395- std::shared_ptr<::testing::NiceMock<MockSurfaceObserver>> mock_surface_observer =
396- std::make_shared<::testing::NiceMock<MockSurfaceObserver>>();
397+ NiceMock<MockCursor> cursor;
398+ std::shared_ptr<NiceMock<MockSurfaceObserver>> mock_surface_observer =
399+ std::make_shared<NiceMock<MockSurfaceObserver>>();
400
401 mtf::SurfaceGeometries client_geometries;
402
403- TestClientCursorAPI()
404+ ClientCursor()
405 {
406 mock_egl.provide_egl_extensions();
407 mock_egl.provide_stub_platform_buffer_swapping();
408@@ -293,7 +469,6 @@
409
410 void expect_client_shutdown()
411 {
412- using namespace testing;
413 Mock::VerifyAndClearExpectations(&cursor);
414
415 // Client shutdown
416@@ -312,7 +487,8 @@
417 mtf::add_fake_input_device(mi::InputDeviceInfo{"mouse", "mouse-uid" , mi::DeviceCapability::pointer})
418 };
419
420- ::testing::NiceMock<mtd::MockEGL> mock_egl;
421+ NiceMock<mtd::MockEGL> mock_egl;
422+ std::chrono::seconds const timeout{5s};
423 };
424
425 }
426@@ -320,10 +496,8 @@
427 // In this set we create a 1x1 client window at the point (1,0). The client requests to disable the cursor
428 // over this window. Since the cursor starts at (0,0) we when we move the cursor by (1,0) thus causing it
429 // to enter the bounds of the first window, we should observe it being disabled.
430-TEST_F(TestClientCursorAPI, client_may_disable_cursor_over_surface)
431+TEST_F(ClientCursor, can_be_disabled)
432 {
433- using namespace ::testing;
434-
435 client_geometries[client_name_1] =
436 geom::Rectangle{{1, 0}, {1, 1}};
437
438@@ -334,7 +508,7 @@
439 .WillOnce(mt::WakeUp(&wait));
440
441 DisabledCursorClient client{new_connection(), client_name_1};
442- client.run();
443+ client.configure_cursor();
444
445 EXPECT_TRUE(wait.wait_for(timeout));
446
447@@ -343,15 +517,13 @@
448
449 fake_mouse->emit_event(mis::a_pointer_event().with_movement(1, 0));
450
451- expectations_satisfied.wait_for(std::chrono::seconds{5});
452+ expectations_satisfied.wait_for(timeout);
453
454 expect_client_shutdown();
455 }
456
457-TEST_F(TestClientCursorAPI, cursor_restored_when_leaving_surface)
458+TEST_F(ClientCursor, is_restored_when_leaving_surface)
459 {
460- using namespace ::testing;
461-
462 client_geometries[client_name_1] =
463 geom::Rectangle{{1, 0}, {1, 1}};
464
465@@ -362,7 +534,7 @@
466 .WillOnce(mt::WakeUp(&wait));
467
468 DisabledCursorClient client{new_connection(), client_name_1};
469- client.run();
470+ client.configure_cursor();
471
472 EXPECT_TRUE(wait.wait_for(timeout));
473
474@@ -374,15 +546,13 @@
475 fake_mouse->emit_event(mis::a_pointer_event().with_movement(1, 0));
476 fake_mouse->emit_event(mis::a_pointer_event().with_movement(2, 0));
477
478- expectations_satisfied.wait_for(std::chrono::seconds{5});
479+ expectations_satisfied.wait_for(timeout);
480
481 expect_client_shutdown();
482 }
483
484-TEST_F(TestClientCursorAPI, cursor_changed_when_crossing_surface_boundaries)
485+TEST_F(ClientCursor, is_changed_when_crossing_surface_boundaries)
486 {
487- using namespace ::testing;
488-
489 client_geometries[client_name_1] =
490 geom::Rectangle{{1, 0}, {1, 1}};
491 client_geometries[client_name_2] =
492@@ -395,7 +565,7 @@
493 .WillOnce(mt::WakeUp(&wait));
494
495 NamedCursorClient client_1{new_connection(), client_name_1, client_cursor_1};
496- client_1.run();
497+ client_1.configure_cursor();
498
499 EXPECT_TRUE(wait.wait_for(timeout));
500 wait.reset();
501@@ -405,7 +575,7 @@
502 .WillOnce(mt::WakeUp(&wait));
503
504 NamedCursorClient client_2{new_connection(), client_name_2, client_cursor_2};
505- client_2.run();
506+ client_2.configure_cursor();
507
508 EXPECT_TRUE(wait.wait_for(timeout));
509
510@@ -417,15 +587,13 @@
511 fake_mouse->emit_event(mis::a_pointer_event().with_movement(1, 0));
512 fake_mouse->emit_event(mis::a_pointer_event().with_movement(1, 0));
513
514- expectations_satisfied.wait_for(std::chrono::seconds{5});
515+ expectations_satisfied.wait_for(timeout);
516
517 expect_client_shutdown();
518 }
519
520-TEST_F(TestClientCursorAPI, cursor_request_taken_from_top_surface)
521+TEST_F(ClientCursor, of_topmost_window_is_applied)
522 {
523- using namespace ::testing;
524-
525 client_geometries[client_name_1] =
526 geom::Rectangle{{1, 0}, {1, 1}};
527 client_geometries[client_name_2] =
528@@ -438,7 +606,7 @@
529 .WillOnce(mt::WakeUp(&wait));
530
531 NamedCursorClient client_1{new_connection(), client_name_1, client_cursor_1};
532- client_1.run();
533+ client_1.configure_cursor();
534
535 EXPECT_TRUE(wait.wait_for(timeout));
536 wait.reset();
537@@ -448,7 +616,7 @@
538 .WillOnce(mt::WakeUp(&wait));
539
540 NamedCursorClient client_2{new_connection(), client_name_2, client_cursor_2};
541- client_2.run();
542+ client_2.configure_cursor();
543
544 EXPECT_TRUE(wait.wait_for(timeout));
545
546@@ -457,35 +625,13 @@
547
548 fake_mouse->emit_event(mis::a_pointer_event().with_movement(1, 0));
549
550- expectations_satisfied.wait_for(std::chrono::seconds{5});
551+ expectations_satisfied.wait_for(timeout);
552
553 expect_client_shutdown();
554 }
555
556-TEST_F(TestClientCursorAPI, cursor_request_applied_without_cursor_motion)
557+TEST_F(ClientCursor, is_applied_without_cursor_motion)
558 {
559- using namespace ::testing;
560-
561- struct ChangingCursorClient : NamedCursorClient
562- {
563- using NamedCursorClient::NamedCursorClient;
564-
565- void setup_cursor(MirWindow* window) override
566- {
567-#pragma GCC diagnostic push
568-#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
569- auto conf1 = mir_cursor_configuration_from_name(cursor_name.c_str());
570- auto conf2 = mir_cursor_configuration_from_name(mir_disabled_cursor_name);
571-#pragma GCC diagnostic pop
572-
573- mir_window_configure_cursor(window, conf1);
574- mir_window_configure_cursor(window, conf2);
575-
576- mir_cursor_configuration_destroy(conf1);
577- mir_cursor_configuration_destroy(conf2);
578- }
579- };
580-
581 client_geometries[client_name_1] =
582 geom::Rectangle{{0, 0}, {1, 1}};
583
584@@ -502,45 +648,17 @@
585 EXPECT_CALL(cursor, hide())
586 .WillOnce(mt::WakeUp(&expectations_satisfied));
587
588- client.run();
589+ client.configure_cursor();
590
591 EXPECT_TRUE(wait.wait_for(timeout));
592
593- expectations_satisfied.wait_for(std::chrono::seconds{5});
594+ expectations_satisfied.wait_for(timeout);
595
596 expect_client_shutdown();
597 }
598
599-TEST_F(TestClientCursorAPI, cursor_request_applied_from_buffer_stream)
600+TEST_F(ClientCursor, from_buffer_stream_is_applied)
601 {
602- using namespace ::testing;
603-
604- static int hotspot_x = 1, hotspot_y = 1;
605-
606- struct BufferStreamClient : CursorClient
607- {
608- using CursorClient::CursorClient;
609-
610- void setup_cursor(MirWindow* window) override
611- {
612- auto stream = mir_connection_create_buffer_stream_sync(
613- connection, 24, 24, mir_pixel_format_argb_8888,
614- mir_buffer_usage_software);
615- auto conf = mir_cursor_configuration_from_buffer_stream(stream, hotspot_x, hotspot_y);
616-
617- mir_buffer_stream_swap_buffers_sync(stream);
618-
619- mir_window_configure_cursor(window, conf);
620-
621- mir_cursor_configuration_destroy(conf);
622-
623- mir_buffer_stream_swap_buffers_sync(stream);
624- mir_buffer_stream_swap_buffers_sync(stream);
625-
626- mir_buffer_stream_release_sync(stream);
627- }
628- };
629-
630 client_geometries[client_name_1] =
631 geom::Rectangle{{0, 0}, {1, 1}};
632
633@@ -553,93 +671,53 @@
634 .WillOnce(mt::WakeUp(&expectations_satisfied));
635 }
636
637- mt::Signal wait;
638-
639- EXPECT_CALL(*mock_surface_observer, cursor_image_set_to(_))
640- .WillRepeatedly(mt::WakeUp(&wait));
641-
642- client.run();
643-
644- EXPECT_TRUE(wait.wait_for(timeout));
645-
646- expectations_satisfied.wait_for(std::chrono::seconds{500});
647+ mt::Signal cursor_image_set;
648+
649+ {
650+ InSequence seq;
651+ EXPECT_CALL(*mock_surface_observer, cursor_image_set_to(_)).Times(2);
652+ EXPECT_CALL(*mock_surface_observer, cursor_image_set_to(_))
653+ .WillOnce(mt::WakeUp(&cursor_image_set));
654+ }
655+
656+ client.configure_cursor();
657+
658+ EXPECT_TRUE(cursor_image_set.wait_for(timeout));
659+
660+ expectations_satisfied.wait_for(60s);
661
662 expect_client_shutdown();
663 }
664
665-TEST_F(TestClientCursorAPI, cursor_request_applied_from_surface)
666+TEST_F(ClientCursor, from_a_surface_config_is_applied)
667 {
668- using namespace ::testing;
669-
670- static int hotspot_x = 1, hotspot_y = 1;
671-
672 client_geometries[client_name_1] =
673 geom::Rectangle{{0, 0}, {1, 1}};
674
675+ SurfaceCursorConfigClient client{new_connection(), client_name_1};
676+
677 {
678 InSequence seq;
679- EXPECT_CALL(cursor, show(_)).Times(3);
680+ EXPECT_CALL(cursor, show(_)).Times(2);
681 EXPECT_CALL(cursor, show(_)).Times(1)
682 .WillOnce(mt::WakeUp(&expectations_satisfied));
683 }
684
685- mt::Signal wait;
686-
687- EXPECT_CALL(*mock_surface_observer, cursor_image_set_to(_))
688- .WillRepeatedly(mt::WakeUp(&wait));
689-
690- auto connection =
691- mir_connect_sync(new_connection().c_str(), client_name_1.c_str());
692- auto spec = mir_create_normal_window_spec(connection, 1, 1);
693- mir_window_spec_set_pixel_format(spec, mir_pixel_format_abgr_8888);
694- mir_window_spec_set_name(spec, client_name_1.c_str());
695- auto const window = mir_create_window_sync(spec);
696- mir_window_spec_release(spec);
697-
698- mir_buffer_stream_swap_buffers_sync(
699- mir_window_get_buffer_stream(window));
700-
701- auto ret = mt::spin_wait_for_condition_or_timeout(
702- [window]
703- {
704- return mir_window_get_visibility(window) == mir_window_visibility_exposed &&
705- mir_window_get_focus_state(window) == mir_window_focus_state_focused;
706- },
707- std::chrono::seconds{5});
708-
709- if (!ret)
710- throw std::runtime_error("Timeout waiting for window to become focused and exposed");
711-
712-#pragma GCC diagnostic push
713-#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
714- auto surface =
715- mir_connection_create_render_surface_sync(connection, 24, 24);
716- auto stream =
717- mir_render_surface_get_buffer_stream(surface, 24, 24, mir_pixel_format_argb_8888);
718- auto conf =
719- mir_cursor_configuration_from_render_surface(surface, hotspot_x, hotspot_y);
720-#pragma GCC diagnostic pop
721-
722- mir_buffer_stream_swap_buffers_sync(stream);
723-
724- mir_window_configure_cursor(window, conf);
725-
726- mir_cursor_configuration_destroy(conf);
727-
728- mir_buffer_stream_swap_buffers_sync(stream);
729- mir_buffer_stream_swap_buffers_sync(stream);
730-
731-#pragma GCC diagnostic push
732-#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
733- mir_render_surface_release(surface);
734-#pragma GCC diagnostic pop
735-
736- mir_window_release_sync(window);
737- mir_connection_release(connection);
738-
739- EXPECT_TRUE(wait.wait_for(timeout));
740-
741- expectations_satisfied.wait_for(std::chrono::seconds{5});
742+ mt::Signal cursor_image_set;
743+
744+ {
745+ InSequence seq;
746+ EXPECT_CALL(*mock_surface_observer, cursor_image_set_to(_)).Times(2);
747+ EXPECT_CALL(*mock_surface_observer, cursor_image_set_to(_))
748+ .WillOnce(mt::WakeUp(&cursor_image_set));
749+ }
750+
751+ client.configure_cursor();
752+
753+ EXPECT_TRUE(cursor_image_set.wait_for(timeout));
754+
755+ expectations_satisfied.wait_for(60s);
756+
757 expect_client_shutdown();
758 }
759
760@@ -652,29 +730,23 @@
761 {
762 using CursorClient::CursorClient;
763
764- void setup_cursor(MirWindow* window) override
765+ void configure_cursor() override
766 {
767 // Workaround race condition (lp:1525003). I've tried, but I've not
768 // found a better way to ensure that the host Mir server is "ready"
769 // for the test logic. - alan_g
770- std::this_thread::sleep_for(std::chrono::milliseconds(20));
771+ std::this_thread::sleep_for(20ms);
772
773 mir_window_set_state(window, mir_window_state_fullscreen);
774-#pragma GCC diagnostic push
775-#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
776- auto conf = mir_cursor_configuration_from_name(mir_disabled_cursor_name);
777-#pragma GCC diagnostic pop
778- mir_window_configure_cursor(window, conf);
779- mir_cursor_configuration_destroy(conf);
780+ CursorConfiguration conf{mir_disabled_cursor_name};
781+ conf.apply(window);
782 }
783 };
784
785 }
786
787-TEST_F(TestClientCursorAPI, cursor_passed_through_nested_server)
788+TEST_F(ClientCursor, passes_through_nested_server)
789 {
790- using namespace ::testing;
791-
792 mtf::HeadlessNestedServerRunner nested_mir(new_connection());
793 nested_mir.start_server();
794
795@@ -690,13 +762,13 @@
796 .Times(1)
797 .WillOnce(mt::WakeUp(&wait));
798
799- client.run();
800+ client.configure_cursor();
801
802 EXPECT_TRUE(wait.wait_for(timeout));
803
804- expectations_satisfied.wait_for(std::chrono::seconds{60});
805+ expectations_satisfied.wait_for(60s);
806 expect_client_shutdown();
807 }
808-
809+
810 nested_mir.stop_server();
811 }

Subscribers

People subscribed via source and target branches