Line data Source code
1 : /*
2 : * Unix SMB/CIFS implementation.
3 : *
4 : * testing of some tevent_req aspects
5 : *
6 : * Copyright (C) Pavel Březina <pbrezina@redhat.com> 2021
7 : *
8 : * ** NOTE! The following LGPL license applies to the tevent
9 : * ** library. This does NOT imply that all of Samba is released
10 : * ** under the LGPL
11 : *
12 : * This library is free software; you can redistribute it and/or
13 : * modify it under the terms of the GNU Lesser General Public
14 : * License as published by the Free Software Foundation; either
15 : * version 3 of the License, or (at your option) any later version.
16 : *
17 : * This library is distributed in the hope that it will be useful,
18 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 : * Lesser General Public License for more details.
21 : *
22 : * You should have received a copy of the GNU Lesser General Public
23 : * License along with this library; if not, see <http://www.gnu.org/licenses/>.
24 : */
25 :
26 : #include <errno.h>
27 : #include <setjmp.h>
28 : #include <stdlib.h>
29 : #include <stdint.h>
30 : #include <signal.h>
31 : #include <unistd.h>
32 :
33 : #include <talloc.h>
34 : #include <tevent.h>
35 : #include <cmocka.h>
36 :
37 : struct test_ctx {
38 : struct tevent_context *ev;
39 :
40 : bool handler_skipped;
41 : bool reattach_reset;
42 :
43 : uint64_t (*get_tag)(const void *event);
44 : void (*set_tag)(void *event, uint64_t tag);
45 : uint64_t current_tag;
46 :
47 : bool attach;
48 : bool before_handler;
49 : bool handler_called;
50 : bool detach;
51 : };
52 :
53 1 : static void fd_handler(struct tevent_context *ev,
54 : struct tevent_fd *fde,
55 : uint16_t flags,
56 : void *private_data)
57 : {
58 1 : struct test_ctx *tctx = (struct test_ctx *)private_data;
59 1 : uint64_t tag = tevent_fd_get_tag(fde);
60 1 : assert_true(tctx->attach);
61 1 : assert_true(tctx->before_handler);
62 1 : assert_false(tctx->handler_called);
63 1 : assert_false(tctx->detach);
64 1 : tctx->handler_called = true;
65 1 : assert_int_equal(tag, tctx->current_tag);
66 1 : return;
67 : }
68 :
69 1 : static void timer_handler(struct tevent_context *ev,
70 : struct tevent_timer *te,
71 : struct timeval current_time,
72 : void *private_data)
73 : {
74 1 : struct test_ctx *tctx = (struct test_ctx *)private_data;
75 1 : uint64_t tag = tevent_timer_get_tag(te);
76 1 : assert_true(tctx->attach);
77 1 : assert_true(tctx->before_handler);
78 1 : assert_false(tctx->handler_called);
79 1 : assert_false(tctx->detach);
80 1 : tctx->handler_called = true;
81 1 : assert_int_equal(tag, tctx->current_tag);
82 1 : return;
83 : }
84 :
85 1 : static void signal_handler(struct tevent_context *ev,
86 : struct tevent_signal *se,
87 : int signum,
88 : int count,
89 : void *siginfo,
90 : void *private_data)
91 : {
92 1 : struct test_ctx *tctx = (struct test_ctx *)private_data;
93 1 : uint64_t tag = tevent_signal_get_tag(se);
94 1 : assert_true(tctx->attach);
95 1 : assert_true(tctx->before_handler);
96 1 : assert_false(tctx->handler_called);
97 1 : assert_false(tctx->detach);
98 1 : tctx->handler_called = true;
99 1 : assert_int_equal(tag, tctx->current_tag);
100 1 : return;
101 : }
102 :
103 2 : static void immediate_handler(struct tevent_context *ctx,
104 : struct tevent_immediate *im,
105 : void *private_data)
106 : {
107 2 : struct test_ctx *tctx = (struct test_ctx *)private_data;
108 2 : uint64_t tag = tevent_immediate_get_tag(im);
109 2 : assert_true(tctx->attach);
110 2 : assert_true(tctx->before_handler);
111 2 : assert_false(tctx->handler_called);
112 2 : assert_false(tctx->detach);
113 2 : tctx->handler_called = true;
114 2 : assert_int_equal(tag, tctx->current_tag);
115 2 : return;
116 : }
117 :
118 1 : static void immediate_handler_reschedule(struct tevent_context *ctx,
119 : struct tevent_immediate *im,
120 : void *private_data)
121 : {
122 1 : struct test_ctx *tctx = (struct test_ctx *)private_data;
123 1 : uint64_t tag = tevent_immediate_get_tag(im);
124 1 : assert_true(tctx->attach);
125 1 : assert_true(tctx->before_handler);
126 1 : assert_false(tctx->handler_called);
127 1 : assert_false(tctx->detach);
128 1 : tctx->handler_called = true;
129 1 : assert_int_equal(tag, tctx->current_tag);
130 :
131 1 : assert_false(tctx->reattach_reset);
132 1 : tctx->reattach_reset = true;
133 1 : tevent_schedule_immediate(im, tctx->ev, immediate_handler, tctx);
134 1 : assert_false(tctx->reattach_reset);
135 1 : assert_false(tctx->handler_skipped);
136 1 : assert_true(tctx->attach);
137 1 : assert_false(tctx->before_handler);
138 1 : assert_false(tctx->handler_called);
139 1 : assert_false(tctx->detach);
140 1 : assert_int_not_equal(tag, tctx->current_tag);
141 1 : tag = tevent_immediate_get_tag(im);
142 1 : assert_int_equal(tag, tctx->current_tag);
143 :
144 1 : tctx->handler_skipped = true;
145 1 : tctx->reattach_reset = true;
146 1 : tevent_schedule_immediate(im, tctx->ev, immediate_handler, tctx);
147 1 : assert_false(tctx->reattach_reset);
148 1 : assert_false(tctx->handler_skipped);
149 1 : assert_true(tctx->attach);
150 1 : assert_false(tctx->before_handler);
151 1 : assert_false(tctx->handler_called);
152 1 : assert_false(tctx->detach);
153 1 : assert_int_not_equal(tag, tctx->current_tag);
154 1 : tag = tevent_immediate_get_tag(im);
155 1 : assert_int_equal(tag, tctx->current_tag);
156 1 : }
157 :
158 1 : static void fd_handler_free(struct tevent_context *ev,
159 : struct tevent_fd *fde,
160 : uint16_t flags,
161 : void *private_data)
162 : {
163 1 : struct test_ctx *tctx = (struct test_ctx *)private_data;
164 1 : uint64_t tag = tevent_fd_get_tag(fde);
165 1 : assert_true(tctx->attach);
166 1 : assert_true(tctx->before_handler);
167 1 : assert_false(tctx->handler_called);
168 1 : assert_false(tctx->detach);
169 1 : tctx->handler_called = true;
170 1 : assert_int_equal(tag, tctx->current_tag);
171 1 : TALLOC_FREE(fde);
172 1 : assert_true(tctx->detach);
173 1 : return;
174 : }
175 :
176 1 : static void timer_handler_free(struct tevent_context *ev,
177 : struct tevent_timer *te,
178 : struct timeval current_time,
179 : void *private_data)
180 : {
181 1 : struct test_ctx *tctx = (struct test_ctx *)private_data;
182 1 : uint64_t tag = tevent_timer_get_tag(te);
183 1 : assert_true(tctx->attach);
184 1 : assert_true(tctx->before_handler);
185 1 : assert_false(tctx->handler_called);
186 1 : assert_false(tctx->detach);
187 1 : tctx->handler_called = true;
188 1 : assert_int_equal(tag, tctx->current_tag);
189 1 : TALLOC_FREE(te);
190 1 : assert_true(tctx->detach);
191 1 : return;
192 : }
193 :
194 1 : static void signal_handler_free(struct tevent_context *ev,
195 : struct tevent_signal *se,
196 : int signum,
197 : int count,
198 : void *siginfo,
199 : void *private_data)
200 : {
201 1 : struct test_ctx *tctx = (struct test_ctx *)private_data;
202 1 : uint64_t tag = tevent_signal_get_tag(se);
203 1 : assert_true(tctx->attach);
204 1 : assert_true(tctx->before_handler);
205 1 : assert_false(tctx->handler_called);
206 1 : assert_false(tctx->detach);
207 1 : tctx->handler_called = true;
208 1 : assert_int_equal(tag, tctx->current_tag);
209 1 : TALLOC_FREE(se);
210 1 : assert_true(tctx->detach);
211 1 : return;
212 : }
213 :
214 1 : static void immediate_handler_free(struct tevent_context *ctx,
215 : struct tevent_immediate *im,
216 : void *private_data)
217 : {
218 1 : struct test_ctx *tctx = (struct test_ctx *)private_data;
219 1 : uint64_t tag = tevent_immediate_get_tag(im);
220 1 : assert_true(tctx->attach);
221 1 : assert_true(tctx->before_handler);
222 1 : assert_false(tctx->handler_called);
223 1 : assert_false(tctx->detach);
224 1 : tctx->handler_called = true;
225 1 : assert_int_equal(tag, tctx->current_tag);
226 1 : TALLOC_FREE(im);
227 1 : assert_true(tctx->detach);
228 1 : return;
229 : }
230 :
231 52 : static void trace_event_cb(void *event,
232 : enum tevent_event_trace_point point,
233 : void *private_data)
234 : {
235 52 : struct test_ctx *tctx = (struct test_ctx *)private_data;
236 52 : uint64_t tag = tctx->get_tag(event);
237 :
238 52 : switch (point) {
239 21 : case TEVENT_EVENT_TRACE_ATTACH:
240 21 : if (tctx->reattach_reset) {
241 4 : assert_true(tctx->attach);
242 4 : assert_true(tctx->detach);
243 4 : tctx->attach = false;
244 4 : tctx->before_handler = false;
245 4 : tctx->handler_called = false;
246 4 : tctx->detach = false;
247 4 : tctx->handler_skipped = false;
248 4 : tctx->reattach_reset = false;
249 : }
250 21 : assert_false(tctx->attach);
251 21 : assert_false(tctx->before_handler);
252 21 : assert_false(tctx->handler_called);
253 21 : assert_false(tctx->detach);
254 21 : tctx->attach = true;
255 21 : assert_int_equal(tag, tctx->current_tag);
256 21 : tag = ++tctx->current_tag;
257 21 : tctx->set_tag(event, tag);
258 21 : break;
259 10 : case TEVENT_EVENT_TRACE_BEFORE_HANDLER:
260 10 : assert_true(tctx->attach);
261 10 : assert_false(tctx->before_handler);
262 10 : assert_false(tctx->handler_called);
263 10 : assert_false(tctx->detach);
264 10 : tctx->before_handler = true;
265 10 : assert_int_equal(tag, tctx->current_tag);
266 10 : break;
267 21 : case TEVENT_EVENT_TRACE_DETACH:
268 21 : assert_true(tctx->attach);
269 21 : if (tctx->handler_skipped) {
270 11 : assert_false(tctx->before_handler);
271 11 : assert_false(tctx->handler_called);
272 : } else {
273 10 : assert_true(tctx->before_handler);
274 10 : assert_true(tctx->handler_called);
275 : }
276 21 : assert_false(tctx->detach);
277 21 : tctx->detach = true;
278 21 : assert_int_equal(tag, tctx->current_tag);
279 21 : break;
280 : }
281 52 : }
282 :
283 24 : static void trace_event_cb1(void *event,
284 : enum tevent_event_trace_point point,
285 : void *private_data)
286 : {
287 24 : struct test_ctx *tctx = (struct test_ctx *)private_data;
288 : uint64_t tag;
289 :
290 24 : switch (point) {
291 8 : case TEVENT_EVENT_TRACE_ATTACH:
292 8 : tctx->attach = true;
293 8 : tag = ++tctx->current_tag;
294 8 : tctx->set_tag(event, tag);
295 8 : break;
296 8 : case TEVENT_EVENT_TRACE_BEFORE_HANDLER:
297 8 : tctx->before_handler = true;
298 8 : break;
299 8 : case TEVENT_EVENT_TRACE_DETACH:
300 8 : tctx->detach = true;
301 8 : break;
302 : }
303 24 : }
304 :
305 24 : static int test_setup(void **state)
306 : {
307 : struct test_ctx *tctx;
308 :
309 24 : tctx = talloc_zero(NULL, struct test_ctx);
310 24 : assert_non_null(tctx);
311 :
312 24 : tctx->ev = tevent_context_init(tctx);
313 24 : assert_non_null(tctx->ev);
314 :
315 24 : *state = tctx;
316 24 : return 0;
317 : }
318 :
319 24 : static int test_teardown(void **state)
320 : {
321 24 : struct test_ctx *tctx = (struct test_ctx *)(*state);
322 24 : tctx->get_tag = NULL;
323 24 : tctx->set_tag = NULL;
324 24 : tevent_set_trace_fd_callback(tctx->ev, NULL, NULL);
325 24 : tevent_set_trace_timer_callback(tctx->ev, NULL, NULL);
326 24 : tevent_set_trace_signal_callback(tctx->ev, NULL, NULL);
327 24 : tevent_set_trace_immediate_callback(tctx->ev, NULL, NULL);
328 24 : TALLOC_FREE(tctx);
329 24 : return 0;
330 : }
331 :
332 10 : static uint64_t fd_get_tag(const void *_event)
333 : {
334 10 : const struct tevent_fd *event =
335 : (const struct tevent_fd *)_event;
336 :
337 10 : return tevent_fd_get_tag(event);
338 : }
339 :
340 4 : static void fd_set_tag(void *_event, uint64_t tag)
341 : {
342 4 : struct tevent_fd *event =
343 : (struct tevent_fd *)_event;
344 :
345 4 : tevent_fd_set_tag(event, tag);
346 4 : }
347 :
348 12 : static uint64_t timer_get_tag(const void *_event)
349 : {
350 12 : const struct tevent_timer *event =
351 : (const struct tevent_timer *)_event;
352 :
353 12 : return tevent_timer_get_tag(event);
354 : }
355 :
356 5 : static void timer_set_tag(void *_event, uint64_t tag)
357 : {
358 5 : struct tevent_timer *event =
359 : (struct tevent_timer *)_event;
360 :
361 5 : tevent_timer_set_tag(event, tag);
362 5 : }
363 :
364 10 : static uint64_t signal_get_tag(const void *_event)
365 : {
366 10 : const struct tevent_signal *event =
367 : (const struct tevent_signal *)_event;
368 :
369 10 : return tevent_signal_get_tag(event);
370 : }
371 :
372 4 : static void signal_set_tag(void *_event, uint64_t tag)
373 : {
374 4 : struct tevent_signal *event =
375 : (struct tevent_signal *)_event;
376 :
377 4 : tevent_signal_set_tag(event, tag);
378 4 : }
379 :
380 20 : static uint64_t immediate_get_tag(const void *_event)
381 : {
382 20 : const struct tevent_immediate *event =
383 : (const struct tevent_immediate *)_event;
384 :
385 20 : return tevent_immediate_get_tag(event);
386 : }
387 :
388 8 : static void immediate_set_tag(void *_event, uint64_t tag)
389 : {
390 8 : struct tevent_immediate *event =
391 : (struct tevent_immediate *)_event;
392 :
393 8 : tevent_immediate_set_tag(event, tag);
394 8 : }
395 :
396 0 : static uint64_t queue_entry_get_tag(const void *_event)
397 : {
398 0 : const struct tevent_queue_entry *event =
399 : (const struct tevent_queue_entry *)_event;
400 :
401 0 : return tevent_queue_entry_get_tag(event);
402 : }
403 :
404 8 : static void queue_entry_set_tag(void *_event, uint64_t tag)
405 : {
406 8 : struct tevent_queue_entry *event =
407 : (struct tevent_queue_entry *)_event;
408 :
409 8 : tevent_queue_entry_set_tag(event, tag);
410 8 : }
411 :
412 1 : static void test_trace_event_fd__loop(void **state)
413 : {
414 1 : struct test_ctx *tctx = (struct test_ctx *)(*state);
415 : struct tevent_fd *fde;
416 :
417 1 : tctx->get_tag = fd_get_tag;
418 1 : tctx->set_tag = fd_set_tag;
419 1 : tevent_set_trace_fd_callback(tctx->ev, (tevent_trace_fd_callback_t)trace_event_cb, tctx);
420 :
421 1 : assert_false(tctx->attach);
422 1 : assert_false(tctx->before_handler);
423 1 : assert_false(tctx->handler_called);
424 1 : assert_false(tctx->detach);
425 :
426 1 : fde = tevent_add_fd(tctx->ev, tctx, 0, TEVENT_FD_WRITE, fd_handler, tctx);
427 1 : assert_non_null(fde);
428 1 : assert_true(tctx->attach);
429 1 : assert_false(tctx->before_handler);
430 1 : assert_false(tctx->handler_called);
431 1 : assert_false(tctx->detach);
432 :
433 1 : TEVENT_FD_WRITEABLE(fde);
434 1 : tevent_loop_once(tctx->ev);
435 1 : assert_true(tctx->attach);
436 1 : assert_true(tctx->before_handler);
437 1 : assert_true(tctx->handler_called);
438 1 : assert_false(tctx->detach);
439 :
440 1 : TALLOC_FREE(fde);
441 1 : assert_true(tctx->attach);
442 1 : assert_true(tctx->before_handler);
443 1 : assert_true(tctx->handler_called);
444 1 : assert_true(tctx->detach);
445 1 : }
446 :
447 1 : static void test_trace_event_fd__reset(void **state)
448 : {
449 1 : struct test_ctx *tctx = (struct test_ctx *)(*state);
450 : struct tevent_fd *fde;
451 :
452 1 : tctx->get_tag = fd_get_tag;
453 1 : tctx->set_tag = fd_set_tag;
454 1 : tevent_set_trace_fd_callback(tctx->ev, (tevent_trace_fd_callback_t)trace_event_cb, tctx);
455 :
456 1 : assert_false(tctx->attach);
457 1 : assert_false(tctx->before_handler);
458 1 : assert_false(tctx->handler_called);
459 1 : assert_false(tctx->detach);
460 :
461 1 : fde = tevent_add_fd(tctx->ev, tctx, 0, TEVENT_FD_WRITE, fd_handler, tctx);
462 1 : assert_non_null(fde);
463 1 : assert_true(tctx->attach);
464 1 : assert_false(tctx->before_handler);
465 1 : assert_false(tctx->handler_called);
466 1 : assert_false(tctx->detach);
467 :
468 1 : tctx->handler_skipped = true;
469 1 : tevent_re_initialise(tctx->ev);
470 1 : assert_true(tctx->attach);
471 1 : assert_false(tctx->before_handler);
472 1 : assert_false(tctx->handler_called);
473 1 : assert_true(tctx->detach);
474 1 : }
475 :
476 1 : static void test_trace_event_fd__free(void **state)
477 : {
478 1 : struct test_ctx *tctx = (struct test_ctx *)(*state);
479 : struct tevent_fd *fde;
480 :
481 1 : tctx->get_tag = fd_get_tag;
482 1 : tctx->set_tag = fd_set_tag;
483 1 : tevent_set_trace_fd_callback(tctx->ev, (tevent_trace_fd_callback_t)trace_event_cb, tctx);
484 :
485 1 : assert_false(tctx->attach);
486 1 : assert_false(tctx->before_handler);
487 1 : assert_false(tctx->handler_called);
488 1 : assert_false(tctx->detach);
489 :
490 1 : fde = tevent_add_fd(tctx->ev, tctx, 0, TEVENT_FD_WRITE, fd_handler, tctx);
491 1 : assert_non_null(fde);
492 1 : assert_true(tctx->attach);
493 1 : assert_false(tctx->before_handler);
494 1 : assert_false(tctx->handler_called);
495 1 : assert_false(tctx->detach);
496 :
497 1 : tctx->handler_skipped = true;
498 1 : TALLOC_FREE(fde);
499 1 : assert_true(tctx->attach);
500 1 : assert_false(tctx->before_handler);
501 1 : assert_false(tctx->handler_called);
502 1 : assert_true(tctx->detach);
503 1 : }
504 :
505 1 : static void test_trace_event_fd__free_in_handler(void **state)
506 : {
507 1 : struct test_ctx *tctx = (struct test_ctx *)(*state);
508 : struct tevent_fd *fde;
509 :
510 1 : tctx->get_tag = fd_get_tag;
511 1 : tctx->set_tag = fd_set_tag;
512 1 : tevent_set_trace_fd_callback(tctx->ev, (tevent_trace_fd_callback_t)trace_event_cb, tctx);
513 :
514 1 : assert_false(tctx->attach);
515 1 : assert_false(tctx->before_handler);
516 1 : assert_false(tctx->handler_called);
517 1 : assert_false(tctx->detach);
518 :
519 1 : fde = tevent_add_fd(tctx->ev, tctx, 0, TEVENT_FD_WRITE, fd_handler_free, tctx);
520 1 : assert_non_null(fde);
521 1 : assert_true(tctx->attach);
522 1 : assert_false(tctx->before_handler);
523 1 : assert_false(tctx->handler_called);
524 1 : assert_false(tctx->detach);
525 :
526 1 : TEVENT_FD_WRITEABLE(fde);
527 1 : tevent_loop_once(tctx->ev);
528 1 : assert_true(tctx->attach);
529 1 : assert_true(tctx->before_handler);
530 1 : assert_true(tctx->handler_called);
531 1 : assert_true(tctx->detach);
532 1 : }
533 :
534 1 : static void test_trace_event_timer__loop(void **state)
535 : {
536 1 : struct test_ctx *tctx = (struct test_ctx *)(*state);
537 : struct tevent_timer *te;
538 : struct timeval next;
539 :
540 1 : tctx->get_tag = timer_get_tag;
541 1 : tctx->set_tag = timer_set_tag;
542 1 : tevent_set_trace_timer_callback(tctx->ev, (tevent_trace_timer_callback_t)trace_event_cb, tctx);
543 :
544 1 : assert_false(tctx->attach);
545 1 : assert_false(tctx->before_handler);
546 1 : assert_false(tctx->handler_called);
547 1 : assert_false(tctx->detach);
548 :
549 1 : next = tevent_timeval_current();
550 1 : te = tevent_add_timer(tctx->ev, tctx, next, timer_handler, tctx);
551 1 : assert_non_null(te);
552 1 : assert_true(tctx->attach);
553 1 : assert_false(tctx->before_handler);
554 1 : assert_false(tctx->handler_called);
555 1 : assert_false(tctx->detach);
556 :
557 1 : tevent_loop_once(tctx->ev);
558 1 : assert_true(tctx->attach);
559 1 : assert_true(tctx->before_handler);
560 1 : assert_true(tctx->handler_called);
561 : /* timer events are self destructing after calling the handler */
562 1 : assert_true(tctx->detach);
563 1 : }
564 :
565 1 : static void test_trace_event_timer__reset(void **state)
566 : {
567 1 : struct test_ctx *tctx = (struct test_ctx *)(*state);
568 : struct tevent_timer *te;
569 : struct timeval next;
570 :
571 1 : tctx->get_tag = timer_get_tag;
572 1 : tctx->set_tag = timer_set_tag;
573 1 : tevent_set_trace_timer_callback(tctx->ev, (tevent_trace_timer_callback_t)trace_event_cb, tctx);
574 :
575 1 : assert_false(tctx->attach);
576 1 : assert_false(tctx->before_handler);
577 1 : assert_false(tctx->handler_called);
578 1 : assert_false(tctx->detach);
579 :
580 1 : next = tevent_timeval_current();
581 1 : te = tevent_add_timer(tctx->ev, tctx, next, timer_handler, tctx);
582 1 : assert_non_null(te);
583 1 : assert_true(tctx->attach);
584 1 : assert_false(tctx->before_handler);
585 1 : assert_false(tctx->handler_called);
586 1 : assert_false(tctx->detach);
587 1 : assert_true(tctx->attach);
588 :
589 1 : assert_false(tctx->reattach_reset);
590 1 : tctx->handler_skipped = true;
591 1 : tctx->reattach_reset = true;
592 1 : next = tevent_timeval_current();
593 1 : tevent_update_timer(te, next);
594 1 : assert_false(tctx->reattach_reset);
595 1 : assert_false(tctx->handler_skipped);
596 1 : assert_true(tctx->attach);
597 1 : assert_false(tctx->before_handler);
598 1 : assert_false(tctx->handler_called);
599 1 : assert_false(tctx->detach);
600 :
601 1 : tctx->handler_skipped = true;
602 1 : tevent_re_initialise(tctx->ev);
603 1 : assert_true(tctx->attach);
604 1 : assert_false(tctx->before_handler);
605 1 : assert_false(tctx->handler_called);
606 1 : assert_true(tctx->detach);
607 1 : }
608 :
609 1 : static void test_trace_event_timer__free(void **state)
610 : {
611 1 : struct test_ctx *tctx = (struct test_ctx *)(*state);
612 : struct tevent_timer *te;
613 : struct timeval next;
614 :
615 1 : tctx->get_tag = timer_get_tag;
616 1 : tctx->set_tag = timer_set_tag;
617 1 : tevent_set_trace_timer_callback(tctx->ev, (tevent_trace_timer_callback_t)trace_event_cb, tctx);
618 :
619 1 : assert_false(tctx->attach);
620 1 : assert_false(tctx->before_handler);
621 1 : assert_false(tctx->handler_called);
622 1 : assert_false(tctx->detach);
623 :
624 1 : next = tevent_timeval_current();
625 1 : te = tevent_add_timer(tctx->ev, tctx, next, timer_handler, tctx);
626 1 : assert_non_null(te);
627 1 : assert_true(tctx->attach);
628 1 : assert_false(tctx->before_handler);
629 1 : assert_false(tctx->handler_called);
630 1 : assert_false(tctx->detach);
631 1 : assert_true(tctx->attach);
632 :
633 1 : tctx->handler_skipped = true;
634 1 : TALLOC_FREE(te);
635 1 : assert_true(tctx->attach);
636 1 : assert_false(tctx->before_handler);
637 1 : assert_false(tctx->handler_called);
638 1 : assert_true(tctx->detach);
639 1 : }
640 :
641 1 : static void test_trace_event_timer__free_in_handler(void **state)
642 : {
643 1 : struct test_ctx *tctx = (struct test_ctx *)(*state);
644 : struct tevent_timer *te;
645 : struct timeval next;
646 :
647 1 : tctx->get_tag = timer_get_tag;
648 1 : tctx->set_tag = timer_set_tag;
649 1 : tevent_set_trace_timer_callback(tctx->ev, (tevent_trace_timer_callback_t)trace_event_cb, tctx);
650 :
651 1 : assert_false(tctx->attach);
652 1 : assert_false(tctx->before_handler);
653 1 : assert_false(tctx->handler_called);
654 1 : assert_false(tctx->detach);
655 :
656 1 : next = tevent_timeval_current();
657 1 : te = tevent_add_timer(tctx->ev, tctx, next, timer_handler_free, tctx);
658 1 : assert_non_null(te);
659 1 : assert_true(tctx->attach);
660 1 : assert_false(tctx->before_handler);
661 1 : assert_false(tctx->handler_called);
662 1 : assert_false(tctx->detach);
663 :
664 1 : tevent_loop_once(tctx->ev);
665 1 : assert_true(tctx->attach);
666 1 : assert_true(tctx->before_handler);
667 1 : assert_true(tctx->handler_called);
668 1 : assert_true(tctx->detach);
669 1 : }
670 :
671 1 : static void test_trace_event_signal__loop(void **state)
672 : {
673 1 : struct test_ctx *tctx = (struct test_ctx *)(*state);
674 : struct tevent_signal *se;
675 :
676 1 : tctx->get_tag = signal_get_tag;
677 1 : tctx->set_tag = signal_set_tag;
678 1 : tevent_set_trace_signal_callback(tctx->ev, (tevent_trace_signal_callback_t)trace_event_cb, tctx);
679 :
680 1 : assert_false(tctx->attach);
681 1 : assert_false(tctx->before_handler);
682 1 : assert_false(tctx->handler_called);
683 1 : assert_false(tctx->detach);
684 :
685 1 : se = tevent_add_signal(tctx->ev, tctx, SIGUSR1, 0, signal_handler, tctx);
686 1 : assert_non_null(se);
687 1 : assert_true(tctx->attach);
688 1 : assert_false(tctx->before_handler);
689 1 : assert_false(tctx->handler_called);
690 1 : assert_false(tctx->detach);
691 :
692 1 : kill(getpid(), SIGUSR1);
693 1 : tevent_loop_once(tctx->ev);
694 1 : assert_true(tctx->attach);
695 1 : assert_true(tctx->before_handler);
696 1 : assert_true(tctx->handler_called);
697 1 : assert_false(tctx->detach);
698 :
699 1 : TALLOC_FREE(se);
700 1 : assert_true(tctx->attach);
701 1 : assert_true(tctx->before_handler);
702 1 : assert_true(tctx->handler_called);
703 1 : assert_true(tctx->detach);
704 1 : }
705 :
706 1 : static void test_trace_event_signal__reset(void **state)
707 : {
708 1 : struct test_ctx *tctx = (struct test_ctx *)(*state);
709 : struct tevent_signal *se;
710 :
711 1 : tctx->get_tag = signal_get_tag;
712 1 : tctx->set_tag = signal_set_tag;
713 1 : tevent_set_trace_signal_callback(tctx->ev, (tevent_trace_signal_callback_t)trace_event_cb, tctx);
714 :
715 1 : assert_false(tctx->attach);
716 1 : assert_false(tctx->before_handler);
717 1 : assert_false(tctx->handler_called);
718 1 : assert_false(tctx->detach);
719 :
720 1 : se = tevent_add_signal(tctx->ev, tctx, SIGUSR1, 0, signal_handler, tctx);
721 1 : assert_non_null(se);
722 1 : assert_true(tctx->attach);
723 1 : assert_false(tctx->before_handler);
724 1 : assert_false(tctx->handler_called);
725 1 : assert_false(tctx->detach);
726 :
727 1 : tctx->handler_skipped = true;
728 1 : TALLOC_FREE(se);
729 1 : assert_true(tctx->attach);
730 1 : assert_false(tctx->before_handler);
731 1 : assert_false(tctx->handler_called);
732 1 : assert_true(tctx->detach);
733 1 : }
734 :
735 1 : static void test_trace_event_signal__free(void **state)
736 : {
737 1 : struct test_ctx *tctx = (struct test_ctx *)(*state);
738 : struct tevent_signal *se;
739 :
740 1 : tctx->get_tag = signal_get_tag;
741 1 : tctx->set_tag = signal_set_tag;
742 1 : tevent_set_trace_signal_callback(tctx->ev, (tevent_trace_signal_callback_t)trace_event_cb, tctx);
743 :
744 1 : assert_false(tctx->attach);
745 1 : assert_false(tctx->before_handler);
746 1 : assert_false(tctx->handler_called);
747 1 : assert_false(tctx->detach);
748 :
749 1 : se = tevent_add_signal(tctx->ev, tctx, SIGUSR1, 0, signal_handler, tctx);
750 1 : assert_non_null(se);
751 1 : assert_true(tctx->attach);
752 1 : assert_false(tctx->before_handler);
753 1 : assert_false(tctx->handler_called);
754 1 : assert_false(tctx->detach);
755 :
756 1 : tctx->handler_skipped = true;
757 1 : TALLOC_FREE(se);
758 1 : assert_true(tctx->attach);
759 1 : assert_false(tctx->before_handler);
760 1 : assert_false(tctx->handler_called);
761 1 : assert_true(tctx->detach);
762 1 : }
763 :
764 1 : static void test_trace_event_signal__free_in_handler(void **state)
765 : {
766 1 : struct test_ctx *tctx = (struct test_ctx *)(*state);
767 : struct tevent_signal *se;
768 :
769 1 : tctx->get_tag = signal_get_tag;
770 1 : tctx->set_tag = signal_set_tag;
771 1 : tevent_set_trace_signal_callback(tctx->ev, (tevent_trace_signal_callback_t)trace_event_cb, tctx);
772 :
773 1 : assert_false(tctx->attach);
774 1 : assert_false(tctx->before_handler);
775 1 : assert_false(tctx->handler_called);
776 1 : assert_false(tctx->detach);
777 :
778 1 : se = tevent_add_signal(tctx->ev, tctx, SIGUSR1, 0, signal_handler_free, tctx);
779 1 : assert_non_null(se);
780 1 : assert_true(tctx->attach);
781 1 : assert_false(tctx->before_handler);
782 1 : assert_false(tctx->handler_called);
783 1 : assert_false(tctx->detach);
784 :
785 1 : kill(getpid(), SIGUSR1);
786 1 : tevent_loop_once(tctx->ev);
787 1 : assert_true(tctx->attach);
788 1 : assert_true(tctx->before_handler);
789 1 : assert_true(tctx->handler_called);
790 1 : assert_true(tctx->detach);
791 1 : }
792 :
793 1 : static void test_trace_event_immediate__loop(void **state)
794 : {
795 1 : struct test_ctx *tctx = (struct test_ctx *)(*state);
796 : struct tevent_immediate *im;
797 :
798 1 : tctx->get_tag = immediate_get_tag;
799 1 : tctx->set_tag = immediate_set_tag;
800 1 : tevent_set_trace_immediate_callback(tctx->ev, (tevent_trace_immediate_callback_t)trace_event_cb, tctx);
801 :
802 1 : assert_false(tctx->attach);
803 1 : assert_false(tctx->before_handler);
804 1 : assert_false(tctx->handler_called);
805 1 : assert_false(tctx->detach);
806 :
807 1 : im = tevent_create_immediate(tctx);
808 1 : assert_non_null(im);
809 :
810 1 : assert_false(tctx->attach);
811 1 : assert_false(tctx->before_handler);
812 1 : assert_false(tctx->handler_called);
813 1 : assert_false(tctx->detach);
814 :
815 1 : tevent_schedule_immediate(im, tctx->ev, immediate_handler, tctx);
816 1 : assert_true(tctx->attach);
817 1 : assert_false(tctx->before_handler);
818 1 : assert_false(tctx->handler_called);
819 1 : assert_false(tctx->detach);
820 :
821 1 : tevent_loop_once(tctx->ev);
822 1 : assert_true(tctx->attach);
823 1 : assert_true(tctx->before_handler);
824 1 : assert_true(tctx->handler_called);
825 : /* immediate events are self detaching */
826 1 : assert_true(tctx->detach);
827 1 : }
828 :
829 1 : static void test_trace_event_immediate__reset(void **state)
830 : {
831 1 : struct test_ctx *tctx = (struct test_ctx *)(*state);
832 : struct tevent_immediate *im;
833 :
834 1 : tctx->get_tag = immediate_get_tag;
835 1 : tctx->set_tag = immediate_set_tag;
836 1 : tevent_set_trace_immediate_callback(tctx->ev, (tevent_trace_immediate_callback_t)trace_event_cb, tctx);
837 :
838 1 : assert_false(tctx->attach);
839 1 : assert_false(tctx->before_handler);
840 1 : assert_false(tctx->handler_called);
841 1 : assert_false(tctx->detach);
842 :
843 1 : im = tevent_create_immediate(tctx);
844 1 : assert_non_null(im);
845 :
846 1 : assert_false(tctx->attach);
847 1 : assert_false(tctx->before_handler);
848 1 : assert_false(tctx->handler_called);
849 1 : assert_false(tctx->detach);
850 :
851 1 : tevent_schedule_immediate(im, tctx->ev, immediate_handler, tctx);
852 1 : assert_true(tctx->attach);
853 1 : assert_false(tctx->before_handler);
854 1 : assert_false(tctx->handler_called);
855 1 : assert_false(tctx->detach);
856 :
857 1 : tctx->handler_skipped = true;
858 1 : tevent_re_initialise(tctx->ev);
859 1 : assert_true(tctx->attach);
860 1 : assert_false(tctx->before_handler);
861 1 : assert_false(tctx->handler_called);
862 1 : assert_true(tctx->detach);
863 1 : }
864 :
865 1 : static void test_trace_event_immediate__free(void **state)
866 : {
867 1 : struct test_ctx *tctx = (struct test_ctx *)(*state);
868 : struct tevent_immediate *im;
869 :
870 1 : tctx->get_tag = immediate_get_tag;
871 1 : tctx->set_tag = immediate_set_tag;
872 1 : tevent_set_trace_immediate_callback(tctx->ev, (tevent_trace_immediate_callback_t)trace_event_cb, tctx);
873 :
874 1 : assert_false(tctx->attach);
875 1 : assert_false(tctx->before_handler);
876 1 : assert_false(tctx->handler_called);
877 1 : assert_false(tctx->detach);
878 :
879 1 : im = tevent_create_immediate(tctx);
880 1 : assert_non_null(im);
881 :
882 1 : assert_false(tctx->attach);
883 1 : assert_false(tctx->before_handler);
884 1 : assert_false(tctx->handler_called);
885 1 : assert_false(tctx->detach);
886 :
887 1 : tevent_schedule_immediate(im, tctx->ev, immediate_handler, tctx);
888 1 : assert_true(tctx->attach);
889 1 : assert_false(tctx->before_handler);
890 1 : assert_false(tctx->handler_called);
891 1 : assert_false(tctx->detach);
892 :
893 1 : tctx->handler_skipped = true;
894 1 : TALLOC_FREE(im);
895 1 : assert_true(tctx->attach);
896 1 : assert_false(tctx->before_handler);
897 1 : assert_false(tctx->handler_called);
898 1 : assert_true(tctx->detach);
899 1 : }
900 :
901 1 : static void test_trace_event_immediate__free_in_handler(void **state)
902 : {
903 1 : struct test_ctx *tctx = (struct test_ctx *)(*state);
904 : struct tevent_immediate *im;
905 :
906 1 : tctx->get_tag = immediate_get_tag;
907 1 : tctx->set_tag = immediate_set_tag;
908 1 : tevent_set_trace_immediate_callback(tctx->ev, (tevent_trace_immediate_callback_t)trace_event_cb, tctx);
909 :
910 1 : assert_false(tctx->attach);
911 1 : assert_false(tctx->before_handler);
912 1 : assert_false(tctx->handler_called);
913 1 : assert_false(tctx->detach);
914 :
915 1 : im = tevent_create_immediate(tctx);
916 1 : assert_non_null(im);
917 :
918 1 : assert_false(tctx->attach);
919 1 : assert_false(tctx->before_handler);
920 1 : assert_false(tctx->handler_called);
921 1 : assert_false(tctx->detach);
922 :
923 1 : tevent_schedule_immediate(im, tctx->ev, immediate_handler_free, tctx);
924 1 : assert_true(tctx->attach);
925 1 : assert_false(tctx->before_handler);
926 1 : assert_false(tctx->handler_called);
927 1 : assert_false(tctx->detach);
928 :
929 1 : tevent_loop_once(tctx->ev);
930 1 : assert_true(tctx->attach);
931 1 : assert_true(tctx->before_handler);
932 1 : assert_true(tctx->handler_called);
933 1 : assert_true(tctx->detach);
934 1 : }
935 :
936 1 : static void test_trace_event_immediate__reschedule(void **state)
937 : {
938 1 : struct test_ctx *tctx = (struct test_ctx *)(*state);
939 : struct tevent_immediate *im;
940 :
941 1 : tctx->get_tag = immediate_get_tag;
942 1 : tctx->set_tag = immediate_set_tag;
943 1 : tevent_set_trace_immediate_callback(tctx->ev, (tevent_trace_immediate_callback_t)trace_event_cb, tctx);
944 :
945 1 : assert_false(tctx->attach);
946 1 : assert_false(tctx->before_handler);
947 1 : assert_false(tctx->handler_called);
948 1 : assert_false(tctx->detach);
949 :
950 1 : im = tevent_create_immediate(tctx);
951 1 : assert_non_null(im);
952 :
953 1 : assert_false(tctx->attach);
954 1 : assert_false(tctx->before_handler);
955 1 : assert_false(tctx->handler_called);
956 1 : assert_false(tctx->detach);
957 :
958 1 : tevent_schedule_immediate(im, tctx->ev, immediate_handler, tctx);
959 1 : assert_true(tctx->attach);
960 1 : assert_false(tctx->before_handler);
961 1 : assert_false(tctx->handler_called);
962 1 : assert_false(tctx->detach);
963 :
964 1 : assert_false(tctx->reattach_reset);
965 1 : tctx->handler_skipped = true;
966 1 : tctx->reattach_reset = true;
967 1 : tevent_schedule_immediate(im, tctx->ev, immediate_handler_reschedule, tctx);
968 1 : assert_false(tctx->reattach_reset);
969 1 : assert_false(tctx->handler_skipped);
970 1 : assert_true(tctx->attach);
971 1 : assert_false(tctx->before_handler);
972 1 : assert_false(tctx->handler_called);
973 1 : assert_false(tctx->detach);
974 :
975 1 : tevent_loop_once(tctx->ev);
976 1 : assert_false(tctx->reattach_reset);
977 1 : assert_true(tctx->attach);
978 1 : assert_false(tctx->before_handler);
979 1 : assert_false(tctx->handler_called);
980 1 : assert_false(tctx->detach);
981 :
982 1 : tevent_loop_once(tctx->ev);
983 1 : assert_true(tctx->attach);
984 1 : assert_true(tctx->before_handler);
985 1 : assert_true(tctx->handler_called);
986 : /* immediate events are self detaching */
987 1 : assert_true(tctx->detach);
988 1 : }
989 :
990 : struct dummy_request_state
991 : {
992 : int i;
993 : struct tevent_queue_entry *e;
994 : };
995 :
996 7 : static void queue_trigger(struct tevent_req *req, void *private_data)
997 : {
998 7 : struct test_ctx *tctx = (struct test_ctx *)private_data;
999 7 : struct dummy_request_state *state = tevent_req_data(
1000 : req, struct dummy_request_state);
1001 :
1002 7 : tctx->handler_called = true;
1003 7 : assert_int_equal(tevent_queue_entry_get_tag(state->e), state->i);
1004 7 : TALLOC_FREE(req);
1005 :
1006 7 : return;
1007 : }
1008 :
1009 1 : static void test_trace_queue__loop(void **state)
1010 : {
1011 1 : struct test_ctx *tctx = (struct test_ctx *)(*state);
1012 : struct tevent_queue *qa, *qb;
1013 : struct tevent_req *r1, *r2, *r3, *r4, *r5;
1014 : struct dummy_request_state *ds1, *ds2, *ds3, *ds4, *ds5;
1015 :
1016 1 : tevent_set_trace_queue_callback(
1017 : tctx->ev,
1018 : (tevent_trace_queue_callback_t)trace_event_cb1,
1019 : tctx);
1020 1 : tctx->get_tag = queue_entry_get_tag;
1021 1 : tctx->set_tag = queue_entry_set_tag;
1022 :
1023 1 : qa = tevent_queue_create(tctx->ev, "test_queue A");
1024 1 : assert_non_null(qa);
1025 1 : qb = tevent_queue_create(tctx->ev, "test_queue B");
1026 1 : assert_non_null(qb);
1027 :
1028 1 : r1 = tevent_req_create(tctx->ev, &ds1, struct dummy_request_state);
1029 1 : ds1->e = tevent_queue_add_entry(qa,
1030 : tctx->ev,
1031 : r1,
1032 : queue_trigger,
1033 : *state);
1034 1 : ds1->i = tctx->current_tag;
1035 1 : assert_int_equal(ds1->i, 1);
1036 :
1037 1 : r2 = tevent_req_create(tctx->ev, &ds2, struct dummy_request_state);
1038 1 : ds2->e = tevent_queue_add_entry(qa,
1039 : tctx->ev,
1040 : r2,
1041 : queue_trigger,
1042 : *state);
1043 1 : ds2->i = tctx->current_tag;
1044 1 : assert_int_equal(ds2->i, 2);
1045 :
1046 1 : r3 = tevent_req_create(tctx->ev, &ds3, struct dummy_request_state);
1047 1 : ds3->e = tevent_queue_add_entry(qb,
1048 : tctx->ev,
1049 : r3,
1050 : queue_trigger,
1051 : *state);
1052 1 : ds3->i = tctx->current_tag;
1053 1 : assert_int_equal(ds3->i, 3);
1054 :
1055 1 : r4 = tevent_req_create(tctx->ev, &ds4, struct dummy_request_state);
1056 1 : ds4->e = tevent_queue_add_entry(qb,
1057 : tctx->ev,
1058 : r4,
1059 : queue_trigger,
1060 : *state);
1061 1 : ds4->i = tctx->current_tag;
1062 1 : assert_int_equal(ds4->i, 4);
1063 :
1064 1 : r5 = tevent_req_create(tctx->ev, &ds5, struct dummy_request_state);
1065 1 : ds5->e = tevent_queue_add_entry(qa,
1066 : tctx->ev,
1067 : r5,
1068 : queue_trigger,
1069 : *state);
1070 1 : ds5->i = tctx->current_tag;
1071 1 : assert_int_equal(ds5->i, 5);
1072 :
1073 1 : tevent_loop_once(tctx->ev);
1074 1 : tevent_loop_once(tctx->ev);
1075 1 : tevent_loop_once(tctx->ev);
1076 1 : tevent_loop_once(tctx->ev);
1077 1 : tevent_loop_once(tctx->ev);
1078 1 : }
1079 :
1080 2 : static void reset_tctx(struct test_ctx *tctx)
1081 : {
1082 2 : tctx->attach = false;
1083 2 : tctx->before_handler = false;
1084 2 : tctx->handler_called = false;
1085 2 : tctx->detach = false;
1086 2 : }
1087 :
1088 1 : static void test_trace_queue__extra(void **state)
1089 : {
1090 1 : struct test_ctx *tctx = (struct test_ctx *)(*state);
1091 : struct tevent_queue *qa;
1092 : struct tevent_req *r1, *r2, *r3;
1093 : struct dummy_request_state *ds1, *ds2, *ds3;
1094 :
1095 1 : tevent_set_trace_queue_callback(
1096 : tctx->ev,
1097 : (tevent_trace_queue_callback_t)trace_event_cb1,
1098 : tctx);
1099 1 : tctx->get_tag = queue_entry_get_tag;
1100 1 : tctx->set_tag = queue_entry_set_tag;
1101 :
1102 1 : qa = tevent_queue_create(tctx->ev, "test_queue A");
1103 1 : assert_non_null(qa);
1104 :
1105 : /*
1106 : * r1 - this tests optimize_empty - request is triggered immediately,
1107 : * (and not even scheduled to tevent_context). The TALLOC_FREE() called
1108 : * from queue_trigger removes the request/queue_entry from the queue qa.
1109 : * So qa is empty
1110 : */
1111 1 : r1 = tevent_req_create(tctx->ev, &ds1, struct dummy_request_state);
1112 1 : ds1->e = tevent_queue_add_optimize_empty(qa,
1113 : tctx->ev,
1114 : r1,
1115 : queue_trigger,
1116 : *state);
1117 1 : assert_true(tctx->attach);
1118 1 : assert_true(tctx->before_handler);
1119 1 : assert_true(tctx->handler_called);
1120 1 : assert_true(tctx->detach);
1121 1 : assert_int_equal(tevent_queue_length(qa), 0);
1122 :
1123 1 : reset_tctx(tctx);
1124 :
1125 : /*
1126 : * Test a blocker request r2 - the trigger function is NULL.
1127 : */
1128 1 : r2 = tevent_req_create(tctx->ev, &ds2, struct dummy_request_state);
1129 1 : ds2->e = tevent_queue_add_entry(qa, tctx->ev, r2, NULL, *state);
1130 1 : ds2->i = tctx->current_tag;
1131 1 : assert_true(tctx->attach);
1132 1 : assert_false(tctx->before_handler);
1133 1 : assert_false(tctx->handler_called);
1134 1 : assert_false(tctx->detach);
1135 1 : assert_int_equal(tevent_queue_length(qa), 1);
1136 :
1137 : /*
1138 : * This runs the tevent_queue_noop_trigger().
1139 : * A blocker r2 is still on the queue head, with triggered==true
1140 : */
1141 1 : tevent_loop_once(tctx->ev);
1142 :
1143 1 : assert_true(tctx->attach);
1144 1 : assert_true(tctx->before_handler);
1145 1 : assert_false(tctx->handler_called);
1146 : /* tevent_queue_noop_trigger() is a noop. Does not set handler_called */
1147 1 : assert_false(tctx->detach);
1148 1 : assert_int_equal(tevent_queue_length(qa), 1);
1149 :
1150 : /*
1151 : * Add a normal request r3. It will be blocked by r2.
1152 : */
1153 1 : r3 = tevent_req_create(tctx->ev, &ds3, struct dummy_request_state);
1154 1 : ds3->e = tevent_queue_add_entry(qa,
1155 : tctx->ev,
1156 : r3,
1157 : queue_trigger,
1158 : *state);
1159 1 : ds3->i = tctx->current_tag;
1160 1 : assert_true(tctx->attach);
1161 1 : assert_true(tctx->before_handler);
1162 1 : assert_false(tctx->handler_called);
1163 1 : assert_false(tctx->detach);
1164 1 : assert_int_equal(tevent_queue_length(qa), 2);
1165 :
1166 : /*
1167 : * Remove the blocker r2.
1168 : */
1169 1 : TALLOC_FREE(r2);
1170 1 : assert_true(tctx->attach);
1171 1 : assert_true(tctx->before_handler);
1172 1 : assert_false(tctx->handler_called);
1173 1 : assert_true(tctx->detach);
1174 1 : assert_int_equal(tevent_queue_length(qa), 1);
1175 :
1176 1 : reset_tctx(tctx);
1177 :
1178 : /* Process r3 */
1179 1 : tevent_loop_once(tctx->ev);
1180 :
1181 1 : assert_false(tctx->attach);
1182 1 : assert_true(tctx->before_handler);
1183 1 : assert_true(tctx->handler_called);
1184 1 : assert_true(tctx->detach);
1185 1 : }
1186 :
1187 1 : static void test_get_set_trace_fd_callback(void **state)
1188 : {
1189 1 : struct test_ctx *tctx = (struct test_ctx *)(*state);
1190 : tevent_trace_fd_callback_t cb;
1191 : void *pvt;
1192 :
1193 1 : tevent_get_trace_fd_callback(tctx->ev, &cb, &pvt);
1194 1 : assert_null(cb);
1195 1 : assert_null(pvt);
1196 :
1197 1 : tevent_set_trace_fd_callback(tctx->ev, (tevent_trace_fd_callback_t)trace_event_cb, tctx);
1198 1 : tevent_get_trace_fd_callback(tctx->ev, &cb, &pvt);
1199 1 : assert_ptr_equal(cb, trace_event_cb);
1200 1 : assert_ptr_equal(pvt, tctx);
1201 :
1202 1 : tevent_set_trace_fd_callback(tctx->ev, NULL, NULL);
1203 1 : tevent_get_trace_fd_callback(tctx->ev, &cb, &pvt);
1204 1 : assert_null(cb);
1205 1 : assert_null(pvt);
1206 1 : }
1207 :
1208 1 : static void test_get_set_trace_timer_callback(void **state)
1209 : {
1210 1 : struct test_ctx *tctx = (struct test_ctx *)(*state);
1211 : tevent_trace_timer_callback_t cb;
1212 : void *pvt;
1213 :
1214 1 : tevent_get_trace_timer_callback(tctx->ev, &cb, &pvt);
1215 1 : assert_null(cb);
1216 1 : assert_null(pvt);
1217 :
1218 1 : tevent_set_trace_timer_callback(tctx->ev, (tevent_trace_timer_callback_t)trace_event_cb, tctx);
1219 1 : tevent_get_trace_timer_callback(tctx->ev, &cb, &pvt);
1220 1 : assert_ptr_equal(cb, trace_event_cb);
1221 1 : assert_ptr_equal(pvt, tctx);
1222 :
1223 1 : tevent_set_trace_timer_callback(tctx->ev, NULL, NULL);
1224 1 : tevent_get_trace_timer_callback(tctx->ev, &cb, &pvt);
1225 1 : assert_null(cb);
1226 1 : assert_null(pvt);
1227 1 : }
1228 :
1229 1 : static void test_get_set_trace_signal_callback(void **state)
1230 : {
1231 1 : struct test_ctx *tctx = (struct test_ctx *)(*state);
1232 : tevent_trace_signal_callback_t cb;
1233 : void *pvt;
1234 :
1235 1 : tevent_get_trace_signal_callback(tctx->ev, &cb, &pvt);
1236 1 : assert_null(cb);
1237 1 : assert_null(pvt);
1238 :
1239 1 : tevent_set_trace_signal_callback(tctx->ev, (tevent_trace_signal_callback_t)trace_event_cb, tctx);
1240 1 : tevent_get_trace_signal_callback(tctx->ev, &cb, &pvt);
1241 1 : assert_ptr_equal(cb, trace_event_cb);
1242 1 : assert_ptr_equal(pvt, tctx);
1243 :
1244 1 : tevent_set_trace_signal_callback(tctx->ev, NULL, NULL);
1245 1 : tevent_get_trace_signal_callback(tctx->ev, &cb, &pvt);
1246 1 : assert_null(cb);
1247 1 : assert_null(pvt);
1248 1 : }
1249 :
1250 1 : static void test_get_set_trace_immediate_callback(void **state)
1251 : {
1252 1 : struct test_ctx *tctx = (struct test_ctx *)(*state);
1253 : tevent_trace_immediate_callback_t cb;
1254 : void *pvt;
1255 :
1256 1 : tevent_get_trace_immediate_callback(tctx->ev, &cb, &pvt);
1257 1 : assert_null(cb);
1258 1 : assert_null(pvt);
1259 :
1260 1 : tevent_set_trace_immediate_callback(tctx->ev, (tevent_trace_immediate_callback_t)trace_event_cb, tctx);
1261 1 : tevent_get_trace_immediate_callback(tctx->ev, &cb, &pvt);
1262 1 : assert_ptr_equal(cb, trace_event_cb);
1263 1 : assert_ptr_equal(pvt, tctx);
1264 :
1265 1 : tevent_set_trace_immediate_callback(tctx->ev, NULL, NULL);
1266 1 : tevent_get_trace_immediate_callback(tctx->ev, &cb, &pvt);
1267 1 : assert_null(cb);
1268 1 : assert_null(pvt);
1269 1 : }
1270 :
1271 1 : static void test_get_set_trace_queue_callback(void **state)
1272 : {
1273 1 : struct test_ctx *tctx = (struct test_ctx *)(*state);
1274 : tevent_trace_queue_callback_t cb;
1275 : void *pvt;
1276 :
1277 1 : tevent_get_trace_queue_callback(tctx->ev, &cb, &pvt);
1278 1 : assert_null(cb);
1279 1 : assert_null(pvt);
1280 :
1281 1 : tevent_set_trace_queue_callback(tctx->ev, (tevent_trace_queue_callback_t)trace_event_cb, tctx);
1282 1 : tevent_get_trace_queue_callback(tctx->ev, &cb, &pvt);
1283 1 : assert_ptr_equal(cb, trace_event_cb);
1284 1 : assert_ptr_equal(pvt, tctx);
1285 :
1286 1 : tevent_set_trace_queue_callback(tctx->ev, NULL, NULL);
1287 1 : tevent_get_trace_queue_callback(tctx->ev, &cb, &pvt);
1288 1 : assert_null(cb);
1289 1 : assert_null(pvt);
1290 1 : }
1291 :
1292 1 : int main(int argc, char **argv)
1293 : {
1294 1 : const struct CMUnitTest tests[] = {
1295 : cmocka_unit_test_setup_teardown(test_trace_event_fd__loop, test_setup, test_teardown),
1296 : cmocka_unit_test_setup_teardown(test_trace_event_fd__reset, test_setup, test_teardown),
1297 : cmocka_unit_test_setup_teardown(test_trace_event_fd__free, test_setup, test_teardown),
1298 : cmocka_unit_test_setup_teardown(test_trace_event_fd__free_in_handler, test_setup, test_teardown),
1299 : cmocka_unit_test_setup_teardown(test_trace_event_timer__loop, test_setup, test_teardown),
1300 : cmocka_unit_test_setup_teardown(test_trace_event_timer__reset, test_setup, test_teardown),
1301 : cmocka_unit_test_setup_teardown(test_trace_event_timer__free, test_setup, test_teardown),
1302 : cmocka_unit_test_setup_teardown(test_trace_event_timer__free_in_handler, test_setup, test_teardown),
1303 : cmocka_unit_test_setup_teardown(test_trace_event_signal__loop, test_setup, test_teardown),
1304 : cmocka_unit_test_setup_teardown(test_trace_event_signal__reset, test_setup, test_teardown),
1305 : cmocka_unit_test_setup_teardown(test_trace_event_signal__free, test_setup, test_teardown),
1306 : cmocka_unit_test_setup_teardown(test_trace_event_signal__free_in_handler, test_setup, test_teardown),
1307 : cmocka_unit_test_setup_teardown(test_trace_event_immediate__loop, test_setup, test_teardown),
1308 : cmocka_unit_test_setup_teardown(test_trace_event_immediate__reset, test_setup, test_teardown),
1309 : cmocka_unit_test_setup_teardown(test_trace_event_immediate__free, test_setup, test_teardown),
1310 : cmocka_unit_test_setup_teardown(test_trace_event_immediate__free_in_handler, test_setup, test_teardown),
1311 : cmocka_unit_test_setup_teardown(test_trace_event_immediate__reschedule, test_setup, test_teardown),
1312 : cmocka_unit_test_setup_teardown(test_trace_queue__loop, test_setup, test_teardown),
1313 : cmocka_unit_test_setup_teardown(test_trace_queue__extra, test_setup, test_teardown),
1314 : cmocka_unit_test_setup_teardown(test_get_set_trace_fd_callback, test_setup, test_teardown),
1315 : cmocka_unit_test_setup_teardown(test_get_set_trace_timer_callback, test_setup, test_teardown),
1316 : cmocka_unit_test_setup_teardown(test_get_set_trace_signal_callback, test_setup, test_teardown),
1317 : cmocka_unit_test_setup_teardown(test_get_set_trace_immediate_callback, test_setup, test_teardown),
1318 : cmocka_unit_test_setup_teardown(test_get_set_trace_queue_callback, test_setup, test_teardown),
1319 : };
1320 :
1321 1 : cmocka_set_message_output(CM_OUTPUT_SUBUNIT);
1322 :
1323 1 : return cmocka_run_group_tests(tests, NULL, NULL);
1324 : }
|