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