Merge lp:~albaguirre/mir/tidy-up-client-cursor-tests into lp:mir
- tidy-up-client-cursor-tests
- Merge into development-branch
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 |
Related bugs: |
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.
Description of the change
To post a comment you must log in.
Revision history for this message
Mir CI Bot (mir-ci-bot) wrote : | # |
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 | } |
PASSED: Continuous integration, rev:4143 /mir-jenkins. ubuntu. com/job/ mir-ci/ 3342/ /mir-jenkins. ubuntu. com/job/ build-mir/ 4514 /mir-jenkins. ubuntu. com/job/ build-0- fetch/4632 /mir-jenkins. ubuntu. com/job/ build-1- sourcepkg/ release= vivid+overlay/ 4621 /mir-jenkins. ubuntu. com/job/ build-1- sourcepkg/ release= xenial/ 4621 /mir-jenkins. ubuntu. com/job/ build-1- sourcepkg/ release= xenial+ overlay/ 4621 /mir-jenkins. ubuntu. com/job/ build-1- sourcepkg/ release= zesty/4621 /mir-jenkins. ubuntu. com/job/ build-2- binpkg- mir/arch= amd64,compiler= clang,platform= mesa,release= zesty/4545 /mir-jenkins. ubuntu. com/job/ build-2- binpkg- mir/arch= amd64,compiler= clang,platform= mesa,release= zesty/4545/ artifact/ output/ *zip*/output. zip /mir-jenkins. ubuntu. com/job/ build-2- binpkg- mir/arch= amd64,compiler= gcc,platform= mesa,release= xenial+ overlay/ 4545 /mir-jenkins. ubuntu. com/job/ build-2- binpkg- mir/arch= amd64,compiler= gcc,platform= mesa,release= xenial+ overlay/ 4545/artifact/ output/ *zip*/output. zip /mir-jenkins. ubuntu. com/job/ build-2- binpkg- mir/arch= amd64,compiler= gcc,platform= mesa,release= zesty/4545 /mir-jenkins. ubuntu. com/job/ build-2- binpkg- mir/arch= amd64,compiler= gcc,platform= mesa,release= zesty/4545/ artifact/ output/ *zip*/output. zip /mir-jenkins. ubuntu. com/job/ build-2- binpkg- mir/arch= cross-armhf, compiler= gcc,platform= android, release= vivid+overlay/ 4545 /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 /mir-jenkins. ubuntu. com/job/ build-2- binpkg- mir/arch= i386,compiler= gcc,platform= android, release= vivid+overlay/ 4545 /mir-jenkins. ubuntu. com/job/ build-2- binpkg- mir/arch= i386,compiler= gcc,platform= android, release= vivid+overlay/ 4545/artifact/ output/ *zip*/output. zip /mir-jenkins. ubuntu. com/job/ build-2- binpkg- mir/arch= i386,compiler= gcc,platform= mesa,release= xenial+ overlay/ 4545 /mir-jenkins. ubuntu. com/job/ build-2- binpkg- mir/arch= i386,compiler= gcc,platform= mesa,release= xenial+ overlay/ 4545/artifact/ output/ *zip*/output. zip
https:/
Executed test runs:
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
Click here to trigger a rebuild: /mir-jenkins. ubuntu. com/job/ mir-ci/ 3342/rebuild
https:/