source: mainline/uspace/lib/display/test/display.c@ dcac756

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since dcac756 was dcac756, checked in by Jiri Svoboda <jiri@…>, 6 years ago

Improve libdisplay tests, fix bugs

  • Property mode set to 100644
File size: 12.1 KB
Line 
1/*
2 * Copyright (c) 2019 Jiri Svoboda
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include <async.h>
30#include <errno.h>
31#include <display.h>
32#include <disp_srv.h>
33#include <gfx/color.h>
34#include <gfx/context.h>
35#include <gfx/render.h>
36#include <ipcgfx/server.h>
37#include <loc.h>
38#include <pcut/pcut.h>
39
40PCUT_INIT;
41
42PCUT_TEST_SUITE(display);
43
44static const char *test_display_server = "test-display";
45static const char *test_display_svc = "test/display";
46
47static void test_display_conn(ipc_call_t *, void *);
48static void test_kbd_event(void *, kbd_event_t *);
49
50static errno_t test_window_create(void *, sysarg_t *);
51static errno_t test_window_destroy(void *, sysarg_t);
52static errno_t test_get_event(void *, sysarg_t *, display_wnd_ev_t *);
53
54static errno_t test_gc_set_color(void *, gfx_color_t *);
55
56static display_ops_t test_display_srv_ops = {
57 .window_create = test_window_create,
58 .window_destroy = test_window_destroy,
59 .get_event = test_get_event
60};
61
62static display_wnd_cb_t test_display_wnd_cb = {
63 .kbd_event = test_kbd_event
64};
65
66static gfx_context_ops_t test_gc_ops = {
67 .set_color = test_gc_set_color
68};
69
70/** Describes to the server how to respond to our request and pass tracking
71 * data back to the client.
72 */
73typedef struct {
74 errno_t rc;
75 sysarg_t wnd_id;
76 display_wnd_ev_t event;
77 bool window_create_called;
78 bool window_destroy_called;
79 bool get_event_called;
80 bool set_color_called;
81 display_srv_t *srv;
82} test_response_t;
83
84/** display_open(), display_close() work for valid display service */
85PCUT_TEST(open_close)
86{
87 errno_t rc;
88 service_id_t sid;
89 display_t *disp = NULL;
90 test_response_t resp;
91
92 async_set_fallback_port_handler(test_display_conn, &resp);
93
94 // FIXME This causes this test to be non-reentrant!
95 rc = loc_server_register(test_display_server);
96 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
97
98 rc = loc_service_register(test_display_svc, &sid);
99 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
100
101 rc = display_open(test_display_svc, &disp);
102 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
103 PCUT_ASSERT_NOT_NULL(disp);
104
105 display_close(disp);
106 rc = loc_service_unregister(sid);
107 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
108}
109
110/** display_window_create() with server returning error response works */
111PCUT_TEST(window_create_failure)
112{
113 errno_t rc;
114 service_id_t sid;
115 display_t *disp = NULL;
116 display_window_t *wnd;
117 test_response_t resp;
118
119 async_set_fallback_port_handler(test_display_conn, &resp);
120
121 // FIXME This causes this test to be non-reentrant!
122 rc = loc_server_register(test_display_server);
123 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
124
125 rc = loc_service_register(test_display_svc, &sid);
126 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
127
128 rc = display_open(test_display_svc, &disp);
129 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
130 PCUT_ASSERT_NOT_NULL(disp);
131
132 wnd = NULL;
133 resp.rc = ENOMEM;
134 resp.window_create_called = false;
135 rc = display_window_create(disp, &test_display_wnd_cb, NULL, &wnd);
136 PCUT_ASSERT_TRUE(resp.window_create_called);
137 PCUT_ASSERT_ERRNO_VAL(resp.rc, rc);
138 PCUT_ASSERT_NULL(wnd);
139
140 display_close(disp);
141 rc = loc_service_unregister(sid);
142 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
143}
144
145/** display_window_create() and display_window_destroy() with success
146 *
147 * with server returning success,
148 */
149PCUT_TEST(window_create_destroy_success)
150{
151 errno_t rc;
152 service_id_t sid;
153 display_t *disp = NULL;
154 display_window_t *wnd;
155 test_response_t resp;
156
157 async_set_fallback_port_handler(test_display_conn, &resp);
158
159 // FIXME This causes this test to be non-reentrant!
160 rc = loc_server_register(test_display_server);
161 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
162
163 rc = loc_service_register(test_display_svc, &sid);
164 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
165
166 rc = display_open(test_display_svc, &disp);
167 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
168 PCUT_ASSERT_NOT_NULL(disp);
169
170 wnd = NULL;
171 resp.rc = EOK;
172 resp.window_create_called = false;
173 rc = display_window_create(disp, &test_display_wnd_cb, NULL, &wnd);
174 PCUT_ASSERT_TRUE(resp.window_create_called);
175 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
176 PCUT_ASSERT_NOT_NULL(wnd);
177
178 resp.window_destroy_called = false;
179 rc = display_window_destroy(wnd);
180 PCUT_ASSERT_TRUE(resp.window_destroy_called);
181 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
182
183 display_close(disp);
184 rc = loc_service_unregister(sid);
185 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
186}
187
188/** display_window_create() with server returning error response works. */
189PCUT_TEST(window_destroy_failure)
190{
191 errno_t rc;
192 service_id_t sid;
193 display_t *disp = NULL;
194 display_window_t *wnd;
195 test_response_t resp;
196
197 async_set_fallback_port_handler(test_display_conn, &resp);
198
199 // FIXME This causes this test to be non-reentrant!
200 rc = loc_server_register(test_display_server);
201 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
202
203 rc = loc_service_register(test_display_svc, &sid);
204 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
205
206 rc = display_open(test_display_svc, &disp);
207 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
208 PCUT_ASSERT_NOT_NULL(disp);
209
210 resp.rc = EOK;
211 resp.window_create_called = false;
212 rc = display_window_create(disp, &test_display_wnd_cb, NULL, &wnd);
213 PCUT_ASSERT_TRUE(resp.window_create_called);
214 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
215 PCUT_ASSERT_NOT_NULL(wnd);
216
217 resp.rc = EIO;
218 resp.window_destroy_called = false;
219 rc = display_window_destroy(wnd);
220 PCUT_ASSERT_TRUE(resp.window_destroy_called);
221 PCUT_ASSERT_ERRNO_VAL(resp.rc, rc);
222
223 display_close(disp);
224 rc = loc_service_unregister(sid);
225 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
226}
227
228/** display_window_get_gc with server returning failure */
229PCUT_TEST(window_get_gc_failure)
230{
231 errno_t rc;
232 service_id_t sid;
233 display_t *disp = NULL;
234 display_window_t *wnd;
235 test_response_t resp;
236 gfx_context_t *gc;
237
238 async_set_fallback_port_handler(test_display_conn, &resp);
239
240 // FIXME This causes this test to be non-reentrant!
241 rc = loc_server_register(test_display_server);
242 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
243
244 rc = loc_service_register(test_display_svc, &sid);
245 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
246
247 rc = display_open(test_display_svc, &disp);
248 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
249 PCUT_ASSERT_NOT_NULL(disp);
250
251 wnd = NULL;
252 resp.rc = EOK;
253 rc = display_window_create(disp, &test_display_wnd_cb, NULL, &wnd);
254 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
255 PCUT_ASSERT_NOT_NULL(wnd);
256
257 gc = NULL;
258 resp.rc = ENOMEM;
259 rc = display_window_get_gc(wnd, &gc);
260 /* async_connect_me_to() does not return specific error */
261 PCUT_ASSERT_ERRNO_VAL(EIO, rc);
262 PCUT_ASSERT_NULL(gc);
263
264 resp.rc = EOK;
265 rc = display_window_destroy(wnd);
266 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
267
268 display_close(disp);
269 rc = loc_service_unregister(sid);
270 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
271}
272
273/** display_window_get_gc with server returning success */
274PCUT_TEST(window_get_gc_success)
275{
276 errno_t rc;
277 service_id_t sid;
278 display_t *disp = NULL;
279 display_window_t *wnd;
280 test_response_t resp;
281 gfx_context_t *gc;
282 gfx_color_t *color;
283
284 async_set_fallback_port_handler(test_display_conn, &resp);
285
286 // FIXME This causes this test to be non-reentrant!
287 rc = loc_server_register(test_display_server);
288 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
289
290 rc = loc_service_register(test_display_svc, &sid);
291 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
292
293 rc = display_open(test_display_svc, &disp);
294 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
295 PCUT_ASSERT_NOT_NULL(disp);
296
297 wnd = NULL;
298 resp.rc = EOK;
299 rc = display_window_create(disp, &test_display_wnd_cb, NULL, &wnd);
300 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
301 PCUT_ASSERT_NOT_NULL(wnd);
302
303 gc = NULL;
304 rc = display_window_get_gc(wnd, &gc);
305 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
306 PCUT_ASSERT_NOT_NULL(gc);
307
308 rc = gfx_color_new_rgb_i16(0, 0, 0, &color);
309 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
310
311 resp.set_color_called = false;
312 rc = gfx_set_color(gc, color);
313 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
314 PCUT_ASSERT_TRUE(resp.set_color_called);
315
316 gfx_color_delete(color);
317
318 rc = display_window_destroy(wnd);
319 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
320
321 display_close(disp);
322 rc = loc_service_unregister(sid);
323 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
324}
325
326/** Keyboard event can be delivered from server to client callback function */
327#include <stdio.h>
328PCUT_TEST(kbd_event_deliver)
329{
330 errno_t rc;
331 service_id_t sid;
332 display_t *disp = NULL;
333 display_window_t *wnd;
334 test_response_t resp;
335 gfx_context_t *gc;
336
337 async_set_fallback_port_handler(test_display_conn, &resp);
338
339 // FIXME This causes this test to be non-reentrant!
340 rc = loc_server_register(test_display_server);
341 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
342
343 rc = loc_service_register(test_display_svc, &sid);
344 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
345
346 rc = display_open(test_display_svc, &disp);
347 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
348 PCUT_ASSERT_NOT_NULL(disp);
349 PCUT_ASSERT_NOT_NULL(resp.srv);
350
351 wnd = NULL;
352 resp.rc = EOK;
353 rc = display_window_create(disp, &test_display_wnd_cb, NULL, &wnd);
354 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
355 PCUT_ASSERT_NOT_NULL(wnd);
356
357 printf(" ** call display_window_get_gc\n");
358 gc = NULL;
359 rc = display_window_get_gc(wnd, &gc);
360 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
361 PCUT_ASSERT_NOT_NULL(gc);
362
363 printf(" ** call display_srv_ev_pending\n");
364 display_srv_ev_pending(resp.srv);
365
366 printf(" ** call display_window_destroy\n");
367 rc = display_window_destroy(wnd);
368 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
369
370 printf(" ** call display_close\n");
371 display_close(disp);
372 printf(" ** call loc_service_unregister\n");
373 rc = loc_service_unregister(sid);
374 PCUT_ASSERT_ERRNO_VAL(EOK, rc);
375}
376
377/** Test display service connection.
378 *
379 * This is very similar to connection handler in the display server.
380 * XXX This should be folded into display_srv, if possible
381 */
382static void test_display_conn(ipc_call_t *icall, void *arg)
383{
384 test_response_t *resp = (test_response_t *) arg;
385 display_srv_t srv;
386 sysarg_t wnd_id;
387 sysarg_t svc_id;
388 gfx_context_t *gc;
389 errno_t rc;
390
391 svc_id = ipc_get_arg2(icall);
392 wnd_id = ipc_get_arg3(icall);
393
394 if (svc_id != 0) {
395 /* Set up protocol structure */
396 display_srv_initialize(&srv);
397 srv.ops = &test_display_srv_ops;
398 srv.arg = arg;
399 resp->srv = &srv;
400
401 /* Handle connection */
402 display_conn(icall, &srv);
403
404 resp->srv = NULL;
405 } else {
406 (void) wnd_id;
407
408 if (resp->rc != EOK) {
409 async_answer_0(icall, resp->rc);
410 return;
411 }
412
413 rc = gfx_context_new(&test_gc_ops, arg, &gc);
414 if (rc != EOK) {
415 async_answer_0(icall, ENOMEM);
416 return;
417 }
418
419 /* Window GC connection */
420 gc_conn(icall, gc);
421 }
422}
423
424static void test_kbd_event(void *arg, kbd_event_t *event)
425{
426}
427
428static errno_t test_window_create(void *arg, sysarg_t *rwnd_id)
429{
430 test_response_t *resp = (test_response_t *) arg;
431
432 resp->window_create_called = true;
433 if (resp->rc == EOK)
434 *rwnd_id = resp->wnd_id;
435
436 return resp->rc;
437}
438
439static errno_t test_window_destroy(void *arg, sysarg_t wnd_id)
440{
441 test_response_t *resp = (test_response_t *) arg;
442
443 resp->window_destroy_called = true;
444 return resp->rc;
445}
446
447static errno_t test_get_event(void *arg, sysarg_t *wnd_id, display_wnd_ev_t *event)
448{
449 test_response_t *resp = (test_response_t *) arg;
450
451 resp->get_event_called = true;
452 if (resp->rc == EOK) {
453 *wnd_id = resp->wnd_id;
454 *event = resp->event;
455 }
456
457 return resp->rc;
458}
459
460static errno_t test_gc_set_color(void *arg, gfx_color_t *color)
461{
462 test_response_t *resp = (test_response_t *) arg;
463
464 resp->set_color_called = true;
465 return resp->rc;
466}
467
468PCUT_EXPORT(display);
Note: See TracBrowser for help on using the repository browser.