Freeze event classes as they are added to a stream class
[babeltrace.git] / tests / lib / test_ctf_writer.c
index 42277026fcb9b2ac95e31dcdadd7305ae9ed0f22..3a56a558d44102ec94e6f90198ecfe3b20e5c73b 100644 (file)
@@ -3,7 +3,7 @@
  *
  * CTF Writer test
  *
- * Copyright 2013 - Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ * Copyright 2013 - 2015 - Jérémie Galarneau <jeremie.galarneau@efficios.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -26,6 +26,7 @@
 #include <babeltrace/ctf-writer/event.h>
 #include <babeltrace/ctf-writer/event-types.h>
 #include <babeltrace/ctf-writer/event-fields.h>
+#include <babeltrace/ctf-ir/stream-class.h>
 #include <babeltrace/ctf/events.h>
 #include <unistd.h>
 #include <stdlib.h>
@@ -34,7 +35,6 @@
 #include <babeltrace/compat/limits.h>
 #include <string.h>
 #include <assert.h>
-#include <unistd.h>
 #include <sys/wait.h>
 #include <fcntl.h>
 #include <dirent.h>
@@ -159,12 +159,12 @@ result:
 
                /* Output the metadata and parser output as diagnostic */
                while (getline(&line, &len, metadata_fp) > 0) {
-                       diag("%s", line);
+                       fprintf(stderr, "# %s", line);
                }
 
                rewind(parser_output_fp);
                while (getline(&line, &len, parser_output_fp) > 0) {
-                       diag("%s", line);
+                       fprintf(stderr, "# %s", line);
                }
 
                free(line);
