* http://www.efficios.com/ctf
*/
-/* For bt_bool, bt_uuid, bt_trace_class, bt_stream_class, bt_field_class */
+/*
+ * For bt_bool, bt_uuid, bt_trace_class, bt_stream_class,
+ * bt_field_class, bt_self_component
+ */
#include <babeltrace/types.h>
/* For bt_trace_class_status */
extern "C" {
#endif
-extern bt_trace_class *bt_trace_class_create(void);
+extern bt_trace_class *bt_trace_class_create(bt_self_component *self_comp);
extern void bt_trace_class_set_assigns_automatic_stream_class_id(
bt_trace_class *trace_class, bt_bool value);
bt_field_wrapper_destroy(field_wrapper);
}
-struct bt_trace_class *bt_trace_class_create(void)
+struct bt_trace_class *bt_trace_class_create(bt_self_component *self_comp)
{
struct bt_trace_class *tc = NULL;
int ret;
+ BT_ASSERT_PRE_NON_NULL(self_comp, "Self component");
BT_LOGD_STR("Creating default trace class object.");
tc = g_new0(struct bt_trace_class, 1);
if (!tc) {
BT_HIDDEN
struct ctf_visitor_generate_ir *ctf_visitor_generate_ir_create(
+ bt_self_component_source *self_comp,
const struct ctf_metadata_decoder_config *config);
void ctf_visitor_generate_ir_destroy(struct ctf_visitor_generate_ir *visitor);
BT_HIDDEN
struct ctf_metadata_decoder *ctf_metadata_decoder_create(
+ bt_self_component_source *self_comp,
const struct ctf_metadata_decoder_config *config)
{
struct ctf_metadata_decoder *mdec =
}
mdec->config = *config;
- mdec->visitor = ctf_visitor_generate_ir_create(config);
+ mdec->visitor = ctf_visitor_generate_ir_create(self_comp, config);
if (!mdec->visitor) {
BT_LOGE("Failed to create a CTF IR metadata AST visitor: "
"mdec-addr=%p", mdec);
*/
BT_HIDDEN
struct ctf_metadata_decoder *ctf_metadata_decoder_create(
+ bt_self_component_source *self_comp,
const struct ctf_metadata_decoder_config *config);
/*
* @returns New visitor context, or NULL on error
*/
static
-struct ctx *ctx_create(
+struct ctx *ctx_create(bt_self_component_source *self_comp,
const struct ctf_metadata_decoder_config *decoder_config)
{
struct ctx *ctx = NULL;
goto error;
}
- ctx->trace_class = bt_trace_class_create();
- if (!ctx->trace_class) {
- BT_LOGE_STR("Cannot create empty trace class.");
- goto error;
+ if (self_comp) {
+ ctx->trace_class = bt_trace_class_create(
+ bt_self_component_source_as_self_component(self_comp));
+ if (!ctx->trace_class) {
+ BT_LOGE_STR("Cannot create empty trace class.");
+ goto error;
+ }
}
ctx->ctf_tc = ctf_trace_class_create();
BT_HIDDEN
struct ctf_visitor_generate_ir *ctf_visitor_generate_ir_create(
+ bt_self_component_source *self_comp,
const struct ctf_metadata_decoder_config *decoder_config)
{
struct ctx *ctx = NULL;
/* Create visitor's context */
- ctx = ctx_create(decoder_config);
+ ctx = ctx_create(self_comp, decoder_config);
if (!ctx) {
BT_LOGE_STR("Cannot create visitor's context.");
goto error;
struct ctx *ctx = (void *) visitor;
BT_ASSERT(ctx);
- BT_ASSERT(ctx->trace_class);
- bt_trace_class_get_ref(ctx->trace_class);
+
+ if (ctx->trace_class) {
+ bt_trace_class_get_ref(ctx->trace_class);
+ }
+
return ctx->trace_class;
}
goto end;
}
- /* Update "in IR" for field classes */
- ret = ctf_trace_class_update_in_ir(ctx->ctf_tc);
- if (ret) {
- ret = -EINVAL;
- goto end;
+ if (ctx->trace_class) {
+ /*
+ * Update "in IR" for field classes.
+ *
+ * If we have no IR trace class, then we'll have no way
+ * to create IR fields anyway, so we leave all the
+ * `in_ir` members false.
+ */
+ ret = ctf_trace_class_update_in_ir(ctx->ctf_tc);
+ if (ret) {
+ ret = -EINVAL;
+ goto end;
+ }
}
/* Update saved value indexes */
goto end;
}
- /* Copy new CTF metadata -> new IR metadata */
- ret = ctf_trace_class_translate(ctx->trace_class, ctx->ctf_tc);
- if (ret) {
- ret = -EINVAL;
- goto end;
+ if (ctx->trace_class) {
+ /* Copy new CTF metadata -> new IR metadata */
+ ret = ctf_trace_class_translate(ctx->trace_class, ctx->ctf_tc);
+ if (ret) {
+ ret = -EINVAL;
+ goto end;
+ }
}
end:
bool done_filling_string;
/* Trace and classes */
+ /* True to set IR fields */
+ bool set_ir_fields;
+
struct {
struct ctf_trace_class *tc;
struct ctf_stream_class *sc;
* packet is created from a stream, and this API must be
* able to return the packet header and context fields
* without creating a stream
- * (bt_msg_iter_borrow_packet_header_context_fields()).
+ * (read_packet_header_context_fields()).
*/
notit->packet_context_field =
bt_packet_context_field_create(
"notit-addr=%p, bfcr-addr=%p, fc-addr=%p, "
"fc-type=%d, fc-in-ir=%d, value=%f",
notit, notit->bfcr, fc, fc->type, fc->in_ir, value);
- BT_ASSERT(fc->in_ir);
+
+ if (unlikely(!fc->in_ir)) {
+ goto end;
+ }
+
field = borrow_next_field(notit);
BT_ASSERT(field);
BT_ASSERT(bt_field_borrow_class_const(field) == fc->ir_fc);
BT_FIELD_CLASS_TYPE_REAL);
bt_field_real_set_value(field, value);
stack_top(notit->stack)->index++;
+
+end:
return status;
}
"fc-type=%d, fc-in-ir=%d",
notit, notit->bfcr, fc, fc->type, fc->in_ir);
- BT_ASSERT(fc->in_ir);
+ if (unlikely(!fc->in_ir)) {
+ goto end;
+ }
+
field = borrow_next_field(notit);
BT_ASSERT(field);
BT_ASSERT(bt_field_borrow_class_const(field) == fc->ir_fc);
* subsequent call to bfcr_string_end_cb().
*/
stack_push(notit->stack, field);
+
+end:
return BT_BFCR_STATUS_OK;
}
"fc-type=%d, fc-in-ir=%d, string-length=%zu",
notit, notit->bfcr, fc, fc->type, fc->in_ir,
len);
- BT_ASSERT(fc->in_ir);
+
+ if (unlikely(!fc->in_ir)) {
+ goto end;
+ }
+
field = stack_top(notit->stack)->base;
BT_ASSERT(field);
"notit-addr=%p, bfcr-addr=%p, fc-addr=%p, "
"fc-type=%d, fc-in-ir=%d",
notit, notit->bfcr, fc, fc->type, fc->in_ir);
- BT_ASSERT(fc->in_ir);
+
+ if (unlikely(!fc->in_ir)) {
+ goto end;
+ }
/* Pop string field */
stack_pop(notit->stack);
/* Go to next field */
stack_top(notit->stack)->index++;
+
+end:
return BT_BFCR_STATUS_OK;
}
return status;
}
-BT_HIDDEN
-enum bt_msg_iter_status bt_msg_iter_borrow_packet_header_context_fields(
- struct bt_msg_iter *notit,
- bt_field **packet_header_field,
- bt_field **packet_context_field)
+static
+enum bt_msg_iter_status read_packet_header_context_fields(
+ struct bt_msg_iter *notit)
{
int ret;
enum bt_msg_iter_status status = BT_MSG_ITER_STATUS_OK;
if (notit->state == STATE_EMIT_MSG_NEW_PACKET) {
/* We're already there */
- goto set_fields;
+ goto end;
}
while (true) {
* Packet header and context fields are
* potentially decoded (or they don't exist).
*/
- goto set_fields;
+ goto end;
case STATE_INIT:
case STATE_EMIT_MSG_NEW_STREAM:
case STATE_DSCOPE_TRACE_PACKET_HEADER_BEGIN:
}
}
-set_fields:
+end:
ret = set_current_packet_content_sizes(notit);
if (ret) {
status = BT_MSG_ITER_STATUS_ERROR;
goto end;
}
- if (packet_header_field) {
- *packet_header_field = notit->dscopes.trace_packet_header;
- }
-
- if (packet_context_field) {
- *packet_context_field = notit->dscopes.stream_packet_context;
- }
-
-end:
return status;
}
struct bt_msg_iter *notit,
struct bt_msg_iter_packet_properties *props)
{
+ enum bt_msg_iter_status status;
+
BT_ASSERT(notit);
BT_ASSERT(props);
+ status = read_packet_header_context_fields(notit);
+ if (status != BT_MSG_ITER_STATUS_OK) {
+ goto end;
+ }
props->exp_packet_total_size =
(uint64_t) notit->cur_exp_packet_total_size;
props->snapshots.packets = notit->snapshots.packets;
props->snapshots.beginning_clock = notit->snapshots.beginning_clock;
props->snapshots.end_clock = notit->snapshots.end_clock;
- return BT_MSG_ITER_STATUS_OK;
+
+end:
+ return status;
}
bt_self_message_iterator *msg_iter,
bt_message **message);
-/**
- * Returns the first packet header and context fields. This function
- * never needs to call the `borrow_stream()` medium operation because
- * it does not create packet or event objects.
- *
- * @param msg_iter CTF message iterator
- * @param packet_header_field Packet header field (\c NULL if there's
- * no packet header field)
- * @param packet_context_field Packet context field (\c NULL if there's
- * no packet context field)
- * @returns One of #bt_msg_iter_status values
- */
-BT_HIDDEN
-enum bt_msg_iter_status bt_msg_iter_borrow_packet_header_context_fields(
- struct bt_msg_iter *notit,
- bt_field **packet_header_field,
- bt_field **packet_context_field);
-
struct bt_msg_iter_packet_properties {
uint64_t exp_packet_total_size;
uint64_t exp_packet_content_size;
BT_LOGD("Building index from .idx file of stream file %s",
ds_file->file->path->str);
-
- ret = bt_msg_iter_borrow_packet_header_context_fields(
- ds_file->msg_iter, NULL, NULL);
+ ret = bt_msg_iter_get_packet_properties(ds_file->msg_iter, &props);
if (ret) {
- BT_LOGD_STR("Cannot borrow first packet's header and context "
- "fields.");
+ BT_LOGD_STR("Cannot read first packet's header and context fields.");
goto error;
}
- ret = bt_msg_iter_get_packet_properties(ds_file->msg_iter, &props);
- BT_ASSERT(ret == 0);
sc = ctf_trace_class_borrow_stream_class_by_id(ds_file->metadata->tc,
props.stream_class_id);
BT_ASSERT(sc);
struct ctf_fs_ds_index_entry *entry;
struct bt_msg_iter_packet_properties props;
- iter_status = bt_msg_iter_borrow_packet_header_context_fields(
- ds_file->msg_iter, NULL, NULL);
+ iter_status = bt_msg_iter_get_packet_properties(
+ ds_file->msg_iter, &props);
if (iter_status != BT_MSG_ITER_STATUS_OK) {
if (iter_status == BT_MSG_ITER_STATUS_EOF) {
break;
goto error;
}
- ret = bt_msg_iter_get_packet_properties(ds_file->msg_iter,
- &props);
- BT_ASSERT(ret == 0);
-
current_packet_offset =
bt_msg_iter_get_current_packet_offset(
ds_file->msg_iter);
return status;
}
-BT_HIDDEN
-int ctf_fs_ds_file_borrow_packet_header_context_fields(
- struct ctf_fs_ds_file *ds_file,
- bt_field **packet_header_field,
- bt_field **packet_context_field)
-{
- enum bt_msg_iter_status msg_iter_status;
- int ret = 0;
-
- BT_ASSERT(ds_file);
- msg_iter_status = bt_msg_iter_borrow_packet_header_context_fields(
- ds_file->msg_iter, packet_header_field, packet_context_field);
- switch (msg_iter_status) {
- case BT_MSG_ITER_STATUS_EOF:
- case BT_MSG_ITER_STATUS_OK:
- break;
- case BT_MSG_ITER_STATUS_AGAIN:
- abort();
- case BT_MSG_ITER_STATUS_INVAL:
- case BT_MSG_ITER_STATUS_ERROR:
- default:
- goto error;
- break;
- }
-
- goto end;
-
-error:
- ret = -1;
-
-end:
- return ret;
-}
-
BT_HIDDEN
void ctf_fs_ds_index_destroy(struct ctf_fs_ds_index *index)
{
struct bt_msg_iter *msg_iter,
bt_stream *stream, const char *path);
-BT_HIDDEN
-int ctf_fs_ds_file_borrow_packet_header_context_fields(
- struct ctf_fs_ds_file *ds_file,
- bt_field **packet_header_field,
- bt_field **packet_context_field);
-
BT_HIDDEN
void ctf_fs_ds_file_destroy(struct ctf_fs_ds_file *stream);
goto error;
}
- ret = ctf_fs_ds_file_borrow_packet_header_context_fields(ds_file,
- NULL, NULL);
+ ret = bt_msg_iter_get_packet_properties(ds_file->msg_iter, &props);
if (ret) {
BT_LOGE("Cannot get stream file's first packet's header and context fields (`%s`).",
path);
goto error;
}
- ret = bt_msg_iter_get_packet_properties(ds_file->msg_iter, &props);
- BT_ASSERT(ret == 0);
sc = ctf_trace_class_borrow_stream_class_by_id(ds_file->metadata->tc,
props.stream_class_id);
BT_ASSERT(sc);
ctf_fs_file_destroy(file);
}
+ if (!ctf_fs_trace->trace) {
+ goto end;
+ }
+
/*
* At this point, DS file groupes are created, but their
* associated stream objects do not exist yet. This is because
}
BT_HIDDEN
-struct ctf_fs_trace *ctf_fs_trace_create(const char *path, const char *name,
+struct ctf_fs_trace *ctf_fs_trace_create(bt_self_component_source *self_comp,
+ const char *path, const char *name,
struct ctf_fs_metadata_config *metadata_config)
{
struct ctf_fs_trace *ctf_fs_trace;
goto error;
}
- ret = ctf_fs_metadata_set_trace_class(ctf_fs_trace, metadata_config);
+ ret = ctf_fs_metadata_set_trace_class(self_comp,
+ ctf_fs_trace, metadata_config);
if (ret) {
goto error;
}
- ctf_fs_trace->trace =
- bt_trace_create(ctf_fs_trace->metadata->trace_class);
- if (!ctf_fs_trace->trace) {
- goto error;
+ if (ctf_fs_trace->metadata->trace_class) {
+ ctf_fs_trace->trace =
+ bt_trace_create(ctf_fs_trace->metadata->trace_class);
+ if (!ctf_fs_trace->trace) {
+ goto error;
+ }
}
- ret = set_trace_name(ctf_fs_trace->trace, name);
- if (ret) {
- goto error;
+ if (ctf_fs_trace->trace) {
+ ret = set_trace_name(ctf_fs_trace->trace, name);
+ if (ret) {
+ goto error;
+ }
}
ret = create_ds_file_groups(ctf_fs_trace);
* trace needs. There won't be any more. Therefore it is safe to
* make this trace static.
*/
- (void) bt_trace_make_static(ctf_fs_trace->trace);
+ if (ctf_fs_trace->trace) {
+ (void) bt_trace_make_static(ctf_fs_trace->trace);
+ }
goto end;
}
static
-int create_ctf_fs_traces(struct ctf_fs_component *ctf_fs,
+int create_ctf_fs_traces(bt_self_component_source *self_comp,
+ struct ctf_fs_component *ctf_fs,
const char *path_param)
{
struct ctf_fs_trace *ctf_fs_trace = NULL;
GString *trace_path = tp_node->data;
GString *trace_name = tn_node->data;
- ctf_fs_trace = ctf_fs_trace_create(trace_path->str,
- trace_name->str, &ctf_fs->metadata_config);
+ ctf_fs_trace = ctf_fs_trace_create(self_comp,
+ trace_path->str, trace_name->str,
+ &ctf_fs->metadata_config);
if (!ctf_fs_trace) {
BT_LOGE("Cannot create trace for `%s`.",
trace_path->str);
goto error;
}
- if (create_ctf_fs_traces(ctf_fs, path_param)) {
+ if (create_ctf_fs_traces(self_comp, ctf_fs, path_param)) {
goto error;
}
const bt_value **result);
BT_HIDDEN
-struct ctf_fs_trace *ctf_fs_trace_create(const char *path, const char *name,
+struct ctf_fs_trace *ctf_fs_trace_create(bt_self_component_source *self_comp,
+ const char *path, const char *name,
struct ctf_fs_metadata_config *config);
BT_HIDDEN
return file;
}
-int ctf_fs_metadata_set_trace_class(struct ctf_fs_trace *ctf_fs_trace,
+BT_HIDDEN
+int ctf_fs_metadata_set_trace_class(
+ bt_self_component_source *self_comp,
+ struct ctf_fs_trace *ctf_fs_trace,
struct ctf_fs_metadata_config *config)
{
int ret = 0;
goto end;
}
- ctf_fs_trace->metadata->decoder = ctf_metadata_decoder_create(
+ ctf_fs_trace->metadata->decoder = ctf_metadata_decoder_create(self_comp,
config ? &decoder_config : NULL);
if (!ctf_fs_trace->metadata->decoder) {
BT_LOGE("Cannot create metadata decoder object");
ctf_fs_trace->metadata->trace_class =
ctf_metadata_decoder_get_ir_trace_class(
ctf_fs_trace->metadata->decoder);
- BT_ASSERT(ctf_fs_trace->metadata->trace_class);
+ BT_ASSERT(!self_comp || ctf_fs_trace->metadata->trace_class);
ctf_fs_trace->metadata->tc =
ctf_metadata_decoder_borrow_ctf_trace_class(
ctf_fs_trace->metadata->decoder);
return ret;
}
+BT_HIDDEN
int ctf_fs_metadata_init(struct ctf_fs_metadata *metadata)
{
/* Nothing to initialize for the moment. */
return 0;
}
+BT_HIDDEN
void ctf_fs_metadata_fini(struct ctf_fs_metadata *metadata)
{
if (metadata->text) {
void ctf_fs_metadata_fini(struct ctf_fs_metadata *metadata);
BT_HIDDEN
-int ctf_fs_metadata_set_trace_class(struct ctf_fs_trace *ctf_fs_trace,
+int ctf_fs_metadata_set_trace_class(bt_self_component_source *self_comp,
+ struct ctf_fs_trace *ctf_fs_trace,
struct ctf_fs_metadata_config *config);
BT_HIDDEN
goto end;
}
- trace = ctf_fs_trace_create(trace_path, trace_name, NULL);
+ trace = ctf_fs_trace_create(NULL, trace_path, trace_name, NULL);
if (!trace) {
BT_LOGE("Failed to create fs trace at \'%s\'", trace_path);
ret = -1;
bt_bool no_timestamp;
} params;
+ bt_self_component_source *self_comp;
bt_trace_class *trace_class;
bt_stream_class *stream_class;
bt_event_class *event_class;
bt_field_class *fc = NULL;
int ret = 0;
- dmesg_comp->trace_class = bt_trace_class_create();
+ dmesg_comp->trace_class = bt_trace_class_create(
+ bt_self_component_source_as_self_component(
+ dmesg_comp->self_comp));
if (!dmesg_comp->trace_class) {
BT_LOGE_STR("Cannot create an empty trace class object.");
goto error;
goto error;
}
+ dmesg_comp->self_comp = self_comp;
dmesg_comp->params.path = g_string_new(NULL);
if (!dmesg_comp->params.path) {
BT_LOGE_STR("Failed to allocate a GString.");
}
static
-void init_static_data(void)
+void init_static_data(bt_self_component_source *self_comp)
{
bt_trace_class *trace_class;
bt_trace *trace;
- /* Test events */
- test_events = g_array_new(FALSE, TRUE, sizeof(struct test_event));
- BT_ASSERT(test_events);
-
/* Metadata, streams, and packets*/
- trace_class = bt_trace_class_create();
- BT_ASSERT(trace);
+ trace_class = bt_trace_class_create(
+ bt_self_component_source_as_self_component(self_comp));
+ BT_ASSERT(trace_class);
src_stream_class = bt_stream_class_create(trace_class);
BT_ASSERT(src_stream_class);
src_event_class = bt_event_class_create(src_stream_class);
static
void fini_static_data(void)
{
- /* Test events */
- g_array_free(test_events, TRUE);
-
/* Metadata */
bt_stream_class_put_ref(src_stream_class);
bt_event_class_put_ref(src_event_class);
{
int ret;
+ init_static_data(self_comp);
ret = bt_self_component_source_add_output_port(
self_comp, "out", NULL, NULL);
BT_ASSERT(ret == 0);
}
}
+typedef void (*compare_func_t)(void);
+
static
-void do_std_test(enum test test, const char *name,
- const struct test_event *expected_test_events)
+void do_std_test(enum test test, const char *name, compare_func_t compare_func)
{
const bt_component_source *src_comp;
const bt_component_sink *sink_comp;
"graph finishes without any error");
/* Compare the resulting test events */
- if (expected_test_events) {
- ok(compare_test_events(expected_test_events),
- "the produced sequence of test events is the expected one");
+ if (compare_func) {
+ compare_func();
}
bt_component_source_put_ref(src_comp);
bt_component_sink_put_ref(sink_comp);
+ fini_static_data();
BT_GRAPH_PUT_REF_AND_RESET(graph);
}
static
-void test_no_auto_msgs(void)
+void test_no_auto_msgs_compare(void)
{
const struct test_event expected_test_events[] = {
{ .type = TEST_EV_TYPE_MSG_STREAM_BEGIN, .stream = src_stream1, .packet = NULL, },
{ .type = TEST_EV_TYPE_SENTINEL, },
};
+ ok(compare_test_events(expected_test_events),
+ "the produced sequence of test events is the expected one");
+}
+
+static
+void test_no_auto_msgs(void)
+{
do_std_test(TEST_NO_AUTO_MSGS, "no automatic messages",
- expected_test_events);
+ test_no_auto_msgs_compare);
}
static
void test_output_port_message_iterator(void)
{
- const struct test_event expected_test_events[] = {
- { .type = TEST_EV_TYPE_MSG_STREAM_BEGIN, .stream = src_stream1, .packet = NULL, },
- { .type = TEST_EV_TYPE_MSG_PACKET_BEGIN, .stream = src_stream1, .packet = src_stream1_packet1, },
- { .type = TEST_EV_TYPE_MSG_EVENT, .stream = src_stream1, .packet = src_stream1_packet1, },
- { .type = TEST_EV_TYPE_MSG_EVENT, .stream = src_stream1, .packet = src_stream1_packet1, },
- { .type = TEST_EV_TYPE_MSG_STREAM_BEGIN, .stream = src_stream2, .packet = NULL, },
- { .type = TEST_EV_TYPE_MSG_EVENT, .stream = src_stream1, .packet = src_stream1_packet1, },
- { .type = TEST_EV_TYPE_MSG_PACKET_BEGIN, .stream = src_stream2, .packet = src_stream2_packet2, },
- { .type = TEST_EV_TYPE_MSG_EVENT, .stream = src_stream2, .packet = src_stream2_packet2, },
- { .type = TEST_EV_TYPE_MSG_EVENT, .stream = src_stream1, .packet = src_stream1_packet1, },
- { .type = TEST_EV_TYPE_MSG_PACKET_END, .stream = src_stream1, .packet = src_stream1_packet1, },
- { .type = TEST_EV_TYPE_MSG_PACKET_END, .stream = src_stream2, .packet = src_stream2_packet2, },
- { .type = TEST_EV_TYPE_MSG_PACKET_BEGIN, .stream = src_stream1, .packet = src_stream1_packet2, },
- { .type = TEST_EV_TYPE_MSG_EVENT, .stream = src_stream1, .packet = src_stream1_packet2, },
- { .type = TEST_EV_TYPE_MSG_STREAM_END, .stream = src_stream2, .packet = NULL, },
- { .type = TEST_EV_TYPE_MSG_PACKET_END, .stream = src_stream1, .packet = src_stream1_packet2, },
- { .type = TEST_EV_TYPE_MSG_STREAM_END, .stream = src_stream1, .packet = NULL, },
- { .type = TEST_EV_TYPE_END, },
- { .type = TEST_EV_TYPE_SENTINEL, },
- };
const bt_component_source *src_comp;
bt_port_output_message_iterator *msg_iter;
bt_message_iterator_status iter_status =
create_source_sink(graph, &src_comp, NULL);
/* Create message iterator on source's output port */
- upstream_port = bt_component_source_borrow_output_port_by_name_const(src_comp,
- "out");
- msg_iter = bt_port_output_message_iterator_create(graph,
- upstream_port);
+ upstream_port = bt_component_source_borrow_output_port_by_name_const(
+ src_comp, "out");
+ msg_iter = bt_port_output_message_iterator_create(graph, upstream_port);
ok(msg_iter, "bt_private_output_port_message_iterator_create() succeeds");
/* Consume the message iterator */
"output port message iterator finishes without any error");
/* Compare the resulting test events */
- ok(compare_test_events(expected_test_events),
- "the produced sequence of test events is the expected one");
+ {
+ const struct test_event expected_test_events[] = {
+ { .type = TEST_EV_TYPE_MSG_STREAM_BEGIN, .stream = src_stream1, .packet = NULL, },
+ { .type = TEST_EV_TYPE_MSG_PACKET_BEGIN, .stream = src_stream1, .packet = src_stream1_packet1, },
+ { .type = TEST_EV_TYPE_MSG_EVENT, .stream = src_stream1, .packet = src_stream1_packet1, },
+ { .type = TEST_EV_TYPE_MSG_EVENT, .stream = src_stream1, .packet = src_stream1_packet1, },
+ { .type = TEST_EV_TYPE_MSG_STREAM_BEGIN, .stream = src_stream2, .packet = NULL, },
+ { .type = TEST_EV_TYPE_MSG_EVENT, .stream = src_stream1, .packet = src_stream1_packet1, },
+ { .type = TEST_EV_TYPE_MSG_PACKET_BEGIN, .stream = src_stream2, .packet = src_stream2_packet2, },
+ { .type = TEST_EV_TYPE_MSG_EVENT, .stream = src_stream2, .packet = src_stream2_packet2, },
+ { .type = TEST_EV_TYPE_MSG_EVENT, .stream = src_stream1, .packet = src_stream1_packet1, },
+ { .type = TEST_EV_TYPE_MSG_PACKET_END, .stream = src_stream1, .packet = src_stream1_packet1, },
+ { .type = TEST_EV_TYPE_MSG_PACKET_END, .stream = src_stream2, .packet = src_stream2_packet2, },
+ { .type = TEST_EV_TYPE_MSG_PACKET_BEGIN, .stream = src_stream1, .packet = src_stream1_packet2, },
+ { .type = TEST_EV_TYPE_MSG_EVENT, .stream = src_stream1, .packet = src_stream1_packet2, },
+ { .type = TEST_EV_TYPE_MSG_STREAM_END, .stream = src_stream2, .packet = NULL, },
+ { .type = TEST_EV_TYPE_MSG_PACKET_END, .stream = src_stream1, .packet = src_stream1_packet2, },
+ { .type = TEST_EV_TYPE_MSG_STREAM_END, .stream = src_stream1, .packet = NULL, },
+ { .type = TEST_EV_TYPE_END, },
+ { .type = TEST_EV_TYPE_SENTINEL, },
+ };
+
+ ok(compare_test_events(expected_test_events),
+ "the produced sequence of test events is the expected one");
+ }
+ fini_static_data();
bt_component_source_put_ref(src_comp);
BT_GRAPH_PUT_REF_AND_RESET(graph);
bt_port_output_message_iterator_put_ref(msg_iter);
}
plan_tests(NR_TESTS);
- init_static_data();
+ test_events = g_array_new(FALSE, TRUE, sizeof(struct test_event));
+ BT_ASSERT(test_events);
test_no_auto_msgs();
test_output_port_message_iterator();
- fini_static_data();
+ g_array_free(test_events, TRUE);
return exit_status();
}
bt_field_class_put_ref(packet_header_type);
}
-static bt_trace_class *create_tc1(void)
+static bt_trace_class *create_tc1(bt_self_component_source *self_comp)
{
bt_trace_class *tc1 = NULL;
- tc1 = bt_trace_class_create();
+ tc1 = bt_trace_class_create(
+ bt_self_component_source_as_self_component(self_comp));
BT_ASSERT(tc1);
set_trace_packet_header(tc1);
create_sc1(tc1);
*ec3 = bt_stream_class_borrow_event_class_by_index(*sc2, 0);
}
-static void test_example_scenario(void)
+static void test_example_scenario(bt_self_component_source *self_comp)
{
/*
* Weak pointers to trace IR objects are to be used very
struct user user_a = { 0 }, user_b = { 0 }, user_c = { 0 };
/* The only reference which exists at this point is on TC1. */
- tc1 = create_tc1();
+ tc1 = create_tc1(self_comp);
ok(tc1, "Initialize trace");
BT_ASSERT(tc1);
init_weak_refs(tc1, &weak_tc1, &weak_sc1, &weak_sc2, &weak_ec1,
BT_EVENT_CLASS_PUT_REF_AND_RESET(user_c.ec);
}
+static
+bt_self_component_status src_init(
+ bt_self_component_source *self_comp,
+ const bt_value *params, void *init_method_data)
+{
+ test_example_scenario(self_comp);
+ return BT_SELF_COMPONENT_STATUS_OK;
+}
+
+static
+bt_self_message_iterator_status src_iter_next(
+ bt_self_message_iterator *self_iterator,
+ bt_message_array_const msgs, uint64_t capacity,
+ uint64_t *count)
+{
+ return BT_SELF_MESSAGE_ITERATOR_STATUS_ERROR;
+}
+
+static void test_example_scenario_in_graph(void)
+{
+ bt_component_class_source *comp_cls;
+ bt_graph *graph;
+ int ret;
+
+ comp_cls = bt_component_class_source_create("src", src_iter_next);
+ BT_ASSERT(comp_cls);
+ ret = bt_component_class_source_set_init_method(comp_cls, src_init);
+ BT_ASSERT(ret == 0);
+ graph = bt_graph_create();
+ ret = bt_graph_add_source_component(graph, comp_cls, "src-comp",
+ NULL, NULL);
+ BT_ASSERT(ret == 0);
+ bt_graph_put_ref(graph);
+ bt_component_class_source_put_ref(comp_cls);
+}
+
static void create_writer_user_full(struct writer_user *user)
{
gchar *trace_path;
/* Initialize tap harness before any tests */
plan_tests(NR_TESTS);
- test_example_scenario();
+ test_example_scenario_in_graph();
test_put_order();
return exit_status();