lib: use object pool for event and packet notifications
[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/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>
35 #include <stdlib.h>
36 #include <string.h>
37 #include <stdbool.h>
38 #include <assert.h>
39 #include <glib.h>
40
41 #include "tap/tap.h"
42
43 #define NR_TESTS 77
44
45 enum event_type {
46 COMP_ACCEPT_PORT_CONNECTION,
47 COMP_PORT_CONNECTED,
48 COMP_PORT_DISCONNECTED,
49 GRAPH_PORT_ADDED,
50 GRAPH_PORT_REMOVED,
51 GRAPH_PORTS_CONNECTED,
52 GRAPH_PORTS_DISCONNECTED,
53 };
54
55 enum test {
56 TEST_EMPTY_GRAPH,
57 TEST_SIMPLE,
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,
61 };
62
63 struct event {
64 enum event_type type;
65
66 union {
67 struct {
68 struct bt_component *comp;
69 struct bt_port *self_port;
70 struct bt_port *other_port;
71 } comp_accept_port_connection;
72
73 struct {
74 struct bt_component *comp;
75 struct bt_port *self_port;
76 struct bt_port *other_port;
77 } comp_port_connected;
78
79 struct {
80 struct bt_component *comp;
81 struct bt_port *port;
82 } comp_port_disconnected;
83
84 struct {
85 struct bt_component *comp;
86 struct bt_port *port;
87 } graph_port_added;
88
89 struct {
90 struct bt_component *comp;
91 struct bt_port *port;
92 } graph_port_removed;
93
94 struct {
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;
101
102 struct {
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;
108 } data;
109 };
110
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;
115
116 static
117 void clear_events(void)
118 {
119 g_array_set_size(events, 0);
120 }
121
122 static
123 void append_event(struct event *event)
124 {
125 g_array_append_val(events, *event);
126 }
127
128 static
129 bool compare_events(struct event *ev_a, struct event *ev_b)
130 {
131 if (ev_a->type != ev_b->type) {
132 return false;
133 }
134
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) {
139 return false;
140 }
141
142 if (ev_a->data.comp_accept_port_connection.self_port !=
143 ev_b->data.comp_accept_port_connection.self_port) {
144 return false;
145 }
146
147 if (ev_a->data.comp_accept_port_connection.other_port !=
148 ev_b->data.comp_accept_port_connection.other_port) {
149 return false;
150 }
151 break;
152 case COMP_PORT_CONNECTED:
153 if (ev_a->data.comp_port_connected.comp !=
154 ev_b->data.comp_port_connected.comp) {
155 return false;
156 }
157
158 if (ev_a->data.comp_port_connected.self_port !=
159 ev_b->data.comp_port_connected.self_port) {
160 return false;
161 }
162
163 if (ev_a->data.comp_port_connected.other_port !=
164 ev_b->data.comp_port_connected.other_port) {
165 return false;
166 }
167 break;
168 case COMP_PORT_DISCONNECTED:
169 if (ev_a->data.comp_port_disconnected.comp !=
170 ev_b->data.comp_port_disconnected.comp) {
171 return false;
172 }
173
174 if (ev_a->data.comp_port_disconnected.port !=
175 ev_b->data.comp_port_disconnected.port) {
176 return false;
177 }
178 break;
179 case GRAPH_PORT_ADDED:
180 if (ev_a->data.graph_port_added.comp !=
181 ev_b->data.graph_port_added.comp) {
182 return false;
183 }
184
185 if (ev_a->data.graph_port_added.port !=
186 ev_b->data.graph_port_added.port) {
187 return false;
188 }
189 break;
190 case GRAPH_PORT_REMOVED:
191 if (ev_a->data.graph_port_removed.comp !=
192 ev_b->data.graph_port_removed.comp) {
193 return false;
194 }
195
196 if (ev_a->data.graph_port_removed.port !=
197 ev_b->data.graph_port_removed.port) {
198 return false;
199 }
200 break;
201 case GRAPH_PORTS_CONNECTED:
202 if (ev_a->data.graph_ports_connected.upstream_comp !=
203 ev_b->data.graph_ports_connected.upstream_comp) {
204 return false;
205 }
206
207 if (ev_a->data.graph_ports_connected.downstream_comp !=
208 ev_b->data.graph_ports_connected.downstream_comp) {
209 return false;
210 }
211
212 if (ev_a->data.graph_ports_connected.upstream_port !=
213 ev_b->data.graph_ports_connected.upstream_port) {
214 return false;
215 }
216
217 if (ev_a->data.graph_ports_connected.downstream_port !=
218 ev_b->data.graph_ports_connected.downstream_port) {
219 return false;
220 }
221
222 if (ev_a->data.graph_ports_connected.conn !=
223 ev_b->data.graph_ports_connected.conn) {
224 return false;
225 }
226 break;
227 case GRAPH_PORTS_DISCONNECTED:
228 if (ev_a->data.graph_ports_disconnected.upstream_comp !=
229 ev_b->data.graph_ports_disconnected.upstream_comp) {
230 return false;
231 }
232
233 if (ev_a->data.graph_ports_disconnected.downstream_comp !=
234 ev_b->data.graph_ports_disconnected.downstream_comp) {
235 return false;
236 }
237
238 if (ev_a->data.graph_ports_disconnected.upstream_port !=
239 ev_b->data.graph_ports_disconnected.upstream_port) {
240 return false;
241 }
242
243 if (ev_a->data.graph_ports_disconnected.downstream_port !=
244 ev_b->data.graph_ports_disconnected.downstream_port) {
245 return false;
246 }
247 break;
248 default:
249 abort();
250 }
251
252 return true;
253 }
254
255 static
256 bool has_event(struct event *event)
257 {
258 size_t i;
259
260 for (i = 0; i < events->len; i++) {
261 struct event *ev = &g_array_index(events, struct event, i);
262
263 if (compare_events(event, ev)) {
264 return true;
265 }
266 }
267
268 return false;
269 }
270
271 static
272 size_t event_pos(struct event *event)
273 {
274 size_t i;
275
276 for (i = 0; i < events->len; i++) {
277 struct event *ev = &g_array_index(events, struct event, i);
278
279 if (compare_events(event, ev)) {
280 return i;
281 }
282 }
283
284 return SIZE_MAX;
285 }
286
287 static
288 struct bt_notification_iterator_next_method_return src_iter_next(
289 struct bt_private_connection_private_notification_iterator *priv_iterator)
290 {
291 struct bt_notification_iterator_next_method_return ret = {
292 .status = BT_NOTIFICATION_ITERATOR_STATUS_ERROR,
293 };
294
295 return ret;
296 }
297
298 static
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)
303 {
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,
310 },
311 };
312
313 append_event(&event);
314 return BT_COMPONENT_STATUS_OK;
315 }
316
317 static
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)
321 {
322 int ret;
323
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,
330 },
331 };
332
333 append_event(&event);
334
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);
339 assert(ret == 0);
340 break;
341 default:
342 break;
343 }
344 }
345
346 static
347 void src_port_disconnected(struct bt_private_component *private_component,
348 struct bt_private_port *private_port)
349 {
350 int ret;
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),
356 },
357 };
358
359 append_event(&event);
360
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);
364 assert(ret == 0);
365 default:
366 break;
367 }
368 }
369
370 static
371 enum bt_component_status src_init(struct bt_private_component *priv_comp,
372 struct bt_value *params, void *init_method_data)
373 {
374 int ret;
375
376 ret = bt_private_component_source_add_output_private_port(
377 priv_comp, "out", NULL, NULL);
378 assert(ret == 0);
379 return BT_COMPONENT_STATUS_OK;
380 }
381
382 static
383 enum bt_component_status sink_consume(
384 struct bt_private_component *priv_component)
385 {
386 struct bt_private_port *def_port;
387 int ret;
388
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");
394 assert(def_port);
395 ret = bt_private_port_remove_from_component(def_port);
396 assert(ret == 0);
397 bt_put(def_port);
398 break;
399 default:
400 break;
401 }
402
403 return BT_COMPONENT_STATUS_OK;
404 }
405
406 static
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)
410 {
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,
417 },
418 };
419
420 append_event(&event);
421 }
422
423 static
424 void sink_port_disconnected(struct bt_private_component *private_component,
425 struct bt_private_port *private_port)
426 {
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),
432 },
433 };
434
435 append_event(&event);
436 }
437
438 static
439 enum bt_component_status sink_init(struct bt_private_component *priv_comp,
440 struct bt_value *params, void *init_method_data)
441 {
442 int ret;
443
444 ret = bt_private_component_sink_add_input_private_port(priv_comp,
445 "in", NULL, NULL);
446 assert(ret == 0);
447 return BT_COMPONENT_STATUS_OK;
448 }
449
450 static
451 void graph_port_added(struct bt_port *port,
452 void *data)
453 {
454 struct bt_component *comp = bt_port_get_component(port);
455
456 assert(comp);
457 bt_put(comp);
458
459 struct event event = {
460 .type = GRAPH_PORT_ADDED,
461 .data.graph_port_added = {
462 .comp = comp,
463 .port = port,
464 },
465 };
466
467 append_event(&event);
468 }
469
470 static
471 void graph_port_removed(struct bt_component *component,
472 struct bt_port *port, void *data)
473 {
474 struct event event = {
475 .type = GRAPH_PORT_REMOVED,
476 .data.graph_port_removed = {
477 .comp = component,
478 .port = port,
479 },
480 };
481
482 append_event(&event);
483 }
484
485 static
486 void graph_ports_connected(struct bt_port *upstream_port,
487 struct bt_port *downstream_port, void *data)
488 {
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);
494
495 assert(upstream_comp);
496 assert(downstream_comp);
497 assert(conn);
498 bt_put(upstream_comp);
499 bt_put(downstream_comp);
500 bt_put(conn);
501
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,
509 .conn = conn,
510 },
511 };
512
513 append_event(&event);
514 }
515
516 static
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,
521 void *data)
522 {
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,
530 },
531 };
532
533 append_event(&event);
534 }
535
536 static
537 void init_test(void)
538 {
539 int ret;
540
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);
544 assert(ret == 0);
545 ret = bt_component_class_set_accept_port_connection_method(
546 src_comp_class, accept_port_connection);
547 assert(ret == 0);
548 ret = bt_component_class_set_port_connected_method(src_comp_class,
549 src_port_connected);
550 assert(ret == 0);
551 ret = bt_component_class_set_port_disconnected_method(
552 src_comp_class, src_port_disconnected);
553 assert(ret == 0);
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);
557 assert(ret == 0);
558 ret = bt_component_class_set_accept_port_connection_method(
559 sink_comp_class, accept_port_connection);
560 assert(ret == 0);
561 ret = bt_component_class_set_port_connected_method(sink_comp_class,
562 sink_port_connected);
563 assert(ret == 0);
564 ret = bt_component_class_set_port_disconnected_method(sink_comp_class,
565 sink_port_disconnected);
566 assert(ret == 0);
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));
570 assert(events);
571 }
572
573 static
574 void fini_test(void)
575 {
576 bt_put(src_comp_class);
577 bt_put(sink_comp_class);
578 g_array_free(events, TRUE);
579 }
580
581 static
582 struct bt_component *create_src(struct bt_graph *graph)
583 {
584 struct bt_component *comp;
585 int ret;
586
587 ret = bt_graph_add_component(graph, src_comp_class, "src-comp", NULL,
588 &comp);
589 assert(ret == 0);
590 return comp;
591 }
592
593 static
594 struct bt_component *create_sink(struct bt_graph *graph)
595 {
596 struct bt_component *comp;
597 int ret;
598
599 ret = bt_graph_add_component(graph, sink_comp_class, "sink-comp",
600 NULL, &comp);
601 assert(ret == 0);
602 return comp;
603 }
604
605 static
606 struct bt_graph *create_graph(void)
607 {
608 struct bt_graph *graph = bt_graph_create();
609 int ret;
610
611 assert(graph);
612 ret = bt_graph_add_port_added_listener(graph, graph_port_added, NULL,
613 NULL);
614 assert(ret >= 0);
615 ret = bt_graph_add_port_removed_listener(graph, graph_port_removed,
616 NULL, NULL);
617 assert(ret >= 0);
618 ret = bt_graph_add_ports_connected_listener(graph,
619 graph_ports_connected, NULL, NULL);
620 assert(ret >= 0);
621 ret = bt_graph_add_ports_disconnected_listener(graph,
622 graph_ports_disconnected, NULL, NULL);
623 assert(ret >= 0);
624 return graph;
625 }
626
627 static
628 void prepare_test(enum test test, const char *name)
629 {
630 clear_events();
631 current_test = test;
632 diag("test: %s", name);
633 }
634
635 static
636 void test_sink_removes_port_in_port_connected_then_src_removes_disconnected_port(void)
637 {
638 int ret;
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;
645 struct event event;
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;
657
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();
661 assert(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,
669 &conn);
670 assert(status == 0);
671 assert(conn);
672
673 /* We're supposed to have 7 events so far */
674 ok(events->len == 7, "we have the expected number of events (before consume)");
675
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)");
681
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)");
687
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);
695
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);
703
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);
711
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);
719
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);
729
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)");
739
740 /* Consume sink once */
741 clear_events();
742 ret = bt_graph_consume(graph);
743 assert(ret == 0);
744
745 /* We're supposed to have 5 new events */
746 ok(events->len == 5, "we have the expected number of events (after consume)");
747
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);
754
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);
761
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);
770
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);
777
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);
784
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)");
804
805 bt_put(graph);
806 bt_put(sink);
807 bt_put(src);
808 bt_put(conn);
809 bt_put(src_def_port);
810 bt_put(sink_def_port);
811 }
812
813 static
814 void test_sink_removes_port_in_port_connected(void)
815 {
816 int ret;
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;
823 struct event event;
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;
834
835 prepare_test(TEST_SINK_REMOVES_PORT_IN_CONSUME,
836 "sink removes port in consume");
837 graph = create_graph();
838 assert(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,
846 &conn);
847 assert(status == 0);
848
849 /* We're supposed to have 7 events so far */
850 ok(events->len == 7, "we have the expected number of events (before consume)");
851
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)");
857
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)");
863
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);
871
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);
879
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);
887
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);
895
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);
905
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)");
915
916 /* Consume sink once */
917 clear_events();
918 ret = bt_graph_consume(graph);
919 assert(ret == 0);
920
921 /* We're supposed to have 4 new events */
922 ok(events->len == 4, "we have the expected number of events (after consume)");
923
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);
930
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);
937
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);
946
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);
953
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)");
965
966 bt_put(graph);
967 bt_put(sink);
968 bt_put(src);
969 bt_put(conn);
970 bt_put(src_def_port);
971 bt_put(sink_def_port);
972 }
973
974 static
975 void test_src_adds_port_in_port_connected(void)
976 {
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;
984 struct event event;
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;
992
993 prepare_test(TEST_SRC_ADDS_PORT_IN_PORT_CONNECTED,
994 "source adds port in port connected");
995 graph = create_graph();
996 assert(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,
1004 &conn);
1005 assert(status == 0);
1006 src_hello_port = bt_component_source_get_output_port_by_name(src,
1007 "hello");
1008 assert(src_hello_port);
1009
1010 /* We're supposed to have 8 events */
1011 ok(events->len == 8, "we have the expected number of events");
1012
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)");
1018
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)");
1024
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);
1032
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);
1040
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);
1048
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);
1055
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);
1063
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);
1073
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)");
1087
1088 bt_put(graph);
1089 bt_put(sink);
1090 bt_put(src);
1091 bt_put(conn);
1092 bt_put(src_def_port);
1093 bt_put(sink_def_port);
1094 bt_put(src_hello_port);
1095 }
1096
1097 static
1098 void test_simple(void)
1099 {
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;
1106 struct event event;
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;
1113
1114 prepare_test(TEST_SIMPLE, "simple");
1115 graph = create_graph();
1116 assert(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,
1124 &conn);
1125 assert(status == 0);
1126
1127 /* We're supposed to have 7 events */
1128 ok(events->len == 7, "we have the expected number of events");
1129
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)");
1135
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)");
1141
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);
1149
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);
1157
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);
1165
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);
1173
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);
1183
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)");
1193
1194 bt_put(graph);
1195 bt_put(sink);
1196 bt_put(src);
1197 bt_put(conn);
1198 bt_put(src_def_port);
1199 bt_put(sink_def_port);
1200 }
1201
1202 static
1203 void test_empty_graph(void)
1204 {
1205 struct bt_graph *graph;
1206
1207 prepare_test(TEST_EMPTY_GRAPH, "empty graph");
1208 graph = create_graph();
1209 ok(events->len == 0, "empty graph generates no events");
1210 bt_put(graph);
1211 }
1212
1213 int main(int argc, char **argv)
1214 {
1215 plan_tests(NR_TESTS);
1216 init_test();
1217 test_empty_graph();
1218 test_simple();
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();
1222 fini_test();
1223 return exit_status();
1224 }
This page took 0.055023 seconds and 4 git commands to generate.