bf4a8629feee67c974179ede89401dfde67a972b
[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 48
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 GRAPH_SRC_OUTPUT_PORT_ADDED,
37 GRAPH_SINK_INPUT_PORT_ADDED,
38 GRAPH_SRC_SINK_PORTS_CONNECTED,
39 };
40
41 enum test {
42 TEST_EMPTY_GRAPH,
43 TEST_SIMPLE,
44 TEST_SRC_PORT_CONNECTED_ERROR,
45 TEST_SINK_PORT_CONNECTED_ERROR,
46 TEST_SRC_ADDS_PORT_IN_PORT_CONNECTED,
47 };
48
49 struct event {
50 enum event_type type;
51
52 union {
53 struct {
54 const bt_component *comp;
55 const bt_port *self_port;
56 const bt_port *other_port;
57 } src_comp_accept_output_port_connection;
58
59 struct {
60 const bt_component *comp;
61 const bt_port *self_port;
62 const bt_port *other_port;
63 } sink_comp_accept_input_port_connection;
64
65 struct {
66 const bt_component *comp;
67 const bt_port *self_port;
68 const bt_port *other_port;
69 } src_comp_output_port_connected;
70
71 struct {
72 const bt_component *comp;
73 const bt_port *self_port;
74 const bt_port *other_port;
75 } sink_comp_input_port_connected;
76
77 struct {
78 const bt_component *comp;
79 const bt_port *port;
80 } graph_src_output_port_added;
81
82 struct {
83 const bt_component *comp;
84 const bt_port *port;
85 } graph_sink_input_port_added;
86
87 struct {
88 const bt_component *upstream_comp;
89 const bt_component *downstream_comp;
90 const bt_port *upstream_port;
91 const bt_port *downstream_port;
92 } graph_src_sink_ports_connected;
93 } data;
94 };
95
96 static GArray *events;
97 static bt_component_class_source *src_comp_class;
98 static bt_component_class_sink *sink_comp_class;
99 static enum test current_test;
100
101 static
102 void clear_events(void)
103 {
104 g_array_set_size(events, 0);
105 }
106
107 static
108 void append_event(struct event *event)
109 {
110 g_array_append_val(events, *event);
111 }
112
113 static
114 bool compare_events(struct event *ev_a, struct event *ev_b)
115 {
116 if (ev_a->type != ev_b->type) {
117 return false;
118 }
119
120 switch (ev_a->type) {
121 case SRC_COMP_ACCEPT_OUTPUT_PORT_CONNECTION:
122 if (ev_a->data.src_comp_accept_output_port_connection.comp !=
123 ev_b->data.src_comp_accept_output_port_connection.comp) {
124 return false;
125 }
126
127 if (ev_a->data.src_comp_accept_output_port_connection.self_port !=
128 ev_b->data.src_comp_accept_output_port_connection.self_port) {
129 return false;
130 }
131
132 if (ev_a->data.src_comp_accept_output_port_connection.other_port !=
133 ev_b->data.src_comp_accept_output_port_connection.other_port) {
134 return false;
135 }
136 break;
137 case SINK_COMP_ACCEPT_INPUT_PORT_CONNECTION:
138 if (ev_a->data.sink_comp_accept_input_port_connection.comp !=
139 ev_b->data.sink_comp_accept_input_port_connection.comp) {
140 return false;
141 }
142
143 if (ev_a->data.sink_comp_accept_input_port_connection.self_port !=
144 ev_b->data.sink_comp_accept_input_port_connection.self_port) {
145 return false;
146 }
147
148 if (ev_a->data.sink_comp_accept_input_port_connection.other_port !=
149 ev_b->data.sink_comp_accept_input_port_connection.other_port) {
150 return false;
151 }
152 break;
153 case SRC_COMP_OUTPUT_PORT_CONNECTED:
154 if (ev_a->data.src_comp_output_port_connected.comp !=
155 ev_b->data.src_comp_output_port_connected.comp) {
156 return false;
157 }
158
159 if (ev_a->data.src_comp_output_port_connected.self_port !=
160 ev_b->data.src_comp_output_port_connected.self_port) {
161 return false;
162 }
163
164 if (ev_a->data.src_comp_output_port_connected.other_port !=
165 ev_b->data.src_comp_output_port_connected.other_port) {
166 return false;
167 }
168 break;
169 case SINK_COMP_INPUT_PORT_CONNECTED:
170 if (ev_a->data.sink_comp_input_port_connected.comp !=
171 ev_b->data.sink_comp_input_port_connected.comp) {
172 return false;
173 }
174
175 if (ev_a->data.sink_comp_input_port_connected.self_port !=
176 ev_b->data.sink_comp_input_port_connected.self_port) {
177 return false;
178 }
179
180 if (ev_a->data.sink_comp_input_port_connected.other_port !=
181 ev_b->data.sink_comp_input_port_connected.other_port) {
182 return false;
183 }
184 break;
185 case GRAPH_SRC_OUTPUT_PORT_ADDED:
186 if (ev_a->data.graph_src_output_port_added.comp !=
187 ev_b->data.graph_src_output_port_added.comp) {
188 return false;
189 }
190
191 if (ev_a->data.graph_src_output_port_added.port !=
192 ev_b->data.graph_src_output_port_added.port) {
193 return false;
194 }
195 break;
196 case GRAPH_SINK_INPUT_PORT_ADDED:
197 if (ev_a->data.graph_sink_input_port_added.comp !=
198 ev_b->data.graph_sink_input_port_added.comp) {
199 return false;
200 }
201
202 if (ev_a->data.graph_sink_input_port_added.port !=
203 ev_b->data.graph_sink_input_port_added.port) {
204 return false;
205 }
206 break;
207 case GRAPH_SRC_SINK_PORTS_CONNECTED:
208 if (ev_a->data.graph_src_sink_ports_connected.upstream_comp !=
209 ev_b->data.graph_src_sink_ports_connected.upstream_comp) {
210 return false;
211 }
212
213 if (ev_a->data.graph_src_sink_ports_connected.downstream_comp !=
214 ev_b->data.graph_src_sink_ports_connected.downstream_comp) {
215 return false;
216 }
217
218 if (ev_a->data.graph_src_sink_ports_connected.upstream_port !=
219 ev_b->data.graph_src_sink_ports_connected.upstream_port) {
220 return false;
221 }
222
223 if (ev_a->data.graph_src_sink_ports_connected.downstream_port !=
224 ev_b->data.graph_src_sink_ports_connected.downstream_port) {
225 return false;
226 }
227 break;
228 default:
229 abort();
230 }
231
232 return true;
233 }
234
235 static
236 bool has_event(struct event *event)
237 {
238 size_t i;
239
240 for (i = 0; i < events->len; i++) {
241 struct event *ev = &g_array_index(events, struct event, i);
242
243 if (compare_events(event, ev)) {
244 return true;
245 }
246 }
247
248 return false;
249 }
250
251 static
252 size_t event_pos(struct event *event)
253 {
254 size_t i;
255
256 for (i = 0; i < events->len; i++) {
257 struct event *ev = &g_array_index(events, struct event, i);
258
259 if (compare_events(event, ev)) {
260 return i;
261 }
262 }
263
264 return SIZE_MAX;
265 }
266
267 static
268 bt_self_message_iterator_status src_iter_next(
269 bt_self_message_iterator *self_iterator,
270 bt_message_array_const msgs, uint64_t capacity,
271 uint64_t *count)
272 {
273 return BT_SELF_MESSAGE_ITERATOR_STATUS_ERROR;
274 }
275
276 static
277 bt_self_component_status src_accept_output_port_connection(
278 bt_self_component_source *self_comp,
279 bt_self_component_port_output *self_comp_port,
280 const bt_port_input *other_port)
281 {
282 struct event event = {
283 .type = SRC_COMP_ACCEPT_OUTPUT_PORT_CONNECTION,
284 .data.src_comp_accept_output_port_connection = {
285 .comp = bt_self_component_as_component(
286 bt_self_component_source_as_self_component(
287 self_comp)),
288 .self_port = bt_self_component_port_as_port(
289 bt_self_component_port_output_as_self_component_port(
290 self_comp_port)),
291 .other_port = bt_port_input_as_port_const(other_port),
292 },
293 };
294
295 append_event(&event);
296 return BT_SELF_COMPONENT_STATUS_OK;
297 }
298
299 static
300 bt_self_component_status sink_accept_input_port_connection(
301 bt_self_component_sink *self_comp,
302 bt_self_component_port_input *self_comp_port,
303 const bt_port_output *other_port)
304 {
305 struct event event = {
306 .type = SINK_COMP_ACCEPT_INPUT_PORT_CONNECTION,
307 .data.sink_comp_accept_input_port_connection = {
308 .comp = bt_self_component_as_component(
309 bt_self_component_sink_as_self_component(
310 self_comp)),
311 .self_port = bt_self_component_port_as_port(
312 bt_self_component_port_input_as_self_component_port(
313 self_comp_port)),
314 .other_port = bt_port_output_as_port_const(other_port),
315 },
316 };
317
318 append_event(&event);
319 return BT_SELF_COMPONENT_STATUS_OK;
320 }
321
322 static
323 bt_self_component_status src_output_port_connected(
324 bt_self_component_source *self_comp,
325 bt_self_component_port_output *self_comp_port,
326 const bt_port_input *other_port)
327 {
328 int ret;
329 struct event event = {
330 .type = SRC_COMP_OUTPUT_PORT_CONNECTED,
331 .data.src_comp_output_port_connected = {
332 .comp = bt_self_component_as_component(
333 bt_self_component_source_as_self_component(
334 self_comp)),
335 .self_port = bt_self_component_port_as_port(
336 bt_self_component_port_output_as_self_component_port(
337 self_comp_port)),
338 .other_port = bt_port_input_as_port_const(other_port),
339 },
340 };
341
342 append_event(&event);
343
344 switch (current_test) {
345 case TEST_SRC_ADDS_PORT_IN_PORT_CONNECTED:
346 ret = bt_self_component_source_add_output_port(
347 self_comp, "hello", NULL, NULL);
348 BT_ASSERT(ret == 0);
349 break;
350 case TEST_SRC_PORT_CONNECTED_ERROR:
351 return BT_SELF_COMPONENT_STATUS_ERROR;
352 default:
353 break;
354 }
355
356 return BT_SELF_COMPONENT_STATUS_OK;
357 }
358
359 static
360 bt_self_component_status sink_input_port_connected(
361 bt_self_component_sink *self_comp,
362 bt_self_component_port_input *self_comp_port,
363 const bt_port_output *other_port)
364 {
365 struct event event = {
366 .type = SINK_COMP_INPUT_PORT_CONNECTED,
367 .data.sink_comp_input_port_connected = {
368 .comp = bt_self_component_as_component(
369 bt_self_component_sink_as_self_component(
370 self_comp)),
371 .self_port = bt_self_component_port_as_port(
372 bt_self_component_port_input_as_self_component_port(
373 self_comp_port)),
374 .other_port = bt_port_output_as_port_const(other_port),
375 },
376 };
377
378 append_event(&event);
379
380 if (current_test == TEST_SINK_PORT_CONNECTED_ERROR) {
381 return BT_SELF_COMPONENT_STATUS_ERROR;
382 } else {
383 return BT_SELF_COMPONENT_STATUS_OK;
384 }
385 }
386
387 static
388 bt_self_component_status src_init(
389 bt_self_component_source *self_comp,
390 const bt_value *params, void *init_method_data)
391 {
392 int ret;
393
394 ret = bt_self_component_source_add_output_port(
395 self_comp, "out", NULL, NULL);
396 BT_ASSERT(ret == 0);
397 return BT_SELF_COMPONENT_STATUS_OK;
398 }
399
400 static
401 bt_self_component_status sink_init(
402 bt_self_component_sink *self_comp,
403 const bt_value *params, void *init_method_data)
404 {
405 int ret;
406
407 ret = bt_self_component_sink_add_input_port(self_comp,
408 "in", NULL, NULL);
409 BT_ASSERT(ret == 0);
410 return BT_SELF_COMPONENT_STATUS_OK;
411 }
412
413 static
414 bt_self_component_status sink_consume(
415 bt_self_component_sink *self_comp)
416 {
417 return BT_SELF_COMPONENT_STATUS_OK;
418 }
419
420 static
421 bt_graph_listener_status graph_src_output_port_added(
422 const bt_component_source *comp, const bt_port_output *port,
423 void *data)
424 {
425 struct event event = {
426 .type = GRAPH_SRC_OUTPUT_PORT_ADDED,
427 .data.graph_src_output_port_added = {
428 .comp = bt_component_source_as_component_const(comp),
429 .port = bt_port_output_as_port_const(port),
430 },
431 };
432
433 append_event(&event);
434
435 return BT_GRAPH_LISTENER_STATUS_OK;
436 }
437
438 static
439 bt_graph_listener_status graph_sink_input_port_added(
440 const bt_component_sink *comp, const bt_port_input *port,
441 void *data)
442 {
443 struct event event = {
444 .type = GRAPH_SINK_INPUT_PORT_ADDED,
445 .data.graph_sink_input_port_added = {
446 .comp = bt_component_sink_as_component_const(comp),
447 .port = bt_port_input_as_port_const(port),
448 },
449 };
450
451 append_event(&event);
452
453 return BT_GRAPH_LISTENER_STATUS_OK;
454 }
455
456 static
457 bt_graph_listener_status graph_src_sink_ports_connected(
458 const bt_component_source *upstream_comp,
459 const bt_component_sink *downstream_comp,
460 const bt_port_output *upstream_port,
461 const bt_port_input *downstream_port, void *data)
462 {
463 struct event event = {
464 .type = GRAPH_SRC_SINK_PORTS_CONNECTED,
465 .data.graph_src_sink_ports_connected = {
466 .upstream_comp =
467 bt_component_source_as_component_const(upstream_comp),
468 .downstream_comp =
469 bt_component_sink_as_component_const(downstream_comp),
470 .upstream_port =
471 bt_port_output_as_port_const(upstream_port),
472 .downstream_port =
473 bt_port_input_as_port_const(downstream_port),
474 },
475 };
476
477 append_event(&event);
478
479 return BT_GRAPH_LISTENER_STATUS_OK;
480 }
481
482 static
483 void init_test(void)
484 {
485 int ret;
486
487 src_comp_class = bt_component_class_source_create(
488 "src", src_iter_next);
489 BT_ASSERT(src_comp_class);
490 ret = bt_component_class_source_set_init_method(
491 src_comp_class, src_init);
492 BT_ASSERT(ret == 0);
493 ret = bt_component_class_source_set_accept_output_port_connection_method(
494 src_comp_class, src_accept_output_port_connection);
495 BT_ASSERT(ret == 0);
496 ret = bt_component_class_source_set_output_port_connected_method(
497 src_comp_class, src_output_port_connected);
498 BT_ASSERT(ret == 0);
499 sink_comp_class = bt_component_class_sink_create("sink",
500 sink_consume);
501 BT_ASSERT(sink_comp_class);
502 ret = bt_component_class_sink_set_init_method(sink_comp_class,
503 sink_init);
504 BT_ASSERT(ret == 0);
505 ret = bt_component_class_sink_set_accept_input_port_connection_method(
506 sink_comp_class, sink_accept_input_port_connection);
507 BT_ASSERT(ret == 0);
508 ret = bt_component_class_sink_set_input_port_connected_method(
509 sink_comp_class, sink_input_port_connected);
510 BT_ASSERT(ret == 0);
511 events = g_array_new(FALSE, TRUE, sizeof(struct event));
512 BT_ASSERT(events);
513 }
514
515 static
516 void fini_test(void)
517 {
518 bt_component_class_source_put_ref(src_comp_class);
519 bt_component_class_sink_put_ref(sink_comp_class);
520 g_array_free(events, TRUE);
521 }
522
523 static
524 const bt_component_source *create_src(bt_graph *graph)
525 {
526 const bt_component_source *comp;
527 int ret;
528
529 ret = bt_graph_add_source_component(graph, src_comp_class,
530 "src-comp", NULL, &comp);
531 BT_ASSERT(ret == 0);
532 return comp;
533 }
534
535 static
536 const bt_component_sink *create_sink(bt_graph *graph)
537 {
538 const bt_component_sink *comp;
539 int ret;
540
541 ret = bt_graph_add_sink_component(graph, sink_comp_class,
542 "sink-comp", NULL, &comp);
543 BT_ASSERT(ret == 0);
544 return comp;
545 }
546
547 static
548 bt_graph *create_graph(void)
549 {
550 bt_graph *graph = bt_graph_create();
551 int ret;
552
553 BT_ASSERT(graph);
554 ret = bt_graph_add_source_component_output_port_added_listener(
555 graph, graph_src_output_port_added, NULL, NULL, NULL);
556 BT_ASSERT(ret >= 0);
557 ret = bt_graph_add_sink_component_input_port_added_listener(
558 graph, graph_sink_input_port_added, NULL, NULL, NULL);
559 BT_ASSERT(ret >= 0);
560 ret = bt_graph_add_source_sink_component_ports_connected_listener(
561 graph, graph_src_sink_ports_connected, NULL, NULL, NULL);
562 BT_ASSERT(ret >= 0);
563 return graph;
564 }
565
566 static
567 void prepare_test(enum test test, const char *name)
568 {
569 clear_events();
570 current_test = test;
571 diag("test: %s", name);
572 }
573
574 static
575 void test_src_adds_port_in_port_connected(void)
576 {
577 const bt_component_source *src;
578 const bt_component_sink *sink;
579 const bt_component *gsrc;
580 const bt_component *gsink;
581 bt_graph *graph;
582 const bt_port_output *src_def_port;
583 const bt_port_output *src_hello_port;
584 const bt_port_input *sink_def_port;
585 const bt_port *gsrc_def_port;
586 const bt_port *gsrc_hello_port;
587 const bt_port *gsink_def_port;
588 struct event event;
589 bt_graph_status status;
590 size_t src_accept_port_connection_pos;
591 size_t sink_accept_port_connection_pos;
592 size_t src_port_connected_pos;
593 size_t sink_port_connected_pos;
594 size_t graph_ports_connected_pos;
595 size_t graph_port_added_src_pos;
596
597 prepare_test(TEST_SRC_ADDS_PORT_IN_PORT_CONNECTED,
598 "source adds port in port connected");
599 graph = create_graph();
600 BT_ASSERT(graph);
601 src = create_src(graph);
602 sink = create_sink(graph);
603 src_def_port = bt_component_source_borrow_output_port_by_name_const(src,
604 "out");
605 BT_ASSERT(src_def_port);
606 sink_def_port = bt_component_sink_borrow_input_port_by_name_const(sink,
607 "in");
608 BT_ASSERT(sink_def_port);
609 status = bt_graph_connect_ports(graph, src_def_port,
610 sink_def_port, NULL);
611 BT_ASSERT(status == 0);
612 src_hello_port = bt_component_source_borrow_output_port_by_name_const(src,
613 "hello");
614 BT_ASSERT(src_hello_port);
615 gsrc = bt_component_source_as_component_const(src);
616 gsink = bt_component_sink_as_component_const(sink);
617 gsrc_def_port = bt_port_output_as_port_const(src_def_port);
618 gsrc_hello_port = bt_port_output_as_port_const(src_hello_port);
619 gsink_def_port = bt_port_input_as_port_const(sink_def_port);
620
621 /* We're supposed to have 8 events */
622 ok(events->len == 8, "we have the expected number of events");
623
624 /* Source's port added */
625 event.type = GRAPH_SRC_OUTPUT_PORT_ADDED;
626 event.data.graph_src_output_port_added.comp = gsrc;
627 event.data.graph_src_output_port_added.port = gsrc_def_port;
628 ok(has_event(&event), "got the expected graph's port added event (for source, initial)");
629
630 /* Sink's port added */
631 event.type = GRAPH_SINK_INPUT_PORT_ADDED;
632 event.data.graph_sink_input_port_added.comp = gsink;
633 event.data.graph_sink_input_port_added.port = gsink_def_port;
634 ok(has_event(&event), "got the expected graph's port added event (for sink, initial)");
635
636 /* Source's accept port connection */
637 event.type = SRC_COMP_ACCEPT_OUTPUT_PORT_CONNECTION;
638 event.data.src_comp_accept_output_port_connection.comp = gsrc;
639 event.data.src_comp_accept_output_port_connection.self_port = gsrc_def_port;
640 event.data.src_comp_accept_output_port_connection.other_port = gsink_def_port;
641 ok(has_event(&event), "got the expected source's accept port connection event");
642 src_accept_port_connection_pos = event_pos(&event);
643
644 /* Sink's accept port connection */
645 event.type = SINK_COMP_ACCEPT_INPUT_PORT_CONNECTION;
646 event.data.sink_comp_accept_input_port_connection.comp = gsink;
647 event.data.sink_comp_accept_input_port_connection.self_port = gsink_def_port;
648 event.data.sink_comp_accept_input_port_connection.other_port = gsrc_def_port;
649 ok(has_event(&event), "got the expected sink's accept port connection event");
650 sink_accept_port_connection_pos = event_pos(&event);
651
652 /* Source's port connected */
653 event.type = SRC_COMP_OUTPUT_PORT_CONNECTED;
654 event.data.src_comp_output_port_connected.comp = gsrc;
655 event.data.src_comp_output_port_connected.self_port = gsrc_def_port;
656 event.data.src_comp_output_port_connected.other_port = gsink_def_port;
657 ok(has_event(&event), "got the expected source's port connected event");
658 src_port_connected_pos = event_pos(&event);
659
660 /* Graph's port added (source) */
661 event.type = GRAPH_SRC_OUTPUT_PORT_ADDED;
662 event.data.graph_src_output_port_added.comp = gsrc;
663 event.data.graph_src_output_port_added.port = gsrc_hello_port;
664 ok(has_event(&event), "got the expected graph's port added event (for source)");
665 graph_port_added_src_pos = event_pos(&event);
666
667 /* Sink's port connected */
668 event.type = SINK_COMP_INPUT_PORT_CONNECTED;
669 event.data.sink_comp_input_port_connected.comp = gsink;
670 event.data.sink_comp_input_port_connected.self_port = gsink_def_port;
671 event.data.sink_comp_input_port_connected.other_port = gsrc_def_port;
672 ok(has_event(&event), "got the expected sink's port connected event");
673 sink_port_connected_pos = event_pos(&event);
674
675 /* Graph's ports connected */
676 event.type = GRAPH_SRC_SINK_PORTS_CONNECTED;
677 event.data.graph_src_sink_ports_connected.upstream_comp = gsrc;
678 event.data.graph_src_sink_ports_connected.downstream_comp = gsink;
679 event.data.graph_src_sink_ports_connected.upstream_port = gsrc_def_port;
680 event.data.graph_src_sink_ports_connected.downstream_port = gsink_def_port;
681 ok(has_event(&event), "got the expected graph's ports connected event");
682 graph_ports_connected_pos = event_pos(&event);
683
684 /* Order of events */
685 ok(src_port_connected_pos < graph_ports_connected_pos,
686 "event order is good (1)");
687 ok(sink_port_connected_pos < graph_ports_connected_pos,
688 "event order is good (2)");
689 ok(src_accept_port_connection_pos < src_port_connected_pos,
690 "event order is good (3)");
691 ok(sink_accept_port_connection_pos < sink_port_connected_pos,
692 "event order is good (4)");
693 ok(src_port_connected_pos < graph_port_added_src_pos,
694 "event order is good (5)");
695 ok(graph_port_added_src_pos < graph_ports_connected_pos,
696 "event order is good (6)");
697
698 bt_component_source_put_ref(src);
699 bt_component_sink_put_ref(sink);
700 bt_graph_put_ref(graph);
701 }
702
703 static
704 void test_simple(void)
705 {
706 const bt_component_source *src;
707 const bt_component_sink *sink;
708 const bt_component *gsrc;
709 const bt_component *gsink;
710 bt_graph *graph;
711 const bt_port_output *src_def_port;
712 const bt_port_input *sink_def_port;
713 const bt_port *gsrc_def_port;
714 const bt_port *gsink_def_port;
715 struct event event;
716 bt_graph_status status;
717 size_t src_accept_port_connection_pos;
718 size_t sink_accept_port_connection_pos;
719 size_t src_port_connected_pos;
720 size_t sink_port_connected_pos;
721 size_t graph_ports_connected_pos;
722
723 prepare_test(TEST_SIMPLE, "simple");
724 graph = create_graph();
725 BT_ASSERT(graph);
726 src = create_src(graph);
727 sink = create_sink(graph);
728 src_def_port = bt_component_source_borrow_output_port_by_name_const(src,
729 "out");
730 BT_ASSERT(src_def_port);
731 sink_def_port = bt_component_sink_borrow_input_port_by_name_const(sink,
732 "in");
733 BT_ASSERT(sink_def_port);
734 status = bt_graph_connect_ports(graph, src_def_port,
735 sink_def_port, NULL);
736 BT_ASSERT(status == 0);
737 gsrc = bt_component_source_as_component_const(src);
738 gsink = bt_component_sink_as_component_const(sink);
739 gsrc_def_port = bt_port_output_as_port_const(src_def_port);
740 gsink_def_port = bt_port_input_as_port_const(sink_def_port);
741
742 /* We're supposed to have 7 events */
743 ok(events->len == 7, "we have the expected number of events");
744
745 /* Source's port added */
746 event.type = GRAPH_SRC_OUTPUT_PORT_ADDED;
747 event.data.graph_src_output_port_added.comp = gsrc;
748 event.data.graph_src_output_port_added.port = gsrc_def_port;
749 ok(has_event(&event), "got the expected graph's port added event (for source, initial)");
750
751 /* Sink's port added */
752 event.type = GRAPH_SINK_INPUT_PORT_ADDED;
753 event.data.graph_sink_input_port_added.comp = gsink;
754 event.data.graph_sink_input_port_added.port = gsink_def_port;
755 ok(has_event(&event), "got the expected graph's port added event (for sink, initial)");
756
757 /* Source's accept port connection */
758 event.type = SRC_COMP_ACCEPT_OUTPUT_PORT_CONNECTION;
759 event.data.src_comp_accept_output_port_connection.comp = gsrc;
760 event.data.src_comp_accept_output_port_connection.self_port = gsrc_def_port;
761 event.data.src_comp_accept_output_port_connection.other_port = gsink_def_port;
762 ok(has_event(&event), "got the expected source's accept port connection event");
763 src_accept_port_connection_pos = event_pos(&event);
764
765 /* Sink's accept port connection */
766 event.type = SINK_COMP_ACCEPT_INPUT_PORT_CONNECTION;
767 event.data.sink_comp_accept_input_port_connection.comp = gsink;
768 event.data.sink_comp_accept_input_port_connection.self_port = gsink_def_port;
769 event.data.sink_comp_accept_input_port_connection.other_port = gsrc_def_port;
770 ok(has_event(&event), "got the expected sink's accept port connection event");
771 sink_accept_port_connection_pos = event_pos(&event);
772
773 /* Source's port connected */
774 event.type = SRC_COMP_OUTPUT_PORT_CONNECTED;
775 event.data.src_comp_output_port_connected.comp = gsrc;
776 event.data.src_comp_output_port_connected.self_port = gsrc_def_port;
777 event.data.src_comp_output_port_connected.other_port = gsink_def_port;
778 ok(has_event(&event), "got the expected source's port connected event");
779 src_port_connected_pos = event_pos(&event);
780
781 /* Sink's port connected */
782 event.type = SINK_COMP_INPUT_PORT_CONNECTED;
783 event.data.sink_comp_input_port_connected.comp = gsink;
784 event.data.sink_comp_input_port_connected.self_port = gsink_def_port;
785 event.data.sink_comp_input_port_connected.other_port = gsrc_def_port;
786 ok(has_event(&event), "got the expected sink's port connected event");
787 sink_port_connected_pos = event_pos(&event);
788
789 /* Graph's ports connected */
790 event.type = GRAPH_SRC_SINK_PORTS_CONNECTED;
791 event.data.graph_src_sink_ports_connected.upstream_comp = gsrc;
792 event.data.graph_src_sink_ports_connected.downstream_comp = gsink;
793 event.data.graph_src_sink_ports_connected.upstream_port = gsrc_def_port;
794 event.data.graph_src_sink_ports_connected.downstream_port = gsink_def_port;
795 ok(has_event(&event), "got the expected graph's ports connected event");
796 graph_ports_connected_pos = event_pos(&event);
797
798 /* Order of events */
799 ok(src_port_connected_pos < graph_ports_connected_pos,
800 "event order is good (1)");
801 ok(sink_port_connected_pos < graph_ports_connected_pos,
802 "event order is good (2)");
803 ok(src_accept_port_connection_pos < src_port_connected_pos,
804 "event order is good (3)");
805 ok(sink_accept_port_connection_pos < sink_port_connected_pos,
806 "event order is good (4)");
807
808 bt_component_sink_put_ref(sink);
809 bt_graph_put_ref(graph);
810 bt_component_source_put_ref(src);
811 }
812
813 static
814 void test_src_port_connected_error(void)
815 {
816 const bt_component_source *src;
817 const bt_component_sink *sink;
818 const bt_component *gsrc;
819 const bt_component *gsink;
820 bt_graph *graph;
821 const bt_port_output *src_def_port;
822 const bt_port_input *sink_def_port;
823 const bt_port *gsrc_def_port;
824 const bt_port *gsink_def_port;
825 const bt_connection *conn = NULL;
826 struct event event;
827 bt_graph_status status;
828 size_t src_accept_port_connection_pos;
829 size_t src_port_connected_pos;
830
831 prepare_test(TEST_SRC_PORT_CONNECTED_ERROR, "port connected error: source");
832 graph = create_graph();
833 BT_ASSERT(graph);
834 src = create_src(graph);
835 sink = create_sink(graph);
836 src_def_port = bt_component_source_borrow_output_port_by_name_const(src,
837 "out");
838 BT_ASSERT(src_def_port);
839 sink_def_port = bt_component_sink_borrow_input_port_by_name_const(sink,
840 "in");
841 BT_ASSERT(sink_def_port);
842 status = bt_graph_connect_ports(graph, src_def_port,
843 sink_def_port, &conn);
844 ok(status != BT_GRAPH_STATUS_OK,
845 "bt_graph_connect_ports() returns an error");
846 ok(!conn, "returned connection is still NULL");
847 gsrc = bt_component_source_as_component_const(src);
848 gsink = bt_component_sink_as_component_const(sink);
849 gsrc_def_port = bt_port_output_as_port_const(src_def_port);
850 gsink_def_port = bt_port_input_as_port_const(sink_def_port);
851
852 /* We're supposed to have 5 events */
853 ok(events->len == 5, "we have the expected number of events");
854
855 /* Source's port added */
856 event.type = GRAPH_SRC_OUTPUT_PORT_ADDED;
857 event.data.graph_src_output_port_added.comp = gsrc;
858 event.data.graph_src_output_port_added.port = gsrc_def_port;
859 ok(has_event(&event), "got the expected graph's port added event (for source, initial)");
860
861 /* Sink's port added */
862 event.type = GRAPH_SINK_INPUT_PORT_ADDED;
863 event.data.graph_sink_input_port_added.comp = gsink;
864 event.data.graph_sink_input_port_added.port = gsink_def_port;
865 ok(has_event(&event), "got the expected graph's port added event (for sink, initial)");
866
867 /* Source's accept port connection */
868 event.type = SRC_COMP_ACCEPT_OUTPUT_PORT_CONNECTION;
869 event.data.src_comp_accept_output_port_connection.comp = gsrc;
870 event.data.src_comp_accept_output_port_connection.self_port = gsrc_def_port;
871 event.data.src_comp_accept_output_port_connection.other_port = gsink_def_port;
872 ok(has_event(&event), "got the expected source's accept port connection event");
873 src_accept_port_connection_pos = event_pos(&event);
874
875 /* Sink's accept port connection */
876 event.type = SINK_COMP_ACCEPT_INPUT_PORT_CONNECTION;
877 event.data.sink_comp_accept_input_port_connection.comp = gsink;
878 event.data.sink_comp_accept_input_port_connection.self_port = gsink_def_port;
879 event.data.sink_comp_accept_input_port_connection.other_port = gsrc_def_port;
880 ok(has_event(&event), "got the expected sink's accept port connection event");
881
882 /* Source's port connected */
883 event.type = SRC_COMP_OUTPUT_PORT_CONNECTED;
884 event.data.src_comp_output_port_connected.comp = gsrc;
885 event.data.src_comp_output_port_connected.self_port = gsrc_def_port;
886 event.data.src_comp_output_port_connected.other_port = gsink_def_port;
887 ok(has_event(&event), "got the expected source's port connected event");
888 src_port_connected_pos = event_pos(&event);
889
890 /* Order of events */
891 ok(src_accept_port_connection_pos < src_port_connected_pos,
892 "event order is good (1)");
893
894 bt_graph_put_ref(graph);
895 bt_component_sink_put_ref(sink);
896 bt_component_source_put_ref(src);
897 bt_connection_put_ref(conn);
898 }
899
900 static
901 void test_sink_port_connected_error(void)
902 {
903 const bt_component_source *src;
904 const bt_component_sink *sink;
905 const bt_component *gsrc;
906 const bt_component *gsink;
907 bt_graph *graph;
908 const bt_port_output *src_def_port;
909 const bt_port_input *sink_def_port;
910 const bt_port *gsrc_def_port;
911 const bt_port *gsink_def_port;
912 const bt_connection *conn = NULL;
913 struct event event;
914 bt_graph_status status;
915 size_t src_accept_port_connection_pos;
916 size_t sink_accept_port_connection_pos;
917 size_t src_port_connected_pos;
918 size_t sink_port_connected_pos;
919
920 prepare_test(TEST_SINK_PORT_CONNECTED_ERROR, "port connected error: sink");
921 graph = create_graph();
922 BT_ASSERT(graph);
923 src = create_src(graph);
924 sink = create_sink(graph);
925 src_def_port = bt_component_source_borrow_output_port_by_name_const(src,
926 "out");
927 BT_ASSERT(src_def_port);
928 sink_def_port = bt_component_sink_borrow_input_port_by_name_const(sink,
929 "in");
930 BT_ASSERT(sink_def_port);
931 status = bt_graph_connect_ports(graph, src_def_port,
932 sink_def_port, &conn);
933 ok(status != BT_GRAPH_STATUS_OK,
934 "bt_graph_connect_ports() returns an error");
935 ok(!conn, "returned connection is still NULL");
936 gsrc = bt_component_source_as_component_const(src);
937 gsink = bt_component_sink_as_component_const(sink);
938 gsrc_def_port = bt_port_output_as_port_const(src_def_port);
939 gsink_def_port = bt_port_input_as_port_const(sink_def_port);
940
941 /* We're supposed to have 6 events */
942 ok(events->len == 6, "we have the expected number of events");
943
944 /* Source's port added */
945 event.type = GRAPH_SRC_OUTPUT_PORT_ADDED;
946 event.data.graph_src_output_port_added.comp = gsrc;
947 event.data.graph_src_output_port_added.port = gsrc_def_port;
948 ok(has_event(&event), "got the expected graph's port added event (for source, initial)");
949
950 /* Sink's port added */
951 event.type = GRAPH_SINK_INPUT_PORT_ADDED;
952 event.data.graph_sink_input_port_added.comp = gsink;
953 event.data.graph_sink_input_port_added.port = gsink_def_port;
954 ok(has_event(&event), "got the expected graph's port added event (for sink, initial)");
955
956 /* Source's accept port connection */
957 event.type = SRC_COMP_ACCEPT_OUTPUT_PORT_CONNECTION;
958 event.data.src_comp_accept_output_port_connection.comp = gsrc;
959 event.data.src_comp_accept_output_port_connection.self_port = gsrc_def_port;
960 event.data.src_comp_accept_output_port_connection.other_port = gsink_def_port;
961 ok(has_event(&event), "got the expected source's accept port connection event");
962 src_accept_port_connection_pos = event_pos(&event);
963
964 /* Sink's accept port connection */
965 event.type = SINK_COMP_ACCEPT_INPUT_PORT_CONNECTION;
966 event.data.sink_comp_accept_input_port_connection.comp = gsink;
967 event.data.sink_comp_accept_input_port_connection.self_port = gsink_def_port;
968 event.data.sink_comp_accept_input_port_connection.other_port = gsrc_def_port;
969 ok(has_event(&event), "got the expected sink's accept port connection event");
970 sink_accept_port_connection_pos = event_pos(&event);
971
972 /* Source's port connected */
973 event.type = SRC_COMP_OUTPUT_PORT_CONNECTED;
974 event.data.src_comp_output_port_connected.comp = gsrc;
975 event.data.src_comp_output_port_connected.self_port = gsrc_def_port;
976 event.data.src_comp_output_port_connected.other_port = gsink_def_port;
977 ok(has_event(&event), "got the expected source's port connected event");
978 src_port_connected_pos = event_pos(&event);
979
980 /* Sink's port connected */
981 event.type = SINK_COMP_INPUT_PORT_CONNECTED;
982 event.data.sink_comp_input_port_connected.comp = gsink;
983 event.data.sink_comp_input_port_connected.self_port = gsink_def_port;
984 event.data.sink_comp_input_port_connected.other_port = gsrc_def_port;
985 ok(has_event(&event), "got the expected sink's port connected event");
986 sink_port_connected_pos = event_pos(&event);
987
988 /* Order of events */
989 ok(src_accept_port_connection_pos < src_port_connected_pos,
990 "event order is good (1)");
991 ok(sink_accept_port_connection_pos < sink_port_connected_pos,
992 "event order is good (2)");
993
994 bt_connection_put_ref(conn);
995 bt_graph_put_ref(graph);
996 bt_component_sink_put_ref(sink);
997 bt_component_source_put_ref(src);
998 }
999
1000 static
1001 void test_empty_graph(void)
1002 {
1003 bt_graph *graph;
1004
1005 prepare_test(TEST_EMPTY_GRAPH, "empty graph");
1006 graph = create_graph();
1007 ok(events->len == 0, "empty graph generates no events");
1008 bt_graph_put_ref(graph);
1009 }
1010
1011 int main(int argc, char **argv)
1012 {
1013 plan_tests(NR_TESTS);
1014 init_test();
1015 test_empty_graph();
1016 test_simple();
1017 test_src_port_connected_error();
1018 test_sink_port_connected_error();
1019 test_src_adds_port_in_port_connected();
1020 fini_test();
1021 return exit_status();
1022 }
This page took 0.051013 seconds and 3 git commands to generate.