@@ -290,6 +290,8 @@ void append_simple_event(struct bt_ctf_stream_class *stream_class,
        struct bt_ctf_field_type *enum_type;
        struct bt_ctf_field_type *enum_type_unsigned =
                bt_ctf_field_type_enumeration_create(uint_12_type);
+       struct bt_ctf_field_type *event_context_type =
+               bt_ctf_field_type_structure_create();
        struct bt_ctf_field_type *returned_type;
        struct bt_ctf_event *simple_event;
        struct bt_ctf_field *integer_field;
@@ -303,13 +305,16 @@ void append_simple_event(struct bt_ctf_stream_class *stream_class,
        const char *mapping_name_negative_test = "negative_value";
        const char *ret_char;
        double ret_double;
-       size_t ret_size_t;
        int64_t ret_range_start_int64_t, ret_range_end_int64_t;
        uint64_t ret_range_start_uint64_t, ret_range_end_uint64_t;
        struct bt_ctf_clock *ret_clock;
        struct bt_ctf_event_class *ret_event_class;
        struct bt_ctf_field *packet_context;
        struct bt_ctf_field *packet_context_field;
+       struct bt_ctf_field *stream_event_context;
+       struct bt_ctf_field *stream_event_context_field;
+       struct bt_ctf_field *event_context;
+       struct bt_ctf_field *event_context_field;
 
        ok(uint_12_type, "Create an unsigned integer type");
 
@@ -322,6 +327,7 @@ void append_simple_event(struct bt_ctf_stream_class *stream_class,
        ok(!bt_ctf_field_type_enumeration_get_container_type(NULL), "bt_ctf_field_type_enumeration_get_container_type handles NULL correctly");
        ok(!bt_ctf_field_type_enumeration_create(enum_type),
                "bt_ctf_field_enumeration_type_create rejects non-integer container field types");
+       bt_ctf_field_type_put(returned_type);
 
        bt_ctf_field_type_set_alignment(float_type, 32);
        ok(bt_ctf_field_type_get_alignment(NULL) < 0,
@@ -365,15 +371,11 @@ void append_simple_event(struct bt_ctf_stream_class *stream_class,
                -54, -55), "bt_ctf_field_type_enumeration_add_mapping rejects mapping where end < start");
        bt_ctf_field_type_enumeration_add_mapping(enum_type, "another entry", -42000, -13000);
 
-       ok(bt_ctf_field_type_enumeration_get_mapping_index_by_value(NULL, -42, &ret_size_t) < 0,
+       ok(bt_ctf_field_type_enumeration_get_mapping_index_by_value(NULL, -42) < 0,
                "bt_ctf_field_type_enumeration_get_mapping_index_by_value handles a NULL field type correctly");
-       ok(bt_ctf_field_type_enumeration_get_mapping_index_by_value(enum_type, -42, NULL) < 0,
-               "bt_ctf_field_type_enumeration_get_mapping_index_by_value handles a NULL index correctly");
-       ok(bt_ctf_field_type_enumeration_get_mapping_index_by_value(enum_type, 1000000, &ret_size_t) < 0,
+       ok(bt_ctf_field_type_enumeration_get_mapping_index_by_value(enum_type, 1000000) < 0,
                "bt_ctf_field_type_enumeration_get_mapping_index_by_value handles invalid values correctly");
-       ok(bt_ctf_field_type_enumeration_get_mapping_index_by_value(enum_type, -55, &ret_size_t) == 0,
-               "bt_ctf_field_type_enumeration_get_mapping_index_by_value handles invalid values correctly");
-       ok(ret_size_t == 1,
+       ok(bt_ctf_field_type_enumeration_get_mapping_index_by_value(enum_type, -55) == 1,
                "bt_ctf_field_type_enumeration_get_mapping_index_by_value returns the correct index");
 
        ok(bt_ctf_event_class_add_field(simple_event_class, enum_type,
@@ -452,8 +454,28 @@ void append_simple_event(struct bt_ctf_stream_class *stream_class,
                "integer_field");
        bt_ctf_event_class_add_field(simple_event_class, float_type,
                "float_field");
-       bt_ctf_stream_class_add_event_class(stream_class,
-               simple_event_class);
+
+       /* Set an event context type which will contain a single integer*/
+       ok(!bt_ctf_field_type_structure_add_field(event_context_type, uint_12_type,
+               "event_specific_context"),
+               "Add event specific context field");
+       ok(bt_ctf_event_class_get_context_type(NULL) == NULL,
+               "bt_ctf_event_class_get_context_type handles NULL correctly");
+       ok(bt_ctf_event_class_get_context_type(simple_event_class) == NULL,
+               "bt_ctf_event_class_get_context_type returns NULL when no event context type is set");
+
+       ok(bt_ctf_event_class_set_context_type(simple_event_class, NULL) < 0,
+               "bt_ctf_event_class_set_context_type handles a NULL context type correctly");
+       ok(bt_ctf_event_class_set_context_type(NULL, event_context_type) < 0,
+               "bt_ctf_event_class_set_context_type handles a NULL event class correctly");
+       ok(!bt_ctf_event_class_set_context_type(simple_event_class, event_context_type),
+               "Set an event class' context type successfully");
+       returned_type = bt_ctf_event_class_get_context_type(simple_event_class);
+       ok(returned_type == event_context_type,
+               "bt_ctf_event_class_get_context_type returns the appropriate type");
+       bt_ctf_field_type_put(returned_type);
+
+       bt_ctf_stream_class_add_event_class(stream_class, simple_event_class);
 
        ok(bt_ctf_stream_class_get_event_class_count(NULL) < 0,
                "bt_ctf_stream_class_get_event_class_count handles NULL correctly");
@@ -474,7 +496,7 @@ void append_simple_event(struct bt_ctf_stream_class *stream_class,
                "bt_ctf_stream_class_get_event_class_by_name handles a NULL event class name correctly");
        ok(bt_ctf_stream_class_get_event_class_by_name(stream_class, "some event name") == NULL,
                "bt_ctf_stream_class_get_event_class_by_name handles non-existing event class names correctly");
-        ret_event_class = bt_ctf_stream_class_get_event_class_by_name(stream_class, "Simple Event");
+       ret_event_class = bt_ctf_stream_class_get_event_class_by_name(stream_class, "Simple Event");
        ok(ret_event_class == simple_event_class,
                "bt_ctf_stream_class_get_event_class_by_name returns a correct event class");
        bt_ctf_event_class_put(ret_event_class);
@@ -537,6 +559,34 @@ void append_simple_event(struct bt_ctf_stream_class *stream_class,
 
        ok(bt_ctf_clock_set_time(clock, current_time) == 0, "Set clock time");
 
+       /* Populate stream event context */
+       stream_event_context = bt_ctf_stream_get_event_context(stream);
+       stream_event_context_field = bt_ctf_field_structure_get_field(
+               stream_event_context, "common_event_context");
+       bt_ctf_field_unsigned_integer_set_value(stream_event_context_field, 42);
+
+       /* Populate the event's context */
+       ok(bt_ctf_event_get_event_context(NULL) == NULL,
+               "bt_ctf_event_get_event_context handles NULL correctly");
+       event_context = bt_ctf_event_get_event_context(simple_event);
+       ok(event_context,
+               "bt_ctf_event_get_event_context returns a field");
+       returned_type = bt_ctf_field_get_type(event_context);
+       ok(returned_type == event_context_type,
+               "bt_ctf_event_get_event_context returns a field of the appropriate type");
+       event_context_field = bt_ctf_field_structure_get_field(event_context,
+               "event_specific_context");
+       ok(!bt_ctf_field_unsigned_integer_set_value(event_context_field, 1234),
+               "Successfully set an event context's value");
+       ok(bt_ctf_event_set_event_context(NULL, event_context) < 0,
+               "bt_ctf_event_set_event_context handles a NULL event correctly");
+       ok(bt_ctf_event_set_event_context(simple_event, NULL) < 0,
+               "bt_ctf_event_set_event_context handles a NULL event context correctly");
+       ok(bt_ctf_event_set_event_context(simple_event, event_context_field) < 0,
+               "bt_ctf_event_set_event_context rejects a context of the wrong type");
+       ok(!bt_ctf_event_set_event_context(simple_event, event_context),
+               "Set an event context successfully");
+
        ok(bt_ctf_stream_append_event(stream, simple_event) == 0,
                "Append simple event to trace stream");
 
@@ -552,7 +602,7 @@ void append_simple_event(struct bt_ctf_stream_class *stream_class,
                "Packet context contains the default packet_size field.");
        bt_ctf_field_put(packet_context_field);
        packet_context_field = bt_ctf_field_structure_get_field(packet_context,
-               "custom_field");
+               "custom_packet_context_field");
        ok(bt_ctf_field_unsigned_integer_set_value(packet_context_field, 8) == 0,
                "Custom packet context field value successfully set.");
 
@@ -574,6 +624,7 @@ void append_simple_event(struct bt_ctf_stream_class *stream_class,
        bt_ctf_field_type_put(enum_type);
        bt_ctf_field_type_put(enum_type_unsigned);
        bt_ctf_field_type_put(returned_type);
+       bt_ctf_field_type_put(event_context_type);
        bt_ctf_field_put(integer_field);
        bt_ctf_field_put(float_field);
        bt_ctf_field_put(enum_field);
@@ -582,6 +633,10 @@ void append_simple_event(struct bt_ctf_stream_class *stream_class,
        bt_ctf_field_put(enum_container_field_unsigned);
        bt_ctf_field_put(packet_context);
        bt_ctf_field_put(packet_context_field);
+       bt_ctf_field_put(stream_event_context);
+       bt_ctf_field_put(stream_event_context_field);
+       bt_ctf_field_put(event_context);
+       bt_ctf_field_put(event_context_field);
 }
 
 void append_complex_event(struct bt_ctf_stream_class *stream_class,
@@ -619,7 +674,6 @@ void append_complex_event(struct bt_ctf_stream_class *stream_class,
        uint64_t ret_unsigned_int;
        int64_t ret_signed_int;
        const char *ret_string;
-       size_t ret_size_t;
        struct bt_ctf_stream_class *ret_stream_class;
        struct bt_ctf_event_class *ret_event_class;
        struct bt_ctf_field *packet_context, *packet_context_field;
@@ -660,30 +714,21 @@ void append_complex_event(struct bt_ctf_stream_class *stream_class,
        bt_ctf_field_type_enumeration_add_mapping(enum_variant_type,
                "UINT35_TYPE", 2, 7);
 
-       ok(bt_ctf_field_type_enumeration_get_mapping_index_by_name(NULL, "INT16_TYPE",
-               &ret_size_t) < 0,
+       ok(bt_ctf_field_type_enumeration_get_mapping_index_by_name(NULL,
+               "INT16_TYPE") < 0,
                "bt_ctf_field_type_enumeration_get_mapping_index_by_name handles a NULL field type correctly");
-       ok(bt_ctf_field_type_enumeration_get_mapping_index_by_name(enum_variant_type, NULL,
-               &ret_size_t) < 0,
+       ok(bt_ctf_field_type_enumeration_get_mapping_index_by_name(
+               enum_variant_type, NULL) < 0,
                "bt_ctf_field_type_enumeration_get_mapping_index_by_name handles a NULL name correctly");
-       ok(bt_ctf_field_type_enumeration_get_mapping_index_by_name(enum_variant_type, "INT16_TYPE",
-               NULL) < 0,
-               "bt_ctf_field_type_enumeration_get_mapping_index_by_name handles a NULL index correctly");
-       ok(bt_ctf_field_type_enumeration_get_mapping_index_by_name(enum_variant_type, "INT16_TYPE",
-               &ret_size_t) == 0,
-               "bt_ctf_field_type_enumeration_get_mapping_index_by_name returns a value");
-       ok(ret_size_t == 1,
+       ok(bt_ctf_field_type_enumeration_get_mapping_index_by_name(
+               enum_variant_type, "INT16_TYPE") == 1,
                "bt_ctf_field_type_enumeration_get_mapping_index_by_name returns the correct index");
 
-       ok(bt_ctf_field_type_enumeration_get_mapping_index_by_unsigned_value(NULL, 1, &ret_size_t) < 0,
+       ok(bt_ctf_field_type_enumeration_get_mapping_index_by_unsigned_value(NULL, 1) < 0,
                "bt_ctf_field_type_enumeration_get_mapping_index_by_unsigned_value handles a NULL field type correctly");
-       ok(bt_ctf_field_type_enumeration_get_mapping_index_by_unsigned_value(enum_variant_type, 1, NULL) < 0,
-               "bt_ctf_field_type_enumeration_get_mapping_index_by_unsigned_value handles a NULL index correctly");
-       ok(bt_ctf_field_type_enumeration_get_mapping_index_by_unsigned_value(enum_variant_type, -42, &ret_size_t) < 0,
-               "bt_ctf_field_type_enumeration_get_mapping_index_by_unsigned_value handles invalid values correctly");
-       ok(bt_ctf_field_type_enumeration_get_mapping_index_by_unsigned_value(enum_variant_type, 5, &ret_size_t) == 0,
+       ok(bt_ctf_field_type_enumeration_get_mapping_index_by_unsigned_value(enum_variant_type, -42) < 0,
                "bt_ctf_field_type_enumeration_get_mapping_index_by_unsigned_value handles invalid values correctly");
-       ok(ret_size_t == 2,
+       ok(bt_ctf_field_type_enumeration_get_mapping_index_by_unsigned_value(enum_variant_type, 5) == 2,
                "bt_ctf_field_type_enumeration_get_mapping_index_by_unsigned_value returns the correct index");
 
        ok(bt_ctf_field_type_variant_add_field(variant_type, uint_3_type,
@@ -977,7 +1022,7 @@ void append_complex_event(struct bt_ctf_stream_class *stream_class,
         */
        packet_context = bt_ctf_stream_get_packet_context(stream);
        packet_context_field = bt_ctf_field_structure_get_field(packet_context,
-               "custom_field");
+               "custom_packet_context_field");
        bt_ctf_field_unsigned_integer_set_value(packet_context_field, 1);
 
        ok(bt_ctf_stream_flush(stream) == 0,
@@ -1319,12 +1364,13 @@ void packet_resize_test(struct bt_ctf_stream_class *stream_class,
                bt_ctf_field_type_integer_create(17);
        struct bt_ctf_field_type *string_type =
                bt_ctf_field_type_string_create();
-       struct bt_ctf_event *event;
-       struct bt_ctf_field *ret_field;
-       struct bt_ctf_field_type *ret_field_type;
+       struct bt_ctf_event *event = NULL;
+       struct bt_ctf_field *ret_field = NULL;
+       struct bt_ctf_field_type *ret_field_type = NULL;
        uint64_t ret_uint64;
        int events_appended = 0;
-       struct bt_ctf_field *packet_context, *packet_context_field;
+       struct bt_ctf_field *packet_context = NULL,
+               *packet_context_field = NULL, *event_context = NULL;
 
        ret |= bt_ctf_event_class_add_field(event_class, integer_type,
                "field_1");
@@ -1350,6 +1396,22 @@ void packet_resize_test(struct bt_ctf_stream_class *stream_class,
                "bt_ctf_event_get_payload_by_index handles an invalid index correctly");
        bt_ctf_event_put(event);
 
+       ok(bt_ctf_stream_get_event_context(NULL) == NULL,
+               "bt_ctf_stream_get_event_context handles NULL correctly");
+       event_context = bt_ctf_stream_get_event_context(stream);
+       ok(event_context,
+               "bt_ctf_stream_get_event_context returns a stream event context");
+       ok(bt_ctf_stream_set_event_context(NULL, event_context) < 0,
+               "bt_ctf_stream_set_event_context handles a NULL stream correctly");
+       ok(bt_ctf_stream_set_event_context(stream, NULL) < 0,
+               "bt_ctf_stream_set_event_context handles a NULL stream event context correctly");
+       ok(!bt_ctf_stream_set_event_context(stream, event_context),
+               "bt_ctf_stream_set_event_context correctly set a stream event context");
+       ret_field = bt_ctf_field_create(integer_type);
+       ok(bt_ctf_stream_set_event_context(stream, ret_field) < 0,
+               "bt_ctf_stream_set_event_context rejects an event context of incorrect type");
+       bt_ctf_field_put(ret_field);
+
        for (i = 0; i < PACKET_RESIZE_TEST_LENGTH; i++) {
                event = bt_ctf_event_create(event_class);
                struct bt_ctf_field *integer =
@@ -1366,6 +1428,14 @@ void packet_resize_test(struct bt_ctf_stream_class *stream_class,
                ret |= bt_ctf_event_set_payload(event, "a_string",
                        string);
                bt_ctf_field_put(string);
+
+               /* Populate stream event context */
+               integer = bt_ctf_field_structure_get_field(event_context,
+                       "common_event_context");
+               ret |= bt_ctf_field_unsigned_integer_set_value(integer,
+                       i % 42);
+               bt_ctf_field_put(integer);
+
                ret |= bt_ctf_stream_append_event(stream, event);
                bt_ctf_event_put(event);
 
@@ -1374,7 +1444,7 @@ void packet_resize_test(struct bt_ctf_stream_class *stream_class,
                }
        }
 
-       events_appended = 1;
+       events_appended = !!(i == PACKET_RESIZE_TEST_LENGTH);
        ok(bt_ctf_stream_get_discarded_events_count(NULL, &ret_uint64) < 0,
                "bt_ctf_stream_get_discarded_events_count handles a NULL stream correctly");
        ok(bt_ctf_stream_get_discarded_events_count(stream, NULL) < 0,
@@ -1396,7 +1466,7 @@ end:
         */
        packet_context = bt_ctf_stream_get_packet_context(stream);
        packet_context_field = bt_ctf_field_structure_get_field(packet_context,
-               "custom_field");
+               "custom_packet_context_field");
        bt_ctf_field_unsigned_integer_set_value(packet_context_field, 2);
 
        ok(bt_ctf_stream_flush(stream) == 0,
@@ -1408,9 +1478,150 @@ end:
        bt_ctf_field_type_put(string_type);
        bt_ctf_field_put(packet_context);
        bt_ctf_field_put(packet_context_field);
+       bt_ctf_field_put(event_context);
        bt_ctf_event_class_put(event_class);
 }
 
+void test_empty_stream(struct bt_ctf_writer *writer)
+{
+       int ret = 0;
+       struct bt_ctf_trace *trace = NULL;
+       struct bt_ctf_stream_class *stream_class = NULL;
+       struct bt_ctf_stream *stream = NULL;
+
+       trace = bt_ctf_writer_get_trace(writer);
+       if (!trace) {
+               diag("Failed to get trace from writer");
+               ret = -1;
+               goto end;
+       }
+
+       stream_class = bt_ctf_stream_class_create("empty_stream");
+       if (!stream_class) {
+               diag("Failed to create stream class");
+               ret = -1;
+               goto end;
+       }
+
+       stream = bt_ctf_writer_create_stream(writer, stream_class);
+       if (!stream) {
+               diag("Failed to create writer stream");
+               ret = -1;
+               goto end;
+       }
+end:
+       ok(ret == 0,
+               "Created a stream class with default attributes and an empty stream");
+       bt_ctf_trace_put(trace);
+       bt_ctf_stream_put(stream);
+       bt_ctf_stream_class_put(stream_class);
+}
+
+void test_instanciate_event_before_stream(struct bt_ctf_writer *writer)
+{
+       int ret = 0;
+       struct bt_ctf_trace *trace = NULL;
+       struct bt_ctf_clock *clock = NULL;
+       struct bt_ctf_stream_class *stream_class = NULL;
+       struct bt_ctf_stream *stream = NULL;
+       struct bt_ctf_event_class *event_class = NULL;
+       struct bt_ctf_event *event = NULL;
+       struct bt_ctf_field_type *integer_type = NULL;
+       struct bt_ctf_field *integer = NULL;
+
+       trace = bt_ctf_writer_get_trace(writer);
+       if (!trace) {
+               diag("Failed to get trace from writer");
+               ret = -1;
+               goto end;
+       }
+
+       clock = bt_ctf_trace_get_clock(trace, 0);
+       if (!clock) {
+               diag("Failed to get clock from trace");
+               ret = -1;
+               goto end;
+       }
+
+       stream_class = bt_ctf_stream_class_create("event_before_stream_test");
+       if (!stream_class) {
+               diag("Failed to create stream class");
+               ret = -1;
+               goto end;
+       }
+
+       ret = bt_ctf_stream_class_set_clock(stream_class, clock);
+       if (ret) {
+               diag("Failed to set stream class clock");
+               goto end;
+       }
+
+       event_class = bt_ctf_event_class_create("some_event_class_name");
+       integer_type = bt_ctf_field_type_integer_create(32);
+       if (!integer_type) {
+               diag("Failed to create integer field type");
+               ret = -1;
+               goto end;
+       }
+
+       ret = bt_ctf_event_class_add_field(event_class, integer_type,
+               "integer_field");
+       if (ret) {
+               diag("Failed to add field to event class");
+               goto end;
+       }
+
+       ret = bt_ctf_stream_class_add_event_class(stream_class,
+               event_class);
+       if (ret) {
+               diag("Failed to add event class to stream class");
+       }
+
+       event = bt_ctf_event_create(event_class);
+       if (!event) {
+               diag("Failed to create event");
+               ret = -1;
+               goto end;
+       }
+
+       integer = bt_ctf_event_get_payload_by_index(event, 0);
+       if (!integer) {
+               diag("Failed to get integer field payload from event");
+               ret = -1;
+               goto end;
+       }
+
+       ret = bt_ctf_field_unsigned_integer_set_value(integer, 1234);
+       if (ret) {
+               diag("Failed to set integer field value");
+               goto end;
+       }
+
+       stream = bt_ctf_writer_create_stream(writer, stream_class);
+       if (!stream) {
+               diag("Failed to create writer stream");
+               ret = -1;
+               goto end;
+       }
+
+       ret = bt_ctf_stream_append_event(stream, event);
+       if (ret) {
+               diag("Failed to append event to stream");
+               goto end;
+       }
+end:
+       ok(ret == 0,
+               "Create an event before instanciating its associated stream");
+       bt_ctf_trace_put(trace);
+       bt_ctf_stream_put(stream);
+       bt_ctf_stream_class_put(stream_class);
+       bt_ctf_event_class_put(event_class);
+       bt_ctf_event_put(event);
+       bt_ctf_field_type_put(integer_type);
+       bt_ctf_field_put(integer);
+       bt_ctf_clock_put(clock);
+}
+
 int main(int argc, char **argv)
 {
        char trace_path[] = "/tmp/ctfwriter_XXXXXX";
@@ -1429,14 +1640,23 @@ int main(int argc, char **argv)
        struct utsname name;
        char hostname[BABELTRACE_HOST_NAME_MAX];
        struct bt_ctf_clock *clock, *ret_clock;
-       struct bt_ctf_stream_class *stream_class;
+       struct bt_ctf_stream_class *stream_class, *ret_stream_class;
        struct bt_ctf_stream *stream1;
        const char *ret_string;
        const unsigned char *ret_uuid;
        unsigned char tmp_uuid[16] = { 0 };
-       struct bt_ctf_field_type *packet_context_type, *packet_context_field_type;
+       struct bt_ctf_field_type *packet_context_type,
+               *packet_context_field_type,
+               *packet_header_type,
+               *packet_header_field_type,
+               *integer_type,
+               *stream_event_context_type,
+               *ret_field_type,
+               *event_header_field_type;
+       struct bt_ctf_field *packet_header, *packet_header_field;
        struct bt_ctf_trace *trace;
        int ret;
+       int64_t ret_int64_t;
 
        if (argc < 3) {
                printf("Usage: tests-ctf-writer path_to_ctf_parser_test path_to_babeltrace\n");
@@ -1455,6 +1675,12 @@ int main(int argc, char **argv)
        writer = bt_ctf_writer_create(trace_path);
        ok(writer, "bt_ctf_create succeeds in creating trace with path");
 
+       ok(!bt_ctf_writer_get_trace(NULL),
+               "bt_ctf_writer_get_trace correctly handles NULL");
+       trace = bt_ctf_writer_get_trace(writer);
+       ok(trace,
+               "bt_ctf_writer_get_trace returns a bt_ctf_trace object");
+
        /* Add environment context to the trace */
        ret = gethostname(hostname, sizeof(hostname));
        if (ret < 0) {
@@ -1472,6 +1698,64 @@ int main(int argc, char **argv)
        ok(bt_ctf_writer_add_environment_field(writer, "test_field",
                NULL),
                "bt_ctf_writer_add_environment_field error with NULL field value");
+       ok(bt_ctf_trace_add_environment_field_integer(NULL, "test_env", 0),
+               "bt_ctf_trace_add_environment_field_integer handles a NULL trace correctly");
+       ok(bt_ctf_trace_add_environment_field_integer(trace, NULL, 0),
+               "bt_ctf_trace_add_environment_field_integer handles a NULL environment field name");
+       ok(!bt_ctf_trace_add_environment_field_integer(trace, "test_env",
+               123456),
+               "Add an integer environment field to a trace instance");
+
+       /* Test bt_ctf_trace_get_environment_field_count */
+       ok(bt_ctf_trace_get_environment_field_count(NULL) < 0,
+               "bt_ctf_trace_get_environment_field_count handles a NULL trace correctly");
+       ok(bt_ctf_trace_get_environment_field_count(trace) == 2,
+               "bt_ctf_trace_get_environment_field_count returns a correct number of environment fields");
+
+       /* Test bt_ctf_trace_get_environment_field_type */
+       ok(bt_ctf_trace_get_environment_field_type(trace, 2) ==
+               BT_ENVIRONMENT_FIELD_TYPE_UNKNOWN,
+               "bt_ctf_trace_get_environment_field_type handles an invalid index correctly");
+       ok(bt_ctf_trace_get_environment_field_type(NULL, 0) ==
+               BT_ENVIRONMENT_FIELD_TYPE_UNKNOWN,
+               "bt_ctf_trace_get_environment_field_type handles a NULL trace correctly");
+       ok(bt_ctf_trace_get_environment_field_type(trace, 1) ==
+               BT_ENVIRONMENT_FIELD_TYPE_INTEGER,
+               "bt_ctf_trace_get_environment_field_type the correct type of environment field");
+
+       /* Test bt_ctf_trace_get_environment_field_name */
+       ok(bt_ctf_trace_get_environment_field_name(NULL, 0) == NULL,
+               "bt_ctf_trace_get_environment_field_name handles a NULL trace correctly");
+       ok(bt_ctf_trace_get_environment_field_name(trace, -1) == NULL,
+               "bt_ctf_trace_get_environment_field_name handles an invalid index correctly");
+       ret_string = bt_ctf_trace_get_environment_field_name(trace, 0);
+       ok(ret_string && !strcmp(ret_string, "host"),
+               "bt_ctf_trace_get_environment_field_name returns a correct field name");
+
+       /* Test bt_ctf_trace_get_environment_field_value_string */
+       ok(bt_ctf_trace_get_environment_field_value_string(NULL, 0) == NULL,
+               "bt_ctf_trace_get_environment_field_value_string handles a NULL trace correctly");
+       ok(bt_ctf_trace_get_environment_field_value_string(trace, -1) == NULL,
+               "bt_ctf_trace_get_environment_field_value_string handles an invalid index correctly");
+       ok(bt_ctf_trace_get_environment_field_value_string(trace, 1) == NULL,
+               "bt_ctf_trace_get_environment_field_value_string validates environment field type");
+       ret_string = bt_ctf_trace_get_environment_field_value_string(trace, 0);
+       ok(ret_string && !strcmp(ret_string, hostname),
+               "bt_ctf_trace_get_environment_field_value_string returns a correct value");
+
+       /* Test bt_ctf_trace_get_environment_field_value_integer */
+       ok(bt_ctf_trace_get_environment_field_value_integer(NULL, 0, &ret_int64_t) < 0,
+               "bt_ctf_trace_get_environment_field_value_integer handles a NULL trace correctly");
+       ok(bt_ctf_trace_get_environment_field_value_integer(trace, 42, &ret_int64_t) < 0,
+               "bt_ctf_trace_get_environment_field_value_integer handles an invalid index correctly");
+       ok(bt_ctf_trace_get_environment_field_value_integer(trace, 1, NULL) < 0,
+               "bt_ctf_trace_get_environment_field_value_integer handles a NULL value argument correctly");
+       ok(bt_ctf_trace_get_environment_field_value_integer(trace, 0, &ret_int64_t) < 0,
+               "bt_ctf_trace_get_environment_field_value_integer validates environment field type");
+       ok(!bt_ctf_trace_get_environment_field_value_integer(trace, 1, &ret_int64_t),
+               "bt_ctf_trace_get_environment_field_value_integer returns a value");
+       ok(ret_int64_t == 123456,
+               "bt_ctf_trace_get_environment_field_value_integer returned a correct value");
 
        if (uname(&name)) {
                perror("uname");
@@ -1564,11 +1848,6 @@ int main(int argc, char **argv)
        ok(bt_ctf_writer_add_clock(writer, clock),
                "Verify a clock can't be added twice to a writer instance");
 
-       ok(!bt_ctf_writer_get_trace(NULL),
-               "bt_ctf_writer_get_trace correctly handles NULL");
-       trace = bt_ctf_writer_get_trace(writer);
-       ok(trace,
-               "bt_ctf_writer_get_trace returns a bt_ctf_trace object");
        ok(bt_ctf_trace_get_clock_count(NULL) < 0,
                "bt_ctf_trace_get_clock_count correctly handles NULL");
        ok(bt_ctf_trace_get_clock_count(trace) == 1,
@@ -1644,7 +1923,7 @@ int main(int argc, char **argv)
        ok(bt_ctf_stream_class_get_name(NULL) == NULL,
                "bt_ctf_stream_class_get_name handles NULL correctly");
        ret_string = bt_ctf_stream_class_get_name(stream_class);
-       ok(!strcmp(ret_string, "test_stream"),
+       ok(ret_string && !strcmp(ret_string, "test_stream"),
                "bt_ctf_stream_class_get_name returns a correct stream class name");
 
        ok(bt_ctf_stream_class_get_clock(stream_class) == NULL,
@@ -1674,8 +1953,67 @@ int main(int argc, char **argv)
        ok(bt_ctf_stream_class_get_id(stream_class) == 123,
                "bt_ctf_stream_class_get_id returns the correct value");
 
-       /* Create a "uint5_t" equivalent custom packet context field */
-       packet_context_field_type = bt_ctf_field_type_integer_create(5);
+       /* Validate default event header fields */
+       ok(bt_ctf_stream_class_get_event_header_type(NULL) == NULL,
+               "bt_ctf_stream_class_get_event_header_type handles NULL correctly");
+       ret_field_type = bt_ctf_stream_class_get_event_header_type(
+               stream_class);
+       ok(ret_field_type,
+               "bt_ctf_stream_class_get_event_header_type returns an event header type");
+       ok(bt_ctf_field_type_get_type_id(ret_field_type) == CTF_TYPE_STRUCT,
+               "Default event header type is a structure");
+       event_header_field_type =
+               bt_ctf_field_type_structure_get_field_type_by_name(
+               ret_field_type, "id");
+       ok(event_header_field_type,
+               "Default event header type contains an \"id\" field");
+       ok(bt_ctf_field_type_get_type_id(
+               event_header_field_type) == CTF_TYPE_INTEGER,
+               "Default event header \"id\" field is an integer");
+       bt_ctf_field_type_put(event_header_field_type);
+       event_header_field_type =
+               bt_ctf_field_type_structure_get_field_type_by_name(
+               ret_field_type, "timestamp");
+       ok(event_header_field_type,
+               "Default event header type contains a \"timestamp\" field");
+       ok(bt_ctf_field_type_get_type_id(
+               event_header_field_type) == CTF_TYPE_INTEGER,
+               "Default event header \"timestamp\" field is an integer");
+       bt_ctf_field_type_put(event_header_field_type);
+       bt_ctf_field_type_put(ret_field_type);
+
+       /* Add a custom trace packet header field */
+       ok(bt_ctf_trace_get_packet_header_type(NULL) == NULL,
+               "bt_ctf_trace_get_packet_header_type handles NULL correctly");
+       packet_header_type = bt_ctf_trace_get_packet_header_type(trace);
+       ok(packet_header_type,
+               "bt_ctf_trace_get_packet_header_type returns a packet header");
+       ok(bt_ctf_field_type_get_type_id(packet_header_type) == CTF_TYPE_STRUCT,
+               "bt_ctf_trace_get_packet_header_type returns a packet header of type struct");
+       ret_field_type = bt_ctf_field_type_structure_get_field_type_by_name(
+               packet_header_type, "magic");
+       ok(ret_field_type, "Default packet header type contains a \"magic\" field");
+       bt_ctf_field_type_put(ret_field_type);
+       ret_field_type = bt_ctf_field_type_structure_get_field_type_by_name(
+               packet_header_type, "uuid");
+       ok(ret_field_type, "Default packet header type contains a \"uuid\" field");
+       bt_ctf_field_type_put(ret_field_type);
+       ret_field_type = bt_ctf_field_type_structure_get_field_type_by_name(
+               packet_header_type, "stream_id");
+       ok(ret_field_type, "Default packet header type contains a \"stream_id\" field");
+       bt_ctf_field_type_put(ret_field_type);
+
+       packet_header_field_type = bt_ctf_field_type_integer_create(22);
+       ok(!bt_ctf_field_type_structure_add_field(packet_header_type,
+               packet_header_field_type, "custom_trace_packet_header_field"),
+               "Added a custom trace packet header field successfully");
+
+       ok(bt_ctf_trace_set_packet_header_type(NULL, packet_header_type) < 0,
+               "bt_ctf_trace_set_packet_header_type handles a NULL trace correctly");
+       ok(bt_ctf_trace_set_packet_header_type(trace, NULL) < 0,
+               "bt_ctf_trace_set_packet_header_type handles a NULL packet_header_type correctly");
+       ok(!bt_ctf_trace_set_packet_header_type(trace, packet_header_type),
+               "Set a trace packet_header_type successfully");
 
        ok(bt_ctf_stream_class_get_packet_context_type(NULL) == NULL,
                "bt_ctf_stream_class_get_packet_context_type handles NULL correctly");
@@ -1691,15 +2029,68 @@ int main(int argc, char **argv)
                "bt_ctf_stream_class_set_packet_context_type handles a NULL stream class correctly");
        ok(bt_ctf_stream_class_set_packet_context_type(stream_class, NULL),
                "bt_ctf_stream_class_set_packet_context_type handles a NULL packet context type correctly");
+
+       integer_type = bt_ctf_field_type_integer_create(32);
+       ok(bt_ctf_stream_class_set_packet_context_type(stream_class,
+               integer_type) < 0,
+               "bt_ctf_stream_class_set_packet_context_type rejects a packet context that is not a structure");
+       /* Create a "uint5_t" equivalent custom packet context field */
+       packet_context_field_type = bt_ctf_field_type_integer_create(5);
+
        ret = bt_ctf_field_type_structure_add_field(packet_context_type,
-               packet_context_field_type, "custom_field");
+               packet_context_field_type, "custom_packet_context_field");
        ok(ret == 0, "Packet context field added successfully");
 
+       /* Define a stream event context containing a my_integer field. */
+       ok(bt_ctf_stream_class_get_event_context_type(NULL) == NULL,
+               "bt_ctf_stream_class_get_event_context_type handles NULL correctly");
+       ok(bt_ctf_stream_class_get_event_context_type(
+               stream_class) == NULL,
+               "bt_ctf_stream_class_get_event_context_type returns NULL when no stream event context type was set.");
+       stream_event_context_type = bt_ctf_field_type_structure_create();
+       bt_ctf_field_type_structure_add_field(stream_event_context_type,
+               integer_type, "common_event_context");
+
+       ok(bt_ctf_stream_class_set_event_context_type(NULL,
+               stream_event_context_type) < 0,
+               "bt_ctf_stream_class_set_event_context_type handles a NULL stream_class correctly");
+       ok(bt_ctf_stream_class_set_event_context_type(stream_class,
+               NULL) < 0,
+               "bt_ctf_stream_class_set_event_context_type handles a NULL event_context correctly");
+       ok(bt_ctf_stream_class_set_event_context_type(stream_class,
+               integer_type) < 0,
+               "bt_ctf_stream_class_set_event_context_type validates that the event context os a structure");
+
+       ok(bt_ctf_stream_class_set_event_context_type(
+               stream_class, stream_event_context_type) == 0,
+               "Set a new stream event context type");
+       ret_field_type = bt_ctf_stream_class_get_event_context_type(
+               stream_class);
+       ok(ret_field_type == stream_event_context_type,
+               "bt_ctf_stream_class_get_event_context_type returns the correct field type.");
+       bt_ctf_field_type_put(ret_field_type);
 
        /* Instantiate a stream and append events */
        stream1 = bt_ctf_writer_create_stream(writer, stream_class);
        ok(stream1, "Instanciate a stream class from writer");
 
+       ok(bt_ctf_stream_get_class(NULL) == NULL,
+               "bt_ctf_stream_get_class correctly handles NULL");
+       ret_stream_class = bt_ctf_stream_get_class(stream1);
+       ok(ret_stream_class,
+               "bt_ctf_stream_get_class returns a stream class");
+       ok(ret_stream_class == stream_class,
+               "Returned stream class is of the correct type");
+
+       /*
+        * Try to modify the packet context type after a stream has been
+        * created.
+        */
+       ret = bt_ctf_field_type_structure_add_field(packet_header_type,
+               packet_header_field_type, "should_fail");
+       ok(ret < 0,
+               "Trace packet header type can't be modified once a stream has been instanciated");
+
        /*
         * Try to modify the packet context type after a stream has been
         * created.
@@ -1707,18 +2098,59 @@ int main(int argc, char **argv)
        ret = bt_ctf_field_type_structure_add_field(packet_context_type,
                packet_context_field_type, "should_fail");
        ok(ret < 0,
-               "Packet context type can't be modified once a stream class has been instanciated");
+               "Packet context type can't be modified once a stream has been instanciated");
+
+       /*
+        * Try to modify the stream event context type after a stream has been
+        * created.
+        */
+       ret = bt_ctf_field_type_structure_add_field(stream_event_context_type,
+               integer_type, "should_fail");
+       ok(ret < 0,
+               "Stream event context type can't be modified once a stream has been instanciated");
 
-       /* Should fail after instanciating a stream (locked)*/
+       /* Should fail after instanciating a stream (frozen) */
        ok(bt_ctf_stream_class_set_clock(stream_class, clock),
                "Changes to a stream class that was already instantiated fail");
 
+       /* Populate the custom packet header field only once for all tests */
+       ok(bt_ctf_stream_get_packet_header(NULL) == NULL,
+               "bt_ctf_stream_get_packet_header handles NULL correctly");
+       packet_header = bt_ctf_stream_get_packet_header(stream1);
+       ok(packet_header,
+               "bt_ctf_stream_get_packet_header returns a packet header");
+       ret_field_type = bt_ctf_field_get_type(packet_header);
+       ok(ret_field_type == packet_header_type,
+               "Stream returns a packet header of the appropriate type");
+       bt_ctf_field_type_put(ret_field_type);
+       packet_header_field = bt_ctf_field_structure_get_field(packet_header,
+               "custom_trace_packet_header_field");
+       ok(packet_header_field,
+               "Packet header structure contains a custom field with the appropriate name");
+       ret_field_type = bt_ctf_field_get_type(packet_header_field);
+       ok(ret_field_type == packet_header_field_type,
+               "Custom packet header field is of the expected type");
+       ok(!bt_ctf_field_unsigned_integer_set_value(packet_header_field,
+               54321), "Set custom packet header value successfully");
+       ok(bt_ctf_stream_set_packet_header(stream1, NULL) < 0,
+               "bt_ctf_stream_set_packet_header handles a NULL packet header correctly");
+       ok(bt_ctf_stream_set_packet_header(NULL, packet_header) < 0,
+               "bt_ctf_stream_set_packet_header handles a NULL stream correctly");
+       ok(bt_ctf_stream_set_packet_header(stream1, packet_header_field) < 0,
+               "bt_ctf_stream_set_packet_header rejects a packet header of the wrong type");
+       ok(!bt_ctf_stream_set_packet_header(stream1, packet_header),
+               "Successfully set a stream's packet header");
+
+       test_instanciate_event_before_stream(writer);
+
        append_simple_event(stream_class, stream1, clock);
 
        packet_resize_test(stream_class, stream1, clock);
 
        append_complex_event(stream_class, stream1, clock);
 
+       test_empty_stream(writer);
+
        metadata_string = bt_ctf_writer_get_metadata_string(writer);
        ok(metadata_string, "Get metadata string");
 
@@ -1728,10 +2160,18 @@ int main(int argc, char **argv)
 
        bt_ctf_clock_put(clock);
        bt_ctf_stream_class_put(stream_class);
+       bt_ctf_stream_class_put(ret_stream_class);
        bt_ctf_writer_put(writer);
        bt_ctf_stream_put(stream1);
        bt_ctf_field_type_put(packet_context_type);
        bt_ctf_field_type_put(packet_context_field_type);
+       bt_ctf_field_type_put(integer_type);
+       bt_ctf_field_type_put(stream_event_context_type);
+       bt_ctf_field_type_put(ret_field_type);
+       bt_ctf_field_type_put(packet_header_type);
+       bt_ctf_field_type_put(packet_header_field_type);
+       bt_ctf_field_put(packet_header);
+       bt_ctf_field_put(packet_header_field);
        bt_ctf_trace_put(trace);
        free(metadata_string);
 
@@ -1751,6 +2191,5 @@ int main(int argc, char **argv)
 
        rmdir(trace_path);
        closedir(trace_dir);
-
        return 0;
 }
This page took 0.033163 seconds and 4 git commands to generate.