X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=tests%2Flib%2Ftest_ctf_ir_ref.c;h=5d0816b136675592efb6888a7cdd45d5e9123258;hb=55eb4a0471fded5edce486a0596dffb488124da7;hp=eecaad880ad0753fe67003ae8e150ec65e28e3cc;hpb=272df73edf74c3d8d6cbbf6450258fdbc9fbad36;p=babeltrace.git diff --git a/tests/lib/test_ctf_ir_ref.c b/tests/lib/test_ctf_ir_ref.c index eecaad88..5d0816b1 100644 --- a/tests/lib/test_ctf_ir_ref.c +++ b/tests/lib/test_ctf_ir_ref.c @@ -20,22 +20,42 @@ */ #include "tap/tap.h" +#include +#include +#include #include -#include +#include #include +#include #include #include #include +#include #include +#include "common.h" #define NR_TESTS 41 struct user { + struct bt_ctf_writer *writer; struct bt_ctf_trace *tc; struct bt_ctf_stream_class *sc; struct bt_ctf_event_class *ec; + struct bt_ctf_stream *stream; + struct bt_ctf_event *event; }; +const char *user_names[] = { + "writer", + "trace", + "stream class", + "event class", + "stream", + "event", +}; + +static const size_t USER_NR_ELEMENTS = sizeof(struct user) / sizeof(void *); + /** * Returns a structure containing the following fields: * - uint8_t payload_8; @@ -108,7 +128,7 @@ static struct bt_ctf_event_class *create_simple_event(const char *name) struct bt_ctf_event_class *event = NULL; struct bt_ctf_field_type *payload = NULL; - assert(name); + assert(name); event = bt_ctf_event_class_create(name); if (!event) { diag("Failed to create simple event"); @@ -150,27 +170,27 @@ static struct bt_ctf_event_class *create_complex_event(const char *name) struct bt_ctf_event_class *event = NULL; struct bt_ctf_field_type *inner = NULL, *outer = NULL; - assert(name); + assert(name); event = bt_ctf_event_class_create(name); if (!event) { diag("Failed to create complex event"); goto error; } - outer = create_integer_struct(); + outer = create_integer_struct(); if (!outer) { diag("Failed to initialize integer structure"); goto error; } - inner = create_integer_struct(); + inner = create_integer_struct(); if (!inner) { diag("Failed to initialize integer structure"); goto error; } ret = bt_ctf_field_type_structure_add_field(outer, inner, - "payload_struct"); + "payload_struct"); if (ret) { diag("Failed to add inner structure to outer structure"); goto error; @@ -237,7 +257,7 @@ end: return sc1; error: BT_PUT(sc1); - goto end; + goto end; } static struct bt_ctf_stream_class *create_sc2(void) @@ -271,7 +291,7 @@ end: return sc2; error: BT_PUT(sc2); - goto end; + goto end; } static struct bt_ctf_trace *create_tc1(void) @@ -280,7 +300,7 @@ static struct bt_ctf_trace *create_tc1(void) struct bt_ctf_trace *tc1 = NULL; struct bt_ctf_stream_class *sc1 = NULL, *sc2 = NULL; - tc1 = bt_ctf_trace_create(); + tc1 = bt_ctf_trace_create(); if (!tc1) { diag("bt_ctf_trace_create returned NULL"); goto error; @@ -313,7 +333,7 @@ end: return tc1; error: BT_PUT(tc1); - goto end; + goto end; } static void init_weak_refs(struct bt_ctf_trace *tc, @@ -337,16 +357,7 @@ static void init_weak_refs(struct bt_ctf_trace *tc, bt_put(*ec3); } -/** - * The objective of this test is to implement and expand upon the scenario - * described in the reference counting documentation and ensure that any node of - * the Trace, Stream Class, Event Class, Stream and Event hiearchy keeps all - * other "alive" and reachable. - * - * External tools (e.g. valgrind) should be used to confirm that this - * known-good test does not leak memory. - */ -int main(int argc, char **argv) +static void test_example_scenario(void) { /** * Weak pointers to CTF-IR objects are to be used very carefully. @@ -361,14 +372,11 @@ int main(int argc, char **argv) *weak_ec3 = NULL; struct user user_a = { 0 }, user_b = { 0 }, user_c = { 0 }; - /* Initialize tap harness before any tests */ - plan_tests(NR_TESTS); - /* The only reference which exists at this point is on TC1. */ tc1 = create_tc1(); - ok(tc1, "Initialize trace"); + ok(tc1, "Initialize trace"); if (!tc1) { - goto end; + return; } init_weak_refs(tc1, &weak_tc1, &weak_sc1, &weak_sc2, &weak_ec1, @@ -424,7 +432,7 @@ int main(int argc, char **argv) /* User A releases its reference to TC1. */ diag("User A releases TC1"); - BT_PUT(user_a.tc); + BT_PUT(user_a.tc); /* * We keep the pointer to TC1 around to validate its reference * count. @@ -487,6 +495,143 @@ int main(int argc, char **argv) /* Reclaim last reference held by User C. */ BT_PUT(user_c.ec); -end: +} + +static void create_user_full(struct user *user) +{ + char trace_path[] = "/tmp/ctfwriter_XXXXXX"; + struct bt_ctf_field_type *ft; + struct bt_ctf_field *field; + struct bt_ctf_clock *clock; + int ret; + + if (!bt_mkdtemp(trace_path)) { + perror("# perror"); + } + + user->writer = bt_ctf_writer_create(trace_path); + assert(user->writer); + user->tc = bt_ctf_writer_get_trace(user->writer); + assert(user->tc); + user->sc = bt_ctf_stream_class_create("sc"); + assert(user->sc); + clock = bt_ctf_clock_create("the_clock"); + assert(clock); + ret = bt_ctf_stream_class_set_clock(user->sc, clock); + assert(!ret); + ret = bt_ctf_clock_set_value(clock, 23); + assert(!ret); + BT_PUT(clock); + user->stream = bt_ctf_writer_create_stream(user->writer, user->sc); + assert(user->stream); + user->ec = bt_ctf_event_class_create("ec"); + assert(user->ec); + ft = create_integer_struct(); + assert(ft); + ret = bt_ctf_event_class_set_payload_type(user->ec, ft); + BT_PUT(ft); + assert(!ret); + ret = bt_ctf_stream_class_add_event_class(user->sc, user->ec); + assert(!ret); + user->event = bt_ctf_event_create(user->ec); + assert(user->event); + field = bt_ctf_event_get_payload(user->event, "payload_8"); + assert(field); + ret = bt_ctf_field_unsigned_integer_set_value(field, 10); + assert(!ret); + BT_PUT(field); + field = bt_ctf_event_get_payload(user->event, "payload_16"); + assert(field); + ret = bt_ctf_field_unsigned_integer_set_value(field, 20); + assert(!ret); + BT_PUT(field); + field = bt_ctf_event_get_payload(user->event, "payload_32"); + assert(field); + ret = bt_ctf_field_unsigned_integer_set_value(field, 30); + assert(!ret); + BT_PUT(field); + ret = bt_ctf_stream_append_event(user->stream, user->event); + assert(!ret); + recursive_rmdir(trace_path); +} + +static void test_put_order_swap(size_t *array, size_t a, size_t b) +{ + size_t temp = array[a]; + + array[a] = array[b]; + array[b] = temp; +} + +static void test_put_order_put_objects(size_t *array, size_t size) +{ + size_t i; + struct user user = { 0 }; + void **objects = (void *) &user; + + create_user_full(&user); + printf("# "); + + for (i = 0; i < size; ++i) { + void *obj = objects[array[i]]; + + printf("%s", user_names[array[i]]); + BT_PUT(obj); + + if (i < size - 1) { + printf(" -> "); + } + } + + puts(""); +} + +static void test_put_order_permute(size_t *array, int k, size_t size) +{ + if (k == 0) { + test_put_order_put_objects(array, size); + } else { + int i; + + for (i = k - 1; i >= 0; i--) { + size_t next_k = k - 1; + + test_put_order_swap(array, i, next_k); + test_put_order_permute(array, next_k, size); + test_put_order_swap(array, i, next_k); + } + } +} + +static void test_put_order(void) +{ + size_t i; + size_t array[USER_NR_ELEMENTS]; + + /* Initialize array of indexes */ + for (i = 0; i < USER_NR_ELEMENTS; ++i) { + array[i] = i; + } + + test_put_order_permute(array, USER_NR_ELEMENTS, USER_NR_ELEMENTS); +} + +/** + * The objective of this test is to implement and expand upon the scenario + * described in the reference counting documentation and ensure that any node of + * the Trace, Stream Class, Event Class, Stream and Event hiearchy keeps all + * other "alive" and reachable. + * + * External tools (e.g. valgrind) should be used to confirm that this + * known-good test does not leak memory. + */ +int main(int argc, char **argv) +{ + /* Initialize tap harness before any tests */ + plan_tests(NR_TESTS); + + test_example_scenario(); + test_put_order(); + return exit_status(); }