6b1976d16e2e2ca6a33ec6469e71128e1b97e74d
[babeltrace.git] / tests / lib / test_graph_topo.c
1 /*
2 * test_graph_topo.c
3 *
4 * Copyright 2017 - Philippe Proulx <pproulx@efficios.com>
5 *
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.
9 *
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.
14 *
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.
18 */
19
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>
34 #include <stdlib.h>
35 #include <string.h>
36 #include <stdbool.h>
37 #include <assert.h>
38 #include <glib.h>
39
40 #include "tap/tap.h"
41
42 #define NR_TESTS 69
43
44 enum event_type {
45 COMP_ACCEPT_PORT_CONNECTION,
46 COMP_PORT_CONNECTED,
47 COMP_PORT_DISCONNECTED,
48 GRAPH_PORT_ADDED,
49 GRAPH_PORT_REMOVED,
50 GRAPH_PORTS_CONNECTED,
51 GRAPH_PORTS_DISCONNECTED,
52 };
53
54 enum test {
55 TEST_EMPTY_GRAPH,
56 TEST_SIMPLE,
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,
60 };
61
62 struct event {
63 enum event_type type;
64
65 union {
66 struct {
67 struct bt_component *comp;
68 struct bt_port *self_port;
69 struct bt_port *other_port;
70 } comp_accept_port_connection;
71
72 struct {
73 struct bt_component *comp;
74 struct bt_port *self_port;
75 struct bt_port *other_port;
76 } comp_port_connected;
77
78 struct {
79 struct bt_component *comp;
80 struct bt_port *port;
81 } comp_port_disconnected;
82
83 struct {
84 struct bt_component *comp;
85 struct bt_port *port;
86 } graph_port_added;
87
88 struct {
89 struct bt_component *comp;
90 struct bt_port *port;
91 } graph_port_removed;
92
93 struct {
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;
100
101 struct {
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;
107 } data;
108 };
109
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;
114
115 static
116 void clear_events(void)
117 {
118 g_array_set_size(events, 0);
119 }
120
121 static
122 void append_event(struct event *event)
123 {
124 g_array_append_val(events, *event);
125 }
126
127 static
128 bool compare_events(struct event *ev_a, struct event *ev_b)
129 {
130 if (ev_a->type != ev_b->type) {
131 return false;
132 }
133
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) {
138 return false;
139 }
140
141 if (ev_a->data.comp_accept_port_connection.self_port !=
142 ev_b->data.comp_accept_port_connection.self_port) {
143 return false;
144 }
145
146 if (ev_a->data.comp_accept_port_connection.other_port !=
147 ev_b->data.comp_accept_port_connection.other_port) {
148 return false;
149 }
150 break;
151 case COMP_PORT_CONNECTED:
152 if (ev_a->data.comp_port_connected.comp !=
153 ev_b->data.comp_port_connected.comp) {
154 return false;
155 }
156
157 if (ev_a->data.comp_port_connected.self_port !=
158 ev_b->data.comp_port_connected.self_port) {
159 return false;
160 }
161
162 if (ev_a->data.comp_port_connected.other_port !=
163 ev_b->data.comp_port_connected.other_port) {
164 return false;
165 }
166 break;
167 case COMP_PORT_DISCONNECTED:
168 if (ev_a->data.comp_port_disconnected.comp !=
169 ev_b->data.comp_port_disconnected.comp) {
170 return false;
171 }
172
173 if (ev_a->data.comp_port_disconnected.port !=
174 ev_b->data.comp_port_disconnected.port) {
175 return false;
176 }
177 break;
178 case GRAPH_PORT_ADDED:
179 if (ev_a->data.graph_port_added.comp !=
180 ev_b->data.graph_port_added.comp) {
181 return false;
182 }
183
184 if (ev_a->data.graph_port_added.port !=
185 ev_b->data.graph_port_added.port) {
186 return false;
187 }
188 break;
189 case GRAPH_PORT_REMOVED:
190 if (ev_a->data.graph_port_removed.comp !=
191 ev_b->data.graph_port_removed.comp) {
192 return false;
193 }
194
195 if (ev_a->data.graph_port_removed.port !=
196 ev_b->data.graph_port_removed.port) {
197 return false;
198 }
199 break;
200 case GRAPH_PORTS_CONNECTED:
201 if (ev_a->data.graph_ports_connected.upstream_comp !=
202 ev_b->data.graph_ports_connected.upstream_comp) {
203 return false;
204 }
205
206 if (ev_a->data.graph_ports_connected.downstream_comp !=
207 ev_b->data.graph_ports_connected.downstream_comp) {
208 return false;
209 }
210
211 if (ev_a->data.graph_ports_connected.upstream_port !=
212 ev_b->data.graph_ports_connected.upstream_port) {
213 return false;
214 }
215
216 if (ev_a->data.graph_ports_connected.downstream_port !=
217 ev_b->data.graph_ports_connected.downstream_port) {
218 return false;
219 }
220
221 if (ev_a->data.graph_ports_connected.conn !=
222 ev_b->data.graph_ports_connected.conn) {
223 return false;
224 }
225 break;
226 case GRAPH_PORTS_DISCONNECTED:
227 if (ev_a->data.graph_ports_disconnected.upstream_comp !=
228 ev_b->data.graph_ports_disconnected.upstream_comp) {
229 return false;
230 }
231
232 if (ev_a->data.graph_ports_disconnected.downstream_comp !=
233 ev_b->data.graph_ports_disconnected.downstream_comp) {
234 return false;
235 }
236
237 if (ev_a->data.graph_ports_disconnected.upstream_port !=
238 ev_b->data.graph_ports_disconnected.upstream_port) {
239 return false;
240 }
241
242 if (ev_a->data.graph_ports_disconnected.downstream_port !=
243 ev_b->data.graph_ports_disconnected.downstream_port) {
244 return false;
245 }
246 break;
247 default:
248 abort();
249 }
250
251 return true;
252 }
253
254 static
255 bool has_event(struct event *event)
256 {
257 size_t i;
258
259 for (i = 0; i < events->len; i++) {
260 struct event *ev = &g_array_index(events, struct event, i);
261
262 if (compare_events(event, ev)) {
263 return true;
264 }
265 }
266
267 return false;
268 }
269
270 static
271 size_t event_pos(struct event *event)
272 {
273 size_t i;
274
275 for (i = 0; i < events->len; i++) {
276 struct event *ev = &g_array_index(events, struct event, i);
277
278 if (compare_events(event, ev)) {
279 return i;
280 }
281 }
282
283 return -1ULL;
284 }
285
286 static
287 struct bt_notification_iterator_next_return src_iter_next(
288 struct bt_private_notification_iterator *priv_iterator)
289 {
290 struct bt_notification_iterator_next_return ret = {
291 .status = BT_NOTIFICATION_ITERATOR_STATUS_ERROR,
292 };
293
294 return ret;
295 }
296
297 static
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)
302 {
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,
309 },
310 };
311
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;
316 }
317
318 static
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)
322 {
323 struct bt_private_port *port;
324
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,
331 },
332 };
333
334 bt_put(event.data.comp_port_connected.comp);
335 bt_put(event.data.comp_port_connected.self_port);
336 append_event(&event);
337
338 switch (current_test) {
339 case TEST_SRC_ADDS_PORT_IN_PORT_CONNECTED:
340 port = bt_private_component_source_add_output_private_port(
341 private_component, "hello", NULL);
342 assert(port);
343 bt_put(port);
344 break;
345 default:
346 break;
347 }
348 }
349
350 static
351 void src_port_disconnected(struct bt_private_component *private_component,
352 struct bt_private_port *private_port)
353 {
354 int ret;
355 struct event event = {
356 .type = COMP_PORT_DISCONNECTED,
357 .data.comp_port_disconnected = {
358 .comp = bt_component_from_private_component(private_component),
359 .port = bt_port_from_private_port(private_port),
360 },
361 };
362
363 bt_put(event.data.comp_port_disconnected.comp);
364 bt_put(event.data.comp_port_disconnected.port);
365 append_event(&event);
366
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);
370 assert(ret == 0);
371 default:
372 break;
373 }
374 }
375
376 static
377 enum bt_component_status src_init(struct bt_private_component *priv_comp,
378 struct bt_value *params, void *init_method_data)
379 {
380 void *priv_port;
381
382 priv_port = bt_private_component_source_add_output_private_port(
383 priv_comp, "out", NULL);
384 assert(priv_port);
385 bt_put(priv_port);
386 return BT_COMPONENT_STATUS_OK;
387 }
388
389 static
390 enum bt_component_status sink_consume(
391 struct bt_private_component *priv_component)
392 {
393 struct bt_private_port *def_port;
394 int ret;
395
396 switch (current_test) {
397 case TEST_SINK_REMOVES_PORT_IN_CONSUME:
398 case TEST_SINK_REMOVES_PORT_IN_CONSUME_THEN_SRC_REMOVES_DISCONNECTED_PORT:
399 def_port = bt_private_component_sink_get_input_private_port_by_name(
400 priv_component, "in");
401 assert(def_port);
402 ret = bt_private_port_remove_from_component(def_port);
403 assert(ret == 0);
404 bt_put(def_port);
405 break;
406 default:
407 break;
408 }
409
410 return BT_COMPONENT_STATUS_OK;
411 }
412
413 static
414 void sink_port_connected(struct bt_private_component *private_component,
415 struct bt_private_port *self_private_port,
416 struct bt_port *other_port)
417 {
418 struct event event = {
419 .type = COMP_PORT_CONNECTED,
420 .data.comp_port_connected = {
421 .comp = bt_component_from_private_component(private_component),
422 .self_port = bt_port_from_private_port(self_private_port),
423 .other_port = other_port,
424 },
425 };
426
427 bt_put(event.data.comp_port_connected.comp);
428 bt_put(event.data.comp_port_connected.self_port);
429 append_event(&event);
430 }
431
432 static
433 void sink_port_disconnected(struct bt_private_component *private_component,
434 struct bt_private_port *private_port)
435 {
436 struct event event = {
437 .type = COMP_PORT_DISCONNECTED,
438 .data.comp_port_disconnected = {
439 .comp = bt_component_from_private_component(private_component),
440 .port = bt_port_from_private_port(private_port),
441 },
442 };
443
444 bt_put(event.data.comp_port_disconnected.comp);
445 bt_put(event.data.comp_port_disconnected.port);
446 append_event(&event);
447 }
448
449 static
450 enum bt_component_status sink_init(struct bt_private_component *priv_comp,
451 struct bt_value *params, void *init_method_data)
452 {
453 void *priv_port;
454
455 priv_port = bt_private_component_sink_add_input_private_port(priv_comp,
456 "in", NULL);
457 assert(priv_port);
458 bt_put(priv_port);
459 return BT_COMPONENT_STATUS_OK;
460 }
461
462 static
463 void graph_port_added(struct bt_port *port,
464 void *data)
465 {
466 struct bt_component *comp = bt_port_get_component(port);
467
468 assert(comp);
469 bt_put(comp);
470
471 struct event event = {
472 .type = GRAPH_PORT_ADDED,
473 .data.graph_port_added = {
474 .comp = comp,
475 .port = port,
476 },
477 };
478
479 append_event(&event);
480 }
481
482 static
483 void graph_port_removed(struct bt_component *component,
484 struct bt_port *port, void *data)
485 {
486 struct event event = {
487 .type = GRAPH_PORT_REMOVED,
488 .data.graph_port_removed = {
489 .comp = component,
490 .port = port,
491 },
492 };
493
494 append_event(&event);
495 }
496
497 static
498 void graph_ports_connected(struct bt_port *upstream_port,
499 struct bt_port *downstream_port, void *data)
500 {
501 struct bt_component *upstream_comp =
502 bt_port_get_component(upstream_port);
503 struct bt_component *downstream_comp =
504 bt_port_get_component(downstream_port);
505 struct bt_connection *conn = bt_port_get_connection(upstream_port);
506
507 assert(upstream_comp);
508 assert(downstream_comp);
509 assert(conn);
510 bt_put(upstream_comp);
511 bt_put(downstream_comp);
512 bt_put(conn);
513
514 struct event event = {
515 .type = GRAPH_PORTS_CONNECTED,
516 .data.graph_ports_connected = {
517 .upstream_comp = upstream_comp,
518 .downstream_comp = downstream_comp,
519 .upstream_port = upstream_port,
520 .downstream_port = downstream_port,
521 .conn = conn,
522 },
523 };
524
525 append_event(&event);
526 }
527
528 static
529 void graph_ports_disconnected(
530 struct bt_component *upstream_comp,
531 struct bt_component *downstream_comp,
532 struct bt_port *upstream_port, struct bt_port *downstream_port,
533 void *data)
534 {
535 struct event event = {
536 .type = GRAPH_PORTS_DISCONNECTED,
537 .data.graph_ports_disconnected = {
538 .upstream_comp = upstream_comp,
539 .downstream_comp = downstream_comp,
540 .upstream_port = upstream_port,
541 .downstream_port = downstream_port,
542 },
543 };
544
545 append_event(&event);
546 }
547
548 static
549 void init_test(void)
550 {
551 int ret;
552
553 src_comp_class = bt_component_class_source_create("src", src_iter_next);
554 assert(src_comp_class);
555 ret = bt_component_class_set_init_method(src_comp_class, src_init);
556 assert(ret == 0);
557 ret = bt_component_class_set_accept_port_connection_method(
558 src_comp_class, accept_port_connection);
559 assert(ret == 0);
560 ret = bt_component_class_set_port_connected_method(src_comp_class,
561 src_port_connected);
562 assert(ret == 0);
563 ret = bt_component_class_set_port_disconnected_method(
564 src_comp_class, src_port_disconnected);
565 assert(ret == 0);
566 sink_comp_class = bt_component_class_sink_create("sink", sink_consume);
567 assert(sink_comp_class);
568 ret = bt_component_class_set_init_method(sink_comp_class, sink_init);
569 assert(ret == 0);
570 ret = bt_component_class_set_accept_port_connection_method(
571 sink_comp_class, accept_port_connection);
572 assert(ret == 0);
573 ret = bt_component_class_set_port_connected_method(sink_comp_class,
574 sink_port_connected);
575 assert(ret == 0);
576 ret = bt_component_class_set_port_disconnected_method(sink_comp_class,
577 sink_port_disconnected);
578 assert(ret == 0);
579 bt_component_class_freeze(src_comp_class);
580 bt_component_class_freeze(sink_comp_class);
581 events = g_array_new(FALSE, TRUE, sizeof(struct event));
582 assert(events);
583 }
584
585 static
586 void fini_test(void)
587 {
588 bt_put(src_comp_class);
589 bt_put(sink_comp_class);
590 g_array_free(events, TRUE);
591 }
592
593 static
594 struct bt_component *create_src(void)
595 {
596 struct bt_component *comp =
597 bt_component_create(src_comp_class, "src-comp", NULL);
598
599 assert(comp);
600 return comp;
601 }
602
603 static
604 struct bt_component *create_sink(void)
605 {
606 struct bt_component *comp =
607 bt_component_create(sink_comp_class, "sink-comp", NULL);
608
609 assert(comp);
610 return comp;
611 }
612
613 static
614 struct bt_graph *create_graph(void)
615 {
616 struct bt_graph *graph = bt_graph_create();
617 int ret;
618
619 assert(graph);
620 ret = bt_graph_add_port_added_listener(graph, graph_port_added, NULL);
621 assert(ret >= 0);
622 ret = bt_graph_add_port_removed_listener(graph, graph_port_removed,
623 NULL);
624 assert(ret >= 0);
625 ret = bt_graph_add_ports_connected_listener(graph, graph_ports_connected,
626 NULL);
627 assert(ret >= 0);
628 ret = bt_graph_add_ports_disconnected_listener(graph,
629 graph_ports_disconnected, NULL);
630 assert(ret >= 0);
631 return graph;
632 }
633
634 static
635 void prepare_test(enum test test, const char *name)
636 {
637 clear_events();
638 current_test = test;
639 diag("test: %s", name);
640 }
641
642 static
643 void test_sink_removes_port_in_port_connected_then_src_removes_disconnected_port(void)
644 {
645 int ret;
646 struct bt_component *src;
647 struct bt_component *sink;
648 struct bt_graph *graph;
649 struct bt_port *src_def_port;
650 struct bt_port *sink_def_port;
651 struct bt_connection *conn;
652 struct event event;
653 enum bt_graph_status status;
654 size_t src_accept_port_connection_pos;
655 size_t sink_accept_port_connection_pos;
656 size_t src_port_connected_pos;
657 size_t sink_port_connected_pos;
658 size_t graph_ports_connected;
659 size_t src_port_disconnected_pos;
660 size_t sink_port_disconnected_pos;
661 size_t graph_ports_disconnected_pos;
662 size_t graph_port_removed_src_pos;
663 size_t graph_port_removed_sink_pos;
664
665 prepare_test(TEST_SINK_REMOVES_PORT_IN_CONSUME_THEN_SRC_REMOVES_DISCONNECTED_PORT,
666 "sink removes port in consume, then source removes disconnected port");
667 src = create_src();
668 sink = create_sink();
669 graph = create_graph();
670 src_def_port = bt_component_source_get_output_port_by_name(src, "out");
671 assert(src_def_port);
672 sink_def_port = bt_component_sink_get_input_port_by_name(sink, "in");
673 assert(sink_def_port);
674 status = bt_graph_connect_ports(graph, src_def_port, sink_def_port,
675 &conn);
676 assert(status == 0);
677 assert(conn);
678
679 /* We're supposed to have 5 events so far */
680 ok(events->len == 5, "we have the expected number of events (before consume)");
681
682 /* Source's accept port connection */
683 event.type = COMP_ACCEPT_PORT_CONNECTION;
684 event.data.comp_accept_port_connection.comp = src;
685 event.data.comp_accept_port_connection.self_port = src_def_port;
686 event.data.comp_accept_port_connection.other_port = sink_def_port;
687 ok(has_event(&event), "got the expected source's accept port connection event");
688 src_accept_port_connection_pos = event_pos(&event);
689
690 /* Sink's accept port connection */
691 event.type = COMP_ACCEPT_PORT_CONNECTION;
692 event.data.comp_accept_port_connection.comp = sink;
693 event.data.comp_accept_port_connection.self_port = sink_def_port;
694 event.data.comp_accept_port_connection.other_port = src_def_port;
695 ok(has_event(&event), "got the expected sink's accept port connection event");
696 sink_accept_port_connection_pos = event_pos(&event);
697
698 /* Source's port connected */
699 event.type = COMP_PORT_CONNECTED;
700 event.data.comp_port_connected.comp = src;
701 event.data.comp_port_connected.self_port = src_def_port;
702 event.data.comp_port_connected.other_port = sink_def_port;
703 ok(has_event(&event), "got the expected source's port connected event");
704 src_port_connected_pos = event_pos(&event);
705
706 /* Sink's port connected */
707 event.type = COMP_PORT_CONNECTED;
708 event.data.comp_port_connected.comp = sink;
709 event.data.comp_port_connected.self_port = sink_def_port;
710 event.data.comp_port_connected.other_port = src_def_port;
711 ok(has_event(&event), "got the expected sink's port connected event");
712 sink_port_connected_pos = event_pos(&event);
713
714 /* Graph's ports connected */
715 event.type = GRAPH_PORTS_CONNECTED;
716 event.data.graph_ports_connected.upstream_comp = src;
717 event.data.graph_ports_connected.downstream_comp = sink;
718 event.data.graph_ports_connected.upstream_port = src_def_port;
719 event.data.graph_ports_connected.downstream_port = sink_def_port;
720 event.data.graph_ports_connected.conn = conn;
721 ok(has_event(&event), "got the expected graph's ports connected event");
722 graph_ports_connected = event_pos(&event);
723
724 /* Order of events */
725 ok(src_port_connected_pos < graph_ports_connected,
726 "event order is good (1)");
727 ok(sink_port_connected_pos < graph_ports_connected,
728 "event order is good (2)");
729 ok(src_accept_port_connection_pos < src_port_connected_pos,
730 "event order is good (3)");
731 ok(sink_accept_port_connection_pos < sink_port_connected_pos,
732 "event order is good (4)");
733
734 /* Consume sink once */
735 clear_events();
736 ret = bt_graph_consume(graph);
737 assert(ret == 0);
738
739 /* We're supposed to have 5 new events */
740 ok(events->len == 5, "we have the expected number of events (after consume)");
741
742 /* Source's port disconnected */
743 event.type = COMP_PORT_DISCONNECTED;
744 event.data.comp_port_disconnected.comp = src;
745 event.data.comp_port_disconnected.port = src_def_port;
746 ok(has_event(&event), "got the expected source's port disconnected event");
747 src_port_disconnected_pos = event_pos(&event);
748
749 /* Sink's port disconnected */
750 event.type = COMP_PORT_DISCONNECTED;
751 event.data.comp_port_disconnected.comp = sink;
752 event.data.comp_port_disconnected.port = sink_def_port;
753 ok(has_event(&event), "got the expected sink's port disconnected event");
754 sink_port_disconnected_pos = event_pos(&event);
755
756 /* Graph's ports disconnected */
757 event.type = GRAPH_PORTS_DISCONNECTED;
758 event.data.graph_ports_disconnected.upstream_comp = src;
759 event.data.graph_ports_disconnected.downstream_comp = sink;
760 event.data.graph_ports_disconnected.upstream_port = src_def_port;
761 event.data.graph_ports_disconnected.downstream_port = sink_def_port;
762 ok(has_event(&event), "got the expected graph's ports disconnected event");
763 graph_ports_disconnected_pos = event_pos(&event);
764
765 /* Graph's port removed (sink) */
766 event.type = GRAPH_PORT_REMOVED;
767 event.data.graph_port_removed.comp = sink;
768 event.data.graph_port_removed.port = sink_def_port;
769 ok(has_event(&event), "got the expected graph's port removed event (for sink)");
770 graph_port_removed_sink_pos = event_pos(&event);
771
772 /* Graph's port removed (source) */
773 event.type = GRAPH_PORT_REMOVED;
774 event.data.graph_port_removed.comp = src;
775 event.data.graph_port_removed.port = src_def_port;
776 ok(has_event(&event), "got the expected graph's port removed event (for source)");
777 graph_port_removed_src_pos = event_pos(&event);
778
779 /* Order of events */
780 ok(src_port_disconnected_pos < graph_ports_disconnected_pos,
781 "event order is good (5)");
782 ok(src_port_disconnected_pos < graph_port_removed_sink_pos,
783 "event order is good (6)");
784 ok(src_port_disconnected_pos < graph_port_removed_src_pos,
785 "event order is good (7)");
786 ok(sink_port_disconnected_pos < graph_ports_disconnected_pos,
787 "event order is good (8)");
788 ok(sink_port_disconnected_pos < graph_port_removed_sink_pos,
789 "event order is good (9)");
790 ok(sink_port_disconnected_pos < graph_port_removed_src_pos,
791 "event order is good (10)");
792 ok(graph_ports_disconnected_pos < graph_port_removed_sink_pos,
793 "event order is good (11)");
794 ok(graph_port_removed_src_pos < graph_ports_disconnected_pos,
795 "event order is good (12)");
796 ok(graph_port_removed_src_pos < graph_port_removed_sink_pos,
797 "event order is good (13)");
798
799 bt_put(graph);
800 bt_put(sink);
801 bt_put(src);
802 bt_put(conn);
803 bt_put(src_def_port);
804 bt_put(sink_def_port);
805 }
806
807 static
808 void test_sink_removes_port_in_port_connected(void)
809 {
810 int ret;
811 struct bt_component *src;
812 struct bt_component *sink;
813 struct bt_graph *graph;
814 struct bt_port *src_def_port;
815 struct bt_port *sink_def_port;
816 struct bt_connection *conn;
817 struct event event;
818 enum bt_graph_status status;
819 size_t src_accept_port_connection_pos;
820 size_t sink_accept_port_connection_pos;
821 size_t src_port_connected_pos;
822 size_t sink_port_connected_pos;
823 size_t graph_ports_connected_pos;
824 size_t src_port_disconnected_pos;
825 size_t sink_port_disconnected_pos;
826 size_t graph_ports_disconnected_pos;
827 size_t graph_port_removed_sink_pos;
828
829 prepare_test(TEST_SINK_REMOVES_PORT_IN_CONSUME,
830 "sink removes port in consume");
831 src = create_src();
832 sink = create_sink();
833 graph = create_graph();
834 src_def_port = bt_component_source_get_output_port_by_name(src, "out");
835 assert(src_def_port);
836 sink_def_port = bt_component_sink_get_input_port_by_name(sink, "in");
837 assert(sink_def_port);
838 status = bt_graph_connect_ports(graph, src_def_port, sink_def_port,
839 &conn);
840 assert(status == 0);
841
842 /* We're supposed to have 5 events so far */
843 ok(events->len == 5, "we have the expected number of events (before consume)");
844
845 /* Source's accept port connection */
846 event.type = COMP_ACCEPT_PORT_CONNECTION;
847 event.data.comp_accept_port_connection.comp = src;
848 event.data.comp_accept_port_connection.self_port = src_def_port;
849 event.data.comp_accept_port_connection.other_port = sink_def_port;
850 ok(has_event(&event), "got the expected source's accept port connection event");
851 src_accept_port_connection_pos = event_pos(&event);
852
853 /* Sink's accept port connection */
854 event.type = COMP_ACCEPT_PORT_CONNECTION;
855 event.data.comp_accept_port_connection.comp = sink;
856 event.data.comp_accept_port_connection.self_port = sink_def_port;
857 event.data.comp_accept_port_connection.other_port = src_def_port;
858 ok(has_event(&event), "got the expected sink's accept port connection event");
859 sink_accept_port_connection_pos = event_pos(&event);
860
861 /* Source's port connected */
862 event.type = COMP_PORT_CONNECTED;
863 event.data.comp_port_connected.comp = src;
864 event.data.comp_port_connected.self_port = src_def_port;
865 event.data.comp_port_connected.other_port = sink_def_port;
866 ok(has_event(&event), "got the expected source's port connected event");
867 src_port_connected_pos = event_pos(&event);
868
869 /* Sink's port connected */
870 event.type = COMP_PORT_CONNECTED;
871 event.data.comp_port_connected.comp = sink;
872 event.data.comp_port_connected.self_port = sink_def_port;
873 event.data.comp_port_connected.other_port = src_def_port;
874 ok(has_event(&event), "got the expected sink's port connected event");
875 sink_port_connected_pos = event_pos(&event);
876
877 /* Graph's ports connected */
878 event.type = GRAPH_PORTS_CONNECTED;
879 event.data.graph_ports_connected.upstream_comp = src;
880 event.data.graph_ports_connected.downstream_comp = sink;
881 event.data.graph_ports_connected.upstream_port = src_def_port;
882 event.data.graph_ports_connected.downstream_port = sink_def_port;
883 event.data.graph_ports_connected.conn = conn;
884 ok(has_event(&event), "got the expected graph's ports connected event");
885 graph_ports_connected_pos = event_pos(&event);
886
887 /* Order of events */
888 ok(src_port_connected_pos < graph_ports_connected_pos,
889 "event order is good (1)");
890 ok(sink_port_connected_pos < graph_ports_connected_pos,
891 "event order is good (2)");
892 ok(src_accept_port_connection_pos < src_port_connected_pos,
893 "event order is good (3)");
894 ok(sink_accept_port_connection_pos < sink_port_connected_pos,
895 "event order is good (4)");
896
897 /* Consume sink once */
898 clear_events();
899 ret = bt_graph_consume(graph);
900 assert(ret == 0);
901
902 /* We're supposed to have 4 new events */
903 ok(events->len == 4, "we have the expected number of events (after consume)");
904
905 /* Source's port disconnected */
906 event.type = COMP_PORT_DISCONNECTED;
907 event.data.comp_port_disconnected.comp = src;
908 event.data.comp_port_disconnected.port = src_def_port;
909 ok(has_event(&event), "got the expected source's port disconnected event");
910 src_port_disconnected_pos = event_pos(&event);
911
912 /* Sink's port disconnected */
913 event.type = COMP_PORT_DISCONNECTED;
914 event.data.comp_port_disconnected.comp = sink;
915 event.data.comp_port_disconnected.port = sink_def_port;
916 ok(has_event(&event), "got the expected sink's port disconnected event");
917 sink_port_disconnected_pos = event_pos(&event);
918
919 /* Graph's ports disconnected */
920 event.type = GRAPH_PORTS_DISCONNECTED;
921 event.data.graph_ports_disconnected.upstream_comp = src;
922 event.data.graph_ports_disconnected.downstream_comp = sink;
923 event.data.graph_ports_disconnected.upstream_port = src_def_port;
924 event.data.graph_ports_disconnected.downstream_port = sink_def_port;
925 ok(has_event(&event), "got the expected graph's ports disconnected event");
926 graph_ports_disconnected_pos = event_pos(&event);
927
928 /* Graph's port removed (sink) */
929 event.type = GRAPH_PORT_REMOVED;
930 event.data.graph_port_removed.comp = sink;
931 event.data.graph_port_removed.port = sink_def_port;
932 ok(has_event(&event), "got the expected graph's port removed event (for sink)");
933 graph_port_removed_sink_pos = event_pos(&event);
934
935 /* Order of events */
936 ok(src_port_disconnected_pos < graph_ports_disconnected_pos,
937 "event order is good (5)");
938 ok(src_port_disconnected_pos < graph_port_removed_sink_pos,
939 "event order is good (7)");
940 ok(sink_port_disconnected_pos < graph_ports_disconnected_pos,
941 "event order is good (8)");
942 ok(sink_port_disconnected_pos < graph_port_removed_sink_pos,
943 "event order is good (10)");
944 ok(graph_ports_disconnected_pos < graph_port_removed_sink_pos,
945 "event order is good (11)");
946
947 bt_put(graph);
948 bt_put(sink);
949 bt_put(src);
950 bt_put(conn);
951 bt_put(src_def_port);
952 bt_put(sink_def_port);
953 }
954
955 static
956 void test_src_adds_port_in_port_connected(void)
957 {
958 struct bt_component *src;
959 struct bt_component *sink;
960 struct bt_graph *graph;
961 struct bt_port *src_def_port;
962 struct bt_port *sink_def_port;
963 struct bt_port *src_hello_port;
964 struct bt_connection *conn;
965 struct event event;
966 enum bt_graph_status status;
967 size_t src_accept_port_connection_pos;
968 size_t sink_accept_port_connection_pos;
969 size_t src_port_connected_pos;
970 size_t sink_port_connected_pos;
971 size_t graph_ports_connected_pos;
972 size_t graph_port_added_src_pos;
973
974 prepare_test(TEST_SRC_ADDS_PORT_IN_PORT_CONNECTED,
975 "source adds port in port connected");
976 src = create_src();
977 sink = create_sink();
978 graph = create_graph();
979 src_def_port = bt_component_source_get_output_port_by_name(src, "out");
980 assert(src_def_port);
981 sink_def_port = bt_component_sink_get_input_port_by_name(sink, "in");
982 assert(sink_def_port);
983 status = bt_graph_connect_ports(graph, src_def_port, sink_def_port,
984 &conn);
985 assert(status == 0);
986 src_hello_port = bt_component_source_get_output_port_by_name(src,
987 "hello");
988 assert(src_hello_port);
989
990 /* We're supposed to have 6 events */
991 ok(events->len == 6, "we have the expected number of events");
992
993 /* Source's accept port connection */
994 event.type = COMP_ACCEPT_PORT_CONNECTION;
995 event.data.comp_accept_port_connection.comp = src;
996 event.data.comp_accept_port_connection.self_port = src_def_port;
997 event.data.comp_accept_port_connection.other_port = sink_def_port;
998 ok(has_event(&event), "got the expected source's accept port connection event");
999 src_accept_port_connection_pos = event_pos(&event);
1000
1001 /* Sink's accept port connection */
1002 event.type = COMP_ACCEPT_PORT_CONNECTION;
1003 event.data.comp_accept_port_connection.comp = sink;
1004 event.data.comp_accept_port_connection.self_port = sink_def_port;
1005 event.data.comp_accept_port_connection.other_port = src_def_port;
1006 ok(has_event(&event), "got the expected sink's accept port connection event");
1007 sink_accept_port_connection_pos = event_pos(&event);
1008
1009 /* Source's port connected */
1010 event.type = COMP_PORT_CONNECTED;
1011 event.data.comp_port_connected.comp = src;
1012 event.data.comp_port_connected.self_port = src_def_port;
1013 event.data.comp_port_connected.other_port = sink_def_port;
1014 ok(has_event(&event), "got the expected source's port connected event");
1015 src_port_connected_pos = event_pos(&event);
1016
1017 /* Graph's port added (source) */
1018 event.type = GRAPH_PORT_ADDED;
1019 event.data.graph_port_added.comp = src;
1020 event.data.graph_port_added.port = src_hello_port;
1021 ok(has_event(&event), "got the expected graph's port added event (for source)");
1022 graph_port_added_src_pos = event_pos(&event);
1023
1024 /* Sink's port connected */
1025 event.type = COMP_PORT_CONNECTED;
1026 event.data.comp_port_connected.comp = sink;
1027 event.data.comp_port_connected.self_port = sink_def_port;
1028 event.data.comp_port_connected.other_port = src_def_port;
1029 ok(has_event(&event), "got the expected sink's port connected event");
1030 sink_port_connected_pos = event_pos(&event);
1031
1032 /* Graph's ports connected */
1033 event.type = GRAPH_PORTS_CONNECTED;
1034 event.data.graph_ports_connected.upstream_comp = src;
1035 event.data.graph_ports_connected.downstream_comp = sink;
1036 event.data.graph_ports_connected.upstream_port = src_def_port;
1037 event.data.graph_ports_connected.downstream_port = sink_def_port;
1038 event.data.graph_ports_connected.conn = conn;
1039 ok(has_event(&event), "got the expected graph's port connected event (for source)");
1040 graph_ports_connected_pos = event_pos(&event);
1041
1042 /* Order of events */
1043 ok(src_port_connected_pos < graph_ports_connected_pos,
1044 "event order is good (1)");
1045 ok(sink_port_connected_pos < graph_ports_connected_pos,
1046 "event order is good (2)");
1047 ok(src_accept_port_connection_pos < src_port_connected_pos,
1048 "event order is good (3)");
1049 ok(sink_accept_port_connection_pos < sink_port_connected_pos,
1050 "event order is good (4)");
1051 ok(src_port_connected_pos < graph_port_added_src_pos,
1052 "event order is good (5)");
1053 ok(graph_port_added_src_pos < graph_ports_connected_pos,
1054 "event order is good (6)");
1055
1056 bt_put(graph);
1057 bt_put(sink);
1058 bt_put(src);
1059 bt_put(conn);
1060 bt_put(src_def_port);
1061 bt_put(sink_def_port);
1062 bt_put(src_hello_port);
1063 }
1064
1065 static
1066 void test_simple(void)
1067 {
1068 struct bt_component *src;
1069 struct bt_component *sink;
1070 struct bt_graph *graph;
1071 struct bt_port *src_def_port;
1072 struct bt_port *sink_def_port;
1073 struct bt_connection *conn;
1074 struct event event;
1075 enum bt_graph_status status;
1076 size_t src_accept_port_connection_pos;
1077 size_t sink_accept_port_connection_pos;
1078 size_t src_port_connected_pos;
1079 size_t sink_port_connected_pos;
1080 size_t graph_ports_connected_pos;
1081
1082 prepare_test(TEST_SIMPLE, "simple");
1083 src = create_src();
1084 sink = create_sink();
1085 graph = create_graph();
1086 src_def_port = bt_component_source_get_output_port_by_name(src, "out");
1087 assert(src_def_port);
1088 sink_def_port = bt_component_sink_get_input_port_by_name(sink, "in");
1089 assert(sink_def_port);
1090 status = bt_graph_connect_ports(graph, src_def_port, sink_def_port,
1091 &conn);
1092 assert(status == 0);
1093
1094 /* We're supposed to have 5 events */
1095 ok(events->len == 5, "we have the expected number of events");
1096
1097 /* Source's accept port connection */
1098 event.type = COMP_ACCEPT_PORT_CONNECTION;
1099 event.data.comp_accept_port_connection.comp = src;
1100 event.data.comp_accept_port_connection.self_port = src_def_port;
1101 event.data.comp_accept_port_connection.other_port = sink_def_port;
1102 ok(has_event(&event), "got the expected source's accept port connection event");
1103 src_accept_port_connection_pos = event_pos(&event);
1104
1105 /* Sink's accept port connection */
1106 event.type = COMP_ACCEPT_PORT_CONNECTION;
1107 event.data.comp_accept_port_connection.comp = sink;
1108 event.data.comp_accept_port_connection.self_port = sink_def_port;
1109 event.data.comp_accept_port_connection.other_port = src_def_port;
1110 ok(has_event(&event), "got the expected sink's accept port connection event");
1111 sink_accept_port_connection_pos = event_pos(&event);
1112
1113 /* Source's port connected */
1114 event.type = COMP_PORT_CONNECTED;
1115 event.data.comp_port_connected.comp = src;
1116 event.data.comp_port_connected.self_port = src_def_port;
1117 event.data.comp_port_connected.other_port = sink_def_port;
1118 ok(has_event(&event), "got the expected source's port connected event");
1119 src_port_connected_pos = event_pos(&event);
1120
1121 /* Sink's port connected */
1122 event.type = COMP_PORT_CONNECTED;
1123 event.data.comp_port_connected.comp = sink;
1124 event.data.comp_port_connected.self_port = sink_def_port;
1125 event.data.comp_port_connected.other_port = src_def_port;
1126 ok(has_event(&event), "got the expected sink's port connected event");
1127 sink_port_connected_pos = event_pos(&event);
1128
1129 /* Graph's port connected */
1130 event.type = GRAPH_PORTS_CONNECTED;
1131 event.data.graph_ports_connected.upstream_comp = src;
1132 event.data.graph_ports_connected.downstream_comp = sink;
1133 event.data.graph_ports_connected.upstream_port = src_def_port;
1134 event.data.graph_ports_connected.downstream_port = sink_def_port;
1135 event.data.graph_ports_connected.conn = conn;
1136 ok(has_event(&event), "got the expected graph's ports connected event");
1137 graph_ports_connected_pos = event_pos(&event);
1138
1139 /* Order of events */
1140 ok(src_port_connected_pos < graph_ports_connected_pos,
1141 "event order is good (1)");
1142 ok(sink_port_connected_pos < graph_ports_connected_pos,
1143 "event order is good (2)");
1144 ok(src_accept_port_connection_pos < src_port_connected_pos,
1145 "event order is good (3)");
1146 ok(sink_accept_port_connection_pos < sink_port_connected_pos,
1147 "event order is good (4)");
1148
1149 bt_put(graph);
1150 bt_put(sink);
1151 bt_put(src);
1152 bt_put(conn);
1153 bt_put(src_def_port);
1154 bt_put(sink_def_port);
1155 }
1156
1157 static
1158 void test_empty_graph(void)
1159 {
1160 struct bt_graph *graph;
1161
1162 prepare_test(TEST_EMPTY_GRAPH, "empty graph");
1163 graph = create_graph();
1164 ok(events->len == 0, "empty graph generates no events");
1165 bt_put(graph);
1166 }
1167
1168 int main(int argc, char **argv)
1169 {
1170 plan_tests(NR_TESTS);
1171 init_test();
1172 test_empty_graph();
1173 test_simple();
1174 test_src_adds_port_in_port_connected();
1175 test_sink_removes_port_in_port_connected();
1176 test_sink_removes_port_in_port_connected_then_src_removes_disconnected_port();
1177 fini_test();
1178 return exit_status();
1179 }
This page took 0.055487 seconds and 4 git commands to generate.