Fix: variable declaration shadows previously declared variable
[babeltrace.git] / tests / lib / test_bt_notification_iterator.c
CommitLineData
223c70b2
PP
1/*
2 * Copyright 2017 - Philippe Proulx <pproulx@efficios.com>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; under version 2 of the License.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
16 */
17
18#include <stdio.h>
19#include <stdlib.h>
20#include <stdint.h>
c55a9f58 21#include <stdbool.h>
223c70b2
PP
22#include <inttypes.h>
23#include <string.h>
24#include <assert.h>
25#include <babeltrace/ctf-ir/event-class.h>
26#include <babeltrace/ctf-ir/event.h>
27#include <babeltrace/ctf-ir/field-types.h>
28#include <babeltrace/ctf-ir/fields.h>
29#include <babeltrace/ctf-ir/packet.h>
30#include <babeltrace/ctf-ir/stream-class.h>
31#include <babeltrace/ctf-ir/stream.h>
32#include <babeltrace/ctf-ir/trace.h>
33#include <babeltrace/graph/clock-class-priority-map.h>
34#include <babeltrace/graph/component-class-filter.h>
35#include <babeltrace/graph/component-class-sink.h>
36#include <babeltrace/graph/component-class-source.h>
37#include <babeltrace/graph/component-class.h>
38#include <babeltrace/graph/component-sink.h>
39#include <babeltrace/graph/component-source.h>
40#include <babeltrace/graph/component.h>
73d5c1ad 41#include <babeltrace/graph/connection.h>
223c70b2
PP
42#include <babeltrace/graph/graph.h>
43#include <babeltrace/graph/notification-event.h>
44#include <babeltrace/graph/notification-inactivity.h>
45#include <babeltrace/graph/notification-iterator.h>
46#include <babeltrace/graph/notification-packet.h>
47#include <babeltrace/graph/notification-stream.h>
e893886e 48#include <babeltrace/graph/output-port-notification-iterator.h>
223c70b2
PP
49#include <babeltrace/graph/port.h>
50#include <babeltrace/graph/private-component-source.h>
b9d103be 51#include <babeltrace/graph/private-component-sink.h>
223c70b2
PP
52#include <babeltrace/graph/private-component.h>
53#include <babeltrace/graph/private-connection.h>
90157d89 54#include <babeltrace/graph/private-connection-private-notification-iterator.h>
223c70b2
PP
55#include <babeltrace/graph/private-port.h>
56#include <babeltrace/plugin/plugin.h>
57#include <babeltrace/ref.h>
58#include <glib.h>
59
60#include "tap/tap.h"
61
e893886e 62#define NR_TESTS 31
223c70b2
PP
63
64enum test {
65 TEST_NO_AUTO_NOTIFS,
66 TEST_AUTO_STREAM_BEGIN_FROM_PACKET_BEGIN,
67 TEST_AUTO_STREAM_BEGIN_FROM_STREAM_END,
68 TEST_AUTO_STREAM_END_FROM_END,
69 TEST_AUTO_PACKET_BEGIN_FROM_PACKET_END,
70 TEST_AUTO_PACKET_BEGIN_FROM_EVENT,
71 TEST_AUTO_PACKET_END_FROM_PACKET_BEGIN,
72 TEST_AUTO_PACKET_END_PACKET_BEGIN_FROM_EVENT,
73 TEST_AUTO_PACKET_END_FROM_STREAM_END,
74 TEST_AUTO_PACKET_END_STREAM_END_FROM_END,
75 TEST_MULTIPLE_AUTO_STREAM_END_FROM_END,
76 TEST_MULTIPLE_AUTO_PACKET_END_STREAM_END_FROM_END,
e893886e 77 TEST_OUTPUT_PORT_NOTIFICATION_ITERATOR,
223c70b2
PP
78};
79
80enum test_event_type {
81 TEST_EV_TYPE_NOTIF_UNEXPECTED,
82 TEST_EV_TYPE_NOTIF_EVENT,
83 TEST_EV_TYPE_NOTIF_INACTIVITY,
84 TEST_EV_TYPE_NOTIF_STREAM_BEGIN,
85 TEST_EV_TYPE_NOTIF_PACKET_BEGIN,
86 TEST_EV_TYPE_NOTIF_PACKET_END,
87 TEST_EV_TYPE_NOTIF_STREAM_END,
88 TEST_EV_TYPE_END,
89 TEST_EV_TYPE_SENTINEL,
90};
91
92struct test_event {
93 enum test_event_type type;
94 struct bt_ctf_stream *stream;
95 struct bt_ctf_packet *packet;
96};
97
223c70b2
PP
98static bool debug = false;
99static enum test current_test;
100static GArray *test_events;
101static struct bt_clock_class_priority_map *src_empty_cc_prio_map;
102static struct bt_ctf_stream_class *src_stream_class;
103static struct bt_ctf_event_class *src_event_class;
104static struct bt_ctf_stream *src_stream1;
105static struct bt_ctf_stream *src_stream2;
106static struct bt_ctf_packet *src_stream1_packet1;
107static struct bt_ctf_packet *src_stream1_packet2;
108static struct bt_ctf_packet *src_stream2_packet1;
109static struct bt_ctf_packet *src_stream2_packet2;
110
111enum {
112 SEQ_END = -1,
113 SEQ_STREAM1_BEGIN = -2,
114 SEQ_STREAM2_BEGIN = -3,
115 SEQ_STREAM1_END = -4,
116 SEQ_STREAM2_END = -5,
117 SEQ_STREAM1_PACKET1_BEGIN = -6,
118 SEQ_STREAM1_PACKET2_BEGIN = -7,
119 SEQ_STREAM2_PACKET1_BEGIN = -8,
120 SEQ_STREAM2_PACKET2_BEGIN = -9,
121 SEQ_STREAM1_PACKET1_END = -10,
122 SEQ_STREAM1_PACKET2_END = -11,
123 SEQ_STREAM2_PACKET1_END = -12,
124 SEQ_STREAM2_PACKET2_END = -13,
125 SEQ_EVENT_STREAM1_PACKET1 = -14,
126 SEQ_EVENT_STREAM1_PACKET2 = -15,
127 SEQ_EVENT_STREAM2_PACKET1 = -16,
128 SEQ_EVENT_STREAM2_PACKET2 = -17,
129 SEQ_INACTIVITY = -18,
130};
131
132struct src_iter_user_data {
133 int64_t *seq;
134 size_t at;
135};
136
137struct sink_user_data {
138 struct bt_notification_iterator *notif_iter;
139};
140
141/*
142 * No automatic notifications generated in this block.
143 * Stream 2 notifications are more indented.
144 */
145static int64_t seq_no_auto_notifs[] = {
146 SEQ_STREAM1_BEGIN,
147 SEQ_STREAM1_PACKET1_BEGIN,
148 SEQ_EVENT_STREAM1_PACKET1,
149 SEQ_EVENT_STREAM1_PACKET1,
150 SEQ_STREAM2_BEGIN,
151 SEQ_EVENT_STREAM1_PACKET1,
152 SEQ_STREAM2_PACKET2_BEGIN,
153 SEQ_EVENT_STREAM2_PACKET2,
154 SEQ_EVENT_STREAM1_PACKET1,
155 SEQ_STREAM1_PACKET1_END,
156 SEQ_STREAM2_PACKET2_END,
157 SEQ_STREAM1_PACKET2_BEGIN,
158 SEQ_EVENT_STREAM1_PACKET2,
159 SEQ_STREAM2_END,
160 SEQ_STREAM1_PACKET2_END,
161 SEQ_STREAM1_END,
162 SEQ_END,
163};
164
165/* Automatic "stream begin" from "packet begin" */
166static int64_t seq_auto_stream_begin_from_packet_begin[] = {
167 /* Automatic "stream begin" here */
168 SEQ_STREAM1_PACKET1_BEGIN,
169 SEQ_STREAM1_PACKET1_END,
170 SEQ_STREAM1_END,
171 SEQ_END,
172};
173
174/* Automatic "stream begin" from "stream end" */
175static int64_t seq_auto_stream_begin_from_stream_end[] = {
176 /* Automatic "stream begin" here */
177 SEQ_STREAM1_END,
178 SEQ_END,
179};
180
181/* Automatic "stream end" from END */
182static int64_t seq_auto_stream_end_from_end[] = {
183 SEQ_STREAM1_BEGIN,
184 /* Automatic "packet end" here */
185 SEQ_END,
186};
187
188/* Automatic "packet begin" from "packet end" */
189static int64_t seq_auto_packet_begin_from_packet_end[] = {
190 SEQ_STREAM1_BEGIN,
191 /* Automatic "packet begin" here */
192 SEQ_STREAM1_PACKET1_END,
193 SEQ_STREAM1_END,
194 SEQ_END,
195};
196
197/* Automatic "packet begin" from event */
198static int64_t seq_auto_packet_begin_from_event[] = {
199 SEQ_STREAM1_BEGIN,
200 /* Automatic "packet begin" here */
201 SEQ_EVENT_STREAM1_PACKET1,
202 SEQ_STREAM1_PACKET1_END,
203 SEQ_STREAM1_END,
204 SEQ_END,
205};
206
207/* Automatic "packet end" from "packet begin" */
208static int64_t seq_auto_packet_end_from_packet_begin[] = {
209 SEQ_STREAM1_BEGIN,
210 SEQ_STREAM1_PACKET1_BEGIN,
211 /* Automatic "packet end" here */
212 SEQ_STREAM1_PACKET2_BEGIN,
213 SEQ_STREAM1_PACKET2_END,
214 SEQ_STREAM1_END,
215 SEQ_END,
216};
217
218/* Automatic "packet end" and "packet begin" from event */
219static int64_t seq_auto_packet_end_packet_begin_from_event[] = {
220 SEQ_STREAM1_BEGIN,
221 SEQ_STREAM1_PACKET1_BEGIN,
222 /* Automatic "packet end" here */
223 /* Automatic "packet begin" here */
224 SEQ_EVENT_STREAM1_PACKET2,
225 SEQ_STREAM1_PACKET2_END,
226 SEQ_STREAM1_END,
227 SEQ_END,
228};
229
230/* Automatic "packet end" from "stream end" */
231static int64_t seq_auto_packet_end_from_stream_end[] = {
232 SEQ_STREAM1_BEGIN,
233 SEQ_STREAM1_PACKET1_BEGIN,
234 /* Automatic "packet end" here */
235 SEQ_STREAM1_END,
236 SEQ_END,
237};
238
239/* Automatic "packet end" and "stream end" from END */
240static int64_t seq_auto_packet_end_stream_end_from_end[] = {
241 SEQ_STREAM1_BEGIN,
242 SEQ_STREAM1_PACKET1_BEGIN,
243 /* Automatic "packet end" here */
244 /* Automatic "stream end" here */
245 SEQ_END,
246};
247
248/* Multiple automatic "stream end" from END */
249static int64_t seq_multiple_auto_stream_end_from_end[] = {
250 SEQ_STREAM1_BEGIN,
251 SEQ_STREAM2_BEGIN,
252 /* Automatic "stream end" here */
253 /* Automatic "stream end" here */
254 SEQ_END,
255};
256
257/* Multiple automatic "packet end" and "stream end" from END */
258static int64_t seq_multiple_auto_packet_end_stream_end_from_end[] = {
259 SEQ_STREAM1_BEGIN,
260 SEQ_STREAM2_BEGIN,
261 SEQ_STREAM1_PACKET1_BEGIN,
262 SEQ_STREAM2_PACKET1_BEGIN,
263 /* Automatic "packet end" here */
264 /* Automatic "stream end" here */
265 /* Automatic "packet end" here */
266 /* Automatic "stream end" here */
267 SEQ_END,
268};
269
270static
271void clear_test_events(void)
272{
273 g_array_set_size(test_events, 0);
274}
275
276static
277void print_test_event(FILE *fp, const struct test_event *event)
278{
279 fprintf(fp, "{ type = ");
280
281 switch (event->type) {
282 case TEST_EV_TYPE_NOTIF_UNEXPECTED:
283 fprintf(fp, "TEST_EV_TYPE_NOTIF_UNEXPECTED");
284 break;
285 case TEST_EV_TYPE_NOTIF_EVENT:
286 fprintf(fp, "TEST_EV_TYPE_NOTIF_EVENT");
287 break;
288 case TEST_EV_TYPE_NOTIF_INACTIVITY:
289 fprintf(fp, "TEST_EV_TYPE_NOTIF_INACTIVITY");
290 break;
291 case TEST_EV_TYPE_NOTIF_STREAM_BEGIN:
292 fprintf(fp, "TEST_EV_TYPE_NOTIF_STREAM_BEGIN");
293 break;
294 case TEST_EV_TYPE_NOTIF_STREAM_END:
295 fprintf(fp, "TEST_EV_TYPE_NOTIF_STREAM_END");
296 break;
297 case TEST_EV_TYPE_NOTIF_PACKET_BEGIN:
298 fprintf(fp, "TEST_EV_TYPE_NOTIF_PACKET_BEGIN");
299 break;
300 case TEST_EV_TYPE_NOTIF_PACKET_END:
301 fprintf(fp, "TEST_EV_TYPE_NOTIF_PACKET_END");
302 break;
303 case TEST_EV_TYPE_END:
304 fprintf(fp, "TEST_EV_TYPE_END");
305 break;
306 case TEST_EV_TYPE_SENTINEL:
307 fprintf(fp, "TEST_EV_TYPE_SENTINEL");
308 break;
309 default:
310 fprintf(fp, "(UNKNOWN)");
311 break;
312 }
313
314 fprintf(fp, ", stream = %p, packet = %p }", event->stream,
315 event->packet);
316}
317
318static
319void append_test_event(struct test_event *event)
320{
321 g_array_append_val(test_events, *event);
322}
323
324static
325bool compare_single_test_events(const struct test_event *ev_a,
326 const struct test_event *ev_b)
327{
328 if (debug) {
329 fprintf(stderr, ":: Comparing test events: ");
330 print_test_event(stderr, ev_a);
331 fprintf(stderr, " vs. ");
332 print_test_event(stderr, ev_b);
333 fprintf(stderr, "\n");
334 }
335
336 if (ev_a->type != ev_b->type) {
337 return false;
338 }
339
340 switch (ev_a->type) {
341 case TEST_EV_TYPE_END:
342 case TEST_EV_TYPE_SENTINEL:
343 break;
344 default:
345 if (ev_a->stream != ev_b->stream) {
346 return false;
347 }
348
349 if (ev_a->packet != ev_b->packet) {
350 return false;
351 }
352 break;
353 }
354
355 return true;
356}
357
358static
359bool compare_test_events(const struct test_event *expected_events)
360{
361 const struct test_event *expected_event = expected_events;
362 size_t i = 0;
363
364 assert(expected_events);
365
366 while (true) {
367 const struct test_event *event;
368
369 if (expected_event->type == TEST_EV_TYPE_SENTINEL) {
370 break;
371 }
372
373 if (i >= test_events->len) {
374 return false;
375 }
376
377 event = &g_array_index(test_events, struct test_event, i);
378
379 if (!compare_single_test_events(event, expected_event)) {
380 return false;
381 }
382
383 i++;
384 expected_event++;
385 }
386
387 if (i != test_events->len) {
388 return false;
389 }
390
391 return true;
392}
393
394static
395void init_static_data(void)
396{
397 int ret;
398 struct bt_ctf_trace *trace;
399 struct bt_ctf_field_type *empty_struct_ft;
400
401 /* Test events */
402 test_events = g_array_new(FALSE, TRUE, sizeof(struct test_event));
403 assert(test_events);
404
405 /* Metadata */
406 empty_struct_ft = bt_ctf_field_type_structure_create();
407 assert(empty_struct_ft);
408 trace = bt_ctf_trace_create();
409 assert(trace);
223c70b2
PP
410 ret = bt_ctf_trace_set_packet_header_type(trace, empty_struct_ft);
411 assert(ret == 0);
412 src_empty_cc_prio_map = bt_clock_class_priority_map_create();
413 assert(src_empty_cc_prio_map);
414 src_stream_class = bt_ctf_stream_class_create("my-stream-class");
415 assert(src_stream_class);
416 ret = bt_ctf_stream_class_set_packet_context_type(src_stream_class,
417 empty_struct_ft);
418 assert(ret == 0);
419 ret = bt_ctf_stream_class_set_event_header_type(src_stream_class,
420 empty_struct_ft);
421 assert(ret == 0);
422 ret = bt_ctf_stream_class_set_event_context_type(src_stream_class,
423 empty_struct_ft);
424 assert(ret == 0);
425 src_event_class = bt_ctf_event_class_create("my-event-class");
426 ret = bt_ctf_event_class_set_context_type(src_event_class,
427 empty_struct_ft);
428 assert(ret == 0);
429 ret = bt_ctf_event_class_set_context_type(src_event_class,
430 empty_struct_ft);
431 assert(ret == 0);
432 ret = bt_ctf_stream_class_add_event_class(src_stream_class,
433 src_event_class);
434 assert(ret == 0);
435 ret = bt_ctf_trace_add_stream_class(trace, src_stream_class);
436 assert(ret == 0);
437 src_stream1 = bt_ctf_stream_create(src_stream_class, "stream-1");
438 assert(src_stream1);
439 src_stream2 = bt_ctf_stream_create(src_stream_class, "stream-2");
440 assert(src_stream2);
441 src_stream1_packet1 = bt_ctf_packet_create(src_stream1);
442 assert(src_stream1_packet1);
443 src_stream1_packet2 = bt_ctf_packet_create(src_stream1);
444 assert(src_stream1_packet2);
445 src_stream2_packet1 = bt_ctf_packet_create(src_stream2);
446 assert(src_stream2_packet1);
447 src_stream2_packet2 = bt_ctf_packet_create(src_stream2);
448 assert(src_stream2_packet2);
449
450 if (debug) {
451 fprintf(stderr, ":: stream 1: %p\n", src_stream1);
452 fprintf(stderr, ":: stream 2: %p\n", src_stream2);
453 fprintf(stderr, ":: stream 1, packet 1: %p\n", src_stream1_packet1);
454 fprintf(stderr, ":: stream 1, packet 2: %p\n", src_stream1_packet2);
455 fprintf(stderr, ":: stream 2, packet 1: %p\n", src_stream2_packet1);
456 fprintf(stderr, ":: stream 2, packet 2: %p\n", src_stream2_packet2);
457 }
458
459 bt_put(trace);
460 bt_put(empty_struct_ft);
461}
462
463static
464void fini_static_data(void)
465{
466 /* Test events */
467 g_array_free(test_events, TRUE);
468
469 /* Metadata */
470 bt_put(src_empty_cc_prio_map);
471 bt_put(src_stream_class);
472 bt_put(src_event_class);
473 bt_put(src_stream1);
474 bt_put(src_stream2);
475 bt_put(src_stream1_packet1);
476 bt_put(src_stream1_packet2);
477 bt_put(src_stream2_packet1);
478 bt_put(src_stream2_packet2);
479}
480
481static
482void src_iter_finalize(
90157d89 483 struct bt_private_connection_private_notification_iterator *private_notification_iterator)
223c70b2
PP
484{
485 struct src_iter_user_data *user_data =
90157d89 486 bt_private_connection_private_notification_iterator_get_user_data(
223c70b2
PP
487 private_notification_iterator);
488
489 if (user_data) {
490 g_free(user_data);
491 }
492}
493
494static
495enum bt_notification_iterator_status src_iter_init(
90157d89 496 struct bt_private_connection_private_notification_iterator *priv_notif_iter,
223c70b2
PP
497 struct bt_private_port *private_port)
498{
499 struct src_iter_user_data *user_data =
500 g_new0(struct src_iter_user_data, 1);
501 int ret;
502
503 assert(user_data);
e893886e
PP
504 ret = bt_private_connection_private_notification_iterator_set_user_data(
505 priv_notif_iter, user_data);
223c70b2
PP
506 assert(ret == 0);
507
508 switch (current_test) {
509 case TEST_NO_AUTO_NOTIFS:
e893886e 510 case TEST_OUTPUT_PORT_NOTIFICATION_ITERATOR:
223c70b2
PP
511 user_data->seq = seq_no_auto_notifs;
512 break;
513 case TEST_AUTO_STREAM_BEGIN_FROM_PACKET_BEGIN:
514 user_data->seq = seq_auto_stream_begin_from_packet_begin;
515 break;
516 case TEST_AUTO_STREAM_BEGIN_FROM_STREAM_END:
517 user_data->seq = seq_auto_stream_begin_from_stream_end;
518 break;
519 case TEST_AUTO_STREAM_END_FROM_END:
520 user_data->seq = seq_auto_stream_end_from_end;
521 break;
522 case TEST_AUTO_PACKET_BEGIN_FROM_PACKET_END:
523 user_data->seq = seq_auto_packet_begin_from_packet_end;
524 break;
525 case TEST_AUTO_PACKET_BEGIN_FROM_EVENT:
526 user_data->seq = seq_auto_packet_begin_from_event;
527 break;
528 case TEST_AUTO_PACKET_END_FROM_PACKET_BEGIN:
529 user_data->seq = seq_auto_packet_end_from_packet_begin;
530 break;
531 case TEST_AUTO_PACKET_END_PACKET_BEGIN_FROM_EVENT:
532 user_data->seq = seq_auto_packet_end_packet_begin_from_event;
533 break;
534 case TEST_AUTO_PACKET_END_FROM_STREAM_END:
535 user_data->seq = seq_auto_packet_end_from_stream_end;
536 break;
537 case TEST_AUTO_PACKET_END_STREAM_END_FROM_END:
538 user_data->seq = seq_auto_packet_end_stream_end_from_end;
539 break;
540 case TEST_MULTIPLE_AUTO_STREAM_END_FROM_END:
541 user_data->seq = seq_multiple_auto_stream_end_from_end;
542 break;
543 case TEST_MULTIPLE_AUTO_PACKET_END_STREAM_END_FROM_END:
544 user_data->seq = seq_multiple_auto_packet_end_stream_end_from_end;
545 break;
546 default:
0fbb9a9f 547 abort();
223c70b2
PP
548 }
549
550 return BT_NOTIFICATION_ITERATOR_STATUS_OK;
551}
552
553static
554struct bt_ctf_event *src_create_event(struct bt_ctf_packet *packet)
555{
556 struct bt_ctf_event *event = bt_ctf_event_create(src_event_class);
557 int ret;
558
559 assert(event);
560 ret = bt_ctf_event_set_packet(event, packet);
561 assert(ret == 0);
562 return event;
563}
564
565static
90157d89 566struct bt_notification_iterator_next_method_return src_iter_next_seq(
223c70b2
PP
567 struct src_iter_user_data *user_data)
568{
90157d89 569 struct bt_notification_iterator_next_method_return next_return = {
223c70b2
PP
570 .status = BT_NOTIFICATION_ITERATOR_STATUS_OK,
571 };
572 int64_t cur_ts_ns;
573 struct bt_ctf_packet *event_packet = NULL;
574
575 assert(user_data->seq);
576 cur_ts_ns = user_data->seq[user_data->at];
577
578 switch (cur_ts_ns) {
579 case SEQ_END:
580 next_return.status =
581 BT_NOTIFICATION_ITERATOR_STATUS_END;
582 break;
583 case SEQ_INACTIVITY:
584 next_return.notification =
585 bt_notification_inactivity_create(src_empty_cc_prio_map);
586 assert(next_return.notification);
587 break;
588 case SEQ_STREAM1_BEGIN:
589 next_return.notification =
590 bt_notification_stream_begin_create(src_stream1);
591 assert(next_return.notification);
592 break;
593 case SEQ_STREAM2_BEGIN:
594 next_return.notification =
595 bt_notification_stream_begin_create(src_stream2);
596 assert(next_return.notification);
597 break;
598 case SEQ_STREAM1_END:
599 next_return.notification =
600 bt_notification_stream_end_create(src_stream1);
601 assert(next_return.notification);
602 break;
603 case SEQ_STREAM2_END:
604 next_return.notification =
605 bt_notification_stream_end_create(src_stream2);
606 assert(next_return.notification);
607 break;
608 case SEQ_STREAM1_PACKET1_BEGIN:
609 next_return.notification =
610 bt_notification_packet_begin_create(src_stream1_packet1);
611 assert(next_return.notification);
612 break;
613 case SEQ_STREAM1_PACKET2_BEGIN:
614 next_return.notification =
615 bt_notification_packet_begin_create(src_stream1_packet2);
616 assert(next_return.notification);
617 break;
618 case SEQ_STREAM2_PACKET1_BEGIN:
619 next_return.notification =
620 bt_notification_packet_begin_create(src_stream2_packet1);
621 assert(next_return.notification);
622 break;
623 case SEQ_STREAM2_PACKET2_BEGIN:
624 next_return.notification =
625 bt_notification_packet_begin_create(src_stream2_packet2);
626 assert(next_return.notification);
627 break;
628 case SEQ_STREAM1_PACKET1_END:
629 next_return.notification =
630 bt_notification_packet_end_create(src_stream1_packet1);
631 assert(next_return.notification);
632 break;
633 case SEQ_STREAM1_PACKET2_END:
634 next_return.notification =
635 bt_notification_packet_end_create(src_stream1_packet2);
636 assert(next_return.notification);
637 break;
638 case SEQ_STREAM2_PACKET1_END:
639 next_return.notification =
640 bt_notification_packet_end_create(src_stream2_packet1);
641 assert(next_return.notification);
642 break;
643 case SEQ_STREAM2_PACKET2_END:
644 next_return.notification =
645 bt_notification_packet_end_create(src_stream2_packet2);
646 assert(next_return.notification);
647 break;
648 case SEQ_EVENT_STREAM1_PACKET1:
649 event_packet = src_stream1_packet1;
650 break;
651 case SEQ_EVENT_STREAM1_PACKET2:
652 event_packet = src_stream1_packet2;
653 break;
654 case SEQ_EVENT_STREAM2_PACKET1:
655 event_packet = src_stream2_packet1;
656 break;
657 case SEQ_EVENT_STREAM2_PACKET2:
658 event_packet = src_stream2_packet2;
659 break;
660 default:
0fbb9a9f 661 abort();
223c70b2
PP
662 }
663
664 if (event_packet) {
665 struct bt_ctf_event *event = src_create_event(event_packet);
666
667 assert(event);
668 next_return.notification = bt_notification_event_create(event,
669 src_empty_cc_prio_map);
670 bt_put(event);
671 assert(next_return.notification);
672 }
673
674 if (next_return.status != BT_NOTIFICATION_ITERATOR_STATUS_END) {
675 user_data->at++;
676 }
677
678 return next_return;
679}
680
681static
90157d89
PP
682struct bt_notification_iterator_next_method_return src_iter_next(
683 struct bt_private_connection_private_notification_iterator *priv_iterator)
223c70b2 684{
90157d89 685 struct bt_notification_iterator_next_method_return next_return = {
223c70b2
PP
686 .status = BT_NOTIFICATION_ITERATOR_STATUS_OK,
687 .notification = NULL,
688 };
689 struct src_iter_user_data *user_data =
90157d89 690 bt_private_connection_private_notification_iterator_get_user_data(priv_iterator);
223c70b2
PP
691
692 assert(user_data);
693 next_return = src_iter_next_seq(user_data);
694 return next_return;
695}
696
697static
698enum bt_component_status src_init(
699 struct bt_private_component *private_component,
700 struct bt_value *params, void *init_method_data)
701{
147337a3 702 int ret;
b9d103be 703
147337a3
PP
704 ret = bt_private_component_source_add_output_private_port(
705 private_component, "out", NULL, NULL);
706 assert(ret == 0);
223c70b2
PP
707 return BT_COMPONENT_STATUS_OK;
708}
709
710static
711void src_finalize(struct bt_private_component *private_component)
712{
713}
714
715static
e893886e
PP
716enum bt_notification_iterator_status common_consume(
717 struct bt_notification_iterator *notif_iter)
223c70b2 718{
e893886e 719 enum bt_notification_iterator_status ret;
223c70b2 720 struct bt_notification *notification = NULL;
223c70b2
PP
721 struct test_event test_event = { 0 };
722 bool do_append_test_event = true;
e893886e 723 assert(notif_iter);
223c70b2 724
e893886e
PP
725 ret = bt_notification_iterator_next(notif_iter);
726 if (ret < 0) {
223c70b2
PP
727 do_append_test_event = false;
728 goto end;
729 }
730
e893886e 731 switch (ret) {
223c70b2
PP
732 case BT_NOTIFICATION_ITERATOR_STATUS_END:
733 test_event.type = TEST_EV_TYPE_END;
223c70b2
PP
734 goto end;
735 case BT_NOTIFICATION_ITERATOR_STATUS_AGAIN:
0fbb9a9f 736 abort();
223c70b2
PP
737 default:
738 break;
739 }
740
741 notification = bt_notification_iterator_get_notification(
e893886e 742 notif_iter);
223c70b2
PP
743 assert(notification);
744
745 switch (bt_notification_get_type(notification)) {
746 case BT_NOTIFICATION_TYPE_EVENT:
747 {
748 struct bt_ctf_event *event;
749
750 test_event.type = TEST_EV_TYPE_NOTIF_EVENT;
751 event = bt_notification_event_get_event(notification);
752 assert(event);
753 test_event.packet = bt_ctf_event_get_packet(event);
754 bt_put(event);
755 assert(test_event.packet);
756 bt_put(test_event.packet);
757 break;
758 }
759 case BT_NOTIFICATION_TYPE_INACTIVITY:
760 test_event.type = TEST_EV_TYPE_NOTIF_INACTIVITY;
761 break;
762 case BT_NOTIFICATION_TYPE_STREAM_BEGIN:
763 test_event.type = TEST_EV_TYPE_NOTIF_STREAM_BEGIN;
764 test_event.stream =
765 bt_notification_stream_begin_get_stream(notification);
766 assert(test_event.stream);
767 bt_put(test_event.stream);
768 break;
769 case BT_NOTIFICATION_TYPE_STREAM_END:
770 test_event.type = TEST_EV_TYPE_NOTIF_STREAM_END;
771 test_event.stream =
772 bt_notification_stream_end_get_stream(notification);
773 assert(test_event.stream);
774 bt_put(test_event.stream);
775 break;
776 case BT_NOTIFICATION_TYPE_PACKET_BEGIN:
777 test_event.type = TEST_EV_TYPE_NOTIF_PACKET_BEGIN;
778 test_event.packet =
779 bt_notification_packet_begin_get_packet(notification);
780 assert(test_event.packet);
781 bt_put(test_event.packet);
782 break;
783 case BT_NOTIFICATION_TYPE_PACKET_END:
784 test_event.type = TEST_EV_TYPE_NOTIF_PACKET_END;
785 test_event.packet =
786 bt_notification_packet_end_get_packet(notification);
787 assert(test_event.packet);
788 bt_put(test_event.packet);
789 break;
790 default:
791 test_event.type = TEST_EV_TYPE_NOTIF_UNEXPECTED;
792 break;
793 }
794
795 if (test_event.packet) {
796 test_event.stream = bt_ctf_packet_get_stream(test_event.packet);
797 assert(test_event.stream);
798 bt_put(test_event.stream);
799 }
800
801end:
802 if (do_append_test_event) {
803 append_test_event(&test_event);
804 }
805
806 bt_put(notification);
807 return ret;
808}
809
e893886e
PP
810static
811enum bt_component_status sink_consume(
812 struct bt_private_component *priv_component)
813{
814 enum bt_component_status ret = BT_COMPONENT_STATUS_OK;
815 struct sink_user_data *user_data =
816 bt_private_component_get_user_data(priv_component);
817 enum bt_notification_iterator_status it_ret;
818
819 assert(user_data && user_data->notif_iter);
820 it_ret = common_consume(user_data->notif_iter);
821
822 if (it_ret < 0) {
823 ret = BT_COMPONENT_STATUS_ERROR;
824 goto end;
825 }
826
827 switch (it_ret) {
828 case BT_NOTIFICATION_ITERATOR_STATUS_END:
829 ret = BT_COMPONENT_STATUS_END;
830 BT_PUT(user_data->notif_iter);
831 goto end;
832 case BT_NOTIFICATION_ITERATOR_STATUS_AGAIN:
833 abort();
834 default:
835 break;
836 }
837
838end:
839 return ret;
840}
841
223c70b2
PP
842static
843void sink_port_connected(struct bt_private_component *private_component,
844 struct bt_private_port *self_private_port,
845 struct bt_port *other_port)
846{
847 struct bt_private_connection *priv_conn =
848 bt_private_port_get_private_connection(self_private_port);
849 struct sink_user_data *user_data = bt_private_component_get_user_data(
850 private_component);
73d5c1ad 851 enum bt_connection_status conn_status;
223c70b2
PP
852
853 assert(user_data);
854 assert(priv_conn);
73d5c1ad
PP
855 conn_status = bt_private_connection_create_notification_iterator(
856 priv_conn, NULL, &user_data->notif_iter);
857 assert(conn_status == 0);
223c70b2
PP
858 bt_put(priv_conn);
859}
860
861static
862enum bt_component_status sink_init(
863 struct bt_private_component *private_component,
864 struct bt_value *params, void *init_method_data)
865{
866 struct sink_user_data *user_data = g_new0(struct sink_user_data, 1);
867 int ret;
868
869 assert(user_data);
870 ret = bt_private_component_set_user_data(private_component,
871 user_data);
872 assert(ret == 0);
147337a3
PP
873 ret = bt_private_component_sink_add_input_private_port(
874 private_component, "in", NULL, NULL);
875 assert(ret == 0);
223c70b2
PP
876 return BT_COMPONENT_STATUS_OK;
877}
878
879static
880void sink_finalize(struct bt_private_component *private_component)
881{
882 struct sink_user_data *user_data = bt_private_component_get_user_data(
883 private_component);
884
885 if (user_data) {
886 bt_put(user_data->notif_iter);
887 g_free(user_data);
888 }
889}
890
891static
36712f1d 892void create_source_sink(struct bt_graph *graph, struct bt_component **source,
223c70b2
PP
893 struct bt_component **sink)
894{
895 struct bt_component_class *src_comp_class;
896 struct bt_component_class *sink_comp_class;
897 int ret;
898
899 /* Create source component */
e893886e
PP
900 if (source) {
901 src_comp_class = bt_component_class_source_create("src",
902 src_iter_next);
903 assert(src_comp_class);
904 ret = bt_component_class_set_init_method(src_comp_class,
905 src_init);
906 assert(ret == 0);
907 ret = bt_component_class_set_finalize_method(src_comp_class,
908 src_finalize);
909 assert(ret == 0);
910 ret = bt_component_class_source_set_notification_iterator_init_method(
911 src_comp_class, src_iter_init);
912 assert(ret == 0);
913 ret = bt_component_class_source_set_notification_iterator_finalize_method(
914 src_comp_class, src_iter_finalize);
915 assert(ret == 0);
916 ret = bt_graph_add_component(graph, src_comp_class, "source",
917 NULL, source);
918 assert(ret == 0);
919 bt_put(src_comp_class);
920 }
223c70b2
PP
921
922 /* Create sink component */
e893886e
PP
923 if (sink) {
924 sink_comp_class = bt_component_class_sink_create("sink",
925 sink_consume);
926 assert(sink_comp_class);
927 ret = bt_component_class_set_init_method(sink_comp_class,
928 sink_init);
929 assert(ret == 0);
930 ret = bt_component_class_set_finalize_method(sink_comp_class,
931 sink_finalize);
932 ret = bt_component_class_set_port_connected_method(
933 sink_comp_class, sink_port_connected);
934 assert(ret == 0);
935 ret = bt_graph_add_component(graph, sink_comp_class, "sink",
936 NULL, sink);
937 assert(ret == 0);
938 bt_put(sink_comp_class);
939 }
223c70b2
PP
940}
941
942static
943void do_std_test(enum test test, const char *name,
944 const struct test_event *expected_test_events)
945{
946 struct bt_component *src_comp;
947 struct bt_component *sink_comp;
948 struct bt_port *upstream_port;
949 struct bt_port *downstream_port;
950 struct bt_graph *graph;
223c70b2
PP
951 enum bt_graph_status graph_status = BT_GRAPH_STATUS_OK;
952
953 clear_test_events();
954 current_test = test;
955 diag("test: %s", name);
223c70b2
PP
956 graph = bt_graph_create();
957 assert(graph);
36712f1d 958 create_source_sink(graph, &src_comp, &sink_comp);
223c70b2
PP
959
960 /* Connect source to sink */
b9d103be 961 upstream_port = bt_component_source_get_output_port_by_name(src_comp, "out");
223c70b2 962 assert(upstream_port);
b9d103be 963 downstream_port = bt_component_sink_get_input_port_by_name(sink_comp, "in");
223c70b2 964 assert(downstream_port);
a256a42d
PP
965 graph_status = bt_graph_connect_ports(graph, upstream_port,
966 downstream_port, NULL);
223c70b2
PP
967 bt_put(upstream_port);
968 bt_put(downstream_port);
969
970 /* Run the graph until the end */
971 while (graph_status == BT_GRAPH_STATUS_OK ||
972 graph_status == BT_GRAPH_STATUS_AGAIN) {
973 graph_status = bt_graph_run(graph);
974 }
975
976 ok(graph_status == BT_GRAPH_STATUS_END, "graph finishes without any error");
977
978 /* Compare the resulting test events */
979 if (expected_test_events) {
980 ok(compare_test_events(expected_test_events),
981 "the produced sequence of test events is the expected one");
982 }
983
984 bt_put(src_comp);
985 bt_put(sink_comp);
986 bt_put(graph);
987}
988
989static
990void test_no_auto_notifs(void)
991{
992 const struct test_event expected_test_events[] = {
993 { .type = TEST_EV_TYPE_NOTIF_STREAM_BEGIN, .stream = src_stream1, .packet = NULL, },
994 { .type = TEST_EV_TYPE_NOTIF_PACKET_BEGIN, .stream = src_stream1, .packet = src_stream1_packet1, },
995 { .type = TEST_EV_TYPE_NOTIF_EVENT, .stream = src_stream1, .packet = src_stream1_packet1, },
996 { .type = TEST_EV_TYPE_NOTIF_EVENT, .stream = src_stream1, .packet = src_stream1_packet1, },
997 { .type = TEST_EV_TYPE_NOTIF_STREAM_BEGIN, .stream = src_stream2, .packet = NULL, },
998 { .type = TEST_EV_TYPE_NOTIF_EVENT, .stream = src_stream1, .packet = src_stream1_packet1, },
999 { .type = TEST_EV_TYPE_NOTIF_PACKET_BEGIN, .stream = src_stream2, .packet = src_stream2_packet2, },
1000 { .type = TEST_EV_TYPE_NOTIF_EVENT, .stream = src_stream2, .packet = src_stream2_packet2, },
1001 { .type = TEST_EV_TYPE_NOTIF_EVENT, .stream = src_stream1, .packet = src_stream1_packet1, },
1002 { .type = TEST_EV_TYPE_NOTIF_PACKET_END, .stream = src_stream1, .packet = src_stream1_packet1, },
1003 { .type = TEST_EV_TYPE_NOTIF_PACKET_END, .stream = src_stream2, .packet = src_stream2_packet2, },
1004 { .type = TEST_EV_TYPE_NOTIF_PACKET_BEGIN, .stream = src_stream1, .packet = src_stream1_packet2, },
1005 { .type = TEST_EV_TYPE_NOTIF_EVENT, .stream = src_stream1, .packet = src_stream1_packet2, },
1006 { .type = TEST_EV_TYPE_NOTIF_STREAM_END, .stream = src_stream2, .packet = NULL, },
1007 { .type = TEST_EV_TYPE_NOTIF_PACKET_END, .stream = src_stream1, .packet = src_stream1_packet2, },
1008 { .type = TEST_EV_TYPE_NOTIF_STREAM_END, .stream = src_stream1, .packet = NULL, },
1009 { .type = TEST_EV_TYPE_END, },
1010 { .type = TEST_EV_TYPE_SENTINEL, },
1011 };
1012
1013 do_std_test(TEST_NO_AUTO_NOTIFS, "no automatic notifications",
1014 expected_test_events);
1015}
1016
1017static
1018void test_auto_stream_begin_from_packet_begin(void)
1019{
1020 const struct test_event expected_test_events[] = {
1021 { .type = TEST_EV_TYPE_NOTIF_STREAM_BEGIN, .stream = src_stream1, .packet = NULL, },
1022 { .type = TEST_EV_TYPE_NOTIF_PACKET_BEGIN, .stream = src_stream1, .packet = src_stream1_packet1, },
1023 { .type = TEST_EV_TYPE_NOTIF_PACKET_END, .stream = src_stream1, .packet = src_stream1_packet1, },
1024 { .type = TEST_EV_TYPE_NOTIF_STREAM_END, .stream = src_stream1, .packet = NULL, },
1025 { .type = TEST_EV_TYPE_END, },
1026 { .type = TEST_EV_TYPE_SENTINEL, },
1027 };
1028
1029 do_std_test(TEST_AUTO_STREAM_BEGIN_FROM_PACKET_BEGIN,
1030 "automatic \"stream begin\" notif. caused by \"packet begin\" notif.",
1031 expected_test_events);
1032}
1033
1034static
1035void test_auto_stream_begin_from_stream_end(void)
1036{
1037 const struct test_event expected_test_events[] = {
1038 { .type = TEST_EV_TYPE_NOTIF_STREAM_BEGIN, .stream = src_stream1, .packet = NULL, },
1039 { .type = TEST_EV_TYPE_NOTIF_STREAM_END, .stream = src_stream1, .packet = NULL, },
1040 { .type = TEST_EV_TYPE_END, },
1041 { .type = TEST_EV_TYPE_SENTINEL, },
1042 };
1043
1044 do_std_test(TEST_AUTO_STREAM_BEGIN_FROM_STREAM_END,
1045 "automatic \"stream begin\" notif. caused by \"stream end\" notif.",
1046 expected_test_events);
1047}
1048
1049static
1050void test_auto_stream_end_from_end(void)
1051{
1052 const struct test_event expected_test_events[] = {
1053 { .type = TEST_EV_TYPE_NOTIF_STREAM_BEGIN, .stream = src_stream1, .packet = NULL, },
1054 { .type = TEST_EV_TYPE_NOTIF_STREAM_END, .stream = src_stream1, .packet = NULL, },
1055 { .type = TEST_EV_TYPE_END, },
1056 { .type = TEST_EV_TYPE_SENTINEL, },
1057 };
1058
1059 do_std_test(TEST_AUTO_STREAM_END_FROM_END,
1060 "automatic \"stream end\" notif. caused by BT_NOTIFICATION_ITERATOR_STATUS_END",
1061 expected_test_events);
1062}
1063
1064static
1065void test_auto_packet_begin_from_packet_end(void)
1066{
1067 const struct test_event expected_test_events[] = {
1068 { .type = TEST_EV_TYPE_NOTIF_STREAM_BEGIN, .stream = src_stream1, .packet = NULL, },
1069 { .type = TEST_EV_TYPE_NOTIF_PACKET_BEGIN, .stream = src_stream1, .packet = src_stream1_packet1, },
1070 { .type = TEST_EV_TYPE_NOTIF_PACKET_END, .stream = src_stream1, .packet = src_stream1_packet1, },
1071 { .type = TEST_EV_TYPE_NOTIF_STREAM_END, .stream = src_stream1, .packet = NULL, },
1072 { .type = TEST_EV_TYPE_END, },
1073 { .type = TEST_EV_TYPE_SENTINEL, },
1074 };
1075
1076 do_std_test(TEST_AUTO_PACKET_BEGIN_FROM_PACKET_END,
1077 "automatic \"packet begin\" notif. caused by \"packet end\" notif.",
1078 expected_test_events);
1079}
1080
1081static
1082void test_auto_packet_begin_from_event(void)
1083{
1084 const struct test_event expected_test_events[] = {
1085 { .type = TEST_EV_TYPE_NOTIF_STREAM_BEGIN, .stream = src_stream1, .packet = NULL, },
1086 { .type = TEST_EV_TYPE_NOTIF_PACKET_BEGIN, .stream = src_stream1, .packet = src_stream1_packet1, },
1087 { .type = TEST_EV_TYPE_NOTIF_EVENT, .stream = src_stream1, .packet = src_stream1_packet1, },
1088 { .type = TEST_EV_TYPE_NOTIF_PACKET_END, .stream = src_stream1, .packet = src_stream1_packet1, },
1089 { .type = TEST_EV_TYPE_NOTIF_STREAM_END, .stream = src_stream1, .packet = NULL, },
1090 { .type = TEST_EV_TYPE_END, },
1091 { .type = TEST_EV_TYPE_SENTINEL, },
1092 };
1093
1094 do_std_test(TEST_AUTO_PACKET_BEGIN_FROM_EVENT,
1095 "automatic \"packet begin\" notif. caused by event notif.",
1096 expected_test_events);
1097}
1098
1099static
1100void test_auto_packet_end_from_packet_begin(void)
1101{
1102 const struct test_event expected_test_events[] = {
1103 { .type = TEST_EV_TYPE_NOTIF_STREAM_BEGIN, .stream = src_stream1, .packet = NULL, },
1104 { .type = TEST_EV_TYPE_NOTIF_PACKET_BEGIN, .stream = src_stream1, .packet = src_stream1_packet1, },
1105 { .type = TEST_EV_TYPE_NOTIF_PACKET_END, .stream = src_stream1, .packet = src_stream1_packet1, },
1106 { .type = TEST_EV_TYPE_NOTIF_PACKET_BEGIN, .stream = src_stream1, .packet = src_stream1_packet2, },
1107 { .type = TEST_EV_TYPE_NOTIF_PACKET_END, .stream = src_stream1, .packet = src_stream1_packet2, },
1108 { .type = TEST_EV_TYPE_NOTIF_STREAM_END, .stream = src_stream1, .packet = NULL, },
1109 { .type = TEST_EV_TYPE_END, },
1110 { .type = TEST_EV_TYPE_SENTINEL, },
1111 };
1112
1113 do_std_test(TEST_AUTO_PACKET_END_FROM_PACKET_BEGIN,
1114 "automatic \"packet end\" notif. caused by \"packet begin\" notif.",
1115 expected_test_events);
1116}
1117
1118static
1119void test_auto_packet_end_packet_begin_from_event(void)
1120{
1121 const struct test_event expected_test_events[] = {
1122 { .type = TEST_EV_TYPE_NOTIF_STREAM_BEGIN, .stream = src_stream1, .packet = NULL, },
1123 { .type = TEST_EV_TYPE_NOTIF_PACKET_BEGIN, .stream = src_stream1, .packet = src_stream1_packet1, },
1124 { .type = TEST_EV_TYPE_NOTIF_PACKET_END, .stream = src_stream1, .packet = src_stream1_packet1, },
1125 { .type = TEST_EV_TYPE_NOTIF_PACKET_BEGIN, .stream = src_stream1, .packet = src_stream1_packet2, },
1126 { .type = TEST_EV_TYPE_NOTIF_EVENT, .stream = src_stream1, .packet = src_stream1_packet2, },
1127 { .type = TEST_EV_TYPE_NOTIF_PACKET_END, .stream = src_stream1, .packet = src_stream1_packet2, },
1128 { .type = TEST_EV_TYPE_NOTIF_STREAM_END, .stream = src_stream1, .packet = NULL, },
1129 { .type = TEST_EV_TYPE_END, },
1130 { .type = TEST_EV_TYPE_SENTINEL, },
1131 };
1132
1133 do_std_test(TEST_AUTO_PACKET_END_PACKET_BEGIN_FROM_EVENT,
1134 "automatic \"packet end\" and \"packet begin\" notifs. caused by event notif.",
1135 expected_test_events);
1136}
1137
1138static
1139void test_auto_packet_end_from_stream_end(void)
1140{
1141 const struct test_event expected_test_events[] = {
1142 { .type = TEST_EV_TYPE_NOTIF_STREAM_BEGIN, .stream = src_stream1, .packet = NULL, },
1143 { .type = TEST_EV_TYPE_NOTIF_PACKET_BEGIN, .stream = src_stream1, .packet = src_stream1_packet1, },
1144 { .type = TEST_EV_TYPE_NOTIF_PACKET_END, .stream = src_stream1, .packet = src_stream1_packet1, },
1145 { .type = TEST_EV_TYPE_NOTIF_STREAM_END, .stream = src_stream1, .packet = NULL, },
1146 { .type = TEST_EV_TYPE_END, },
1147 { .type = TEST_EV_TYPE_SENTINEL, },
1148 };
1149
1150 do_std_test(TEST_AUTO_PACKET_END_FROM_STREAM_END,
1151 "automatic \"packet end\" notif. caused by \"stream end\" notif.",
1152 expected_test_events);
1153}
1154
1155static
1156void test_auto_packet_end_stream_end_from_end(void)
1157{
1158 const struct test_event expected_test_events[] = {
1159 { .type = TEST_EV_TYPE_NOTIF_STREAM_BEGIN, .stream = src_stream1, .packet = NULL, },
1160 { .type = TEST_EV_TYPE_NOTIF_PACKET_BEGIN, .stream = src_stream1, .packet = src_stream1_packet1, },
1161 { .type = TEST_EV_TYPE_NOTIF_PACKET_END, .stream = src_stream1, .packet = src_stream1_packet1, },
1162 { .type = TEST_EV_TYPE_NOTIF_STREAM_END, .stream = src_stream1, .packet = NULL, },
1163 { .type = TEST_EV_TYPE_END, },
1164 { .type = TEST_EV_TYPE_SENTINEL, },
1165 };
1166
1167 do_std_test(TEST_AUTO_PACKET_END_STREAM_END_FROM_END,
1168 "automatic \"packet end\" and \"stream end\" notifs. caused by BT_NOTIFICATION_ITERATOR_STATUS_END",
1169 expected_test_events);
1170}
1171
1172static
1173void test_multiple_auto_stream_end_from_end(void)
1174{
1175 bool expected = true;
1176 struct test_event expected_event;
1177 struct test_event expected_event2;
1178 struct test_event *event;
1179 struct test_event *event2;
1180
1181 do_std_test(TEST_MULTIPLE_AUTO_STREAM_END_FROM_END,
1182 "multiple automatic \"stream end\" notifs. caused by BT_NOTIFICATION_ITERATOR_STATUS_END",
1183 NULL);
1184
1185 if (test_events->len != 5) {
1186 expected = false;
1187 goto end;
1188 }
1189
1190 expected_event.type = TEST_EV_TYPE_NOTIF_STREAM_BEGIN;
1191 expected_event.stream = src_stream1;
1192 expected_event.packet = NULL;
1193 event = &g_array_index(test_events, struct test_event, 0);
1194 if (!compare_single_test_events(event, &expected_event)) {
1195 expected = false;
1196 goto end;
1197 }
1198
1199 expected_event.type = TEST_EV_TYPE_NOTIF_STREAM_BEGIN;
1200 expected_event.stream = src_stream2;
1201 expected_event.packet = NULL;
1202 event = &g_array_index(test_events, struct test_event, 1);
1203 if (!compare_single_test_events(event, &expected_event)) {
1204 expected = false;
1205 goto end;
1206 }
1207
1208 expected_event.type = TEST_EV_TYPE_NOTIF_STREAM_END;
1209 expected_event.stream = src_stream1;
1210 expected_event.packet = NULL;
1211 expected_event2.type = TEST_EV_TYPE_NOTIF_STREAM_END;
1212 expected_event2.stream = src_stream2;
1213 expected_event2.packet = NULL;
1214 event = &g_array_index(test_events, struct test_event, 2);
1215 event2 = &g_array_index(test_events, struct test_event, 3);
1216 if (!(compare_single_test_events(event, &expected_event) &&
1217 compare_single_test_events(event2, &expected_event2)) &&
1218 !(compare_single_test_events(event2, &expected_event) &&
1219 compare_single_test_events(event, &expected_event2))) {
1220 expected = false;
1221 goto end;
1222 }
1223
1224 expected_event.type = TEST_EV_TYPE_END;
1225 expected_event.stream = NULL;
1226 expected_event.packet = NULL;
1227 event = &g_array_index(test_events, struct test_event, 4);
1228 if (!compare_single_test_events(event, &expected_event)) {
1229 expected = false;
1230 goto end;
1231 }
1232
1233end:
1234 ok(expected,
1235 "the produced sequence of test events is the expected one");
1236}
1237
1238static
1239void test_multiple_auto_packet_end_stream_end_from_end(void)
1240{
1241 bool expected = true;
1242 struct test_event expected_event;
1243 struct test_event expected_event2;
1244 struct test_event *event;
1245 struct test_event *event2;
1246
1247 do_std_test(TEST_MULTIPLE_AUTO_PACKET_END_STREAM_END_FROM_END,
1248 "multiple automatic \"packet end\" and \"stream end\" notifs. caused by BT_NOTIFICATION_ITERATOR_STATUS_END",
1249 NULL);
1250
1251 if (test_events->len != 9) {
1252 expected = false;
1253 goto end;
1254 }
1255
1256 expected_event.type = TEST_EV_TYPE_NOTIF_STREAM_BEGIN;
1257 expected_event.stream = src_stream1;
1258 expected_event.packet = NULL;
1259 event = &g_array_index(test_events, struct test_event, 0);
1260 if (!compare_single_test_events(event, &expected_event)) {
1261 expected = false;
1262 goto end;
1263 }
1264
1265 expected_event.type = TEST_EV_TYPE_NOTIF_STREAM_BEGIN;
1266 expected_event.stream = src_stream2;
1267 expected_event.packet = NULL;
1268 event = &g_array_index(test_events, struct test_event, 1);
1269 if (!compare_single_test_events(event, &expected_event)) {
1270 expected = false;
1271 goto end;
1272 }
1273
1274 expected_event.type = TEST_EV_TYPE_NOTIF_PACKET_BEGIN;
1275 expected_event.stream = src_stream1;
1276 expected_event.packet = src_stream1_packet1;
1277 event = &g_array_index(test_events, struct test_event, 2);
1278 if (!compare_single_test_events(event, &expected_event)) {
1279 expected = false;
1280 goto end;
1281 }
1282
1283 expected_event.type = TEST_EV_TYPE_NOTIF_PACKET_BEGIN;
1284 expected_event.stream = src_stream2;
1285 expected_event.packet = src_stream2_packet1;
1286 event = &g_array_index(test_events, struct test_event, 3);
1287 if (!compare_single_test_events(event, &expected_event)) {
1288 expected = false;
1289 goto end;
1290 }
1291
1292 expected_event.type = TEST_EV_TYPE_NOTIF_PACKET_END;
1293 expected_event.stream = src_stream1;
1294 expected_event.packet = src_stream1_packet1;
1295 expected_event2.type = TEST_EV_TYPE_NOTIF_PACKET_END;
1296 expected_event2.stream = src_stream2;
1297 expected_event2.packet = src_stream2_packet1;
1298 event = &g_array_index(test_events, struct test_event, 4);
1299 event2 = &g_array_index(test_events, struct test_event, 6);
1300 if (!(compare_single_test_events(event, &expected_event) &&
1301 compare_single_test_events(event2, &expected_event2)) &&
1302 !(compare_single_test_events(event2, &expected_event) &&
1303 compare_single_test_events(event, &expected_event2))) {
1304 expected = false;
1305 goto end;
1306 }
1307
1308 expected_event.type = TEST_EV_TYPE_NOTIF_STREAM_END;
1309 expected_event.stream = src_stream1;
1310 expected_event.packet = NULL;
1311 expected_event2.type = TEST_EV_TYPE_NOTIF_STREAM_END;
1312 expected_event2.stream = src_stream2;
1313 expected_event2.packet = NULL;
1314 event = &g_array_index(test_events, struct test_event, 5);
1315 event2 = &g_array_index(test_events, struct test_event, 7);
1316 if (!(compare_single_test_events(event, &expected_event) &&
1317 compare_single_test_events(event2, &expected_event2)) &&
1318 !(compare_single_test_events(event2, &expected_event) &&
1319 compare_single_test_events(event, &expected_event2))) {
1320 expected = false;
1321 goto end;
1322 }
1323
1324 expected_event.type = TEST_EV_TYPE_END;
1325 expected_event.stream = NULL;
1326 expected_event.packet = NULL;
1327 event = &g_array_index(test_events, struct test_event, 8);
1328 if (!compare_single_test_events(event, &expected_event)) {
1329 expected = false;
1330 goto end;
1331 }
1332
1333end:
1334 ok(expected,
1335 "the produced sequence of test events is the expected one");
1336}
1337
e893886e
PP
1338static
1339void test_output_port_notification_iterator(void)
1340{
1341 const struct test_event expected_test_events[] = {
1342 { .type = TEST_EV_TYPE_NOTIF_STREAM_BEGIN, .stream = src_stream1, .packet = NULL, },
1343 { .type = TEST_EV_TYPE_NOTIF_PACKET_BEGIN, .stream = src_stream1, .packet = src_stream1_packet1, },
1344 { .type = TEST_EV_TYPE_NOTIF_EVENT, .stream = src_stream1, .packet = src_stream1_packet1, },
1345 { .type = TEST_EV_TYPE_NOTIF_EVENT, .stream = src_stream1, .packet = src_stream1_packet1, },
1346 { .type = TEST_EV_TYPE_NOTIF_STREAM_BEGIN, .stream = src_stream2, .packet = NULL, },
1347 { .type = TEST_EV_TYPE_NOTIF_EVENT, .stream = src_stream1, .packet = src_stream1_packet1, },
1348 { .type = TEST_EV_TYPE_NOTIF_PACKET_BEGIN, .stream = src_stream2, .packet = src_stream2_packet2, },
1349 { .type = TEST_EV_TYPE_NOTIF_EVENT, .stream = src_stream2, .packet = src_stream2_packet2, },
1350 { .type = TEST_EV_TYPE_NOTIF_EVENT, .stream = src_stream1, .packet = src_stream1_packet1, },
1351 { .type = TEST_EV_TYPE_NOTIF_PACKET_END, .stream = src_stream1, .packet = src_stream1_packet1, },
1352 { .type = TEST_EV_TYPE_NOTIF_PACKET_END, .stream = src_stream2, .packet = src_stream2_packet2, },
1353 { .type = TEST_EV_TYPE_NOTIF_PACKET_BEGIN, .stream = src_stream1, .packet = src_stream1_packet2, },
1354 { .type = TEST_EV_TYPE_NOTIF_EVENT, .stream = src_stream1, .packet = src_stream1_packet2, },
1355 { .type = TEST_EV_TYPE_NOTIF_STREAM_END, .stream = src_stream2, .packet = NULL, },
1356 { .type = TEST_EV_TYPE_NOTIF_PACKET_END, .stream = src_stream1, .packet = src_stream1_packet2, },
1357 { .type = TEST_EV_TYPE_NOTIF_STREAM_END, .stream = src_stream1, .packet = NULL, },
1358 { .type = TEST_EV_TYPE_END, },
1359 { .type = TEST_EV_TYPE_SENTINEL, },
1360 };
1361 struct bt_component *src_comp;
1362 struct bt_notification_iterator *notif_iter;
1363 enum bt_notification_iterator_status iter_status =
1364 BT_NOTIFICATION_ITERATOR_STATUS_OK;
1365 struct bt_port *upstream_port;
1366 struct bt_graph *graph;
1367
1368 clear_test_events();
1369 current_test = TEST_OUTPUT_PORT_NOTIFICATION_ITERATOR;
1370 diag("test: output port notification iterator");
1371 graph = bt_graph_create();
1372 assert(graph);
1373 create_source_sink(graph, &src_comp, NULL);
1374
1375 /* Create notification iterator on source's output port */
1376 upstream_port = bt_component_source_get_output_port_by_name(src_comp, "out");
1377 notif_iter = bt_output_port_notification_iterator_create(upstream_port,
1378 NULL, NULL);
1379 ok(notif_iter, "bt_output_port_notification_iterator_create() succeeds");
1380 bt_put(upstream_port);
1381
1382 /* Consume the notification iterator */
1383 while (iter_status == BT_NOTIFICATION_ITERATOR_STATUS_OK) {
1384 iter_status = common_consume(notif_iter);
1385 }
1386
1387 ok(iter_status == BT_NOTIFICATION_ITERATOR_STATUS_END,
1388 "output port notification iterator finishes without any error");
1389
1390 /* Compare the resulting test events */
1391 ok(compare_test_events(expected_test_events),
1392 "the produced sequence of test events is the expected one");
1393
1394 bt_put(src_comp);
1395 bt_put(graph);
1396 bt_put(notif_iter);
1397}
1398
1399static
1400void test_output_port_notification_iterator_subscribe_events(void)
1401{
1402 const struct test_event expected_test_events[] = {
1403 { .type = TEST_EV_TYPE_NOTIF_EVENT, .stream = src_stream1, .packet = src_stream1_packet1, },
1404 { .type = TEST_EV_TYPE_NOTIF_EVENT, .stream = src_stream1, .packet = src_stream1_packet1, },
1405 { .type = TEST_EV_TYPE_NOTIF_EVENT, .stream = src_stream1, .packet = src_stream1_packet1, },
1406 { .type = TEST_EV_TYPE_NOTIF_EVENT, .stream = src_stream2, .packet = src_stream2_packet2, },
1407 { .type = TEST_EV_TYPE_NOTIF_EVENT, .stream = src_stream1, .packet = src_stream1_packet1, },
1408 { .type = TEST_EV_TYPE_NOTIF_EVENT, .stream = src_stream1, .packet = src_stream1_packet2, },
1409 { .type = TEST_EV_TYPE_END, },
1410 { .type = TEST_EV_TYPE_SENTINEL, },
1411 };
1412 const enum bt_notification_type notification_types[] = {
1413 BT_NOTIFICATION_TYPE_EVENT,
1414 BT_NOTIFICATION_TYPE_SENTINEL,
1415 };
1416 struct bt_component *src_comp;
1417 struct bt_notification_iterator *notif_iter;
1418 enum bt_notification_iterator_status iter_status =
1419 BT_NOTIFICATION_ITERATOR_STATUS_OK;
1420 struct bt_port *upstream_port;
1421 struct bt_graph *graph;
1422
1423 clear_test_events();
1424 current_test = TEST_OUTPUT_PORT_NOTIFICATION_ITERATOR;
1425 diag("test: output port notification iterator with event subscription");
1426 graph = bt_graph_create();
1427 assert(graph);
1428 create_source_sink(graph, &src_comp, NULL);
1429
1430 /* Create notification iterator on source's output port */
1431 upstream_port = bt_component_source_get_output_port_by_name(src_comp, "out");
1432 notif_iter = bt_output_port_notification_iterator_create(upstream_port,
1433 NULL, notification_types);
1434 ok(notif_iter, "bt_output_port_notification_iterator_create() succeeds");
1435 bt_put(upstream_port);
1436
1437 /* Consume the notification iterator */
1438 while (iter_status == BT_NOTIFICATION_ITERATOR_STATUS_OK) {
1439 iter_status = common_consume(notif_iter);
1440 }
1441
1442 ok(iter_status == BT_NOTIFICATION_ITERATOR_STATUS_END,
1443 "output port notification iterator finishes without any error");
1444
1445 /* Compare the resulting test events */
1446 ok(compare_test_events(expected_test_events),
1447 "the produced sequence of test events is the expected one");
1448
1449 bt_put(src_comp);
1450 bt_put(graph);
1451 bt_put(notif_iter);
1452}
1453
1454static
1455void test_output_port_notification_iterator_cannot_consume(void)
1456{
1457 struct bt_component *src_comp;
1458 struct bt_notification_iterator *notif_iter;
1459 struct bt_port *upstream_port;
1460 struct bt_graph *graph;
1461
1462 clear_test_events();
1463 current_test = TEST_OUTPUT_PORT_NOTIFICATION_ITERATOR;
1464 diag("test: cannot consume graph with existing output port notification iterator");
1465 graph = bt_graph_create();
1466 assert(graph);
1467 create_source_sink(graph, &src_comp, NULL);
1468
1469 /* Create notification iterator on source's output port */
1470 upstream_port = bt_component_source_get_output_port_by_name(src_comp, "out");
1471 notif_iter = bt_output_port_notification_iterator_create(upstream_port,
1472 NULL, NULL);
1473 assert(notif_iter);
1474 bt_put(upstream_port);
1475
1476 /*
1477 * This should fail because the graph is now managed by the
1478 * notification iterator.
1479 */
1480 ok(bt_graph_run(graph) == BT_GRAPH_STATUS_CANNOT_CONSUME,
1481 "bt_graph_run() returns BT_GRAPH_STATUS_CANNOT_CONSUME when there's an output port notification iterator");
1482
1483 bt_put(src_comp);
1484 bt_put(graph);
1485 bt_put(notif_iter);
1486}
1487
223c70b2
PP
1488#define DEBUG_ENV_VAR "TEST_BT_NOTIFICATION_ITERATOR_DEBUG"
1489
1490int main(int argc, char **argv)
1491{
1492 if (getenv(DEBUG_ENV_VAR) && strcmp(getenv(DEBUG_ENV_VAR), "1") == 0) {
1493 debug = true;
1494 }
1495
1496 plan_tests(NR_TESTS);
1497 init_static_data();
1498 test_no_auto_notifs();
1499 test_auto_stream_begin_from_packet_begin();
1500 test_auto_stream_begin_from_stream_end();
1501 test_auto_stream_end_from_end();
1502 test_auto_packet_begin_from_packet_end();
1503 test_auto_packet_begin_from_event();
1504 test_auto_packet_end_from_packet_begin();
1505 test_auto_packet_end_packet_begin_from_event();
1506 test_auto_packet_end_from_stream_end();
1507 test_auto_packet_end_stream_end_from_end();
1508 test_multiple_auto_stream_end_from_end();
1509 test_multiple_auto_packet_end_stream_end_from_end();
e893886e
PP
1510 test_output_port_notification_iterator();
1511 test_output_port_notification_iterator_subscribe_events();
1512 test_output_port_notification_iterator_cannot_consume();
223c70b2
PP
1513 fini_static_data();
1514 return exit_status();
1515}
This page took 0.096214 seconds and 4 git commands to generate.