4 * Copyright 2017 - Philippe Proulx <pproulx@efficios.com>
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.
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.
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.
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>
45 COMP_ACCEPT_PORT_CONNECTION
,
47 COMP_PORT_DISCONNECTED
,
50 GRAPH_PORTS_CONNECTED
,
51 GRAPH_PORTS_DISCONNECTED
,
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
,
67 struct bt_component
*comp
;
68 struct bt_port
*self_port
;
69 struct bt_port
*other_port
;
70 } comp_accept_port_connection
;
73 struct bt_component
*comp
;
74 struct bt_port
*self_port
;
75 struct bt_port
*other_port
;
76 } comp_port_connected
;
79 struct bt_component
*comp
;
81 } comp_port_disconnected
;
84 struct bt_component
*comp
;
89 struct bt_component
*comp
;
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
;
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
;
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
;
116 void clear_events(void)
118 g_array_set_size(events
, 0);
122 void append_event(struct event
*event
)
124 g_array_append_val(events
, *event
);
128 bool compare_events(struct event
*ev_a
, struct event
*ev_b
)
130 if (ev_a
->type
!= ev_b
->type
) {
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
) {
141 if (ev_a
->data
.comp_accept_port_connection
.self_port
!=
142 ev_b
->data
.comp_accept_port_connection
.self_port
) {
146 if (ev_a
->data
.comp_accept_port_connection
.other_port
!=
147 ev_b
->data
.comp_accept_port_connection
.other_port
) {
151 case COMP_PORT_CONNECTED
:
152 if (ev_a
->data
.comp_port_connected
.comp
!=
153 ev_b
->data
.comp_port_connected
.comp
) {
157 if (ev_a
->data
.comp_port_connected
.self_port
!=
158 ev_b
->data
.comp_port_connected
.self_port
) {
162 if (ev_a
->data
.comp_port_connected
.other_port
!=
163 ev_b
->data
.comp_port_connected
.other_port
) {
167 case COMP_PORT_DISCONNECTED
:
168 if (ev_a
->data
.comp_port_disconnected
.comp
!=
169 ev_b
->data
.comp_port_disconnected
.comp
) {
173 if (ev_a
->data
.comp_port_disconnected
.port
!=
174 ev_b
->data
.comp_port_disconnected
.port
) {
178 case GRAPH_PORT_ADDED
:
179 if (ev_a
->data
.graph_port_added
.comp
!=
180 ev_b
->data
.graph_port_added
.comp
) {
184 if (ev_a
->data
.graph_port_added
.port
!=
185 ev_b
->data
.graph_port_added
.port
) {
189 case GRAPH_PORT_REMOVED
:
190 if (ev_a
->data
.graph_port_removed
.comp
!=
191 ev_b
->data
.graph_port_removed
.comp
) {
195 if (ev_a
->data
.graph_port_removed
.port
!=
196 ev_b
->data
.graph_port_removed
.port
) {
200 case GRAPH_PORTS_CONNECTED
:
201 if (ev_a
->data
.graph_ports_connected
.upstream_comp
!=
202 ev_b
->data
.graph_ports_connected
.upstream_comp
) {
206 if (ev_a
->data
.graph_ports_connected
.downstream_comp
!=
207 ev_b
->data
.graph_ports_connected
.downstream_comp
) {
211 if (ev_a
->data
.graph_ports_connected
.upstream_port
!=
212 ev_b
->data
.graph_ports_connected
.upstream_port
) {
216 if (ev_a
->data
.graph_ports_connected
.downstream_port
!=
217 ev_b
->data
.graph_ports_connected
.downstream_port
) {
221 if (ev_a
->data
.graph_ports_connected
.conn
!=
222 ev_b
->data
.graph_ports_connected
.conn
) {
226 case GRAPH_PORTS_DISCONNECTED
:
227 if (ev_a
->data
.graph_ports_disconnected
.upstream_comp
!=
228 ev_b
->data
.graph_ports_disconnected
.upstream_comp
) {
232 if (ev_a
->data
.graph_ports_disconnected
.downstream_comp
!=
233 ev_b
->data
.graph_ports_disconnected
.downstream_comp
) {
237 if (ev_a
->data
.graph_ports_disconnected
.upstream_port
!=
238 ev_b
->data
.graph_ports_disconnected
.upstream_port
) {
242 if (ev_a
->data
.graph_ports_disconnected
.downstream_port
!=
243 ev_b
->data
.graph_ports_disconnected
.downstream_port
) {
255 bool has_event(struct event
*event
)
259 for (i
= 0; i
< events
->len
; i
++) {
260 struct event
*ev
= &g_array_index(events
, struct event
, i
);
262 if (compare_events(event
, ev
)) {
271 size_t event_pos(struct event
*event
)
275 for (i
= 0; i
< events
->len
; i
++) {
276 struct event
*ev
= &g_array_index(events
, struct event
, i
);
278 if (compare_events(event
, ev
)) {
287 struct bt_notification_iterator_next_method_return
src_iter_next(
288 struct bt_private_connection_private_notification_iterator
*priv_iterator
)
290 struct bt_notification_iterator_next_method_return ret
= {
291 .status
= BT_NOTIFICATION_ITERATOR_STATUS_ERROR
,
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
)
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
,
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
;
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
)
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
,
334 bt_put(event
.data
.comp_port_connected
.comp
);
335 bt_put(event
.data
.comp_port_connected
.self_port
);
336 append_event(&event
);
338 switch (current_test
) {
339 case TEST_SRC_ADDS_PORT_IN_PORT_CONNECTED
:
340 ret
= bt_private_component_source_add_output_private_port(
341 private_component
, "hello", NULL
, NULL
);
350 void src_port_disconnected(struct bt_private_component
*private_component
,
351 struct bt_private_port
*private_port
)
354 struct event event
= {
355 .type
= COMP_PORT_DISCONNECTED
,
356 .data
.comp_port_disconnected
= {
357 .comp
= bt_component_from_private_component(private_component
),
358 .port
= bt_port_from_private_port(private_port
),
362 bt_put(event
.data
.comp_port_disconnected
.comp
);
363 bt_put(event
.data
.comp_port_disconnected
.port
);
364 append_event(&event
);
366 switch (current_test
) {
367 case TEST_SINK_REMOVES_PORT_IN_CONSUME_THEN_SRC_REMOVES_DISCONNECTED_PORT
:
368 ret
= bt_private_port_remove_from_component(private_port
);
376 enum bt_component_status
src_init(struct bt_private_component
*priv_comp
,
377 struct bt_value
*params
, void *init_method_data
)
381 ret
= bt_private_component_source_add_output_private_port(
382 priv_comp
, "out", NULL
, NULL
);
384 return BT_COMPONENT_STATUS_OK
;
388 enum bt_component_status
sink_consume(
389 struct bt_private_component
*priv_component
)
391 struct bt_private_port
*def_port
;
394 switch (current_test
) {
395 case TEST_SINK_REMOVES_PORT_IN_CONSUME
:
396 case TEST_SINK_REMOVES_PORT_IN_CONSUME_THEN_SRC_REMOVES_DISCONNECTED_PORT
:
397 def_port
= bt_private_component_sink_get_input_private_port_by_name(
398 priv_component
, "in");
400 ret
= bt_private_port_remove_from_component(def_port
);
408 return BT_COMPONENT_STATUS_OK
;
412 void sink_port_connected(struct bt_private_component
*private_component
,
413 struct bt_private_port
*self_private_port
,
414 struct bt_port
*other_port
)
416 struct event event
= {
417 .type
= COMP_PORT_CONNECTED
,
418 .data
.comp_port_connected
= {
419 .comp
= bt_component_from_private_component(private_component
),
420 .self_port
= bt_port_from_private_port(self_private_port
),
421 .other_port
= other_port
,
425 bt_put(event
.data
.comp_port_connected
.comp
);
426 bt_put(event
.data
.comp_port_connected
.self_port
);
427 append_event(&event
);
431 void sink_port_disconnected(struct bt_private_component
*private_component
,
432 struct bt_private_port
*private_port
)
434 struct event event
= {
435 .type
= COMP_PORT_DISCONNECTED
,
436 .data
.comp_port_disconnected
= {
437 .comp
= bt_component_from_private_component(private_component
),
438 .port
= bt_port_from_private_port(private_port
),
442 bt_put(event
.data
.comp_port_disconnected
.comp
);
443 bt_put(event
.data
.comp_port_disconnected
.port
);
444 append_event(&event
);
448 enum bt_component_status
sink_init(struct bt_private_component
*priv_comp
,
449 struct bt_value
*params
, void *init_method_data
)
453 ret
= bt_private_component_sink_add_input_private_port(priv_comp
,
456 return BT_COMPONENT_STATUS_OK
;
460 void graph_port_added(struct bt_port
*port
,
463 struct bt_component
*comp
= bt_port_get_component(port
);
468 struct event event
= {
469 .type
= GRAPH_PORT_ADDED
,
470 .data
.graph_port_added
= {
476 append_event(&event
);
480 void graph_port_removed(struct bt_component
*component
,
481 struct bt_port
*port
, void *data
)
483 struct event event
= {
484 .type
= GRAPH_PORT_REMOVED
,
485 .data
.graph_port_removed
= {
491 append_event(&event
);
495 void graph_ports_connected(struct bt_port
*upstream_port
,
496 struct bt_port
*downstream_port
, void *data
)
498 struct bt_component
*upstream_comp
=
499 bt_port_get_component(upstream_port
);
500 struct bt_component
*downstream_comp
=
501 bt_port_get_component(downstream_port
);
502 struct bt_connection
*conn
= bt_port_get_connection(upstream_port
);
504 assert(upstream_comp
);
505 assert(downstream_comp
);
507 bt_put(upstream_comp
);
508 bt_put(downstream_comp
);
511 struct event event
= {
512 .type
= GRAPH_PORTS_CONNECTED
,
513 .data
.graph_ports_connected
= {
514 .upstream_comp
= upstream_comp
,
515 .downstream_comp
= downstream_comp
,
516 .upstream_port
= upstream_port
,
517 .downstream_port
= downstream_port
,
522 append_event(&event
);
526 void graph_ports_disconnected(
527 struct bt_component
*upstream_comp
,
528 struct bt_component
*downstream_comp
,
529 struct bt_port
*upstream_port
, struct bt_port
*downstream_port
,
532 struct event event
= {
533 .type
= GRAPH_PORTS_DISCONNECTED
,
534 .data
.graph_ports_disconnected
= {
535 .upstream_comp
= upstream_comp
,
536 .downstream_comp
= downstream_comp
,
537 .upstream_port
= upstream_port
,
538 .downstream_port
= downstream_port
,
542 append_event(&event
);
550 src_comp_class
= bt_component_class_source_create("src", src_iter_next
);
551 assert(src_comp_class
);
552 ret
= bt_component_class_set_init_method(src_comp_class
, src_init
);
554 ret
= bt_component_class_set_accept_port_connection_method(
555 src_comp_class
, accept_port_connection
);
557 ret
= bt_component_class_set_port_connected_method(src_comp_class
,
560 ret
= bt_component_class_set_port_disconnected_method(
561 src_comp_class
, src_port_disconnected
);
563 sink_comp_class
= bt_component_class_sink_create("sink", sink_consume
);
564 assert(sink_comp_class
);
565 ret
= bt_component_class_set_init_method(sink_comp_class
, sink_init
);
567 ret
= bt_component_class_set_accept_port_connection_method(
568 sink_comp_class
, accept_port_connection
);
570 ret
= bt_component_class_set_port_connected_method(sink_comp_class
,
571 sink_port_connected
);
573 ret
= bt_component_class_set_port_disconnected_method(sink_comp_class
,
574 sink_port_disconnected
);
576 bt_component_class_freeze(src_comp_class
);
577 bt_component_class_freeze(sink_comp_class
);
578 events
= g_array_new(FALSE
, TRUE
, sizeof(struct event
));
585 bt_put(src_comp_class
);
586 bt_put(sink_comp_class
);
587 g_array_free(events
, TRUE
);
591 struct bt_component
*create_src(struct bt_graph
*graph
)
593 struct bt_component
*comp
;
596 ret
= bt_graph_add_component(graph
, src_comp_class
, "src-comp", NULL
,
603 struct bt_component
*create_sink(struct bt_graph
*graph
)
605 struct bt_component
*comp
;
608 ret
= bt_graph_add_component(graph
, sink_comp_class
, "sink-comp",
615 struct bt_graph
*create_graph(void)
617 struct bt_graph
*graph
= bt_graph_create();
621 ret
= bt_graph_add_port_added_listener(graph
, graph_port_added
, NULL
,
624 ret
= bt_graph_add_port_removed_listener(graph
, graph_port_removed
,
627 ret
= bt_graph_add_ports_connected_listener(graph
,
628 graph_ports_connected
, NULL
, NULL
);
630 ret
= bt_graph_add_ports_disconnected_listener(graph
,
631 graph_ports_disconnected
, NULL
, NULL
);
637 void prepare_test(enum test test
, const char *name
)
641 diag("test: %s", name
);
645 void test_sink_removes_port_in_port_connected_then_src_removes_disconnected_port(void)
648 struct bt_component
*src
;
649 struct bt_component
*sink
;
650 struct bt_graph
*graph
;
651 struct bt_port
*src_def_port
;
652 struct bt_port
*sink_def_port
;
653 struct bt_connection
*conn
;
655 enum bt_graph_status status
;
656 size_t src_accept_port_connection_pos
;
657 size_t sink_accept_port_connection_pos
;
658 size_t src_port_connected_pos
;
659 size_t sink_port_connected_pos
;
660 size_t graph_ports_connected
;
661 size_t src_port_disconnected_pos
;
662 size_t sink_port_disconnected_pos
;
663 size_t graph_ports_disconnected_pos
;
664 size_t graph_port_removed_src_pos
;
665 size_t graph_port_removed_sink_pos
;
667 prepare_test(TEST_SINK_REMOVES_PORT_IN_CONSUME_THEN_SRC_REMOVES_DISCONNECTED_PORT
,
668 "sink removes port in consume, then source removes disconnected port");
669 graph
= create_graph();
671 src
= create_src(graph
);
672 sink
= create_sink(graph
);
673 src_def_port
= bt_component_source_get_output_port_by_name(src
, "out");
674 assert(src_def_port
);
675 sink_def_port
= bt_component_sink_get_input_port_by_name(sink
, "in");
676 assert(sink_def_port
);
677 status
= bt_graph_connect_ports(graph
, src_def_port
, sink_def_port
,
682 /* We're supposed to have 7 events so far */
683 ok(events
->len
== 7, "we have the expected number of events (before consume)");
685 /* Source's port added */
686 event
.type
= GRAPH_PORT_ADDED
;
687 event
.data
.graph_port_added
.comp
= src
;
688 event
.data
.graph_port_added
.port
= src_def_port
;
689 ok(has_event(&event
), "got the expected graph's port added event (for source, initial)");
691 /* Sink's port added */
692 event
.type
= GRAPH_PORT_ADDED
;
693 event
.data
.graph_port_added
.comp
= sink
;
694 event
.data
.graph_port_added
.port
= sink_def_port
;
695 ok(has_event(&event
), "got the expected graph's port added event (for sink, initial)");
697 /* Source's accept port connection */
698 event
.type
= COMP_ACCEPT_PORT_CONNECTION
;
699 event
.data
.comp_accept_port_connection
.comp
= src
;
700 event
.data
.comp_accept_port_connection
.self_port
= src_def_port
;
701 event
.data
.comp_accept_port_connection
.other_port
= sink_def_port
;
702 ok(has_event(&event
), "got the expected source's accept port connection event");
703 src_accept_port_connection_pos
= event_pos(&event
);
705 /* Sink's accept port connection */
706 event
.type
= COMP_ACCEPT_PORT_CONNECTION
;
707 event
.data
.comp_accept_port_connection
.comp
= sink
;
708 event
.data
.comp_accept_port_connection
.self_port
= sink_def_port
;
709 event
.data
.comp_accept_port_connection
.other_port
= src_def_port
;
710 ok(has_event(&event
), "got the expected sink's accept port connection event");
711 sink_accept_port_connection_pos
= event_pos(&event
);
713 /* Source's port connected */
714 event
.type
= COMP_PORT_CONNECTED
;
715 event
.data
.comp_port_connected
.comp
= src
;
716 event
.data
.comp_port_connected
.self_port
= src_def_port
;
717 event
.data
.comp_port_connected
.other_port
= sink_def_port
;
718 ok(has_event(&event
), "got the expected source's port connected event");
719 src_port_connected_pos
= event_pos(&event
);
721 /* Sink's port connected */
722 event
.type
= COMP_PORT_CONNECTED
;
723 event
.data
.comp_port_connected
.comp
= sink
;
724 event
.data
.comp_port_connected
.self_port
= sink_def_port
;
725 event
.data
.comp_port_connected
.other_port
= src_def_port
;
726 ok(has_event(&event
), "got the expected sink's port connected event");
727 sink_port_connected_pos
= event_pos(&event
);
729 /* Graph's ports connected */
730 event
.type
= GRAPH_PORTS_CONNECTED
;
731 event
.data
.graph_ports_connected
.upstream_comp
= src
;
732 event
.data
.graph_ports_connected
.downstream_comp
= sink
;
733 event
.data
.graph_ports_connected
.upstream_port
= src_def_port
;
734 event
.data
.graph_ports_connected
.downstream_port
= sink_def_port
;
735 event
.data
.graph_ports_connected
.conn
= conn
;
736 ok(has_event(&event
), "got the expected graph's ports connected event");
737 graph_ports_connected
= event_pos(&event
);
739 /* Order of events */
740 ok(src_port_connected_pos
< graph_ports_connected
,
741 "event order is good (1)");
742 ok(sink_port_connected_pos
< graph_ports_connected
,
743 "event order is good (2)");
744 ok(src_accept_port_connection_pos
< src_port_connected_pos
,
745 "event order is good (3)");
746 ok(sink_accept_port_connection_pos
< sink_port_connected_pos
,
747 "event order is good (4)");
749 /* Consume sink once */
751 ret
= bt_graph_consume(graph
);
754 /* We're supposed to have 5 new events */
755 ok(events
->len
== 5, "we have the expected number of events (after consume)");
757 /* Source's port disconnected */
758 event
.type
= COMP_PORT_DISCONNECTED
;
759 event
.data
.comp_port_disconnected
.comp
= src
;
760 event
.data
.comp_port_disconnected
.port
= src_def_port
;
761 ok(has_event(&event
), "got the expected source's port disconnected event");
762 src_port_disconnected_pos
= event_pos(&event
);
764 /* Sink's port disconnected */
765 event
.type
= COMP_PORT_DISCONNECTED
;
766 event
.data
.comp_port_disconnected
.comp
= sink
;
767 event
.data
.comp_port_disconnected
.port
= sink_def_port
;
768 ok(has_event(&event
), "got the expected sink's port disconnected event");
769 sink_port_disconnected_pos
= event_pos(&event
);
771 /* Graph's ports disconnected */
772 event
.type
= GRAPH_PORTS_DISCONNECTED
;
773 event
.data
.graph_ports_disconnected
.upstream_comp
= src
;
774 event
.data
.graph_ports_disconnected
.downstream_comp
= sink
;
775 event
.data
.graph_ports_disconnected
.upstream_port
= src_def_port
;
776 event
.data
.graph_ports_disconnected
.downstream_port
= sink_def_port
;
777 ok(has_event(&event
), "got the expected graph's ports disconnected event");
778 graph_ports_disconnected_pos
= event_pos(&event
);
780 /* Graph's port removed (sink) */
781 event
.type
= GRAPH_PORT_REMOVED
;
782 event
.data
.graph_port_removed
.comp
= sink
;
783 event
.data
.graph_port_removed
.port
= sink_def_port
;
784 ok(has_event(&event
), "got the expected graph's port removed event (for sink)");
785 graph_port_removed_sink_pos
= event_pos(&event
);
787 /* Graph's port removed (source) */
788 event
.type
= GRAPH_PORT_REMOVED
;
789 event
.data
.graph_port_removed
.comp
= src
;
790 event
.data
.graph_port_removed
.port
= src_def_port
;
791 ok(has_event(&event
), "got the expected graph's port removed event (for source)");
792 graph_port_removed_src_pos
= event_pos(&event
);
794 /* Order of events */
795 ok(src_port_disconnected_pos
< graph_ports_disconnected_pos
,
796 "event order is good (5)");
797 ok(src_port_disconnected_pos
< graph_port_removed_sink_pos
,
798 "event order is good (6)");
799 ok(src_port_disconnected_pos
< graph_port_removed_src_pos
,
800 "event order is good (7)");
801 ok(sink_port_disconnected_pos
< graph_ports_disconnected_pos
,
802 "event order is good (8)");
803 ok(sink_port_disconnected_pos
< graph_port_removed_sink_pos
,
804 "event order is good (9)");
805 ok(sink_port_disconnected_pos
< graph_port_removed_src_pos
,
806 "event order is good (10)");
807 ok(graph_ports_disconnected_pos
< graph_port_removed_sink_pos
,
808 "event order is good (11)");
809 ok(graph_port_removed_src_pos
< graph_ports_disconnected_pos
,
810 "event order is good (12)");
811 ok(graph_port_removed_src_pos
< graph_port_removed_sink_pos
,
812 "event order is good (13)");
818 bt_put(src_def_port
);
819 bt_put(sink_def_port
);
823 void test_sink_removes_port_in_port_connected(void)
826 struct bt_component
*src
;
827 struct bt_component
*sink
;
828 struct bt_graph
*graph
;
829 struct bt_port
*src_def_port
;
830 struct bt_port
*sink_def_port
;
831 struct bt_connection
*conn
;
833 enum bt_graph_status status
;
834 size_t src_accept_port_connection_pos
;
835 size_t sink_accept_port_connection_pos
;
836 size_t src_port_connected_pos
;
837 size_t sink_port_connected_pos
;
838 size_t graph_ports_connected_pos
;
839 size_t src_port_disconnected_pos
;
840 size_t sink_port_disconnected_pos
;
841 size_t graph_ports_disconnected_pos
;
842 size_t graph_port_removed_sink_pos
;
844 prepare_test(TEST_SINK_REMOVES_PORT_IN_CONSUME
,
845 "sink removes port in consume");
846 graph
= create_graph();
848 src
= create_src(graph
);
849 sink
= create_sink(graph
);
850 src_def_port
= bt_component_source_get_output_port_by_name(src
, "out");
851 assert(src_def_port
);
852 sink_def_port
= bt_component_sink_get_input_port_by_name(sink
, "in");
853 assert(sink_def_port
);
854 status
= bt_graph_connect_ports(graph
, src_def_port
, sink_def_port
,
858 /* We're supposed to have 7 events so far */
859 ok(events
->len
== 7, "we have the expected number of events (before consume)");
861 /* Source's port added */
862 event
.type
= GRAPH_PORT_ADDED
;
863 event
.data
.graph_port_added
.comp
= src
;
864 event
.data
.graph_port_added
.port
= src_def_port
;
865 ok(has_event(&event
), "got the expected graph's port added event (for source, initial)");
867 /* Sink's port added */
868 event
.type
= GRAPH_PORT_ADDED
;
869 event
.data
.graph_port_added
.comp
= sink
;
870 event
.data
.graph_port_added
.port
= sink_def_port
;
871 ok(has_event(&event
), "got the expected graph's port added event (for sink, initial)");
873 /* Source's accept port connection */
874 event
.type
= COMP_ACCEPT_PORT_CONNECTION
;
875 event
.data
.comp_accept_port_connection
.comp
= src
;
876 event
.data
.comp_accept_port_connection
.self_port
= src_def_port
;
877 event
.data
.comp_accept_port_connection
.other_port
= sink_def_port
;
878 ok(has_event(&event
), "got the expected source's accept port connection event");
879 src_accept_port_connection_pos
= event_pos(&event
);
881 /* Sink's accept port connection */
882 event
.type
= COMP_ACCEPT_PORT_CONNECTION
;
883 event
.data
.comp_accept_port_connection
.comp
= sink
;
884 event
.data
.comp_accept_port_connection
.self_port
= sink_def_port
;
885 event
.data
.comp_accept_port_connection
.other_port
= src_def_port
;
886 ok(has_event(&event
), "got the expected sink's accept port connection event");
887 sink_accept_port_connection_pos
= event_pos(&event
);
889 /* Source's port connected */
890 event
.type
= COMP_PORT_CONNECTED
;
891 event
.data
.comp_port_connected
.comp
= src
;
892 event
.data
.comp_port_connected
.self_port
= src_def_port
;
893 event
.data
.comp_port_connected
.other_port
= sink_def_port
;
894 ok(has_event(&event
), "got the expected source's port connected event");
895 src_port_connected_pos
= event_pos(&event
);
897 /* Sink's port connected */
898 event
.type
= COMP_PORT_CONNECTED
;
899 event
.data
.comp_port_connected
.comp
= sink
;
900 event
.data
.comp_port_connected
.self_port
= sink_def_port
;
901 event
.data
.comp_port_connected
.other_port
= src_def_port
;
902 ok(has_event(&event
), "got the expected sink's port connected event");
903 sink_port_connected_pos
= event_pos(&event
);
905 /* Graph's ports connected */
906 event
.type
= GRAPH_PORTS_CONNECTED
;
907 event
.data
.graph_ports_connected
.upstream_comp
= src
;
908 event
.data
.graph_ports_connected
.downstream_comp
= sink
;
909 event
.data
.graph_ports_connected
.upstream_port
= src_def_port
;
910 event
.data
.graph_ports_connected
.downstream_port
= sink_def_port
;
911 event
.data
.graph_ports_connected
.conn
= conn
;
912 ok(has_event(&event
), "got the expected graph's ports connected event");
913 graph_ports_connected_pos
= event_pos(&event
);
915 /* Order of events */
916 ok(src_port_connected_pos
< graph_ports_connected_pos
,
917 "event order is good (1)");
918 ok(sink_port_connected_pos
< graph_ports_connected_pos
,
919 "event order is good (2)");
920 ok(src_accept_port_connection_pos
< src_port_connected_pos
,
921 "event order is good (3)");
922 ok(sink_accept_port_connection_pos
< sink_port_connected_pos
,
923 "event order is good (4)");
925 /* Consume sink once */
927 ret
= bt_graph_consume(graph
);
930 /* We're supposed to have 4 new events */
931 ok(events
->len
== 4, "we have the expected number of events (after consume)");
933 /* Source's port disconnected */
934 event
.type
= COMP_PORT_DISCONNECTED
;
935 event
.data
.comp_port_disconnected
.comp
= src
;
936 event
.data
.comp_port_disconnected
.port
= src_def_port
;
937 ok(has_event(&event
), "got the expected source's port disconnected event");
938 src_port_disconnected_pos
= event_pos(&event
);
940 /* Sink's port disconnected */
941 event
.type
= COMP_PORT_DISCONNECTED
;
942 event
.data
.comp_port_disconnected
.comp
= sink
;
943 event
.data
.comp_port_disconnected
.port
= sink_def_port
;
944 ok(has_event(&event
), "got the expected sink's port disconnected event");
945 sink_port_disconnected_pos
= event_pos(&event
);
947 /* Graph's ports disconnected */
948 event
.type
= GRAPH_PORTS_DISCONNECTED
;
949 event
.data
.graph_ports_disconnected
.upstream_comp
= src
;
950 event
.data
.graph_ports_disconnected
.downstream_comp
= sink
;
951 event
.data
.graph_ports_disconnected
.upstream_port
= src_def_port
;
952 event
.data
.graph_ports_disconnected
.downstream_port
= sink_def_port
;
953 ok(has_event(&event
), "got the expected graph's ports disconnected event");
954 graph_ports_disconnected_pos
= event_pos(&event
);
956 /* Graph's port removed (sink) */
957 event
.type
= GRAPH_PORT_REMOVED
;
958 event
.data
.graph_port_removed
.comp
= sink
;
959 event
.data
.graph_port_removed
.port
= sink_def_port
;
960 ok(has_event(&event
), "got the expected graph's port removed event (for sink)");
961 graph_port_removed_sink_pos
= event_pos(&event
);
963 /* Order of events */
964 ok(src_port_disconnected_pos
< graph_ports_disconnected_pos
,
965 "event order is good (5)");
966 ok(src_port_disconnected_pos
< graph_port_removed_sink_pos
,
967 "event order is good (7)");
968 ok(sink_port_disconnected_pos
< graph_ports_disconnected_pos
,
969 "event order is good (8)");
970 ok(sink_port_disconnected_pos
< graph_port_removed_sink_pos
,
971 "event order is good (10)");
972 ok(graph_ports_disconnected_pos
< graph_port_removed_sink_pos
,
973 "event order is good (11)");
979 bt_put(src_def_port
);
980 bt_put(sink_def_port
);
984 void test_src_adds_port_in_port_connected(void)
986 struct bt_component
*src
;
987 struct bt_component
*sink
;
988 struct bt_graph
*graph
;
989 struct bt_port
*src_def_port
;
990 struct bt_port
*sink_def_port
;
991 struct bt_port
*src_hello_port
;
992 struct bt_connection
*conn
;
994 enum bt_graph_status status
;
995 size_t src_accept_port_connection_pos
;
996 size_t sink_accept_port_connection_pos
;
997 size_t src_port_connected_pos
;
998 size_t sink_port_connected_pos
;
999 size_t graph_ports_connected_pos
;
1000 size_t graph_port_added_src_pos
;
1002 prepare_test(TEST_SRC_ADDS_PORT_IN_PORT_CONNECTED
,
1003 "source adds port in port connected");
1004 graph
= create_graph();
1006 src
= create_src(graph
);
1007 sink
= create_sink(graph
);
1008 src_def_port
= bt_component_source_get_output_port_by_name(src
, "out");
1009 assert(src_def_port
);
1010 sink_def_port
= bt_component_sink_get_input_port_by_name(sink
, "in");
1011 assert(sink_def_port
);
1012 status
= bt_graph_connect_ports(graph
, src_def_port
, sink_def_port
,
1014 assert(status
== 0);
1015 src_hello_port
= bt_component_source_get_output_port_by_name(src
,
1017 assert(src_hello_port
);
1019 /* We're supposed to have 8 events */
1020 ok(events
->len
== 8, "we have the expected number of events");
1022 /* Source's port added */
1023 event
.type
= GRAPH_PORT_ADDED
;
1024 event
.data
.graph_port_added
.comp
= src
;
1025 event
.data
.graph_port_added
.port
= src_def_port
;
1026 ok(has_event(&event
), "got the expected graph's port added event (for source, initial)");
1028 /* Sink's port added */
1029 event
.type
= GRAPH_PORT_ADDED
;
1030 event
.data
.graph_port_added
.comp
= sink
;
1031 event
.data
.graph_port_added
.port
= sink_def_port
;
1032 ok(has_event(&event
), "got the expected graph's port added event (for sink, initial)");
1034 /* Source's accept port connection */
1035 event
.type
= COMP_ACCEPT_PORT_CONNECTION
;
1036 event
.data
.comp_accept_port_connection
.comp
= src
;
1037 event
.data
.comp_accept_port_connection
.self_port
= src_def_port
;
1038 event
.data
.comp_accept_port_connection
.other_port
= sink_def_port
;
1039 ok(has_event(&event
), "got the expected source's accept port connection event");
1040 src_accept_port_connection_pos
= event_pos(&event
);
1042 /* Sink's accept port connection */
1043 event
.type
= COMP_ACCEPT_PORT_CONNECTION
;
1044 event
.data
.comp_accept_port_connection
.comp
= sink
;
1045 event
.data
.comp_accept_port_connection
.self_port
= sink_def_port
;
1046 event
.data
.comp_accept_port_connection
.other_port
= src_def_port
;
1047 ok(has_event(&event
), "got the expected sink's accept port connection event");
1048 sink_accept_port_connection_pos
= event_pos(&event
);
1050 /* Source's port connected */
1051 event
.type
= COMP_PORT_CONNECTED
;
1052 event
.data
.comp_port_connected
.comp
= src
;
1053 event
.data
.comp_port_connected
.self_port
= src_def_port
;
1054 event
.data
.comp_port_connected
.other_port
= sink_def_port
;
1055 ok(has_event(&event
), "got the expected source's port connected event");
1056 src_port_connected_pos
= event_pos(&event
);
1058 /* Graph's port added (source) */
1059 event
.type
= GRAPH_PORT_ADDED
;
1060 event
.data
.graph_port_added
.comp
= src
;
1061 event
.data
.graph_port_added
.port
= src_hello_port
;
1062 ok(has_event(&event
), "got the expected graph's port added event (for source)");
1063 graph_port_added_src_pos
= event_pos(&event
);
1065 /* Sink's port connected */
1066 event
.type
= COMP_PORT_CONNECTED
;
1067 event
.data
.comp_port_connected
.comp
= sink
;
1068 event
.data
.comp_port_connected
.self_port
= sink_def_port
;
1069 event
.data
.comp_port_connected
.other_port
= src_def_port
;
1070 ok(has_event(&event
), "got the expected sink's port connected event");
1071 sink_port_connected_pos
= event_pos(&event
);
1073 /* Graph's ports connected */
1074 event
.type
= GRAPH_PORTS_CONNECTED
;
1075 event
.data
.graph_ports_connected
.upstream_comp
= src
;
1076 event
.data
.graph_ports_connected
.downstream_comp
= sink
;
1077 event
.data
.graph_ports_connected
.upstream_port
= src_def_port
;
1078 event
.data
.graph_ports_connected
.downstream_port
= sink_def_port
;
1079 event
.data
.graph_ports_connected
.conn
= conn
;
1080 ok(has_event(&event
), "got the expected graph's port connected event (for source)");
1081 graph_ports_connected_pos
= event_pos(&event
);
1083 /* Order of events */
1084 ok(src_port_connected_pos
< graph_ports_connected_pos
,
1085 "event order is good (1)");
1086 ok(sink_port_connected_pos
< graph_ports_connected_pos
,
1087 "event order is good (2)");
1088 ok(src_accept_port_connection_pos
< src_port_connected_pos
,
1089 "event order is good (3)");
1090 ok(sink_accept_port_connection_pos
< sink_port_connected_pos
,
1091 "event order is good (4)");
1092 ok(src_port_connected_pos
< graph_port_added_src_pos
,
1093 "event order is good (5)");
1094 ok(graph_port_added_src_pos
< graph_ports_connected_pos
,
1095 "event order is good (6)");
1101 bt_put(src_def_port
);
1102 bt_put(sink_def_port
);
1103 bt_put(src_hello_port
);
1107 void test_simple(void)
1109 struct bt_component
*src
;
1110 struct bt_component
*sink
;
1111 struct bt_graph
*graph
;
1112 struct bt_port
*src_def_port
;
1113 struct bt_port
*sink_def_port
;
1114 struct bt_connection
*conn
;
1116 enum bt_graph_status status
;
1117 size_t src_accept_port_connection_pos
;
1118 size_t sink_accept_port_connection_pos
;
1119 size_t src_port_connected_pos
;
1120 size_t sink_port_connected_pos
;
1121 size_t graph_ports_connected_pos
;
1123 prepare_test(TEST_SIMPLE
, "simple");
1124 graph
= create_graph();
1126 src
= create_src(graph
);
1127 sink
= create_sink(graph
);
1128 src_def_port
= bt_component_source_get_output_port_by_name(src
, "out");
1129 assert(src_def_port
);
1130 sink_def_port
= bt_component_sink_get_input_port_by_name(sink
, "in");
1131 assert(sink_def_port
);
1132 status
= bt_graph_connect_ports(graph
, src_def_port
, sink_def_port
,
1134 assert(status
== 0);
1136 /* We're supposed to have 7 events */
1137 ok(events
->len
== 7, "we have the expected number of events");
1139 /* Source's port added */
1140 event
.type
= GRAPH_PORT_ADDED
;
1141 event
.data
.graph_port_added
.comp
= src
;
1142 event
.data
.graph_port_added
.port
= src_def_port
;
1143 ok(has_event(&event
), "got the expected graph's port added event (for source, initial)");
1145 /* Sink's port added */
1146 event
.type
= GRAPH_PORT_ADDED
;
1147 event
.data
.graph_port_added
.comp
= sink
;
1148 event
.data
.graph_port_added
.port
= sink_def_port
;
1149 ok(has_event(&event
), "got the expected graph's port added event (for sink, initial)");
1151 /* Source's accept port connection */
1152 event
.type
= COMP_ACCEPT_PORT_CONNECTION
;
1153 event
.data
.comp_accept_port_connection
.comp
= src
;
1154 event
.data
.comp_accept_port_connection
.self_port
= src_def_port
;
1155 event
.data
.comp_accept_port_connection
.other_port
= sink_def_port
;
1156 ok(has_event(&event
), "got the expected source's accept port connection event");
1157 src_accept_port_connection_pos
= event_pos(&event
);
1159 /* Sink's accept port connection */
1160 event
.type
= COMP_ACCEPT_PORT_CONNECTION
;
1161 event
.data
.comp_accept_port_connection
.comp
= sink
;
1162 event
.data
.comp_accept_port_connection
.self_port
= sink_def_port
;
1163 event
.data
.comp_accept_port_connection
.other_port
= src_def_port
;
1164 ok(has_event(&event
), "got the expected sink's accept port connection event");
1165 sink_accept_port_connection_pos
= event_pos(&event
);
1167 /* Source's port connected */
1168 event
.type
= COMP_PORT_CONNECTED
;
1169 event
.data
.comp_port_connected
.comp
= src
;
1170 event
.data
.comp_port_connected
.self_port
= src_def_port
;
1171 event
.data
.comp_port_connected
.other_port
= sink_def_port
;
1172 ok(has_event(&event
), "got the expected source's port connected event");
1173 src_port_connected_pos
= event_pos(&event
);
1175 /* Sink's port connected */
1176 event
.type
= COMP_PORT_CONNECTED
;
1177 event
.data
.comp_port_connected
.comp
= sink
;
1178 event
.data
.comp_port_connected
.self_port
= sink_def_port
;
1179 event
.data
.comp_port_connected
.other_port
= src_def_port
;
1180 ok(has_event(&event
), "got the expected sink's port connected event");
1181 sink_port_connected_pos
= event_pos(&event
);
1183 /* Graph's port connected */
1184 event
.type
= GRAPH_PORTS_CONNECTED
;
1185 event
.data
.graph_ports_connected
.upstream_comp
= src
;
1186 event
.data
.graph_ports_connected
.downstream_comp
= sink
;
1187 event
.data
.graph_ports_connected
.upstream_port
= src_def_port
;
1188 event
.data
.graph_ports_connected
.downstream_port
= sink_def_port
;
1189 event
.data
.graph_ports_connected
.conn
= conn
;
1190 ok(has_event(&event
), "got the expected graph's ports connected event");
1191 graph_ports_connected_pos
= event_pos(&event
);
1193 /* Order of events */
1194 ok(src_port_connected_pos
< graph_ports_connected_pos
,
1195 "event order is good (1)");
1196 ok(sink_port_connected_pos
< graph_ports_connected_pos
,
1197 "event order is good (2)");
1198 ok(src_accept_port_connection_pos
< src_port_connected_pos
,
1199 "event order is good (3)");
1200 ok(sink_accept_port_connection_pos
< sink_port_connected_pos
,
1201 "event order is good (4)");
1207 bt_put(src_def_port
);
1208 bt_put(sink_def_port
);
1212 void test_empty_graph(void)
1214 struct bt_graph
*graph
;
1216 prepare_test(TEST_EMPTY_GRAPH
, "empty graph");
1217 graph
= create_graph();
1218 ok(events
->len
== 0, "empty graph generates no events");
1222 int main(int argc
, char **argv
)
1224 plan_tests(NR_TESTS
);
1228 test_src_adds_port_in_port_connected();
1229 test_sink_removes_port_in_port_connected();
1230 test_sink_removes_port_in_port_connected_then_src_removes_disconnected_port();
1232 return exit_status();