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