• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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