4 * Copyright 2017 - Philippe Proulx <pproulx@efficios.com>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; under version 2 of the License.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 #include <babeltrace/graph/component-class.h>
21 #include <babeltrace/graph/component-class-source.h>
22 #include <babeltrace/graph/component-class-sink.h>
23 #include <babeltrace/graph/component.h>
24 #include <babeltrace/graph/component-source.h>
25 #include <babeltrace/graph/component-sink.h>
26 #include <babeltrace/graph/graph.h>
27 #include <babeltrace/graph/connection.h>
28 #include <babeltrace/graph/port.h>
29 #include <babeltrace/graph/private-component.h>
30 #include <babeltrace/graph/private-component-source.h>
31 #include <babeltrace/graph/private-component-sink.h>
32 #include <babeltrace/graph/private-port.h>
33 #include <babeltrace/graph/private-connection.h>
45 COMP_ACCEPT_PORT_CONNECTION
,
47 COMP_PORT_DISCONNECTED
,
50 GRAPH_PORTS_CONNECTED
,
51 GRAPH_PORTS_DISCONNECTED
,
57 TEST_SRC_ADDS_PORT_IN_PORT_CONNECTED
,
58 TEST_SINK_REMOVES_PORT_IN_CONSUME
,
59 TEST_SINK_REMOVES_PORT_IN_CONSUME_THEN_SRC_REMOVES_DISCONNECTED_PORT
,
67 struct bt_component
*comp
;
68 struct bt_port
*self_port
;
69 struct bt_port
*other_port
;
70 } comp_accept_port_connection
;
73 struct bt_component
*comp
;
74 struct bt_port
*self_port
;
75 struct bt_port
*other_port
;
76 } comp_port_connected
;
79 struct bt_component
*comp
;
81 } comp_port_disconnected
;
84 struct bt_component
*comp
;
89 struct bt_component
*comp
;
94 struct bt_component
*upstream_comp
;
95 struct bt_component
*downstream_comp
;
96 struct bt_port
*upstream_port
;
97 struct bt_port
*downstream_port
;
98 struct bt_connection
*conn
;
99 } graph_ports_connected
;
102 struct bt_component
*upstream_comp
;
103 struct bt_component
*downstream_comp
;
104 struct bt_port
*upstream_port
;
105 struct bt_port
*downstream_port
;
106 } graph_ports_disconnected
;
110 static GArray
*events
;
111 static struct bt_component_class
*src_comp_class
;
112 static struct bt_component_class
*sink_comp_class
;
113 static enum test current_test
;
116 void clear_events(void)
118 g_array_set_size(events
, 0);
122 void append_event(struct event
*event
)
124 g_array_append_val(events
, *event
);
128 bool compare_events(struct event
*ev_a
, struct event
*ev_b
)
130 if (ev_a
->type
!= ev_b
->type
) {
134 switch (ev_a
->type
) {
135 case COMP_ACCEPT_PORT_CONNECTION
:
136 if (ev_a
->data
.comp_accept_port_connection
.comp
!=
137 ev_b
->data
.comp_accept_port_connection
.comp
) {
141 if (ev_a
->data
.comp_accept_port_connection
.self_port
!=
142 ev_b
->data
.comp_accept_port_connection
.self_port
) {
146 if (ev_a
->data
.comp_accept_port_connection
.other_port
!=
147 ev_b
->data
.comp_accept_port_connection
.other_port
) {
151 case COMP_PORT_CONNECTED
:
152 if (ev_a
->data
.comp_port_connected
.comp
!=
153 ev_b
->data
.comp_port_connected
.comp
) {
157 if (ev_a
->data
.comp_port_connected
.self_port
!=
158 ev_b
->data
.comp_port_connected
.self_port
) {
162 if (ev_a
->data
.comp_port_connected
.other_port
!=
163 ev_b
->data
.comp_port_connected
.other_port
) {
167 case COMP_PORT_DISCONNECTED
:
168 if (ev_a
->data
.comp_port_disconnected
.comp
!=
169 ev_b
->data
.comp_port_disconnected
.comp
) {
173 if (ev_a
->data
.comp_port_disconnected
.port
!=
174 ev_b
->data
.comp_port_disconnected
.port
) {
178 case GRAPH_PORT_ADDED
:
179 if (ev_a
->data
.graph_port_added
.comp
!=
180 ev_b
->data
.graph_port_added
.comp
) {
184 if (ev_a
->data
.graph_port_added
.port
!=
185 ev_b
->data
.graph_port_added
.port
) {
189 case GRAPH_PORT_REMOVED
:
190 if (ev_a
->data
.graph_port_removed
.comp
!=
191 ev_b
->data
.graph_port_removed
.comp
) {
195 if (ev_a
->data
.graph_port_removed
.port
!=
196 ev_b
->data
.graph_port_removed
.port
) {
200 case GRAPH_PORTS_CONNECTED
:
201 if (ev_a
->data
.graph_ports_connected
.upstream_comp
!=
202 ev_b
->data
.graph_ports_connected
.upstream_comp
) {
206 if (ev_a
->data
.graph_ports_connected
.downstream_comp
!=
207 ev_b
->data
.graph_ports_connected
.downstream_comp
) {
211 if (ev_a
->data
.graph_ports_connected
.upstream_port
!=
212 ev_b
->data
.graph_ports_connected
.upstream_port
) {
216 if (ev_a
->data
.graph_ports_connected
.downstream_port
!=
217 ev_b
->data
.graph_ports_connected
.downstream_port
) {
221 if (ev_a
->data
.graph_ports_connected
.conn
!=
222 ev_b
->data
.graph_ports_connected
.conn
) {
226 case GRAPH_PORTS_DISCONNECTED
:
227 if (ev_a
->data
.graph_ports_disconnected
.upstream_comp
!=
228 ev_b
->data
.graph_ports_disconnected
.upstream_comp
) {
232 if (ev_a
->data
.graph_ports_disconnected
.downstream_comp
!=
233 ev_b
->data
.graph_ports_disconnected
.downstream_comp
) {
237 if (ev_a
->data
.graph_ports_disconnected
.upstream_port
!=
238 ev_b
->data
.graph_ports_disconnected
.upstream_port
) {
242 if (ev_a
->data
.graph_ports_disconnected
.downstream_port
!=
243 ev_b
->data
.graph_ports_disconnected
.downstream_port
) {
255 bool has_event(struct event
*event
)
259 for (i
= 0; i
< events
->len
; i
++) {
260 struct event
*ev
= &g_array_index(events
, struct event
, i
);
262 if (compare_events(event
, ev
)) {
271 size_t event_pos(struct event
*event
)
275 for (i
= 0; i
< events
->len
; i
++) {
276 struct event
*ev
= &g_array_index(events
, struct event
, i
);
278 if (compare_events(event
, ev
)) {
287 struct bt_notification_iterator_next_return
src_iter_next(
288 struct bt_private_notification_iterator
*priv_iterator
)
290 struct bt_notification_iterator_next_return ret
= {
291 .status
= BT_NOTIFICATION_ITERATOR_STATUS_ERROR
,
298 enum bt_component_status
accept_port_connection(
299 struct bt_private_component
*private_component
,
300 struct bt_private_port
*self_private_port
,
301 struct bt_port
*other_port
)
303 struct event event
= {
304 .type
= COMP_ACCEPT_PORT_CONNECTION
,
305 .data
.comp_accept_port_connection
= {
306 .comp
= bt_component_from_private_component(private_component
),
307 .self_port
= bt_port_from_private_port(self_private_port
),
308 .other_port
= other_port
,
312 bt_put(event
.data
.comp_accept_port_connection
.comp
);
313 bt_put(event
.data
.comp_accept_port_connection
.self_port
);
314 append_event(&event
);
315 return BT_COMPONENT_STATUS_OK
;
319 void src_port_connected(struct bt_private_component
*private_component
,
320 struct bt_private_port
*self_private_port
,
321 struct bt_port
*other_port
)
325 struct event event
= {
326 .type
= COMP_PORT_CONNECTED
,
327 .data
.comp_port_connected
= {
328 .comp
= bt_component_from_private_component(private_component
),
329 .self_port
= bt_port_from_private_port(self_private_port
),
330 .other_port
= other_port
,
334 bt_put(event
.data
.comp_port_connected
.comp
);
335 bt_put(event
.data
.comp_port_connected
.self_port
);
336 append_event(&event
);
338 switch (current_test
) {
339 case TEST_SRC_ADDS_PORT_IN_PORT_CONNECTED
:
340 ret
= bt_private_component_source_add_output_private_port(
341 private_component
, "hello", NULL
, NULL
);
350 void src_port_disconnected(struct bt_private_component
*private_component
,
351 struct bt_private_port
*private_port
)
354 struct event event
= {
355 .type
= COMP_PORT_DISCONNECTED
,
356 .data
.comp_port_disconnected
= {
357 .comp
= bt_component_from_private_component(private_component
),
358 .port
= bt_port_from_private_port(private_port
),
362 bt_put(event
.data
.comp_port_disconnected
.comp
);
363 bt_put(event
.data
.comp_port_disconnected
.port
);
364 append_event(&event
);
366 switch (current_test
) {
367 case TEST_SINK_REMOVES_PORT_IN_CONSUME_THEN_SRC_REMOVES_DISCONNECTED_PORT
:
368 ret
= bt_private_port_remove_from_component(private_port
);
376 enum bt_component_status
src_init(struct bt_private_component
*priv_comp
,
377 struct bt_value
*params
, void *init_method_data
)
381 ret
= bt_private_component_source_add_output_private_port(
382 priv_comp
, "out", NULL
, NULL
);
384 return BT_COMPONENT_STATUS_OK
;
388 enum bt_component_status
sink_consume(
389 struct bt_private_component
*priv_component
)
391 struct bt_private_port
*def_port
;
394 switch (current_test
) {
395 case TEST_SINK_REMOVES_PORT_IN_CONSUME
:
396 case TEST_SINK_REMOVES_PORT_IN_CONSUME_THEN_SRC_REMOVES_DISCONNECTED_PORT
:
397 def_port
= bt_private_component_sink_get_input_private_port_by_name(
398 priv_component
, "in");
400 ret
= bt_private_port_remove_from_component(def_port
);
408 return BT_COMPONENT_STATUS_OK
;
412 void sink_port_connected(struct bt_private_component
*private_component
,
413 struct bt_private_port
*self_private_port
,
414 struct bt_port
*other_port
)
416 struct event event
= {
417 .type
= COMP_PORT_CONNECTED
,
418 .data
.comp_port_connected
= {
419 .comp
= bt_component_from_private_component(private_component
),
420 .self_port
= bt_port_from_private_port(self_private_port
),
421 .other_port
= other_port
,
425 bt_put(event
.data
.comp_port_connected
.comp
);
426 bt_put(event
.data
.comp_port_connected
.self_port
);
427 append_event(&event
);
431 void sink_port_disconnected(struct bt_private_component
*private_component
,
432 struct bt_private_port
*private_port
)
434 struct event event
= {
435 .type
= COMP_PORT_DISCONNECTED
,
436 .data
.comp_port_disconnected
= {
437 .comp
= bt_component_from_private_component(private_component
),
438 .port
= bt_port_from_private_port(private_port
),
442 bt_put(event
.data
.comp_port_disconnected
.comp
);
443 bt_put(event
.data
.comp_port_disconnected
.port
);
444 append_event(&event
);
448 enum bt_component_status
sink_init(struct bt_private_component
*priv_comp
,
449 struct bt_value
*params
, void *init_method_data
)
453 ret
= bt_private_component_sink_add_input_private_port(priv_comp
,
456 return BT_COMPONENT_STATUS_OK
;
460 void graph_port_added(struct bt_port
*port
,
463 struct bt_component
*comp
= bt_port_get_component(port
);
468 struct event event
= {
469 .type
= GRAPH_PORT_ADDED
,
470 .data
.graph_port_added
= {
476 append_event(&event
);
480 void graph_port_removed(struct bt_component
*component
,
481 struct bt_port
*port
, void *data
)
483 struct event event
= {
484 .type
= GRAPH_PORT_REMOVED
,
485 .data
.graph_port_removed
= {
491 append_event(&event
);
495 void graph_ports_connected(struct bt_port
*upstream_port
,
496 struct bt_port
*downstream_port
, void *data
)
498 struct bt_component
*upstream_comp
=
499 bt_port_get_component(upstream_port
);
500 struct bt_component
*downstream_comp
=
501 bt_port_get_component(downstream_port
);
502 struct bt_connection
*conn
= bt_port_get_connection(upstream_port
);
504 assert(upstream_comp
);
505 assert(downstream_comp
);
507 bt_put(upstream_comp
);
508 bt_put(downstream_comp
);
511 struct event event
= {
512 .type
= GRAPH_PORTS_CONNECTED
,
513 .data
.graph_ports_connected
= {
514 .upstream_comp
= upstream_comp
,
515 .downstream_comp
= downstream_comp
,
516 .upstream_port
= upstream_port
,
517 .downstream_port
= downstream_port
,
522 append_event(&event
);
526 void graph_ports_disconnected(
527 struct bt_component
*upstream_comp
,
528 struct bt_component
*downstream_comp
,
529 struct bt_port
*upstream_port
, struct bt_port
*downstream_port
,
532 struct event event
= {
533 .type
= GRAPH_PORTS_DISCONNECTED
,
534 .data
.graph_ports_disconnected
= {
535 .upstream_comp
= upstream_comp
,
536 .downstream_comp
= downstream_comp
,
537 .upstream_port
= upstream_port
,
538 .downstream_port
= downstream_port
,
542 append_event(&event
);
550 src_comp_class
= bt_component_class_source_create("src", src_iter_next
);
551 assert(src_comp_class
);
552 ret
= bt_component_class_set_init_method(src_comp_class
, src_init
);
554 ret
= bt_component_class_set_accept_port_connection_method(
555 src_comp_class
, accept_port_connection
);
557 ret
= bt_component_class_set_port_connected_method(src_comp_class
,
560 ret
= bt_component_class_set_port_disconnected_method(
561 src_comp_class
, src_port_disconnected
);
563 sink_comp_class
= bt_component_class_sink_create("sink", sink_consume
);
564 assert(sink_comp_class
);
565 ret
= bt_component_class_set_init_method(sink_comp_class
, sink_init
);
567 ret
= bt_component_class_set_accept_port_connection_method(
568 sink_comp_class
, accept_port_connection
);
570 ret
= bt_component_class_set_port_connected_method(sink_comp_class
,
571 sink_port_connected
);
573 ret
= bt_component_class_set_port_disconnected_method(sink_comp_class
,
574 sink_port_disconnected
);
576 bt_component_class_freeze(src_comp_class
);
577 bt_component_class_freeze(sink_comp_class
);
578 events
= g_array_new(FALSE
, TRUE
, sizeof(struct event
));
585 bt_put(src_comp_class
);
586 bt_put(sink_comp_class
);
587 g_array_free(events
, TRUE
);
591 struct bt_component
*create_src(struct bt_graph
*graph
)
593 struct bt_component
*comp
;
596 ret
= bt_graph_add_component(graph
, src_comp_class
, "src-comp", NULL
,
603 struct bt_component
*create_sink(struct bt_graph
*graph
)
605 struct bt_component
*comp
;
608 ret
= bt_graph_add_component(graph
, sink_comp_class
, "sink-comp",
615 struct bt_graph
*create_graph(void)
617 struct bt_graph
*graph
= bt_graph_create();
621 ret
= bt_graph_add_port_added_listener(graph
, graph_port_added
, NULL
);
623 ret
= bt_graph_add_port_removed_listener(graph
, graph_port_removed
,
626 ret
= bt_graph_add_ports_connected_listener(graph
, graph_ports_connected
,
629 ret
= bt_graph_add_ports_disconnected_listener(graph
,
630 graph_ports_disconnected
, NULL
);
636 void prepare_test(enum test test
, const char *name
)
640 diag("test: %s", name
);
644 void test_sink_removes_port_in_port_connected_then_src_removes_disconnected_port(void)
647 struct bt_component
*src
;
648 struct bt_component
*sink
;
649 struct bt_graph
*graph
;
650 struct bt_port
*src_def_port
;
651 struct bt_port
*sink_def_port
;
652 struct bt_connection
*conn
;
654 enum bt_graph_status status
;
655 size_t src_accept_port_connection_pos
;
656 size_t sink_accept_port_connection_pos
;
657 size_t src_port_connected_pos
;
658 size_t sink_port_connected_pos
;
659 size_t graph_ports_connected
;
660 size_t src_port_disconnected_pos
;
661 size_t sink_port_disconnected_pos
;
662 size_t graph_ports_disconnected_pos
;
663 size_t graph_port_removed_src_pos
;
664 size_t graph_port_removed_sink_pos
;
666 prepare_test(TEST_SINK_REMOVES_PORT_IN_CONSUME_THEN_SRC_REMOVES_DISCONNECTED_PORT
,
667 "sink removes port in consume, then source removes disconnected port");
668 graph
= create_graph();
670 src
= create_src(graph
);
671 sink
= create_sink(graph
);
672 src_def_port
= bt_component_source_get_output_port_by_name(src
, "out");
673 assert(src_def_port
);
674 sink_def_port
= bt_component_sink_get_input_port_by_name(sink
, "in");
675 assert(sink_def_port
);
676 status
= bt_graph_connect_ports(graph
, src_def_port
, sink_def_port
,
681 /* We're supposed to have 7 events so far */
682 ok(events
->len
== 7, "we have the expected number of events (before consume)");
684 /* Source's port added */
685 event
.type
= GRAPH_PORT_ADDED
;
686 event
.data
.graph_port_added
.comp
= src
;
687 event
.data
.graph_port_added
.port
= src_def_port
;
688 ok(has_event(&event
), "got the expected graph's port added event (for source, initial)");
690 /* Sink's port added */
691 event
.type
= GRAPH_PORT_ADDED
;
692 event
.data
.graph_port_added
.comp
= sink
;
693 event
.data
.graph_port_added
.port
= sink_def_port
;
694 ok(has_event(&event
), "got the expected graph's port added event (for sink, initial)");
696 /* Source's accept port connection */
697 event
.type
= COMP_ACCEPT_PORT_CONNECTION
;
698 event
.data
.comp_accept_port_connection
.comp
= src
;
699 event
.data
.comp_accept_port_connection
.self_port
= src_def_port
;
700 event
.data
.comp_accept_port_connection
.other_port
= sink_def_port
;
701 ok(has_event(&event
), "got the expected source's accept port connection event");
702 src_accept_port_connection_pos
= event_pos(&event
);
704 /* Sink's accept port connection */
705 event
.type
= COMP_ACCEPT_PORT_CONNECTION
;
706 event
.data
.comp_accept_port_connection
.comp
= sink
;
707 event
.data
.comp_accept_port_connection
.self_port
= sink_def_port
;
708 event
.data
.comp_accept_port_connection
.other_port
= src_def_port
;
709 ok(has_event(&event
), "got the expected sink's accept port connection event");
710 sink_accept_port_connection_pos
= event_pos(&event
);
712 /* Source's port connected */
713 event
.type
= COMP_PORT_CONNECTED
;
714 event
.data
.comp_port_connected
.comp
= src
;
715 event
.data
.comp_port_connected
.self_port
= src_def_port
;
716 event
.data
.comp_port_connected
.other_port
= sink_def_port
;
717 ok(has_event(&event
), "got the expected source's port connected event");
718 src_port_connected_pos
= event_pos(&event
);
720 /* Sink's port connected */
721 event
.type
= COMP_PORT_CONNECTED
;
722 event
.data
.comp_port_connected
.comp
= sink
;
723 event
.data
.comp_port_connected
.self_port
= sink_def_port
;
724 event
.data
.comp_port_connected
.other_port
= src_def_port
;
725 ok(has_event(&event
), "got the expected sink's port connected event");
726 sink_port_connected_pos
= event_pos(&event
);
728 /* Graph's ports connected */
729 event
.type
= GRAPH_PORTS_CONNECTED
;
730 event
.data
.graph_ports_connected
.upstream_comp
= src
;
731 event
.data
.graph_ports_connected
.downstream_comp
= sink
;
732 event
.data
.graph_ports_connected
.upstream_port
= src_def_port
;
733 event
.data
.graph_ports_connected
.downstream_port
= sink_def_port
;
734 event
.data
.graph_ports_connected
.conn
= conn
;
735 ok(has_event(&event
), "got the expected graph's ports connected event");
736 graph_ports_connected
= event_pos(&event
);
738 /* Order of events */
739 ok(src_port_connected_pos
< graph_ports_connected
,
740 "event order is good (1)");
741 ok(sink_port_connected_pos
< graph_ports_connected
,
742 "event order is good (2)");
743 ok(src_accept_port_connection_pos
< src_port_connected_pos
,
744 "event order is good (3)");
745 ok(sink_accept_port_connection_pos
< sink_port_connected_pos
,
746 "event order is good (4)");
748 /* Consume sink once */
750 ret
= bt_graph_consume(graph
);
753 /* We're supposed to have 5 new events */
754 ok(events
->len
== 5, "we have the expected number of events (after consume)");
756 /* Source's port disconnected */
757 event
.type
= COMP_PORT_DISCONNECTED
;
758 event
.data
.comp_port_disconnected
.comp
= src
;
759 event
.data
.comp_port_disconnected
.port
= src_def_port
;
760 ok(has_event(&event
), "got the expected source's port disconnected event");
761 src_port_disconnected_pos
= event_pos(&event
);
763 /* Sink's port disconnected */
764 event
.type
= COMP_PORT_DISCONNECTED
;
765 event
.data
.comp_port_disconnected
.comp
= sink
;
766 event
.data
.comp_port_disconnected
.port
= sink_def_port
;
767 ok(has_event(&event
), "got the expected sink's port disconnected event");
768 sink_port_disconnected_pos
= event_pos(&event
);
770 /* Graph's ports disconnected */
771 event
.type
= GRAPH_PORTS_DISCONNECTED
;
772 event
.data
.graph_ports_disconnected
.upstream_comp
= src
;
773 event
.data
.graph_ports_disconnected
.downstream_comp
= sink
;
774 event
.data
.graph_ports_disconnected
.upstream_port
= src_def_port
;
775 event
.data
.graph_ports_disconnected
.downstream_port
= sink_def_port
;
776 ok(has_event(&event
), "got the expected graph's ports disconnected event");
777 graph_ports_disconnected_pos
= event_pos(&event
);
779 /* Graph's port removed (sink) */
780 event
.type
= GRAPH_PORT_REMOVED
;
781 event
.data
.graph_port_removed
.comp
= sink
;
782 event
.data
.graph_port_removed
.port
= sink_def_port
;
783 ok(has_event(&event
), "got the expected graph's port removed event (for sink)");
784 graph_port_removed_sink_pos
= event_pos(&event
);
786 /* Graph's port removed (source) */
787 event
.type
= GRAPH_PORT_REMOVED
;
788 event
.data
.graph_port_removed
.comp
= src
;
789 event
.data
.graph_port_removed
.port
= src_def_port
;
790 ok(has_event(&event
), "got the expected graph's port removed event (for source)");
791 graph_port_removed_src_pos
= event_pos(&event
);
793 /* Order of events */
794 ok(src_port_disconnected_pos
< graph_ports_disconnected_pos
,
795 "event order is good (5)");
796 ok(src_port_disconnected_pos
< graph_port_removed_sink_pos
,
797 "event order is good (6)");
798 ok(src_port_disconnected_pos
< graph_port_removed_src_pos
,
799 "event order is good (7)");
800 ok(sink_port_disconnected_pos
< graph_ports_disconnected_pos
,
801 "event order is good (8)");
802 ok(sink_port_disconnected_pos
< graph_port_removed_sink_pos
,
803 "event order is good (9)");
804 ok(sink_port_disconnected_pos
< graph_port_removed_src_pos
,
805 "event order is good (10)");
806 ok(graph_ports_disconnected_pos
< graph_port_removed_sink_pos
,
807 "event order is good (11)");
808 ok(graph_port_removed_src_pos
< graph_ports_disconnected_pos
,
809 "event order is good (12)");
810 ok(graph_port_removed_src_pos
< graph_port_removed_sink_pos
,
811 "event order is good (13)");
817 bt_put(src_def_port
);
818 bt_put(sink_def_port
);
822 void test_sink_removes_port_in_port_connected(void)
825 struct bt_component
*src
;
826 struct bt_component
*sink
;
827 struct bt_graph
*graph
;
828 struct bt_port
*src_def_port
;
829 struct bt_port
*sink_def_port
;
830 struct bt_connection
*conn
;
832 enum bt_graph_status status
;
833 size_t src_accept_port_connection_pos
;
834 size_t sink_accept_port_connection_pos
;
835 size_t src_port_connected_pos
;
836 size_t sink_port_connected_pos
;
837 size_t graph_ports_connected_pos
;
838 size_t src_port_disconnected_pos
;
839 size_t sink_port_disconnected_pos
;
840 size_t graph_ports_disconnected_pos
;
841 size_t graph_port_removed_sink_pos
;
843 prepare_test(TEST_SINK_REMOVES_PORT_IN_CONSUME
,
844 "sink removes port in consume");
845 graph
= create_graph();
847 src
= create_src(graph
);
848 sink
= create_sink(graph
);
849 src_def_port
= bt_component_source_get_output_port_by_name(src
, "out");
850 assert(src_def_port
);
851 sink_def_port
= bt_component_sink_get_input_port_by_name(sink
, "in");
852 assert(sink_def_port
);
853 status
= bt_graph_connect_ports(graph
, src_def_port
, sink_def_port
,
857 /* We're supposed to have 7 events so far */
858 ok(events
->len
== 7, "we have the expected number of events (before consume)");
860 /* Source's port added */
861 event
.type
= GRAPH_PORT_ADDED
;
862 event
.data
.graph_port_added
.comp
= src
;
863 event
.data
.graph_port_added
.port
= src_def_port
;
864 ok(has_event(&event
), "got the expected graph's port added event (for source, initial)");
866 /* Sink's port added */
867 event
.type
= GRAPH_PORT_ADDED
;
868 event
.data
.graph_port_added
.comp
= sink
;
869 event
.data
.graph_port_added
.port
= sink_def_port
;
870 ok(has_event(&event
), "got the expected graph's port added event (for sink, initial)");
872 /* Source's accept port connection */
873 event
.type
= COMP_ACCEPT_PORT_CONNECTION
;
874 event
.data
.comp_accept_port_connection
.comp
= src
;
875 event
.data
.comp_accept_port_connection
.self_port
= src_def_port
;
876 event
.data
.comp_accept_port_connection
.other_port
= sink_def_port
;
877 ok(has_event(&event
), "got the expected source's accept port connection event");
878 src_accept_port_connection_pos
= event_pos(&event
);
880 /* Sink's accept port connection */
881 event
.type
= COMP_ACCEPT_PORT_CONNECTION
;
882 event
.data
.comp_accept_port_connection
.comp
= sink
;
883 event
.data
.comp_accept_port_connection
.self_port
= sink_def_port
;
884 event
.data
.comp_accept_port_connection
.other_port
= src_def_port
;
885 ok(has_event(&event
), "got the expected sink's accept port connection event");
886 sink_accept_port_connection_pos
= event_pos(&event
);
888 /* Source's port connected */
889 event
.type
= COMP_PORT_CONNECTED
;
890 event
.data
.comp_port_connected
.comp
= src
;
891 event
.data
.comp_port_connected
.self_port
= src_def_port
;
892 event
.data
.comp_port_connected
.other_port
= sink_def_port
;
893 ok(has_event(&event
), "got the expected source's port connected event");
894 src_port_connected_pos
= event_pos(&event
);
896 /* Sink's port connected */
897 event
.type
= COMP_PORT_CONNECTED
;
898 event
.data
.comp_port_connected
.comp
= sink
;
899 event
.data
.comp_port_connected
.self_port
= sink_def_port
;
900 event
.data
.comp_port_connected
.other_port
= src_def_port
;
901 ok(has_event(&event
), "got the expected sink's port connected event");
902 sink_port_connected_pos
= event_pos(&event
);
904 /* Graph's ports connected */
905 event
.type
= GRAPH_PORTS_CONNECTED
;
906 event
.data
.graph_ports_connected
.upstream_comp
= src
;
907 event
.data
.graph_ports_connected
.downstream_comp
= sink
;
908 event
.data
.graph_ports_connected
.upstream_port
= src_def_port
;
909 event
.data
.graph_ports_connected
.downstream_port
= sink_def_port
;
910 event
.data
.graph_ports_connected
.conn
= conn
;
911 ok(has_event(&event
), "got the expected graph's ports connected event");
912 graph_ports_connected_pos
= event_pos(&event
);
914 /* Order of events */
915 ok(src_port_connected_pos
< graph_ports_connected_pos
,
916 "event order is good (1)");
917 ok(sink_port_connected_pos
< graph_ports_connected_pos
,
918 "event order is good (2)");
919 ok(src_accept_port_connection_pos
< src_port_connected_pos
,
920 "event order is good (3)");
921 ok(sink_accept_port_connection_pos
< sink_port_connected_pos
,
922 "event order is good (4)");
924 /* Consume sink once */
926 ret
= bt_graph_consume(graph
);
929 /* We're supposed to have 4 new events */
930 ok(events
->len
== 4, "we have the expected number of events (after consume)");
932 /* Source's port disconnected */
933 event
.type
= COMP_PORT_DISCONNECTED
;
934 event
.data
.comp_port_disconnected
.comp
= src
;
935 event
.data
.comp_port_disconnected
.port
= src_def_port
;
936 ok(has_event(&event
), "got the expected source's port disconnected event");
937 src_port_disconnected_pos
= event_pos(&event
);
939 /* Sink's port disconnected */
940 event
.type
= COMP_PORT_DISCONNECTED
;
941 event
.data
.comp_port_disconnected
.comp
= sink
;
942 event
.data
.comp_port_disconnected
.port
= sink_def_port
;
943 ok(has_event(&event
), "got the expected sink's port disconnected event");
944 sink_port_disconnected_pos
= event_pos(&event
);
946 /* Graph's ports disconnected */
947 event
.type
= GRAPH_PORTS_DISCONNECTED
;
948 event
.data
.graph_ports_disconnected
.upstream_comp
= src
;
949 event
.data
.graph_ports_disconnected
.downstream_comp
= sink
;
950 event
.data
.graph_ports_disconnected
.upstream_port
= src_def_port
;
951 event
.data
.graph_ports_disconnected
.downstream_port
= sink_def_port
;
952 ok(has_event(&event
), "got the expected graph's ports disconnected event");
953 graph_ports_disconnected_pos
= event_pos(&event
);
955 /* Graph's port removed (sink) */
956 event
.type
= GRAPH_PORT_REMOVED
;
957 event
.data
.graph_port_removed
.comp
= sink
;
958 event
.data
.graph_port_removed
.port
= sink_def_port
;
959 ok(has_event(&event
), "got the expected graph's port removed event (for sink)");
960 graph_port_removed_sink_pos
= event_pos(&event
);
962 /* Order of events */
963 ok(src_port_disconnected_pos
< graph_ports_disconnected_pos
,
964 "event order is good (5)");
965 ok(src_port_disconnected_pos
< graph_port_removed_sink_pos
,
966 "event order is good (7)");
967 ok(sink_port_disconnected_pos
< graph_ports_disconnected_pos
,
968 "event order is good (8)");
969 ok(sink_port_disconnected_pos
< graph_port_removed_sink_pos
,
970 "event order is good (10)");
971 ok(graph_ports_disconnected_pos
< graph_port_removed_sink_pos
,
972 "event order is good (11)");
978 bt_put(src_def_port
);
979 bt_put(sink_def_port
);
983 void test_src_adds_port_in_port_connected(void)
985 struct bt_component
*src
;
986 struct bt_component
*sink
;
987 struct bt_graph
*graph
;
988 struct bt_port
*src_def_port
;
989 struct bt_port
*sink_def_port
;
990 struct bt_port
*src_hello_port
;
991 struct bt_connection
*conn
;
993 enum bt_graph_status status
;
994 size_t src_accept_port_connection_pos
;
995 size_t sink_accept_port_connection_pos
;
996 size_t src_port_connected_pos
;
997 size_t sink_port_connected_pos
;
998 size_t graph_ports_connected_pos
;
999 size_t graph_port_added_src_pos
;
1001 prepare_test(TEST_SRC_ADDS_PORT_IN_PORT_CONNECTED
,
1002 "source adds port in port connected");
1003 graph
= create_graph();
1005 src
= create_src(graph
);
1006 sink
= create_sink(graph
);
1007 src_def_port
= bt_component_source_get_output_port_by_name(src
, "out");
1008 assert(src_def_port
);
1009 sink_def_port
= bt_component_sink_get_input_port_by_name(sink
, "in");
1010 assert(sink_def_port
);
1011 status
= bt_graph_connect_ports(graph
, src_def_port
, sink_def_port
,
1013 assert(status
== 0);
1014 src_hello_port
= bt_component_source_get_output_port_by_name(src
,
1016 assert(src_hello_port
);
1018 /* We're supposed to have 8 events */
1019 ok(events
->len
== 8, "we have the expected number of events");
1021 /* Source's port added */
1022 event
.type
= GRAPH_PORT_ADDED
;
1023 event
.data
.graph_port_added
.comp
= src
;
1024 event
.data
.graph_port_added
.port
= src_def_port
;
1025 ok(has_event(&event
), "got the expected graph's port added event (for source, initial)");
1027 /* Sink's port added */
1028 event
.type
= GRAPH_PORT_ADDED
;
1029 event
.data
.graph_port_added
.comp
= sink
;
1030 event
.data
.graph_port_added
.port
= sink_def_port
;
1031 ok(has_event(&event
), "got the expected graph's port added event (for sink, initial)");
1033 /* Source's accept port connection */
1034 event
.type
= COMP_ACCEPT_PORT_CONNECTION
;
1035 event
.data
.comp_accept_port_connection
.comp
= src
;
1036 event
.data
.comp_accept_port_connection
.self_port
= src_def_port
;
1037 event
.data
.comp_accept_port_connection
.other_port
= sink_def_port
;
1038 ok(has_event(&event
), "got the expected source's accept port connection event");
1039 src_accept_port_connection_pos
= event_pos(&event
);
1041 /* Sink's accept port connection */
1042 event
.type
= COMP_ACCEPT_PORT_CONNECTION
;
1043 event
.data
.comp_accept_port_connection
.comp
= sink
;
1044 event
.data
.comp_accept_port_connection
.self_port
= sink_def_port
;
1045 event
.data
.comp_accept_port_connection
.other_port
= src_def_port
;
1046 ok(has_event(&event
), "got the expected sink's accept port connection event");
1047 sink_accept_port_connection_pos
= event_pos(&event
);
1049 /* Source's port connected */
1050 event
.type
= COMP_PORT_CONNECTED
;
1051 event
.data
.comp_port_connected
.comp
= src
;
1052 event
.data
.comp_port_connected
.self_port
= src_def_port
;
1053 event
.data
.comp_port_connected
.other_port
= sink_def_port
;
1054 ok(has_event(&event
), "got the expected source's port connected event");
1055 src_port_connected_pos
= event_pos(&event
);
1057 /* Graph's port added (source) */
1058 event
.type
= GRAPH_PORT_ADDED
;
1059 event
.data
.graph_port_added
.comp
= src
;
1060 event
.data
.graph_port_added
.port
= src_hello_port
;
1061 ok(has_event(&event
), "got the expected graph's port added event (for source)");
1062 graph_port_added_src_pos
= event_pos(&event
);
1064 /* Sink's port connected */
1065 event
.type
= COMP_PORT_CONNECTED
;
1066 event
.data
.comp_port_connected
.comp
= sink
;
1067 event
.data
.comp_port_connected
.self_port
= sink_def_port
;
1068 event
.data
.comp_port_connected
.other_port
= src_def_port
;
1069 ok(has_event(&event
), "got the expected sink's port connected event");
1070 sink_port_connected_pos
= event_pos(&event
);
1072 /* Graph's ports connected */
1073 event
.type
= GRAPH_PORTS_CONNECTED
;
1074 event
.data
.graph_ports_connected
.upstream_comp
= src
;
1075 event
.data
.graph_ports_connected
.downstream_comp
= sink
;
1076 event
.data
.graph_ports_connected
.upstream_port
= src_def_port
;
1077 event
.data
.graph_ports_connected
.downstream_port
= sink_def_port
;
1078 event
.data
.graph_ports_connected
.conn
= conn
;
1079 ok(has_event(&event
), "got the expected graph's port connected event (for source)");
1080 graph_ports_connected_pos
= event_pos(&event
);
1082 /* Order of events */
1083 ok(src_port_connected_pos
< graph_ports_connected_pos
,
1084 "event order is good (1)");
1085 ok(sink_port_connected_pos
< graph_ports_connected_pos
,
1086 "event order is good (2)");
1087 ok(src_accept_port_connection_pos
< src_port_connected_pos
,
1088 "event order is good (3)");
1089 ok(sink_accept_port_connection_pos
< sink_port_connected_pos
,
1090 "event order is good (4)");
1091 ok(src_port_connected_pos
< graph_port_added_src_pos
,
1092 "event order is good (5)");
1093 ok(graph_port_added_src_pos
< graph_ports_connected_pos
,
1094 "event order is good (6)");
1100 bt_put(src_def_port
);
1101 bt_put(sink_def_port
);
1102 bt_put(src_hello_port
);
1106 void test_simple(void)
1108 struct bt_component
*src
;
1109 struct bt_component
*sink
;
1110 struct bt_graph
*graph
;
1111 struct bt_port
*src_def_port
;
1112 struct bt_port
*sink_def_port
;
1113 struct bt_connection
*conn
;
1115 enum bt_graph_status status
;
1116 size_t src_accept_port_connection_pos
;
1117 size_t sink_accept_port_connection_pos
;
1118 size_t src_port_connected_pos
;
1119 size_t sink_port_connected_pos
;
1120 size_t graph_ports_connected_pos
;
1122 prepare_test(TEST_SIMPLE
, "simple");
1123 graph
= create_graph();
1125 src
= create_src(graph
);
1126 sink
= create_sink(graph
);
1127 src_def_port
= bt_component_source_get_output_port_by_name(src
, "out");
1128 assert(src_def_port
);
1129 sink_def_port
= bt_component_sink_get_input_port_by_name(sink
, "in");
1130 assert(sink_def_port
);
1131 status
= bt_graph_connect_ports(graph
, src_def_port
, sink_def_port
,
1133 assert(status
== 0);
1135 /* We're supposed to have 7 events */
1136 ok(events
->len
== 7, "we have the expected number of events");
1138 /* Source's port added */
1139 event
.type
= GRAPH_PORT_ADDED
;
1140 event
.data
.graph_port_added
.comp
= src
;
1141 event
.data
.graph_port_added
.port
= src_def_port
;
1142 ok(has_event(&event
), "got the expected graph's port added event (for source, initial)");
1144 /* Sink's port added */
1145 event
.type
= GRAPH_PORT_ADDED
;
1146 event
.data
.graph_port_added
.comp
= sink
;
1147 event
.data
.graph_port_added
.port
= sink_def_port
;
1148 ok(has_event(&event
), "got the expected graph's port added event (for sink, initial)");
1150 /* Source's accept port connection */
1151 event
.type
= COMP_ACCEPT_PORT_CONNECTION
;
1152 event
.data
.comp_accept_port_connection
.comp
= src
;
1153 event
.data
.comp_accept_port_connection
.self_port
= src_def_port
;
1154 event
.data
.comp_accept_port_connection
.other_port
= sink_def_port
;
1155 ok(has_event(&event
), "got the expected source's accept port connection event");
1156 src_accept_port_connection_pos
= event_pos(&event
);
1158 /* Sink's accept port connection */
1159 event
.type
= COMP_ACCEPT_PORT_CONNECTION
;
1160 event
.data
.comp_accept_port_connection
.comp
= sink
;
1161 event
.data
.comp_accept_port_connection
.self_port
= sink_def_port
;
1162 event
.data
.comp_accept_port_connection
.other_port
= src_def_port
;
1163 ok(has_event(&event
), "got the expected sink's accept port connection event");
1164 sink_accept_port_connection_pos
= event_pos(&event
);
1166 /* Source's port connected */
1167 event
.type
= COMP_PORT_CONNECTED
;
1168 event
.data
.comp_port_connected
.comp
= src
;
1169 event
.data
.comp_port_connected
.self_port
= src_def_port
;
1170 event
.data
.comp_port_connected
.other_port
= sink_def_port
;
1171 ok(has_event(&event
), "got the expected source's port connected event");
1172 src_port_connected_pos
= event_pos(&event
);
1174 /* Sink's port connected */
1175 event
.type
= COMP_PORT_CONNECTED
;
1176 event
.data
.comp_port_connected
.comp
= sink
;
1177 event
.data
.comp_port_connected
.self_port
= sink_def_port
;
1178 event
.data
.comp_port_connected
.other_port
= src_def_port
;
1179 ok(has_event(&event
), "got the expected sink's port connected event");
1180 sink_port_connected_pos
= event_pos(&event
);
1182 /* Graph's port connected */
1183 event
.type
= GRAPH_PORTS_CONNECTED
;
1184 event
.data
.graph_ports_connected
.upstream_comp
= src
;
1185 event
.data
.graph_ports_connected
.downstream_comp
= sink
;
1186 event
.data
.graph_ports_connected
.upstream_port
= src_def_port
;
1187 event
.data
.graph_ports_connected
.downstream_port
= sink_def_port
;
1188 event
.data
.graph_ports_connected
.conn
= conn
;
1189 ok(has_event(&event
), "got the expected graph's ports connected event");
1190 graph_ports_connected_pos
= event_pos(&event
);
1192 /* Order of events */
1193 ok(src_port_connected_pos
< graph_ports_connected_pos
,
1194 "event order is good (1)");
1195 ok(sink_port_connected_pos
< graph_ports_connected_pos
,
1196 "event order is good (2)");
1197 ok(src_accept_port_connection_pos
< src_port_connected_pos
,
1198 "event order is good (3)");
1199 ok(sink_accept_port_connection_pos
< sink_port_connected_pos
,
1200 "event order is good (4)");
1206 bt_put(src_def_port
);
1207 bt_put(sink_def_port
);
1211 void test_empty_graph(void)
1213 struct bt_graph
*graph
;
1215 prepare_test(TEST_EMPTY_GRAPH
, "empty graph");
1216 graph
= create_graph();
1217 ok(events
->len
== 0, "empty graph generates no events");
1221 int main(int argc
, char **argv
)
1223 plan_tests(NR_TESTS
);
1227 test_src_adds_port_in_port_connected();
1228 test_sink_removes_port_in_port_connected();
1229 test_sink_removes_port_in_port_connected_then_src_removes_disconnected_port();
1231 return exit_status();