Split CTF IR and CTF writer APIs and implementations
[babeltrace.git] / tests / lib / test_ctf_ir_ref.c
1 /*
2 * test_ctf_ir_ref.c
3 *
4 * CTF IR Reference Count test
5 *
6 * Copyright 2016 - Jérémie Galarneau <jeremie.galarneau@efficios.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; under version 2 of the License.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 */
21
22 #include "tap/tap.h"
23 #include <babeltrace/ctf-writer/clock.h>
24 #include <babeltrace/ctf-writer/event.h>
25 #include <babeltrace/ctf-writer/fields.h>
26 #include <babeltrace/ctf-writer/stream-class.h>
27 #include <babeltrace/ctf-writer/stream.h>
28 #include <babeltrace/ctf-writer/trace.h>
29 #include <babeltrace/ctf-writer/writer.h>
30 #include <babeltrace/ctf-ir/clock-class.h>
31 #include <babeltrace/ctf-ir/event.h>
32 #include <babeltrace/ctf-ir/event-class.h>
33 #include <babeltrace/ctf-ir/fields.h>
34 #include <babeltrace/ctf-ir/stream-class.h>
35 #include <babeltrace/ctf-ir/stream.h>
36 #include <babeltrace/ctf-ir/trace.h>
37 #include <babeltrace/object-internal.h>
38 #include <babeltrace/compat/stdlib-internal.h>
39 #include <assert.h>
40 #include "common.h"
41
42 #define NR_TESTS 41
43
44 struct user {
45 struct bt_trace *tc;
46 struct bt_stream_class *sc;
47 struct bt_event_class *ec;
48 struct bt_stream *stream;
49 struct bt_event *event;
50 };
51
52 struct writer_user {
53 struct bt_ctf_writer *writer;
54 struct bt_ctf_trace *tc;
55 struct bt_ctf_stream_class *sc;
56 struct bt_ctf_event_class *ec;
57 struct bt_ctf_stream *stream;
58 struct bt_ctf_event *event;
59 };
60
61 const char *writer_user_names[] = {
62 "writer",
63 "trace",
64 "stream class",
65 "event class",
66 "stream",
67 "event",
68 };
69
70 static const size_t WRITER_USER_NR_ELEMENTS =
71 sizeof(struct writer_user) / sizeof(void *);
72
73 /**
74 * Returns a structure containing the following fields:
75 * - uint8_t payload_8;
76 * - uint16_t payload_16;
77 * - uint32_t payload_32;
78 */
79 static struct bt_field_type *create_integer_struct(void)
80 {
81 int ret;
82 struct bt_field_type *structure = NULL;
83 struct bt_field_type *ui8 = NULL, *ui16 = NULL, *ui32 = NULL;
84
85 structure = bt_field_type_structure_create();
86 if (!structure) {
87 goto error;
88 }
89
90 ui8 = bt_field_type_integer_create(8);
91 if (!ui8) {
92 diag("Failed to create uint8_t type");
93 goto error;
94 }
95 ret = bt_field_type_structure_add_field(structure, ui8,
96 "payload_8");
97 if (ret) {
98 diag("Failed to add uint8_t to structure");
99 goto error;
100 }
101 ui16 = bt_field_type_integer_create(16);
102 if (!ui16) {
103 diag("Failed to create uint16_t type");
104 goto error;
105 }
106 ret = bt_field_type_structure_add_field(structure, ui16,
107 "payload_16");
108 if (ret) {
109 diag("Failed to add uint16_t to structure");
110 goto error;
111 }
112 ui32 = bt_field_type_integer_create(32);
113 if (!ui32) {
114 diag("Failed to create uint32_t type");
115 goto error;
116 }
117 ret = bt_field_type_structure_add_field(structure, ui32,
118 "payload_32");
119 if (ret) {
120 diag("Failed to add uint32_t to structure");
121 goto error;
122 }
123 end:
124 BT_PUT(ui8);
125 BT_PUT(ui16);
126 BT_PUT(ui32);
127 return structure;
128 error:
129 BT_PUT(structure);
130 goto end;
131 }
132
133 static struct bt_ctf_field_type *create_writer_integer_struct(void)
134 {
135 int ret;
136 struct bt_ctf_field_type *structure = NULL;
137 struct bt_ctf_field_type *ui8 = NULL, *ui16 = NULL, *ui32 = NULL;
138
139 structure = bt_ctf_field_type_structure_create();
140 if (!structure) {
141 goto error;
142 }
143
144 ui8 = bt_ctf_field_type_integer_create(8);
145 if (!ui8) {
146 diag("Failed to create uint8_t type");
147 goto error;
148 }
149 ret = bt_ctf_field_type_structure_add_field(structure, ui8,
150 "payload_8");
151 if (ret) {
152 diag("Failed to add uint8_t to structure");
153 goto error;
154 }
155 ui16 = bt_ctf_field_type_integer_create(16);
156 if (!ui16) {
157 diag("Failed to create uint16_t type");
158 goto error;
159 }
160 ret = bt_ctf_field_type_structure_add_field(structure, ui16,
161 "payload_16");
162 if (ret) {
163 diag("Failed to add uint16_t to structure");
164 goto error;
165 }
166 ui32 = bt_ctf_field_type_integer_create(32);
167 if (!ui32) {
168 diag("Failed to create uint32_t type");
169 goto error;
170 }
171 ret = bt_ctf_field_type_structure_add_field(structure, ui32,
172 "payload_32");
173 if (ret) {
174 diag("Failed to add uint32_t to structure");
175 goto error;
176 }
177 end:
178 BT_PUT(ui8);
179 BT_PUT(ui16);
180 BT_PUT(ui32);
181 return structure;
182 error:
183 BT_PUT(structure);
184 goto end;
185 }
186
187 /**
188 * A simple event has the following payload:
189 * - uint8_t payload_8;
190 * - uint16_t payload_16;
191 * - uint32_t payload_32;
192 */
193 static struct bt_event_class *create_simple_event(const char *name)
194 {
195 int ret;
196 struct bt_event_class *event = NULL;
197 struct bt_field_type *payload = NULL;
198
199 assert(name);
200 event = bt_event_class_create(name);
201 if (!event) {
202 diag("Failed to create simple event");
203 goto error;
204 }
205
206 payload = create_integer_struct();
207 if (!payload) {
208 diag("Failed to initialize integer structure");
209 goto error;
210 }
211
212 ret = bt_event_class_set_payload_field_type(event, payload);
213 if (ret) {
214 diag("Failed to set simple event payload");
215 goto error;
216 }
217 end:
218 BT_PUT(payload);
219 return event;
220 error:
221 BT_PUT(event);
222 goto end;;
223 }
224
225 /**
226 * A complex event has the following payload:
227 * - uint8_t payload_8;
228 * - uint16_t payload_16;
229 * - uint32_t payload_32;
230 * - struct payload_struct:
231 * - uint8_t payload_8;
232 * - uint16_t payload_16;
233 * - uint32_t payload_32;
234 */
235 static struct bt_event_class *create_complex_event(const char *name)
236 {
237 int ret;
238 struct bt_event_class *event = NULL;
239 struct bt_field_type *inner = NULL, *outer = NULL;
240
241 assert(name);
242 event = bt_event_class_create(name);
243 if (!event) {
244 diag("Failed to create complex event");
245 goto error;
246 }
247
248 outer = create_integer_struct();
249 if (!outer) {
250 diag("Failed to initialize integer structure");
251 goto error;
252 }
253
254 inner = create_integer_struct();
255 if (!inner) {
256 diag("Failed to initialize integer structure");
257 goto error;
258 }
259
260 ret = bt_field_type_structure_add_field(outer, inner,
261 "payload_struct");
262 if (ret) {
263 diag("Failed to add inner structure to outer structure");
264 goto error;
265 }
266
267 ret = bt_event_class_set_payload_field_type(event, outer);
268 if (ret) {
269 diag("Failed to set complex event payload");
270 goto error;
271 }
272 end:
273 BT_PUT(inner);
274 BT_PUT(outer);
275 return event;
276 error:
277 BT_PUT(event);
278 goto end;;
279 }
280
281 static void set_stream_class_field_types(
282 struct bt_stream_class *stream_class)
283 {
284 struct bt_field_type *packet_context_type;
285 struct bt_field_type *event_header_type;
286 struct bt_field_type *ft;
287 int ret;
288
289 packet_context_type = bt_field_type_structure_create();
290 assert(packet_context_type);
291 ft = bt_field_type_integer_create(32);
292 assert(ft);
293 ret = bt_field_type_structure_add_field(packet_context_type,
294 ft, "packet_size");
295 assert(ret == 0);
296 bt_put(ft);
297 ft = bt_field_type_integer_create(32);
298 assert(ft);
299 ret = bt_field_type_structure_add_field(packet_context_type,
300 ft, "content_size");
301 assert(ret == 0);
302 bt_put(ft);
303
304 event_header_type = bt_field_type_structure_create();
305 assert(event_header_type);
306 ft = bt_field_type_integer_create(32);
307 assert(ft);
308 ret = bt_field_type_structure_add_field(event_header_type,
309 ft, "id");
310 assert(ret == 0);
311 bt_put(ft);
312
313 ret = bt_stream_class_set_packet_context_field_type(stream_class,
314 packet_context_type);
315 assert(ret == 0);
316 ret = bt_stream_class_set_event_header_field_type(stream_class,
317 event_header_type);
318 assert(ret == 0);
319
320 bt_put(packet_context_type);
321 bt_put(event_header_type);
322 }
323
324 static struct bt_stream_class *create_sc1(void)
325 {
326 int ret;
327 struct bt_event_class *ec1 = NULL, *ec2 = NULL;
328 struct bt_stream_class *sc1 = NULL, *ret_stream = NULL;
329
330 sc1 = bt_stream_class_create("sc1");
331 if (!sc1) {
332 diag("Failed to create Stream Class");
333 goto error;
334 }
335
336 set_stream_class_field_types(sc1);
337 ec1 = create_complex_event("ec1");
338 if (!ec1) {
339 diag("Failed to create complex event EC1");
340 goto error;
341 }
342 ret = bt_stream_class_add_event_class(sc1, ec1);
343 if (ret) {
344 diag("Failed to add EC1 to SC1");
345 goto error;
346 }
347
348 ec2 = create_simple_event("ec2");
349 if (!ec2) {
350 diag("Failed to create simple event EC2");
351 goto error;
352 }
353 ret = bt_stream_class_add_event_class(sc1, ec2);
354 if (ret) {
355 diag("Failed to add EC1 to SC1");
356 goto error;
357 }
358
359 ret_stream = bt_event_class_get_stream_class(ec1);
360 ok(ret_stream == sc1, "Get parent stream SC1 from EC1");
361 BT_PUT(ret_stream);
362
363 ret_stream = bt_event_class_get_stream_class(ec2);
364 ok(ret_stream == sc1, "Get parent stream SC1 from EC2");
365 end:
366 BT_PUT(ret_stream);
367 BT_PUT(ec1);
368 BT_PUT(ec2);
369 return sc1;
370 error:
371 BT_PUT(sc1);
372 goto end;
373 }
374
375 static struct bt_stream_class *create_sc2(void)
376 {
377 int ret;
378 struct bt_event_class *ec3 = NULL;
379 struct bt_stream_class *sc2 = NULL, *ret_stream = NULL;
380
381 sc2 = bt_stream_class_create("sc2");
382 if (!sc2) {
383 diag("Failed to create Stream Class");
384 goto error;
385 }
386
387 set_stream_class_field_types(sc2);
388 ec3 = create_simple_event("ec3");
389 if (!ec3) {
390 diag("Failed to create simple event EC3");
391 goto error;
392 }
393 ret = bt_stream_class_add_event_class(sc2, ec3);
394 if (ret) {
395 diag("Failed to add EC3 to SC2");
396 goto error;
397 }
398
399 ret_stream = bt_event_class_get_stream_class(ec3);
400 ok(ret_stream == sc2, "Get parent stream SC2 from EC3");
401 end:
402 BT_PUT(ret_stream);
403 BT_PUT(ec3);
404 return sc2;
405 error:
406 BT_PUT(sc2);
407 goto end;
408 }
409
410 static void set_trace_packet_header(struct bt_trace *trace)
411 {
412 struct bt_field_type *packet_header_type;
413 struct bt_field_type *ft;
414 int ret;
415
416 packet_header_type = bt_field_type_structure_create();
417 assert(packet_header_type);
418 ft = bt_field_type_integer_create(32);
419 assert(ft);
420 ret = bt_field_type_structure_add_field(packet_header_type,
421 ft, "stream_id");
422 assert(ret == 0);
423 bt_put(ft);
424
425 ret = bt_trace_set_packet_header_field_type(trace,
426 packet_header_type);
427 assert(ret == 0);
428
429 bt_put(packet_header_type);
430 }
431
432 static struct bt_trace *create_tc1(void)
433 {
434 int ret;
435 struct bt_trace *tc1 = NULL;
436 struct bt_stream_class *sc1 = NULL, *sc2 = NULL;
437
438 tc1 = bt_trace_create();
439 if (!tc1) {
440 diag("bt_trace_create returned NULL");
441 goto error;
442 }
443
444 set_trace_packet_header(tc1);
445 sc1 = create_sc1();
446 ok(sc1, "Create SC1");
447 if (!sc1) {
448 goto error;
449 }
450 ret = bt_trace_add_stream_class(tc1, sc1);
451 ok(!ret, "Add SC1 to TC1");
452 if (ret) {
453 goto error;
454 }
455
456 sc2 = create_sc2();
457 ok(sc2, "Create SC2");
458 if (!sc2) {
459 goto error;
460 }
461 ret = bt_trace_add_stream_class(tc1, sc2);
462 ok(!ret, "Add SC2 to TC1");
463 if (ret) {
464 goto error;
465 }
466 end:
467 BT_PUT(sc1);
468 BT_PUT(sc2);
469 return tc1;
470 error:
471 BT_PUT(tc1);
472 goto end;
473 }
474
475 static void init_weak_refs(struct bt_trace *tc,
476 struct bt_trace **tc1,
477 struct bt_stream_class **sc1,
478 struct bt_stream_class **sc2,
479 struct bt_event_class **ec1,
480 struct bt_event_class **ec2,
481 struct bt_event_class **ec3)
482 {
483 *tc1 = tc;
484 *sc1 = bt_trace_get_stream_class_by_index(tc, 0);
485 *sc2 = bt_trace_get_stream_class_by_index(tc, 1);
486 *ec1 = bt_stream_class_get_event_class_by_index(*sc1, 0);
487 *ec2 = bt_stream_class_get_event_class_by_index(*sc1, 1);
488 *ec3 = bt_stream_class_get_event_class_by_index(*sc2, 0);
489 bt_put(*sc1);
490 bt_put(*sc2);
491 bt_put(*ec1);
492 bt_put(*ec2);
493 bt_put(*ec3);
494 }
495
496 static void test_example_scenario(void)
497 {
498 /**
499 * Weak pointers to CTF-IR objects are to be used very carefully.
500 * This is NOT a good practice and is strongly discouraged; this
501 * is only done to facilitate the validation of expected reference
502 * counts without affecting them by taking "real" references to the
503 * objects.
504 */
505 struct bt_trace *tc1 = NULL, *weak_tc1 = NULL;
506 struct bt_stream_class *weak_sc1 = NULL, *weak_sc2 = NULL;
507 struct bt_event_class *weak_ec1 = NULL, *weak_ec2 = NULL,
508 *weak_ec3 = NULL;
509 struct user user_a = { 0 }, user_b = { 0 }, user_c = { 0 };
510
511 /* The only reference which exists at this point is on TC1. */
512 tc1 = create_tc1();
513 ok(tc1, "Initialize trace");
514 if (!tc1) {
515 return;
516 }
517
518 init_weak_refs(tc1, &weak_tc1, &weak_sc1, &weak_sc2, &weak_ec1,
519 &weak_ec2, &weak_ec3);
520
521 ok(bt_object_get_ref_count(weak_sc1) == 0,
522 "Initial SC1 reference count is 0");
523 ok(bt_object_get_ref_count(weak_sc2) == 0,
524 "Initial SC2 reference count is 0");
525 ok(bt_object_get_ref_count(weak_ec1) == 0,
526 "Initial EC1 reference count is 0");
527 ok(bt_object_get_ref_count(weak_ec2) == 0,
528 "Initial EC2 reference count is 0");
529 ok(bt_object_get_ref_count(weak_ec3) == 0,
530 "Initial EC3 reference count is 0");
531
532 /* User A has ownership of the trace. */
533 BT_MOVE(user_a.tc, tc1);
534 ok(bt_object_get_ref_count(user_a.tc) == 1,
535 "TC1 reference count is 1");
536
537 /* User A acquires a reference to SC2 from TC1. */
538 user_a.sc = bt_trace_get_stream_class_by_index(user_a.tc, 1);
539 ok(user_a.sc, "User A acquires SC2 from TC1");
540 ok(bt_object_get_ref_count(weak_tc1) == 2,
541 "TC1 reference count is 2");
542 ok(bt_object_get_ref_count(weak_sc2) == 1,
543 "SC2 reference count is 1");
544
545 /* User A acquires a reference to EC3 from SC2. */
546 user_a.ec = bt_stream_class_get_event_class_by_index(user_a.sc, 0);
547 ok(user_a.ec, "User A acquires EC3 from SC2");
548 ok(bt_object_get_ref_count(weak_tc1) == 2,
549 "TC1 reference count is 2");
550 ok(bt_object_get_ref_count(weak_sc2) == 2,
551 "SC2 reference count is 2");
552 ok(bt_object_get_ref_count(weak_ec3) == 1,
553 "EC3 reference count is 1");
554
555 /* User A releases its reference to SC2. */
556 diag("User A releases SC2");
557 BT_PUT(user_a.sc);
558 /*
559 * We keep the pointer to SC2 around to validate its reference
560 * count.
561 */
562 ok(bt_object_get_ref_count(weak_tc1) == 2,
563 "TC1 reference count is 2");
564 ok(bt_object_get_ref_count(weak_sc2) == 1,
565 "SC2 reference count is 1");
566 ok(bt_object_get_ref_count(weak_ec3) == 1,
567 "EC3 reference count is 1");
568
569 /* User A releases its reference to TC1. */
570 diag("User A releases TC1");
571 BT_PUT(user_a.tc);
572 /*
573 * We keep the pointer to TC1 around to validate its reference
574 * count.
575 */
576 ok(bt_object_get_ref_count(weak_tc1) == 1,
577 "TC1 reference count is 1");
578 ok(bt_object_get_ref_count(weak_sc2) == 1,
579 "SC2 reference count is 1");
580 ok(bt_object_get_ref_count(weak_ec3) == 1,
581 "EC3 reference count is 1");
582
583 /* User B acquires a reference to SC1. */
584 diag("User B acquires a reference to SC1");
585 user_b.sc = bt_get(weak_sc1);
586 ok(bt_object_get_ref_count(weak_tc1) == 2,
587 "TC1 reference count is 2");
588 ok(bt_object_get_ref_count(weak_sc1) == 1,
589 "SC1 reference count is 1");
590
591 /* User C acquires a reference to EC1. */
592 diag("User C acquires a reference to EC1");
593 user_c.ec = bt_stream_class_get_event_class_by_index(user_b.sc, 0);
594 ok(bt_object_get_ref_count(weak_ec1) == 1,
595 "EC1 reference count is 1");
596 ok(bt_object_get_ref_count(weak_sc1) == 2,
597 "SC1 reference count is 2");
598
599 /* User A releases its reference on EC3. */
600 diag("User A releases its reference on EC3");
601 BT_PUT(user_a.ec);
602 ok(bt_object_get_ref_count(weak_ec3) == 0,
603 "EC3 reference count is 1");
604 ok(bt_object_get_ref_count(weak_sc2) == 0,
605 "SC2 reference count is 0");
606 ok(bt_object_get_ref_count(weak_tc1) == 1,
607 "TC1 reference count is 1");
608
609 /* User B releases its reference on SC1. */
610 diag("User B releases its reference on SC1");
611 BT_PUT(user_b.sc);
612 ok(bt_object_get_ref_count(weak_sc1) == 1,
613 "SC1 reference count is 1");
614
615 /*
616 * User C is the sole owner of an object and is keeping the whole
617 * trace hierarchy "alive" by holding a reference to EC1.
618 */
619 ok(bt_object_get_ref_count(weak_tc1) == 1,
620 "TC1 reference count is 1");
621 ok(bt_object_get_ref_count(weak_sc1) == 1,
622 "SC1 reference count is 1");
623 ok(bt_object_get_ref_count(weak_sc2) == 0,
624 "SC2 reference count is 0");
625 ok(bt_object_get_ref_count(weak_ec1) == 1,
626 "EC1 reference count is 1");
627 ok(bt_object_get_ref_count(weak_ec2) == 0,
628 "EC2 reference count is 0");
629 ok(bt_object_get_ref_count(weak_ec3) == 0,
630 "EC3 reference count is 0");
631
632 /* Reclaim last reference held by User C. */
633 BT_PUT(user_c.ec);
634 }
635
636 static void create_writer_user_full(struct writer_user *user)
637 {
638 gchar *trace_path;
639 struct bt_ctf_field_type *ft;
640 struct bt_ctf_field *field;
641 struct bt_ctf_clock *clock;
642 int ret;
643
644 trace_path = g_build_filename(g_get_tmp_dir(), "ctfwriter_XXXXXX", NULL);
645 if (!bt_mkdtemp(trace_path)) {
646 perror("# perror");
647 }
648
649 user->writer = bt_ctf_writer_create(trace_path);
650 assert(user->writer);
651 ret = bt_ctf_writer_set_byte_order(user->writer,
652 BT_CTF_BYTE_ORDER_LITTLE_ENDIAN);
653 assert(ret == 0);
654 user->tc = bt_ctf_writer_get_trace(user->writer);
655 assert(user->tc);
656 user->sc = bt_ctf_stream_class_create("sc");
657 assert(user->sc);
658 clock = bt_ctf_clock_create("the_clock");
659 assert(clock);
660 ret = bt_ctf_writer_add_clock(user->writer, clock);
661 assert(!ret);
662 ret = bt_ctf_stream_class_set_clock(user->sc, clock);
663 assert(!ret);
664 BT_PUT(clock);
665 user->stream = bt_ctf_writer_create_stream(user->writer, user->sc);
666 assert(user->stream);
667 user->ec = bt_ctf_event_class_create("ec");
668 assert(user->ec);
669 ft = create_writer_integer_struct();
670 assert(ft);
671 ret = bt_ctf_event_class_set_payload_field_type(user->ec, ft);
672 BT_PUT(ft);
673 assert(!ret);
674 ret = bt_ctf_stream_class_add_event_class(user->sc, user->ec);
675 assert(!ret);
676 user->event = bt_ctf_event_create(user->ec);
677 assert(user->event);
678 field = bt_ctf_event_get_payload(user->event, "payload_8");
679 assert(field);
680 ret = bt_ctf_field_integer_unsigned_set_value(field, 10);
681 assert(!ret);
682 BT_PUT(field);
683 field = bt_ctf_event_get_payload(user->event, "payload_16");
684 assert(field);
685 ret = bt_ctf_field_integer_unsigned_set_value(field, 20);
686 assert(!ret);
687 BT_PUT(field);
688 field = bt_ctf_event_get_payload(user->event, "payload_32");
689 assert(field);
690 ret = bt_ctf_field_integer_unsigned_set_value(field, 30);
691 assert(!ret);
692 BT_PUT(field);
693 ret = bt_ctf_stream_append_event(user->stream, user->event);
694 assert(!ret);
695 recursive_rmdir(trace_path);
696 g_free(trace_path);
697 }
698
699 static void test_put_order_swap(size_t *array, size_t a, size_t b)
700 {
701 size_t temp = array[a];
702
703 array[a] = array[b];
704 array[b] = temp;
705 }
706
707 static void test_put_order_put_objects(size_t *array, size_t size)
708 {
709 size_t i;
710 struct writer_user user = { 0 };
711 void **objects = (void *) &user;
712
713 create_writer_user_full(&user);
714 printf("# ");
715
716 for (i = 0; i < size; ++i) {
717 void *obj = objects[array[i]];
718
719 printf("%s", writer_user_names[array[i]]);
720 BT_PUT(obj);
721
722 if (i < size - 1) {
723 printf(" -> ");
724 }
725 }
726
727 puts("");
728 }
729
730 static void test_put_order_permute(size_t *array, int k, size_t size)
731 {
732 if (k == 0) {
733 test_put_order_put_objects(array, size);
734 } else {
735 int i;
736
737 for (i = k - 1; i >= 0; i--) {
738 size_t next_k = k - 1;
739
740 test_put_order_swap(array, i, next_k);
741 test_put_order_permute(array, next_k, size);
742 test_put_order_swap(array, i, next_k);
743 }
744 }
745 }
746
747 static void test_put_order(void)
748 {
749 size_t i;
750 size_t array[WRITER_USER_NR_ELEMENTS];
751
752 /* Initialize array of indexes */
753 for (i = 0; i < WRITER_USER_NR_ELEMENTS; ++i) {
754 array[i] = i;
755 }
756
757 test_put_order_permute(array, WRITER_USER_NR_ELEMENTS,
758 WRITER_USER_NR_ELEMENTS);
759 }
760
761 /**
762 * The objective of this test is to implement and expand upon the scenario
763 * described in the reference counting documentation and ensure that any node of
764 * the Trace, Stream Class, Event Class, Stream and Event hiearchy keeps all
765 * other "alive" and reachable.
766 *
767 * External tools (e.g. valgrind) should be used to confirm that this
768 * known-good test does not leak memory.
769 */
770 int main(int argc, char **argv)
771 {
772 /* Initialize tap harness before any tests */
773 plan_tests(NR_TESTS);
774
775 test_example_scenario();
776 test_put_order();
777
778 return exit_status();
779 }
This page took 0.055844 seconds and 4 git commands to generate.