Add bt_ctf_trace_get_stream_count() and bt_ctf_trace_get_stream()
[babeltrace.git] / tests / lib / test_trace_listener.c
CommitLineData
3a586ea9 1/*
1323fbeb 2 * test_trace_lister.c
3a586ea9 3 *
1323fbeb 4 * CTF IR trace listener interface test
3a586ea9
JG
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"
23#include <babeltrace/ctf-ir/event-class.h>
24#include <babeltrace/ctf-ir/field-types.h>
25#include <babeltrace/ctf-ir/stream-class.h>
26#include <babeltrace/ctf-ir/trace.h>
c1e730fe 27#include <babeltrace/ctf-ir/trace-internal.h>
3a586ea9
JG
28#include <stdlib.h>
29#include <string.h>
30
1323fbeb 31#define NR_TESTS 21
3a586ea9
JG
32
33struct visitor_state {
34 int i;
35};
36
37struct expected_result {
d9a13d86
PP
38 const char *object_name;
39 enum bt_ctf_object_type object_type;
3a586ea9
JG
40};
41
42struct expected_result expected_results[] = {
d9a13d86
PP
43 { NULL, BT_CTF_OBJECT_TYPE_TRACE },
44 { "sc1", BT_CTF_OBJECT_TYPE_STREAM_CLASS },
45 { "ec1", BT_CTF_OBJECT_TYPE_EVENT_CLASS },
46 { "sc2", BT_CTF_OBJECT_TYPE_STREAM_CLASS },
47 { "ec2", BT_CTF_OBJECT_TYPE_EVENT_CLASS },
48 { "ec3", BT_CTF_OBJECT_TYPE_EVENT_CLASS },
1323fbeb 49 /* Elements added after the initial add_listener call. */
d9a13d86
PP
50 { "sc3", BT_CTF_OBJECT_TYPE_STREAM_CLASS },
51 { "ec4", BT_CTF_OBJECT_TYPE_EVENT_CLASS },
52 { "ec5", BT_CTF_OBJECT_TYPE_EVENT_CLASS },
3a586ea9
JG
53};
54
d9a13d86 55const char *object_type_str(enum bt_ctf_object_type type)
3a586ea9
JG
56{
57 switch (type) {
d9a13d86 58 case BT_CTF_OBJECT_TYPE_TRACE:
3a586ea9 59 return "trace";
d9a13d86 60 case BT_CTF_OBJECT_TYPE_STREAM_CLASS:
3a586ea9 61 return "stream class";
d9a13d86 62 case BT_CTF_OBJECT_TYPE_STREAM:
3a586ea9 63 return "stream";
d9a13d86 64 case BT_CTF_OBJECT_TYPE_EVENT_CLASS:
3a586ea9 65 return "event class";
d9a13d86 66 case BT_CTF_OBJECT_TYPE_EVENT:
3a586ea9
JG
67 return "event";
68 default:
69 return "unknown";
70 }
71}
72
73struct bt_ctf_event_class *init_event_class(const char *name)
74{
75 int ret;
76 struct bt_ctf_event_class *ec = bt_ctf_event_class_create(name);
77 struct bt_ctf_field_type *int_field =
78 bt_ctf_field_type_integer_create(8);
79
80 if (!ec || !int_field) {
81 goto error;
82 }
83
84 ret = bt_ctf_event_class_add_field(ec, int_field, "an_int_field");
85 if (ret) {
86 goto error;
87 }
88
89 BT_PUT(int_field);
90 return ec;
91error:
92 BT_PUT(ec);
93 BT_PUT(int_field);
94 return NULL;
95}
96
97struct bt_ctf_trace *init_trace(void)
98{
99 int ret;
100 struct bt_ctf_trace *trace = bt_ctf_trace_create();
101 struct bt_ctf_stream_class *sc1 = bt_ctf_stream_class_create("sc1");
102 struct bt_ctf_stream_class *sc2 = bt_ctf_stream_class_create("sc2");
103 struct bt_ctf_event_class *ec1 = init_event_class("ec1");
104 struct bt_ctf_event_class *ec2 = init_event_class("ec2");
105 struct bt_ctf_event_class *ec3 = init_event_class("ec3");
106
107 if (!trace || !sc1 || !sc2 || !ec1 || !ec2 || !ec3) {
108 goto end;
109 }
110
111 ret = bt_ctf_stream_class_add_event_class(sc1, ec1);
112 if (ret) {
113 goto error;
114 }
115
116 ret = bt_ctf_stream_class_add_event_class(sc2, ec2);
117 if (ret) {
118 goto error;
119 }
120
121 ret = bt_ctf_stream_class_add_event_class(sc2, ec3);
122 if (ret) {
123 goto error;
124 }
125
126 ret = bt_ctf_trace_add_stream_class(trace, sc1);
127 if (ret) {
128 goto error;
129 }
130
131 ret = bt_ctf_trace_add_stream_class(trace, sc2);
132 if (ret) {
133 goto error;
134 }
135end:
136 BT_PUT(sc1);
137 BT_PUT(sc2);
138 BT_PUT(ec1);
139 BT_PUT(ec2);
140 BT_PUT(ec3);
141 return trace;
142error:
143 BT_PUT(trace);
144 goto end;
145}
146
d9a13d86 147void visitor(struct bt_ctf_object *object, void *data)
3a586ea9 148{
3a586ea9 149 bool names_match;
d9a13d86 150 const char *object_name;
3a586ea9
JG
151 struct visitor_state *state = data;
152 struct expected_result *expected = &expected_results[state->i++];
153
d9a13d86
PP
154 switch (bt_ctf_object_get_type(object)) {
155 case BT_CTF_OBJECT_TYPE_TRACE:
156 object_name = NULL;
157 names_match = expected->object_name == NULL;
3a586ea9 158 break;
d9a13d86
PP
159 case BT_CTF_OBJECT_TYPE_STREAM_CLASS:
160 object_name = bt_ctf_stream_class_get_name(
161 bt_ctf_object_get_object(object));
162 if (!object_name) {
1323fbeb 163 return;
3a586ea9
JG
164 }
165
d9a13d86 166 names_match = !strcmp(object_name, expected->object_name);
3a586ea9 167 break;
d9a13d86
PP
168 case BT_CTF_OBJECT_TYPE_EVENT_CLASS:
169 object_name = bt_ctf_event_class_get_name(
170 bt_ctf_object_get_object(object));
171 if (!object_name) {
1323fbeb 172 return;
3a586ea9
JG
173 }
174
d9a13d86 175 names_match = !strcmp(object_name, expected->object_name);
3a586ea9
JG
176 break;
177 default:
178 diag("Encountered an unexpected type while visiting trace");
1323fbeb 179 return;
3a586ea9
JG
180 }
181
d9a13d86
PP
182 ok(expected->object_type == bt_ctf_object_get_type(object),
183 "Encoutered object type %s, expected %s",
184 object_type_str(expected->object_type),
185 object_type_str(bt_ctf_object_get_type(object)));
3a586ea9 186 ok(names_match, "Element name is %s, expected %s",
d9a13d86
PP
187 object_name ? : "NULL",
188 expected->object_name ? : "NULL");
3a586ea9
JG
189}
190
191int main(int argc, char **argv)
192{
1323fbeb 193 int ret, index;
3a586ea9
JG
194 struct bt_ctf_trace *trace;
195 struct visitor_state state = { 0 };
1323fbeb
JG
196 struct bt_ctf_stream_class *sc3;
197 struct bt_ctf_event_class *ec4, *ec5;
198
3a586ea9
JG
199 plan_tests(NR_TESTS);
200
3a586ea9
JG
201 trace = init_trace();
202 if (!trace) {
203 diag("Failed to initialize reference trace, aborting.");
204 exit(-1);
205 }
206
1323fbeb
JG
207 ret = bt_ctf_trace_add_listener(trace, visitor, &state);
208 ok(!ret, "bt_ctf_trace_add_listener returned success");
209
210 /*
d9a13d86 211 * Validate that listeners are notified when new objects are added to a
1323fbeb
JG
212 * trace.
213 */
214 sc3 = bt_ctf_stream_class_create("sc3");
215 if (!sc3) {
216 diag("Failed to create stream class, aborting.");
217 exit(-1);
218 }
219
220 ec4 = init_event_class("ec4");
221 ec5 = init_event_class("ec5");
222 if (!ec4 || !ec5) {
223 diag("Failed to create event classes, aborting.");
224 exit(-1);
225 }
226
227 ret = bt_ctf_stream_class_add_event_class(sc3, ec4);
228 if (ret) {
229 diag("Failed to add event class to stream class, aborting.");
230 }
231
232 index = state.i;
233 ret = bt_ctf_trace_add_stream_class(trace, sc3);
234 if (ret) {
235 diag("Failed to add stream class sc3 to trace, aborting.");
236 exit(-1);
237 }
238
239 /* Listener should have been invoked two times (sc3 + ec4). */
240 ok(index + 2 == state.i, "trace modification listener has been invoked twice after addition of a stream class");
241
242 index = state.i;
243 ret = bt_ctf_stream_class_add_event_class(sc3, ec5);
244 if (ret) {
245 diag("Failed to add event class to stream class, aborting.");
246 exit(-1);
247 }
248
249 ok(index + 1 == state.i, "trace modification has been invoked once after addition of an event class");
3a586ea9 250
dc3fffef
PP
251 BT_PUT(sc3);
252 BT_PUT(ec5);
253 BT_PUT(ec4);
3a586ea9
JG
254 BT_PUT(trace);
255 return exit_status();
256}
257
This page took 0.0368000000000001 seconds and 4 git commands to generate.