1 /*
2 * Copyright (C) 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <assert.h>
18 #include <err.h>
19 #include <lib/trusty/event.h>
20 #include <lib/trusty/handle_set.h>
21 #include <lib/trusty/ipc_msg.h>
22 #include <lib/trusty/uuid.h>
23 #include <lib/unittest/unittest.h>
24
25 #include <trace.h>
26
27 #define EXPECTED_TO_FAIL_TIMEOUT_MSEC 1000
28 #define NOT_EXPECTED_TO_FAIL_TIMEOUT_MSEC (30000)
29
30 #define MAX_EVT_CNT 100
31 #define TEST_EVS_NAME1 "com.android.trusty.test-uevent-source1"
32 #define TEST_EVS_NAME2 "com.android.trusty.test-uevent-source2"
33 #define TEST_EVT_NAME1 "com.android.trusty.test-uevent-client1"
34 #define TEST_EVT_NAME2 "com.android.trusty.test-uevent-client2"
35
36 typedef struct uirq {
37 struct handle* hset;
38 struct handle* hevts;
39 struct handle* hevt1;
40 struct handle* hevt2;
41 struct handle_ref hevts_ref;
42 struct handle_ref hevt1_ref;
43 struct handle_ref hevt2_ref;
44 } uirq_t;
45
TEST_F_SETUP(uirq)46 TEST_F_SETUP(uirq) {
47 memset(_state, 0, sizeof(*_state));
48 }
49
TEST_F_TEARDOWN(uirq)50 TEST_F_TEARDOWN(uirq) {
51 if (_state->hevts_ref.handle) {
52 handle_set_detach_ref(&_state->hevts_ref);
53 }
54
55 if (_state->hevt1_ref.handle) {
56 handle_set_detach_ref(&_state->hevt1_ref);
57 }
58
59 if (_state->hevt2_ref.handle) {
60 handle_set_detach_ref(&_state->hevt2_ref);
61 }
62
63 if (_state->hevts) {
64 handle_close(_state->hevts);
65 }
66
67 if (_state->hevt1) {
68 handle_close(_state->hevt1);
69 }
70
71 if (_state->hevt2) {
72 handle_close(_state->hevt2);
73 }
74
75 if (_state->hset) {
76 handle_close(_state->hset);
77 }
78 }
79
TEST_F(uirq,event_source_create_invalid)80 TEST_F(uirq, event_source_create_invalid) {
81 int rc;
82
83 rc = event_source_create(NULL, NULL, NULL, NULL, 0, 0, &_state->hevts);
84 ASSERT_EQ(ERR_INVALID_ARGS, rc);
85
86 rc = event_source_create("", NULL, NULL, NULL, 0, 0, &_state->hevts);
87 ASSERT_EQ(ERR_INVALID_ARGS, rc);
88 test_abort:;
89 }
90
TEST_F(uirq,event_source_create_close)91 TEST_F(uirq, event_source_create_close) {
92 int rc;
93 uint32_t cnt;
94
95 /* create/close named event 10000 times */
96 for (cnt = 0; cnt < 10000; cnt++) {
97 rc = event_source_create(TEST_EVS_NAME1, NULL, NULL, NULL, 0, 0,
98 &_state->hevts);
99 ASSERT_EQ(0, rc);
100
101 /* then close it */
102 handle_close(_state->hevts);
103 _state->hevts = NULL;
104 }
105 test_abort:;
106 }
107
TEST_F(uirq,event_source_create_existing)108 TEST_F(uirq, event_source_create_existing) {
109 int rc;
110 struct handle* h = NULL;
111
112 /* create named event */
113 rc = event_source_create(TEST_EVS_NAME1, NULL, NULL, NULL, 0, 0,
114 &_state->hevts);
115 ASSERT_EQ(0, rc);
116
117 /* then publish it */
118 rc = event_source_publish(_state->hevts);
119 ASSERT_EQ(0, rc);
120
121 /* try to create event with the same name again */
122 rc = event_source_create(TEST_EVS_NAME1, NULL, NULL, NULL, 0, 0, &h);
123 ASSERT_EQ(0, rc);
124
125 /* then publish it */
126 rc = event_source_publish(h);
127 EXPECT_EQ(ERR_ALREADY_EXISTS, rc);
128
129 if (h) {
130 handle_close(h);
131 }
132
133 test_abort:;
134 }
135
TEST_F(uirq,event_source_wait_no_clients)136 TEST_F(uirq, event_source_wait_no_clients) {
137 int rc;
138 uint32_t uevt;
139
140 /* create named event */
141 rc = event_source_create(TEST_EVS_NAME1, NULL, NULL, NULL, 0, 0,
142 &_state->hevts);
143 ASSERT_EQ(0, rc);
144
145 rc = handle_wait(_state->hevts, &uevt, EXPECTED_TO_FAIL_TIMEOUT_MSEC);
146 EXPECT_EQ(ERR_TIMED_OUT, rc, "wait on created event");
147
148 rc = event_source_signal(_state->hevts);
149 EXPECT_EQ(0, rc, "signal event");
150
151 /* event without clients becomes ready */
152 rc = handle_wait(_state->hevts, &uevt, NOT_EXPECTED_TO_FAIL_TIMEOUT_MSEC);
153 EXPECT_EQ(0, rc, "wait on signaled event");
154
155 /* do it again: it should time out */
156 rc = handle_wait(_state->hevts, &uevt, EXPECTED_TO_FAIL_TIMEOUT_MSEC);
157 EXPECT_EQ(ERR_TIMED_OUT, rc, "wait on created event");
158
159 rc = event_source_signal(_state->hevts);
160 EXPECT_EQ(0, rc, "signal event");
161
162 rc = handle_wait(_state->hevts, &uevt, NOT_EXPECTED_TO_FAIL_TIMEOUT_MSEC);
163 EXPECT_EQ(0, rc, "wait on created event");
164
165 test_abort:;
166 }
167
TEST_F(uirq,event_client_open_invalid)168 TEST_F(uirq, event_client_open_invalid) {
169 int rc;
170 struct uuid cid = zero_uuid;
171
172 /* open named event with NULL name */
173 rc = event_source_open(&cid, NULL, 0, 0, &_state->hevt1);
174 ASSERT_EQ(ERR_INVALID_ARGS, rc);
175
176 /* open named event with empty name */
177 rc = event_source_open(&cid, "", 1, 0, &_state->hevt1);
178 ASSERT_EQ(ERR_INVALID_ARGS, rc);
179
180 /* open non-existing named event */
181 rc = event_source_open(&cid, TEST_EVS_NAME1, strlen(TEST_EVS_NAME1) + 1, 0,
182 &_state->hevt1);
183 ASSERT_EQ(ERR_NOT_FOUND, rc);
184
185 test_abort:;
186 }
187
TEST_F(uirq,event_client_open_close)188 TEST_F(uirq, event_client_open_close) {
189 int rc;
190 struct uuid cid = zero_uuid;
191
192 /* create named event source */
193 rc = event_source_create(TEST_EVS_NAME1, NULL, NULL, NULL, 0, 0,
194 &_state->hevts);
195 ASSERT_EQ(0, rc);
196
197 rc = event_source_publish(_state->hevts);
198 ASSERT_EQ(0, rc);
199
200 /* open/close the same named event 10000 times */
201 for (int i = 0; i < 10000; i++) {
202 rc = event_source_open(&cid, TEST_EVS_NAME1, strlen(TEST_EVS_NAME1) + 1,
203 0, &_state->hevt1);
204 ASSERT_EQ(0, rc);
205
206 handle_close(_state->hevt1);
207 _state->hevt1 = NULL;
208 }
209
210 test_abort:;
211 }
212
TEST_F(uirq,event_client_wait_single)213 TEST_F(uirq, event_client_wait_single) {
214 int rc;
215 uint32_t uevt;
216 struct handle_ref ref;
217 struct uuid cid = zero_uuid;
218
219 /* create handle set */
220 _state->hset = handle_set_create();
221
222 /* create named event source */
223 rc = event_source_create(TEST_EVS_NAME1, NULL, NULL, NULL, 0, 0,
224 &_state->hevts);
225 ASSERT_EQ(0, rc);
226
227 rc = event_source_publish(_state->hevts);
228 ASSERT_EQ(0, rc);
229
230 /* open the same named event */
231 rc = event_source_open(&cid, TEST_EVS_NAME1, strlen(TEST_EVS_NAME1) + 1, 0,
232 &_state->hevt1);
233 ASSERT_EQ(0, rc);
234
235 /* wait on unsignaled event: should timeout */
236 rc = handle_wait(_state->hevt1, &uevt, EXPECTED_TO_FAIL_TIMEOUT_MSEC);
237 EXPECT_EQ(ERR_TIMED_OUT, rc, "wait on client");
238
239 /* signal event */
240 rc = event_source_signal(_state->hevts);
241 EXPECT_EQ(0, rc, "notify event signaled");
242
243 /* wait on signaled event: should return as it is signaled */
244 rc = handle_wait(_state->hevt1, &uevt, NOT_EXPECTED_TO_FAIL_TIMEOUT_MSEC);
245 EXPECT_EQ(0, rc, "wait on client");
246
247 /* wait on event source: should timeout as we have not notified */
248 rc = handle_wait(_state->hevts, &uevt, EXPECTED_TO_FAIL_TIMEOUT_MSEC);
249 EXPECT_EQ(ERR_TIMED_OUT, rc, "wait on source");
250
251 /* notify that event is handled to put source into handled state */
252 rc = event_client_notify_handled(_state->hevt1);
253 EXPECT_EQ(0, rc, "notify event handled");
254
255 /* wait on event source again: should return as event is handled */
256 rc = handle_wait(_state->hevts, &uevt, NOT_EXPECTED_TO_FAIL_TIMEOUT_MSEC);
257 EXPECT_EQ(0, rc, "wait on source");
258
259 /* Check handle sets: add both events to handle set */
260 memset(&_state->hevts_ref, 0, sizeof(_state->hevts_ref));
261 _state->hevts_ref.handle = _state->hevts;
262 _state->hevts_ref.emask = ~0U;
263 _state->hevts_ref.cookie = NULL;
264 rc = handle_set_attach(_state->hset, &_state->hevts_ref);
265 ASSERT_EQ(0, rc);
266
267 memset(&_state->hevt1_ref, 0, sizeof(_state->hevt1_ref));
268 _state->hevt1_ref.handle = _state->hevt1;
269 _state->hevt1_ref.emask = ~0U;
270 _state->hevt1_ref.cookie = NULL;
271 rc = handle_set_attach(_state->hset, &_state->hevt1_ref);
272 ASSERT_EQ(0, rc);
273
274 /* trigger and handle event MAX_EVT_CNT times */
275 uint32_t cnt = MAX_EVT_CNT;
276 rc = event_source_signal(_state->hevts);
277 ASSERT_EQ(0, rc, "notify event signaled");
278 while (cnt) {
279 rc = handle_set_wait(_state->hset, &ref,
280 NOT_EXPECTED_TO_FAIL_TIMEOUT_MSEC);
281 ASSERT_EQ(0, rc, "wait any");
282
283 if (ref.handle) {
284 /* dec ref obtained by handle_set_wait */
285 handle_decref(ref.handle);
286 }
287
288 if (ref.handle == _state->hevt1) {
289 cnt--;
290 rc = event_client_notify_handled(_state->hevt1);
291 ASSERT_EQ(0, rc, "notify event handled");
292 } else if (ref.handle == _state->hevts) {
293 rc = event_source_signal(_state->hevts);
294 ASSERT_EQ(0, rc, "notify event signaled");
295 } else {
296 break;
297 }
298 }
299 EXPECT_EQ(0, cnt, "event counter");
300
301 test_abort:;
302 }
303
TEST_F(uirq,event_client_wait_multiple)304 TEST_F(uirq, event_client_wait_multiple) {
305 int rc;
306 struct handle_ref ref;
307 struct uuid cid = zero_uuid;
308
309 /* create handle set */
310 _state->hset = handle_set_create();
311
312 /* create named event source */
313 rc = event_source_create(TEST_EVS_NAME1, NULL, NULL, NULL, 0, 0,
314 &_state->hevts);
315 ASSERT_EQ(0, rc);
316
317 rc = event_source_publish(_state->hevts);
318 ASSERT_EQ(0, rc);
319
320 /* open named event */
321 rc = event_source_open(&cid, TEST_EVS_NAME1, strlen(TEST_EVS_NAME1) + 1, 0,
322 &_state->hevt1);
323 ASSERT_EQ(0, rc);
324
325 /* open the same named event */
326 rc = event_source_open(&cid, TEST_EVS_NAME1, strlen(TEST_EVS_NAME1) + 1, 0,
327 &_state->hevt2);
328 ASSERT_EQ(0, rc);
329
330 /* Add all handles to handle set */
331 memset(&_state->hevts_ref, 0, sizeof(_state->hevts_ref));
332 _state->hevts_ref.handle = _state->hevts;
333 _state->hevts_ref.emask = ~0U;
334 _state->hevts_ref.cookie = NULL;
335 rc = handle_set_attach(_state->hset, &_state->hevts_ref);
336 ASSERT_EQ(0, rc);
337
338 memset(&_state->hevt1_ref, 0, sizeof(_state->hevt1_ref));
339 _state->hevt1_ref.handle = _state->hevt1;
340 _state->hevt1_ref.emask = ~0U;
341 _state->hevt1_ref.cookie = NULL;
342 rc = handle_set_attach(_state->hset, &_state->hevt1_ref);
343 ASSERT_EQ(0, rc);
344
345 memset(&_state->hevt2_ref, 0, sizeof(_state->hevt2_ref));
346 _state->hevt2_ref.handle = _state->hevt2;
347 _state->hevt2_ref.emask = ~0U;
348 _state->hevt2_ref.cookie = NULL;
349 rc = handle_set_attach(_state->hset, &_state->hevt2_ref);
350 ASSERT_EQ(0, rc);
351
352 /* trigger and handle event MAX_EVT_CNT times */
353 uint32_t evts_cnt = 0;
354 uint32_t evt1_cnt = 0;
355 uint32_t evt2_cnt = 0;
356
357 rc = event_source_signal(_state->hevts);
358 ASSERT_EQ(0, rc, "notify event signaled");
359 evts_cnt++;
360 for (;;) {
361 rc = handle_set_wait(_state->hset, &ref,
362 NOT_EXPECTED_TO_FAIL_TIMEOUT_MSEC);
363 ASSERT_EQ(0, rc, "wait any");
364
365 if (ref.handle) {
366 /* dec ref obtained by handle_set_wait */
367 handle_decref(ref.handle);
368 }
369
370 if (ref.handle == _state->hevts) {
371 if (evts_cnt == MAX_EVT_CNT)
372 break;
373 rc = event_source_signal(_state->hevts);
374 ASSERT_EQ(0, rc, "notify event signaled");
375 evts_cnt++;
376 } else if (ref.handle == _state->hevt1) {
377 evt1_cnt++;
378 rc = event_client_notify_handled(_state->hevt1);
379 ASSERT_EQ(0, rc, "notify event handled");
380 } else if (ref.handle == _state->hevt2) {
381 evt2_cnt++;
382 rc = event_client_notify_handled(_state->hevt2);
383 ASSERT_EQ(0, rc, "notify event handled");
384 } else {
385 break;
386 }
387 }
388 EXPECT_EQ(MAX_EVT_CNT, evts_cnt, "evts count");
389 EXPECT_EQ(MAX_EVT_CNT, evt1_cnt, "evt1 count");
390 EXPECT_EQ(MAX_EVT_CNT, evt2_cnt, "evt2 count");
391
392 test_abort:;
393 }
394
TEST_F(uirq,event_client_open_signaled)395 TEST_F(uirq, event_client_open_signaled) {
396 int rc;
397 uint32_t uevt;
398 struct uuid cid = zero_uuid;
399
400 /* create named event source */
401 rc = event_source_create(TEST_EVS_NAME1, NULL, NULL, NULL, 0, 0,
402 &_state->hevts);
403 ASSERT_EQ(0, rc);
404
405 rc = event_source_publish(_state->hevts);
406 ASSERT_EQ(0, rc);
407
408 /* open the named event */
409 rc = event_source_open(&cid, TEST_EVS_NAME1, strlen(TEST_EVS_NAME1) + 1, 0,
410 &_state->hevt1);
411 ASSERT_EQ(0, rc);
412
413 /* signal event */
414 rc = event_source_signal(_state->hevts);
415 EXPECT_EQ(0, rc, "notify event signaled");
416
417 /* open named event again */
418 rc = event_source_open(&cid, TEST_EVS_NAME1, strlen(TEST_EVS_NAME1) + 1, 0,
419 &_state->hevt2);
420 ASSERT_EQ(0, rc);
421
422 /* wait on client 1: should be signaled */
423 rc = handle_wait(_state->hevt1, &uevt, NOT_EXPECTED_TO_FAIL_TIMEOUT_MSEC);
424 EXPECT_EQ(0, rc, "wait on client1");
425
426 /* wait on client 2: should timeout as it should not be signaled */
427 rc = handle_wait(_state->hevt2, &uevt, EXPECTED_TO_FAIL_TIMEOUT_MSEC);
428 EXPECT_EQ(ERR_TIMED_OUT, rc, "wait on source");
429
430 /* wait on event source: should timeout: event is not handled */
431 rc = handle_wait(_state->hevts, &uevt, EXPECTED_TO_FAIL_TIMEOUT_MSEC);
432 EXPECT_EQ(ERR_TIMED_OUT, rc, "wait on source");
433
434 /* notify that event1 is handled: to put it in unsignaled state */
435 rc = event_client_notify_handled(_state->hevt1);
436 EXPECT_EQ(0, rc, "notify event handled");
437
438 /* wait on event source again: should return as event is handled */
439 rc = handle_wait(_state->hevts, &uevt, NOT_EXPECTED_TO_FAIL_TIMEOUT_MSEC);
440 EXPECT_EQ(0, rc, "wait on source");
441
442 /* signal event again: now both events must ack */
443 rc = event_source_signal(_state->hevts);
444 EXPECT_EQ(0, rc, "notify event signaled");
445
446 /* wait on client 1: should be signaled */
447 rc = handle_wait(_state->hevt1, &uevt, NOT_EXPECTED_TO_FAIL_TIMEOUT_MSEC);
448 EXPECT_EQ(0, rc, "wait on client1");
449
450 /* wait on client 2: should be signaled */
451 rc = handle_wait(_state->hevt2, &uevt, NOT_EXPECTED_TO_FAIL_TIMEOUT_MSEC);
452 EXPECT_EQ(0, rc, "wait on client2");
453
454 /* notify that event1 is handled */
455 rc = event_client_notify_handled(_state->hevt1);
456 EXPECT_EQ(0, rc, "notify event handled");
457
458 /* notify that event2 is handled */
459 rc = event_client_notify_handled(_state->hevt2);
460 EXPECT_EQ(0, rc, "notify event handled");
461
462 /* wait on event source again: should be handled */
463 rc = handle_wait(_state->hevts, &uevt, NOT_EXPECTED_TO_FAIL_TIMEOUT_MSEC);
464 EXPECT_EQ(0, rc, "wait on source");
465
466 test_abort:;
467 }
468
TEST_F(uirq,event_source_resignal_signaled)469 TEST_F(uirq, event_source_resignal_signaled) {
470 int rc;
471 uint32_t uevt;
472 struct uuid cid = zero_uuid;
473
474 /* create named event source */
475 rc = event_source_create(TEST_EVS_NAME1, NULL, NULL, NULL, 0, 0,
476 &_state->hevts);
477 ASSERT_EQ(0, rc);
478
479 rc = event_source_publish(_state->hevts);
480 ASSERT_EQ(0, rc);
481
482 /* open the named event */
483 rc = event_source_open(&cid, TEST_EVS_NAME1, strlen(TEST_EVS_NAME1) + 1, 0,
484 &_state->hevt1);
485 ASSERT_EQ(0, rc);
486
487 /* open named event again */
488 rc = event_source_open(&cid, TEST_EVS_NAME1, strlen(TEST_EVS_NAME1) + 1, 0,
489 &_state->hevt2);
490 ASSERT_EQ(0, rc);
491
492 /* signal event */
493 rc = event_source_signal(_state->hevts);
494 EXPECT_EQ(0, rc, "notify event signaled");
495
496 /* signal event again */
497 rc = event_source_signal(_state->hevts);
498 EXPECT_EQ(0, rc, "notify event signaled");
499
500 /* wait on client 1: should be signaled */
501 rc = handle_wait(_state->hevt1, &uevt, NOT_EXPECTED_TO_FAIL_TIMEOUT_MSEC);
502 EXPECT_EQ(0, rc, "wait on client1");
503
504 /* wait on client 2: should be signaled */
505 rc = handle_wait(_state->hevt2, &uevt, NOT_EXPECTED_TO_FAIL_TIMEOUT_MSEC);
506 EXPECT_EQ(0, rc, "wait on client2");
507
508 /* notify that event1 is handled */
509 rc = event_client_notify_handled(_state->hevt1);
510 EXPECT_EQ(0, rc, "notify event handled");
511
512 /* notify that event2 is handled */
513 rc = event_client_notify_handled(_state->hevt2);
514 EXPECT_EQ(0, rc, "notify event handled");
515
516 /* wait on event source: should be handled */
517 rc = handle_wait(_state->hevts, &uevt, NOT_EXPECTED_TO_FAIL_TIMEOUT_MSEC);
518 EXPECT_EQ(0, rc, "wait on source");
519
520 test_abort:;
521 }
522
TEST_F(uirq,event_source_resignal_notified)523 TEST_F(uirq, event_source_resignal_notified) {
524 int rc;
525 uint32_t uevt;
526 struct uuid cid = zero_uuid;
527
528 /* create named event source */
529 rc = event_source_create(TEST_EVS_NAME1, NULL, NULL, NULL, 0, 0,
530 &_state->hevts);
531 ASSERT_EQ(0, rc);
532
533 rc = event_source_publish(_state->hevts);
534 ASSERT_EQ(0, rc);
535
536 /* open the named event */
537 rc = event_source_open(&cid, TEST_EVS_NAME1, strlen(TEST_EVS_NAME1) + 1, 0,
538 &_state->hevt1);
539 ASSERT_EQ(0, rc);
540
541 /* open named event again */
542 rc = event_source_open(&cid, TEST_EVS_NAME1, strlen(TEST_EVS_NAME1) + 1, 0,
543 &_state->hevt2);
544 ASSERT_EQ(0, rc);
545
546 /* signal event */
547 rc = event_source_signal(_state->hevts);
548 EXPECT_EQ(0, rc, "notify event signaled");
549
550 /* wait on client 1: to put it into notifieed state */
551 rc = handle_wait(_state->hevt1, &uevt, NOT_EXPECTED_TO_FAIL_TIMEOUT_MSEC);
552 EXPECT_EQ(0, rc, "wait on client1");
553
554 /* signal event again */
555 rc = event_source_signal(_state->hevts);
556 EXPECT_EQ(0, rc, "notify event signaled");
557
558 /* notify that event1 is handled: it should enter signaled state */
559 rc = event_client_notify_handled(_state->hevt1);
560 EXPECT_EQ(0, rc, "notify event handled");
561
562 /* wait on client 2: should be signaled */
563 rc = handle_wait(_state->hevt2, &uevt, NOT_EXPECTED_TO_FAIL_TIMEOUT_MSEC);
564 EXPECT_EQ(0, rc, "wait on client2");
565
566 /* notify that event2 is handled to put it into unsignaled state */
567 rc = event_client_notify_handled(_state->hevt2);
568 EXPECT_EQ(0, rc, "notify event handled");
569
570 /* wait on event source: should timeout as event1 stil signaled */
571 rc = handle_wait(_state->hevts, &uevt, EXPECTED_TO_FAIL_TIMEOUT_MSEC);
572 EXPECT_EQ(ERR_TIMED_OUT, rc, "wait on source");
573
574 /* wait on client 1: should be signaled */
575 rc = handle_wait(_state->hevt1, &uevt, NOT_EXPECTED_TO_FAIL_TIMEOUT_MSEC);
576 EXPECT_EQ(0, rc, "wait on client1");
577
578 /* notify that event1 is handled to put it into unsignaled state */
579 rc = event_client_notify_handled(_state->hevt1);
580 EXPECT_EQ(0, rc, "notify event handled");
581
582 /* wait on event source: should be handled */
583 rc = handle_wait(_state->hevts, &uevt, NOT_EXPECTED_TO_FAIL_TIMEOUT_MSEC);
584 EXPECT_EQ(0, rc, "wait on source");
585
586 test_abort:;
587 }
588
TEST_F(uirq,event_source_resignal_handled)589 TEST_F(uirq, event_source_resignal_handled) {
590 int rc;
591 uint32_t uevt;
592 struct uuid cid = zero_uuid;
593
594 /* create named event source */
595 rc = event_source_create(TEST_EVS_NAME1, NULL, NULL, NULL, 0, 0,
596 &_state->hevts);
597 ASSERT_EQ(0, rc);
598
599 rc = event_source_publish(_state->hevts);
600 ASSERT_EQ(0, rc);
601
602 /* open the named event */
603 rc = event_source_open(&cid, TEST_EVS_NAME1, strlen(TEST_EVS_NAME1) + 1, 0,
604 &_state->hevt1);
605 ASSERT_EQ(0, rc);
606
607 /* open named event again */
608 rc = event_source_open(&cid, TEST_EVS_NAME1, strlen(TEST_EVS_NAME1) + 1, 0,
609 &_state->hevt2);
610 ASSERT_EQ(0, rc);
611
612 /* signal event */
613 rc = event_source_signal(_state->hevts);
614 EXPECT_EQ(0, rc, "notify event signaled");
615
616 /* wait on client 1: to put it into notified state */
617 rc = handle_wait(_state->hevt1, &uevt, NOT_EXPECTED_TO_FAIL_TIMEOUT_MSEC);
618 EXPECT_EQ(0, rc, "wait on client1");
619
620 /* notify that event1 is handled to put it into unsignaled state */
621 rc = event_client_notify_handled(_state->hevt1);
622 EXPECT_EQ(0, rc, "notify event handled");
623
624 /* signal event again to put event 1 into signaled state */
625 rc = event_source_signal(_state->hevts);
626 EXPECT_EQ(0, rc, "notify event signaled");
627
628 /* wait on client 2: should be in signaled state */
629 rc = handle_wait(_state->hevt2, &uevt, NOT_EXPECTED_TO_FAIL_TIMEOUT_MSEC);
630 EXPECT_EQ(0, rc, "wait on client2");
631
632 /* notify that event2 is handled to put it into unsignaled state */
633 rc = event_client_notify_handled(_state->hevt2);
634 EXPECT_EQ(0, rc, "notify event handled");
635
636 /* wait on event source: should timeout as event1 still signaled */
637 rc = handle_wait(_state->hevts, &uevt, EXPECTED_TO_FAIL_TIMEOUT_MSEC);
638 EXPECT_EQ(ERR_TIMED_OUT, rc, "wait on source");
639
640 /* wait on client 1: to put it into notified state */
641 rc = handle_wait(_state->hevt1, &uevt, NOT_EXPECTED_TO_FAIL_TIMEOUT_MSEC);
642 EXPECT_EQ(0, rc, "wait on client1");
643
644 /* notify that event1 is handled to put it into unsignaled state */
645 rc = event_client_notify_handled(_state->hevt1);
646 EXPECT_EQ(0, rc, "notify event handled");
647
648 /* wait on event source: should be in handled */
649 rc = handle_wait(_state->hevts, &uevt, NOT_EXPECTED_TO_FAIL_TIMEOUT_MSEC);
650 EXPECT_EQ(0, rc, "wait on source");
651
652 test_abort:;
653 }
654
TEST_F(uirq,event_source_close)655 TEST_F(uirq, event_source_close) {
656 int rc;
657 uint32_t uevt;
658 struct uuid cid = zero_uuid;
659
660 /* create named event source */
661 rc = event_source_create(TEST_EVS_NAME1, NULL, NULL, NULL, 0, 0,
662 &_state->hevts);
663 ASSERT_EQ(0, rc);
664
665 rc = event_source_publish(_state->hevts);
666 ASSERT_EQ(0, rc);
667
668 /* open the named event */
669 rc = event_source_open(&cid, TEST_EVS_NAME1, strlen(TEST_EVS_NAME1) + 1, 0,
670 &_state->hevt1);
671 ASSERT_EQ(0, rc);
672
673 /* close sevent source */
674 handle_close(_state->hevts);
675 _state->hevts = NULL;
676
677 /* wait on closed client: should return HUP event */
678 rc = handle_wait(_state->hevt1, &uevt, NOT_EXPECTED_TO_FAIL_TIMEOUT_MSEC);
679 EXPECT_EQ(0, rc, "wait on source");
680 EXPECT_EQ(1, !!(uevt & IPC_HANDLE_POLL_HUP));
681
682 /* Invoke notify on client with closed source */
683 rc = event_client_notify_handled(_state->hevt1);
684 EXPECT_EQ(ERR_CHANNEL_CLOSED, rc, "notify event handled");
685
686 test_abort:;
687 }
688
TEST_F(uirq,event_client_close_signaled)689 TEST_F(uirq, event_client_close_signaled) {
690 int rc;
691 uint32_t uevt;
692 struct uuid cid = zero_uuid;
693
694 /* create named event source */
695 rc = event_source_create(TEST_EVS_NAME1, NULL, NULL, NULL, 0, 0,
696 &_state->hevts);
697 ASSERT_EQ(0, rc);
698
699 rc = event_source_publish(_state->hevts);
700 ASSERT_EQ(0, rc);
701
702 /* open the named event */
703 rc = event_source_open(&cid, TEST_EVS_NAME1, strlen(TEST_EVS_NAME1) + 1, 0,
704 &_state->hevt1);
705 ASSERT_EQ(0, rc);
706
707 /* signal event */
708 rc = event_source_signal(_state->hevts);
709 EXPECT_EQ(0, rc, "notify event signaled");
710
711 /* close signaled event */
712 handle_close(_state->hevt1);
713 _state->hevt1 = NULL;
714
715 /* wait on event source: should not block */
716 rc = handle_wait(_state->hevts, &uevt, NOT_EXPECTED_TO_FAIL_TIMEOUT_MSEC);
717 EXPECT_EQ(0, rc, "wait on source");
718
719 test_abort:;
720 }
721
TEST_F(uirq,event_client_close_notified)722 TEST_F(uirq, event_client_close_notified) {
723 int rc;
724 uint32_t uevt;
725 struct uuid cid = zero_uuid;
726
727 /* create named event source */
728 rc = event_source_create(TEST_EVS_NAME1, NULL, NULL, NULL, 0, 0,
729 &_state->hevts);
730 ASSERT_EQ(0, rc);
731
732 rc = event_source_publish(_state->hevts);
733 ASSERT_EQ(0, rc);
734
735 /* open the named event */
736 rc = event_source_open(&cid, TEST_EVS_NAME1, strlen(TEST_EVS_NAME1) + 1, 0,
737 &_state->hevt1);
738 ASSERT_EQ(0, rc);
739
740 /* signal event */
741 rc = event_source_signal(_state->hevts);
742 EXPECT_EQ(0, rc, "notify event signaled");
743
744 /* wait on client 1: to put it into notified state */
745 rc = handle_wait(_state->hevt1, &uevt, NOT_EXPECTED_TO_FAIL_TIMEOUT_MSEC);
746 EXPECT_EQ(0, rc, "wait on client1");
747
748 /* close client */
749 handle_close(_state->hevt1);
750 _state->hevt1 = NULL;
751
752 /* wait on event source: should not block */
753 rc = handle_wait(_state->hevts, &uevt, NOT_EXPECTED_TO_FAIL_TIMEOUT_MSEC);
754 EXPECT_EQ(0, rc, "wait on source");
755
756 test_abort:;
757 }
758
TEST_F(uirq,event_client_close_notified_signaled)759 TEST_F(uirq, event_client_close_notified_signaled) {
760 int rc;
761 uint32_t uevt;
762 struct uuid cid = zero_uuid;
763
764 /* create named event source */
765 rc = event_source_create(TEST_EVS_NAME1, NULL, NULL, NULL, 0, 0,
766 &_state->hevts);
767 ASSERT_EQ(0, rc);
768
769 rc = event_source_publish(_state->hevts);
770 ASSERT_EQ(0, rc);
771
772 /* open the named event */
773 rc = event_source_open(&cid, TEST_EVS_NAME1, strlen(TEST_EVS_NAME1) + 1, 0,
774 &_state->hevt1);
775 ASSERT_EQ(0, rc);
776
777 /* signal event */
778 rc = event_source_signal(_state->hevts);
779 EXPECT_EQ(0, rc, "notify event signaled");
780
781 /* wait on client 1: to put it into notified state */
782 rc = handle_wait(_state->hevt1, &uevt, NOT_EXPECTED_TO_FAIL_TIMEOUT_MSEC);
783 EXPECT_EQ(0, rc, "wait on client1");
784
785 /* signal event to put it intonotified signaled state */
786 rc = event_source_signal(_state->hevts);
787 EXPECT_EQ(0, rc, "notify event signaled");
788
789 /* close client */
790 handle_close(_state->hevt1);
791 _state->hevt1 = NULL;
792
793 /* wait on event source: should not block */
794 rc = handle_wait(_state->hevts, &uevt, NOT_EXPECTED_TO_FAIL_TIMEOUT_MSEC);
795 EXPECT_EQ(0, rc, "wait on source");
796
797 test_abort:;
798 }
799
TEST_F(uirq,event_client_ack_unread)800 TEST_F(uirq, event_client_ack_unread) {
801 int rc;
802 uint32_t uevt;
803 struct uuid cid = zero_uuid;
804
805 /* create named event source */
806 rc = event_source_create(TEST_EVS_NAME1, NULL, NULL, NULL, 0, 0,
807 &_state->hevts);
808 ASSERT_EQ(0, rc);
809
810 rc = event_source_publish(_state->hevts);
811 ASSERT_EQ(0, rc);
812
813 /* open the named event */
814 rc = event_source_open(&cid, TEST_EVS_NAME1, strlen(TEST_EVS_NAME1) + 1, 0,
815 &_state->hevt1);
816 ASSERT_EQ(0, rc);
817
818 /* signal event */
819 rc = event_source_signal(_state->hevts);
820 EXPECT_EQ(0, rc, "notify event signaled");
821
822 /*
823 * Notify that event1 is handled: should error because we need to wait on
824 * event first
825 */
826 rc = event_client_notify_handled(_state->hevt1);
827 EXPECT_EQ(ERR_BAD_STATE, rc, "notify event handled");
828
829 /* wait on client 1: to put it into notifird state */
830 rc = handle_wait(_state->hevt1, &uevt, NOT_EXPECTED_TO_FAIL_TIMEOUT_MSEC);
831 EXPECT_EQ(0, rc, "wait on client1");
832
833 /* notify that event1 is handled: should be OK */
834 rc = event_client_notify_handled(_state->hevt1);
835 EXPECT_EQ(0, rc, "notify event handled");
836
837 test_abort:;
838 }
839
TEST_F(uirq,event_client_wait_on_notified_signaled)840 TEST_F(uirq, event_client_wait_on_notified_signaled) {
841 int rc;
842 uint32_t uevt;
843 struct uuid cid = zero_uuid;
844
845 /* create named event source */
846 rc = event_source_create(TEST_EVS_NAME1, NULL, NULL, NULL, 0, 0,
847 &_state->hevts);
848 ASSERT_EQ(0, rc);
849
850 rc = event_source_publish(_state->hevts);
851 ASSERT_EQ(0, rc);
852
853 /* open the named event */
854 rc = event_source_open(&cid, TEST_EVS_NAME1, strlen(TEST_EVS_NAME1) + 1, 0,
855 &_state->hevt1);
856 ASSERT_EQ(0, rc);
857
858 /* signal event */
859 rc = event_source_signal(_state->hevts);
860 EXPECT_EQ(0, rc, "notify event signaled");
861
862 /* wait on client 1: should be signaled: enters notified state */
863 rc = handle_wait(_state->hevt1, &uevt, NOT_EXPECTED_TO_FAIL_TIMEOUT_MSEC);
864 EXPECT_EQ(0, rc, "wait on client1");
865
866 /* signal event again to put is into notified signaled state */
867 rc = event_source_signal(_state->hevts);
868 EXPECT_EQ(0, rc, "notify event signaled");
869
870 /* wait on client 1: should timeout as it is in notified signaled state */
871 rc = handle_wait(_state->hevt1, &uevt, EXPECTED_TO_FAIL_TIMEOUT_MSEC);
872 EXPECT_EQ(ERR_TIMED_OUT, rc, "wait on client1");
873
874 /*
875 * notify that event1 is handled: shoudl be OK: puts event into signaled
876 * state
877 */
878 rc = event_client_notify_handled(_state->hevt1);
879 EXPECT_EQ(0, rc, "notify event handled");
880
881 /* wait on client 1: should be signaled as it is in signaled state */
882 rc = handle_wait(_state->hevt1, &uevt, NOT_EXPECTED_TO_FAIL_TIMEOUT_MSEC);
883 EXPECT_EQ(0, rc, "wait on client1");
884
885 /* notify that event1 is handled to put source into handled state */
886 rc = event_client_notify_handled(_state->hevt1);
887 EXPECT_EQ(0, rc, "notify event handled");
888
889 /* wait on event source: should be in handled state */
890 rc = handle_wait(_state->hevts, &uevt, NOT_EXPECTED_TO_FAIL_TIMEOUT_MSEC);
891 EXPECT_EQ(0, rc, "wait on source");
892
893 test_abort:;
894 }
895
896 PORT_TEST(uirq, "com.android.kernel.uirq-unittest");
897