• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2015 Collabora, Ltd.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining
5  * a copy of this software and associated documentation files (the
6  * "Software"), to deal in the Software without restriction, including
7  * without limitation the rights to use, copy, modify, merge, publish,
8  * distribute, sublicense, and/or sell copies of the Software, and to
9  * permit persons to whom the Software is furnished to do so, subject to
10  * the following conditions:
11  *
12  * The above copyright notice and this permission notice (including the
13  * next paragraph) shall be included in all copies or substantial
14  * portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19  * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
20  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
21  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23  * SOFTWARE.
24  */
25 
26 #include "config.h"
27 
28 #include <stdint.h>
29 #include <stdio.h>
30 #include <string.h>
31 
32 #include "shared/helpers.h"
33 #include "shared/xalloc.h"
34 #include "weston-test-client-helper.h"
35 #include "ivi-application-client-protocol.h"
36 #include "ivi-test.h"
37 #include "weston-test-fixture-compositor.h"
38 
39 static enum test_result_code
fixture_setup(struct weston_test_harness * harness)40 fixture_setup(struct weston_test_harness *harness)
41 {
42 	struct compositor_setup setup;
43 
44 	compositor_setup_defaults(&setup);
45 	setup.shell = SHELL_IVI;
46 	setup.extra_module = "test-ivi-layout.so";
47 
48 	return weston_test_harness_execute_as_client(harness, &setup);
49 }
50 DECLARE_FIXTURE_SETUP(fixture_setup);
51 
52 struct runner {
53 	struct client *client;
54 	struct weston_test_runner *test_runner;
55 	int done;
56 };
57 
58 static void
runner_finished_handler(void * data,struct weston_test_runner * test_runner)59 runner_finished_handler(void *data, struct weston_test_runner *test_runner)
60 {
61 	struct runner *runner = data;
62 
63 	runner->done = 1;
64 }
65 
66 static const struct weston_test_runner_listener test_runner_listener = {
67 	runner_finished_handler
68 };
69 
70 static struct runner *
client_create_runner(struct client * client)71 client_create_runner(struct client *client)
72 {
73 	struct runner *runner;
74 	struct global *g;
75 	struct global *global_runner = NULL;
76 
77 	runner = xzalloc(sizeof(*runner));
78 	runner->client = client;
79 
80 	wl_list_for_each(g, &client->global_list, link) {
81 		if (strcmp(g->interface, "weston_test_runner"))
82 			continue;
83 
84 		if (global_runner)
85 			assert(0 && "multiple weston_test_runner objects");
86 
87 		global_runner = g;
88 	}
89 
90 	assert(global_runner && "no weston_test_runner found");
91 	assert(global_runner->version == 1);
92 
93 	runner->test_runner = wl_registry_bind(client->wl_registry,
94 					       global_runner->name,
95 					       &weston_test_runner_interface,
96 					       1);
97 	assert(runner->test_runner);
98 
99 	weston_test_runner_add_listener(runner->test_runner,
100 					&test_runner_listener, runner);
101 
102 	return runner;
103 }
104 
105 static void
runner_destroy(struct runner * runner)106 runner_destroy(struct runner *runner)
107 {
108 	weston_test_runner_destroy(runner->test_runner);
109 	client_roundtrip(runner->client);
110 	free(runner);
111 }
112 
113 static void
runner_run(struct runner * runner,const char * test_name)114 runner_run(struct runner *runner, const char *test_name)
115 {
116 	testlog("weston_test_runner.run(\"%s\")\n", test_name);
117 
118 	runner->done = 0;
119 	weston_test_runner_run(runner->test_runner, test_name);
120 
121 	while (!runner->done) {
122 		if (wl_display_dispatch(runner->client->wl_display) < 0)
123 			assert(0 && "runner wait");
124 	}
125 }
126 
127 static struct ivi_application *
get_ivi_application(struct client * client)128 get_ivi_application(struct client *client)
129 {
130 	struct global *g;
131 	struct global *global_iviapp = NULL;
132 	struct ivi_application *iviapp;
133 
134 	wl_list_for_each(g, &client->global_list, link) {
135 		if (strcmp(g->interface, "ivi_application"))
136 			continue;
137 
138 		if (global_iviapp)
139 			assert(0 && "multiple ivi_application objects");
140 
141 		global_iviapp = g;
142 	}
143 
144 	assert(global_iviapp && "no ivi_application found");
145 
146 	assert(global_iviapp->version == 1);
147 
148 	iviapp = wl_registry_bind(client->wl_registry, global_iviapp->name,
149 				  &ivi_application_interface, 1);
150 	assert(iviapp);
151 
152 	return iviapp;
153 }
154 
155 struct ivi_window {
156 	struct wl_surface *wl_surface;
157 	struct ivi_surface *ivi_surface;
158 	uint32_t ivi_id;
159 };
160 
161 static struct ivi_window *
client_create_ivi_window(struct client * client,struct ivi_application * iviapp,uint32_t ivi_id)162 client_create_ivi_window(struct client *client,
163 			 struct ivi_application *iviapp,
164 			 uint32_t ivi_id)
165 {
166 	struct ivi_window *wnd;
167 
168 	wnd = xzalloc(sizeof(*wnd));
169 	wnd->wl_surface = wl_compositor_create_surface(client->wl_compositor);
170 	wnd->ivi_surface = ivi_application_surface_create(iviapp, ivi_id,
171 							  wnd->wl_surface);
172 	wnd->ivi_id = ivi_id;
173 
174 	return wnd;
175 }
176 
177 static void
ivi_window_destroy(struct ivi_window * wnd)178 ivi_window_destroy(struct ivi_window *wnd)
179 {
180 	ivi_surface_destroy(wnd->ivi_surface);
181 	wl_surface_destroy(wnd->wl_surface);
182 	free(wnd);
183 }
184 
185 /******************************** tests ********************************/
186 
187 /*
188  * These tests make use of weston_test_runner global interface exposed by
189  * ivi-layout-test-plugin.c. This allows these tests to trigger compositor-side
190  * checks.
191  *
192  * See ivi-layout-test-plugin.c for further details.
193  */
194 
195 /**
196  * RUNNER_TEST() names are defined in ivi-layout-test-plugin.c.
197  * Each RUNNER_TEST name listed here uses the same simple initial client setup.
198  */
199 const char * const basic_test_names[] = {
200 	"surface_visibility",
201 	"surface_opacity",
202 	"surface_dimension",
203 	"surface_position",
204 	"surface_destination_rectangle",
205 	"surface_source_rectangle",
206 	"surface_bad_opacity",
207 	"surface_properties_changed_notification",
208 	"surface_bad_properties_changed_notification",
209 	"surface_on_many_layer",
210 };
211 
212 const char * const surface_property_commit_changes_test_names[] = {
213 	"commit_changes_after_visibility_set_surface_destroy",
214 	"commit_changes_after_opacity_set_surface_destroy",
215 	"commit_changes_after_source_rectangle_set_surface_destroy",
216 	"commit_changes_after_destination_rectangle_set_surface_destroy",
217 };
218 
219 const char * const render_order_test_names[] = {
220 	"layer_render_order",
221 	"layer_bad_render_order",
222 	"layer_add_surfaces",
223 };
224 
TEST_P(ivi_layout_runner,basic_test_names)225 TEST_P(ivi_layout_runner, basic_test_names)
226 {
227 	/* an element from basic_test_names */
228 	const char * const *test_name = data;
229 	struct client *client;
230 	struct runner *runner;
231 	struct ivi_application *iviapp;
232 	struct ivi_window *wnd;
233 
234 	client = create_client();
235 	runner = client_create_runner(client);
236 	iviapp = get_ivi_application(client);
237 
238 	wnd = client_create_ivi_window(client, iviapp, IVI_TEST_SURFACE_ID(0));
239 
240 	runner_run(runner, *test_name);
241 
242 	ivi_window_destroy(wnd);
243 	runner_destroy(runner);
244 }
245 
TEST(ivi_layout_surface_create)246 TEST(ivi_layout_surface_create)
247 {
248 	struct client *client;
249 	struct runner *runner;
250 	struct ivi_application *iviapp;
251 	struct ivi_window *winds[2];
252 
253 	client = create_client();
254 	runner = client_create_runner(client);
255 	iviapp = get_ivi_application(client);
256 
257 	winds[0] = client_create_ivi_window(client, iviapp,
258 					    IVI_TEST_SURFACE_ID(0));
259 	winds[1] = client_create_ivi_window(client, iviapp,
260 					    IVI_TEST_SURFACE_ID(1));
261 
262 	runner_run(runner, "surface_create_p1");
263 
264 	ivi_window_destroy(winds[0]);
265 
266 	runner_run(runner, "surface_create_p2");
267 
268 	ivi_window_destroy(winds[1]);
269 	runner_destroy(runner);
270 }
271 
TEST_P(commit_changes_after_properties_set_surface_destroy,surface_property_commit_changes_test_names)272 TEST_P(commit_changes_after_properties_set_surface_destroy, surface_property_commit_changes_test_names)
273 {
274 	/* an element from surface_property_commit_changes_test_names */
275 	const char * const *test_name = data;
276 	struct client *client;
277 	struct runner *runner;
278 	struct ivi_application *iviapp;
279 	struct ivi_window *wnd;
280 
281 	client = create_client();
282 	runner = client_create_runner(client);
283 	iviapp = get_ivi_application(client);
284 
285 	wnd = client_create_ivi_window(client, iviapp, IVI_TEST_SURFACE_ID(0));
286 
287 	runner_run(runner, *test_name);
288 
289 	ivi_window_destroy(wnd);
290 
291 	runner_run(runner, "ivi_layout_commit_changes");
292 
293 	runner_destroy(runner);
294 }
295 
TEST(get_surface_after_destroy_ivi_surface)296 TEST(get_surface_after_destroy_ivi_surface)
297 {
298 	struct client *client;
299 	struct runner *runner;
300 	struct ivi_application *iviapp;
301 	struct ivi_window *wnd;
302 
303 	client = create_client();
304 	runner = client_create_runner(client);
305 	iviapp = get_ivi_application(client);
306 
307 	wnd = client_create_ivi_window(client, iviapp, IVI_TEST_SURFACE_ID(0));
308 
309 	ivi_surface_destroy(wnd->ivi_surface);
310 
311 	runner_run(runner, "get_surface_after_destroy_surface");
312 
313 	wl_surface_destroy(wnd->wl_surface);
314 	free(wnd);
315 	runner_destroy(runner);
316 }
317 
TEST(get_surface_after_destroy_wl_surface)318 TEST(get_surface_after_destroy_wl_surface)
319 {
320 	struct client *client;
321 	struct runner *runner;
322 	struct ivi_application *iviapp;
323 	struct ivi_window *wnd;
324 
325 	client = create_client();
326 	runner = client_create_runner(client);
327 	iviapp = get_ivi_application(client);
328 
329 	wnd = client_create_ivi_window(client, iviapp, IVI_TEST_SURFACE_ID(0));
330 
331 	wl_surface_destroy(wnd->wl_surface);
332 
333 	runner_run(runner, "get_surface_after_destroy_surface");
334 
335 	ivi_surface_destroy(wnd->ivi_surface);
336 	free(wnd);
337 	runner_destroy(runner);
338 }
339 
TEST_P(ivi_layout_layer_render_order_runner,render_order_test_names)340 TEST_P(ivi_layout_layer_render_order_runner, render_order_test_names)
341 {
342 	/* an element from render_order_test_names */
343 	const char * const *test_name = data;
344 	struct client *client;
345 	struct runner *runner;
346 	struct ivi_application *iviapp;
347 	struct ivi_window *winds[3];
348 
349 	client = create_client();
350 	runner = client_create_runner(client);
351 	iviapp = get_ivi_application(client);
352 
353 	winds[0] = client_create_ivi_window(client, iviapp,
354 					    IVI_TEST_SURFACE_ID(0));
355 	winds[1] = client_create_ivi_window(client, iviapp,
356 					    IVI_TEST_SURFACE_ID(1));
357 	winds[2] = client_create_ivi_window(client, iviapp,
358 					    IVI_TEST_SURFACE_ID(2));
359 
360 	runner_run(runner, *test_name);
361 
362 	ivi_window_destroy(winds[0]);
363 	ivi_window_destroy(winds[1]);
364 	ivi_window_destroy(winds[2]);
365 	runner_destroy(runner);
366 }
367 
TEST(destroy_surface_after_layer_render_order)368 TEST(destroy_surface_after_layer_render_order)
369 {
370 	struct client *client;
371 	struct runner *runner;
372 	struct ivi_application *iviapp;
373 	struct ivi_window *winds[3];
374 
375 	client = create_client();
376 	runner = client_create_runner(client);
377 	iviapp = get_ivi_application(client);
378 
379 	winds[0] = client_create_ivi_window(client, iviapp,
380 					    IVI_TEST_SURFACE_ID(0));
381 	winds[1] = client_create_ivi_window(client, iviapp,
382 					    IVI_TEST_SURFACE_ID(1));
383 	winds[2] = client_create_ivi_window(client, iviapp,
384 					    IVI_TEST_SURFACE_ID(2));
385 
386 	runner_run(runner, "test_layer_render_order_destroy_one_surface_p1");
387 
388 	ivi_window_destroy(winds[1]);
389 
390 	runner_run(runner, "test_layer_render_order_destroy_one_surface_p2");
391 
392 	ivi_window_destroy(winds[0]);
393 	ivi_window_destroy(winds[2]);
394 	runner_destroy(runner);
395 }
396 
TEST(commit_changes_after_render_order_set_surface_destroy)397 TEST(commit_changes_after_render_order_set_surface_destroy)
398 {
399 	struct client *client;
400 	struct runner *runner;
401 	struct ivi_application *iviapp;
402 	struct ivi_window *winds[3];
403 
404 	client = create_client();
405 	runner = client_create_runner(client);
406 	iviapp = get_ivi_application(client);
407 
408 	winds[0] = client_create_ivi_window(client, iviapp,
409 					    IVI_TEST_SURFACE_ID(0));
410 	winds[1] = client_create_ivi_window(client, iviapp,
411 					    IVI_TEST_SURFACE_ID(1));
412 	winds[2] = client_create_ivi_window(client, iviapp,
413 					    IVI_TEST_SURFACE_ID(2));
414 
415 	runner_run(runner, "commit_changes_after_render_order_set_surface_destroy");
416 
417 	ivi_window_destroy(winds[1]);
418 
419 	runner_run(runner, "ivi_layout_commit_changes");
420 	runner_run(runner, "cleanup_layer");
421 
422 	ivi_window_destroy(winds[0]);
423 	ivi_window_destroy(winds[2]);
424 	runner_destroy(runner);
425 }
426 
TEST(ivi_layout_surface_configure_notification)427 TEST(ivi_layout_surface_configure_notification)
428 {
429 	struct client *client;
430 	struct runner *runner;
431 	struct ivi_application *iviapp;
432 	struct ivi_window *wind;
433 	struct buffer *buffer;
434 
435 	client = create_client();
436 	runner = client_create_runner(client);
437 	iviapp = get_ivi_application(client);
438 
439 	runner_run(runner, "surface_configure_notification_p1");
440 
441 	wind = client_create_ivi_window(client, iviapp, IVI_TEST_SURFACE_ID(0));
442 
443 	buffer = create_shm_buffer_a8r8g8b8(client, 200, 300);
444 
445 	wl_surface_attach(wind->wl_surface, buffer->proxy, 0, 0);
446 	wl_surface_damage(wind->wl_surface, 0, 0, 20, 30);
447 	wl_surface_commit(wind->wl_surface);
448 
449 	runner_run(runner, "surface_configure_notification_p2");
450 
451 	wl_surface_attach(wind->wl_surface, buffer->proxy, 0, 0);
452 	wl_surface_damage(wind->wl_surface, 0, 0, 40, 50);
453 	wl_surface_commit(wind->wl_surface);
454 
455 	runner_run(runner, "surface_configure_notification_p3");
456 
457 	buffer_destroy(buffer);
458 	ivi_window_destroy(wind);
459 	runner_destroy(runner);
460 }
461 
TEST(ivi_layout_surface_create_notification)462 TEST(ivi_layout_surface_create_notification)
463 {
464 	struct client *client;
465 	struct runner *runner;
466 	struct ivi_application *iviapp;
467 	struct ivi_window *wind;
468 
469 	client = create_client();
470 	runner = client_create_runner(client);
471 	iviapp = get_ivi_application(client);
472 
473 	runner_run(runner, "surface_create_notification_p1");
474 
475 	wind = client_create_ivi_window(client, iviapp, IVI_TEST_SURFACE_ID(0));
476 
477 	runner_run(runner, "surface_create_notification_p2");
478 
479 	ivi_window_destroy(wind);
480 	wind = client_create_ivi_window(client, iviapp, IVI_TEST_SURFACE_ID(0));
481 	runner_run(runner, "surface_create_notification_p3");
482 
483 	ivi_window_destroy(wind);
484 	runner_destroy(runner);
485 }
486 
TEST(ivi_layout_surface_remove_notification)487 TEST(ivi_layout_surface_remove_notification)
488 {
489 	struct client *client;
490 	struct runner *runner;
491 	struct ivi_application *iviapp;
492 	struct ivi_window *wind;
493 
494 	client = create_client();
495 	runner = client_create_runner(client);
496 	iviapp = get_ivi_application(client);
497 
498 	wind = client_create_ivi_window(client, iviapp, IVI_TEST_SURFACE_ID(0));
499 	runner_run(runner, "surface_remove_notification_p1");
500 	ivi_window_destroy(wind);
501 
502 	runner_run(runner, "surface_remove_notification_p2");
503 
504 	wind = client_create_ivi_window(client, iviapp, IVI_TEST_SURFACE_ID(0));
505 	ivi_window_destroy(wind);
506 	runner_run(runner, "surface_remove_notification_p3");
507 
508 	runner_destroy(runner);
509 }
510