lib: rename "notification" -> "message"
[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 const bt_component *comp;
62 const bt_port *self_port;
63 const bt_port *other_port;
64 } src_comp_accept_output_port_connection;
65
66 struct {
67 const bt_component *comp;
68 const bt_port *self_port;
69 const bt_port *other_port;
70 } sink_comp_accept_input_port_connection;
71
72 struct {
73 const bt_component *comp;
74 const bt_port *self_port;
75 const bt_port *other_port;
76 } src_comp_output_port_connected;
77
78 struct {
79 const bt_component *comp;
80 const bt_port *self_port;
81 const bt_port *other_port;
82 } sink_comp_input_port_connected;
83
84 struct {
85 const bt_component *comp;
86 const bt_port *self_port;
87 } src_comp_output_port_disconnected;
88
89 struct {
90 const bt_component *comp;
91 const bt_port *self_port;
92 } sink_comp_input_port_disconnected;
93
94 struct {
95 const bt_component *comp;
96 const bt_port *port;
97 } graph_src_output_port_added;
98
99 struct {
100 const bt_component *comp;
101 const bt_port *port;
102 } graph_sink_input_port_added;
103
104 struct {
105 const bt_component *comp;
106 const bt_port *port;
107 } graph_src_output_port_removed;
108
109 struct {
110 const bt_component *comp;
111 const bt_port *port;
112 } graph_sink_input_port_removed;
113
114 struct {
115 const bt_component *upstream_comp;
116 const bt_component *downstream_comp;
117 const bt_port *upstream_port;
118 const bt_port *downstream_port;
119 } graph_src_sink_ports_connected;
120
121 struct {
122 const bt_component *upstream_comp;
123 const bt_component *downstream_comp;
124 const bt_port *upstream_port;
125 const bt_port *downstream_port;
126 } graph_src_sink_ports_disconnected;
127 } data;
128 };
129
130 static GArray *events;
131 static bt_component_class_source *src_comp_class;
132 static bt_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_message_iterator_status src_iter_next(
368 bt_self_message_iterator *self_iterator,
369 bt_message_array_const msgs, uint64_t capacity,
370 uint64_t *count)
371 {
372 return BT_SELF_MESSAGE_ITERATOR_STATUS_ERROR;
373 }
374
375 static
376 enum bt_self_component_status src_accept_output_port_connection(
377 bt_self_component_source *self_comp,
378 bt_self_component_port_output *self_comp_port,
379 const 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_const(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 bt_self_component_sink *self_comp,
401 bt_self_component_port_input *self_comp_port,
402 const 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_const(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 bt_self_component_source *self_comp,
424 bt_self_component_port_output *self_comp_port,
425 const 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_const(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 bt_self_component_sink *self_comp,
461 bt_self_component_port_input *self_comp_port,
462 const 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_const(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(bt_self_component_source *self_comp,
488 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(bt_self_component_sink *self_comp,
518 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 bt_self_component_source *self_comp,
538 const 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 bt_self_component_sink *self_comp,
551 const 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 bt_self_component_sink *self_comp)
564 {
565 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(const bt_component_source *comp,
588 const 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_const(comp),
594 .port = bt_port_output_as_port_const(port),
595 },
596 };
597
598 append_event(&event);
599 }
600
601 static
602 void graph_sink_input_port_added(const bt_component_sink *comp,
603 const 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_const(comp),
609 .port = bt_port_input_as_port_const(port),
610 },
611 };
612
613 append_event(&event);
614 }
615
616 static
617 void graph_src_output_port_removed(const bt_component_source *comp,
618 const 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_const(comp),
624 .port = bt_port_output_as_port_const(port),
625 },
626 };
627
628 append_event(&event);
629 }
630
631 static
632 void graph_sink_input_port_removed(const bt_component_sink *comp,
633 const 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_const(comp),
639 .port = bt_port_input_as_port_const(port),
640 },
641 };
642
643 append_event(&event);
644 }
645
646 static
647 void graph_src_sink_ports_connected(const bt_component_source *upstream_comp,
648 const bt_component_sink *downstream_comp,
649 const bt_port_output *upstream_port,
650 const 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_const(upstream_comp),
657 .downstream_comp =
658 bt_component_sink_as_component_const(downstream_comp),
659 .upstream_port =
660 bt_port_output_as_port_const(upstream_port),
661 .downstream_port =
662 bt_port_input_as_port_const(downstream_port),
663 },
664 };
665
666 append_event(&event);
667 }
668
669 static
670 void graph_src_sink_ports_disconnected(const bt_component_source *upstream_comp,
671 const bt_component_sink *downstream_comp,
672 const bt_port_output *upstream_port,
673 const 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_const(upstream_comp),
680 .downstream_comp =
681 bt_component_sink_as_component_const(downstream_comp),
682 .upstream_port =
683 bt_port_output_as_port_const(upstream_port),
684 .downstream_port =
685 bt_port_input_as_port_const(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_component_class_source_create(
698 "src", src_iter_next);
699 BT_ASSERT(src_comp_class);
700 ret = bt_component_class_source_set_init_method(
701 src_comp_class, src_init);
702 BT_ASSERT(ret == 0);
703 ret = bt_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_component_class_source_set_output_port_connected_method(
707 src_comp_class, src_output_port_connected);
708 BT_ASSERT(ret == 0);
709 ret = bt_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_component_class_sink_create("sink",
713 sink_consume);
714 BT_ASSERT(sink_comp_class);
715 ret = bt_component_class_sink_set_init_method(sink_comp_class,
716 sink_init);
717 BT_ASSERT(ret == 0);
718 ret = bt_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_component_class_sink_set_input_port_connected_method(
722 sink_comp_class, sink_input_port_connected);
723 BT_ASSERT(ret == 0);
724 ret = bt_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_component_class_source_put_ref(src_comp_class);
735 bt_component_class_sink_put_ref(sink_comp_class);
736 g_array_free(events, TRUE);
737 }
738
739 static
740 const bt_component_source *create_src(bt_graph *graph)
741 {
742 const bt_component_source *comp;
743 int ret;
744
745 ret = bt_graph_add_source_component(graph, src_comp_class,
746 "src-comp", NULL, &comp);
747 BT_ASSERT(ret == 0);
748 return comp;
749 }
750
751 static
752 const bt_component_sink *create_sink(bt_graph *graph)
753 {
754 const bt_component_sink *comp;
755 int ret;
756
757 ret = bt_graph_add_sink_component(graph, sink_comp_class,
758 "sink-comp", NULL, &comp);
759 BT_ASSERT(ret == 0);
760 return comp;
761 }
762
763 static
764 bt_graph *create_graph(void)
765 {
766 bt_graph *graph = bt_graph_create();
767 int ret;
768
769 BT_ASSERT(graph);
770 ret = bt_graph_add_source_component_output_port_added_listener(
771 graph, graph_src_output_port_added, NULL, NULL, NULL);
772 BT_ASSERT(ret >= 0);
773 ret = bt_graph_add_sink_component_input_port_added_listener(
774 graph, graph_sink_input_port_added, NULL, NULL, NULL);
775 BT_ASSERT(ret >= 0);
776 ret = bt_graph_add_source_component_output_port_removed_listener(
777 graph, graph_src_output_port_removed, NULL, NULL, NULL);
778 BT_ASSERT(ret >= 0);
779 ret = bt_graph_add_sink_component_input_port_removed_listener(
780 graph, graph_sink_input_port_removed, NULL, NULL, NULL);
781 BT_ASSERT(ret >= 0);
782 ret = bt_graph_add_source_sink_component_ports_connected_listener(
783 graph, graph_src_sink_ports_connected, NULL, NULL, NULL);
784 BT_ASSERT(ret >= 0);
785 ret = bt_graph_add_source_sink_component_ports_disconnected_listener(
786 graph, graph_src_sink_ports_disconnected, NULL, NULL, NULL);
787 BT_ASSERT(ret >= 0);
788 return graph;
789 }
790
791 static
792 void prepare_test(enum test test, const char *name)
793 {
794 clear_events();
795 current_test = test;
796 diag("test: %s", name);
797 }
798
799 static
800 void test_sink_removes_port_in_consume_then_src_removes_disconnected_port(void)
801 {
802 int ret;
803 const bt_component_source *src;
804 const bt_component_sink *sink;
805 const bt_component *gsrc;
806 const bt_component *gsink;
807 bt_graph *graph;
808 const bt_port_output *src_def_port;
809 const bt_port_input *sink_def_port;
810 const bt_port *gsrc_def_port;
811 const bt_port *gsink_def_port;
812 struct event event;
813 enum bt_graph_status status;
814 size_t src_accept_port_connection_pos;
815 size_t sink_accept_port_connection_pos;
816 size_t src_port_connected_pos;
817 size_t sink_port_connected_pos;
818 size_t graph_ports_connected_pos;
819 size_t src_port_disconnected_pos;
820 size_t sink_port_disconnected_pos;
821 size_t graph_ports_disconnected_pos;
822 size_t graph_port_removed_src_pos;
823 size_t graph_port_removed_sink_pos;
824
825 prepare_test(TEST_SINK_REMOVES_PORT_IN_CONSUME_THEN_SRC_REMOVES_DISCONNECTED_PORT,
826 "sink removes port in consume, then source removes disconnected port");
827 graph = create_graph();
828 BT_ASSERT(graph);
829 src = create_src(graph);
830 sink = create_sink(graph);
831 src_def_port = bt_component_source_borrow_output_port_by_name_const(src,
832 "out");
833 BT_ASSERT(src_def_port);
834 sink_def_port = bt_component_sink_borrow_input_port_by_name_const(sink,
835 "in");
836 BT_ASSERT(sink_def_port);
837 status = bt_graph_connect_ports(graph, src_def_port,
838 sink_def_port, NULL);
839 BT_ASSERT(status == 0);
840 gsrc = bt_component_source_as_component_const(src);
841 gsink = bt_component_sink_as_component_const(sink);
842 gsrc_def_port = bt_port_output_as_port_const(src_def_port);
843 gsink_def_port = bt_port_input_as_port_const(sink_def_port);
844
845 /* We're supposed to have 7 events so far */
846 ok(events->len == 7, "we have the expected number of events (before consume)");
847
848 /* Source's port added */
849 event.type = GRAPH_SRC_OUTPUT_PORT_ADDED;
850 event.data.graph_src_output_port_added.comp = gsrc;
851 event.data.graph_src_output_port_added.port = gsrc_def_port;
852 ok(has_event(&event), "got the expected graph's port added event (for source, initial)");
853
854 /* Sink's port added */
855 event.type = GRAPH_SINK_INPUT_PORT_ADDED;
856 event.data.graph_sink_input_port_added.comp = gsink;
857 event.data.graph_sink_input_port_added.port = gsink_def_port;
858 ok(has_event(&event), "got the expected graph's port added event (for sink, initial)");
859
860 /* Source's accept port connection */
861 event.type = SRC_COMP_ACCEPT_OUTPUT_PORT_CONNECTION;
862 event.data.src_comp_accept_output_port_connection.comp = gsrc;
863 event.data.src_comp_accept_output_port_connection.self_port = gsrc_def_port;
864 event.data.src_comp_accept_output_port_connection.other_port = gsink_def_port;
865 ok(has_event(&event), "got the expected source's accept port connection event");
866 src_accept_port_connection_pos = event_pos(&event);
867
868 /* Sink's accept port connection */
869 event.type = SINK_COMP_ACCEPT_INPUT_PORT_CONNECTION;
870 event.data.sink_comp_accept_input_port_connection.comp = gsink;
871 event.data.sink_comp_accept_input_port_connection.self_port = gsink_def_port;
872 event.data.sink_comp_accept_input_port_connection.other_port = gsrc_def_port;
873 ok(has_event(&event), "got the expected sink's accept port connection event");
874 sink_accept_port_connection_pos = event_pos(&event);
875
876 /* Source's port connected */
877 event.type = SRC_COMP_OUTPUT_PORT_CONNECTED;
878 event.data.src_comp_output_port_connected.comp = gsrc;
879 event.data.src_comp_output_port_connected.self_port = gsrc_def_port;
880 event.data.src_comp_output_port_connected.other_port = gsink_def_port;
881 ok(has_event(&event), "got the expected source's port connected event");
882 src_port_connected_pos = event_pos(&event);
883
884 /* Sink's port connected */
885 event.type = SINK_COMP_INPUT_PORT_CONNECTED;
886 event.data.sink_comp_input_port_connected.comp = gsink;
887 event.data.sink_comp_input_port_connected.self_port = gsink_def_port;
888 event.data.sink_comp_input_port_connected.other_port = gsrc_def_port;
889 ok(has_event(&event), "got the expected sink's port connected event");
890 sink_port_connected_pos = event_pos(&event);
891
892 /* Graph's ports connected */
893 event.type = GRAPH_SRC_SINK_PORTS_CONNECTED;
894 event.data.graph_src_sink_ports_connected.upstream_comp = gsrc;
895 event.data.graph_src_sink_ports_connected.downstream_comp = gsink;
896 event.data.graph_src_sink_ports_connected.upstream_port = gsrc_def_port;
897 event.data.graph_src_sink_ports_connected.downstream_port = gsink_def_port;
898 ok(has_event(&event), "got the expected graph's ports connected event");
899 graph_ports_connected_pos = event_pos(&event);
900
901 /* Order of events */
902 ok(src_port_connected_pos < graph_ports_connected_pos,
903 "event order is good (1)");
904 ok(sink_port_connected_pos < graph_ports_connected_pos,
905 "event order is good (2)");
906 ok(src_accept_port_connection_pos < src_port_connected_pos,
907 "event order is good (3)");
908 ok(sink_accept_port_connection_pos < sink_port_connected_pos,
909 "event order is good (4)");
910
911 /* Consume sink once */
912 clear_events();
913 ret = bt_graph_consume(graph);
914 BT_ASSERT(ret == 0);
915
916 /* We're supposed to have 5 new events */
917 ok(events->len == 5, "we have the expected number of events (after consume)");
918
919 /* Source's port disconnected */
920 event.type = SRC_COMP_OUTPUT_PORT_DISCONNECTED;
921 event.data.src_comp_output_port_disconnected.comp = gsrc;
922 event.data.src_comp_output_port_disconnected.self_port = gsrc_def_port;
923 ok(has_event(&event), "got the expected source's port disconnected event");
924 src_port_disconnected_pos = event_pos(&event);
925
926 /* Sink's port disconnected */
927 event.type = SINK_COMP_INPUT_PORT_DISCONNECTED;
928 event.data.sink_comp_input_port_disconnected.comp = gsink;
929 event.data.sink_comp_input_port_disconnected.self_port = gsink_def_port;
930 ok(has_event(&event), "got the expected sink's port disconnected event");
931 sink_port_disconnected_pos = event_pos(&event);
932
933 /* Graph's ports disconnected */
934 event.type = GRAPH_SRC_SINK_PORTS_DISCONNECTED;
935 event.data.graph_src_sink_ports_disconnected.upstream_comp = gsrc;
936 event.data.graph_src_sink_ports_disconnected.downstream_comp = gsink;
937 event.data.graph_src_sink_ports_disconnected.upstream_port = gsrc_def_port;
938 event.data.graph_src_sink_ports_disconnected.downstream_port = gsink_def_port;
939 ok(has_event(&event), "got the expected graph's ports disconnected event");
940 graph_ports_disconnected_pos = event_pos(&event);
941
942 /* Graph's port removed (sink) */
943 event.type = GRAPH_SINK_INPUT_PORT_REMOVED;
944 event.data.graph_sink_input_port_removed.comp = gsink;
945 event.data.graph_sink_input_port_removed.port = gsink_def_port;
946 ok(has_event(&event), "got the expected graph's port removed event (for sink)");
947 graph_port_removed_sink_pos = event_pos(&event);
948
949 /* Graph's port removed (source) */
950 event.type = GRAPH_SRC_OUTPUT_PORT_REMOVED;
951 event.data.graph_src_output_port_removed.comp = gsrc;
952 event.data.graph_src_output_port_removed.port = gsrc_def_port;
953 ok(has_event(&event), "got the expected graph's port removed event (for source)");
954 graph_port_removed_src_pos = event_pos(&event);
955
956 /* Order of events */
957 ok(src_port_disconnected_pos < graph_ports_disconnected_pos,
958 "event order is good (5)");
959 ok(src_port_disconnected_pos < graph_port_removed_sink_pos,
960 "event order is good (6)");
961 ok(src_port_disconnected_pos < graph_port_removed_src_pos,
962 "event order is good (7)");
963 ok(sink_port_disconnected_pos < graph_ports_disconnected_pos,
964 "event order is good (8)");
965 ok(sink_port_disconnected_pos < graph_port_removed_sink_pos,
966 "event order is good (9)");
967 ok(sink_port_disconnected_pos < graph_port_removed_src_pos,
968 "event order is good (10)");
969 ok(graph_ports_disconnected_pos < graph_port_removed_sink_pos,
970 "event order is good (11)");
971 ok(graph_port_removed_src_pos < graph_ports_disconnected_pos,
972 "event order is good (12)");
973 ok(graph_port_removed_src_pos < graph_port_removed_sink_pos,
974 "event order is good (13)");
975
976 bt_graph_put_ref(graph);
977 bt_component_sink_put_ref(sink);
978 bt_component_source_put_ref(src);
979 }
980
981 static
982 void test_sink_removes_port_in_consume(void)
983 {
984 int ret;
985 const bt_component_source *src;
986 const bt_component_sink *sink;
987 const bt_component *gsrc;
988 const bt_component *gsink;
989 bt_graph *graph;
990 const bt_port_output *src_def_port;
991 const bt_port_input *sink_def_port;
992 const bt_port *gsrc_def_port;
993 const bt_port *gsink_def_port;
994 struct event event;
995 enum bt_graph_status status;
996 size_t src_accept_port_connection_pos;
997 size_t sink_accept_port_connection_pos;
998 size_t src_port_connected_pos;
999 size_t sink_port_connected_pos;
1000 size_t graph_ports_connected_pos;
1001 size_t src_port_disconnected_pos;
1002 size_t sink_port_disconnected_pos;
1003 size_t graph_ports_disconnected_pos;
1004 size_t graph_port_removed_sink_pos;
1005
1006 prepare_test(TEST_SINK_REMOVES_PORT_IN_CONSUME,
1007 "sink removes port in consume");
1008 graph = create_graph();
1009 BT_ASSERT(graph);
1010 src = create_src(graph);
1011 sink = create_sink(graph);
1012 src_def_port = bt_component_source_borrow_output_port_by_name_const(src,
1013 "out");
1014 BT_ASSERT(src_def_port);
1015 sink_def_port = bt_component_sink_borrow_input_port_by_name_const(sink,
1016 "in");
1017 BT_ASSERT(sink_def_port);
1018 status = bt_graph_connect_ports(graph, src_def_port,
1019 sink_def_port, NULL);
1020 BT_ASSERT(status == 0);
1021 gsrc = bt_component_source_as_component_const(src);
1022 gsink = bt_component_sink_as_component_const(sink);
1023 gsrc_def_port = bt_port_output_as_port_const(src_def_port);
1024 gsink_def_port = bt_port_input_as_port_const(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_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_component_sink_put_ref(sink);
1143 bt_component_source_put_ref(src);
1144 bt_graph_put_ref(graph);
1145 }
1146
1147 static
1148 void test_src_adds_port_in_port_connected(void)
1149 {
1150 const bt_component_source *src;
1151 const bt_component_sink *sink;
1152 const bt_component *gsrc;
1153 const bt_component *gsink;
1154 bt_graph *graph;
1155 const bt_port_output *src_def_port;
1156 const bt_port_output *src_hello_port;
1157 const bt_port_input *sink_def_port;
1158 const bt_port *gsrc_def_port;
1159 const bt_port *gsrc_hello_port;
1160 const 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_const(src,
1177 "out");
1178 BT_ASSERT(src_def_port);
1179 sink_def_port = bt_component_sink_borrow_input_port_by_name_const(sink,
1180 "in");
1181 BT_ASSERT(sink_def_port);
1182 status = bt_graph_connect_ports(graph, src_def_port,
1183 sink_def_port, NULL);
1184 BT_ASSERT(status == 0);
1185 src_hello_port = bt_component_source_borrow_output_port_by_name_const(src,
1186 "hello");
1187 BT_ASSERT(src_hello_port);
1188 gsrc = bt_component_source_as_component_const(src);
1189 gsink = bt_component_sink_as_component_const(sink);
1190 gsrc_def_port = bt_port_output_as_port_const(src_def_port);
1191 gsrc_hello_port = bt_port_output_as_port_const(src_hello_port);
1192 gsink_def_port = bt_port_input_as_port_const(sink_def_port);
1193
1194 /* We're supposed to have 8 events */
1195 ok(events->len == 8, "we have the expected number of events");
1196
1197 /* Source's port added */
1198 event.type = GRAPH_SRC_OUTPUT_PORT_ADDED;
1199 event.data.graph_src_output_port_added.comp = gsrc;
1200 event.data.graph_src_output_port_added.port = gsrc_def_port;
1201 ok(has_event(&event), "got the expected graph's port added event (for source, initial)");
1202
1203 /* Sink's port added */
1204 event.type = GRAPH_SINK_INPUT_PORT_ADDED;
1205 event.data.graph_sink_input_port_added.comp = gsink;
1206 event.data.graph_sink_input_port_added.port = gsink_def_port;
1207 ok(has_event(&event), "got the expected graph's port added event (for sink, initial)");
1208
1209 /* Source's accept port connection */
1210 event.type = SRC_COMP_ACCEPT_OUTPUT_PORT_CONNECTION;
1211 event.data.src_comp_accept_output_port_connection.comp = gsrc;
1212 event.data.src_comp_accept_output_port_connection.self_port = gsrc_def_port;
1213 event.data.src_comp_accept_output_port_connection.other_port = gsink_def_port;
1214 ok(has_event(&event), "got the expected source's accept port connection event");
1215 src_accept_port_connection_pos = event_pos(&event);
1216
1217 /* Sink's accept port connection */
1218 event.type = SINK_COMP_ACCEPT_INPUT_PORT_CONNECTION;
1219 event.data.sink_comp_accept_input_port_connection.comp = gsink;
1220 event.data.sink_comp_accept_input_port_connection.self_port = gsink_def_port;
1221 event.data.sink_comp_accept_input_port_connection.other_port = gsrc_def_port;
1222 ok(has_event(&event), "got the expected sink's accept port connection event");
1223 sink_accept_port_connection_pos = event_pos(&event);
1224
1225 /* Source's port connected */
1226 event.type = SRC_COMP_OUTPUT_PORT_CONNECTED;
1227 event.data.src_comp_output_port_connected.comp = gsrc;
1228 event.data.src_comp_output_port_connected.self_port = gsrc_def_port;
1229 event.data.src_comp_output_port_connected.other_port = gsink_def_port;
1230 ok(has_event(&event), "got the expected source's port connected event");
1231 src_port_connected_pos = event_pos(&event);
1232
1233 /* Graph's port added (source) */
1234 event.type = GRAPH_SRC_OUTPUT_PORT_ADDED;
1235 event.data.graph_src_output_port_added.comp = gsrc;
1236 event.data.graph_src_output_port_added.port = gsrc_hello_port;
1237 ok(has_event(&event), "got the expected graph's port added event (for source)");
1238 graph_port_added_src_pos = event_pos(&event);
1239
1240 /* Sink's port connected */
1241 event.type = SINK_COMP_INPUT_PORT_CONNECTED;
1242 event.data.sink_comp_input_port_connected.comp = gsink;
1243 event.data.sink_comp_input_port_connected.self_port = gsink_def_port;
1244 event.data.sink_comp_input_port_connected.other_port = gsrc_def_port;
1245 ok(has_event(&event), "got the expected sink's port connected event");
1246 sink_port_connected_pos = event_pos(&event);
1247
1248 /* Graph's ports connected */
1249 event.type = GRAPH_SRC_SINK_PORTS_CONNECTED;
1250 event.data.graph_src_sink_ports_connected.upstream_comp = gsrc;
1251 event.data.graph_src_sink_ports_connected.downstream_comp = gsink;
1252 event.data.graph_src_sink_ports_connected.upstream_port = gsrc_def_port;
1253 event.data.graph_src_sink_ports_connected.downstream_port = gsink_def_port;
1254 ok(has_event(&event), "got the expected graph's ports connected event");
1255 graph_ports_connected_pos = event_pos(&event);
1256
1257 /* Order of events */
1258 ok(src_port_connected_pos < graph_ports_connected_pos,
1259 "event order is good (1)");
1260 ok(sink_port_connected_pos < graph_ports_connected_pos,
1261 "event order is good (2)");
1262 ok(src_accept_port_connection_pos < src_port_connected_pos,
1263 "event order is good (3)");
1264 ok(sink_accept_port_connection_pos < sink_port_connected_pos,
1265 "event order is good (4)");
1266 ok(src_port_connected_pos < graph_port_added_src_pos,
1267 "event order is good (5)");
1268 ok(graph_port_added_src_pos < graph_ports_connected_pos,
1269 "event order is good (6)");
1270
1271 bt_component_source_put_ref(src);
1272 bt_component_sink_put_ref(sink);
1273 bt_graph_put_ref(graph);
1274 }
1275
1276 static
1277 void test_simple(void)
1278 {
1279 const bt_component_source *src;
1280 const bt_component_sink *sink;
1281 const bt_component *gsrc;
1282 const bt_component *gsink;
1283 bt_graph *graph;
1284 const bt_port_output *src_def_port;
1285 const bt_port_input *sink_def_port;
1286 const bt_port *gsrc_def_port;
1287 const bt_port *gsink_def_port;
1288 struct event event;
1289 enum bt_graph_status status;
1290 size_t src_accept_port_connection_pos;
1291 size_t sink_accept_port_connection_pos;
1292 size_t src_port_connected_pos;
1293 size_t sink_port_connected_pos;
1294 size_t graph_ports_connected_pos;
1295
1296 prepare_test(TEST_SIMPLE, "simple");
1297 graph = create_graph();
1298 BT_ASSERT(graph);
1299 src = create_src(graph);
1300 sink = create_sink(graph);
1301 src_def_port = bt_component_source_borrow_output_port_by_name_const(src,
1302 "out");
1303 BT_ASSERT(src_def_port);
1304 sink_def_port = bt_component_sink_borrow_input_port_by_name_const(sink,
1305 "in");
1306 BT_ASSERT(sink_def_port);
1307 status = bt_graph_connect_ports(graph, src_def_port,
1308 sink_def_port, NULL);
1309 BT_ASSERT(status == 0);
1310 gsrc = bt_component_source_as_component_const(src);
1311 gsink = bt_component_sink_as_component_const(sink);
1312 gsrc_def_port = bt_port_output_as_port_const(src_def_port);
1313 gsink_def_port = bt_port_input_as_port_const(sink_def_port);
1314
1315 /* We're supposed to have 7 events */
1316 ok(events->len == 7, "we have the expected number of events");
1317
1318 /* Source's port added */
1319 event.type = GRAPH_SRC_OUTPUT_PORT_ADDED;
1320 event.data.graph_src_output_port_added.comp = gsrc;
1321 event.data.graph_src_output_port_added.port = gsrc_def_port;
1322 ok(has_event(&event), "got the expected graph's port added event (for source, initial)");
1323
1324 /* Sink's port added */
1325 event.type = GRAPH_SINK_INPUT_PORT_ADDED;
1326 event.data.graph_sink_input_port_added.comp = gsink;
1327 event.data.graph_sink_input_port_added.port = gsink_def_port;
1328 ok(has_event(&event), "got the expected graph's port added event (for sink, initial)");
1329
1330 /* Source's accept port connection */
1331 event.type = SRC_COMP_ACCEPT_OUTPUT_PORT_CONNECTION;
1332 event.data.src_comp_accept_output_port_connection.comp = gsrc;
1333 event.data.src_comp_accept_output_port_connection.self_port = gsrc_def_port;
1334 event.data.src_comp_accept_output_port_connection.other_port = gsink_def_port;
1335 ok(has_event(&event), "got the expected source's accept port connection event");
1336 src_accept_port_connection_pos = event_pos(&event);
1337
1338 /* Sink's accept port connection */
1339 event.type = SINK_COMP_ACCEPT_INPUT_PORT_CONNECTION;
1340 event.data.sink_comp_accept_input_port_connection.comp = gsink;
1341 event.data.sink_comp_accept_input_port_connection.self_port = gsink_def_port;
1342 event.data.sink_comp_accept_input_port_connection.other_port = gsrc_def_port;
1343 ok(has_event(&event), "got the expected sink's accept port connection event");
1344 sink_accept_port_connection_pos = event_pos(&event);
1345
1346 /* Source's port connected */
1347 event.type = SRC_COMP_OUTPUT_PORT_CONNECTED;
1348 event.data.src_comp_output_port_connected.comp = gsrc;
1349 event.data.src_comp_output_port_connected.self_port = gsrc_def_port;
1350 event.data.src_comp_output_port_connected.other_port = gsink_def_port;
1351 ok(has_event(&event), "got the expected source's port connected event");
1352 src_port_connected_pos = event_pos(&event);
1353
1354 /* Sink's port connected */
1355 event.type = SINK_COMP_INPUT_PORT_CONNECTED;
1356 event.data.sink_comp_input_port_connected.comp = gsink;
1357 event.data.sink_comp_input_port_connected.self_port = gsink_def_port;
1358 event.data.sink_comp_input_port_connected.other_port = gsrc_def_port;
1359 ok(has_event(&event), "got the expected sink's port connected event");
1360 sink_port_connected_pos = event_pos(&event);
1361
1362 /* Graph's ports connected */
1363 event.type = GRAPH_SRC_SINK_PORTS_CONNECTED;
1364 event.data.graph_src_sink_ports_connected.upstream_comp = gsrc;
1365 event.data.graph_src_sink_ports_connected.downstream_comp = gsink;
1366 event.data.graph_src_sink_ports_connected.upstream_port = gsrc_def_port;
1367 event.data.graph_src_sink_ports_connected.downstream_port = gsink_def_port;
1368 ok(has_event(&event), "got the expected graph's ports connected event");
1369 graph_ports_connected_pos = event_pos(&event);
1370
1371 /* Order of events */
1372 ok(src_port_connected_pos < graph_ports_connected_pos,
1373 "event order is good (1)");
1374 ok(sink_port_connected_pos < graph_ports_connected_pos,
1375 "event order is good (2)");
1376 ok(src_accept_port_connection_pos < src_port_connected_pos,
1377 "event order is good (3)");
1378 ok(sink_accept_port_connection_pos < sink_port_connected_pos,
1379 "event order is good (4)");
1380
1381 bt_component_sink_put_ref(sink);
1382 bt_graph_put_ref(graph);
1383 bt_component_source_put_ref(src);
1384 }
1385
1386 static
1387 void test_src_port_connected_error(void)
1388 {
1389 const bt_component_source *src;
1390 const bt_component_sink *sink;
1391 const bt_component *gsrc;
1392 const bt_component *gsink;
1393 bt_graph *graph;
1394 const bt_port_output *src_def_port;
1395 const bt_port_input *sink_def_port;
1396 const bt_port *gsrc_def_port;
1397 const bt_port *gsink_def_port;
1398 const bt_connection *conn = NULL;
1399 struct event event;
1400 enum bt_graph_status status;
1401 size_t src_accept_port_connection_pos;
1402 size_t src_port_connected_pos;
1403
1404 prepare_test(TEST_SRC_PORT_CONNECTED_ERROR, "port connected error: source");
1405 graph = create_graph();
1406 BT_ASSERT(graph);
1407 src = create_src(graph);
1408 sink = create_sink(graph);
1409 src_def_port = bt_component_source_borrow_output_port_by_name_const(src,
1410 "out");
1411 BT_ASSERT(src_def_port);
1412 sink_def_port = bt_component_sink_borrow_input_port_by_name_const(sink,
1413 "in");
1414 BT_ASSERT(sink_def_port);
1415 status = bt_graph_connect_ports(graph, src_def_port,
1416 sink_def_port, &conn);
1417 ok(status != BT_GRAPH_STATUS_OK,
1418 "bt_graph_connect_ports() returns an error");
1419 ok(!conn, "returned connection is still NULL");
1420 gsrc = bt_component_source_as_component_const(src);
1421 gsink = bt_component_sink_as_component_const(sink);
1422 gsrc_def_port = bt_port_output_as_port_const(src_def_port);
1423 gsink_def_port = bt_port_input_as_port_const(sink_def_port);
1424
1425 /* We're supposed to have 5 events */
1426 ok(events->len == 5, "we have the expected number of events");
1427
1428 /* Source's port added */
1429 event.type = GRAPH_SRC_OUTPUT_PORT_ADDED;
1430 event.data.graph_src_output_port_added.comp = gsrc;
1431 event.data.graph_src_output_port_added.port = gsrc_def_port;
1432 ok(has_event(&event), "got the expected graph's port added event (for source, initial)");
1433
1434 /* Sink's port added */
1435 event.type = GRAPH_SINK_INPUT_PORT_ADDED;
1436 event.data.graph_sink_input_port_added.comp = gsink;
1437 event.data.graph_sink_input_port_added.port = gsink_def_port;
1438 ok(has_event(&event), "got the expected graph's port added event (for sink, initial)");
1439
1440 /* Source's accept port connection */
1441 event.type = SRC_COMP_ACCEPT_OUTPUT_PORT_CONNECTION;
1442 event.data.src_comp_accept_output_port_connection.comp = gsrc;
1443 event.data.src_comp_accept_output_port_connection.self_port = gsrc_def_port;
1444 event.data.src_comp_accept_output_port_connection.other_port = gsink_def_port;
1445 ok(has_event(&event), "got the expected source's accept port connection event");
1446 src_accept_port_connection_pos = event_pos(&event);
1447
1448 /* Sink's accept port connection */
1449 event.type = SINK_COMP_ACCEPT_INPUT_PORT_CONNECTION;
1450 event.data.sink_comp_accept_input_port_connection.comp = gsink;
1451 event.data.sink_comp_accept_input_port_connection.self_port = gsink_def_port;
1452 event.data.sink_comp_accept_input_port_connection.other_port = gsrc_def_port;
1453 ok(has_event(&event), "got the expected sink's accept port connection event");
1454
1455 /* Source's port connected */
1456 event.type = SRC_COMP_OUTPUT_PORT_CONNECTED;
1457 event.data.src_comp_output_port_connected.comp = gsrc;
1458 event.data.src_comp_output_port_connected.self_port = gsrc_def_port;
1459 event.data.src_comp_output_port_connected.other_port = gsink_def_port;
1460 ok(has_event(&event), "got the expected source's port connected event");
1461 src_port_connected_pos = event_pos(&event);
1462
1463 /* Order of events */
1464 ok(src_accept_port_connection_pos < src_port_connected_pos,
1465 "event order is good (1)");
1466
1467 bt_graph_put_ref(graph);
1468 bt_component_sink_put_ref(sink);
1469 bt_component_source_put_ref(src);
1470 bt_connection_put_ref(conn);
1471 }
1472
1473 static
1474 void test_sink_port_connected_error(void)
1475 {
1476 const bt_component_source *src;
1477 const bt_component_sink *sink;
1478 const bt_component *gsrc;
1479 const bt_component *gsink;
1480 bt_graph *graph;
1481 const bt_port_output *src_def_port;
1482 const bt_port_input *sink_def_port;
1483 const bt_port *gsrc_def_port;
1484 const bt_port *gsink_def_port;
1485 const bt_connection *conn = NULL;
1486 struct event event;
1487 enum bt_graph_status status;
1488 size_t src_accept_port_connection_pos;
1489 size_t sink_accept_port_connection_pos;
1490 size_t src_port_connected_pos;
1491 size_t src_port_disconnected_pos;
1492 size_t sink_port_connected_pos;
1493
1494 prepare_test(TEST_SINK_PORT_CONNECTED_ERROR, "port connected error: sink");
1495 graph = create_graph();
1496 BT_ASSERT(graph);
1497 src = create_src(graph);
1498 sink = create_sink(graph);
1499 src_def_port = bt_component_source_borrow_output_port_by_name_const(src,
1500 "out");
1501 BT_ASSERT(src_def_port);
1502 sink_def_port = bt_component_sink_borrow_input_port_by_name_const(sink,
1503 "in");
1504 BT_ASSERT(sink_def_port);
1505 status = bt_graph_connect_ports(graph, src_def_port,
1506 sink_def_port, &conn);
1507 ok(status != BT_GRAPH_STATUS_OK,
1508 "bt_graph_connect_ports() returns an error");
1509 ok(!conn, "returned connection is still NULL");
1510 gsrc = bt_component_source_as_component_const(src);
1511 gsink = bt_component_sink_as_component_const(sink);
1512 gsrc_def_port = bt_port_output_as_port_const(src_def_port);
1513 gsink_def_port = bt_port_input_as_port_const(sink_def_port);
1514
1515 /* We're supposed to have 5 events */
1516 ok(events->len == 7, "we have the expected number of events");
1517
1518 /* Source's port added */
1519 event.type = GRAPH_SRC_OUTPUT_PORT_ADDED;
1520 event.data.graph_src_output_port_added.comp = gsrc;
1521 event.data.graph_src_output_port_added.port = gsrc_def_port;
1522 ok(has_event(&event), "got the expected graph's port added event (for source, initial)");
1523
1524 /* Sink's port added */
1525 event.type = GRAPH_SINK_INPUT_PORT_ADDED;
1526 event.data.graph_sink_input_port_added.comp = gsink;
1527 event.data.graph_sink_input_port_added.port = gsink_def_port;
1528 ok(has_event(&event), "got the expected graph's port added event (for sink, initial)");
1529
1530 /* Source's accept port connection */
1531 event.type = SRC_COMP_ACCEPT_OUTPUT_PORT_CONNECTION;
1532 event.data.src_comp_accept_output_port_connection.comp = gsrc;
1533 event.data.src_comp_accept_output_port_connection.self_port = gsrc_def_port;
1534 event.data.src_comp_accept_output_port_connection.other_port = gsink_def_port;
1535 ok(has_event(&event), "got the expected source's accept port connection event");
1536 src_accept_port_connection_pos = event_pos(&event);
1537
1538 /* Sink's accept port connection */
1539 event.type = SINK_COMP_ACCEPT_INPUT_PORT_CONNECTION;
1540 event.data.sink_comp_accept_input_port_connection.comp = gsink;
1541 event.data.sink_comp_accept_input_port_connection.self_port = gsink_def_port;
1542 event.data.sink_comp_accept_input_port_connection.other_port = gsrc_def_port;
1543 ok(has_event(&event), "got the expected sink's accept port connection event");
1544 sink_accept_port_connection_pos = event_pos(&event);
1545
1546 /* Source's port connected */
1547 event.type = SRC_COMP_OUTPUT_PORT_CONNECTED;
1548 event.data.src_comp_output_port_connected.comp = gsrc;
1549 event.data.src_comp_output_port_connected.self_port = gsrc_def_port;
1550 event.data.src_comp_output_port_connected.other_port = gsink_def_port;
1551 ok(has_event(&event), "got the expected source's port connected event");
1552 src_port_connected_pos = event_pos(&event);
1553
1554 /* Sink's port connected */
1555 event.type = SINK_COMP_INPUT_PORT_CONNECTED;
1556 event.data.sink_comp_input_port_connected.comp = gsink;
1557 event.data.sink_comp_input_port_connected.self_port = gsink_def_port;
1558 event.data.sink_comp_input_port_connected.other_port = gsrc_def_port;
1559 ok(has_event(&event), "got the expected sink's port connected event");
1560 sink_port_connected_pos = event_pos(&event);
1561
1562 /* Source's port disconnected */
1563 event.type = SRC_COMP_OUTPUT_PORT_DISCONNECTED;
1564 event.data.src_comp_output_port_disconnected.comp = gsrc;
1565 event.data.src_comp_output_port_disconnected.self_port = gsrc_def_port;
1566 ok(has_event(&event), "got the expected source's port disconnected event");
1567 src_port_disconnected_pos = event_pos(&event);
1568
1569 /* Order of events */
1570 ok(src_accept_port_connection_pos < src_port_connected_pos,
1571 "event order is good (1)");
1572 ok(sink_accept_port_connection_pos < sink_port_connected_pos,
1573 "event order is good (2)");
1574 ok(sink_port_connected_pos < src_port_disconnected_pos,
1575 "event order is good (3)");
1576
1577 bt_connection_put_ref(conn);
1578 bt_graph_put_ref(graph);
1579 bt_component_sink_put_ref(sink);
1580 bt_component_source_put_ref(src);
1581 }
1582
1583 static
1584 void test_empty_graph(void)
1585 {
1586 bt_graph *graph;
1587
1588 prepare_test(TEST_EMPTY_GRAPH, "empty graph");
1589 graph = create_graph();
1590 ok(events->len == 0, "empty graph generates no events");
1591 bt_graph_put_ref(graph);
1592 }
1593
1594 int main(int argc, char **argv)
1595 {
1596 plan_tests(NR_TESTS);
1597 init_test();
1598 test_empty_graph();
1599 test_simple();
1600 test_src_port_connected_error();
1601 test_sink_port_connected_error();
1602 test_src_adds_port_in_port_connected();
1603 test_sink_removes_port_in_consume();
1604 test_sink_removes_port_in_consume_then_src_removes_disconnected_port();
1605 fini_test();
1606 return exit_status();
1607 }
This page took 0.09841 seconds and 4 git commands to generate.