lib: rename transforming bt_X_borrow_Y() -> bt_X_as_Y()
[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/babeltrace.h>
21 #include <babeltrace/assert-internal.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <stdbool.h>
25 #include <glib.h>
26
27 #include "tap/tap.h"
28
29 #define NR_TESTS 99
30
31 enum event_type {
32 SRC_COMP_ACCEPT_OUTPUT_PORT_CONNECTION,
33 SINK_COMP_ACCEPT_INPUT_PORT_CONNECTION,
34 SRC_COMP_OUTPUT_PORT_CONNECTED,
35 SINK_COMP_INPUT_PORT_CONNECTED,
36 SRC_COMP_OUTPUT_PORT_DISCONNECTED,
37 SINK_COMP_INPUT_PORT_DISCONNECTED,
38 GRAPH_SRC_OUTPUT_PORT_ADDED,
39 GRAPH_SINK_INPUT_PORT_ADDED,
40 GRAPH_SRC_OUTPUT_PORT_REMOVED,
41 GRAPH_SINK_INPUT_PORT_REMOVED,
42 GRAPH_SRC_SINK_PORTS_CONNECTED,
43 GRAPH_SRC_SINK_PORTS_DISCONNECTED,
44 };
45
46 enum test {
47 TEST_EMPTY_GRAPH,
48 TEST_SIMPLE,
49 TEST_SRC_PORT_CONNECTED_ERROR,
50 TEST_SINK_PORT_CONNECTED_ERROR,
51 TEST_SRC_ADDS_PORT_IN_PORT_CONNECTED,
52 TEST_SINK_REMOVES_PORT_IN_CONSUME,
53 TEST_SINK_REMOVES_PORT_IN_CONSUME_THEN_SRC_REMOVES_DISCONNECTED_PORT,
54 };
55
56 struct event {
57 enum event_type type;
58
59 union {
60 struct {
61 struct bt_component *comp;
62 struct bt_port *self_port;
63 struct bt_port *other_port;
64 } src_comp_accept_output_port_connection;
65
66 struct {
67 struct bt_component *comp;
68 struct bt_port *self_port;
69 struct bt_port *other_port;
70 } sink_comp_accept_input_port_connection;
71
72 struct {
73 struct bt_component *comp;
74 struct bt_port *self_port;
75 struct bt_port *other_port;
76 } src_comp_output_port_connected;
77
78 struct {
79 struct bt_component *comp;
80 struct bt_port *self_port;
81 struct bt_port *other_port;
82 } sink_comp_input_port_connected;
83
84 struct {
85 struct bt_component *comp;
86 struct bt_port *self_port;
87 } src_comp_output_port_disconnected;
88
89 struct {
90 struct bt_component *comp;
91 struct bt_port *self_port;
92 } sink_comp_input_port_disconnected;
93
94 struct {
95 struct bt_component *comp;
96 struct bt_port *port;
97 } graph_src_output_port_added;
98
99 struct {
100 struct bt_component *comp;
101 struct bt_port *port;
102 } graph_sink_input_port_added;
103
104 struct {
105 struct bt_component *comp;
106 struct bt_port *port;
107 } graph_src_output_port_removed;
108
109 struct {
110 struct bt_component *comp;
111 struct bt_port *port;
112 } graph_sink_input_port_removed;
113
114 struct {
115 struct bt_component *upstream_comp;
116 struct bt_component *downstream_comp;
117 struct bt_port *upstream_port;
118 struct bt_port *downstream_port;
119 } graph_src_sink_ports_connected;
120
121 struct {
122 struct bt_component *upstream_comp;
123 struct bt_component *downstream_comp;
124 struct bt_port *upstream_port;
125 struct bt_port *downstream_port;
126 } graph_src_sink_ports_disconnected;
127 } data;
128 };
129
130 static GArray *events;
131 static struct bt_private_component_class_source *src_comp_class;
132 static struct bt_private_component_class_sink *sink_comp_class;
133 static enum test current_test;
134
135 static
136 void clear_events(void)
137 {
138 g_array_set_size(events, 0);
139 }
140
141 static
142 void append_event(struct event *event)
143 {
144 g_array_append_val(events, *event);
145 }
146
147 static
148 bool compare_events(struct event *ev_a, struct event *ev_b)
149 {
150 if (ev_a->type != ev_b->type) {
151 return false;
152 }
153
154 switch (ev_a->type) {
155 case SRC_COMP_ACCEPT_OUTPUT_PORT_CONNECTION:
156 if (ev_a->data.src_comp_accept_output_port_connection.comp !=
157 ev_b->data.src_comp_accept_output_port_connection.comp) {
158 return false;
159 }
160
161 if (ev_a->data.src_comp_accept_output_port_connection.self_port !=
162 ev_b->data.src_comp_accept_output_port_connection.self_port) {
163 return false;
164 }
165
166 if (ev_a->data.src_comp_accept_output_port_connection.other_port !=
167 ev_b->data.src_comp_accept_output_port_connection.other_port) {
168 return false;
169 }
170 break;
171 case SINK_COMP_ACCEPT_INPUT_PORT_CONNECTION:
172 if (ev_a->data.sink_comp_accept_input_port_connection.comp !=
173 ev_b->data.sink_comp_accept_input_port_connection.comp) {
174 return false;
175 }
176
177 if (ev_a->data.sink_comp_accept_input_port_connection.self_port !=
178 ev_b->data.sink_comp_accept_input_port_connection.self_port) {
179 return false;
180 }
181
182 if (ev_a->data.sink_comp_accept_input_port_connection.other_port !=
183 ev_b->data.sink_comp_accept_input_port_connection.other_port) {
184 return false;
185 }
186 break;
187 case SRC_COMP_OUTPUT_PORT_CONNECTED:
188 if (ev_a->data.src_comp_output_port_connected.comp !=
189 ev_b->data.src_comp_output_port_connected.comp) {
190 return false;
191 }
192
193 if (ev_a->data.src_comp_output_port_connected.self_port !=
194 ev_b->data.src_comp_output_port_connected.self_port) {
195 return false;
196 }
197
198 if (ev_a->data.src_comp_output_port_connected.other_port !=
199 ev_b->data.src_comp_output_port_connected.other_port) {
200 return false;
201 }
202 break;
203 case SINK_COMP_INPUT_PORT_CONNECTED:
204 if (ev_a->data.sink_comp_input_port_connected.comp !=
205 ev_b->data.sink_comp_input_port_connected.comp) {
206 return false;
207 }
208
209 if (ev_a->data.sink_comp_input_port_connected.self_port !=
210 ev_b->data.sink_comp_input_port_connected.self_port) {
211 return false;
212 }
213
214 if (ev_a->data.sink_comp_input_port_connected.other_port !=
215 ev_b->data.sink_comp_input_port_connected.other_port) {
216 return false;
217 }
218 break;
219 case SRC_COMP_OUTPUT_PORT_DISCONNECTED:
220 if (ev_a->data.src_comp_output_port_disconnected.comp !=
221 ev_b->data.src_comp_output_port_disconnected.comp) {
222 return false;
223 }
224
225 if (ev_a->data.src_comp_output_port_disconnected.self_port !=
226 ev_b->data.src_comp_output_port_disconnected.self_port) {
227 return false;
228 }
229 break;
230 case SINK_COMP_INPUT_PORT_DISCONNECTED:
231 if (ev_a->data.sink_comp_input_port_disconnected.comp !=
232 ev_b->data.sink_comp_input_port_disconnected.comp) {
233 return false;
234 }
235
236 if (ev_a->data.sink_comp_input_port_disconnected.self_port !=
237 ev_b->data.sink_comp_input_port_disconnected.self_port) {
238 return false;
239 }
240 break;
241 case GRAPH_SRC_OUTPUT_PORT_ADDED:
242 if (ev_a->data.graph_src_output_port_added.comp !=
243 ev_b->data.graph_src_output_port_added.comp) {
244 return false;
245 }
246
247 if (ev_a->data.graph_src_output_port_added.port !=
248 ev_b->data.graph_src_output_port_added.port) {
249 return false;
250 }
251 break;
252 case GRAPH_SINK_INPUT_PORT_ADDED:
253 if (ev_a->data.graph_sink_input_port_added.comp !=
254 ev_b->data.graph_sink_input_port_added.comp) {
255 return false;
256 }
257
258 if (ev_a->data.graph_sink_input_port_added.port !=
259 ev_b->data.graph_sink_input_port_added.port) {
260 return false;
261 }
262 break;
263 case GRAPH_SRC_OUTPUT_PORT_REMOVED:
264 if (ev_a->data.graph_src_output_port_removed.comp !=
265 ev_b->data.graph_src_output_port_removed.comp) {
266 return false;
267 }
268
269 if (ev_a->data.graph_src_output_port_removed.port !=
270 ev_b->data.graph_src_output_port_removed.port) {
271 return false;
272 }
273 break;
274 case GRAPH_SINK_INPUT_PORT_REMOVED:
275 if (ev_a->data.graph_sink_input_port_removed.comp !=
276 ev_b->data.graph_sink_input_port_removed.comp) {
277 return false;
278 }
279
280 if (ev_a->data.graph_sink_input_port_removed.port !=
281 ev_b->data.graph_sink_input_port_removed.port) {
282 return false;
283 }
284 break;
285 case GRAPH_SRC_SINK_PORTS_CONNECTED:
286 if (ev_a->data.graph_src_sink_ports_connected.upstream_comp !=
287 ev_b->data.graph_src_sink_ports_connected.upstream_comp) {
288 return false;
289 }
290
291 if (ev_a->data.graph_src_sink_ports_connected.downstream_comp !=
292 ev_b->data.graph_src_sink_ports_connected.downstream_comp) {
293 return false;
294 }
295
296 if (ev_a->data.graph_src_sink_ports_connected.upstream_port !=
297 ev_b->data.graph_src_sink_ports_connected.upstream_port) {
298 return false;
299 }
300
301 if (ev_a->data.graph_src_sink_ports_connected.downstream_port !=
302 ev_b->data.graph_src_sink_ports_connected.downstream_port) {
303 return false;
304 }
305 break;
306 case GRAPH_SRC_SINK_PORTS_DISCONNECTED:
307 if (ev_a->data.graph_src_sink_ports_disconnected.upstream_comp !=
308 ev_b->data.graph_src_sink_ports_disconnected.upstream_comp) {
309 return false;
310 }
311
312 if (ev_a->data.graph_src_sink_ports_disconnected.downstream_comp !=
313 ev_b->data.graph_src_sink_ports_disconnected.downstream_comp) {
314 return false;
315 }
316
317 if (ev_a->data.graph_src_sink_ports_disconnected.upstream_port !=
318 ev_b->data.graph_src_sink_ports_disconnected.upstream_port) {
319 return false;
320 }
321
322 if (ev_a->data.graph_src_sink_ports_disconnected.downstream_port !=
323 ev_b->data.graph_src_sink_ports_disconnected.downstream_port) {
324 return false;
325 }
326 break;
327 default:
328 abort();
329 }
330
331 return true;
332 }
333
334 static
335 bool has_event(struct event *event)
336 {
337 size_t i;
338
339 for (i = 0; i < events->len; i++) {
340 struct event *ev = &g_array_index(events, struct event, i);
341
342 if (compare_events(event, ev)) {
343 return true;
344 }
345 }
346
347 return false;
348 }
349
350 static
351 size_t event_pos(struct event *event)
352 {
353 size_t i;
354
355 for (i = 0; i < events->len; i++) {
356 struct event *ev = &g_array_index(events, struct event, i);
357
358 if (compare_events(event, ev)) {
359 return i;
360 }
361 }
362
363 return SIZE_MAX;
364 }
365
366 static
367 enum bt_self_notification_iterator_status src_iter_next(
368 struct bt_self_notification_iterator *self_iterator,
369 bt_notification_array notifs, uint64_t capacity,
370 uint64_t *count)
371 {
372 return BT_SELF_NOTIFICATION_ITERATOR_STATUS_ERROR;
373 }
374
375 static
376 enum bt_self_component_status src_accept_output_port_connection(
377 struct bt_self_component_source *self_comp,
378 struct bt_self_component_port_output *self_comp_port,
379 struct bt_port_input *other_port)
380 {
381 struct event event = {
382 .type = SRC_COMP_ACCEPT_OUTPUT_PORT_CONNECTION,
383 .data.src_comp_accept_output_port_connection = {
384 .comp = bt_self_component_as_component(
385 bt_self_component_source_as_self_component(
386 self_comp)),
387 .self_port = bt_self_component_port_as_port(
388 bt_self_component_port_output_as_self_component_port(
389 self_comp_port)),
390 .other_port = bt_port_input_as_port(other_port),
391 },
392 };
393
394 append_event(&event);
395 return BT_SELF_COMPONENT_STATUS_OK;
396 }
397
398 static
399 enum bt_self_component_status sink_accept_input_port_connection(
400 struct bt_self_component_sink *self_comp,
401 struct bt_self_component_port_input *self_comp_port,
402 struct bt_port_output *other_port)
403 {
404 struct event event = {
405 .type = SINK_COMP_ACCEPT_INPUT_PORT_CONNECTION,
406 .data.sink_comp_accept_input_port_connection = {
407 .comp = bt_self_component_as_component(
408 bt_self_component_sink_as_self_component(
409 self_comp)),
410 .self_port = bt_self_component_port_as_port(
411 bt_self_component_port_input_as_self_component_port(
412 self_comp_port)),
413 .other_port = bt_port_output_as_port(other_port),
414 },
415 };
416
417 append_event(&event);
418 return BT_SELF_COMPONENT_STATUS_OK;
419 }
420
421 static
422 enum bt_self_component_status src_output_port_connected(
423 struct bt_self_component_source *self_comp,
424 struct bt_self_component_port_output *self_comp_port,
425 struct bt_port_input *other_port)
426 {
427 int ret;
428 struct event event = {
429 .type = SRC_COMP_OUTPUT_PORT_CONNECTED,
430 .data.src_comp_output_port_connected = {
431 .comp = bt_self_component_as_component(
432 bt_self_component_source_as_self_component(
433 self_comp)),
434 .self_port = bt_self_component_port_as_port(
435 bt_self_component_port_output_as_self_component_port(
436 self_comp_port)),
437 .other_port = bt_port_input_as_port(other_port),
438 },
439 };
440
441 append_event(&event);
442
443 switch (current_test) {
444 case TEST_SRC_ADDS_PORT_IN_PORT_CONNECTED:
445 ret = bt_self_component_source_add_output_port(
446 self_comp, "hello", NULL, NULL);
447 BT_ASSERT(ret == 0);
448 break;
449 case TEST_SRC_PORT_CONNECTED_ERROR:
450 return BT_SELF_COMPONENT_STATUS_ERROR;
451 default:
452 break;
453 }
454
455 return BT_SELF_COMPONENT_STATUS_OK;
456 }
457
458 static
459 enum bt_self_component_status sink_input_port_connected(
460 struct bt_self_component_sink *self_comp,
461 struct bt_self_component_port_input *self_comp_port,
462 struct bt_port_output *other_port)
463 {
464 struct event event = {
465 .type = SINK_COMP_INPUT_PORT_CONNECTED,
466 .data.sink_comp_input_port_connected = {
467 .comp = bt_self_component_as_component(
468 bt_self_component_sink_as_self_component(
469 self_comp)),
470 .self_port = bt_self_component_port_as_port(
471 bt_self_component_port_input_as_self_component_port(
472 self_comp_port)),
473 .other_port = bt_port_output_as_port(other_port),
474 },
475 };
476
477 append_event(&event);
478
479 if (current_test == TEST_SINK_PORT_CONNECTED_ERROR) {
480 return BT_SELF_COMPONENT_STATUS_ERROR;
481 } else {
482 return BT_SELF_COMPONENT_STATUS_OK;
483 }
484 }
485
486 static
487 void src_output_port_disconnected(struct bt_self_component_source *self_comp,
488 struct bt_self_component_port_output *self_comp_port)
489 {
490 int ret;
491 struct event event = {
492 .type = SRC_COMP_OUTPUT_PORT_DISCONNECTED,
493 .data.src_comp_output_port_disconnected = {
494 .comp = bt_self_component_as_component(
495 bt_self_component_source_as_self_component(
496 self_comp)),
497 .self_port = bt_self_component_port_as_port(
498 bt_self_component_port_output_as_self_component_port(
499 self_comp_port)),
500 },
501 };
502
503 append_event(&event);
504
505 switch (current_test) {
506 case TEST_SINK_REMOVES_PORT_IN_CONSUME_THEN_SRC_REMOVES_DISCONNECTED_PORT:
507 ret = bt_self_component_port_remove_from_component(
508 bt_self_component_port_output_as_self_component_port(
509 self_comp_port));
510 BT_ASSERT(ret == 0);
511 default:
512 break;
513 }
514 }
515
516 static
517 void sink_input_port_disconnected(struct bt_self_component_sink *self_comp,
518 struct bt_self_component_port_input *self_comp_port)
519 {
520 struct event event = {
521 .type = SINK_COMP_INPUT_PORT_DISCONNECTED,
522 .data.sink_comp_input_port_disconnected = {
523 .comp = bt_self_component_as_component(
524 bt_self_component_sink_as_self_component(
525 self_comp)),
526 .self_port = bt_self_component_port_as_port(
527 bt_self_component_port_input_as_self_component_port(
528 self_comp_port)),
529 },
530 };
531
532 append_event(&event);
533 }
534
535 static
536 enum bt_self_component_status src_init(
537 struct bt_self_component_source *self_comp,
538 struct bt_value *params, void *init_method_data)
539 {
540 int ret;
541
542 ret = bt_self_component_source_add_output_port(
543 self_comp, "out", NULL, NULL);
544 BT_ASSERT(ret == 0);
545 return BT_SELF_COMPONENT_STATUS_OK;
546 }
547
548 static
549 enum bt_self_component_status sink_init(
550 struct bt_self_component_sink *self_comp,
551 struct bt_value *params, void *init_method_data)
552 {
553 int ret;
554
555 ret = bt_self_component_sink_add_input_port(self_comp,
556 "in", NULL, NULL);
557 BT_ASSERT(ret == 0);
558 return BT_SELF_COMPONENT_STATUS_OK;
559 }
560
561 static
562 enum bt_self_component_status sink_consume(
563 struct bt_self_component_sink *self_comp)
564 {
565 struct bt_self_component_port_input *def_port;
566 int ret;
567
568 switch (current_test) {
569 case TEST_SINK_REMOVES_PORT_IN_CONSUME:
570 case TEST_SINK_REMOVES_PORT_IN_CONSUME_THEN_SRC_REMOVES_DISCONNECTED_PORT:
571 def_port = bt_self_component_sink_borrow_input_port_by_name(
572 self_comp, "in");
573 BT_ASSERT(def_port);
574 ret = bt_self_component_port_remove_from_component(
575 bt_self_component_port_input_as_self_component_port(
576 def_port));
577 BT_ASSERT(ret == 0);
578 break;
579 default:
580 break;
581 }
582
583 return BT_SELF_COMPONENT_STATUS_OK;
584 }
585
586 static
587 void graph_src_output_port_added(struct bt_component_source *comp,
588 struct bt_port_output *port, void *data)
589 {
590 struct event event = {
591 .type = GRAPH_SRC_OUTPUT_PORT_ADDED,
592 .data.graph_src_output_port_added = {
593 .comp = bt_component_source_as_component(comp),
594 .port = bt_port_output_as_port(port),
595 },
596 };
597
598 append_event(&event);
599 }
600
601 static
602 void graph_sink_input_port_added(struct bt_component_sink *comp,
603 struct bt_port_input *port, void *data)
604 {
605 struct event event = {
606 .type = GRAPH_SINK_INPUT_PORT_ADDED,
607 .data.graph_sink_input_port_added = {
608 .comp = bt_component_sink_as_component(comp),
609 .port = bt_port_input_as_port(port),
610 },
611 };
612
613 append_event(&event);
614 }
615
616 static
617 void graph_src_output_port_removed(struct bt_component_source *comp,
618 struct bt_port_output *port, void *data)
619 {
620 struct event event = {
621 .type = GRAPH_SRC_OUTPUT_PORT_REMOVED,
622 .data.graph_src_output_port_removed = {
623 .comp = bt_component_source_as_component(comp),
624 .port = bt_port_output_as_port(port),
625 },
626 };
627
628 append_event(&event);
629 }
630
631 static
632 void graph_sink_input_port_removed(struct bt_component_sink *comp,
633 struct bt_port_input *port, void *data)
634 {
635 struct event event = {
636 .type = GRAPH_SINK_INPUT_PORT_REMOVED,
637 .data.graph_sink_input_port_removed = {
638 .comp = bt_component_sink_as_component(comp),
639 .port = bt_port_input_as_port(port),
640 },
641 };
642
643 append_event(&event);
644 }
645
646 static
647 void graph_src_sink_ports_connected(struct bt_component_source *upstream_comp,
648 struct bt_component_sink *downstream_comp,
649 struct bt_port_output *upstream_port,
650 struct bt_port_input *downstream_port, void *data)
651 {
652 struct event event = {
653 .type = GRAPH_SRC_SINK_PORTS_CONNECTED,
654 .data.graph_src_sink_ports_connected = {
655 .upstream_comp =
656 bt_component_source_as_component(upstream_comp),
657 .downstream_comp =
658 bt_component_sink_as_component(downstream_comp),
659 .upstream_port =
660 bt_port_output_as_port(upstream_port),
661 .downstream_port =
662 bt_port_input_as_port(downstream_port),
663 },
664 };
665
666 append_event(&event);
667 }
668
669 static
670 void graph_src_sink_ports_disconnected(struct bt_component_source *upstream_comp,
671 struct bt_component_sink *downstream_comp,
672 struct bt_port_output *upstream_port,
673 struct bt_port_input *downstream_port, void *data)
674 {
675 struct event event = {
676 .type = GRAPH_SRC_SINK_PORTS_DISCONNECTED,
677 .data.graph_src_sink_ports_disconnected = {
678 .upstream_comp =
679 bt_component_source_as_component(upstream_comp),
680 .downstream_comp =
681 bt_component_sink_as_component(downstream_comp),
682 .upstream_port =
683 bt_port_output_as_port(upstream_port),
684 .downstream_port =
685 bt_port_input_as_port(downstream_port),
686 },
687 };
688
689 append_event(&event);
690 }
691
692 static
693 void init_test(void)
694 {
695 int ret;
696
697 src_comp_class = bt_private_component_class_source_create(
698 "src", src_iter_next);
699 BT_ASSERT(src_comp_class);
700 ret = bt_private_component_class_source_set_init_method(
701 src_comp_class, src_init);
702 BT_ASSERT(ret == 0);
703 ret = bt_private_component_class_source_set_accept_output_port_connection_method(
704 src_comp_class, src_accept_output_port_connection);
705 BT_ASSERT(ret == 0);
706 ret = bt_private_component_class_source_set_output_port_connected_method(
707 src_comp_class, src_output_port_connected);
708 BT_ASSERT(ret == 0);
709 ret = bt_private_component_class_source_set_output_port_disconnected_method(
710 src_comp_class, src_output_port_disconnected);
711 BT_ASSERT(ret == 0);
712 sink_comp_class = bt_private_component_class_sink_create("sink",
713 sink_consume);
714 BT_ASSERT(sink_comp_class);
715 ret = bt_private_component_class_sink_set_init_method(sink_comp_class,
716 sink_init);
717 BT_ASSERT(ret == 0);
718 ret = bt_private_component_class_sink_set_accept_input_port_connection_method(
719 sink_comp_class, sink_accept_input_port_connection);
720 BT_ASSERT(ret == 0);
721 ret = bt_private_component_class_sink_set_input_port_connected_method(
722 sink_comp_class, sink_input_port_connected);
723 BT_ASSERT(ret == 0);
724 ret = bt_private_component_class_sink_set_input_port_disconnected_method(
725 sink_comp_class, sink_input_port_disconnected);
726 BT_ASSERT(ret == 0);
727 events = g_array_new(FALSE, TRUE, sizeof(struct event));
728 BT_ASSERT(events);
729 }
730
731 static
732 void fini_test(void)
733 {
734 bt_object_put_ref(src_comp_class);
735 bt_object_put_ref(sink_comp_class);
736 g_array_free(events, TRUE);
737 }
738
739 static
740 struct bt_component_source *create_src(struct bt_private_graph *graph)
741 {
742 struct bt_component_source *comp;
743 int ret;
744
745 ret = bt_private_graph_add_source_component(graph,
746 bt_private_component_class_source_as_component_class_source(
747 src_comp_class),
748 "src-comp", NULL, &comp);
749 BT_ASSERT(ret == 0);
750 return comp;
751 }
752
753 static
754 struct bt_component_sink *create_sink(struct bt_private_graph *graph)
755 {
756 struct bt_component_sink *comp;
757 int ret;
758
759 ret = bt_private_graph_add_sink_component(graph,
760 bt_private_component_class_sink_as_component_class_sink(
761 sink_comp_class),
762 "sink-comp", NULL, &comp);
763 BT_ASSERT(ret == 0);
764 return comp;
765 }
766
767 static
768 struct bt_private_graph *create_graph(void)
769 {
770 struct bt_private_graph *graph = bt_private_graph_create();
771 int ret;
772
773 BT_ASSERT(graph);
774 ret = bt_private_graph_add_source_component_output_port_added_listener(
775 graph, graph_src_output_port_added, NULL, NULL, NULL);
776 BT_ASSERT(ret >= 0);
777 ret = bt_private_graph_add_sink_component_input_port_added_listener(
778 graph, graph_sink_input_port_added, NULL, NULL, NULL);
779 BT_ASSERT(ret >= 0);
780 ret = bt_private_graph_add_source_component_output_port_removed_listener(
781 graph, graph_src_output_port_removed, NULL, NULL, NULL);
782 BT_ASSERT(ret >= 0);
783 ret = bt_private_graph_add_sink_component_input_port_removed_listener(
784 graph, graph_sink_input_port_removed, NULL, NULL, NULL);
785 BT_ASSERT(ret >= 0);
786 ret = bt_private_graph_add_source_sink_component_ports_connected_listener(
787 graph, graph_src_sink_ports_connected, NULL, NULL, NULL);
788 BT_ASSERT(ret >= 0);
789 ret = bt_private_graph_add_source_sink_component_ports_disconnected_listener(
790 graph, graph_src_sink_ports_disconnected, NULL, NULL, NULL);
791 BT_ASSERT(ret >= 0);
792 return graph;
793 }
794
795 static
796 void prepare_test(enum test test, const char *name)
797 {
798 clear_events();
799 current_test = test;
800 diag("test: %s", name);
801 }
802
803 static
804 void test_sink_removes_port_in_consume_then_src_removes_disconnected_port(void)
805 {
806 int ret;
807 struct bt_component_source *src;
808 struct bt_component_sink *sink;
809 struct bt_component *gsrc;
810 struct bt_component *gsink;
811 struct bt_private_graph *graph;
812 struct bt_port_output *src_def_port;
813 struct bt_port_input *sink_def_port;
814 struct bt_port *gsrc_def_port;
815 struct bt_port *gsink_def_port;
816 struct event event;
817 enum bt_graph_status status;
818 size_t src_accept_port_connection_pos;
819 size_t sink_accept_port_connection_pos;
820 size_t src_port_connected_pos;
821 size_t sink_port_connected_pos;
822 size_t graph_ports_connected_pos;
823 size_t src_port_disconnected_pos;
824 size_t sink_port_disconnected_pos;
825 size_t graph_ports_disconnected_pos;
826 size_t graph_port_removed_src_pos;
827 size_t graph_port_removed_sink_pos;
828
829 prepare_test(TEST_SINK_REMOVES_PORT_IN_CONSUME_THEN_SRC_REMOVES_DISCONNECTED_PORT,
830 "sink removes port in consume, then source removes disconnected port");
831 graph = create_graph();
832 BT_ASSERT(graph);
833 src = create_src(graph);
834 sink = create_sink(graph);
835 src_def_port = bt_component_source_borrow_output_port_by_name(src, "out");
836 BT_ASSERT(src_def_port);
837 sink_def_port = bt_component_sink_borrow_input_port_by_name(sink, "in");
838 BT_ASSERT(sink_def_port);
839 status = bt_private_graph_connect_ports(graph, src_def_port,
840 sink_def_port, NULL);
841 BT_ASSERT(status == 0);
842 gsrc = bt_component_source_as_component(src);
843 gsink = bt_component_sink_as_component(sink);
844 gsrc_def_port = bt_port_output_as_port(src_def_port);
845 gsink_def_port = bt_port_input_as_port(sink_def_port);
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_SRC_OUTPUT_PORT_ADDED;
852 event.data.graph_src_output_port_added.comp = gsrc;
853 event.data.graph_src_output_port_added.port = gsrc_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_SINK_INPUT_PORT_ADDED;
858 event.data.graph_sink_input_port_added.comp = gsink;
859 event.data.graph_sink_input_port_added.port = gsink_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 = SRC_COMP_ACCEPT_OUTPUT_PORT_CONNECTION;
864 event.data.src_comp_accept_output_port_connection.comp = gsrc;
865 event.data.src_comp_accept_output_port_connection.self_port = gsrc_def_port;
866 event.data.src_comp_accept_output_port_connection.other_port = gsink_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 = SINK_COMP_ACCEPT_INPUT_PORT_CONNECTION;
872 event.data.sink_comp_accept_input_port_connection.comp = gsink;
873 event.data.sink_comp_accept_input_port_connection.self_port = gsink_def_port;
874 event.data.sink_comp_accept_input_port_connection.other_port = gsrc_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 = SRC_COMP_OUTPUT_PORT_CONNECTED;
880 event.data.src_comp_output_port_connected.comp = gsrc;
881 event.data.src_comp_output_port_connected.self_port = gsrc_def_port;
882 event.data.src_comp_output_port_connected.other_port = gsink_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 = SINK_COMP_INPUT_PORT_CONNECTED;
888 event.data.sink_comp_input_port_connected.comp = gsink;
889 event.data.sink_comp_input_port_connected.self_port = gsink_def_port;
890 event.data.sink_comp_input_port_connected.other_port = gsrc_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_SRC_SINK_PORTS_CONNECTED;
896 event.data.graph_src_sink_ports_connected.upstream_comp = gsrc;
897 event.data.graph_src_sink_ports_connected.downstream_comp = gsink;
898 event.data.graph_src_sink_ports_connected.upstream_port = gsrc_def_port;
899 event.data.graph_src_sink_ports_connected.downstream_port = gsink_def_port;
900 ok(has_event(&event), "got the expected graph's ports connected event");
901 graph_ports_connected_pos = event_pos(&event);
902
903 /* Order of events */
904 ok(src_port_connected_pos < graph_ports_connected_pos,
905 "event order is good (1)");
906 ok(sink_port_connected_pos < graph_ports_connected_pos,
907 "event order is good (2)");
908 ok(src_accept_port_connection_pos < src_port_connected_pos,
909 "event order is good (3)");
910 ok(sink_accept_port_connection_pos < sink_port_connected_pos,
911 "event order is good (4)");
912
913 /* Consume sink once */
914 clear_events();
915 ret = bt_private_graph_consume(graph);
916 BT_ASSERT(ret == 0);
917
918 /* We're supposed to have 5 new events */
919 ok(events->len == 5, "we have the expected number of events (after consume)");
920
921 /* Source's port disconnected */
922 event.type = SRC_COMP_OUTPUT_PORT_DISCONNECTED;
923 event.data.src_comp_output_port_disconnected.comp = gsrc;
924 event.data.src_comp_output_port_disconnected.self_port = gsrc_def_port;
925 ok(has_event(&event), "got the expected source's port disconnected event");
926 src_port_disconnected_pos = event_pos(&event);
927
928 /* Sink's port disconnected */
929 event.type = SINK_COMP_INPUT_PORT_DISCONNECTED;
930 event.data.sink_comp_input_port_disconnected.comp = gsink;
931 event.data.sink_comp_input_port_disconnected.self_port = gsink_def_port;
932 ok(has_event(&event), "got the expected sink's port disconnected event");
933 sink_port_disconnected_pos = event_pos(&event);
934
935 /* Graph's ports disconnected */
936 event.type = GRAPH_SRC_SINK_PORTS_DISCONNECTED;
937 event.data.graph_src_sink_ports_disconnected.upstream_comp = gsrc;
938 event.data.graph_src_sink_ports_disconnected.downstream_comp = gsink;
939 event.data.graph_src_sink_ports_disconnected.upstream_port = gsrc_def_port;
940 event.data.graph_src_sink_ports_disconnected.downstream_port = gsink_def_port;
941 ok(has_event(&event), "got the expected graph's ports disconnected event");
942 graph_ports_disconnected_pos = event_pos(&event);
943
944 /* Graph's port removed (sink) */
945 event.type = GRAPH_SINK_INPUT_PORT_REMOVED;
946 event.data.graph_sink_input_port_removed.comp = gsink;
947 event.data.graph_sink_input_port_removed.port = gsink_def_port;
948 ok(has_event(&event), "got the expected graph's port removed event (for sink)");
949 graph_port_removed_sink_pos = event_pos(&event);
950
951 /* Graph's port removed (source) */
952 event.type = GRAPH_SRC_OUTPUT_PORT_REMOVED;
953 event.data.graph_src_output_port_removed.comp = gsrc;
954 event.data.graph_src_output_port_removed.port = gsrc_def_port;
955 ok(has_event(&event), "got the expected graph's port removed event (for source)");
956 graph_port_removed_src_pos = event_pos(&event);
957
958 /* Order of events */
959 ok(src_port_disconnected_pos < graph_ports_disconnected_pos,
960 "event order is good (5)");
961 ok(src_port_disconnected_pos < graph_port_removed_sink_pos,
962 "event order is good (6)");
963 ok(src_port_disconnected_pos < graph_port_removed_src_pos,
964 "event order is good (7)");
965 ok(sink_port_disconnected_pos < graph_ports_disconnected_pos,
966 "event order is good (8)");
967 ok(sink_port_disconnected_pos < graph_port_removed_sink_pos,
968 "event order is good (9)");
969 ok(sink_port_disconnected_pos < graph_port_removed_src_pos,
970 "event order is good (10)");
971 ok(graph_ports_disconnected_pos < graph_port_removed_sink_pos,
972 "event order is good (11)");
973 ok(graph_port_removed_src_pos < graph_ports_disconnected_pos,
974 "event order is good (12)");
975 ok(graph_port_removed_src_pos < graph_port_removed_sink_pos,
976 "event order is good (13)");
977
978 bt_object_put_ref(graph);
979 bt_object_put_ref(sink);
980 bt_object_put_ref(src);
981 }
982
983 static
984 void test_sink_removes_port_in_consume(void)
985 {
986 int ret;
987 struct bt_component_source *src;
988 struct bt_component_sink *sink;
989 struct bt_component *gsrc;
990 struct bt_component *gsink;
991 struct bt_private_graph *graph;
992 struct bt_port_output *src_def_port;
993 struct bt_port_input *sink_def_port;
994 struct bt_port *gsrc_def_port;
995 struct bt_port *gsink_def_port;
996 struct event event;
997 enum bt_graph_status status;
998 size_t src_accept_port_connection_pos;
999 size_t sink_accept_port_connection_pos;
1000 size_t src_port_connected_pos;
1001 size_t sink_port_connected_pos;
1002 size_t graph_ports_connected_pos;
1003 size_t src_port_disconnected_pos;
1004 size_t sink_port_disconnected_pos;
1005 size_t graph_ports_disconnected_pos;
1006 size_t graph_port_removed_sink_pos;
1007
1008 prepare_test(TEST_SINK_REMOVES_PORT_IN_CONSUME,
1009 "sink removes port in consume");
1010 graph = create_graph();
1011 BT_ASSERT(graph);
1012 src = create_src(graph);
1013 sink = create_sink(graph);
1014 src_def_port = bt_component_source_borrow_output_port_by_name(src, "out");
1015 BT_ASSERT(src_def_port);
1016 sink_def_port = bt_component_sink_borrow_input_port_by_name(sink, "in");
1017 BT_ASSERT(sink_def_port);
1018 status = bt_private_graph_connect_ports(graph, src_def_port,
1019 sink_def_port, NULL);
1020 BT_ASSERT(status == 0);
1021 gsrc = bt_component_source_as_component(src);
1022 gsink = bt_component_sink_as_component(sink);
1023 gsrc_def_port = bt_port_output_as_port(src_def_port);
1024 gsink_def_port = bt_port_input_as_port(sink_def_port);
1025
1026 /* We're supposed to have 7 events so far */
1027 ok(events->len == 7, "we have the expected number of events (before consume)");
1028
1029 /* Source's port added */
1030 event.type = GRAPH_SRC_OUTPUT_PORT_ADDED;
1031 event.data.graph_src_output_port_added.comp = gsrc;
1032 event.data.graph_src_output_port_added.port = gsrc_def_port;
1033 ok(has_event(&event), "got the expected graph's port added event (for source, initial)");
1034
1035 /* Sink's port added */
1036 event.type = GRAPH_SINK_INPUT_PORT_ADDED;
1037 event.data.graph_sink_input_port_added.comp = gsink;
1038 event.data.graph_sink_input_port_added.port = gsink_def_port;
1039 ok(has_event(&event), "got the expected graph's port added event (for sink, initial)");
1040
1041 /* Source's accept port connection */
1042 event.type = SRC_COMP_ACCEPT_OUTPUT_PORT_CONNECTION;
1043 event.data.src_comp_accept_output_port_connection.comp = gsrc;
1044 event.data.src_comp_accept_output_port_connection.self_port = gsrc_def_port;
1045 event.data.src_comp_accept_output_port_connection.other_port = gsink_def_port;
1046 ok(has_event(&event), "got the expected source's accept port connection event");
1047 src_accept_port_connection_pos = event_pos(&event);
1048
1049 /* Sink's accept port connection */
1050 event.type = SINK_COMP_ACCEPT_INPUT_PORT_CONNECTION;
1051 event.data.sink_comp_accept_input_port_connection.comp = gsink;
1052 event.data.sink_comp_accept_input_port_connection.self_port = gsink_def_port;
1053 event.data.sink_comp_accept_input_port_connection.other_port = gsrc_def_port;
1054 ok(has_event(&event), "got the expected sink's accept port connection event");
1055 sink_accept_port_connection_pos = event_pos(&event);
1056
1057 /* Source's port connected */
1058 event.type = SRC_COMP_OUTPUT_PORT_CONNECTED;
1059 event.data.src_comp_output_port_connected.comp = gsrc;
1060 event.data.src_comp_output_port_connected.self_port = gsrc_def_port;
1061 event.data.src_comp_output_port_connected.other_port = gsink_def_port;
1062 ok(has_event(&event), "got the expected source's port connected event");
1063 src_port_connected_pos = event_pos(&event);
1064
1065 /* Sink's port connected */
1066 event.type = SINK_COMP_INPUT_PORT_CONNECTED;
1067 event.data.sink_comp_input_port_connected.comp = gsink;
1068 event.data.sink_comp_input_port_connected.self_port = gsink_def_port;
1069 event.data.sink_comp_input_port_connected.other_port = gsrc_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_SRC_SINK_PORTS_CONNECTED;
1075 event.data.graph_src_sink_ports_connected.upstream_comp = gsrc;
1076 event.data.graph_src_sink_ports_connected.downstream_comp = gsink;
1077 event.data.graph_src_sink_ports_connected.upstream_port = gsrc_def_port;
1078 event.data.graph_src_sink_ports_connected.downstream_port = gsink_def_port;
1079 ok(has_event(&event), "got the expected graph's ports connected event");
1080 graph_ports_connected_pos = event_pos(&event);
1081
1082 /* Order of events */
1083 ok(src_port_connected_pos < graph_ports_connected_pos,
1084 "event order is good (1)");
1085 ok(sink_port_connected_pos < graph_ports_connected_pos,
1086 "event order is good (2)");
1087 ok(src_accept_port_connection_pos < src_port_connected_pos,
1088 "event order is good (3)");
1089 ok(sink_accept_port_connection_pos < sink_port_connected_pos,
1090 "event order is good (4)");
1091
1092 /* Consume sink once */
1093 clear_events();
1094 ret = bt_private_graph_consume(graph);
1095 BT_ASSERT(ret == 0);
1096
1097 /* We're supposed to have 4 new events */
1098 ok(events->len == 4, "we have the expected number of events (after consume)");
1099
1100 /* Source's port disconnected */
1101 event.type = SRC_COMP_OUTPUT_PORT_DISCONNECTED;
1102 event.data.src_comp_output_port_disconnected.comp = gsrc;
1103 event.data.src_comp_output_port_disconnected.self_port = gsrc_def_port;
1104 ok(has_event(&event), "got the expected source's port disconnected event");
1105 src_port_disconnected_pos = event_pos(&event);
1106
1107 /* Sink's port disconnected */
1108 event.type = SINK_COMP_INPUT_PORT_DISCONNECTED;
1109 event.data.sink_comp_input_port_disconnected.comp = gsink;
1110 event.data.sink_comp_input_port_disconnected.self_port = gsink_def_port;
1111 ok(has_event(&event), "got the expected sink's port disconnected event");
1112 sink_port_disconnected_pos = event_pos(&event);
1113
1114 /* Graph's ports disconnected */
1115 event.type = GRAPH_SRC_SINK_PORTS_DISCONNECTED;
1116 event.data.graph_src_sink_ports_disconnected.upstream_comp = gsrc;
1117 event.data.graph_src_sink_ports_disconnected.downstream_comp = gsink;
1118 event.data.graph_src_sink_ports_disconnected.upstream_port = gsrc_def_port;
1119 event.data.graph_src_sink_ports_disconnected.downstream_port = gsink_def_port;
1120 ok(has_event(&event), "got the expected graph's ports disconnected event");
1121 graph_ports_disconnected_pos = event_pos(&event);
1122
1123 /* Graph's port removed (sink) */
1124 event.type = GRAPH_SINK_INPUT_PORT_REMOVED;
1125 event.data.graph_sink_input_port_removed.comp = gsink;
1126 event.data.graph_sink_input_port_removed.port = gsink_def_port;
1127 ok(has_event(&event), "got the expected graph's port removed event (for sink)");
1128 graph_port_removed_sink_pos = event_pos(&event);
1129
1130 /* Order of events */
1131 ok(src_port_disconnected_pos < graph_ports_disconnected_pos,
1132 "event order is good (5)");
1133 ok(src_port_disconnected_pos < graph_port_removed_sink_pos,
1134 "event order is good (7)");
1135 ok(sink_port_disconnected_pos < graph_ports_disconnected_pos,
1136 "event order is good (8)");
1137 ok(sink_port_disconnected_pos < graph_port_removed_sink_pos,
1138 "event order is good (10)");
1139 ok(graph_ports_disconnected_pos < graph_port_removed_sink_pos,
1140 "event order is good (11)");
1141
1142 bt_object_put_ref(sink);
1143 bt_object_put_ref(src);
1144 bt_object_put_ref(graph);
1145 }
1146
1147 static
1148 void test_src_adds_port_in_port_connected(void)
1149 {
1150 struct bt_component_source *src;
1151 struct bt_component_sink *sink;
1152 struct bt_component *gsrc;
1153 struct bt_component *gsink;
1154 struct bt_private_graph *graph;
1155 struct bt_port_output *src_def_port;
1156 struct bt_port_output *src_hello_port;
1157 struct bt_port_input *sink_def_port;
1158 struct bt_port *gsrc_def_port;
1159 struct bt_port *gsrc_hello_port;
1160 struct bt_port *gsink_def_port;
1161 struct event event;
1162 enum bt_graph_status status;
1163 size_t src_accept_port_connection_pos;
1164 size_t sink_accept_port_connection_pos;
1165 size_t src_port_connected_pos;
1166 size_t sink_port_connected_pos;
1167 size_t graph_ports_connected_pos;
1168 size_t graph_port_added_src_pos;
1169
1170 prepare_test(TEST_SRC_ADDS_PORT_IN_PORT_CONNECTED,
1171 "source adds port in port connected");
1172 graph = create_graph();
1173 BT_ASSERT(graph);
1174 src = create_src(graph);
1175 sink = create_sink(graph);
1176 src_def_port = bt_component_source_borrow_output_port_by_name(src, "out");
1177 BT_ASSERT(src_def_port);
1178 sink_def_port = bt_component_sink_borrow_input_port_by_name(sink, "in");
1179 BT_ASSERT(sink_def_port);
1180 status = bt_private_graph_connect_ports(graph, src_def_port,
1181 sink_def_port, NULL);
1182 BT_ASSERT(status == 0);
1183 src_hello_port = bt_component_source_borrow_output_port_by_name(src,
1184 "hello");
1185 BT_ASSERT(src_hello_port);
1186 gsrc = bt_component_source_as_component(src);
1187 gsink = bt_component_sink_as_component(sink);
1188 gsrc_def_port = bt_port_output_as_port(src_def_port);
1189 gsrc_hello_port = bt_port_output_as_port(src_hello_port);
1190 gsink_def_port = bt_port_input_as_port(sink_def_port);
1191
1192 /* We're supposed to have 8 events */
1193 ok(events->len == 8, "we have the expected number of events");
1194
1195 /* Source's port added */
1196 event.type = GRAPH_SRC_OUTPUT_PORT_ADDED;
1197 event.data.graph_src_output_port_added.comp = gsrc;
1198 event.data.graph_src_output_port_added.port = gsrc_def_port;
1199 ok(has_event(&event), "got the expected graph's port added event (for source, initial)");
1200
1201 /* Sink's port added */
1202 event.type = GRAPH_SINK_INPUT_PORT_ADDED;
1203 event.data.graph_sink_input_port_added.comp = gsink;
1204 event.data.graph_sink_input_port_added.port = gsink_def_port;
1205 ok(has_event(&event), "got the expected graph's port added event (for sink, initial)");
1206
1207 /* Source's accept port connection */
1208 event.type = SRC_COMP_ACCEPT_OUTPUT_PORT_CONNECTION;
1209 event.data.src_comp_accept_output_port_connection.comp = gsrc;
1210 event.data.src_comp_accept_output_port_connection.self_port = gsrc_def_port;
1211 event.data.src_comp_accept_output_port_connection.other_port = gsink_def_port;
1212 ok(has_event(&event), "got the expected source's accept port connection event");
1213 src_accept_port_connection_pos = event_pos(&event);
1214
1215 /* Sink's accept port connection */
1216 event.type = SINK_COMP_ACCEPT_INPUT_PORT_CONNECTION;
1217 event.data.sink_comp_accept_input_port_connection.comp = gsink;
1218 event.data.sink_comp_accept_input_port_connection.self_port = gsink_def_port;
1219 event.data.sink_comp_accept_input_port_connection.other_port = gsrc_def_port;
1220 ok(has_event(&event), "got the expected sink's accept port connection event");
1221 sink_accept_port_connection_pos = event_pos(&event);
1222
1223 /* Source's port connected */
1224 event.type = SRC_COMP_OUTPUT_PORT_CONNECTED;
1225 event.data.src_comp_output_port_connected.comp = gsrc;
1226 event.data.src_comp_output_port_connected.self_port = gsrc_def_port;
1227 event.data.src_comp_output_port_connected.other_port = gsink_def_port;
1228 ok(has_event(&event), "got the expected source's port connected event");
1229 src_port_connected_pos = event_pos(&event);
1230
1231 /* Graph's port added (source) */
1232 event.type = GRAPH_SRC_OUTPUT_PORT_ADDED;
1233 event.data.graph_src_output_port_added.comp = gsrc;
1234 event.data.graph_src_output_port_added.port = gsrc_hello_port;
1235 ok(has_event(&event), "got the expected graph's port added event (for source)");
1236 graph_port_added_src_pos = event_pos(&event);
1237
1238 /* Sink's port connected */
1239 event.type = SINK_COMP_INPUT_PORT_CONNECTED;
1240 event.data.sink_comp_input_port_connected.comp = gsink;
1241 event.data.sink_comp_input_port_connected.self_port = gsink_def_port;
1242 event.data.sink_comp_input_port_connected.other_port = gsrc_def_port;
1243 ok(has_event(&event), "got the expected sink's port connected event");
1244 sink_port_connected_pos = event_pos(&event);
1245
1246 /* Graph's ports connected */
1247 event.type = GRAPH_SRC_SINK_PORTS_CONNECTED;
1248 event.data.graph_src_sink_ports_connected.upstream_comp = gsrc;
1249 event.data.graph_src_sink_ports_connected.downstream_comp = gsink;
1250 event.data.graph_src_sink_ports_connected.upstream_port = gsrc_def_port;
1251 event.data.graph_src_sink_ports_connected.downstream_port = gsink_def_port;
1252 ok(has_event(&event), "got the expected graph's ports connected event");
1253 graph_ports_connected_pos = event_pos(&event);
1254
1255 /* Order of events */
1256 ok(src_port_connected_pos < graph_ports_connected_pos,
1257 "event order is good (1)");
1258 ok(sink_port_connected_pos < graph_ports_connected_pos,
1259 "event order is good (2)");
1260 ok(src_accept_port_connection_pos < src_port_connected_pos,
1261 "event order is good (3)");
1262 ok(sink_accept_port_connection_pos < sink_port_connected_pos,
1263 "event order is good (4)");
1264 ok(src_port_connected_pos < graph_port_added_src_pos,
1265 "event order is good (5)");
1266 ok(graph_port_added_src_pos < graph_ports_connected_pos,
1267 "event order is good (6)");
1268
1269 bt_object_put_ref(src);
1270 bt_object_put_ref(sink);
1271 bt_object_put_ref(graph);
1272 }
1273
1274 static
1275 void test_simple(void)
1276 {
1277 struct bt_component_source *src;
1278 struct bt_component_sink *sink;
1279 struct bt_component *gsrc;
1280 struct bt_component *gsink;
1281 struct bt_private_graph *graph;
1282 struct bt_port_output *src_def_port;
1283 struct bt_port_input *sink_def_port;
1284 struct bt_port *gsrc_def_port;
1285 struct bt_port *gsink_def_port;
1286 struct event event;
1287 enum bt_graph_status status;
1288 size_t src_accept_port_connection_pos;
1289 size_t sink_accept_port_connection_pos;
1290 size_t src_port_connected_pos;
1291 size_t sink_port_connected_pos;
1292 size_t graph_ports_connected_pos;
1293
1294 prepare_test(TEST_SIMPLE, "simple");
1295 graph = create_graph();
1296 BT_ASSERT(graph);
1297 src = create_src(graph);
1298 sink = create_sink(graph);
1299 src_def_port = bt_component_source_borrow_output_port_by_name(src, "out");
1300 BT_ASSERT(src_def_port);
1301 sink_def_port = bt_component_sink_borrow_input_port_by_name(sink, "in");
1302 BT_ASSERT(sink_def_port);
1303 status = bt_private_graph_connect_ports(graph, src_def_port,
1304 sink_def_port, NULL);
1305 BT_ASSERT(status == 0);
1306 gsrc = bt_component_source_as_component(src);
1307 gsink = bt_component_sink_as_component(sink);
1308 gsrc_def_port = bt_port_output_as_port(src_def_port);
1309 gsink_def_port = bt_port_input_as_port(sink_def_port);
1310
1311 /* We're supposed to have 7 events */
1312 ok(events->len == 7, "we have the expected number of events");
1313
1314 /* Source's port added */
1315 event.type = GRAPH_SRC_OUTPUT_PORT_ADDED;
1316 event.data.graph_src_output_port_added.comp = gsrc;
1317 event.data.graph_src_output_port_added.port = gsrc_def_port;
1318 ok(has_event(&event), "got the expected graph's port added event (for source, initial)");
1319
1320 /* Sink's port added */
1321 event.type = GRAPH_SINK_INPUT_PORT_ADDED;
1322 event.data.graph_sink_input_port_added.comp = gsink;
1323 event.data.graph_sink_input_port_added.port = gsink_def_port;
1324 ok(has_event(&event), "got the expected graph's port added event (for sink, initial)");
1325
1326 /* Source's accept port connection */
1327 event.type = SRC_COMP_ACCEPT_OUTPUT_PORT_CONNECTION;
1328 event.data.src_comp_accept_output_port_connection.comp = gsrc;
1329 event.data.src_comp_accept_output_port_connection.self_port = gsrc_def_port;
1330 event.data.src_comp_accept_output_port_connection.other_port = gsink_def_port;
1331 ok(has_event(&event), "got the expected source's accept port connection event");
1332 src_accept_port_connection_pos = event_pos(&event);
1333
1334 /* Sink's accept port connection */
1335 event.type = SINK_COMP_ACCEPT_INPUT_PORT_CONNECTION;
1336 event.data.sink_comp_accept_input_port_connection.comp = gsink;
1337 event.data.sink_comp_accept_input_port_connection.self_port = gsink_def_port;
1338 event.data.sink_comp_accept_input_port_connection.other_port = gsrc_def_port;
1339 ok(has_event(&event), "got the expected sink's accept port connection event");
1340 sink_accept_port_connection_pos = event_pos(&event);
1341
1342 /* Source's port connected */
1343 event.type = SRC_COMP_OUTPUT_PORT_CONNECTED;
1344 event.data.src_comp_output_port_connected.comp = gsrc;
1345 event.data.src_comp_output_port_connected.self_port = gsrc_def_port;
1346 event.data.src_comp_output_port_connected.other_port = gsink_def_port;
1347 ok(has_event(&event), "got the expected source's port connected event");
1348 src_port_connected_pos = event_pos(&event);
1349
1350 /* Sink's port connected */
1351 event.type = SINK_COMP_INPUT_PORT_CONNECTED;
1352 event.data.sink_comp_input_port_connected.comp = gsink;
1353 event.data.sink_comp_input_port_connected.self_port = gsink_def_port;
1354 event.data.sink_comp_input_port_connected.other_port = gsrc_def_port;
1355 ok(has_event(&event), "got the expected sink's port connected event");
1356 sink_port_connected_pos = event_pos(&event);
1357
1358 /* Graph's ports connected */
1359 event.type = GRAPH_SRC_SINK_PORTS_CONNECTED;
1360 event.data.graph_src_sink_ports_connected.upstream_comp = gsrc;
1361 event.data.graph_src_sink_ports_connected.downstream_comp = gsink;
1362 event.data.graph_src_sink_ports_connected.upstream_port = gsrc_def_port;
1363 event.data.graph_src_sink_ports_connected.downstream_port = gsink_def_port;
1364 ok(has_event(&event), "got the expected graph's ports connected event");
1365 graph_ports_connected_pos = event_pos(&event);
1366
1367 /* Order of events */
1368 ok(src_port_connected_pos < graph_ports_connected_pos,
1369 "event order is good (1)");
1370 ok(sink_port_connected_pos < graph_ports_connected_pos,
1371 "event order is good (2)");
1372 ok(src_accept_port_connection_pos < src_port_connected_pos,
1373 "event order is good (3)");
1374 ok(sink_accept_port_connection_pos < sink_port_connected_pos,
1375 "event order is good (4)");
1376
1377 bt_object_put_ref(sink);
1378 bt_object_put_ref(graph);
1379 bt_object_put_ref(src);
1380 }
1381
1382 static
1383 void test_src_port_connected_error(void)
1384 {
1385 struct bt_component_source *src;
1386 struct bt_component_sink *sink;
1387 struct bt_component *gsrc;
1388 struct bt_component *gsink;
1389 struct bt_private_graph *graph;
1390 struct bt_port_output *src_def_port;
1391 struct bt_port_input *sink_def_port;
1392 struct bt_port *gsrc_def_port;
1393 struct bt_port *gsink_def_port;
1394 struct bt_connection *conn = NULL;
1395 struct event event;
1396 enum bt_graph_status status;
1397 size_t src_accept_port_connection_pos;
1398 size_t src_port_connected_pos;
1399
1400 prepare_test(TEST_SRC_PORT_CONNECTED_ERROR, "port connected error: source");
1401 graph = create_graph();
1402 BT_ASSERT(graph);
1403 src = create_src(graph);
1404 sink = create_sink(graph);
1405 src_def_port = bt_component_source_borrow_output_port_by_name(src, "out");
1406 BT_ASSERT(src_def_port);
1407 sink_def_port = bt_component_sink_borrow_input_port_by_name(sink, "in");
1408 BT_ASSERT(sink_def_port);
1409 status = bt_private_graph_connect_ports(graph, src_def_port,
1410 sink_def_port, &conn);
1411 ok(status != BT_GRAPH_STATUS_OK,
1412 "bt_private_graph_connect_ports() returns an error");
1413 ok(!conn, "returned connection is still NULL");
1414 gsrc = bt_component_source_as_component(src);
1415 gsink = bt_component_sink_as_component(sink);
1416 gsrc_def_port = bt_port_output_as_port(src_def_port);
1417 gsink_def_port = bt_port_input_as_port(sink_def_port);
1418
1419 /* We're supposed to have 5 events */
1420 ok(events->len == 5, "we have the expected number of events");
1421
1422 /* Source's port added */
1423 event.type = GRAPH_SRC_OUTPUT_PORT_ADDED;
1424 event.data.graph_src_output_port_added.comp = gsrc;
1425 event.data.graph_src_output_port_added.port = gsrc_def_port;
1426 ok(has_event(&event), "got the expected graph's port added event (for source, initial)");
1427
1428 /* Sink's port added */
1429 event.type = GRAPH_SINK_INPUT_PORT_ADDED;
1430 event.data.graph_sink_input_port_added.comp = gsink;
1431 event.data.graph_sink_input_port_added.port = gsink_def_port;
1432 ok(has_event(&event), "got the expected graph's port added event (for sink, initial)");
1433
1434 /* Source's accept port connection */
1435 event.type = SRC_COMP_ACCEPT_OUTPUT_PORT_CONNECTION;
1436 event.data.src_comp_accept_output_port_connection.comp = gsrc;
1437 event.data.src_comp_accept_output_port_connection.self_port = gsrc_def_port;
1438 event.data.src_comp_accept_output_port_connection.other_port = gsink_def_port;
1439 ok(has_event(&event), "got the expected source's accept port connection event");
1440 src_accept_port_connection_pos = event_pos(&event);
1441
1442 /* Sink's accept port connection */
1443 event.type = SINK_COMP_ACCEPT_INPUT_PORT_CONNECTION;
1444 event.data.sink_comp_accept_input_port_connection.comp = gsink;
1445 event.data.sink_comp_accept_input_port_connection.self_port = gsink_def_port;
1446 event.data.sink_comp_accept_input_port_connection.other_port = gsrc_def_port;
1447 ok(has_event(&event), "got the expected sink's accept port connection event");
1448
1449 /* Source's port connected */
1450 event.type = SRC_COMP_OUTPUT_PORT_CONNECTED;
1451 event.data.src_comp_output_port_connected.comp = gsrc;
1452 event.data.src_comp_output_port_connected.self_port = gsrc_def_port;
1453 event.data.src_comp_output_port_connected.other_port = gsink_def_port;
1454 ok(has_event(&event), "got the expected source's port connected event");
1455 src_port_connected_pos = event_pos(&event);
1456
1457 /* Order of events */
1458 ok(src_accept_port_connection_pos < src_port_connected_pos,
1459 "event order is good (1)");
1460
1461 bt_object_put_ref(graph);
1462 bt_object_put_ref(sink);
1463 bt_object_put_ref(src);
1464 bt_object_put_ref(conn);
1465 }
1466
1467 static
1468 void test_sink_port_connected_error(void)
1469 {
1470 struct bt_component_source *src;
1471 struct bt_component_sink *sink;
1472 struct bt_component *gsrc;
1473 struct bt_component *gsink;
1474 struct bt_private_graph *graph;
1475 struct bt_port_output *src_def_port;
1476 struct bt_port_input *sink_def_port;
1477 struct bt_port *gsrc_def_port;
1478 struct bt_port *gsink_def_port;
1479 struct bt_connection *conn = NULL;
1480 struct event event;
1481 enum bt_graph_status status;
1482 size_t src_accept_port_connection_pos;
1483 size_t sink_accept_port_connection_pos;
1484 size_t src_port_connected_pos;
1485 size_t src_port_disconnected_pos;
1486 size_t sink_port_connected_pos;
1487
1488 prepare_test(TEST_SINK_PORT_CONNECTED_ERROR, "port connected error: sink");
1489 graph = create_graph();
1490 BT_ASSERT(graph);
1491 src = create_src(graph);
1492 sink = create_sink(graph);
1493 src_def_port = bt_component_source_borrow_output_port_by_name(src, "out");
1494 BT_ASSERT(src_def_port);
1495 sink_def_port = bt_component_sink_borrow_input_port_by_name(sink, "in");
1496 BT_ASSERT(sink_def_port);
1497 status = bt_private_graph_connect_ports(graph, src_def_port,
1498 sink_def_port, &conn);
1499 ok(status != BT_GRAPH_STATUS_OK,
1500 "bt_private_graph_connect_ports() returns an error");
1501 ok(!conn, "returned connection is still NULL");
1502 gsrc = bt_component_source_as_component(src);
1503 gsink = bt_component_sink_as_component(sink);
1504 gsrc_def_port = bt_port_output_as_port(src_def_port);
1505 gsink_def_port = bt_port_input_as_port(sink_def_port);
1506
1507 /* We're supposed to have 5 events */
1508 ok(events->len == 7, "we have the expected number of events");
1509
1510 /* Source's port added */
1511 event.type = GRAPH_SRC_OUTPUT_PORT_ADDED;
1512 event.data.graph_src_output_port_added.comp = gsrc;
1513 event.data.graph_src_output_port_added.port = gsrc_def_port;
1514 ok(has_event(&event), "got the expected graph's port added event (for source, initial)");
1515
1516 /* Sink's port added */
1517 event.type = GRAPH_SINK_INPUT_PORT_ADDED;
1518 event.data.graph_sink_input_port_added.comp = gsink;
1519 event.data.graph_sink_input_port_added.port = gsink_def_port;
1520 ok(has_event(&event), "got the expected graph's port added event (for sink, initial)");
1521
1522 /* Source's accept port connection */
1523 event.type = SRC_COMP_ACCEPT_OUTPUT_PORT_CONNECTION;
1524 event.data.src_comp_accept_output_port_connection.comp = gsrc;
1525 event.data.src_comp_accept_output_port_connection.self_port = gsrc_def_port;
1526 event.data.src_comp_accept_output_port_connection.other_port = gsink_def_port;
1527 ok(has_event(&event), "got the expected source's accept port connection event");
1528 src_accept_port_connection_pos = event_pos(&event);
1529
1530 /* Sink's accept port connection */
1531 event.type = SINK_COMP_ACCEPT_INPUT_PORT_CONNECTION;
1532 event.data.sink_comp_accept_input_port_connection.comp = gsink;
1533 event.data.sink_comp_accept_input_port_connection.self_port = gsink_def_port;
1534 event.data.sink_comp_accept_input_port_connection.other_port = gsrc_def_port;
1535 ok(has_event(&event), "got the expected sink's accept port connection event");
1536 sink_accept_port_connection_pos = event_pos(&event);
1537
1538 /* Source's port connected */
1539 event.type = SRC_COMP_OUTPUT_PORT_CONNECTED;
1540 event.data.src_comp_output_port_connected.comp = gsrc;
1541 event.data.src_comp_output_port_connected.self_port = gsrc_def_port;
1542 event.data.src_comp_output_port_connected.other_port = gsink_def_port;
1543 ok(has_event(&event), "got the expected source's port connected event");
1544 src_port_connected_pos = event_pos(&event);
1545
1546 /* Sink's port connected */
1547 event.type = SINK_COMP_INPUT_PORT_CONNECTED;
1548 event.data.sink_comp_input_port_connected.comp = gsink;
1549 event.data.sink_comp_input_port_connected.self_port = gsink_def_port;
1550 event.data.sink_comp_input_port_connected.other_port = gsrc_def_port;
1551 ok(has_event(&event), "got the expected sink's port connected event");
1552 sink_port_connected_pos = event_pos(&event);
1553
1554 /* Source's port disconnected */
1555 event.type = SRC_COMP_OUTPUT_PORT_DISCONNECTED;
1556 event.data.src_comp_output_port_disconnected.comp = gsrc;
1557 event.data.src_comp_output_port_disconnected.self_port = gsrc_def_port;
1558 ok(has_event(&event), "got the expected source's port disconnected event");
1559 src_port_disconnected_pos = event_pos(&event);
1560
1561 /* Order of events */
1562 ok(src_accept_port_connection_pos < src_port_connected_pos,
1563 "event order is good (1)");
1564 ok(sink_accept_port_connection_pos < sink_port_connected_pos,
1565 "event order is good (2)");
1566 ok(sink_port_connected_pos < src_port_disconnected_pos,
1567 "event order is good (3)");
1568
1569 bt_object_put_ref(conn);
1570 bt_object_put_ref(graph);
1571 bt_object_put_ref(sink);
1572 bt_object_put_ref(src);
1573 }
1574
1575 static
1576 void test_empty_graph(void)
1577 {
1578 struct bt_private_graph *graph;
1579
1580 prepare_test(TEST_EMPTY_GRAPH, "empty graph");
1581 graph = create_graph();
1582 ok(events->len == 0, "empty graph generates no events");
1583 bt_object_put_ref(graph);
1584 }
1585
1586 int main(int argc, char **argv)
1587 {
1588 plan_tests(NR_TESTS);
1589 init_test();
1590 test_empty_graph();
1591 test_simple();
1592 test_src_port_connected_error();
1593 test_sink_port_connected_error();
1594 test_src_adds_port_in_port_connected();
1595 test_sink_removes_port_in_consume();
1596 test_sink_removes_port_in_consume_then_src_removes_disconnected_port();
1597 fini_test();
1598 return exit_status();
1599 }
This page took 0.10007 seconds and 4 git commands to generate.