lib: notification iterator: transfer a batch of 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 <babeltrace/assert-internal.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 enum bt_notification_iterator_status src_iter_next(
289 struct bt_private_connection_private_notification_iterator *priv_iterator,
290 bt_notification_array notifs, uint64_t capacity,
291 uint64_t *count)
292 {
293 return BT_NOTIFICATION_ITERATOR_STATUS_ERROR;
294 }
295
296 static
297 enum bt_component_status accept_port_connection(
298 struct bt_private_component *private_component,
299 struct bt_private_port *self_private_port,
300 struct bt_port *other_port)
301 {
302 struct event event = {
303 .type = COMP_ACCEPT_PORT_CONNECTION,
304 .data.comp_accept_port_connection = {
305 .comp = bt_component_borrow_from_private(private_component),
306 .self_port = bt_port_borrow_from_private(self_private_port),
307 .other_port = other_port,
308 },
309 };
310
311 append_event(&event);
312 return BT_COMPONENT_STATUS_OK;
313 }
314
315 static
316 void src_port_connected(struct bt_private_component *private_component,
317 struct bt_private_port *self_private_port,
318 struct bt_port *other_port)
319 {
320 int ret;
321
322 struct event event = {
323 .type = COMP_PORT_CONNECTED,
324 .data.comp_port_connected = {
325 .comp = bt_component_borrow_from_private(private_component),
326 .self_port = bt_port_borrow_from_private(self_private_port),
327 .other_port = other_port,
328 },
329 };
330
331 append_event(&event);
332
333 switch (current_test) {
334 case TEST_SRC_ADDS_PORT_IN_PORT_CONNECTED:
335 ret = bt_private_component_source_add_output_private_port(
336 private_component, "hello", NULL, NULL);
337 BT_ASSERT(ret == 0);
338 break;
339 default:
340 break;
341 }
342 }
343
344 static
345 void src_port_disconnected(struct bt_private_component *private_component,
346 struct bt_private_port *private_port)
347 {
348 int ret;
349 struct event event = {
350 .type = COMP_PORT_DISCONNECTED,
351 .data.comp_port_disconnected = {
352 .comp = bt_component_borrow_from_private(private_component),
353 .port = bt_port_borrow_from_private(private_port),
354 },
355 };
356
357 append_event(&event);
358
359 switch (current_test) {
360 case TEST_SINK_REMOVES_PORT_IN_CONSUME_THEN_SRC_REMOVES_DISCONNECTED_PORT:
361 ret = bt_private_port_remove_from_component(private_port);
362 BT_ASSERT(ret == 0);
363 default:
364 break;
365 }
366 }
367
368 static
369 enum bt_component_status src_init(struct bt_private_component *priv_comp,
370 struct bt_value *params, void *init_method_data)
371 {
372 int ret;
373
374 ret = bt_private_component_source_add_output_private_port(
375 priv_comp, "out", NULL, NULL);
376 BT_ASSERT(ret == 0);
377 return BT_COMPONENT_STATUS_OK;
378 }
379
380 static
381 enum bt_component_status sink_consume(
382 struct bt_private_component *priv_component)
383 {
384 struct bt_private_port *def_port;
385 int ret;
386
387 switch (current_test) {
388 case TEST_SINK_REMOVES_PORT_IN_CONSUME:
389 case TEST_SINK_REMOVES_PORT_IN_CONSUME_THEN_SRC_REMOVES_DISCONNECTED_PORT:
390 def_port = bt_private_component_sink_get_input_private_port_by_name(
391 priv_component, "in");
392 BT_ASSERT(def_port);
393 ret = bt_private_port_remove_from_component(def_port);
394 BT_ASSERT(ret == 0);
395 bt_put(def_port);
396 break;
397 default:
398 break;
399 }
400
401 return BT_COMPONENT_STATUS_OK;
402 }
403
404 static
405 void sink_port_connected(struct bt_private_component *private_component,
406 struct bt_private_port *self_private_port,
407 struct bt_port *other_port)
408 {
409 struct event event = {
410 .type = COMP_PORT_CONNECTED,
411 .data.comp_port_connected = {
412 .comp = bt_component_borrow_from_private(private_component),
413 .self_port = bt_port_borrow_from_private(self_private_port),
414 .other_port = other_port,
415 },
416 };
417
418 append_event(&event);
419 }
420
421 static
422 void sink_port_disconnected(struct bt_private_component *private_component,
423 struct bt_private_port *private_port)
424 {
425 struct event event = {
426 .type = COMP_PORT_DISCONNECTED,
427 .data.comp_port_disconnected = {
428 .comp = bt_component_borrow_from_private(private_component),
429 .port = bt_port_borrow_from_private(private_port),
430 },
431 };
432
433 append_event(&event);
434 }
435
436 static
437 enum bt_component_status sink_init(struct bt_private_component *priv_comp,
438 struct bt_value *params, void *init_method_data)
439 {
440 int ret;
441
442 ret = bt_private_component_sink_add_input_private_port(priv_comp,
443 "in", NULL, NULL);
444 BT_ASSERT(ret == 0);
445 return BT_COMPONENT_STATUS_OK;
446 }
447
448 static
449 void graph_port_added(struct bt_port *port,
450 void *data)
451 {
452 struct bt_component *comp = bt_port_get_component(port);
453
454 BT_ASSERT(comp);
455 bt_put(comp);
456
457 struct event event = {
458 .type = GRAPH_PORT_ADDED,
459 .data.graph_port_added = {
460 .comp = comp,
461 .port = port,
462 },
463 };
464
465 append_event(&event);
466 }
467
468 static
469 void graph_port_removed(struct bt_component *component,
470 struct bt_port *port, void *data)
471 {
472 struct event event = {
473 .type = GRAPH_PORT_REMOVED,
474 .data.graph_port_removed = {
475 .comp = component,
476 .port = port,
477 },
478 };
479
480 append_event(&event);
481 }
482
483 static
484 void graph_ports_connected(struct bt_port *upstream_port,
485 struct bt_port *downstream_port, void *data)
486 {
487 struct bt_component *upstream_comp =
488 bt_port_get_component(upstream_port);
489 struct bt_component *downstream_comp =
490 bt_port_get_component(downstream_port);
491 struct bt_connection *conn = bt_port_get_connection(upstream_port);
492
493 BT_ASSERT(upstream_comp);
494 BT_ASSERT(downstream_comp);
495 BT_ASSERT(conn);
496 bt_put(upstream_comp);
497 bt_put(downstream_comp);
498 bt_put(conn);
499
500 struct event event = {
501 .type = GRAPH_PORTS_CONNECTED,
502 .data.graph_ports_connected = {
503 .upstream_comp = upstream_comp,
504 .downstream_comp = downstream_comp,
505 .upstream_port = upstream_port,
506 .downstream_port = downstream_port,
507 .conn = conn,
508 },
509 };
510
511 append_event(&event);
512 }
513
514 static
515 void graph_ports_disconnected(
516 struct bt_component *upstream_comp,
517 struct bt_component *downstream_comp,
518 struct bt_port *upstream_port, struct bt_port *downstream_port,
519 void *data)
520 {
521 struct event event = {
522 .type = GRAPH_PORTS_DISCONNECTED,
523 .data.graph_ports_disconnected = {
524 .upstream_comp = upstream_comp,
525 .downstream_comp = downstream_comp,
526 .upstream_port = upstream_port,
527 .downstream_port = downstream_port,
528 },
529 };
530
531 append_event(&event);
532 }
533
534 static
535 void init_test(void)
536 {
537 int ret;
538
539 src_comp_class = bt_component_class_source_create("src", src_iter_next);
540 BT_ASSERT(src_comp_class);
541 ret = bt_component_class_set_init_method(src_comp_class, src_init);
542 BT_ASSERT(ret == 0);
543 ret = bt_component_class_set_accept_port_connection_method(
544 src_comp_class, accept_port_connection);
545 BT_ASSERT(ret == 0);
546 ret = bt_component_class_set_port_connected_method(src_comp_class,
547 src_port_connected);
548 BT_ASSERT(ret == 0);
549 ret = bt_component_class_set_port_disconnected_method(
550 src_comp_class, src_port_disconnected);
551 BT_ASSERT(ret == 0);
552 sink_comp_class = bt_component_class_sink_create("sink", sink_consume);
553 BT_ASSERT(sink_comp_class);
554 ret = bt_component_class_set_init_method(sink_comp_class, sink_init);
555 BT_ASSERT(ret == 0);
556 ret = bt_component_class_set_accept_port_connection_method(
557 sink_comp_class, accept_port_connection);
558 BT_ASSERT(ret == 0);
559 ret = bt_component_class_set_port_connected_method(sink_comp_class,
560 sink_port_connected);
561 BT_ASSERT(ret == 0);
562 ret = bt_component_class_set_port_disconnected_method(sink_comp_class,
563 sink_port_disconnected);
564 BT_ASSERT(ret == 0);
565 bt_component_class_freeze(src_comp_class);
566 bt_component_class_freeze(sink_comp_class);
567 events = g_array_new(FALSE, TRUE, sizeof(struct event));
568 BT_ASSERT(events);
569 }
570
571 static
572 void fini_test(void)
573 {
574 bt_put(src_comp_class);
575 bt_put(sink_comp_class);
576 g_array_free(events, TRUE);
577 }
578
579 static
580 struct bt_component *create_src(struct bt_graph *graph)
581 {
582 struct bt_component *comp;
583 int ret;
584
585 ret = bt_graph_add_component(graph, src_comp_class, "src-comp", NULL,
586 &comp);
587 BT_ASSERT(ret == 0);
588 return comp;
589 }
590
591 static
592 struct bt_component *create_sink(struct bt_graph *graph)
593 {
594 struct bt_component *comp;
595 int ret;
596
597 ret = bt_graph_add_component(graph, sink_comp_class, "sink-comp",
598 NULL, &comp);
599 BT_ASSERT(ret == 0);
600 return comp;
601 }
602
603 static
604 struct bt_graph *create_graph(void)
605 {
606 struct bt_graph *graph = bt_graph_create();
607 int ret;
608
609 BT_ASSERT(graph);
610 ret = bt_graph_add_port_added_listener(graph, graph_port_added, NULL,
611 NULL);
612 BT_ASSERT(ret >= 0);
613 ret = bt_graph_add_port_removed_listener(graph, graph_port_removed,
614 NULL, NULL);
615 BT_ASSERT(ret >= 0);
616 ret = bt_graph_add_ports_connected_listener(graph,
617 graph_ports_connected, NULL, NULL);
618 BT_ASSERT(ret >= 0);
619 ret = bt_graph_add_ports_disconnected_listener(graph,
620 graph_ports_disconnected, NULL, NULL);
621 BT_ASSERT(ret >= 0);
622 return graph;
623 }
624
625 static
626 void prepare_test(enum test test, const char *name)
627 {
628 clear_events();
629 current_test = test;
630 diag("test: %s", name);
631 }
632
633 static
634 void test_sink_removes_port_in_port_connected_then_src_removes_disconnected_port(void)
635 {
636 int ret;
637 struct bt_component *src;
638 struct bt_component *sink;
639 struct bt_graph *graph;
640 struct bt_port *src_def_port;
641 struct bt_port *sink_def_port;
642 struct bt_connection *conn;
643 struct event event;
644 enum bt_graph_status status;
645 size_t src_accept_port_connection_pos;
646 size_t sink_accept_port_connection_pos;
647 size_t src_port_connected_pos;
648 size_t sink_port_connected_pos;
649 size_t graph_ports_connected;
650 size_t src_port_disconnected_pos;
651 size_t sink_port_disconnected_pos;
652 size_t graph_ports_disconnected_pos;
653 size_t graph_port_removed_src_pos;
654 size_t graph_port_removed_sink_pos;
655
656 prepare_test(TEST_SINK_REMOVES_PORT_IN_CONSUME_THEN_SRC_REMOVES_DISCONNECTED_PORT,
657 "sink removes port in consume, then source removes disconnected port");
658 graph = create_graph();
659 BT_ASSERT(graph);
660 src = create_src(graph);
661 sink = create_sink(graph);
662 src_def_port = bt_component_source_get_output_port_by_name(src, "out");
663 BT_ASSERT(src_def_port);
664 sink_def_port = bt_component_sink_get_input_port_by_name(sink, "in");
665 BT_ASSERT(sink_def_port);
666 status = bt_graph_connect_ports(graph, src_def_port, sink_def_port,
667 &conn);
668 BT_ASSERT(status == 0);
669 BT_ASSERT(conn);
670
671 /* We're supposed to have 7 events so far */
672 ok(events->len == 7, "we have the expected number of events (before consume)");
673
674 /* Source's port added */
675 event.type = GRAPH_PORT_ADDED;
676 event.data.graph_port_added.comp = src;
677 event.data.graph_port_added.port = src_def_port;
678 ok(has_event(&event), "got the expected graph's port added event (for source, initial)");
679
680 /* Sink's port added */
681 event.type = GRAPH_PORT_ADDED;
682 event.data.graph_port_added.comp = sink;
683 event.data.graph_port_added.port = sink_def_port;
684 ok(has_event(&event), "got the expected graph's port added event (for sink, initial)");
685
686 /* Source's accept port connection */
687 event.type = COMP_ACCEPT_PORT_CONNECTION;
688 event.data.comp_accept_port_connection.comp = src;
689 event.data.comp_accept_port_connection.self_port = src_def_port;
690 event.data.comp_accept_port_connection.other_port = sink_def_port;
691 ok(has_event(&event), "got the expected source's accept port connection event");
692 src_accept_port_connection_pos = event_pos(&event);
693
694 /* Sink's accept port connection */
695 event.type = COMP_ACCEPT_PORT_CONNECTION;
696 event.data.comp_accept_port_connection.comp = sink;
697 event.data.comp_accept_port_connection.self_port = sink_def_port;
698 event.data.comp_accept_port_connection.other_port = src_def_port;
699 ok(has_event(&event), "got the expected sink's accept port connection event");
700 sink_accept_port_connection_pos = event_pos(&event);
701
702 /* Source's port connected */
703 event.type = COMP_PORT_CONNECTED;
704 event.data.comp_port_connected.comp = src;
705 event.data.comp_port_connected.self_port = src_def_port;
706 event.data.comp_port_connected.other_port = sink_def_port;
707 ok(has_event(&event), "got the expected source's port connected event");
708 src_port_connected_pos = event_pos(&event);
709
710 /* Sink's port connected */
711 event.type = COMP_PORT_CONNECTED;
712 event.data.comp_port_connected.comp = sink;
713 event.data.comp_port_connected.self_port = sink_def_port;
714 event.data.comp_port_connected.other_port = src_def_port;
715 ok(has_event(&event), "got the expected sink's port connected event");
716 sink_port_connected_pos = event_pos(&event);
717
718 /* Graph's ports connected */
719 event.type = GRAPH_PORTS_CONNECTED;
720 event.data.graph_ports_connected.upstream_comp = src;
721 event.data.graph_ports_connected.downstream_comp = sink;
722 event.data.graph_ports_connected.upstream_port = src_def_port;
723 event.data.graph_ports_connected.downstream_port = sink_def_port;
724 event.data.graph_ports_connected.conn = conn;
725 ok(has_event(&event), "got the expected graph's ports connected event");
726 graph_ports_connected = event_pos(&event);
727
728 /* Order of events */
729 ok(src_port_connected_pos < graph_ports_connected,
730 "event order is good (1)");
731 ok(sink_port_connected_pos < graph_ports_connected,
732 "event order is good (2)");
733 ok(src_accept_port_connection_pos < src_port_connected_pos,
734 "event order is good (3)");
735 ok(sink_accept_port_connection_pos < sink_port_connected_pos,
736 "event order is good (4)");
737
738 /* Consume sink once */
739 clear_events();
740 ret = bt_graph_consume(graph);
741 BT_ASSERT(ret == 0);
742
743 /* We're supposed to have 5 new events */
744 ok(events->len == 5, "we have the expected number of events (after consume)");
745
746 /* Source's port disconnected */
747 event.type = COMP_PORT_DISCONNECTED;
748 event.data.comp_port_disconnected.comp = src;
749 event.data.comp_port_disconnected.port = src_def_port;
750 ok(has_event(&event), "got the expected source's port disconnected event");
751 src_port_disconnected_pos = event_pos(&event);
752
753 /* Sink's port disconnected */
754 event.type = COMP_PORT_DISCONNECTED;
755 event.data.comp_port_disconnected.comp = sink;
756 event.data.comp_port_disconnected.port = sink_def_port;
757 ok(has_event(&event), "got the expected sink's port disconnected event");
758 sink_port_disconnected_pos = event_pos(&event);
759
760 /* Graph's ports disconnected */
761 event.type = GRAPH_PORTS_DISCONNECTED;
762 event.data.graph_ports_disconnected.upstream_comp = src;
763 event.data.graph_ports_disconnected.downstream_comp = sink;
764 event.data.graph_ports_disconnected.upstream_port = src_def_port;
765 event.data.graph_ports_disconnected.downstream_port = sink_def_port;
766 ok(has_event(&event), "got the expected graph's ports disconnected event");
767 graph_ports_disconnected_pos = event_pos(&event);
768
769 /* Graph's port removed (sink) */
770 event.type = GRAPH_PORT_REMOVED;
771 event.data.graph_port_removed.comp = sink;
772 event.data.graph_port_removed.port = sink_def_port;
773 ok(has_event(&event), "got the expected graph's port removed event (for sink)");
774 graph_port_removed_sink_pos = event_pos(&event);
775
776 /* Graph's port removed (source) */
777 event.type = GRAPH_PORT_REMOVED;
778 event.data.graph_port_removed.comp = src;
779 event.data.graph_port_removed.port = src_def_port;
780 ok(has_event(&event), "got the expected graph's port removed event (for source)");
781 graph_port_removed_src_pos = event_pos(&event);
782
783 /* Order of events */
784 ok(src_port_disconnected_pos < graph_ports_disconnected_pos,
785 "event order is good (5)");
786 ok(src_port_disconnected_pos < graph_port_removed_sink_pos,
787 "event order is good (6)");
788 ok(src_port_disconnected_pos < graph_port_removed_src_pos,
789 "event order is good (7)");
790 ok(sink_port_disconnected_pos < graph_ports_disconnected_pos,
791 "event order is good (8)");
792 ok(sink_port_disconnected_pos < graph_port_removed_sink_pos,
793 "event order is good (9)");
794 ok(sink_port_disconnected_pos < graph_port_removed_src_pos,
795 "event order is good (10)");
796 ok(graph_ports_disconnected_pos < graph_port_removed_sink_pos,
797 "event order is good (11)");
798 ok(graph_port_removed_src_pos < graph_ports_disconnected_pos,
799 "event order is good (12)");
800 ok(graph_port_removed_src_pos < graph_port_removed_sink_pos,
801 "event order is good (13)");
802
803 bt_put(graph);
804 bt_put(sink);
805 bt_put(src);
806 bt_put(conn);
807 bt_put(src_def_port);
808 bt_put(sink_def_port);
809 }
810
811 static
812 void test_sink_removes_port_in_port_connected(void)
813 {
814 int ret;
815 struct bt_component *src;
816 struct bt_component *sink;
817 struct bt_graph *graph;
818 struct bt_port *src_def_port;
819 struct bt_port *sink_def_port;
820 struct bt_connection *conn;
821 struct event event;
822 enum bt_graph_status status;
823 size_t src_accept_port_connection_pos;
824 size_t sink_accept_port_connection_pos;
825 size_t src_port_connected_pos;
826 size_t sink_port_connected_pos;
827 size_t graph_ports_connected_pos;
828 size_t src_port_disconnected_pos;
829 size_t sink_port_disconnected_pos;
830 size_t graph_ports_disconnected_pos;
831 size_t graph_port_removed_sink_pos;
832
833 prepare_test(TEST_SINK_REMOVES_PORT_IN_CONSUME,
834 "sink removes port in consume");
835 graph = create_graph();
836 BT_ASSERT(graph);
837 src = create_src(graph);
838 sink = create_sink(graph);
839 src_def_port = bt_component_source_get_output_port_by_name(src, "out");
840 BT_ASSERT(src_def_port);
841 sink_def_port = bt_component_sink_get_input_port_by_name(sink, "in");
842 BT_ASSERT(sink_def_port);
843 status = bt_graph_connect_ports(graph, src_def_port, sink_def_port,
844 &conn);
845 BT_ASSERT(status == 0);
846
847 /* We're supposed to have 7 events so far */
848 ok(events->len == 7, "we have the expected number of events (before consume)");
849
850 /* Source's port added */
851 event.type = GRAPH_PORT_ADDED;
852 event.data.graph_port_added.comp = src;
853 event.data.graph_port_added.port = src_def_port;
854 ok(has_event(&event), "got the expected graph's port added event (for source, initial)");
855
856 /* Sink's port added */
857 event.type = GRAPH_PORT_ADDED;
858 event.data.graph_port_added.comp = sink;
859 event.data.graph_port_added.port = sink_def_port;
860 ok(has_event(&event), "got the expected graph's port added event (for sink, initial)");
861
862 /* Source's accept port connection */
863 event.type = COMP_ACCEPT_PORT_CONNECTION;
864 event.data.comp_accept_port_connection.comp = src;
865 event.data.comp_accept_port_connection.self_port = src_def_port;
866 event.data.comp_accept_port_connection.other_port = sink_def_port;
867 ok(has_event(&event), "got the expected source's accept port connection event");
868 src_accept_port_connection_pos = event_pos(&event);
869
870 /* Sink's accept port connection */
871 event.type = COMP_ACCEPT_PORT_CONNECTION;
872 event.data.comp_accept_port_connection.comp = sink;
873 event.data.comp_accept_port_connection.self_port = sink_def_port;
874 event.data.comp_accept_port_connection.other_port = src_def_port;
875 ok(has_event(&event), "got the expected sink's accept port connection event");
876 sink_accept_port_connection_pos = event_pos(&event);
877
878 /* Source's port connected */
879 event.type = COMP_PORT_CONNECTED;
880 event.data.comp_port_connected.comp = src;
881 event.data.comp_port_connected.self_port = src_def_port;
882 event.data.comp_port_connected.other_port = sink_def_port;
883 ok(has_event(&event), "got the expected source's port connected event");
884 src_port_connected_pos = event_pos(&event);
885
886 /* Sink's port connected */
887 event.type = COMP_PORT_CONNECTED;
888 event.data.comp_port_connected.comp = sink;
889 event.data.comp_port_connected.self_port = sink_def_port;
890 event.data.comp_port_connected.other_port = src_def_port;
891 ok(has_event(&event), "got the expected sink's port connected event");
892 sink_port_connected_pos = event_pos(&event);
893
894 /* Graph's ports connected */
895 event.type = GRAPH_PORTS_CONNECTED;
896 event.data.graph_ports_connected.upstream_comp = src;
897 event.data.graph_ports_connected.downstream_comp = sink;
898 event.data.graph_ports_connected.upstream_port = src_def_port;
899 event.data.graph_ports_connected.downstream_port = sink_def_port;
900 event.data.graph_ports_connected.conn = conn;
901 ok(has_event(&event), "got the expected graph's ports connected event");
902 graph_ports_connected_pos = event_pos(&event);
903
904 /* Order of events */
905 ok(src_port_connected_pos < graph_ports_connected_pos,
906 "event order is good (1)");
907 ok(sink_port_connected_pos < graph_ports_connected_pos,
908 "event order is good (2)");
909 ok(src_accept_port_connection_pos < src_port_connected_pos,
910 "event order is good (3)");
911 ok(sink_accept_port_connection_pos < sink_port_connected_pos,
912 "event order is good (4)");
913
914 /* Consume sink once */
915 clear_events();
916 ret = bt_graph_consume(graph);
917 BT_ASSERT(ret == 0);
918
919 /* We're supposed to have 4 new events */
920 ok(events->len == 4, "we have the expected number of events (after consume)");
921
922 /* Source's port disconnected */
923 event.type = COMP_PORT_DISCONNECTED;
924 event.data.comp_port_disconnected.comp = src;
925 event.data.comp_port_disconnected.port = src_def_port;
926 ok(has_event(&event), "got the expected source's port disconnected event");
927 src_port_disconnected_pos = event_pos(&event);
928
929 /* Sink's port disconnected */
930 event.type = COMP_PORT_DISCONNECTED;
931 event.data.comp_port_disconnected.comp = sink;
932 event.data.comp_port_disconnected.port = sink_def_port;
933 ok(has_event(&event), "got the expected sink's port disconnected event");
934 sink_port_disconnected_pos = event_pos(&event);
935
936 /* Graph's ports disconnected */
937 event.type = GRAPH_PORTS_DISCONNECTED;
938 event.data.graph_ports_disconnected.upstream_comp = src;
939 event.data.graph_ports_disconnected.downstream_comp = sink;
940 event.data.graph_ports_disconnected.upstream_port = src_def_port;
941 event.data.graph_ports_disconnected.downstream_port = sink_def_port;
942 ok(has_event(&event), "got the expected graph's ports disconnected event");
943 graph_ports_disconnected_pos = event_pos(&event);
944
945 /* Graph's port removed (sink) */
946 event.type = GRAPH_PORT_REMOVED;
947 event.data.graph_port_removed.comp = sink;
948 event.data.graph_port_removed.port = sink_def_port;
949 ok(has_event(&event), "got the expected graph's port removed event (for sink)");
950 graph_port_removed_sink_pos = event_pos(&event);
951
952 /* Order of events */
953 ok(src_port_disconnected_pos < graph_ports_disconnected_pos,
954 "event order is good (5)");
955 ok(src_port_disconnected_pos < graph_port_removed_sink_pos,
956 "event order is good (7)");
957 ok(sink_port_disconnected_pos < graph_ports_disconnected_pos,
958 "event order is good (8)");
959 ok(sink_port_disconnected_pos < graph_port_removed_sink_pos,
960 "event order is good (10)");
961 ok(graph_ports_disconnected_pos < graph_port_removed_sink_pos,
962 "event order is good (11)");
963
964 bt_put(graph);
965 bt_put(sink);
966 bt_put(src);
967 bt_put(conn);
968 bt_put(src_def_port);
969 bt_put(sink_def_port);
970 }
971
972 static
973 void test_src_adds_port_in_port_connected(void)
974 {
975 struct bt_component *src;
976 struct bt_component *sink;
977 struct bt_graph *graph;
978 struct bt_port *src_def_port;
979 struct bt_port *sink_def_port;
980 struct bt_port *src_hello_port;
981 struct bt_connection *conn;
982 struct event event;
983 enum bt_graph_status status;
984 size_t src_accept_port_connection_pos;
985 size_t sink_accept_port_connection_pos;
986 size_t src_port_connected_pos;
987 size_t sink_port_connected_pos;
988 size_t graph_ports_connected_pos;
989 size_t graph_port_added_src_pos;
990
991 prepare_test(TEST_SRC_ADDS_PORT_IN_PORT_CONNECTED,
992 "source adds port in port connected");
993 graph = create_graph();
994 BT_ASSERT(graph);
995 src = create_src(graph);
996 sink = create_sink(graph);
997 src_def_port = bt_component_source_get_output_port_by_name(src, "out");
998 BT_ASSERT(src_def_port);
999 sink_def_port = bt_component_sink_get_input_port_by_name(sink, "in");
1000 BT_ASSERT(sink_def_port);
1001 status = bt_graph_connect_ports(graph, src_def_port, sink_def_port,
1002 &conn);
1003 BT_ASSERT(status == 0);
1004 src_hello_port = bt_component_source_get_output_port_by_name(src,
1005 "hello");
1006 BT_ASSERT(src_hello_port);
1007
1008 /* We're supposed to have 8 events */
1009 ok(events->len == 8, "we have the expected number of events");
1010
1011 /* Source's port added */
1012 event.type = GRAPH_PORT_ADDED;
1013 event.data.graph_port_added.comp = src;
1014 event.data.graph_port_added.port = src_def_port;
1015 ok(has_event(&event), "got the expected graph's port added event (for source, initial)");
1016
1017 /* Sink's port added */
1018 event.type = GRAPH_PORT_ADDED;
1019 event.data.graph_port_added.comp = sink;
1020 event.data.graph_port_added.port = sink_def_port;
1021 ok(has_event(&event), "got the expected graph's port added event (for sink, initial)");
1022
1023 /* Source's accept port connection */
1024 event.type = COMP_ACCEPT_PORT_CONNECTION;
1025 event.data.comp_accept_port_connection.comp = src;
1026 event.data.comp_accept_port_connection.self_port = src_def_port;
1027 event.data.comp_accept_port_connection.other_port = sink_def_port;
1028 ok(has_event(&event), "got the expected source's accept port connection event");
1029 src_accept_port_connection_pos = event_pos(&event);
1030
1031 /* Sink's accept port connection */
1032 event.type = COMP_ACCEPT_PORT_CONNECTION;
1033 event.data.comp_accept_port_connection.comp = sink;
1034 event.data.comp_accept_port_connection.self_port = sink_def_port;
1035 event.data.comp_accept_port_connection.other_port = src_def_port;
1036 ok(has_event(&event), "got the expected sink's accept port connection event");
1037 sink_accept_port_connection_pos = event_pos(&event);
1038
1039 /* Source's port connected */
1040 event.type = COMP_PORT_CONNECTED;
1041 event.data.comp_port_connected.comp = src;
1042 event.data.comp_port_connected.self_port = src_def_port;
1043 event.data.comp_port_connected.other_port = sink_def_port;
1044 ok(has_event(&event), "got the expected source's port connected event");
1045 src_port_connected_pos = event_pos(&event);
1046
1047 /* Graph's port added (source) */
1048 event.type = GRAPH_PORT_ADDED;
1049 event.data.graph_port_added.comp = src;
1050 event.data.graph_port_added.port = src_hello_port;
1051 ok(has_event(&event), "got the expected graph's port added event (for source)");
1052 graph_port_added_src_pos = event_pos(&event);
1053
1054 /* Sink's port connected */
1055 event.type = COMP_PORT_CONNECTED;
1056 event.data.comp_port_connected.comp = sink;
1057 event.data.comp_port_connected.self_port = sink_def_port;
1058 event.data.comp_port_connected.other_port = src_def_port;
1059 ok(has_event(&event), "got the expected sink's port connected event");
1060 sink_port_connected_pos = event_pos(&event);
1061
1062 /* Graph's ports connected */
1063 event.type = GRAPH_PORTS_CONNECTED;
1064 event.data.graph_ports_connected.upstream_comp = src;
1065 event.data.graph_ports_connected.downstream_comp = sink;
1066 event.data.graph_ports_connected.upstream_port = src_def_port;
1067 event.data.graph_ports_connected.downstream_port = sink_def_port;
1068 event.data.graph_ports_connected.conn = conn;
1069 ok(has_event(&event), "got the expected graph's port connected event (for source)");
1070 graph_ports_connected_pos = event_pos(&event);
1071
1072 /* Order of events */
1073 ok(src_port_connected_pos < graph_ports_connected_pos,
1074 "event order is good (1)");
1075 ok(sink_port_connected_pos < graph_ports_connected_pos,
1076 "event order is good (2)");
1077 ok(src_accept_port_connection_pos < src_port_connected_pos,
1078 "event order is good (3)");
1079 ok(sink_accept_port_connection_pos < sink_port_connected_pos,
1080 "event order is good (4)");
1081 ok(src_port_connected_pos < graph_port_added_src_pos,
1082 "event order is good (5)");
1083 ok(graph_port_added_src_pos < graph_ports_connected_pos,
1084 "event order is good (6)");
1085
1086 bt_put(graph);
1087 bt_put(sink);
1088 bt_put(src);
1089 bt_put(conn);
1090 bt_put(src_def_port);
1091 bt_put(sink_def_port);
1092 bt_put(src_hello_port);
1093 }
1094
1095 static
1096 void test_simple(void)
1097 {
1098 struct bt_component *src;
1099 struct bt_component *sink;
1100 struct bt_graph *graph;
1101 struct bt_port *src_def_port;
1102 struct bt_port *sink_def_port;
1103 struct bt_connection *conn;
1104 struct event event;
1105 enum bt_graph_status status;
1106 size_t src_accept_port_connection_pos;
1107 size_t sink_accept_port_connection_pos;
1108 size_t src_port_connected_pos;
1109 size_t sink_port_connected_pos;
1110 size_t graph_ports_connected_pos;
1111
1112 prepare_test(TEST_SIMPLE, "simple");
1113 graph = create_graph();
1114 BT_ASSERT(graph);
1115 src = create_src(graph);
1116 sink = create_sink(graph);
1117 src_def_port = bt_component_source_get_output_port_by_name(src, "out");
1118 BT_ASSERT(src_def_port);
1119 sink_def_port = bt_component_sink_get_input_port_by_name(sink, "in");
1120 BT_ASSERT(sink_def_port);
1121 status = bt_graph_connect_ports(graph, src_def_port, sink_def_port,
1122 &conn);
1123 BT_ASSERT(status == 0);
1124
1125 /* We're supposed to have 7 events */
1126 ok(events->len == 7, "we have the expected number of events");
1127
1128 /* Source's port added */
1129 event.type = GRAPH_PORT_ADDED;
1130 event.data.graph_port_added.comp = src;
1131 event.data.graph_port_added.port = src_def_port;
1132 ok(has_event(&event), "got the expected graph's port added event (for source, initial)");
1133
1134 /* Sink's port added */
1135 event.type = GRAPH_PORT_ADDED;
1136 event.data.graph_port_added.comp = sink;
1137 event.data.graph_port_added.port = sink_def_port;
1138 ok(has_event(&event), "got the expected graph's port added event (for sink, initial)");
1139
1140 /* Source's accept port connection */
1141 event.type = COMP_ACCEPT_PORT_CONNECTION;
1142 event.data.comp_accept_port_connection.comp = src;
1143 event.data.comp_accept_port_connection.self_port = src_def_port;
1144 event.data.comp_accept_port_connection.other_port = sink_def_port;
1145 ok(has_event(&event), "got the expected source's accept port connection event");
1146 src_accept_port_connection_pos = event_pos(&event);
1147
1148 /* Sink's accept port connection */
1149 event.type = COMP_ACCEPT_PORT_CONNECTION;
1150 event.data.comp_accept_port_connection.comp = sink;
1151 event.data.comp_accept_port_connection.self_port = sink_def_port;
1152 event.data.comp_accept_port_connection.other_port = src_def_port;
1153 ok(has_event(&event), "got the expected sink's accept port connection event");
1154 sink_accept_port_connection_pos = event_pos(&event);
1155
1156 /* Source's port connected */
1157 event.type = COMP_PORT_CONNECTED;
1158 event.data.comp_port_connected.comp = src;
1159 event.data.comp_port_connected.self_port = src_def_port;
1160 event.data.comp_port_connected.other_port = sink_def_port;
1161 ok(has_event(&event), "got the expected source's port connected event");
1162 src_port_connected_pos = event_pos(&event);
1163
1164 /* Sink's port connected */
1165 event.type = COMP_PORT_CONNECTED;
1166 event.data.comp_port_connected.comp = sink;
1167 event.data.comp_port_connected.self_port = sink_def_port;
1168 event.data.comp_port_connected.other_port = src_def_port;
1169 ok(has_event(&event), "got the expected sink's port connected event");
1170 sink_port_connected_pos = event_pos(&event);
1171
1172 /* Graph's port connected */
1173 event.type = GRAPH_PORTS_CONNECTED;
1174 event.data.graph_ports_connected.upstream_comp = src;
1175 event.data.graph_ports_connected.downstream_comp = sink;
1176 event.data.graph_ports_connected.upstream_port = src_def_port;
1177 event.data.graph_ports_connected.downstream_port = sink_def_port;
1178 event.data.graph_ports_connected.conn = conn;
1179 ok(has_event(&event), "got the expected graph's ports connected event");
1180 graph_ports_connected_pos = event_pos(&event);
1181
1182 /* Order of events */
1183 ok(src_port_connected_pos < graph_ports_connected_pos,
1184 "event order is good (1)");
1185 ok(sink_port_connected_pos < graph_ports_connected_pos,
1186 "event order is good (2)");
1187 ok(src_accept_port_connection_pos < src_port_connected_pos,
1188 "event order is good (3)");
1189 ok(sink_accept_port_connection_pos < sink_port_connected_pos,
1190 "event order is good (4)");
1191
1192 bt_put(graph);
1193 bt_put(sink);
1194 bt_put(src);
1195 bt_put(conn);
1196 bt_put(src_def_port);
1197 bt_put(sink_def_port);
1198 }
1199
1200 static
1201 void test_empty_graph(void)
1202 {
1203 struct bt_graph *graph;
1204
1205 prepare_test(TEST_EMPTY_GRAPH, "empty graph");
1206 graph = create_graph();
1207 ok(events->len == 0, "empty graph generates no events");
1208 bt_put(graph);
1209 }
1210
1211 int main(int argc, char **argv)
1212 {
1213 plan_tests(NR_TESTS);
1214 init_test();
1215 test_empty_graph();
1216 test_simple();
1217 test_src_adds_port_in_port_connected();
1218 test_sink_removes_port_in_port_connected();
1219 test_sink_removes_port_in_port_connected_then_src_removes_disconnected_port();
1220 fini_test();
1221 return exit_status();
1222 }
This page took 0.069681 seconds and 5 git commands to generate.