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_borrow_from_private(private_component
),
308 .self_port
= bt_port_borrow_from_private(self_private_port
),
309 .other_port
= other_port
,
313 append_event(&event
);
314 return BT_COMPONENT_STATUS_OK
;
318 void src_port_connected(struct bt_private_component
*private_component
,
319 struct bt_private_port
*self_private_port
,
320 struct bt_port
*other_port
)
324 struct event event
= {
325 .type
= COMP_PORT_CONNECTED
,
326 .data
.comp_port_connected
= {
327 .comp
= bt_component_borrow_from_private(private_component
),
328 .self_port
= bt_port_borrow_from_private(self_private_port
),
329 .other_port
= other_port
,
333 append_event(&event
);
335 switch (current_test
) {
336 case TEST_SRC_ADDS_PORT_IN_PORT_CONNECTED
:
337 ret
= bt_private_component_source_add_output_private_port(
338 private_component
, "hello", NULL
, NULL
);
347 void src_port_disconnected(struct bt_private_component
*private_component
,
348 struct bt_private_port
*private_port
)
351 struct event event
= {
352 .type
= COMP_PORT_DISCONNECTED
,
353 .data
.comp_port_disconnected
= {
354 .comp
= bt_component_borrow_from_private(private_component
),
355 .port
= bt_port_borrow_from_private(private_port
),
359 append_event(&event
);
361 switch (current_test
) {
362 case TEST_SINK_REMOVES_PORT_IN_CONSUME_THEN_SRC_REMOVES_DISCONNECTED_PORT
:
363 ret
= bt_private_port_remove_from_component(private_port
);
371 enum bt_component_status
src_init(struct bt_private_component
*priv_comp
,
372 struct bt_value
*params
, void *init_method_data
)
376 ret
= bt_private_component_source_add_output_private_port(
377 priv_comp
, "out", NULL
, NULL
);
379 return BT_COMPONENT_STATUS_OK
;
383 enum bt_component_status
sink_consume(
384 struct bt_private_component
*priv_component
)
386 struct bt_private_port
*def_port
;
389 switch (current_test
) {
390 case TEST_SINK_REMOVES_PORT_IN_CONSUME
:
391 case TEST_SINK_REMOVES_PORT_IN_CONSUME_THEN_SRC_REMOVES_DISCONNECTED_PORT
:
392 def_port
= bt_private_component_sink_get_input_private_port_by_name(
393 priv_component
, "in");
395 ret
= bt_private_port_remove_from_component(def_port
);
403 return BT_COMPONENT_STATUS_OK
;
407 void sink_port_connected(struct bt_private_component
*private_component
,
408 struct bt_private_port
*self_private_port
,
409 struct bt_port
*other_port
)
411 struct event event
= {
412 .type
= COMP_PORT_CONNECTED
,
413 .data
.comp_port_connected
= {
414 .comp
= bt_component_borrow_from_private(private_component
),
415 .self_port
= bt_port_borrow_from_private(self_private_port
),
416 .other_port
= other_port
,
420 append_event(&event
);
424 void sink_port_disconnected(struct bt_private_component
*private_component
,
425 struct bt_private_port
*private_port
)
427 struct event event
= {
428 .type
= COMP_PORT_DISCONNECTED
,
429 .data
.comp_port_disconnected
= {
430 .comp
= bt_component_borrow_from_private(private_component
),
431 .port
= bt_port_borrow_from_private(private_port
),
435 append_event(&event
);
439 enum bt_component_status
sink_init(struct bt_private_component
*priv_comp
,
440 struct bt_value
*params
, void *init_method_data
)
444 ret
= bt_private_component_sink_add_input_private_port(priv_comp
,
447 return BT_COMPONENT_STATUS_OK
;
451 void graph_port_added(struct bt_port
*port
,
454 struct bt_component
*comp
= bt_port_get_component(port
);
459 struct event event
= {
460 .type
= GRAPH_PORT_ADDED
,
461 .data
.graph_port_added
= {
467 append_event(&event
);
471 void graph_port_removed(struct bt_component
*component
,
472 struct bt_port
*port
, void *data
)
474 struct event event
= {
475 .type
= GRAPH_PORT_REMOVED
,
476 .data
.graph_port_removed
= {
482 append_event(&event
);
486 void graph_ports_connected(struct bt_port
*upstream_port
,
487 struct bt_port
*downstream_port
, void *data
)
489 struct bt_component
*upstream_comp
=
490 bt_port_get_component(upstream_port
);
491 struct bt_component
*downstream_comp
=
492 bt_port_get_component(downstream_port
);
493 struct bt_connection
*conn
= bt_port_get_connection(upstream_port
);
495 assert(upstream_comp
);
496 assert(downstream_comp
);
498 bt_put(upstream_comp
);
499 bt_put(downstream_comp
);
502 struct event event
= {
503 .type
= GRAPH_PORTS_CONNECTED
,
504 .data
.graph_ports_connected
= {
505 .upstream_comp
= upstream_comp
,
506 .downstream_comp
= downstream_comp
,
507 .upstream_port
= upstream_port
,
508 .downstream_port
= downstream_port
,
513 append_event(&event
);
517 void graph_ports_disconnected(
518 struct bt_component
*upstream_comp
,
519 struct bt_component
*downstream_comp
,
520 struct bt_port
*upstream_port
, struct bt_port
*downstream_port
,
523 struct event event
= {
524 .type
= GRAPH_PORTS_DISCONNECTED
,
525 .data
.graph_ports_disconnected
= {
526 .upstream_comp
= upstream_comp
,
527 .downstream_comp
= downstream_comp
,
528 .upstream_port
= upstream_port
,
529 .downstream_port
= downstream_port
,
533 append_event(&event
);
541 src_comp_class
= bt_component_class_source_create("src", src_iter_next
);
542 assert(src_comp_class
);
543 ret
= bt_component_class_set_init_method(src_comp_class
, src_init
);
545 ret
= bt_component_class_set_accept_port_connection_method(
546 src_comp_class
, accept_port_connection
);
548 ret
= bt_component_class_set_port_connected_method(src_comp_class
,
551 ret
= bt_component_class_set_port_disconnected_method(
552 src_comp_class
, src_port_disconnected
);
554 sink_comp_class
= bt_component_class_sink_create("sink", sink_consume
);
555 assert(sink_comp_class
);
556 ret
= bt_component_class_set_init_method(sink_comp_class
, sink_init
);
558 ret
= bt_component_class_set_accept_port_connection_method(
559 sink_comp_class
, accept_port_connection
);
561 ret
= bt_component_class_set_port_connected_method(sink_comp_class
,
562 sink_port_connected
);
564 ret
= bt_component_class_set_port_disconnected_method(sink_comp_class
,
565 sink_port_disconnected
);
567 bt_component_class_freeze(src_comp_class
);
568 bt_component_class_freeze(sink_comp_class
);
569 events
= g_array_new(FALSE
, TRUE
, sizeof(struct event
));
576 bt_put(src_comp_class
);
577 bt_put(sink_comp_class
);
578 g_array_free(events
, TRUE
);
582 struct bt_component
*create_src(struct bt_graph
*graph
)
584 struct bt_component
*comp
;
587 ret
= bt_graph_add_component(graph
, src_comp_class
, "src-comp", NULL
,
594 struct bt_component
*create_sink(struct bt_graph
*graph
)
596 struct bt_component
*comp
;
599 ret
= bt_graph_add_component(graph
, sink_comp_class
, "sink-comp",
606 struct bt_graph
*create_graph(void)
608 struct bt_graph
*graph
= bt_graph_create();
612 ret
= bt_graph_add_port_added_listener(graph
, graph_port_added
, NULL
,
615 ret
= bt_graph_add_port_removed_listener(graph
, graph_port_removed
,
618 ret
= bt_graph_add_ports_connected_listener(graph
,
619 graph_ports_connected
, NULL
, NULL
);
621 ret
= bt_graph_add_ports_disconnected_listener(graph
,
622 graph_ports_disconnected
, NULL
, NULL
);
628 void prepare_test(enum test test
, const char *name
)
632 diag("test: %s", name
);
636 void test_sink_removes_port_in_port_connected_then_src_removes_disconnected_port(void)
639 struct bt_component
*src
;
640 struct bt_component
*sink
;
641 struct bt_graph
*graph
;
642 struct bt_port
*src_def_port
;
643 struct bt_port
*sink_def_port
;
644 struct bt_connection
*conn
;
646 enum bt_graph_status status
;
647 size_t src_accept_port_connection_pos
;
648 size_t sink_accept_port_connection_pos
;
649 size_t src_port_connected_pos
;
650 size_t sink_port_connected_pos
;
651 size_t graph_ports_connected
;
652 size_t src_port_disconnected_pos
;
653 size_t sink_port_disconnected_pos
;
654 size_t graph_ports_disconnected_pos
;
655 size_t graph_port_removed_src_pos
;
656 size_t graph_port_removed_sink_pos
;
658 prepare_test(TEST_SINK_REMOVES_PORT_IN_CONSUME_THEN_SRC_REMOVES_DISCONNECTED_PORT
,
659 "sink removes port in consume, then source removes disconnected port");
660 graph
= create_graph();
662 src
= create_src(graph
);
663 sink
= create_sink(graph
);
664 src_def_port
= bt_component_source_get_output_port_by_name(src
, "out");
665 assert(src_def_port
);
666 sink_def_port
= bt_component_sink_get_input_port_by_name(sink
, "in");
667 assert(sink_def_port
);
668 status
= bt_graph_connect_ports(graph
, src_def_port
, sink_def_port
,
673 /* We're supposed to have 7 events so far */
674 ok(events
->len
== 7, "we have the expected number of events (before consume)");
676 /* Source's port added */
677 event
.type
= GRAPH_PORT_ADDED
;
678 event
.data
.graph_port_added
.comp
= src
;
679 event
.data
.graph_port_added
.port
= src_def_port
;
680 ok(has_event(&event
), "got the expected graph's port added event (for source, initial)");
682 /* Sink's port added */
683 event
.type
= GRAPH_PORT_ADDED
;
684 event
.data
.graph_port_added
.comp
= sink
;
685 event
.data
.graph_port_added
.port
= sink_def_port
;
686 ok(has_event(&event
), "got the expected graph's port added event (for sink, initial)");
688 /* Source's accept port connection */
689 event
.type
= COMP_ACCEPT_PORT_CONNECTION
;
690 event
.data
.comp_accept_port_connection
.comp
= src
;
691 event
.data
.comp_accept_port_connection
.self_port
= src_def_port
;
692 event
.data
.comp_accept_port_connection
.other_port
= sink_def_port
;
693 ok(has_event(&event
), "got the expected source's accept port connection event");
694 src_accept_port_connection_pos
= event_pos(&event
);
696 /* Sink's accept port connection */
697 event
.type
= COMP_ACCEPT_PORT_CONNECTION
;
698 event
.data
.comp_accept_port_connection
.comp
= sink
;
699 event
.data
.comp_accept_port_connection
.self_port
= sink_def_port
;
700 event
.data
.comp_accept_port_connection
.other_port
= src_def_port
;
701 ok(has_event(&event
), "got the expected sink's accept port connection event");
702 sink_accept_port_connection_pos
= event_pos(&event
);
704 /* Source's port connected */
705 event
.type
= COMP_PORT_CONNECTED
;
706 event
.data
.comp_port_connected
.comp
= src
;
707 event
.data
.comp_port_connected
.self_port
= src_def_port
;
708 event
.data
.comp_port_connected
.other_port
= sink_def_port
;
709 ok(has_event(&event
), "got the expected source's port connected event");
710 src_port_connected_pos
= event_pos(&event
);
712 /* Sink's port connected */
713 event
.type
= COMP_PORT_CONNECTED
;
714 event
.data
.comp_port_connected
.comp
= sink
;
715 event
.data
.comp_port_connected
.self_port
= sink_def_port
;
716 event
.data
.comp_port_connected
.other_port
= src_def_port
;
717 ok(has_event(&event
), "got the expected sink's port connected event");
718 sink_port_connected_pos
= event_pos(&event
);
720 /* Graph's ports connected */
721 event
.type
= GRAPH_PORTS_CONNECTED
;
722 event
.data
.graph_ports_connected
.upstream_comp
= src
;
723 event
.data
.graph_ports_connected
.downstream_comp
= sink
;
724 event
.data
.graph_ports_connected
.upstream_port
= src_def_port
;
725 event
.data
.graph_ports_connected
.downstream_port
= sink_def_port
;
726 event
.data
.graph_ports_connected
.conn
= conn
;
727 ok(has_event(&event
), "got the expected graph's ports connected event");
728 graph_ports_connected
= event_pos(&event
);
730 /* Order of events */
731 ok(src_port_connected_pos
< graph_ports_connected
,
732 "event order is good (1)");
733 ok(sink_port_connected_pos
< graph_ports_connected
,
734 "event order is good (2)");
735 ok(src_accept_port_connection_pos
< src_port_connected_pos
,
736 "event order is good (3)");
737 ok(sink_accept_port_connection_pos
< sink_port_connected_pos
,
738 "event order is good (4)");
740 /* Consume sink once */
742 ret
= bt_graph_consume(graph
);
745 /* We're supposed to have 5 new events */
746 ok(events
->len
== 5, "we have the expected number of events (after consume)");
748 /* Source's port disconnected */
749 event
.type
= COMP_PORT_DISCONNECTED
;
750 event
.data
.comp_port_disconnected
.comp
= src
;
751 event
.data
.comp_port_disconnected
.port
= src_def_port
;
752 ok(has_event(&event
), "got the expected source's port disconnected event");
753 src_port_disconnected_pos
= event_pos(&event
);
755 /* Sink's port disconnected */
756 event
.type
= COMP_PORT_DISCONNECTED
;
757 event
.data
.comp_port_disconnected
.comp
= sink
;
758 event
.data
.comp_port_disconnected
.port
= sink_def_port
;
759 ok(has_event(&event
), "got the expected sink's port disconnected event");
760 sink_port_disconnected_pos
= event_pos(&event
);
762 /* Graph's ports disconnected */
763 event
.type
= GRAPH_PORTS_DISCONNECTED
;
764 event
.data
.graph_ports_disconnected
.upstream_comp
= src
;
765 event
.data
.graph_ports_disconnected
.downstream_comp
= sink
;
766 event
.data
.graph_ports_disconnected
.upstream_port
= src_def_port
;
767 event
.data
.graph_ports_disconnected
.downstream_port
= sink_def_port
;
768 ok(has_event(&event
), "got the expected graph's ports disconnected event");
769 graph_ports_disconnected_pos
= event_pos(&event
);
771 /* Graph's port removed (sink) */
772 event
.type
= GRAPH_PORT_REMOVED
;
773 event
.data
.graph_port_removed
.comp
= sink
;
774 event
.data
.graph_port_removed
.port
= sink_def_port
;
775 ok(has_event(&event
), "got the expected graph's port removed event (for sink)");
776 graph_port_removed_sink_pos
= event_pos(&event
);
778 /* Graph's port removed (source) */
779 event
.type
= GRAPH_PORT_REMOVED
;
780 event
.data
.graph_port_removed
.comp
= src
;
781 event
.data
.graph_port_removed
.port
= src_def_port
;
782 ok(has_event(&event
), "got the expected graph's port removed event (for source)");
783 graph_port_removed_src_pos
= event_pos(&event
);
785 /* Order of events */
786 ok(src_port_disconnected_pos
< graph_ports_disconnected_pos
,
787 "event order is good (5)");
788 ok(src_port_disconnected_pos
< graph_port_removed_sink_pos
,
789 "event order is good (6)");
790 ok(src_port_disconnected_pos
< graph_port_removed_src_pos
,
791 "event order is good (7)");
792 ok(sink_port_disconnected_pos
< graph_ports_disconnected_pos
,
793 "event order is good (8)");
794 ok(sink_port_disconnected_pos
< graph_port_removed_sink_pos
,
795 "event order is good (9)");
796 ok(sink_port_disconnected_pos
< graph_port_removed_src_pos
,
797 "event order is good (10)");
798 ok(graph_ports_disconnected_pos
< graph_port_removed_sink_pos
,
799 "event order is good (11)");
800 ok(graph_port_removed_src_pos
< graph_ports_disconnected_pos
,
801 "event order is good (12)");
802 ok(graph_port_removed_src_pos
< graph_port_removed_sink_pos
,
803 "event order is good (13)");
809 bt_put(src_def_port
);
810 bt_put(sink_def_port
);
814 void test_sink_removes_port_in_port_connected(void)
817 struct bt_component
*src
;
818 struct bt_component
*sink
;
819 struct bt_graph
*graph
;
820 struct bt_port
*src_def_port
;
821 struct bt_port
*sink_def_port
;
822 struct bt_connection
*conn
;
824 enum bt_graph_status status
;
825 size_t src_accept_port_connection_pos
;
826 size_t sink_accept_port_connection_pos
;
827 size_t src_port_connected_pos
;
828 size_t sink_port_connected_pos
;
829 size_t graph_ports_connected_pos
;
830 size_t src_port_disconnected_pos
;
831 size_t sink_port_disconnected_pos
;
832 size_t graph_ports_disconnected_pos
;
833 size_t graph_port_removed_sink_pos
;
835 prepare_test(TEST_SINK_REMOVES_PORT_IN_CONSUME
,
836 "sink removes port in consume");
837 graph
= create_graph();
839 src
= create_src(graph
);
840 sink
= create_sink(graph
);
841 src_def_port
= bt_component_source_get_output_port_by_name(src
, "out");
842 assert(src_def_port
);
843 sink_def_port
= bt_component_sink_get_input_port_by_name(sink
, "in");
844 assert(sink_def_port
);
845 status
= bt_graph_connect_ports(graph
, src_def_port
, sink_def_port
,
849 /* We're supposed to have 7 events so far */
850 ok(events
->len
== 7, "we have the expected number of events (before consume)");
852 /* Source's port added */
853 event
.type
= GRAPH_PORT_ADDED
;
854 event
.data
.graph_port_added
.comp
= src
;
855 event
.data
.graph_port_added
.port
= src_def_port
;
856 ok(has_event(&event
), "got the expected graph's port added event (for source, initial)");
858 /* Sink's port added */
859 event
.type
= GRAPH_PORT_ADDED
;
860 event
.data
.graph_port_added
.comp
= sink
;
861 event
.data
.graph_port_added
.port
= sink_def_port
;
862 ok(has_event(&event
), "got the expected graph's port added event (for sink, initial)");
864 /* Source's accept port connection */
865 event
.type
= COMP_ACCEPT_PORT_CONNECTION
;
866 event
.data
.comp_accept_port_connection
.comp
= src
;
867 event
.data
.comp_accept_port_connection
.self_port
= src_def_port
;
868 event
.data
.comp_accept_port_connection
.other_port
= sink_def_port
;
869 ok(has_event(&event
), "got the expected source's accept port connection event");
870 src_accept_port_connection_pos
= event_pos(&event
);
872 /* Sink's accept port connection */
873 event
.type
= COMP_ACCEPT_PORT_CONNECTION
;
874 event
.data
.comp_accept_port_connection
.comp
= sink
;
875 event
.data
.comp_accept_port_connection
.self_port
= sink_def_port
;
876 event
.data
.comp_accept_port_connection
.other_port
= src_def_port
;
877 ok(has_event(&event
), "got the expected sink's accept port connection event");
878 sink_accept_port_connection_pos
= event_pos(&event
);
880 /* Source's port connected */
881 event
.type
= COMP_PORT_CONNECTED
;
882 event
.data
.comp_port_connected
.comp
= src
;
883 event
.data
.comp_port_connected
.self_port
= src_def_port
;
884 event
.data
.comp_port_connected
.other_port
= sink_def_port
;
885 ok(has_event(&event
), "got the expected source's port connected event");
886 src_port_connected_pos
= event_pos(&event
);
888 /* Sink's port connected */
889 event
.type
= COMP_PORT_CONNECTED
;
890 event
.data
.comp_port_connected
.comp
= sink
;
891 event
.data
.comp_port_connected
.self_port
= sink_def_port
;
892 event
.data
.comp_port_connected
.other_port
= src_def_port
;
893 ok(has_event(&event
), "got the expected sink's port connected event");
894 sink_port_connected_pos
= event_pos(&event
);
896 /* Graph's ports connected */
897 event
.type
= GRAPH_PORTS_CONNECTED
;
898 event
.data
.graph_ports_connected
.upstream_comp
= src
;
899 event
.data
.graph_ports_connected
.downstream_comp
= sink
;
900 event
.data
.graph_ports_connected
.upstream_port
= src_def_port
;
901 event
.data
.graph_ports_connected
.downstream_port
= sink_def_port
;
902 event
.data
.graph_ports_connected
.conn
= conn
;
903 ok(has_event(&event
), "got the expected graph's ports connected event");
904 graph_ports_connected_pos
= event_pos(&event
);
906 /* Order of events */
907 ok(src_port_connected_pos
< graph_ports_connected_pos
,
908 "event order is good (1)");
909 ok(sink_port_connected_pos
< graph_ports_connected_pos
,
910 "event order is good (2)");
911 ok(src_accept_port_connection_pos
< src_port_connected_pos
,
912 "event order is good (3)");
913 ok(sink_accept_port_connection_pos
< sink_port_connected_pos
,
914 "event order is good (4)");
916 /* Consume sink once */
918 ret
= bt_graph_consume(graph
);
921 /* We're supposed to have 4 new events */
922 ok(events
->len
== 4, "we have the expected number of events (after consume)");
924 /* Source's port disconnected */
925 event
.type
= COMP_PORT_DISCONNECTED
;
926 event
.data
.comp_port_disconnected
.comp
= src
;
927 event
.data
.comp_port_disconnected
.port
= src_def_port
;
928 ok(has_event(&event
), "got the expected source's port disconnected event");
929 src_port_disconnected_pos
= event_pos(&event
);
931 /* Sink's port disconnected */
932 event
.type
= COMP_PORT_DISCONNECTED
;
933 event
.data
.comp_port_disconnected
.comp
= sink
;
934 event
.data
.comp_port_disconnected
.port
= sink_def_port
;
935 ok(has_event(&event
), "got the expected sink's port disconnected event");
936 sink_port_disconnected_pos
= event_pos(&event
);
938 /* Graph's ports disconnected */
939 event
.type
= GRAPH_PORTS_DISCONNECTED
;
940 event
.data
.graph_ports_disconnected
.upstream_comp
= src
;
941 event
.data
.graph_ports_disconnected
.downstream_comp
= sink
;
942 event
.data
.graph_ports_disconnected
.upstream_port
= src_def_port
;
943 event
.data
.graph_ports_disconnected
.downstream_port
= sink_def_port
;
944 ok(has_event(&event
), "got the expected graph's ports disconnected event");
945 graph_ports_disconnected_pos
= event_pos(&event
);
947 /* Graph's port removed (sink) */
948 event
.type
= GRAPH_PORT_REMOVED
;
949 event
.data
.graph_port_removed
.comp
= sink
;
950 event
.data
.graph_port_removed
.port
= sink_def_port
;
951 ok(has_event(&event
), "got the expected graph's port removed event (for sink)");
952 graph_port_removed_sink_pos
= event_pos(&event
);
954 /* Order of events */
955 ok(src_port_disconnected_pos
< graph_ports_disconnected_pos
,
956 "event order is good (5)");
957 ok(src_port_disconnected_pos
< graph_port_removed_sink_pos
,
958 "event order is good (7)");
959 ok(sink_port_disconnected_pos
< graph_ports_disconnected_pos
,
960 "event order is good (8)");
961 ok(sink_port_disconnected_pos
< graph_port_removed_sink_pos
,
962 "event order is good (10)");
963 ok(graph_ports_disconnected_pos
< graph_port_removed_sink_pos
,
964 "event order is good (11)");
970 bt_put(src_def_port
);
971 bt_put(sink_def_port
);
975 void test_src_adds_port_in_port_connected(void)
977 struct bt_component
*src
;
978 struct bt_component
*sink
;
979 struct bt_graph
*graph
;
980 struct bt_port
*src_def_port
;
981 struct bt_port
*sink_def_port
;
982 struct bt_port
*src_hello_port
;
983 struct bt_connection
*conn
;
985 enum bt_graph_status status
;
986 size_t src_accept_port_connection_pos
;
987 size_t sink_accept_port_connection_pos
;
988 size_t src_port_connected_pos
;
989 size_t sink_port_connected_pos
;
990 size_t graph_ports_connected_pos
;
991 size_t graph_port_added_src_pos
;
993 prepare_test(TEST_SRC_ADDS_PORT_IN_PORT_CONNECTED
,
994 "source adds port in port connected");
995 graph
= create_graph();
997 src
= create_src(graph
);
998 sink
= create_sink(graph
);
999 src_def_port
= bt_component_source_get_output_port_by_name(src
, "out");
1000 assert(src_def_port
);
1001 sink_def_port
= bt_component_sink_get_input_port_by_name(sink
, "in");
1002 assert(sink_def_port
);
1003 status
= bt_graph_connect_ports(graph
, src_def_port
, sink_def_port
,
1005 assert(status
== 0);
1006 src_hello_port
= bt_component_source_get_output_port_by_name(src
,
1008 assert(src_hello_port
);
1010 /* We're supposed to have 8 events */
1011 ok(events
->len
== 8, "we have the expected number of events");
1013 /* Source's port added */
1014 event
.type
= GRAPH_PORT_ADDED
;
1015 event
.data
.graph_port_added
.comp
= src
;
1016 event
.data
.graph_port_added
.port
= src_def_port
;
1017 ok(has_event(&event
), "got the expected graph's port added event (for source, initial)");
1019 /* Sink's port added */
1020 event
.type
= GRAPH_PORT_ADDED
;
1021 event
.data
.graph_port_added
.comp
= sink
;
1022 event
.data
.graph_port_added
.port
= sink_def_port
;
1023 ok(has_event(&event
), "got the expected graph's port added event (for sink, initial)");
1025 /* Source's accept port connection */
1026 event
.type
= COMP_ACCEPT_PORT_CONNECTION
;
1027 event
.data
.comp_accept_port_connection
.comp
= src
;
1028 event
.data
.comp_accept_port_connection
.self_port
= src_def_port
;
1029 event
.data
.comp_accept_port_connection
.other_port
= sink_def_port
;
1030 ok(has_event(&event
), "got the expected source's accept port connection event");
1031 src_accept_port_connection_pos
= event_pos(&event
);
1033 /* Sink's accept port connection */
1034 event
.type
= COMP_ACCEPT_PORT_CONNECTION
;
1035 event
.data
.comp_accept_port_connection
.comp
= sink
;
1036 event
.data
.comp_accept_port_connection
.self_port
= sink_def_port
;
1037 event
.data
.comp_accept_port_connection
.other_port
= src_def_port
;
1038 ok(has_event(&event
), "got the expected sink's accept port connection event");
1039 sink_accept_port_connection_pos
= event_pos(&event
);
1041 /* Source's port connected */
1042 event
.type
= COMP_PORT_CONNECTED
;
1043 event
.data
.comp_port_connected
.comp
= src
;
1044 event
.data
.comp_port_connected
.self_port
= src_def_port
;
1045 event
.data
.comp_port_connected
.other_port
= sink_def_port
;
1046 ok(has_event(&event
), "got the expected source's port connected event");
1047 src_port_connected_pos
= event_pos(&event
);
1049 /* Graph's port added (source) */
1050 event
.type
= GRAPH_PORT_ADDED
;
1051 event
.data
.graph_port_added
.comp
= src
;
1052 event
.data
.graph_port_added
.port
= src_hello_port
;
1053 ok(has_event(&event
), "got the expected graph's port added event (for source)");
1054 graph_port_added_src_pos
= event_pos(&event
);
1056 /* Sink's port connected */
1057 event
.type
= COMP_PORT_CONNECTED
;
1058 event
.data
.comp_port_connected
.comp
= sink
;
1059 event
.data
.comp_port_connected
.self_port
= sink_def_port
;
1060 event
.data
.comp_port_connected
.other_port
= src_def_port
;
1061 ok(has_event(&event
), "got the expected sink's port connected event");
1062 sink_port_connected_pos
= event_pos(&event
);
1064 /* Graph's ports connected */
1065 event
.type
= GRAPH_PORTS_CONNECTED
;
1066 event
.data
.graph_ports_connected
.upstream_comp
= src
;
1067 event
.data
.graph_ports_connected
.downstream_comp
= sink
;
1068 event
.data
.graph_ports_connected
.upstream_port
= src_def_port
;
1069 event
.data
.graph_ports_connected
.downstream_port
= sink_def_port
;
1070 event
.data
.graph_ports_connected
.conn
= conn
;
1071 ok(has_event(&event
), "got the expected graph's port connected event (for source)");
1072 graph_ports_connected_pos
= event_pos(&event
);
1074 /* Order of events */
1075 ok(src_port_connected_pos
< graph_ports_connected_pos
,
1076 "event order is good (1)");
1077 ok(sink_port_connected_pos
< graph_ports_connected_pos
,
1078 "event order is good (2)");
1079 ok(src_accept_port_connection_pos
< src_port_connected_pos
,
1080 "event order is good (3)");
1081 ok(sink_accept_port_connection_pos
< sink_port_connected_pos
,
1082 "event order is good (4)");
1083 ok(src_port_connected_pos
< graph_port_added_src_pos
,
1084 "event order is good (5)");
1085 ok(graph_port_added_src_pos
< graph_ports_connected_pos
,
1086 "event order is good (6)");
1092 bt_put(src_def_port
);
1093 bt_put(sink_def_port
);
1094 bt_put(src_hello_port
);
1098 void test_simple(void)
1100 struct bt_component
*src
;
1101 struct bt_component
*sink
;
1102 struct bt_graph
*graph
;
1103 struct bt_port
*src_def_port
;
1104 struct bt_port
*sink_def_port
;
1105 struct bt_connection
*conn
;
1107 enum bt_graph_status status
;
1108 size_t src_accept_port_connection_pos
;
1109 size_t sink_accept_port_connection_pos
;
1110 size_t src_port_connected_pos
;
1111 size_t sink_port_connected_pos
;
1112 size_t graph_ports_connected_pos
;
1114 prepare_test(TEST_SIMPLE
, "simple");
1115 graph
= create_graph();
1117 src
= create_src(graph
);
1118 sink
= create_sink(graph
);
1119 src_def_port
= bt_component_source_get_output_port_by_name(src
, "out");
1120 assert(src_def_port
);
1121 sink_def_port
= bt_component_sink_get_input_port_by_name(sink
, "in");
1122 assert(sink_def_port
);
1123 status
= bt_graph_connect_ports(graph
, src_def_port
, sink_def_port
,
1125 assert(status
== 0);
1127 /* We're supposed to have 7 events */
1128 ok(events
->len
== 7, "we have the expected number of events");
1130 /* Source's port added */
1131 event
.type
= GRAPH_PORT_ADDED
;
1132 event
.data
.graph_port_added
.comp
= src
;
1133 event
.data
.graph_port_added
.port
= src_def_port
;
1134 ok(has_event(&event
), "got the expected graph's port added event (for source, initial)");
1136 /* Sink's port added */
1137 event
.type
= GRAPH_PORT_ADDED
;
1138 event
.data
.graph_port_added
.comp
= sink
;
1139 event
.data
.graph_port_added
.port
= sink_def_port
;
1140 ok(has_event(&event
), "got the expected graph's port added event (for sink, initial)");
1142 /* Source's accept port connection */
1143 event
.type
= COMP_ACCEPT_PORT_CONNECTION
;
1144 event
.data
.comp_accept_port_connection
.comp
= src
;
1145 event
.data
.comp_accept_port_connection
.self_port
= src_def_port
;
1146 event
.data
.comp_accept_port_connection
.other_port
= sink_def_port
;
1147 ok(has_event(&event
), "got the expected source's accept port connection event");
1148 src_accept_port_connection_pos
= event_pos(&event
);
1150 /* Sink's accept port connection */
1151 event
.type
= COMP_ACCEPT_PORT_CONNECTION
;
1152 event
.data
.comp_accept_port_connection
.comp
= sink
;
1153 event
.data
.comp_accept_port_connection
.self_port
= sink_def_port
;
1154 event
.data
.comp_accept_port_connection
.other_port
= src_def_port
;
1155 ok(has_event(&event
), "got the expected sink's accept port connection event");
1156 sink_accept_port_connection_pos
= event_pos(&event
);
1158 /* Source's port connected */
1159 event
.type
= COMP_PORT_CONNECTED
;
1160 event
.data
.comp_port_connected
.comp
= src
;
1161 event
.data
.comp_port_connected
.self_port
= src_def_port
;
1162 event
.data
.comp_port_connected
.other_port
= sink_def_port
;
1163 ok(has_event(&event
), "got the expected source's port connected event");
1164 src_port_connected_pos
= event_pos(&event
);
1166 /* Sink's port connected */
1167 event
.type
= COMP_PORT_CONNECTED
;
1168 event
.data
.comp_port_connected
.comp
= sink
;
1169 event
.data
.comp_port_connected
.self_port
= sink_def_port
;
1170 event
.data
.comp_port_connected
.other_port
= src_def_port
;
1171 ok(has_event(&event
), "got the expected sink's port connected event");
1172 sink_port_connected_pos
= event_pos(&event
);
1174 /* Graph's port connected */
1175 event
.type
= GRAPH_PORTS_CONNECTED
;
1176 event
.data
.graph_ports_connected
.upstream_comp
= src
;
1177 event
.data
.graph_ports_connected
.downstream_comp
= sink
;
1178 event
.data
.graph_ports_connected
.upstream_port
= src_def_port
;
1179 event
.data
.graph_ports_connected
.downstream_port
= sink_def_port
;
1180 event
.data
.graph_ports_connected
.conn
= conn
;
1181 ok(has_event(&event
), "got the expected graph's ports connected event");
1182 graph_ports_connected_pos
= event_pos(&event
);
1184 /* Order of events */
1185 ok(src_port_connected_pos
< graph_ports_connected_pos
,
1186 "event order is good (1)");
1187 ok(sink_port_connected_pos
< graph_ports_connected_pos
,
1188 "event order is good (2)");
1189 ok(src_accept_port_connection_pos
< src_port_connected_pos
,
1190 "event order is good (3)");
1191 ok(sink_accept_port_connection_pos
< sink_port_connected_pos
,
1192 "event order is good (4)");
1198 bt_put(src_def_port
);
1199 bt_put(sink_def_port
);
1203 void test_empty_graph(void)
1205 struct bt_graph
*graph
;
1207 prepare_test(TEST_EMPTY_GRAPH
, "empty graph");
1208 graph
= create_graph();
1209 ok(events
->len
== 0, "empty graph generates no events");
1213 int main(int argc
, char **argv
)
1215 plan_tests(NR_TESTS
);
1219 test_src_adds_port_in_port_connected();
1220 test_sink_removes_port_in_port_connected();
1221 test_sink_removes_port_in_port_connected_then_src_removes_disconnected_port();
1223 return exit_status();