/*
- * test_ir_visit.c
+ * test_trace_lister.c
*
- * CTF IR visitor interface test
+ * CTF IR trace listener interface test
*
* Copyright 2016 - Jérémie Galarneau <jeremie.galarneau@efficios.com>
*
#include <babeltrace/ctf-ir/field-types.h>
#include <babeltrace/ctf-ir/stream-class.h>
#include <babeltrace/ctf-ir/trace.h>
-#include <babeltrace/ctf-ir/visitor.h>
#include <stdlib.h>
#include <string.h>
-#define NR_TESTS 13
+#define NR_TESTS 21
struct visitor_state {
int i;
};
struct expected_result {
- const char *element_name;
- enum bt_ctf_ir_type element_type;
+ const char *object_name;
+ enum bt_ctf_object_type object_type;
};
struct expected_result expected_results[] = {
- { NULL, BT_CTF_IR_TYPE_TRACE },
- { "sc1", BT_CTF_IR_TYPE_STREAM_CLASS },
- { "ec1", BT_CTF_IR_TYPE_EVENT_CLASS },
- { "sc2", BT_CTF_IR_TYPE_STREAM_CLASS },
- { "ec2", BT_CTF_IR_TYPE_EVENT_CLASS },
- { "ec3", BT_CTF_IR_TYPE_EVENT_CLASS },
+ { NULL, BT_CTF_OBJECT_TYPE_TRACE },
+ { "sc1", BT_CTF_OBJECT_TYPE_STREAM_CLASS },
+ { "ec1", BT_CTF_OBJECT_TYPE_EVENT_CLASS },
+ { "sc2", BT_CTF_OBJECT_TYPE_STREAM_CLASS },
+ { "ec2", BT_CTF_OBJECT_TYPE_EVENT_CLASS },
+ { "ec3", BT_CTF_OBJECT_TYPE_EVENT_CLASS },
+ /* Elements added after the initial add_listener call. */
+ { "sc3", BT_CTF_OBJECT_TYPE_STREAM_CLASS },
+ { "ec4", BT_CTF_OBJECT_TYPE_EVENT_CLASS },
+ { "ec5", BT_CTF_OBJECT_TYPE_EVENT_CLASS },
};
-const char *element_type_str(enum bt_ctf_ir_type type)
+const char *object_type_str(enum bt_ctf_object_type type)
{
switch (type) {
- case BT_CTF_IR_TYPE_TRACE:
+ case BT_CTF_OBJECT_TYPE_TRACE:
return "trace";
- case BT_CTF_IR_TYPE_STREAM_CLASS:
+ case BT_CTF_OBJECT_TYPE_STREAM_CLASS:
return "stream class";
- case BT_CTF_IR_TYPE_STREAM:
+ case BT_CTF_OBJECT_TYPE_STREAM:
return "stream";
- case BT_CTF_IR_TYPE_EVENT_CLASS:
+ case BT_CTF_OBJECT_TYPE_EVENT_CLASS:
return "event class";
- case BT_CTF_IR_TYPE_EVENT:
+ case BT_CTF_OBJECT_TYPE_EVENT:
return "event";
default:
return "unknown";
goto end;
}
-int visitor(struct bt_ctf_ir_element *element, void *data)
+void visitor(struct bt_ctf_object *object, void *data)
{
- int ret = 0;
bool names_match;
- const char *element_name;
+ const char *object_name;
struct visitor_state *state = data;
struct expected_result *expected = &expected_results[state->i++];
- switch (bt_ctf_ir_element_get_type(element)) {
- case BT_CTF_IR_TYPE_TRACE:
- element_name = NULL;
- names_match = expected->element_name == NULL;
+ switch (bt_ctf_object_get_type(object)) {
+ case BT_CTF_OBJECT_TYPE_TRACE:
+ object_name = NULL;
+ names_match = expected->object_name == NULL;
break;
- case BT_CTF_IR_TYPE_STREAM_CLASS:
- element_name = bt_ctf_stream_class_get_name(
- bt_ctf_ir_element_get_element(element));
- if (!element_name) {
- ret = -1;
- goto end;
+ case BT_CTF_OBJECT_TYPE_STREAM_CLASS:
+ object_name = bt_ctf_stream_class_get_name(
+ bt_ctf_object_get_object(object));
+ if (!object_name) {
+ return;
}
- names_match = !strcmp(element_name, expected->element_name);
+ names_match = !strcmp(object_name, expected->object_name);
break;
- case BT_CTF_IR_TYPE_EVENT_CLASS:
- element_name = bt_ctf_event_class_get_name(
- bt_ctf_ir_element_get_element(element));
- if (!element_name) {
- ret = -1;
- goto end;
+ case BT_CTF_OBJECT_TYPE_EVENT_CLASS:
+ object_name = bt_ctf_event_class_get_name(
+ bt_ctf_object_get_object(object));
+ if (!object_name) {
+ return;
}
- names_match = !strcmp(element_name, expected->element_name);
+ names_match = !strcmp(object_name, expected->object_name);
break;
default:
diag("Encountered an unexpected type while visiting trace");
- ret = -1;
- goto end;
+ return;
}
- ok(expected->element_type == bt_ctf_ir_element_get_type(element),
- "Encoutered element type %s, expected %s",
- element_type_str(expected->element_type),
- element_type_str(bt_ctf_ir_element_get_type(element)));
+ ok(expected->object_type == bt_ctf_object_get_type(object),
+ "Encoutered object type %s, expected %s",
+ object_type_str(expected->object_type),
+ object_type_str(bt_ctf_object_get_type(object)));
ok(names_match, "Element name is %s, expected %s",
- element_name ? : "NULL",
- expected->element_name ? : "NULL");
-end:
- return ret;
+ object_name ? : "NULL",
+ expected->object_name ? : "NULL");
}
int main(int argc, char **argv)
{
- int ret;
+ int ret, index;
struct bt_ctf_trace *trace;
struct visitor_state state = { 0 };
-
+ struct bt_ctf_stream_class *sc3;
+ struct bt_ctf_event_class *ec4, *ec5;
+
plan_tests(NR_TESTS);
- /*
- * Initialize a reference trace which we'll walk using the
- * bt_ctf_*_visit() interface.
- */
trace = init_trace();
if (!trace) {
diag("Failed to initialize reference trace, aborting.");
exit(-1);
}
- ret = bt_ctf_trace_visit(trace, visitor, &state);
- ok(!ret, "bt_ctf_trace_visit returned success");
+ ret = bt_ctf_trace_add_listener(trace, visitor, &state);
+ ok(!ret, "bt_ctf_trace_add_listener returned success");
+
+ /*
+ * Validate that listeners are notified when new objects are added to a
+ * trace.
+ */
+ sc3 = bt_ctf_stream_class_create("sc3");
+ if (!sc3) {
+ diag("Failed to create stream class, aborting.");
+ exit(-1);
+ }
+
+ ec4 = init_event_class("ec4");
+ ec5 = init_event_class("ec5");
+ if (!ec4 || !ec5) {
+ diag("Failed to create event classes, aborting.");
+ exit(-1);
+ }
+
+ ret = bt_ctf_stream_class_add_event_class(sc3, ec4);
+ if (ret) {
+ diag("Failed to add event class to stream class, aborting.");
+ }
+
+ index = state.i;
+ ret = bt_ctf_trace_add_stream_class(trace, sc3);
+ if (ret) {
+ diag("Failed to add stream class sc3 to trace, aborting.");
+ exit(-1);
+ }
+
+ /* Listener should have been invoked two times (sc3 + ec4). */
+ ok(index + 2 == state.i, "trace modification listener has been invoked twice after addition of a stream class");
+
+ index = state.i;
+ ret = bt_ctf_stream_class_add_event_class(sc3, ec5);
+ if (ret) {
+ diag("Failed to add event class to stream class, aborting.");
+ exit(-1);
+ }
+
+ ok(index + 1 == state.i, "trace modification has been invoked once after addition of an event class");
+ BT_PUT(sc3);
+ BT_PUT(ec5);
+ BT_PUT(ec4);
BT_PUT(trace);
return exit_status();
}