Replace all assert(false) and assert(0) with abort()
[babeltrace.git] / tests / lib / test_graph_topo.c
1 /*
2 * test_graph_topo.c
3 *
4 * Copyright 2017 - Philippe Proulx <pproulx@efficios.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; under version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 #include <babeltrace/graph/component-class.h>
21 #include <babeltrace/graph/component-class-source.h>
22 #include <babeltrace/graph/component-class-sink.h>
23 #include <babeltrace/graph/component.h>
24 #include <babeltrace/graph/component-source.h>
25 #include <babeltrace/graph/component-sink.h>
26 #include <babeltrace/graph/graph.h>
27 #include <babeltrace/graph/connection.h>
28 #include <babeltrace/graph/port.h>
29 #include <babeltrace/graph/private-component.h>
30 #include <babeltrace/graph/private-component-source.h>
31 #include <babeltrace/graph/private-component-sink.h>
32 #include <babeltrace/graph/private-port.h>
33 #include <babeltrace/graph/private-connection.h>
34 #include <stdlib.h>
35 #include <string.h>
36 #include <stdbool.h>
37 #include <assert.h>
38 #include <glib.h>
39
40 #include "tap/tap.h"
41
42 #define NR_TESTS 69
43
44 enum event_type {
45 COMP_ACCEPT_PORT_CONNECTION,
46 COMP_PORT_CONNECTED,
47 COMP_PORT_DISCONNECTED,
48 GRAPH_PORT_ADDED,
49 GRAPH_PORT_REMOVED,
50 GRAPH_PORTS_CONNECTED,
51 GRAPH_PORTS_DISCONNECTED,
52 };
53
54 enum test {
55 TEST_EMPTY_GRAPH,
56 TEST_SIMPLE,
57 TEST_SRC_ADDS_PORT_IN_PORT_CONNECTED,
58 TEST_SINK_REMOVES_PORT_IN_CONSUME,
59 TEST_SINK_REMOVES_PORT_IN_CONSUME_THEN_SRC_REMOVES_DISCONNECTED_PORT,
60 };
61
62 struct event {
63 enum event_type type;
64
65 union {
66 struct {
67 struct bt_component *comp;
68 struct bt_port *self_port;
69 struct bt_port *other_port;
70 } comp_accept_port_connection;
71
72 struct {
73 struct bt_component *comp;
74 struct bt_port *self_port;
75 struct bt_port *other_port;
76 } comp_port_connected;
77
78 struct {
79 struct bt_component *comp;
80 struct bt_port *port;
81 } comp_port_disconnected;
82
83 struct {
84 struct bt_component *comp;
85 struct bt_port *port;
86 } graph_port_added;
87
88 struct {
89 struct bt_component *comp;
90 struct bt_port *port;
91 } graph_port_removed;
92
93 struct {
94 struct bt_component *upstream_comp;
95 struct bt_component *downstream_comp;
96 struct bt_port *upstream_port;
97 struct bt_port *downstream_port;
98 struct bt_connection *conn;
99 } graph_ports_connected;
100
101 struct {
102 struct bt_component *upstream_comp;
103 struct bt_component *downstream_comp;
104 struct bt_port *upstream_port;
105 struct bt_port *downstream_port;
106 } graph_ports_disconnected;
107 } data;
108 };
109
110 static GArray *events;
111 static struct bt_component_class *src_comp_class;
112 static struct bt_component_class *sink_comp_class;
113 static enum test current_test;
114
115 static
116 void clear_events(void)
117 {
118 g_array_set_size(events, 0);
119 }
120
121 static
122 void append_event(struct event *event)
123 {
124 g_array_append_val(events, *event);
125 }
126
127 static
128 bool compare_events(struct event *ev_a, struct event *ev_b)
129 {
130 if (ev_a->type != ev_b->type) {
131 return false;
132 }
133
134 switch (ev_a->type) {
135 case COMP_ACCEPT_PORT_CONNECTION:
136 if (ev_a->data.comp_accept_port_connection.comp !=
137 ev_b->data.comp_accept_port_connection.comp) {
138 return false;
139 }
140
141 if (ev_a->data.comp_accept_port_connection.self_port !=
142 ev_b->data.comp_accept_port_connection.self_port) {
143 return false;
144 }
145
146 if (ev_a->data.comp_accept_port_connection.other_port !=
147 ev_b->data.comp_accept_port_connection.other_port) {
148 return false;
149 }
150 break;
151 case COMP_PORT_CONNECTED:
152 if (ev_a->data.comp_port_connected.comp !=
153 ev_b->data.comp_port_connected.comp) {
154 return false;
155 }
156
157 if (ev_a->data.comp_port_connected.self_port !=
158 ev_b->data.comp_port_connected.self_port) {
159 return false;
160 }
161
162 if (ev_a->data.comp_port_connected.other_port !=
163 ev_b->data.comp_port_connected.other_port) {
164 return false;
165 }
166 break;
167 case COMP_PORT_DISCONNECTED:
168 if (ev_a->data.comp_port_disconnected.comp !=
169 ev_b->data.comp_port_disconnected.comp) {
170 return false;
171 }
172
173 if (ev_a->data.comp_port_disconnected.port !=
174 ev_b->data.comp_port_disconnected.port) {
175 return false;
176 }
177 break;
178 case GRAPH_PORT_ADDED:
179 if (ev_a->data.graph_port_added.comp !=
180 ev_b->data.graph_port_added.comp) {
181 return false;
182 }
183
184 if (ev_a->data.graph_port_added.port !=
185 ev_b->data.graph_port_added.port) {
186 return false;
187 }
188 break;
189 case GRAPH_PORT_REMOVED:
190 if (ev_a->data.graph_port_removed.comp !=
191 ev_b->data.graph_port_removed.comp) {
192 return false;
193 }
194
195 if (ev_a->data.graph_port_removed.port !=
196 ev_b->data.graph_port_removed.port) {
197 return false;
198 }
199 break;
200 case GRAPH_PORTS_CONNECTED:
201 if (ev_a->data.graph_ports_connected.upstream_comp !=
202 ev_b->data.graph_ports_connected.upstream_comp) {
203 return false;
204 }
205
206 if (ev_a->data.graph_ports_connected.downstream_comp !=
207 ev_b->data.graph_ports_connected.downstream_comp) {
208 return false;
209 }
210
211 if (ev_a->data.graph_ports_connected.upstream_port !=
212 ev_b->data.graph_ports_connected.upstream_port) {
213 return false;
214 }
215
216 if (ev_a->data.graph_ports_connected.downstream_port !=
217 ev_b->data.graph_ports_connected.downstream_port) {
218 return false;
219 }
220
221 if (ev_a->data.graph_ports_connected.conn !=
222 ev_b->data.graph_ports_connected.conn) {
223 return false;
224 }
225 break;
226 case GRAPH_PORTS_DISCONNECTED:
227 if (ev_a->data.graph_ports_disconnected.upstream_comp !=
228 ev_b->data.graph_ports_disconnected.upstream_comp) {
229 return false;
230 }
231
232 if (ev_a->data.graph_ports_disconnected.downstream_comp !=
233 ev_b->data.graph_ports_disconnected.downstream_comp) {
234 return false;
235 }
236
237 if (ev_a->data.graph_ports_disconnected.upstream_port !=
238 ev_b->data.graph_ports_disconnected.upstream_port) {
239 return false;
240 }
241
242 if (ev_a->data.graph_ports_disconnected.downstream_port !=
243 ev_b->data.graph_ports_disconnected.downstream_port) {
244 return false;
245 }
246 break;
247 default:
248 abort();
249 }
250
251 return true;
252 }
253
254 static
255 bool has_event(struct event *event)
256 {
257 size_t i;
258
259 for (i = 0; i < events->len; i++) {
260 struct event *ev = &g_array_index(events, struct event, i);
261
262 if (compare_events(event, ev)) {
263 return true;
264 }
265 }
266
267 return false;
268 }
269
270 static
271 size_t event_pos(struct event *event)
272 {
273 size_t i;
274
275 for (i = 0; i < events->len; i++) {
276 struct event *ev = &g_array_index(events, struct event, i);
277
278 if (compare_events(event, ev)) {
279 return i;
280 }
281 }
282
283 return -1ULL;
284 }
285
286 static
287 struct bt_notification_iterator_next_return src_iter_next(
288 struct bt_private_notification_iterator *priv_iterator)
289 {
290 struct bt_notification_iterator_next_return ret = {
291 .status = BT_NOTIFICATION_ITERATOR_STATUS_ERROR,
292 };
293
294 return ret;
295 }
296
297 static
298 enum bt_component_status accept_port_connection(
299 struct bt_private_component *private_component,
300 struct bt_private_port *self_private_port,
301 struct bt_port *other_port)
302 {
303 struct event event = {
304 .type = COMP_ACCEPT_PORT_CONNECTION,
305 .data.comp_accept_port_connection = {
306 .comp = bt_component_from_private_component(private_component),
307 .self_port = bt_port_from_private_port(self_private_port),
308 .other_port = other_port,
309 },
310 };
311
312 bt_put(event.data.comp_accept_port_connection.comp);
313 bt_put(event.data.comp_accept_port_connection.self_port);
314 append_event(&event);
315 return BT_COMPONENT_STATUS_OK;
316 }
317
318 static
319 void src_port_connected(struct bt_private_component *private_component,
320 struct bt_private_port *self_private_port,
321 struct bt_port *other_port)
322 {
323 struct bt_private_port *port;
324
325 struct event event = {
326 .type = COMP_PORT_CONNECTED,
327 .data.comp_port_connected = {
328 .comp = bt_component_from_private_component(private_component),
329 .self_port = bt_port_from_private_port(self_private_port),
330 .other_port = other_port,
331 },
332 };
333
334 bt_put(event.data.comp_port_connected.comp);
335 bt_put(event.data.comp_port_connected.self_port);
336 append_event(&event);
337
338 switch (current_test) {
339 case TEST_SRC_ADDS_PORT_IN_PORT_CONNECTED:
340 port = bt_private_component_source_add_output_private_port(
341 private_component, "hello", NULL);
342 assert(port);
343 bt_put(port);
344 break;
345 default:
346 break;
347 }
348 }
349
350 static
351 void src_port_disconnected(struct bt_private_component *private_component,
352 struct bt_private_port *private_port)
353 {
354 int ret;
355 struct event event = {
356 .type = COMP_PORT_DISCONNECTED,
357 .data.comp_port_disconnected = {
358 .comp = bt_component_from_private_component(private_component),
359 .port = bt_port_from_private_port(private_port),
360 },
361 };
362
363 bt_put(event.data.comp_port_disconnected.comp);
364 bt_put(event.data.comp_port_disconnected.port);
365 append_event(&event);
366
367 switch (current_test) {
368 case TEST_SINK_REMOVES_PORT_IN_CONSUME_THEN_SRC_REMOVES_DISCONNECTED_PORT:
369 ret = bt_private_port_remove_from_component(private_port);
370 assert(ret == 0);
371 default:
372 break;
373 }
374 }
375
376 static
377 enum bt_component_status src_init(struct bt_private_component *priv_comp,
378 struct bt_value *params, void *init_method_data)
379 {
380 void *priv_port;
381
382 priv_port = bt_private_component_source_add_output_private_port(
383 priv_comp, "out", NULL);
384 assert(priv_port);
385 bt_put(priv_port);
386 return BT_COMPONENT_STATUS_OK;
387 }
388
389 static
390 enum bt_component_status sink_consume(
391 struct bt_private_component *priv_component)
392 {
393 struct bt_private_port *def_port;
394 int ret;
395
396 switch (current_test) {
397 case TEST_SINK_REMOVES_PORT_IN_CONSUME:
398 case TEST_SINK_REMOVES_PORT_IN_CONSUME_THEN_SRC_REMOVES_DISCONNECTED_PORT:
399 def_port = bt_private_component_sink_get_input_private_port_by_name(
400 priv_component, "in");
401 assert(def_port);
402 ret = bt_private_port_remove_from_component(def_port);
403 assert(ret == 0);
404 bt_put(def_port);
405 break;
406 default:
407 break;
408 }
409
410 return BT_COMPONENT_STATUS_OK;
411 }
412
413 static
414 void sink_port_connected(struct bt_private_component *private_component,
415 struct bt_private_port *self_private_port,
416 struct bt_port *other_port)
417 {
418 struct event event = {
419 .type = COMP_PORT_CONNECTED,
420 .data.comp_port_connected = {
421 .comp = bt_component_from_private_component(private_component),
422 .self_port = bt_port_from_private_port(self_private_port),
423 .other_port = other_port,
424 },
425 };
426
427 bt_put(event.data.comp_port_connected.comp);
428 bt_put(event.data.comp_port_connected.self_port);
429 append_event(&event);
430 }
431
432 static
433 void sink_port_disconnected(struct bt_private_component *private_component,
434 struct bt_private_port *private_port)
435 {
436 struct event event = {
437 .type = COMP_PORT_DISCONNECTED,
438 .data.comp_port_disconnected = {
439 .comp = bt_component_from_private_component(private_component),
440 .port = bt_port_from_private_port(private_port),
441 },
442 };
443
444 bt_put(event.data.comp_port_disconnected.comp);
445 bt_put(event.data.comp_port_disconnected.port);
446 append_event(&event);
447 }
448
449 static
450 enum bt_component_status sink_init(struct bt_private_component *priv_comp,
451 struct bt_value *params, void *init_method_data)
452 {
453 void *priv_port;
454
455 priv_port = bt_private_component_sink_add_input_private_port(priv_comp,
456 "in", NULL);
457 assert(priv_port);
458 bt_put(priv_port);
459 return BT_COMPONENT_STATUS_OK;
460 }
461
462 static
463 void graph_port_added(struct bt_port *port,
464 void *data)
465 {
466 struct bt_component *comp = bt_port_get_component(port);
467
468 assert(comp);
469 bt_put(comp);
470
471 struct event event = {
472 .type = GRAPH_PORT_ADDED,
473 .data.graph_port_added = {
474 .comp = comp,
475 .port = port,
476 },
477 };
478
479 append_event(&event);
480 }
481
482 static
483 void graph_port_removed(struct bt_component *component,
484 struct bt_port *port, void *data)
485 {
486 struct event event = {
487 .type = GRAPH_PORT_REMOVED,
488 .data.graph_port_removed = {
489 .comp = component,
490 .port = port,
491 },
492 };
493
494 append_event(&event);
495 }
496
497 static
498 void graph_ports_connected(struct bt_port *upstream_port,
499 struct bt_port *downstream_port, void *data)
500 {
501 struct bt_component *upstream_comp =
502 bt_port_get_component(upstream_port);
503 struct bt_component *downstream_comp =
504 bt_port_get_component(downstream_port);
505 struct bt_connection *conn = bt_port_get_connection(upstream_port);
506
507 assert(upstream_comp);
508 assert(downstream_comp);
509 assert(conn);
510 bt_put(upstream_comp);
511 bt_put(downstream_comp);
512 bt_put(conn);
513
514 struct event event = {
515 .type = GRAPH_PORTS_CONNECTED,
516 .data.graph_ports_connected = {
517 .upstream_comp = upstream_comp,
518 .downstream_comp = downstream_comp,
519 .upstream_port = upstream_port,
520 .downstream_port = downstream_port,
521 .conn = conn,
522 },
523 };
524
525 append_event(&event);
526 }
527
528 static
529 void graph_ports_disconnected(
530 struct bt_component *upstream_comp,
531 struct bt_component *downstream_comp,
532 struct bt_port *upstream_port, struct bt_port *downstream_port,
533 void *data)
534 {
535 struct event event = {
536 .type = GRAPH_PORTS_DISCONNECTED,
537 .data.graph_ports_disconnected = {
538 .upstream_comp = upstream_comp,
539 .downstream_comp = downstream_comp,
540 .upstream_port = upstream_port,
541 .downstream_port = downstream_port,
542 },
543 };
544
545 append_event(&event);
546 }
547
548 static
549 void init_test(void)
550 {
551 int ret;
552
553 src_comp_class = bt_component_class_source_create("src", src_iter_next);
554 assert(src_comp_class);
555 ret = bt_component_class_set_init_method(src_comp_class, src_init);
556 assert(ret == 0);
557 ret = bt_component_class_set_accept_port_connection_method(
558 src_comp_class, accept_port_connection);
559 assert(ret == 0);
560 ret = bt_component_class_set_port_connected_method(src_comp_class,
561 src_port_connected);
562 assert(ret == 0);
563 ret = bt_component_class_set_port_disconnected_method(
564 src_comp_class, src_port_disconnected);
565 assert(ret == 0);
566 sink_comp_class = bt_component_class_sink_create("sink", sink_consume);
567 assert(sink_comp_class);
568 ret = bt_component_class_set_init_method(sink_comp_class, sink_init);
569 assert(ret == 0);
570 ret = bt_component_class_set_accept_port_connection_method(
571 sink_comp_class, accept_port_connection);
572 assert(ret == 0);
573 ret = bt_component_class_set_port_connected_method(sink_comp_class,
574 sink_port_connected);
575 assert(ret == 0);
576 ret = bt_component_class_set_port_disconnected_method(sink_comp_class,
577 sink_port_disconnected);
578 assert(ret == 0);
579 bt_component_class_freeze(src_comp_class);
580 bt_component_class_freeze(sink_comp_class);
581 events = g_array_new(FALSE, TRUE, sizeof(struct event));
582 assert(events);
583 }
584
585 static
586 void fini_test(void)
587 {
588 bt_put(src_comp_class);
589 bt_put(sink_comp_class);
590 g_array_free(events, TRUE);
591 }
592
593 static
594 struct bt_component *create_src(void)
595 {
596 struct bt_component *comp =
597 bt_component_create(src_comp_class, "src-comp", NULL);
598
599 assert(comp);
600 return comp;
601 }
602
603 static
604 struct bt_component *create_sink(void)
605 {
606 struct bt_component *comp =
607 bt_component_create(sink_comp_class, "sink-comp", NULL);
608
609 assert(comp);
610 return comp;
611 }
612
613 static
614 struct bt_graph *create_graph(void)
615 {
616 struct bt_graph *graph = bt_graph_create();
617 int ret;
618
619 assert(graph);
620 ret = bt_graph_add_port_added_listener(graph, graph_port_added, NULL);
621 assert(ret == 0);
622 ret = bt_graph_add_port_removed_listener(graph, graph_port_removed,
623 NULL);
624 assert(ret == 0);
625 ret = bt_graph_add_ports_connected_listener(graph, graph_ports_connected,
626 NULL);
627 assert(ret == 0);
628 ret = bt_graph_add_ports_disconnected_listener(graph,
629 graph_ports_disconnected, NULL);
630 assert(ret == 0);
631 return graph;
632 }
633
634 static
635 void prepare_test(enum test test, const char *name)
636 {
637 clear_events();
638 current_test = test;
639 diag("test: %s", name);
640 }
641
642 static
643 void test_sink_removes_port_in_port_connected_then_src_removes_disconnected_port(void)
644 {
645 int ret;
646 struct bt_component *src;
647 struct bt_component *sink;
648 struct bt_graph *graph;
649 struct bt_port *src_def_port;
650 struct bt_port *sink_def_port;
651 struct bt_connection *conn;
652 struct event event;
653 size_t src_accept_port_connection_pos;
654 size_t sink_accept_port_connection_pos;
655 size_t src_port_connected_pos;
656 size_t sink_port_connected_pos;
657 size_t graph_ports_connected;
658 size_t src_port_disconnected_pos;
659 size_t sink_port_disconnected_pos;
660 size_t graph_ports_disconnected_pos;
661 size_t graph_port_removed_src_pos;
662 size_t graph_port_removed_sink_pos;
663
664 prepare_test(TEST_SINK_REMOVES_PORT_IN_CONSUME_THEN_SRC_REMOVES_DISCONNECTED_PORT,
665 "sink removes port in consume, then source removes disconnected port");
666 src = create_src();
667 sink = create_sink();
668 graph = create_graph();
669 src_def_port = bt_component_source_get_output_port_by_name(src, "out");
670 assert(src_def_port);
671 sink_def_port = bt_component_sink_get_input_port_by_name(sink, "in");
672 assert(sink_def_port);
673 conn = bt_graph_connect_ports(graph, src_def_port, sink_def_port);
674 assert(conn);
675
676 /* We're supposed to have 5 events so far */
677 ok(events->len == 5, "we have the expected number of events (before consume)");
678
679 /* Source's accept port connection */
680 event.type = COMP_ACCEPT_PORT_CONNECTION;
681 event.data.comp_accept_port_connection.comp = src;
682 event.data.comp_accept_port_connection.self_port = src_def_port;
683 event.data.comp_accept_port_connection.other_port = sink_def_port;
684 ok(has_event(&event), "got the expected source's accept port connection event");
685 src_accept_port_connection_pos = event_pos(&event);
686
687 /* Sink's accept port connection */
688 event.type = COMP_ACCEPT_PORT_CONNECTION;
689 event.data.comp_accept_port_connection.comp = sink;
690 event.data.comp_accept_port_connection.self_port = sink_def_port;
691 event.data.comp_accept_port_connection.other_port = src_def_port;
692 ok(has_event(&event), "got the expected sink's accept port connection event");
693 sink_accept_port_connection_pos = event_pos(&event);
694
695 /* Source's port connected */
696 event.type = COMP_PORT_CONNECTED;
697 event.data.comp_port_connected.comp = src;
698 event.data.comp_port_connected.self_port = src_def_port;
699 event.data.comp_port_connected.other_port = sink_def_port;
700 ok(has_event(&event), "got the expected source's port connected event");
701 src_port_connected_pos = event_pos(&event);
702
703 /* Sink's port connected */
704 event.type = COMP_PORT_CONNECTED;
705 event.data.comp_port_connected.comp = sink;
706 event.data.comp_port_connected.self_port = sink_def_port;
707 event.data.comp_port_connected.other_port = src_def_port;
708 ok(has_event(&event), "got the expected sink's port connected event");
709 sink_port_connected_pos = event_pos(&event);
710
711 /* Graph's ports connected */
712 event.type = GRAPH_PORTS_CONNECTED;
713 event.data.graph_ports_connected.upstream_comp = src;
714 event.data.graph_ports_connected.downstream_comp = sink;
715 event.data.graph_ports_connected.upstream_port = src_def_port;
716 event.data.graph_ports_connected.downstream_port = sink_def_port;
717 event.data.graph_ports_connected.conn = conn;
718 ok(has_event(&event), "got the expected graph's ports connected event");
719 graph_ports_connected = event_pos(&event);
720
721 /* Order of events */
722 ok(src_port_connected_pos < graph_ports_connected,
723 "event order is good (1)");
724 ok(sink_port_connected_pos < graph_ports_connected,
725 "event order is good (2)");
726 ok(src_accept_port_connection_pos < src_port_connected_pos,
727 "event order is good (3)");
728 ok(sink_accept_port_connection_pos < sink_port_connected_pos,
729 "event order is good (4)");
730
731 /* Consume sink once */
732 clear_events();
733 ret = bt_graph_consume(graph);
734 assert(ret == 0);
735
736 /* We're supposed to have 5 new events */
737 ok(events->len == 5, "we have the expected number of events (after consume)");
738
739 /* Source's port disconnected */
740 event.type = COMP_PORT_DISCONNECTED;
741 event.data.comp_port_disconnected.comp = src;
742 event.data.comp_port_disconnected.port = src_def_port;
743 ok(has_event(&event), "got the expected source's port disconnected event");
744 src_port_disconnected_pos = event_pos(&event);
745
746 /* Sink's port disconnected */
747 event.type = COMP_PORT_DISCONNECTED;
748 event.data.comp_port_disconnected.comp = sink;
749 event.data.comp_port_disconnected.port = sink_def_port;
750 ok(has_event(&event), "got the expected sink's port disconnected event");
751 sink_port_disconnected_pos = event_pos(&event);
752
753 /* Graph's ports disconnected */
754 event.type = GRAPH_PORTS_DISCONNECTED;
755 event.data.graph_ports_disconnected.upstream_comp = src;
756 event.data.graph_ports_disconnected.downstream_comp = sink;
757 event.data.graph_ports_disconnected.upstream_port = src_def_port;
758 event.data.graph_ports_disconnected.downstream_port = sink_def_port;
759 ok(has_event(&event), "got the expected graph's ports disconnected event");
760 graph_ports_disconnected_pos = event_pos(&event);
761
762 /* Graph's port removed (sink) */
763 event.type = GRAPH_PORT_REMOVED;
764 event.data.graph_port_removed.comp = sink;
765 event.data.graph_port_removed.port = sink_def_port;
766 ok(has_event(&event), "got the expected graph's port removed event (for sink)");
767 graph_port_removed_sink_pos = event_pos(&event);
768
769 /* Graph's port removed (source) */
770 event.type = GRAPH_PORT_REMOVED;
771 event.data.graph_port_removed.comp = src;
772 event.data.graph_port_removed.port = src_def_port;
773 ok(has_event(&event), "got the expected graph's port removed event (for source)");
774 graph_port_removed_src_pos = event_pos(&event);
775
776 /* Order of events */
777 ok(src_port_disconnected_pos < graph_ports_disconnected_pos,
778 "event order is good (5)");
779 ok(src_port_disconnected_pos < graph_port_removed_sink_pos,
780 "event order is good (6)");
781 ok(src_port_disconnected_pos < graph_port_removed_src_pos,
782 "event order is good (7)");
783 ok(sink_port_disconnected_pos < graph_ports_disconnected_pos,
784 "event order is good (8)");
785 ok(sink_port_disconnected_pos < graph_port_removed_sink_pos,
786 "event order is good (9)");
787 ok(sink_port_disconnected_pos < graph_port_removed_src_pos,
788 "event order is good (10)");
789 ok(graph_ports_disconnected_pos < graph_port_removed_sink_pos,
790 "event order is good (11)");
791 ok(graph_port_removed_src_pos < graph_ports_disconnected_pos,
792 "event order is good (12)");
793 ok(graph_port_removed_src_pos < graph_port_removed_sink_pos,
794 "event order is good (13)");
795
796 bt_put(graph);
797 bt_put(sink);
798 bt_put(src);
799 bt_put(conn);
800 bt_put(src_def_port);
801 bt_put(sink_def_port);
802 }
803
804 static
805 void test_sink_removes_port_in_port_connected(void)
806 {
807 int ret;
808 struct bt_component *src;
809 struct bt_component *sink;
810 struct bt_graph *graph;
811 struct bt_port *src_def_port;
812 struct bt_port *sink_def_port;
813 struct bt_connection *conn;
814 struct event event;
815 size_t src_accept_port_connection_pos;
816 size_t sink_accept_port_connection_pos;
817 size_t src_port_connected_pos;
818 size_t sink_port_connected_pos;
819 size_t graph_ports_connected_pos;
820 size_t src_port_disconnected_pos;
821 size_t sink_port_disconnected_pos;
822 size_t graph_ports_disconnected_pos;
823 size_t graph_port_removed_sink_pos;
824
825 prepare_test(TEST_SINK_REMOVES_PORT_IN_CONSUME,
826 "sink removes port in consume");
827 src = create_src();
828 sink = create_sink();
829 graph = create_graph();
830 src_def_port = bt_component_source_get_output_port_by_name(src, "out");
831 assert(src_def_port);
832 sink_def_port = bt_component_sink_get_input_port_by_name(sink, "in");
833 assert(sink_def_port);
834 conn = bt_graph_connect_ports(graph, src_def_port, sink_def_port);
835 assert(conn);
836
837 /* We're supposed to have 5 events so far */
838 ok(events->len == 5, "we have the expected number of events (before consume)");
839
840 /* Source's accept port connection */
841 event.type = COMP_ACCEPT_PORT_CONNECTION;
842 event.data.comp_accept_port_connection.comp = src;
843 event.data.comp_accept_port_connection.self_port = src_def_port;
844 event.data.comp_accept_port_connection.other_port = sink_def_port;
845 ok(has_event(&event), "got the expected source's accept port connection event");
846 src_accept_port_connection_pos = event_pos(&event);
847
848 /* Sink's accept port connection */
849 event.type = COMP_ACCEPT_PORT_CONNECTION;
850 event.data.comp_accept_port_connection.comp = sink;
851 event.data.comp_accept_port_connection.self_port = sink_def_port;
852 event.data.comp_accept_port_connection.other_port = src_def_port;
853 ok(has_event(&event), "got the expected sink's accept port connection event");
854 sink_accept_port_connection_pos = event_pos(&event);
855
856 /* Source's port connected */
857 event.type = COMP_PORT_CONNECTED;
858 event.data.comp_port_connected.comp = src;
859 event.data.comp_port_connected.self_port = src_def_port;
860 event.data.comp_port_connected.other_port = sink_def_port;
861 ok(has_event(&event), "got the expected source's port connected event");
862 src_port_connected_pos = event_pos(&event);
863
864 /* Sink's port connected */
865 event.type = COMP_PORT_CONNECTED;
866 event.data.comp_port_connected.comp = sink;
867 event.data.comp_port_connected.self_port = sink_def_port;
868 event.data.comp_port_connected.other_port = src_def_port;
869 ok(has_event(&event), "got the expected sink's port connected event");
870 sink_port_connected_pos = event_pos(&event);
871
872 /* Graph's ports connected */
873 event.type = GRAPH_PORTS_CONNECTED;
874 event.data.graph_ports_connected.upstream_comp = src;
875 event.data.graph_ports_connected.downstream_comp = sink;
876 event.data.graph_ports_connected.upstream_port = src_def_port;
877 event.data.graph_ports_connected.downstream_port = sink_def_port;
878 event.data.graph_ports_connected.conn = conn;
879 ok(has_event(&event), "got the expected graph's ports connected event");
880 graph_ports_connected_pos = event_pos(&event);
881
882 /* Order of events */
883 ok(src_port_connected_pos < graph_ports_connected_pos,
884 "event order is good (1)");
885 ok(sink_port_connected_pos < graph_ports_connected_pos,
886 "event order is good (2)");
887 ok(src_accept_port_connection_pos < src_port_connected_pos,
888 "event order is good (3)");
889 ok(sink_accept_port_connection_pos < sink_port_connected_pos,
890 "event order is good (4)");
891
892 /* Consume sink once */
893 clear_events();
894 ret = bt_graph_consume(graph);
895 assert(ret == 0);
896
897 /* We're supposed to have 4 new events */
898 ok(events->len == 4, "we have the expected number of events (after consume)");
899
900 /* Source's port disconnected */
901 event.type = COMP_PORT_DISCONNECTED;
902 event.data.comp_port_disconnected.comp = src;
903 event.data.comp_port_disconnected.port = src_def_port;
904 ok(has_event(&event), "got the expected source's port disconnected event");
905 src_port_disconnected_pos = event_pos(&event);
906
907 /* Sink's port disconnected */
908 event.type = COMP_PORT_DISCONNECTED;
909 event.data.comp_port_disconnected.comp = sink;
910 event.data.comp_port_disconnected.port = sink_def_port;
911 ok(has_event(&event), "got the expected sink's port disconnected event");
912 sink_port_disconnected_pos = event_pos(&event);
913
914 /* Graph's ports disconnected */
915 event.type = GRAPH_PORTS_DISCONNECTED;
916 event.data.graph_ports_disconnected.upstream_comp = src;
917 event.data.graph_ports_disconnected.downstream_comp = sink;
918 event.data.graph_ports_disconnected.upstream_port = src_def_port;
919 event.data.graph_ports_disconnected.downstream_port = sink_def_port;
920 ok(has_event(&event), "got the expected graph's ports disconnected event");
921 graph_ports_disconnected_pos = event_pos(&event);
922
923 /* Graph's port removed (sink) */
924 event.type = GRAPH_PORT_REMOVED;
925 event.data.graph_port_removed.comp = sink;
926 event.data.graph_port_removed.port = sink_def_port;
927 ok(has_event(&event), "got the expected graph's port removed event (for sink)");
928 graph_port_removed_sink_pos = event_pos(&event);
929
930 /* Order of events */
931 ok(src_port_disconnected_pos < graph_ports_disconnected_pos,
932 "event order is good (5)");
933 ok(src_port_disconnected_pos < graph_port_removed_sink_pos,
934 "event order is good (7)");
935 ok(sink_port_disconnected_pos < graph_ports_disconnected_pos,
936 "event order is good (8)");
937 ok(sink_port_disconnected_pos < graph_port_removed_sink_pos,
938 "event order is good (10)");
939 ok(graph_ports_disconnected_pos < graph_port_removed_sink_pos,
940 "event order is good (11)");
941
942 bt_put(graph);
943 bt_put(sink);
944 bt_put(src);
945 bt_put(conn);
946 bt_put(src_def_port);
947 bt_put(sink_def_port);
948 }
949
950 static
951 void test_src_adds_port_in_port_connected(void)
952 {
953 struct bt_component *src;
954 struct bt_component *sink;
955 struct bt_graph *graph;
956 struct bt_port *src_def_port;
957 struct bt_port *sink_def_port;
958 struct bt_port *src_hello_port;
959 struct bt_connection *conn;
960 struct event event;
961 size_t src_accept_port_connection_pos;
962 size_t sink_accept_port_connection_pos;
963 size_t src_port_connected_pos;
964 size_t sink_port_connected_pos;
965 size_t graph_ports_connected_pos;
966 size_t graph_port_added_src_pos;
967
968 prepare_test(TEST_SRC_ADDS_PORT_IN_PORT_CONNECTED,
969 "source adds port in port connected");
970 src = create_src();
971 sink = create_sink();
972 graph = create_graph();
973 src_def_port = bt_component_source_get_output_port_by_name(src, "out");
974 assert(src_def_port);
975 sink_def_port = bt_component_sink_get_input_port_by_name(sink, "in");
976 assert(sink_def_port);
977 conn = bt_graph_connect_ports(graph, src_def_port, sink_def_port);
978 assert(conn);
979 src_hello_port = bt_component_source_get_output_port_by_name(src,
980 "hello");
981 assert(src_hello_port);
982
983 /* We're supposed to have 6 events */
984 ok(events->len == 6, "we have the expected number of events");
985
986 /* Source's accept port connection */
987 event.type = COMP_ACCEPT_PORT_CONNECTION;
988 event.data.comp_accept_port_connection.comp = src;
989 event.data.comp_accept_port_connection.self_port = src_def_port;
990 event.data.comp_accept_port_connection.other_port = sink_def_port;
991 ok(has_event(&event), "got the expected source's accept port connection event");
992 src_accept_port_connection_pos = event_pos(&event);
993
994 /* Sink's accept port connection */
995 event.type = COMP_ACCEPT_PORT_CONNECTION;
996 event.data.comp_accept_port_connection.comp = sink;
997 event.data.comp_accept_port_connection.self_port = sink_def_port;
998 event.data.comp_accept_port_connection.other_port = src_def_port;
999 ok(has_event(&event), "got the expected sink's accept port connection event");
1000 sink_accept_port_connection_pos = event_pos(&event);
1001
1002 /* Source's port connected */
1003 event.type = COMP_PORT_CONNECTED;
1004 event.data.comp_port_connected.comp = src;
1005 event.data.comp_port_connected.self_port = src_def_port;
1006 event.data.comp_port_connected.other_port = sink_def_port;
1007 ok(has_event(&event), "got the expected source's port connected event");
1008 src_port_connected_pos = event_pos(&event);
1009
1010 /* Graph's port added (source) */
1011 event.type = GRAPH_PORT_ADDED;
1012 event.data.graph_port_added.comp = src;
1013 event.data.graph_port_added.port = src_hello_port;
1014 ok(has_event(&event), "got the expected graph's port added event (for source)");
1015 graph_port_added_src_pos = event_pos(&event);
1016
1017 /* Sink's port connected */
1018 event.type = COMP_PORT_CONNECTED;
1019 event.data.comp_port_connected.comp = sink;
1020 event.data.comp_port_connected.self_port = sink_def_port;
1021 event.data.comp_port_connected.other_port = src_def_port;
1022 ok(has_event(&event), "got the expected sink's port connected event");
1023 sink_port_connected_pos = event_pos(&event);
1024
1025 /* Graph's ports connected */
1026 event.type = GRAPH_PORTS_CONNECTED;
1027 event.data.graph_ports_connected.upstream_comp = src;
1028 event.data.graph_ports_connected.downstream_comp = sink;
1029 event.data.graph_ports_connected.upstream_port = src_def_port;
1030 event.data.graph_ports_connected.downstream_port = sink_def_port;
1031 event.data.graph_ports_connected.conn = conn;
1032 ok(has_event(&event), "got the expected graph's port connected event (for source)");
1033 graph_ports_connected_pos = event_pos(&event);
1034
1035 /* Order of events */
1036 ok(src_port_connected_pos < graph_ports_connected_pos,
1037 "event order is good (1)");
1038 ok(sink_port_connected_pos < graph_ports_connected_pos,
1039 "event order is good (2)");
1040 ok(src_accept_port_connection_pos < src_port_connected_pos,
1041 "event order is good (3)");
1042 ok(sink_accept_port_connection_pos < sink_port_connected_pos,
1043 "event order is good (4)");
1044 ok(src_port_connected_pos < graph_port_added_src_pos,
1045 "event order is good (5)");
1046 ok(graph_port_added_src_pos < graph_ports_connected_pos,
1047 "event order is good (6)");
1048
1049 bt_put(graph);
1050 bt_put(sink);
1051 bt_put(src);
1052 bt_put(conn);
1053 bt_put(src_def_port);
1054 bt_put(sink_def_port);
1055 bt_put(src_hello_port);
1056 }
1057
1058 static
1059 void test_simple(void)
1060 {
1061 struct bt_component *src;
1062 struct bt_component *sink;
1063 struct bt_graph *graph;
1064 struct bt_port *src_def_port;
1065 struct bt_port *sink_def_port;
1066 struct bt_connection *conn;
1067 struct event event;
1068 size_t src_accept_port_connection_pos;
1069 size_t sink_accept_port_connection_pos;
1070 size_t src_port_connected_pos;
1071 size_t sink_port_connected_pos;
1072 size_t graph_ports_connected_pos;
1073
1074 prepare_test(TEST_SIMPLE, "simple");
1075 src = create_src();
1076 sink = create_sink();
1077 graph = create_graph();
1078 src_def_port = bt_component_source_get_output_port_by_name(src, "out");
1079 assert(src_def_port);
1080 sink_def_port = bt_component_sink_get_input_port_by_name(sink, "in");
1081 assert(sink_def_port);
1082 conn = bt_graph_connect_ports(graph, src_def_port, sink_def_port);
1083 assert(conn);
1084
1085 /* We're supposed to have 5 events */
1086 ok(events->len == 5, "we have the expected number of events");
1087
1088 /* Source's accept port connection */
1089 event.type = COMP_ACCEPT_PORT_CONNECTION;
1090 event.data.comp_accept_port_connection.comp = src;
1091 event.data.comp_accept_port_connection.self_port = src_def_port;
1092 event.data.comp_accept_port_connection.other_port = sink_def_port;
1093 ok(has_event(&event), "got the expected source's accept port connection event");
1094 src_accept_port_connection_pos = event_pos(&event);
1095
1096 /* Sink's accept port connection */
1097 event.type = COMP_ACCEPT_PORT_CONNECTION;
1098 event.data.comp_accept_port_connection.comp = sink;
1099 event.data.comp_accept_port_connection.self_port = sink_def_port;
1100 event.data.comp_accept_port_connection.other_port = src_def_port;
1101 ok(has_event(&event), "got the expected sink's accept port connection event");
1102 sink_accept_port_connection_pos = event_pos(&event);
1103
1104 /* Source's port connected */
1105 event.type = COMP_PORT_CONNECTED;
1106 event.data.comp_port_connected.comp = src;
1107 event.data.comp_port_connected.self_port = src_def_port;
1108 event.data.comp_port_connected.other_port = sink_def_port;
1109 ok(has_event(&event), "got the expected source's port connected event");
1110 src_port_connected_pos = event_pos(&event);
1111
1112 /* Sink's port connected */
1113 event.type = COMP_PORT_CONNECTED;
1114 event.data.comp_port_connected.comp = sink;
1115 event.data.comp_port_connected.self_port = sink_def_port;
1116 event.data.comp_port_connected.other_port = src_def_port;
1117 ok(has_event(&event), "got the expected sink's port connected event");
1118 sink_port_connected_pos = event_pos(&event);
1119
1120 /* Graph's port connected */
1121 event.type = GRAPH_PORTS_CONNECTED;
1122 event.data.graph_ports_connected.upstream_comp = src;
1123 event.data.graph_ports_connected.downstream_comp = sink;
1124 event.data.graph_ports_connected.upstream_port = src_def_port;
1125 event.data.graph_ports_connected.downstream_port = sink_def_port;
1126 event.data.graph_ports_connected.conn = conn;
1127 ok(has_event(&event), "got the expected graph's ports connected event");
1128 graph_ports_connected_pos = event_pos(&event);
1129
1130 /* Order of events */
1131 ok(src_port_connected_pos < graph_ports_connected_pos,
1132 "event order is good (1)");
1133 ok(sink_port_connected_pos < graph_ports_connected_pos,
1134 "event order is good (2)");
1135 ok(src_accept_port_connection_pos < src_port_connected_pos,
1136 "event order is good (3)");
1137 ok(sink_accept_port_connection_pos < sink_port_connected_pos,
1138 "event order is good (4)");
1139
1140 bt_put(graph);
1141 bt_put(sink);
1142 bt_put(src);
1143 bt_put(conn);
1144 bt_put(src_def_port);
1145 bt_put(sink_def_port);
1146 }
1147
1148 static
1149 void test_empty_graph(void)
1150 {
1151 struct bt_graph *graph;
1152
1153 prepare_test(TEST_EMPTY_GRAPH, "empty graph");
1154 graph = create_graph();
1155 ok(events->len == 0, "empty graph generates no events");
1156 bt_put(graph);
1157 }
1158
1159 int main(int argc, char **argv)
1160 {
1161 plan_tests(NR_TESTS);
1162 init_test();
1163 test_empty_graph();
1164 test_simple();
1165 test_src_adds_port_in_port_connected();
1166 test_sink_removes_port_in_port_connected();
1167 test_sink_removes_port_in_port_connected_then_src_removes_disconnected_port();
1168 fini_test();
1169 return exit_status();
1170 }
This page took 0.08479 seconds and 4 git commands to generate.