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/ref.h>
21 #include <babeltrace/graph/component-class.h>
22 #include <babeltrace/graph/component-class-source.h>
23 #include <babeltrace/graph/component-class-sink.h>
24 #include <babeltrace/graph/component.h>
25 #include <babeltrace/graph/component-source.h>
26 #include <babeltrace/graph/component-sink.h>
27 #include <babeltrace/graph/graph.h>
28 #include <babeltrace/graph/connection.h>
29 #include <babeltrace/graph/port.h>
30 #include <babeltrace/graph/private-component.h>
31 #include <babeltrace/graph/private-component-source.h>
32 #include <babeltrace/graph/private-component-sink.h>
33 #include <babeltrace/graph/private-port.h>
34 #include <babeltrace/graph/private-connection.h>
38 #include <babeltrace/assert-internal.h>
46 COMP_ACCEPT_PORT_CONNECTION
,
48 COMP_PORT_DISCONNECTED
,
51 GRAPH_PORTS_CONNECTED
,
52 GRAPH_PORTS_DISCONNECTED
,
58 TEST_SRC_ADDS_PORT_IN_PORT_CONNECTED
,
59 TEST_SINK_REMOVES_PORT_IN_CONSUME
,
60 TEST_SINK_REMOVES_PORT_IN_CONSUME_THEN_SRC_REMOVES_DISCONNECTED_PORT
,
68 struct bt_component
*comp
;
69 struct bt_port
*self_port
;
70 struct bt_port
*other_port
;
71 } comp_accept_port_connection
;
74 struct bt_component
*comp
;
75 struct bt_port
*self_port
;
76 struct bt_port
*other_port
;
77 } comp_port_connected
;
80 struct bt_component
*comp
;
82 } comp_port_disconnected
;
85 struct bt_component
*comp
;
90 struct bt_component
*comp
;
95 struct bt_component
*upstream_comp
;
96 struct bt_component
*downstream_comp
;
97 struct bt_port
*upstream_port
;
98 struct bt_port
*downstream_port
;
99 struct bt_connection
*conn
;
100 } graph_ports_connected
;
103 struct bt_component
*upstream_comp
;
104 struct bt_component
*downstream_comp
;
105 struct bt_port
*upstream_port
;
106 struct bt_port
*downstream_port
;
107 } graph_ports_disconnected
;
111 static GArray
*events
;
112 static struct bt_component_class
*src_comp_class
;
113 static struct bt_component_class
*sink_comp_class
;
114 static enum test current_test
;
117 void clear_events(void)
119 g_array_set_size(events
, 0);
123 void append_event(struct event
*event
)
125 g_array_append_val(events
, *event
);
129 bool compare_events(struct event
*ev_a
, struct event
*ev_b
)
131 if (ev_a
->type
!= ev_b
->type
) {
135 switch (ev_a
->type
) {
136 case COMP_ACCEPT_PORT_CONNECTION
:
137 if (ev_a
->data
.comp_accept_port_connection
.comp
!=
138 ev_b
->data
.comp_accept_port_connection
.comp
) {
142 if (ev_a
->data
.comp_accept_port_connection
.self_port
!=
143 ev_b
->data
.comp_accept_port_connection
.self_port
) {
147 if (ev_a
->data
.comp_accept_port_connection
.other_port
!=
148 ev_b
->data
.comp_accept_port_connection
.other_port
) {
152 case COMP_PORT_CONNECTED
:
153 if (ev_a
->data
.comp_port_connected
.comp
!=
154 ev_b
->data
.comp_port_connected
.comp
) {
158 if (ev_a
->data
.comp_port_connected
.self_port
!=
159 ev_b
->data
.comp_port_connected
.self_port
) {
163 if (ev_a
->data
.comp_port_connected
.other_port
!=
164 ev_b
->data
.comp_port_connected
.other_port
) {
168 case COMP_PORT_DISCONNECTED
:
169 if (ev_a
->data
.comp_port_disconnected
.comp
!=
170 ev_b
->data
.comp_port_disconnected
.comp
) {
174 if (ev_a
->data
.comp_port_disconnected
.port
!=
175 ev_b
->data
.comp_port_disconnected
.port
) {
179 case GRAPH_PORT_ADDED
:
180 if (ev_a
->data
.graph_port_added
.comp
!=
181 ev_b
->data
.graph_port_added
.comp
) {
185 if (ev_a
->data
.graph_port_added
.port
!=
186 ev_b
->data
.graph_port_added
.port
) {
190 case GRAPH_PORT_REMOVED
:
191 if (ev_a
->data
.graph_port_removed
.comp
!=
192 ev_b
->data
.graph_port_removed
.comp
) {
196 if (ev_a
->data
.graph_port_removed
.port
!=
197 ev_b
->data
.graph_port_removed
.port
) {
201 case GRAPH_PORTS_CONNECTED
:
202 if (ev_a
->data
.graph_ports_connected
.upstream_comp
!=
203 ev_b
->data
.graph_ports_connected
.upstream_comp
) {
207 if (ev_a
->data
.graph_ports_connected
.downstream_comp
!=
208 ev_b
->data
.graph_ports_connected
.downstream_comp
) {
212 if (ev_a
->data
.graph_ports_connected
.upstream_port
!=
213 ev_b
->data
.graph_ports_connected
.upstream_port
) {
217 if (ev_a
->data
.graph_ports_connected
.downstream_port
!=
218 ev_b
->data
.graph_ports_connected
.downstream_port
) {
222 if (ev_a
->data
.graph_ports_connected
.conn
!=
223 ev_b
->data
.graph_ports_connected
.conn
) {
227 case GRAPH_PORTS_DISCONNECTED
:
228 if (ev_a
->data
.graph_ports_disconnected
.upstream_comp
!=
229 ev_b
->data
.graph_ports_disconnected
.upstream_comp
) {
233 if (ev_a
->data
.graph_ports_disconnected
.downstream_comp
!=
234 ev_b
->data
.graph_ports_disconnected
.downstream_comp
) {
238 if (ev_a
->data
.graph_ports_disconnected
.upstream_port
!=
239 ev_b
->data
.graph_ports_disconnected
.upstream_port
) {
243 if (ev_a
->data
.graph_ports_disconnected
.downstream_port
!=
244 ev_b
->data
.graph_ports_disconnected
.downstream_port
) {
256 bool has_event(struct event
*event
)
260 for (i
= 0; i
< events
->len
; i
++) {
261 struct event
*ev
= &g_array_index(events
, struct event
, i
);
263 if (compare_events(event
, ev
)) {
272 size_t event_pos(struct event
*event
)
276 for (i
= 0; i
< events
->len
; i
++) {
277 struct event
*ev
= &g_array_index(events
, struct event
, i
);
279 if (compare_events(event
, ev
)) {
288 enum bt_notification_iterator_status
src_iter_next(
289 struct bt_private_connection_private_notification_iterator
*priv_iterator
,
290 bt_notification_array notifs
, uint64_t capacity
,
293 return BT_NOTIFICATION_ITERATOR_STATUS_ERROR
;
297 enum bt_component_status
accept_port_connection(
298 struct bt_private_component
*private_component
,
299 struct bt_private_port
*self_private_port
,
300 struct bt_port
*other_port
)
302 struct event event
= {
303 .type
= COMP_ACCEPT_PORT_CONNECTION
,
304 .data
.comp_accept_port_connection
= {
305 .comp
= bt_component_borrow_from_private(private_component
),
306 .self_port
= bt_port_borrow_from_private(self_private_port
),
307 .other_port
= other_port
,
311 append_event(&event
);
312 return BT_COMPONENT_STATUS_OK
;
316 void src_port_connected(struct bt_private_component
*private_component
,
317 struct bt_private_port
*self_private_port
,
318 struct bt_port
*other_port
)
322 struct event event
= {
323 .type
= COMP_PORT_CONNECTED
,
324 .data
.comp_port_connected
= {
325 .comp
= bt_component_borrow_from_private(private_component
),
326 .self_port
= bt_port_borrow_from_private(self_private_port
),
327 .other_port
= other_port
,
331 append_event(&event
);
333 switch (current_test
) {
334 case TEST_SRC_ADDS_PORT_IN_PORT_CONNECTED
:
335 ret
= bt_private_component_source_add_output_private_port(
336 private_component
, "hello", NULL
, NULL
);
345 void src_port_disconnected(struct bt_private_component
*private_component
,
346 struct bt_private_port
*private_port
)
349 struct event event
= {
350 .type
= COMP_PORT_DISCONNECTED
,
351 .data
.comp_port_disconnected
= {
352 .comp
= bt_component_borrow_from_private(private_component
),
353 .port
= bt_port_borrow_from_private(private_port
),
357 append_event(&event
);
359 switch (current_test
) {
360 case TEST_SINK_REMOVES_PORT_IN_CONSUME_THEN_SRC_REMOVES_DISCONNECTED_PORT
:
361 ret
= bt_private_port_remove_from_component(private_port
);
369 enum bt_component_status
src_init(struct bt_private_component
*priv_comp
,
370 struct bt_value
*params
, void *init_method_data
)
374 ret
= bt_private_component_source_add_output_private_port(
375 priv_comp
, "out", NULL
, NULL
);
377 return BT_COMPONENT_STATUS_OK
;
381 enum bt_component_status
sink_consume(
382 struct bt_private_component
*priv_component
)
384 struct bt_private_port
*def_port
;
387 switch (current_test
) {
388 case TEST_SINK_REMOVES_PORT_IN_CONSUME
:
389 case TEST_SINK_REMOVES_PORT_IN_CONSUME_THEN_SRC_REMOVES_DISCONNECTED_PORT
:
390 def_port
= bt_private_component_sink_get_input_private_port_by_name(
391 priv_component
, "in");
393 ret
= bt_private_port_remove_from_component(def_port
);
401 return BT_COMPONENT_STATUS_OK
;
405 void sink_port_connected(struct bt_private_component
*private_component
,
406 struct bt_private_port
*self_private_port
,
407 struct bt_port
*other_port
)
409 struct event event
= {
410 .type
= COMP_PORT_CONNECTED
,
411 .data
.comp_port_connected
= {
412 .comp
= bt_component_borrow_from_private(private_component
),
413 .self_port
= bt_port_borrow_from_private(self_private_port
),
414 .other_port
= other_port
,
418 append_event(&event
);
422 void sink_port_disconnected(struct bt_private_component
*private_component
,
423 struct bt_private_port
*private_port
)
425 struct event event
= {
426 .type
= COMP_PORT_DISCONNECTED
,
427 .data
.comp_port_disconnected
= {
428 .comp
= bt_component_borrow_from_private(private_component
),
429 .port
= bt_port_borrow_from_private(private_port
),
433 append_event(&event
);
437 enum bt_component_status
sink_init(struct bt_private_component
*priv_comp
,
438 struct bt_value
*params
, void *init_method_data
)
442 ret
= bt_private_component_sink_add_input_private_port(priv_comp
,
445 return BT_COMPONENT_STATUS_OK
;
449 void graph_port_added(struct bt_port
*port
,
452 struct bt_component
*comp
= bt_port_get_component(port
);
457 struct event event
= {
458 .type
= GRAPH_PORT_ADDED
,
459 .data
.graph_port_added
= {
465 append_event(&event
);
469 void graph_port_removed(struct bt_component
*component
,
470 struct bt_port
*port
, void *data
)
472 struct event event
= {
473 .type
= GRAPH_PORT_REMOVED
,
474 .data
.graph_port_removed
= {
480 append_event(&event
);
484 void graph_ports_connected(struct bt_port
*upstream_port
,
485 struct bt_port
*downstream_port
, void *data
)
487 struct bt_component
*upstream_comp
=
488 bt_port_get_component(upstream_port
);
489 struct bt_component
*downstream_comp
=
490 bt_port_get_component(downstream_port
);
491 struct bt_connection
*conn
= bt_port_get_connection(upstream_port
);
493 BT_ASSERT(upstream_comp
);
494 BT_ASSERT(downstream_comp
);
496 bt_put(upstream_comp
);
497 bt_put(downstream_comp
);
500 struct event event
= {
501 .type
= GRAPH_PORTS_CONNECTED
,
502 .data
.graph_ports_connected
= {
503 .upstream_comp
= upstream_comp
,
504 .downstream_comp
= downstream_comp
,
505 .upstream_port
= upstream_port
,
506 .downstream_port
= downstream_port
,
511 append_event(&event
);
515 void graph_ports_disconnected(
516 struct bt_component
*upstream_comp
,
517 struct bt_component
*downstream_comp
,
518 struct bt_port
*upstream_port
, struct bt_port
*downstream_port
,
521 struct event event
= {
522 .type
= GRAPH_PORTS_DISCONNECTED
,
523 .data
.graph_ports_disconnected
= {
524 .upstream_comp
= upstream_comp
,
525 .downstream_comp
= downstream_comp
,
526 .upstream_port
= upstream_port
,
527 .downstream_port
= downstream_port
,
531 append_event(&event
);
539 src_comp_class
= bt_component_class_source_create("src", src_iter_next
);
540 BT_ASSERT(src_comp_class
);
541 ret
= bt_component_class_set_init_method(src_comp_class
, src_init
);
543 ret
= bt_component_class_set_accept_port_connection_method(
544 src_comp_class
, accept_port_connection
);
546 ret
= bt_component_class_set_port_connected_method(src_comp_class
,
549 ret
= bt_component_class_set_port_disconnected_method(
550 src_comp_class
, src_port_disconnected
);
552 sink_comp_class
= bt_component_class_sink_create("sink", sink_consume
);
553 BT_ASSERT(sink_comp_class
);
554 ret
= bt_component_class_set_init_method(sink_comp_class
, sink_init
);
556 ret
= bt_component_class_set_accept_port_connection_method(
557 sink_comp_class
, accept_port_connection
);
559 ret
= bt_component_class_set_port_connected_method(sink_comp_class
,
560 sink_port_connected
);
562 ret
= bt_component_class_set_port_disconnected_method(sink_comp_class
,
563 sink_port_disconnected
);
565 bt_component_class_freeze(src_comp_class
);
566 bt_component_class_freeze(sink_comp_class
);
567 events
= g_array_new(FALSE
, TRUE
, sizeof(struct event
));
574 bt_put(src_comp_class
);
575 bt_put(sink_comp_class
);
576 g_array_free(events
, TRUE
);
580 struct bt_component
*create_src(struct bt_graph
*graph
)
582 struct bt_component
*comp
;
585 ret
= bt_graph_add_component(graph
, src_comp_class
, "src-comp", NULL
,
592 struct bt_component
*create_sink(struct bt_graph
*graph
)
594 struct bt_component
*comp
;
597 ret
= bt_graph_add_component(graph
, sink_comp_class
, "sink-comp",
604 struct bt_graph
*create_graph(void)
606 struct bt_graph
*graph
= bt_graph_create();
610 ret
= bt_graph_add_port_added_listener(graph
, graph_port_added
, NULL
,
613 ret
= bt_graph_add_port_removed_listener(graph
, graph_port_removed
,
616 ret
= bt_graph_add_ports_connected_listener(graph
,
617 graph_ports_connected
, NULL
, NULL
);
619 ret
= bt_graph_add_ports_disconnected_listener(graph
,
620 graph_ports_disconnected
, NULL
, NULL
);
626 void prepare_test(enum test test
, const char *name
)
630 diag("test: %s", name
);
634 void test_sink_removes_port_in_port_connected_then_src_removes_disconnected_port(void)
637 struct bt_component
*src
;
638 struct bt_component
*sink
;
639 struct bt_graph
*graph
;
640 struct bt_port
*src_def_port
;
641 struct bt_port
*sink_def_port
;
642 struct bt_connection
*conn
;
644 enum bt_graph_status status
;
645 size_t src_accept_port_connection_pos
;
646 size_t sink_accept_port_connection_pos
;
647 size_t src_port_connected_pos
;
648 size_t sink_port_connected_pos
;
649 size_t graph_ports_connected
;
650 size_t src_port_disconnected_pos
;
651 size_t sink_port_disconnected_pos
;
652 size_t graph_ports_disconnected_pos
;
653 size_t graph_port_removed_src_pos
;
654 size_t graph_port_removed_sink_pos
;
656 prepare_test(TEST_SINK_REMOVES_PORT_IN_CONSUME_THEN_SRC_REMOVES_DISCONNECTED_PORT
,
657 "sink removes port in consume, then source removes disconnected port");
658 graph
= create_graph();
660 src
= create_src(graph
);
661 sink
= create_sink(graph
);
662 src_def_port
= bt_component_source_get_output_port_by_name(src
, "out");
663 BT_ASSERT(src_def_port
);
664 sink_def_port
= bt_component_sink_get_input_port_by_name(sink
, "in");
665 BT_ASSERT(sink_def_port
);
666 status
= bt_graph_connect_ports(graph
, src_def_port
, sink_def_port
,
668 BT_ASSERT(status
== 0);
671 /* We're supposed to have 7 events so far */
672 ok(events
->len
== 7, "we have the expected number of events (before consume)");
674 /* Source's port added */
675 event
.type
= GRAPH_PORT_ADDED
;
676 event
.data
.graph_port_added
.comp
= src
;
677 event
.data
.graph_port_added
.port
= src_def_port
;
678 ok(has_event(&event
), "got the expected graph's port added event (for source, initial)");
680 /* Sink's port added */
681 event
.type
= GRAPH_PORT_ADDED
;
682 event
.data
.graph_port_added
.comp
= sink
;
683 event
.data
.graph_port_added
.port
= sink_def_port
;
684 ok(has_event(&event
), "got the expected graph's port added event (for sink, initial)");
686 /* Source's accept port connection */
687 event
.type
= COMP_ACCEPT_PORT_CONNECTION
;
688 event
.data
.comp_accept_port_connection
.comp
= src
;
689 event
.data
.comp_accept_port_connection
.self_port
= src_def_port
;
690 event
.data
.comp_accept_port_connection
.other_port
= sink_def_port
;
691 ok(has_event(&event
), "got the expected source's accept port connection event");
692 src_accept_port_connection_pos
= event_pos(&event
);
694 /* Sink's accept port connection */
695 event
.type
= COMP_ACCEPT_PORT_CONNECTION
;
696 event
.data
.comp_accept_port_connection
.comp
= sink
;
697 event
.data
.comp_accept_port_connection
.self_port
= sink_def_port
;
698 event
.data
.comp_accept_port_connection
.other_port
= src_def_port
;
699 ok(has_event(&event
), "got the expected sink's accept port connection event");
700 sink_accept_port_connection_pos
= event_pos(&event
);
702 /* Source's port connected */
703 event
.type
= COMP_PORT_CONNECTED
;
704 event
.data
.comp_port_connected
.comp
= src
;
705 event
.data
.comp_port_connected
.self_port
= src_def_port
;
706 event
.data
.comp_port_connected
.other_port
= sink_def_port
;
707 ok(has_event(&event
), "got the expected source's port connected event");
708 src_port_connected_pos
= event_pos(&event
);
710 /* Sink's port connected */
711 event
.type
= COMP_PORT_CONNECTED
;
712 event
.data
.comp_port_connected
.comp
= sink
;
713 event
.data
.comp_port_connected
.self_port
= sink_def_port
;
714 event
.data
.comp_port_connected
.other_port
= src_def_port
;
715 ok(has_event(&event
), "got the expected sink's port connected event");
716 sink_port_connected_pos
= event_pos(&event
);
718 /* Graph's ports connected */
719 event
.type
= GRAPH_PORTS_CONNECTED
;
720 event
.data
.graph_ports_connected
.upstream_comp
= src
;
721 event
.data
.graph_ports_connected
.downstream_comp
= sink
;
722 event
.data
.graph_ports_connected
.upstream_port
= src_def_port
;
723 event
.data
.graph_ports_connected
.downstream_port
= sink_def_port
;
724 event
.data
.graph_ports_connected
.conn
= conn
;
725 ok(has_event(&event
), "got the expected graph's ports connected event");
726 graph_ports_connected
= event_pos(&event
);
728 /* Order of events */
729 ok(src_port_connected_pos
< graph_ports_connected
,
730 "event order is good (1)");
731 ok(sink_port_connected_pos
< graph_ports_connected
,
732 "event order is good (2)");
733 ok(src_accept_port_connection_pos
< src_port_connected_pos
,
734 "event order is good (3)");
735 ok(sink_accept_port_connection_pos
< sink_port_connected_pos
,
736 "event order is good (4)");
738 /* Consume sink once */
740 ret
= bt_graph_consume(graph
);
743 /* We're supposed to have 5 new events */
744 ok(events
->len
== 5, "we have the expected number of events (after consume)");
746 /* Source's port disconnected */
747 event
.type
= COMP_PORT_DISCONNECTED
;
748 event
.data
.comp_port_disconnected
.comp
= src
;
749 event
.data
.comp_port_disconnected
.port
= src_def_port
;
750 ok(has_event(&event
), "got the expected source's port disconnected event");
751 src_port_disconnected_pos
= event_pos(&event
);
753 /* Sink's port disconnected */
754 event
.type
= COMP_PORT_DISCONNECTED
;
755 event
.data
.comp_port_disconnected
.comp
= sink
;
756 event
.data
.comp_port_disconnected
.port
= sink_def_port
;
757 ok(has_event(&event
), "got the expected sink's port disconnected event");
758 sink_port_disconnected_pos
= event_pos(&event
);
760 /* Graph's ports disconnected */
761 event
.type
= GRAPH_PORTS_DISCONNECTED
;
762 event
.data
.graph_ports_disconnected
.upstream_comp
= src
;
763 event
.data
.graph_ports_disconnected
.downstream_comp
= sink
;
764 event
.data
.graph_ports_disconnected
.upstream_port
= src_def_port
;
765 event
.data
.graph_ports_disconnected
.downstream_port
= sink_def_port
;
766 ok(has_event(&event
), "got the expected graph's ports disconnected event");
767 graph_ports_disconnected_pos
= event_pos(&event
);
769 /* Graph's port removed (sink) */
770 event
.type
= GRAPH_PORT_REMOVED
;
771 event
.data
.graph_port_removed
.comp
= sink
;
772 event
.data
.graph_port_removed
.port
= sink_def_port
;
773 ok(has_event(&event
), "got the expected graph's port removed event (for sink)");
774 graph_port_removed_sink_pos
= event_pos(&event
);
776 /* Graph's port removed (source) */
777 event
.type
= GRAPH_PORT_REMOVED
;
778 event
.data
.graph_port_removed
.comp
= src
;
779 event
.data
.graph_port_removed
.port
= src_def_port
;
780 ok(has_event(&event
), "got the expected graph's port removed event (for source)");
781 graph_port_removed_src_pos
= event_pos(&event
);
783 /* Order of events */
784 ok(src_port_disconnected_pos
< graph_ports_disconnected_pos
,
785 "event order is good (5)");
786 ok(src_port_disconnected_pos
< graph_port_removed_sink_pos
,
787 "event order is good (6)");
788 ok(src_port_disconnected_pos
< graph_port_removed_src_pos
,
789 "event order is good (7)");
790 ok(sink_port_disconnected_pos
< graph_ports_disconnected_pos
,
791 "event order is good (8)");
792 ok(sink_port_disconnected_pos
< graph_port_removed_sink_pos
,
793 "event order is good (9)");
794 ok(sink_port_disconnected_pos
< graph_port_removed_src_pos
,
795 "event order is good (10)");
796 ok(graph_ports_disconnected_pos
< graph_port_removed_sink_pos
,
797 "event order is good (11)");
798 ok(graph_port_removed_src_pos
< graph_ports_disconnected_pos
,
799 "event order is good (12)");
800 ok(graph_port_removed_src_pos
< graph_port_removed_sink_pos
,
801 "event order is good (13)");
807 bt_put(src_def_port
);
808 bt_put(sink_def_port
);
812 void test_sink_removes_port_in_port_connected(void)
815 struct bt_component
*src
;
816 struct bt_component
*sink
;
817 struct bt_graph
*graph
;
818 struct bt_port
*src_def_port
;
819 struct bt_port
*sink_def_port
;
820 struct bt_connection
*conn
;
822 enum bt_graph_status status
;
823 size_t src_accept_port_connection_pos
;
824 size_t sink_accept_port_connection_pos
;
825 size_t src_port_connected_pos
;
826 size_t sink_port_connected_pos
;
827 size_t graph_ports_connected_pos
;
828 size_t src_port_disconnected_pos
;
829 size_t sink_port_disconnected_pos
;
830 size_t graph_ports_disconnected_pos
;
831 size_t graph_port_removed_sink_pos
;
833 prepare_test(TEST_SINK_REMOVES_PORT_IN_CONSUME
,
834 "sink removes port in consume");
835 graph
= create_graph();
837 src
= create_src(graph
);
838 sink
= create_sink(graph
);
839 src_def_port
= bt_component_source_get_output_port_by_name(src
, "out");
840 BT_ASSERT(src_def_port
);
841 sink_def_port
= bt_component_sink_get_input_port_by_name(sink
, "in");
842 BT_ASSERT(sink_def_port
);
843 status
= bt_graph_connect_ports(graph
, src_def_port
, sink_def_port
,
845 BT_ASSERT(status
== 0);
847 /* We're supposed to have 7 events so far */
848 ok(events
->len
== 7, "we have the expected number of events (before consume)");
850 /* Source's port added */
851 event
.type
= GRAPH_PORT_ADDED
;
852 event
.data
.graph_port_added
.comp
= src
;
853 event
.data
.graph_port_added
.port
= src_def_port
;
854 ok(has_event(&event
), "got the expected graph's port added event (for source, initial)");
856 /* Sink's port added */
857 event
.type
= GRAPH_PORT_ADDED
;
858 event
.data
.graph_port_added
.comp
= sink
;
859 event
.data
.graph_port_added
.port
= sink_def_port
;
860 ok(has_event(&event
), "got the expected graph's port added event (for sink, initial)");
862 /* Source's accept port connection */
863 event
.type
= COMP_ACCEPT_PORT_CONNECTION
;
864 event
.data
.comp_accept_port_connection
.comp
= src
;
865 event
.data
.comp_accept_port_connection
.self_port
= src_def_port
;
866 event
.data
.comp_accept_port_connection
.other_port
= sink_def_port
;
867 ok(has_event(&event
), "got the expected source's accept port connection event");
868 src_accept_port_connection_pos
= event_pos(&event
);
870 /* Sink's accept port connection */
871 event
.type
= COMP_ACCEPT_PORT_CONNECTION
;
872 event
.data
.comp_accept_port_connection
.comp
= sink
;
873 event
.data
.comp_accept_port_connection
.self_port
= sink_def_port
;
874 event
.data
.comp_accept_port_connection
.other_port
= src_def_port
;
875 ok(has_event(&event
), "got the expected sink's accept port connection event");
876 sink_accept_port_connection_pos
= event_pos(&event
);
878 /* Source's port connected */
879 event
.type
= COMP_PORT_CONNECTED
;
880 event
.data
.comp_port_connected
.comp
= src
;
881 event
.data
.comp_port_connected
.self_port
= src_def_port
;
882 event
.data
.comp_port_connected
.other_port
= sink_def_port
;
883 ok(has_event(&event
), "got the expected source's port connected event");
884 src_port_connected_pos
= event_pos(&event
);
886 /* Sink's port connected */
887 event
.type
= COMP_PORT_CONNECTED
;
888 event
.data
.comp_port_connected
.comp
= sink
;
889 event
.data
.comp_port_connected
.self_port
= sink_def_port
;
890 event
.data
.comp_port_connected
.other_port
= src_def_port
;
891 ok(has_event(&event
), "got the expected sink's port connected event");
892 sink_port_connected_pos
= event_pos(&event
);
894 /* Graph's ports connected */
895 event
.type
= GRAPH_PORTS_CONNECTED
;
896 event
.data
.graph_ports_connected
.upstream_comp
= src
;
897 event
.data
.graph_ports_connected
.downstream_comp
= sink
;
898 event
.data
.graph_ports_connected
.upstream_port
= src_def_port
;
899 event
.data
.graph_ports_connected
.downstream_port
= sink_def_port
;
900 event
.data
.graph_ports_connected
.conn
= conn
;
901 ok(has_event(&event
), "got the expected graph's ports connected event");
902 graph_ports_connected_pos
= event_pos(&event
);
904 /* Order of events */
905 ok(src_port_connected_pos
< graph_ports_connected_pos
,
906 "event order is good (1)");
907 ok(sink_port_connected_pos
< graph_ports_connected_pos
,
908 "event order is good (2)");
909 ok(src_accept_port_connection_pos
< src_port_connected_pos
,
910 "event order is good (3)");
911 ok(sink_accept_port_connection_pos
< sink_port_connected_pos
,
912 "event order is good (4)");
914 /* Consume sink once */
916 ret
= bt_graph_consume(graph
);
919 /* We're supposed to have 4 new events */
920 ok(events
->len
== 4, "we have the expected number of events (after consume)");
922 /* Source's port disconnected */
923 event
.type
= COMP_PORT_DISCONNECTED
;
924 event
.data
.comp_port_disconnected
.comp
= src
;
925 event
.data
.comp_port_disconnected
.port
= src_def_port
;
926 ok(has_event(&event
), "got the expected source's port disconnected event");
927 src_port_disconnected_pos
= event_pos(&event
);
929 /* Sink's port disconnected */
930 event
.type
= COMP_PORT_DISCONNECTED
;
931 event
.data
.comp_port_disconnected
.comp
= sink
;
932 event
.data
.comp_port_disconnected
.port
= sink_def_port
;
933 ok(has_event(&event
), "got the expected sink's port disconnected event");
934 sink_port_disconnected_pos
= event_pos(&event
);
936 /* Graph's ports disconnected */
937 event
.type
= GRAPH_PORTS_DISCONNECTED
;
938 event
.data
.graph_ports_disconnected
.upstream_comp
= src
;
939 event
.data
.graph_ports_disconnected
.downstream_comp
= sink
;
940 event
.data
.graph_ports_disconnected
.upstream_port
= src_def_port
;
941 event
.data
.graph_ports_disconnected
.downstream_port
= sink_def_port
;
942 ok(has_event(&event
), "got the expected graph's ports disconnected event");
943 graph_ports_disconnected_pos
= event_pos(&event
);
945 /* Graph's port removed (sink) */
946 event
.type
= GRAPH_PORT_REMOVED
;
947 event
.data
.graph_port_removed
.comp
= sink
;
948 event
.data
.graph_port_removed
.port
= sink_def_port
;
949 ok(has_event(&event
), "got the expected graph's port removed event (for sink)");
950 graph_port_removed_sink_pos
= event_pos(&event
);
952 /* Order of events */
953 ok(src_port_disconnected_pos
< graph_ports_disconnected_pos
,
954 "event order is good (5)");
955 ok(src_port_disconnected_pos
< graph_port_removed_sink_pos
,
956 "event order is good (7)");
957 ok(sink_port_disconnected_pos
< graph_ports_disconnected_pos
,
958 "event order is good (8)");
959 ok(sink_port_disconnected_pos
< graph_port_removed_sink_pos
,
960 "event order is good (10)");
961 ok(graph_ports_disconnected_pos
< graph_port_removed_sink_pos
,
962 "event order is good (11)");
968 bt_put(src_def_port
);
969 bt_put(sink_def_port
);
973 void test_src_adds_port_in_port_connected(void)
975 struct bt_component
*src
;
976 struct bt_component
*sink
;
977 struct bt_graph
*graph
;
978 struct bt_port
*src_def_port
;
979 struct bt_port
*sink_def_port
;
980 struct bt_port
*src_hello_port
;
981 struct bt_connection
*conn
;
983 enum bt_graph_status status
;
984 size_t src_accept_port_connection_pos
;
985 size_t sink_accept_port_connection_pos
;
986 size_t src_port_connected_pos
;
987 size_t sink_port_connected_pos
;
988 size_t graph_ports_connected_pos
;
989 size_t graph_port_added_src_pos
;
991 prepare_test(TEST_SRC_ADDS_PORT_IN_PORT_CONNECTED
,
992 "source adds port in port connected");
993 graph
= create_graph();
995 src
= create_src(graph
);
996 sink
= create_sink(graph
);
997 src_def_port
= bt_component_source_get_output_port_by_name(src
, "out");
998 BT_ASSERT(src_def_port
);
999 sink_def_port
= bt_component_sink_get_input_port_by_name(sink
, "in");
1000 BT_ASSERT(sink_def_port
);
1001 status
= bt_graph_connect_ports(graph
, src_def_port
, sink_def_port
,
1003 BT_ASSERT(status
== 0);
1004 src_hello_port
= bt_component_source_get_output_port_by_name(src
,
1006 BT_ASSERT(src_hello_port
);
1008 /* We're supposed to have 8 events */
1009 ok(events
->len
== 8, "we have the expected number of events");
1011 /* Source's port added */
1012 event
.type
= GRAPH_PORT_ADDED
;
1013 event
.data
.graph_port_added
.comp
= src
;
1014 event
.data
.graph_port_added
.port
= src_def_port
;
1015 ok(has_event(&event
), "got the expected graph's port added event (for source, initial)");
1017 /* Sink's port added */
1018 event
.type
= GRAPH_PORT_ADDED
;
1019 event
.data
.graph_port_added
.comp
= sink
;
1020 event
.data
.graph_port_added
.port
= sink_def_port
;
1021 ok(has_event(&event
), "got the expected graph's port added event (for sink, initial)");
1023 /* Source's accept port connection */
1024 event
.type
= COMP_ACCEPT_PORT_CONNECTION
;
1025 event
.data
.comp_accept_port_connection
.comp
= src
;
1026 event
.data
.comp_accept_port_connection
.self_port
= src_def_port
;
1027 event
.data
.comp_accept_port_connection
.other_port
= sink_def_port
;
1028 ok(has_event(&event
), "got the expected source's accept port connection event");
1029 src_accept_port_connection_pos
= event_pos(&event
);
1031 /* Sink's accept port connection */
1032 event
.type
= COMP_ACCEPT_PORT_CONNECTION
;
1033 event
.data
.comp_accept_port_connection
.comp
= sink
;
1034 event
.data
.comp_accept_port_connection
.self_port
= sink_def_port
;
1035 event
.data
.comp_accept_port_connection
.other_port
= src_def_port
;
1036 ok(has_event(&event
), "got the expected sink's accept port connection event");
1037 sink_accept_port_connection_pos
= event_pos(&event
);
1039 /* Source's port connected */
1040 event
.type
= COMP_PORT_CONNECTED
;
1041 event
.data
.comp_port_connected
.comp
= src
;
1042 event
.data
.comp_port_connected
.self_port
= src_def_port
;
1043 event
.data
.comp_port_connected
.other_port
= sink_def_port
;
1044 ok(has_event(&event
), "got the expected source's port connected event");
1045 src_port_connected_pos
= event_pos(&event
);
1047 /* Graph's port added (source) */
1048 event
.type
= GRAPH_PORT_ADDED
;
1049 event
.data
.graph_port_added
.comp
= src
;
1050 event
.data
.graph_port_added
.port
= src_hello_port
;
1051 ok(has_event(&event
), "got the expected graph's port added event (for source)");
1052 graph_port_added_src_pos
= event_pos(&event
);
1054 /* Sink's port connected */
1055 event
.type
= COMP_PORT_CONNECTED
;
1056 event
.data
.comp_port_connected
.comp
= sink
;
1057 event
.data
.comp_port_connected
.self_port
= sink_def_port
;
1058 event
.data
.comp_port_connected
.other_port
= src_def_port
;
1059 ok(has_event(&event
), "got the expected sink's port connected event");
1060 sink_port_connected_pos
= event_pos(&event
);
1062 /* Graph's ports connected */
1063 event
.type
= GRAPH_PORTS_CONNECTED
;
1064 event
.data
.graph_ports_connected
.upstream_comp
= src
;
1065 event
.data
.graph_ports_connected
.downstream_comp
= sink
;
1066 event
.data
.graph_ports_connected
.upstream_port
= src_def_port
;
1067 event
.data
.graph_ports_connected
.downstream_port
= sink_def_port
;
1068 event
.data
.graph_ports_connected
.conn
= conn
;
1069 ok(has_event(&event
), "got the expected graph's port connected event (for source)");
1070 graph_ports_connected_pos
= event_pos(&event
);
1072 /* Order of events */
1073 ok(src_port_connected_pos
< graph_ports_connected_pos
,
1074 "event order is good (1)");
1075 ok(sink_port_connected_pos
< graph_ports_connected_pos
,
1076 "event order is good (2)");
1077 ok(src_accept_port_connection_pos
< src_port_connected_pos
,
1078 "event order is good (3)");
1079 ok(sink_accept_port_connection_pos
< sink_port_connected_pos
,
1080 "event order is good (4)");
1081 ok(src_port_connected_pos
< graph_port_added_src_pos
,
1082 "event order is good (5)");
1083 ok(graph_port_added_src_pos
< graph_ports_connected_pos
,
1084 "event order is good (6)");
1090 bt_put(src_def_port
);
1091 bt_put(sink_def_port
);
1092 bt_put(src_hello_port
);
1096 void test_simple(void)
1098 struct bt_component
*src
;
1099 struct bt_component
*sink
;
1100 struct bt_graph
*graph
;
1101 struct bt_port
*src_def_port
;
1102 struct bt_port
*sink_def_port
;
1103 struct bt_connection
*conn
;
1105 enum bt_graph_status status
;
1106 size_t src_accept_port_connection_pos
;
1107 size_t sink_accept_port_connection_pos
;
1108 size_t src_port_connected_pos
;
1109 size_t sink_port_connected_pos
;
1110 size_t graph_ports_connected_pos
;
1112 prepare_test(TEST_SIMPLE
, "simple");
1113 graph
= create_graph();
1115 src
= create_src(graph
);
1116 sink
= create_sink(graph
);
1117 src_def_port
= bt_component_source_get_output_port_by_name(src
, "out");
1118 BT_ASSERT(src_def_port
);
1119 sink_def_port
= bt_component_sink_get_input_port_by_name(sink
, "in");
1120 BT_ASSERT(sink_def_port
);
1121 status
= bt_graph_connect_ports(graph
, src_def_port
, sink_def_port
,
1123 BT_ASSERT(status
== 0);
1125 /* We're supposed to have 7 events */
1126 ok(events
->len
== 7, "we have the expected number of events");
1128 /* Source's port added */
1129 event
.type
= GRAPH_PORT_ADDED
;
1130 event
.data
.graph_port_added
.comp
= src
;
1131 event
.data
.graph_port_added
.port
= src_def_port
;
1132 ok(has_event(&event
), "got the expected graph's port added event (for source, initial)");
1134 /* Sink's port added */
1135 event
.type
= GRAPH_PORT_ADDED
;
1136 event
.data
.graph_port_added
.comp
= sink
;
1137 event
.data
.graph_port_added
.port
= sink_def_port
;
1138 ok(has_event(&event
), "got the expected graph's port added event (for sink, initial)");
1140 /* Source's accept port connection */
1141 event
.type
= COMP_ACCEPT_PORT_CONNECTION
;
1142 event
.data
.comp_accept_port_connection
.comp
= src
;
1143 event
.data
.comp_accept_port_connection
.self_port
= src_def_port
;
1144 event
.data
.comp_accept_port_connection
.other_port
= sink_def_port
;
1145 ok(has_event(&event
), "got the expected source's accept port connection event");
1146 src_accept_port_connection_pos
= event_pos(&event
);
1148 /* Sink's accept port connection */
1149 event
.type
= COMP_ACCEPT_PORT_CONNECTION
;
1150 event
.data
.comp_accept_port_connection
.comp
= sink
;
1151 event
.data
.comp_accept_port_connection
.self_port
= sink_def_port
;
1152 event
.data
.comp_accept_port_connection
.other_port
= src_def_port
;
1153 ok(has_event(&event
), "got the expected sink's accept port connection event");
1154 sink_accept_port_connection_pos
= event_pos(&event
);
1156 /* Source's port connected */
1157 event
.type
= COMP_PORT_CONNECTED
;
1158 event
.data
.comp_port_connected
.comp
= src
;
1159 event
.data
.comp_port_connected
.self_port
= src_def_port
;
1160 event
.data
.comp_port_connected
.other_port
= sink_def_port
;
1161 ok(has_event(&event
), "got the expected source's port connected event");
1162 src_port_connected_pos
= event_pos(&event
);
1164 /* Sink's port connected */
1165 event
.type
= COMP_PORT_CONNECTED
;
1166 event
.data
.comp_port_connected
.comp
= sink
;
1167 event
.data
.comp_port_connected
.self_port
= sink_def_port
;
1168 event
.data
.comp_port_connected
.other_port
= src_def_port
;
1169 ok(has_event(&event
), "got the expected sink's port connected event");
1170 sink_port_connected_pos
= event_pos(&event
);
1172 /* Graph's port connected */
1173 event
.type
= GRAPH_PORTS_CONNECTED
;
1174 event
.data
.graph_ports_connected
.upstream_comp
= src
;
1175 event
.data
.graph_ports_connected
.downstream_comp
= sink
;
1176 event
.data
.graph_ports_connected
.upstream_port
= src_def_port
;
1177 event
.data
.graph_ports_connected
.downstream_port
= sink_def_port
;
1178 event
.data
.graph_ports_connected
.conn
= conn
;
1179 ok(has_event(&event
), "got the expected graph's ports connected event");
1180 graph_ports_connected_pos
= event_pos(&event
);
1182 /* Order of events */
1183 ok(src_port_connected_pos
< graph_ports_connected_pos
,
1184 "event order is good (1)");
1185 ok(sink_port_connected_pos
< graph_ports_connected_pos
,
1186 "event order is good (2)");
1187 ok(src_accept_port_connection_pos
< src_port_connected_pos
,
1188 "event order is good (3)");
1189 ok(sink_accept_port_connection_pos
< sink_port_connected_pos
,
1190 "event order is good (4)");
1196 bt_put(src_def_port
);
1197 bt_put(sink_def_port
);
1201 void test_empty_graph(void)
1203 struct bt_graph
*graph
;
1205 prepare_test(TEST_EMPTY_GRAPH
, "empty graph");
1206 graph
= create_graph();
1207 ok(events
->len
== 0, "empty graph generates no events");
1211 int main(int argc
, char **argv
)
1213 plan_tests(NR_TESTS
);
1217 test_src_adds_port_in_port_connected();
1218 test_sink_removes_port_in_port_connected();
1219 test_sink_removes_port_in_port_connected_then_src_removes_disconnected_port();
1221 return exit_status();