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>
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 struct bt_notification_iterator_next_method_return
src_iter_next(
289 struct bt_private_connection_private_notification_iterator
*priv_iterator
)
291 struct bt_notification_iterator_next_method_return ret
= {
292 .status
= BT_NOTIFICATION_ITERATOR_STATUS_ERROR
,
299 enum bt_component_status
accept_port_connection(
300 struct bt_private_component
*private_component
,
301 struct bt_private_port
*self_private_port
,
302 struct bt_port
*other_port
)
304 struct event event
= {
305 .type
= COMP_ACCEPT_PORT_CONNECTION
,
306 .data
.comp_accept_port_connection
= {
307 .comp
= bt_component_from_private(private_component
),
308 .self_port
= bt_port_from_private(self_private_port
),
309 .other_port
= other_port
,
313 bt_put(event
.data
.comp_accept_port_connection
.comp
);
314 bt_put(event
.data
.comp_accept_port_connection
.self_port
);
315 append_event(&event
);
316 return BT_COMPONENT_STATUS_OK
;
320 void src_port_connected(struct bt_private_component
*private_component
,
321 struct bt_private_port
*self_private_port
,
322 struct bt_port
*other_port
)
326 struct event event
= {
327 .type
= COMP_PORT_CONNECTED
,
328 .data
.comp_port_connected
= {
329 .comp
= bt_component_from_private(private_component
),
330 .self_port
= bt_port_from_private(self_private_port
),
331 .other_port
= other_port
,
335 bt_put(event
.data
.comp_port_connected
.comp
);
336 bt_put(event
.data
.comp_port_connected
.self_port
);
337 append_event(&event
);
339 switch (current_test
) {
340 case TEST_SRC_ADDS_PORT_IN_PORT_CONNECTED
:
341 ret
= bt_private_component_source_add_output_private_port(
342 private_component
, "hello", NULL
, NULL
);
351 void src_port_disconnected(struct bt_private_component
*private_component
,
352 struct bt_private_port
*private_port
)
355 struct event event
= {
356 .type
= COMP_PORT_DISCONNECTED
,
357 .data
.comp_port_disconnected
= {
358 .comp
= bt_component_from_private(private_component
),
359 .port
= bt_port_from_private(private_port
),
363 bt_put(event
.data
.comp_port_disconnected
.comp
);
364 bt_put(event
.data
.comp_port_disconnected
.port
);
365 append_event(&event
);
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
);
377 enum bt_component_status
src_init(struct bt_private_component
*priv_comp
,
378 struct bt_value
*params
, void *init_method_data
)
382 ret
= bt_private_component_source_add_output_private_port(
383 priv_comp
, "out", NULL
, NULL
);
385 return BT_COMPONENT_STATUS_OK
;
389 enum bt_component_status
sink_consume(
390 struct bt_private_component
*priv_component
)
392 struct bt_private_port
*def_port
;
395 switch (current_test
) {
396 case TEST_SINK_REMOVES_PORT_IN_CONSUME
:
397 case TEST_SINK_REMOVES_PORT_IN_CONSUME_THEN_SRC_REMOVES_DISCONNECTED_PORT
:
398 def_port
= bt_private_component_sink_get_input_private_port_by_name(
399 priv_component
, "in");
401 ret
= bt_private_port_remove_from_component(def_port
);
409 return BT_COMPONENT_STATUS_OK
;
413 void sink_port_connected(struct bt_private_component
*private_component
,
414 struct bt_private_port
*self_private_port
,
415 struct bt_port
*other_port
)
417 struct event event
= {
418 .type
= COMP_PORT_CONNECTED
,
419 .data
.comp_port_connected
= {
420 .comp
= bt_component_from_private(private_component
),
421 .self_port
= bt_port_from_private(self_private_port
),
422 .other_port
= other_port
,
426 bt_put(event
.data
.comp_port_connected
.comp
);
427 bt_put(event
.data
.comp_port_connected
.self_port
);
428 append_event(&event
);
432 void sink_port_disconnected(struct bt_private_component
*private_component
,
433 struct bt_private_port
*private_port
)
435 struct event event
= {
436 .type
= COMP_PORT_DISCONNECTED
,
437 .data
.comp_port_disconnected
= {
438 .comp
= bt_component_from_private(private_component
),
439 .port
= bt_port_from_private(private_port
),
443 bt_put(event
.data
.comp_port_disconnected
.comp
);
444 bt_put(event
.data
.comp_port_disconnected
.port
);
445 append_event(&event
);
449 enum bt_component_status
sink_init(struct bt_private_component
*priv_comp
,
450 struct bt_value
*params
, void *init_method_data
)
454 ret
= bt_private_component_sink_add_input_private_port(priv_comp
,
457 return BT_COMPONENT_STATUS_OK
;
461 void graph_port_added(struct bt_port
*port
,
464 struct bt_component
*comp
= bt_port_get_component(port
);
469 struct event event
= {
470 .type
= GRAPH_PORT_ADDED
,
471 .data
.graph_port_added
= {
477 append_event(&event
);
481 void graph_port_removed(struct bt_component
*component
,
482 struct bt_port
*port
, void *data
)
484 struct event event
= {
485 .type
= GRAPH_PORT_REMOVED
,
486 .data
.graph_port_removed
= {
492 append_event(&event
);
496 void graph_ports_connected(struct bt_port
*upstream_port
,
497 struct bt_port
*downstream_port
, void *data
)
499 struct bt_component
*upstream_comp
=
500 bt_port_get_component(upstream_port
);
501 struct bt_component
*downstream_comp
=
502 bt_port_get_component(downstream_port
);
503 struct bt_connection
*conn
= bt_port_get_connection(upstream_port
);
505 assert(upstream_comp
);
506 assert(downstream_comp
);
508 bt_put(upstream_comp
);
509 bt_put(downstream_comp
);
512 struct event event
= {
513 .type
= GRAPH_PORTS_CONNECTED
,
514 .data
.graph_ports_connected
= {
515 .upstream_comp
= upstream_comp
,
516 .downstream_comp
= downstream_comp
,
517 .upstream_port
= upstream_port
,
518 .downstream_port
= downstream_port
,
523 append_event(&event
);
527 void graph_ports_disconnected(
528 struct bt_component
*upstream_comp
,
529 struct bt_component
*downstream_comp
,
530 struct bt_port
*upstream_port
, struct bt_port
*downstream_port
,
533 struct event event
= {
534 .type
= GRAPH_PORTS_DISCONNECTED
,
535 .data
.graph_ports_disconnected
= {
536 .upstream_comp
= upstream_comp
,
537 .downstream_comp
= downstream_comp
,
538 .upstream_port
= upstream_port
,
539 .downstream_port
= downstream_port
,
543 append_event(&event
);
551 src_comp_class
= bt_component_class_source_create("src", src_iter_next
);
552 assert(src_comp_class
);
553 ret
= bt_component_class_set_init_method(src_comp_class
, src_init
);
555 ret
= bt_component_class_set_accept_port_connection_method(
556 src_comp_class
, accept_port_connection
);
558 ret
= bt_component_class_set_port_connected_method(src_comp_class
,
561 ret
= bt_component_class_set_port_disconnected_method(
562 src_comp_class
, src_port_disconnected
);
564 sink_comp_class
= bt_component_class_sink_create("sink", sink_consume
);
565 assert(sink_comp_class
);
566 ret
= bt_component_class_set_init_method(sink_comp_class
, sink_init
);
568 ret
= bt_component_class_set_accept_port_connection_method(
569 sink_comp_class
, accept_port_connection
);
571 ret
= bt_component_class_set_port_connected_method(sink_comp_class
,
572 sink_port_connected
);
574 ret
= bt_component_class_set_port_disconnected_method(sink_comp_class
,
575 sink_port_disconnected
);
577 bt_component_class_freeze(src_comp_class
);
578 bt_component_class_freeze(sink_comp_class
);
579 events
= g_array_new(FALSE
, TRUE
, sizeof(struct event
));
586 bt_put(src_comp_class
);
587 bt_put(sink_comp_class
);
588 g_array_free(events
, TRUE
);
592 struct bt_component
*create_src(struct bt_graph
*graph
)
594 struct bt_component
*comp
;
597 ret
= bt_graph_add_component(graph
, src_comp_class
, "src-comp", NULL
,
604 struct bt_component
*create_sink(struct bt_graph
*graph
)
606 struct bt_component
*comp
;
609 ret
= bt_graph_add_component(graph
, sink_comp_class
, "sink-comp",
616 struct bt_graph
*create_graph(void)
618 struct bt_graph
*graph
= bt_graph_create();
622 ret
= bt_graph_add_port_added_listener(graph
, graph_port_added
, NULL
,
625 ret
= bt_graph_add_port_removed_listener(graph
, graph_port_removed
,
628 ret
= bt_graph_add_ports_connected_listener(graph
,
629 graph_ports_connected
, NULL
, NULL
);
631 ret
= bt_graph_add_ports_disconnected_listener(graph
,
632 graph_ports_disconnected
, NULL
, NULL
);
638 void prepare_test(enum test test
, const char *name
)
642 diag("test: %s", name
);
646 void test_sink_removes_port_in_port_connected_then_src_removes_disconnected_port(void)
649 struct bt_component
*src
;
650 struct bt_component
*sink
;
651 struct bt_graph
*graph
;
652 struct bt_port
*src_def_port
;
653 struct bt_port
*sink_def_port
;
654 struct bt_connection
*conn
;
656 enum bt_graph_status status
;
657 size_t src_accept_port_connection_pos
;
658 size_t sink_accept_port_connection_pos
;
659 size_t src_port_connected_pos
;
660 size_t sink_port_connected_pos
;
661 size_t graph_ports_connected
;
662 size_t src_port_disconnected_pos
;
663 size_t sink_port_disconnected_pos
;
664 size_t graph_ports_disconnected_pos
;
665 size_t graph_port_removed_src_pos
;
666 size_t graph_port_removed_sink_pos
;
668 prepare_test(TEST_SINK_REMOVES_PORT_IN_CONSUME_THEN_SRC_REMOVES_DISCONNECTED_PORT
,
669 "sink removes port in consume, then source removes disconnected port");
670 graph
= create_graph();
672 src
= create_src(graph
);
673 sink
= create_sink(graph
);
674 src_def_port
= bt_component_source_get_output_port_by_name(src
, "out");
675 assert(src_def_port
);
676 sink_def_port
= bt_component_sink_get_input_port_by_name(sink
, "in");
677 assert(sink_def_port
);
678 status
= bt_graph_connect_ports(graph
, src_def_port
, sink_def_port
,
683 /* We're supposed to have 7 events so far */
684 ok(events
->len
== 7, "we have the expected number of events (before consume)");
686 /* Source's port added */
687 event
.type
= GRAPH_PORT_ADDED
;
688 event
.data
.graph_port_added
.comp
= src
;
689 event
.data
.graph_port_added
.port
= src_def_port
;
690 ok(has_event(&event
), "got the expected graph's port added event (for source, initial)");
692 /* Sink's port added */
693 event
.type
= GRAPH_PORT_ADDED
;
694 event
.data
.graph_port_added
.comp
= sink
;
695 event
.data
.graph_port_added
.port
= sink_def_port
;
696 ok(has_event(&event
), "got the expected graph's port added event (for sink, initial)");
698 /* Source's accept port connection */
699 event
.type
= COMP_ACCEPT_PORT_CONNECTION
;
700 event
.data
.comp_accept_port_connection
.comp
= src
;
701 event
.data
.comp_accept_port_connection
.self_port
= src_def_port
;
702 event
.data
.comp_accept_port_connection
.other_port
= sink_def_port
;
703 ok(has_event(&event
), "got the expected source's accept port connection event");
704 src_accept_port_connection_pos
= event_pos(&event
);
706 /* Sink's accept port connection */
707 event
.type
= COMP_ACCEPT_PORT_CONNECTION
;
708 event
.data
.comp_accept_port_connection
.comp
= sink
;
709 event
.data
.comp_accept_port_connection
.self_port
= sink_def_port
;
710 event
.data
.comp_accept_port_connection
.other_port
= src_def_port
;
711 ok(has_event(&event
), "got the expected sink's accept port connection event");
712 sink_accept_port_connection_pos
= event_pos(&event
);
714 /* Source's port connected */
715 event
.type
= COMP_PORT_CONNECTED
;
716 event
.data
.comp_port_connected
.comp
= src
;
717 event
.data
.comp_port_connected
.self_port
= src_def_port
;
718 event
.data
.comp_port_connected
.other_port
= sink_def_port
;
719 ok(has_event(&event
), "got the expected source's port connected event");
720 src_port_connected_pos
= event_pos(&event
);
722 /* Sink's port connected */
723 event
.type
= COMP_PORT_CONNECTED
;
724 event
.data
.comp_port_connected
.comp
= sink
;
725 event
.data
.comp_port_connected
.self_port
= sink_def_port
;
726 event
.data
.comp_port_connected
.other_port
= src_def_port
;
727 ok(has_event(&event
), "got the expected sink's port connected event");
728 sink_port_connected_pos
= event_pos(&event
);
730 /* Graph's ports connected */
731 event
.type
= GRAPH_PORTS_CONNECTED
;
732 event
.data
.graph_ports_connected
.upstream_comp
= src
;
733 event
.data
.graph_ports_connected
.downstream_comp
= sink
;
734 event
.data
.graph_ports_connected
.upstream_port
= src_def_port
;
735 event
.data
.graph_ports_connected
.downstream_port
= sink_def_port
;
736 event
.data
.graph_ports_connected
.conn
= conn
;
737 ok(has_event(&event
), "got the expected graph's ports connected event");
738 graph_ports_connected
= event_pos(&event
);
740 /* Order of events */
741 ok(src_port_connected_pos
< graph_ports_connected
,
742 "event order is good (1)");
743 ok(sink_port_connected_pos
< graph_ports_connected
,
744 "event order is good (2)");
745 ok(src_accept_port_connection_pos
< src_port_connected_pos
,
746 "event order is good (3)");
747 ok(sink_accept_port_connection_pos
< sink_port_connected_pos
,
748 "event order is good (4)");
750 /* Consume sink once */
752 ret
= bt_graph_consume(graph
);
755 /* We're supposed to have 5 new events */
756 ok(events
->len
== 5, "we have the expected number of events (after consume)");
758 /* Source's port disconnected */
759 event
.type
= COMP_PORT_DISCONNECTED
;
760 event
.data
.comp_port_disconnected
.comp
= src
;
761 event
.data
.comp_port_disconnected
.port
= src_def_port
;
762 ok(has_event(&event
), "got the expected source's port disconnected event");
763 src_port_disconnected_pos
= event_pos(&event
);
765 /* Sink's port disconnected */
766 event
.type
= COMP_PORT_DISCONNECTED
;
767 event
.data
.comp_port_disconnected
.comp
= sink
;
768 event
.data
.comp_port_disconnected
.port
= sink_def_port
;
769 ok(has_event(&event
), "got the expected sink's port disconnected event");
770 sink_port_disconnected_pos
= event_pos(&event
);
772 /* Graph's ports disconnected */
773 event
.type
= GRAPH_PORTS_DISCONNECTED
;
774 event
.data
.graph_ports_disconnected
.upstream_comp
= src
;
775 event
.data
.graph_ports_disconnected
.downstream_comp
= sink
;
776 event
.data
.graph_ports_disconnected
.upstream_port
= src_def_port
;
777 event
.data
.graph_ports_disconnected
.downstream_port
= sink_def_port
;
778 ok(has_event(&event
), "got the expected graph's ports disconnected event");
779 graph_ports_disconnected_pos
= event_pos(&event
);
781 /* Graph's port removed (sink) */
782 event
.type
= GRAPH_PORT_REMOVED
;
783 event
.data
.graph_port_removed
.comp
= sink
;
784 event
.data
.graph_port_removed
.port
= sink_def_port
;
785 ok(has_event(&event
), "got the expected graph's port removed event (for sink)");
786 graph_port_removed_sink_pos
= event_pos(&event
);
788 /* Graph's port removed (source) */
789 event
.type
= GRAPH_PORT_REMOVED
;
790 event
.data
.graph_port_removed
.comp
= src
;
791 event
.data
.graph_port_removed
.port
= src_def_port
;
792 ok(has_event(&event
), "got the expected graph's port removed event (for source)");
793 graph_port_removed_src_pos
= event_pos(&event
);
795 /* Order of events */
796 ok(src_port_disconnected_pos
< graph_ports_disconnected_pos
,
797 "event order is good (5)");
798 ok(src_port_disconnected_pos
< graph_port_removed_sink_pos
,
799 "event order is good (6)");
800 ok(src_port_disconnected_pos
< graph_port_removed_src_pos
,
801 "event order is good (7)");
802 ok(sink_port_disconnected_pos
< graph_ports_disconnected_pos
,
803 "event order is good (8)");
804 ok(sink_port_disconnected_pos
< graph_port_removed_sink_pos
,
805 "event order is good (9)");
806 ok(sink_port_disconnected_pos
< graph_port_removed_src_pos
,
807 "event order is good (10)");
808 ok(graph_ports_disconnected_pos
< graph_port_removed_sink_pos
,
809 "event order is good (11)");
810 ok(graph_port_removed_src_pos
< graph_ports_disconnected_pos
,
811 "event order is good (12)");
812 ok(graph_port_removed_src_pos
< graph_port_removed_sink_pos
,
813 "event order is good (13)");
819 bt_put(src_def_port
);
820 bt_put(sink_def_port
);
824 void test_sink_removes_port_in_port_connected(void)
827 struct bt_component
*src
;
828 struct bt_component
*sink
;
829 struct bt_graph
*graph
;
830 struct bt_port
*src_def_port
;
831 struct bt_port
*sink_def_port
;
832 struct bt_connection
*conn
;
834 enum bt_graph_status status
;
835 size_t src_accept_port_connection_pos
;
836 size_t sink_accept_port_connection_pos
;
837 size_t src_port_connected_pos
;
838 size_t sink_port_connected_pos
;
839 size_t graph_ports_connected_pos
;
840 size_t src_port_disconnected_pos
;
841 size_t sink_port_disconnected_pos
;
842 size_t graph_ports_disconnected_pos
;
843 size_t graph_port_removed_sink_pos
;
845 prepare_test(TEST_SINK_REMOVES_PORT_IN_CONSUME
,
846 "sink removes port in consume");
847 graph
= create_graph();
849 src
= create_src(graph
);
850 sink
= create_sink(graph
);
851 src_def_port
= bt_component_source_get_output_port_by_name(src
, "out");
852 assert(src_def_port
);
853 sink_def_port
= bt_component_sink_get_input_port_by_name(sink
, "in");
854 assert(sink_def_port
);
855 status
= bt_graph_connect_ports(graph
, src_def_port
, sink_def_port
,
859 /* We're supposed to have 7 events so far */
860 ok(events
->len
== 7, "we have the expected number of events (before consume)");
862 /* Source's port added */
863 event
.type
= GRAPH_PORT_ADDED
;
864 event
.data
.graph_port_added
.comp
= src
;
865 event
.data
.graph_port_added
.port
= src_def_port
;
866 ok(has_event(&event
), "got the expected graph's port added event (for source, initial)");
868 /* Sink's port added */
869 event
.type
= GRAPH_PORT_ADDED
;
870 event
.data
.graph_port_added
.comp
= sink
;
871 event
.data
.graph_port_added
.port
= sink_def_port
;
872 ok(has_event(&event
), "got the expected graph's port added event (for sink, initial)");
874 /* Source's accept port connection */
875 event
.type
= COMP_ACCEPT_PORT_CONNECTION
;
876 event
.data
.comp_accept_port_connection
.comp
= src
;
877 event
.data
.comp_accept_port_connection
.self_port
= src_def_port
;
878 event
.data
.comp_accept_port_connection
.other_port
= sink_def_port
;
879 ok(has_event(&event
), "got the expected source's accept port connection event");
880 src_accept_port_connection_pos
= event_pos(&event
);
882 /* Sink's accept port connection */
883 event
.type
= COMP_ACCEPT_PORT_CONNECTION
;
884 event
.data
.comp_accept_port_connection
.comp
= sink
;
885 event
.data
.comp_accept_port_connection
.self_port
= sink_def_port
;
886 event
.data
.comp_accept_port_connection
.other_port
= src_def_port
;
887 ok(has_event(&event
), "got the expected sink's accept port connection event");
888 sink_accept_port_connection_pos
= event_pos(&event
);
890 /* Source's port connected */
891 event
.type
= COMP_PORT_CONNECTED
;
892 event
.data
.comp_port_connected
.comp
= src
;
893 event
.data
.comp_port_connected
.self_port
= src_def_port
;
894 event
.data
.comp_port_connected
.other_port
= sink_def_port
;
895 ok(has_event(&event
), "got the expected source's port connected event");
896 src_port_connected_pos
= event_pos(&event
);
898 /* Sink's port connected */
899 event
.type
= COMP_PORT_CONNECTED
;
900 event
.data
.comp_port_connected
.comp
= sink
;
901 event
.data
.comp_port_connected
.self_port
= sink_def_port
;
902 event
.data
.comp_port_connected
.other_port
= src_def_port
;
903 ok(has_event(&event
), "got the expected sink's port connected event");
904 sink_port_connected_pos
= event_pos(&event
);
906 /* Graph's ports connected */
907 event
.type
= GRAPH_PORTS_CONNECTED
;
908 event
.data
.graph_ports_connected
.upstream_comp
= src
;
909 event
.data
.graph_ports_connected
.downstream_comp
= sink
;
910 event
.data
.graph_ports_connected
.upstream_port
= src_def_port
;
911 event
.data
.graph_ports_connected
.downstream_port
= sink_def_port
;
912 event
.data
.graph_ports_connected
.conn
= conn
;
913 ok(has_event(&event
), "got the expected graph's ports connected event");
914 graph_ports_connected_pos
= event_pos(&event
);
916 /* Order of events */
917 ok(src_port_connected_pos
< graph_ports_connected_pos
,
918 "event order is good (1)");
919 ok(sink_port_connected_pos
< graph_ports_connected_pos
,
920 "event order is good (2)");
921 ok(src_accept_port_connection_pos
< src_port_connected_pos
,
922 "event order is good (3)");
923 ok(sink_accept_port_connection_pos
< sink_port_connected_pos
,
924 "event order is good (4)");
926 /* Consume sink once */
928 ret
= bt_graph_consume(graph
);
931 /* We're supposed to have 4 new events */
932 ok(events
->len
== 4, "we have the expected number of events (after consume)");
934 /* Source's port disconnected */
935 event
.type
= COMP_PORT_DISCONNECTED
;
936 event
.data
.comp_port_disconnected
.comp
= src
;
937 event
.data
.comp_port_disconnected
.port
= src_def_port
;
938 ok(has_event(&event
), "got the expected source's port disconnected event");
939 src_port_disconnected_pos
= event_pos(&event
);
941 /* Sink's port disconnected */
942 event
.type
= COMP_PORT_DISCONNECTED
;
943 event
.data
.comp_port_disconnected
.comp
= sink
;
944 event
.data
.comp_port_disconnected
.port
= sink_def_port
;
945 ok(has_event(&event
), "got the expected sink's port disconnected event");
946 sink_port_disconnected_pos
= event_pos(&event
);
948 /* Graph's ports disconnected */
949 event
.type
= GRAPH_PORTS_DISCONNECTED
;
950 event
.data
.graph_ports_disconnected
.upstream_comp
= src
;
951 event
.data
.graph_ports_disconnected
.downstream_comp
= sink
;
952 event
.data
.graph_ports_disconnected
.upstream_port
= src_def_port
;
953 event
.data
.graph_ports_disconnected
.downstream_port
= sink_def_port
;
954 ok(has_event(&event
), "got the expected graph's ports disconnected event");
955 graph_ports_disconnected_pos
= event_pos(&event
);
957 /* Graph's port removed (sink) */
958 event
.type
= GRAPH_PORT_REMOVED
;
959 event
.data
.graph_port_removed
.comp
= sink
;
960 event
.data
.graph_port_removed
.port
= sink_def_port
;
961 ok(has_event(&event
), "got the expected graph's port removed event (for sink)");
962 graph_port_removed_sink_pos
= event_pos(&event
);
964 /* Order of events */
965 ok(src_port_disconnected_pos
< graph_ports_disconnected_pos
,
966 "event order is good (5)");
967 ok(src_port_disconnected_pos
< graph_port_removed_sink_pos
,
968 "event order is good (7)");
969 ok(sink_port_disconnected_pos
< graph_ports_disconnected_pos
,
970 "event order is good (8)");
971 ok(sink_port_disconnected_pos
< graph_port_removed_sink_pos
,
972 "event order is good (10)");
973 ok(graph_ports_disconnected_pos
< graph_port_removed_sink_pos
,
974 "event order is good (11)");
980 bt_put(src_def_port
);
981 bt_put(sink_def_port
);
985 void test_src_adds_port_in_port_connected(void)
987 struct bt_component
*src
;
988 struct bt_component
*sink
;
989 struct bt_graph
*graph
;
990 struct bt_port
*src_def_port
;
991 struct bt_port
*sink_def_port
;
992 struct bt_port
*src_hello_port
;
993 struct bt_connection
*conn
;
995 enum bt_graph_status status
;
996 size_t src_accept_port_connection_pos
;
997 size_t sink_accept_port_connection_pos
;
998 size_t src_port_connected_pos
;
999 size_t sink_port_connected_pos
;
1000 size_t graph_ports_connected_pos
;
1001 size_t graph_port_added_src_pos
;
1003 prepare_test(TEST_SRC_ADDS_PORT_IN_PORT_CONNECTED
,
1004 "source adds port in port connected");
1005 graph
= create_graph();
1007 src
= create_src(graph
);
1008 sink
= create_sink(graph
);
1009 src_def_port
= bt_component_source_get_output_port_by_name(src
, "out");
1010 assert(src_def_port
);
1011 sink_def_port
= bt_component_sink_get_input_port_by_name(sink
, "in");
1012 assert(sink_def_port
);
1013 status
= bt_graph_connect_ports(graph
, src_def_port
, sink_def_port
,
1015 assert(status
== 0);
1016 src_hello_port
= bt_component_source_get_output_port_by_name(src
,
1018 assert(src_hello_port
);
1020 /* We're supposed to have 8 events */
1021 ok(events
->len
== 8, "we have the expected number of events");
1023 /* Source's port added */
1024 event
.type
= GRAPH_PORT_ADDED
;
1025 event
.data
.graph_port_added
.comp
= src
;
1026 event
.data
.graph_port_added
.port
= src_def_port
;
1027 ok(has_event(&event
), "got the expected graph's port added event (for source, initial)");
1029 /* Sink's port added */
1030 event
.type
= GRAPH_PORT_ADDED
;
1031 event
.data
.graph_port_added
.comp
= sink
;
1032 event
.data
.graph_port_added
.port
= sink_def_port
;
1033 ok(has_event(&event
), "got the expected graph's port added event (for sink, initial)");
1035 /* Source's accept port connection */
1036 event
.type
= COMP_ACCEPT_PORT_CONNECTION
;
1037 event
.data
.comp_accept_port_connection
.comp
= src
;
1038 event
.data
.comp_accept_port_connection
.self_port
= src_def_port
;
1039 event
.data
.comp_accept_port_connection
.other_port
= sink_def_port
;
1040 ok(has_event(&event
), "got the expected source's accept port connection event");
1041 src_accept_port_connection_pos
= event_pos(&event
);
1043 /* Sink's accept port connection */
1044 event
.type
= COMP_ACCEPT_PORT_CONNECTION
;
1045 event
.data
.comp_accept_port_connection
.comp
= sink
;
1046 event
.data
.comp_accept_port_connection
.self_port
= sink_def_port
;
1047 event
.data
.comp_accept_port_connection
.other_port
= src_def_port
;
1048 ok(has_event(&event
), "got the expected sink's accept port connection event");
1049 sink_accept_port_connection_pos
= event_pos(&event
);
1051 /* Source's port connected */
1052 event
.type
= COMP_PORT_CONNECTED
;
1053 event
.data
.comp_port_connected
.comp
= src
;
1054 event
.data
.comp_port_connected
.self_port
= src_def_port
;
1055 event
.data
.comp_port_connected
.other_port
= sink_def_port
;
1056 ok(has_event(&event
), "got the expected source's port connected event");
1057 src_port_connected_pos
= event_pos(&event
);
1059 /* Graph's port added (source) */
1060 event
.type
= GRAPH_PORT_ADDED
;
1061 event
.data
.graph_port_added
.comp
= src
;
1062 event
.data
.graph_port_added
.port
= src_hello_port
;
1063 ok(has_event(&event
), "got the expected graph's port added event (for source)");
1064 graph_port_added_src_pos
= event_pos(&event
);
1066 /* Sink's port connected */
1067 event
.type
= COMP_PORT_CONNECTED
;
1068 event
.data
.comp_port_connected
.comp
= sink
;
1069 event
.data
.comp_port_connected
.self_port
= sink_def_port
;
1070 event
.data
.comp_port_connected
.other_port
= src_def_port
;
1071 ok(has_event(&event
), "got the expected sink's port connected event");
1072 sink_port_connected_pos
= event_pos(&event
);
1074 /* Graph's ports connected */
1075 event
.type
= GRAPH_PORTS_CONNECTED
;
1076 event
.data
.graph_ports_connected
.upstream_comp
= src
;
1077 event
.data
.graph_ports_connected
.downstream_comp
= sink
;
1078 event
.data
.graph_ports_connected
.upstream_port
= src_def_port
;
1079 event
.data
.graph_ports_connected
.downstream_port
= sink_def_port
;
1080 event
.data
.graph_ports_connected
.conn
= conn
;
1081 ok(has_event(&event
), "got the expected graph's port connected event (for source)");
1082 graph_ports_connected_pos
= event_pos(&event
);
1084 /* Order of events */
1085 ok(src_port_connected_pos
< graph_ports_connected_pos
,
1086 "event order is good (1)");
1087 ok(sink_port_connected_pos
< graph_ports_connected_pos
,
1088 "event order is good (2)");
1089 ok(src_accept_port_connection_pos
< src_port_connected_pos
,
1090 "event order is good (3)");
1091 ok(sink_accept_port_connection_pos
< sink_port_connected_pos
,
1092 "event order is good (4)");
1093 ok(src_port_connected_pos
< graph_port_added_src_pos
,
1094 "event order is good (5)");
1095 ok(graph_port_added_src_pos
< graph_ports_connected_pos
,
1096 "event order is good (6)");
1102 bt_put(src_def_port
);
1103 bt_put(sink_def_port
);
1104 bt_put(src_hello_port
);
1108 void test_simple(void)
1110 struct bt_component
*src
;
1111 struct bt_component
*sink
;
1112 struct bt_graph
*graph
;
1113 struct bt_port
*src_def_port
;
1114 struct bt_port
*sink_def_port
;
1115 struct bt_connection
*conn
;
1117 enum bt_graph_status status
;
1118 size_t src_accept_port_connection_pos
;
1119 size_t sink_accept_port_connection_pos
;
1120 size_t src_port_connected_pos
;
1121 size_t sink_port_connected_pos
;
1122 size_t graph_ports_connected_pos
;
1124 prepare_test(TEST_SIMPLE
, "simple");
1125 graph
= create_graph();
1127 src
= create_src(graph
);
1128 sink
= create_sink(graph
);
1129 src_def_port
= bt_component_source_get_output_port_by_name(src
, "out");
1130 assert(src_def_port
);
1131 sink_def_port
= bt_component_sink_get_input_port_by_name(sink
, "in");
1132 assert(sink_def_port
);
1133 status
= bt_graph_connect_ports(graph
, src_def_port
, sink_def_port
,
1135 assert(status
== 0);
1137 /* We're supposed to have 7 events */
1138 ok(events
->len
== 7, "we have the expected number of events");
1140 /* Source's port added */
1141 event
.type
= GRAPH_PORT_ADDED
;
1142 event
.data
.graph_port_added
.comp
= src
;
1143 event
.data
.graph_port_added
.port
= src_def_port
;
1144 ok(has_event(&event
), "got the expected graph's port added event (for source, initial)");
1146 /* Sink's port added */
1147 event
.type
= GRAPH_PORT_ADDED
;
1148 event
.data
.graph_port_added
.comp
= sink
;
1149 event
.data
.graph_port_added
.port
= sink_def_port
;
1150 ok(has_event(&event
), "got the expected graph's port added event (for sink, initial)");
1152 /* Source's accept port connection */
1153 event
.type
= COMP_ACCEPT_PORT_CONNECTION
;
1154 event
.data
.comp_accept_port_connection
.comp
= src
;
1155 event
.data
.comp_accept_port_connection
.self_port
= src_def_port
;
1156 event
.data
.comp_accept_port_connection
.other_port
= sink_def_port
;
1157 ok(has_event(&event
), "got the expected source's accept port connection event");
1158 src_accept_port_connection_pos
= event_pos(&event
);
1160 /* Sink's accept port connection */
1161 event
.type
= COMP_ACCEPT_PORT_CONNECTION
;
1162 event
.data
.comp_accept_port_connection
.comp
= sink
;
1163 event
.data
.comp_accept_port_connection
.self_port
= sink_def_port
;
1164 event
.data
.comp_accept_port_connection
.other_port
= src_def_port
;
1165 ok(has_event(&event
), "got the expected sink's accept port connection event");
1166 sink_accept_port_connection_pos
= event_pos(&event
);
1168 /* Source's port connected */
1169 event
.type
= COMP_PORT_CONNECTED
;
1170 event
.data
.comp_port_connected
.comp
= src
;
1171 event
.data
.comp_port_connected
.self_port
= src_def_port
;
1172 event
.data
.comp_port_connected
.other_port
= sink_def_port
;
1173 ok(has_event(&event
), "got the expected source's port connected event");
1174 src_port_connected_pos
= event_pos(&event
);
1176 /* Sink's port connected */
1177 event
.type
= COMP_PORT_CONNECTED
;
1178 event
.data
.comp_port_connected
.comp
= sink
;
1179 event
.data
.comp_port_connected
.self_port
= sink_def_port
;
1180 event
.data
.comp_port_connected
.other_port
= src_def_port
;
1181 ok(has_event(&event
), "got the expected sink's port connected event");
1182 sink_port_connected_pos
= event_pos(&event
);
1184 /* Graph's port connected */
1185 event
.type
= GRAPH_PORTS_CONNECTED
;
1186 event
.data
.graph_ports_connected
.upstream_comp
= src
;
1187 event
.data
.graph_ports_connected
.downstream_comp
= sink
;
1188 event
.data
.graph_ports_connected
.upstream_port
= src_def_port
;
1189 event
.data
.graph_ports_connected
.downstream_port
= sink_def_port
;
1190 event
.data
.graph_ports_connected
.conn
= conn
;
1191 ok(has_event(&event
), "got the expected graph's ports connected event");
1192 graph_ports_connected_pos
= event_pos(&event
);
1194 /* Order of events */
1195 ok(src_port_connected_pos
< graph_ports_connected_pos
,
1196 "event order is good (1)");
1197 ok(sink_port_connected_pos
< graph_ports_connected_pos
,
1198 "event order is good (2)");
1199 ok(src_accept_port_connection_pos
< src_port_connected_pos
,
1200 "event order is good (3)");
1201 ok(sink_accept_port_connection_pos
< sink_port_connected_pos
,
1202 "event order is good (4)");
1208 bt_put(src_def_port
);
1209 bt_put(sink_def_port
);
1213 void test_empty_graph(void)
1215 struct bt_graph
*graph
;
1217 prepare_test(TEST_EMPTY_GRAPH
, "empty graph");
1218 graph
= create_graph();
1219 ok(events
->len
== 0, "empty graph generates no events");
1223 int main(int argc
, char **argv
)
1225 plan_tests(NR_TESTS
);
1229 test_src_adds_port_in_port_connected();
1230 test_sink_removes_port_in_port_connected();
1231 test_sink_removes_port_in_port_connected_then_src_removes_disconnected_port();
1233 return exit_status();