assert-pre-internal.h: add BT_ASSERT_PRE_VALID_INDEX()
[babeltrace.git] / tests / lib / test_ctf_ir_ref.c
CommitLineData
c9b3f44b
JG
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"
6271743c 23#include <babeltrace/ctf-writer/clock.h>
3dca2276
PP
24#include <babeltrace/ctf-writer/event.h>
25#include <babeltrace/ctf-writer/fields.h>
6271743c 26#include <babeltrace/ctf-writer/stream-class.h>
3dca2276
PP
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>
c9b3f44b 31#include <babeltrace/ctf-ir/event.h>
272df73e 32#include <babeltrace/ctf-ir/event-class.h>
3dca2276
PP
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>
c9b3f44b 37#include <babeltrace/object-internal.h>
3d9990ac 38#include <babeltrace/compat/stdlib-internal.h>
25583cd0 39#include <babeltrace/assert-internal.h>
851299b9 40#include "common.h"
c9b3f44b 41
8bbe269d
MJ
42#define NR_TESTS 41
43
c9b3f44b 44struct user {
50842bdc
PP
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;
c9b3f44b
JG
50};
51
3dca2276
PP
52struct 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
61const char *writer_user_names[] = {
6271743c
PP
62 "writer",
63 "trace",
64 "stream class",
65 "event class",
66 "stream",
67 "event",
68};
69
3dca2276
PP
70static const size_t WRITER_USER_NR_ELEMENTS =
71 sizeof(struct writer_user) / sizeof(void *);
6271743c 72
c9b3f44b
JG
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 */
50842bdc 79static struct bt_field_type *create_integer_struct(void)
c9b3f44b
JG
80{
81 int ret;
50842bdc
PP
82 struct bt_field_type *structure = NULL;
83 struct bt_field_type *ui8 = NULL, *ui16 = NULL, *ui32 = NULL;
c9b3f44b 84
50842bdc 85 structure = bt_field_type_structure_create();
c9b3f44b
JG
86 if (!structure) {
87 goto error;
88 }
89
50842bdc 90 ui8 = bt_field_type_integer_create(8);
c9b3f44b
JG
91 if (!ui8) {
92 diag("Failed to create uint8_t type");
93 goto error;
94 }
50842bdc 95 ret = bt_field_type_structure_add_field(structure, ui8,
c9b3f44b
JG
96 "payload_8");
97 if (ret) {
98 diag("Failed to add uint8_t to structure");
99 goto error;
100 }
50842bdc 101 ui16 = bt_field_type_integer_create(16);
c9b3f44b
JG
102 if (!ui16) {
103 diag("Failed to create uint16_t type");
104 goto error;
105 }
50842bdc 106 ret = bt_field_type_structure_add_field(structure, ui16,
c9b3f44b
JG
107 "payload_16");
108 if (ret) {
109 diag("Failed to add uint16_t to structure");
110 goto error;
111 }
50842bdc 112 ui32 = bt_field_type_integer_create(32);
c9b3f44b
JG
113 if (!ui32) {
114 diag("Failed to create uint32_t type");
115 goto error;
116 }
50842bdc 117 ret = bt_field_type_structure_add_field(structure, ui32,
c9b3f44b
JG
118 "payload_32");
119 if (ret) {
120 diag("Failed to add uint32_t to structure");
121 goto error;
122 }
123end:
124 BT_PUT(ui8);
125 BT_PUT(ui16);
126 BT_PUT(ui32);
127 return structure;
128error:
129 BT_PUT(structure);
130 goto end;
131}
132
3dca2276
PP
133static 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 }
177end:
178 BT_PUT(ui8);
179 BT_PUT(ui16);
180 BT_PUT(ui32);
181 return structure;
182error:
183 BT_PUT(structure);
184 goto end;
185}
186
c9b3f44b
JG
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 */
50842bdc 193static struct bt_event_class *create_simple_event(const char *name)
c9b3f44b
JG
194{
195 int ret;
50842bdc
PP
196 struct bt_event_class *event = NULL;
197 struct bt_field_type *payload = NULL;
c9b3f44b 198
25583cd0 199 BT_ASSERT(name);
50842bdc 200 event = bt_event_class_create(name);
c9b3f44b
JG
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
3dca2276 212 ret = bt_event_class_set_payload_field_type(event, payload);
c9b3f44b
JG
213 if (ret) {
214 diag("Failed to set simple event payload");
215 goto error;
216 }
217end:
218 BT_PUT(payload);
219 return event;
220error:
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 */
50842bdc 235static struct bt_event_class *create_complex_event(const char *name)
c9b3f44b
JG
236{
237 int ret;
50842bdc
PP
238 struct bt_event_class *event = NULL;
239 struct bt_field_type *inner = NULL, *outer = NULL;
c9b3f44b 240
25583cd0 241 BT_ASSERT(name);
50842bdc 242 event = bt_event_class_create(name);
c9b3f44b
JG
243 if (!event) {
244 diag("Failed to create complex event");
245 goto error;
246 }
247
27f4d205 248 outer = create_integer_struct();
c9b3f44b
JG
249 if (!outer) {
250 diag("Failed to initialize integer structure");
251 goto error;
252 }
253
27f4d205 254 inner = create_integer_struct();
c9b3f44b
JG
255 if (!inner) {
256 diag("Failed to initialize integer structure");
257 goto error;
258 }
259
50842bdc 260 ret = bt_field_type_structure_add_field(outer, inner,
27f4d205 261 "payload_struct");
c9b3f44b
JG
262 if (ret) {
263 diag("Failed to add inner structure to outer structure");
264 goto error;
265 }
266
3dca2276 267 ret = bt_event_class_set_payload_field_type(event, outer);
c9b3f44b
JG
268 if (ret) {
269 diag("Failed to set complex event payload");
270 goto error;
271 }
272end:
273 BT_PUT(inner);
274 BT_PUT(outer);
275 return event;
276error:
277 BT_PUT(event);
278 goto end;;
279}
280
da1cc671 281static void set_stream_class_field_types(
50842bdc 282 struct bt_stream_class *stream_class)
da1cc671 283{
50842bdc
PP
284 struct bt_field_type *packet_context_type;
285 struct bt_field_type *event_header_type;
286 struct bt_field_type *ft;
da1cc671
PP
287 int ret;
288
50842bdc 289 packet_context_type = bt_field_type_structure_create();
25583cd0 290 BT_ASSERT(packet_context_type);
50842bdc 291 ft = bt_field_type_integer_create(32);
25583cd0 292 BT_ASSERT(ft);
50842bdc 293 ret = bt_field_type_structure_add_field(packet_context_type,
da1cc671 294 ft, "packet_size");
25583cd0 295 BT_ASSERT(ret == 0);
da1cc671 296 bt_put(ft);
50842bdc 297 ft = bt_field_type_integer_create(32);
25583cd0 298 BT_ASSERT(ft);
50842bdc 299 ret = bt_field_type_structure_add_field(packet_context_type,
da1cc671 300 ft, "content_size");
25583cd0 301 BT_ASSERT(ret == 0);
da1cc671
PP
302 bt_put(ft);
303
50842bdc 304 event_header_type = bt_field_type_structure_create();
25583cd0 305 BT_ASSERT(event_header_type);
50842bdc 306 ft = bt_field_type_integer_create(32);
25583cd0 307 BT_ASSERT(ft);
50842bdc 308 ret = bt_field_type_structure_add_field(event_header_type,
da1cc671 309 ft, "id");
25583cd0 310 BT_ASSERT(ret == 0);
da1cc671
PP
311 bt_put(ft);
312
3dca2276 313 ret = bt_stream_class_set_packet_context_field_type(stream_class,
da1cc671 314 packet_context_type);
25583cd0 315 BT_ASSERT(ret == 0);
3dca2276 316 ret = bt_stream_class_set_event_header_field_type(stream_class,
da1cc671 317 event_header_type);
25583cd0 318 BT_ASSERT(ret == 0);
da1cc671
PP
319
320 bt_put(packet_context_type);
321 bt_put(event_header_type);
322}
323
50842bdc 324static struct bt_stream_class *create_sc1(void)
c9b3f44b
JG
325{
326 int ret;
50842bdc
PP
327 struct bt_event_class *ec1 = NULL, *ec2 = NULL;
328 struct bt_stream_class *sc1 = NULL, *ret_stream = NULL;
c9b3f44b 329
3dca2276 330 sc1 = bt_stream_class_create("sc1");
c9b3f44b
JG
331 if (!sc1) {
332 diag("Failed to create Stream Class");
333 goto error;
334 }
335
da1cc671 336 set_stream_class_field_types(sc1);
c9b3f44b
JG
337 ec1 = create_complex_event("ec1");
338 if (!ec1) {
339 diag("Failed to create complex event EC1");
340 goto error;
341 }
50842bdc 342 ret = bt_stream_class_add_event_class(sc1, ec1);
c9b3f44b
JG
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 }
50842bdc 353 ret = bt_stream_class_add_event_class(sc1, ec2);
c9b3f44b
JG
354 if (ret) {
355 diag("Failed to add EC1 to SC1");
356 goto error;
357 }
358
50842bdc 359 ret_stream = bt_event_class_get_stream_class(ec1);
c9b3f44b
JG
360 ok(ret_stream == sc1, "Get parent stream SC1 from EC1");
361 BT_PUT(ret_stream);
362
50842bdc 363 ret_stream = bt_event_class_get_stream_class(ec2);
c9b3f44b
JG
364 ok(ret_stream == sc1, "Get parent stream SC1 from EC2");
365end:
366 BT_PUT(ret_stream);
367 BT_PUT(ec1);
368 BT_PUT(ec2);
369 return sc1;
370error:
371 BT_PUT(sc1);
27f4d205 372 goto end;
c9b3f44b
JG
373}
374
50842bdc 375static struct bt_stream_class *create_sc2(void)
c9b3f44b
JG
376{
377 int ret;
50842bdc
PP
378 struct bt_event_class *ec3 = NULL;
379 struct bt_stream_class *sc2 = NULL, *ret_stream = NULL;
c9b3f44b 380
3dca2276 381 sc2 = bt_stream_class_create("sc2");
c9b3f44b
JG
382 if (!sc2) {
383 diag("Failed to create Stream Class");
384 goto error;
385 }
386
da1cc671 387 set_stream_class_field_types(sc2);
c9b3f44b
JG
388 ec3 = create_simple_event("ec3");
389 if (!ec3) {
390 diag("Failed to create simple event EC3");
391 goto error;
392 }
50842bdc 393 ret = bt_stream_class_add_event_class(sc2, ec3);
c9b3f44b
JG
394 if (ret) {
395 diag("Failed to add EC3 to SC2");
396 goto error;
397 }
398
50842bdc 399 ret_stream = bt_event_class_get_stream_class(ec3);
c9b3f44b
JG
400 ok(ret_stream == sc2, "Get parent stream SC2 from EC3");
401end:
402 BT_PUT(ret_stream);
403 BT_PUT(ec3);
404 return sc2;
405error:
406 BT_PUT(sc2);
27f4d205 407 goto end;
c9b3f44b
JG
408}
409
50842bdc 410static void set_trace_packet_header(struct bt_trace *trace)
da1cc671 411{
50842bdc
PP
412 struct bt_field_type *packet_header_type;
413 struct bt_field_type *ft;
da1cc671
PP
414 int ret;
415
50842bdc 416 packet_header_type = bt_field_type_structure_create();
25583cd0 417 BT_ASSERT(packet_header_type);
50842bdc 418 ft = bt_field_type_integer_create(32);
25583cd0 419 BT_ASSERT(ft);
50842bdc 420 ret = bt_field_type_structure_add_field(packet_header_type,
da1cc671 421 ft, "stream_id");
25583cd0 422 BT_ASSERT(ret == 0);
da1cc671
PP
423 bt_put(ft);
424
3dca2276 425 ret = bt_trace_set_packet_header_field_type(trace,
da1cc671 426 packet_header_type);
25583cd0 427 BT_ASSERT(ret == 0);
da1cc671
PP
428
429 bt_put(packet_header_type);
430}
431
50842bdc 432static struct bt_trace *create_tc1(void)
c9b3f44b
JG
433{
434 int ret;
50842bdc
PP
435 struct bt_trace *tc1 = NULL;
436 struct bt_stream_class *sc1 = NULL, *sc2 = NULL;
c9b3f44b 437
50842bdc 438 tc1 = bt_trace_create();
c9b3f44b 439 if (!tc1) {
50842bdc 440 diag("bt_trace_create returned NULL");
c9b3f44b
JG
441 goto error;
442 }
443
da1cc671 444 set_trace_packet_header(tc1);
c9b3f44b
JG
445 sc1 = create_sc1();
446 ok(sc1, "Create SC1");
447 if (!sc1) {
448 goto error;
449 }
50842bdc 450 ret = bt_trace_add_stream_class(tc1, sc1);
c9b3f44b
JG
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 }
50842bdc 461 ret = bt_trace_add_stream_class(tc1, sc2);
c9b3f44b
JG
462 ok(!ret, "Add SC2 to TC1");
463 if (ret) {
464 goto error;
465 }
466end:
467 BT_PUT(sc1);
468 BT_PUT(sc2);
469 return tc1;
470error:
471 BT_PUT(tc1);
27f4d205 472 goto end;
c9b3f44b
JG
473}
474
50842bdc
PP
475static 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)
c9b3f44b
JG
482{
483 *tc1 = tc;
50842bdc
PP
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);
c9b3f44b
JG
489 bt_put(*sc1);
490 bt_put(*sc2);
491 bt_put(*ec1);
492 bt_put(*ec2);
493 bt_put(*ec3);
494}
495
6271743c 496static void test_example_scenario(void)
c9b3f44b
JG
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 */
50842bdc
PP
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,
c9b3f44b
JG
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();
27f4d205 513 ok(tc1, "Initialize trace");
c9b3f44b 514 if (!tc1) {
6271743c 515 return;
c9b3f44b
JG
516 }
517
518 init_weak_refs(tc1, &weak_tc1, &weak_sc1, &weak_sc2, &weak_ec1,
519 &weak_ec2, &weak_ec3);
c9b3f44b 520
3fea54f6 521 ok(bt_object_get_ref_count((void *) weak_sc1) == 0,
c9b3f44b 522 "Initial SC1 reference count is 0");
3fea54f6 523 ok(bt_object_get_ref_count((void *) weak_sc2) == 0,
c9b3f44b 524 "Initial SC2 reference count is 0");
3fea54f6 525 ok(bt_object_get_ref_count((void *) weak_ec1) == 0,
c9b3f44b 526 "Initial EC1 reference count is 0");
3fea54f6 527 ok(bt_object_get_ref_count((void *) weak_ec2) == 0,
c9b3f44b 528 "Initial EC2 reference count is 0");
3fea54f6 529 ok(bt_object_get_ref_count((void *) weak_ec3) == 0,
c9b3f44b
JG
530 "Initial EC3 reference count is 0");
531
532 /* User A has ownership of the trace. */
533 BT_MOVE(user_a.tc, tc1);
3fea54f6 534 ok(bt_object_get_ref_count((void *) user_a.tc) == 1,
c9b3f44b
JG
535 "TC1 reference count is 1");
536
537 /* User A acquires a reference to SC2 from TC1. */
50842bdc 538 user_a.sc = bt_trace_get_stream_class_by_index(user_a.tc, 1);
c9b3f44b 539 ok(user_a.sc, "User A acquires SC2 from TC1");
3fea54f6 540 ok(bt_object_get_ref_count((void *) weak_tc1) == 2,
c9b3f44b 541 "TC1 reference count is 2");
3fea54f6 542 ok(bt_object_get_ref_count((void *) weak_sc2) == 1,
c9b3f44b
JG
543 "SC2 reference count is 1");
544
545 /* User A acquires a reference to EC3 from SC2. */
50842bdc 546 user_a.ec = bt_stream_class_get_event_class_by_index(user_a.sc, 0);
c9b3f44b 547 ok(user_a.ec, "User A acquires EC3 from SC2");
3fea54f6 548 ok(bt_object_get_ref_count((void *) weak_tc1) == 2,
c9b3f44b 549 "TC1 reference count is 2");
3fea54f6 550 ok(bt_object_get_ref_count((void *) weak_sc2) == 2,
c9b3f44b 551 "SC2 reference count is 2");
3fea54f6 552 ok(bt_object_get_ref_count((void *) weak_ec3) == 1,
c9b3f44b
JG
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 */
3fea54f6 562 ok(bt_object_get_ref_count((void *) weak_tc1) == 2,
c9b3f44b 563 "TC1 reference count is 2");
3fea54f6 564 ok(bt_object_get_ref_count((void *) weak_sc2) == 1,
c9b3f44b 565 "SC2 reference count is 1");
3fea54f6 566 ok(bt_object_get_ref_count((void *) weak_ec3) == 1,
c9b3f44b
JG
567 "EC3 reference count is 1");
568
569 /* User A releases its reference to TC1. */
570 diag("User A releases TC1");
27f4d205 571 BT_PUT(user_a.tc);
c9b3f44b
JG
572 /*
573 * We keep the pointer to TC1 around to validate its reference
574 * count.
575 */
3fea54f6 576 ok(bt_object_get_ref_count((void *) weak_tc1) == 1,
c9b3f44b 577 "TC1 reference count is 1");
3fea54f6 578 ok(bt_object_get_ref_count((void *) weak_sc2) == 1,
c9b3f44b 579 "SC2 reference count is 1");
3fea54f6 580 ok(bt_object_get_ref_count((void *) weak_ec3) == 1,
c9b3f44b
JG
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);
3fea54f6 586 ok(bt_object_get_ref_count((void *) weak_tc1) == 2,
c9b3f44b 587 "TC1 reference count is 2");
3fea54f6 588 ok(bt_object_get_ref_count((void *) weak_sc1) == 1,
c9b3f44b
JG
589 "SC1 reference count is 1");
590
591 /* User C acquires a reference to EC1. */
592 diag("User C acquires a reference to EC1");
50842bdc 593 user_c.ec = bt_stream_class_get_event_class_by_index(user_b.sc, 0);
3fea54f6 594 ok(bt_object_get_ref_count((void *) weak_ec1) == 1,
c9b3f44b 595 "EC1 reference count is 1");
3fea54f6 596 ok(bt_object_get_ref_count((void *) weak_sc1) == 2,
c9b3f44b
JG
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);
3fea54f6 602 ok(bt_object_get_ref_count((void *) weak_ec3) == 0,
c9b3f44b 603 "EC3 reference count is 1");
3fea54f6 604 ok(bt_object_get_ref_count((void *) weak_sc2) == 0,
c9b3f44b 605 "SC2 reference count is 0");
3fea54f6 606 ok(bt_object_get_ref_count((void *) weak_tc1) == 1,
c9b3f44b
JG
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);
3fea54f6 612 ok(bt_object_get_ref_count((void *) weak_sc1) == 1,
c9b3f44b
JG
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 */
3fea54f6 619 ok(bt_object_get_ref_count((void *) weak_tc1) == 1,
c9b3f44b 620 "TC1 reference count is 1");
3fea54f6 621 ok(bt_object_get_ref_count((void *) weak_sc1) == 1,
c9b3f44b 622 "SC1 reference count is 1");
3fea54f6 623 ok(bt_object_get_ref_count((void *) weak_sc2) == 0,
c9b3f44b 624 "SC2 reference count is 0");
3fea54f6 625 ok(bt_object_get_ref_count((void *) weak_ec1) == 1,
c9b3f44b 626 "EC1 reference count is 1");
3fea54f6 627 ok(bt_object_get_ref_count((void *) weak_ec2) == 0,
c9b3f44b 628 "EC2 reference count is 0");
3fea54f6 629 ok(bt_object_get_ref_count((void *) weak_ec3) == 0,
c9b3f44b
JG
630 "EC3 reference count is 0");
631
632 /* Reclaim last reference held by User C. */
633 BT_PUT(user_c.ec);
6271743c
PP
634}
635
3dca2276 636static void create_writer_user_full(struct writer_user *user)
6271743c 637{
32bd47d1 638 gchar *trace_path;
3dca2276
PP
639 struct bt_ctf_field_type *ft;
640 struct bt_ctf_field *field;
6271743c
PP
641 struct bt_ctf_clock *clock;
642 int ret;
643
32bd47d1 644 trace_path = g_build_filename(g_get_tmp_dir(), "ctfwriter_XXXXXX", NULL);
6271743c
PP
645 if (!bt_mkdtemp(trace_path)) {
646 perror("# perror");
647 }
648
649 user->writer = bt_ctf_writer_create(trace_path);
25583cd0 650 BT_ASSERT(user->writer);
dc3fffef 651 ret = bt_ctf_writer_set_byte_order(user->writer,
3dca2276 652 BT_CTF_BYTE_ORDER_LITTLE_ENDIAN);
25583cd0 653 BT_ASSERT(ret == 0);
6271743c 654 user->tc = bt_ctf_writer_get_trace(user->writer);
25583cd0 655 BT_ASSERT(user->tc);
3dca2276 656 user->sc = bt_ctf_stream_class_create("sc");
25583cd0 657 BT_ASSERT(user->sc);
6271743c 658 clock = bt_ctf_clock_create("the_clock");
25583cd0 659 BT_ASSERT(clock);
81582b6b 660 ret = bt_ctf_writer_add_clock(user->writer, clock);
25583cd0 661 BT_ASSERT(!ret);
3dca2276 662 ret = bt_ctf_stream_class_set_clock(user->sc, clock);
25583cd0 663 BT_ASSERT(!ret);
dc3fffef 664 BT_PUT(clock);
6271743c 665 user->stream = bt_ctf_writer_create_stream(user->writer, user->sc);
25583cd0 666 BT_ASSERT(user->stream);
3dca2276 667 user->ec = bt_ctf_event_class_create("ec");
25583cd0 668 BT_ASSERT(user->ec);
3dca2276 669 ft = create_writer_integer_struct();
25583cd0 670 BT_ASSERT(ft);
3dca2276 671 ret = bt_ctf_event_class_set_payload_field_type(user->ec, ft);
6271743c 672 BT_PUT(ft);
25583cd0 673 BT_ASSERT(!ret);
3dca2276 674 ret = bt_ctf_stream_class_add_event_class(user->sc, user->ec);
25583cd0 675 BT_ASSERT(!ret);
3dca2276 676 user->event = bt_ctf_event_create(user->ec);
25583cd0 677 BT_ASSERT(user->event);
3dca2276 678 field = bt_ctf_event_get_payload(user->event, "payload_8");
25583cd0 679 BT_ASSERT(field);
3dca2276 680 ret = bt_ctf_field_integer_unsigned_set_value(field, 10);
25583cd0 681 BT_ASSERT(!ret);
6271743c 682 BT_PUT(field);
3dca2276 683 field = bt_ctf_event_get_payload(user->event, "payload_16");
25583cd0 684 BT_ASSERT(field);
3dca2276 685 ret = bt_ctf_field_integer_unsigned_set_value(field, 20);
25583cd0 686 BT_ASSERT(!ret);
6271743c 687 BT_PUT(field);
3dca2276 688 field = bt_ctf_event_get_payload(user->event, "payload_32");
25583cd0 689 BT_ASSERT(field);
3dca2276 690 ret = bt_ctf_field_integer_unsigned_set_value(field, 30);
25583cd0 691 BT_ASSERT(!ret);
6271743c 692 BT_PUT(field);
3dca2276 693 ret = bt_ctf_stream_append_event(user->stream, user->event);
25583cd0 694 BT_ASSERT(!ret);
851299b9 695 recursive_rmdir(trace_path);
32bd47d1 696 g_free(trace_path);
6271743c
PP
697}
698
699static 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
707static void test_put_order_put_objects(size_t *array, size_t size)
708{
709 size_t i;
3dca2276 710 struct writer_user user = { 0 };
6f2097e2 711 void **objects = (void *) &user;
6271743c 712
3dca2276 713 create_writer_user_full(&user);
6271743c
PP
714 printf("# ");
715
716 for (i = 0; i < size; ++i) {
6f2097e2 717 void *obj = objects[array[i]];
6271743c 718
3dca2276 719 printf("%s", writer_user_names[array[i]]);
6271743c
PP
720 BT_PUT(obj);
721
722 if (i < size - 1) {
723 printf(" -> ");
724 }
725 }
726
727 puts("");
728}
729
730static 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
747static void test_put_order(void)
748{
749 size_t i;
3dca2276 750 size_t array[WRITER_USER_NR_ELEMENTS];
6271743c
PP
751
752 /* Initialize array of indexes */
3dca2276 753 for (i = 0; i < WRITER_USER_NR_ELEMENTS; ++i) {
6271743c
PP
754 array[i] = i;
755 }
756
3dca2276
PP
757 test_put_order_permute(array, WRITER_USER_NR_ELEMENTS,
758 WRITER_USER_NR_ELEMENTS);
6271743c
PP
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 */
770int main(int argc, char **argv)
771{
27f4d205 772 /* Initialize tap harness before any tests */
6271743c
PP
773 plan_tests(NR_TESTS);
774
775 test_example_scenario();
776 test_put_order();
777
c9b3f44b
JG
778 return exit_status();
779}
This page took 0.075689 seconds and 4 git commands to generate.