2886dc9409f9922941658545a46ee07b2b2f1af0
[babeltrace.git] / tests / lib / test_ir_visit.c
1 /*
2 * test_ir_visit.c
3 *
4 * CTF IR visitor interface test
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>
27 #include <babeltrace/ctf-ir/visitor.h>
28 #include <stdlib.h>
29 #include <stdbool.h>
30 #include <string.h>
31 #include <assert.h>
32
33 #define NR_TESTS 13
34
35 struct visitor_state {
36 int i;
37 };
38
39 struct expected_result {
40 const char *object_name;
41 enum bt_ctf_object_type object_type;
42 };
43
44 struct expected_result expected_results[] = {
45 { NULL, BT_CTF_OBJECT_TYPE_TRACE },
46 { "sc1", BT_CTF_OBJECT_TYPE_STREAM_CLASS },
47 { "ec1", BT_CTF_OBJECT_TYPE_EVENT_CLASS },
48 { "sc2", BT_CTF_OBJECT_TYPE_STREAM_CLASS },
49 { "ec2", BT_CTF_OBJECT_TYPE_EVENT_CLASS },
50 { "ec3", BT_CTF_OBJECT_TYPE_EVENT_CLASS },
51 };
52
53 const char *object_type_str(enum bt_ctf_object_type type)
54 {
55 switch (type) {
56 case BT_CTF_OBJECT_TYPE_TRACE:
57 return "trace";
58 case BT_CTF_OBJECT_TYPE_STREAM_CLASS:
59 return "stream class";
60 case BT_CTF_OBJECT_TYPE_STREAM:
61 return "stream";
62 case BT_CTF_OBJECT_TYPE_EVENT_CLASS:
63 return "event class";
64 case BT_CTF_OBJECT_TYPE_EVENT:
65 return "event";
66 default:
67 return "unknown";
68 }
69 }
70
71 struct bt_ctf_event_class *init_event_class(const char *name)
72 {
73 int ret;
74 struct bt_ctf_event_class *ec = bt_ctf_event_class_create(name);
75 struct bt_ctf_field_type *int_field =
76 bt_ctf_field_type_integer_create(8);
77
78 if (!ec || !int_field) {
79 goto error;
80 }
81
82 ret = bt_ctf_event_class_add_field(ec, int_field, "an_int_field");
83 if (ret) {
84 goto error;
85 }
86
87 BT_PUT(int_field);
88 return ec;
89 error:
90 BT_PUT(ec);
91 BT_PUT(int_field);
92 return NULL;
93 }
94
95 static void set_stream_class_field_types(
96 struct bt_ctf_stream_class *stream_class)
97 {
98 struct bt_ctf_field_type *packet_context_type;
99 struct bt_ctf_field_type *event_header_type;
100 struct bt_ctf_field_type *ft;
101 int ret;
102
103 packet_context_type = bt_ctf_field_type_structure_create();
104 assert(packet_context_type);
105 ft = bt_ctf_field_type_integer_create(32);
106 assert(ft);
107 ret = bt_ctf_field_type_structure_add_field(packet_context_type,
108 ft, "packet_size");
109 assert(ret == 0);
110 bt_put(ft);
111 ft = bt_ctf_field_type_integer_create(32);
112 assert(ft);
113 ret = bt_ctf_field_type_structure_add_field(packet_context_type,
114 ft, "content_size");
115 assert(ret == 0);
116 bt_put(ft);
117
118 event_header_type = bt_ctf_field_type_structure_create();
119 assert(event_header_type);
120 ft = bt_ctf_field_type_integer_create(32);
121 assert(ft);
122 ret = bt_ctf_field_type_structure_add_field(event_header_type,
123 ft, "id");
124 assert(ret == 0);
125 bt_put(ft);
126
127 ret = bt_ctf_stream_class_set_packet_context_type(stream_class,
128 packet_context_type);
129 assert(ret == 0);
130 ret = bt_ctf_stream_class_set_event_header_type(stream_class,
131 event_header_type);
132 assert(ret == 0);
133
134 bt_put(packet_context_type);
135 bt_put(event_header_type);
136 }
137
138 static void set_trace_packet_header(struct bt_ctf_trace *trace)
139 {
140 struct bt_ctf_field_type *packet_header_type;
141 struct bt_ctf_field_type *ft;
142 int ret;
143
144 packet_header_type = bt_ctf_field_type_structure_create();
145 assert(packet_header_type);
146 ft = bt_ctf_field_type_integer_create(32);
147 assert(ft);
148 ret = bt_ctf_field_type_structure_add_field(packet_header_type,
149 ft, "stream_id");
150 assert(ret == 0);
151 bt_put(ft);
152
153 ret = bt_ctf_trace_set_packet_header_type(trace,
154 packet_header_type);
155 assert(ret == 0);
156
157 bt_put(packet_header_type);
158 }
159
160 struct bt_ctf_trace *init_trace(void)
161 {
162 int ret;
163 struct bt_ctf_trace *trace = bt_ctf_trace_create();
164 struct bt_ctf_stream_class *sc1 = bt_ctf_stream_class_create("sc1");
165 struct bt_ctf_stream_class *sc2 = bt_ctf_stream_class_create("sc2");
166 struct bt_ctf_event_class *ec1 = init_event_class("ec1");
167 struct bt_ctf_event_class *ec2 = init_event_class("ec2");
168 struct bt_ctf_event_class *ec3 = init_event_class("ec3");
169
170 if (!trace || !sc1 || !sc2 || !ec1 || !ec2 || !ec3) {
171 goto end;
172 }
173
174 set_trace_packet_header(trace);
175 set_stream_class_field_types(sc1);
176 set_stream_class_field_types(sc2);
177 ret = bt_ctf_stream_class_add_event_class(sc1, ec1);
178 if (ret) {
179 goto error;
180 }
181
182 ret = bt_ctf_stream_class_add_event_class(sc2, ec2);
183 if (ret) {
184 goto error;
185 }
186
187 ret = bt_ctf_stream_class_add_event_class(sc2, ec3);
188 if (ret) {
189 goto error;
190 }
191
192 ret = bt_ctf_trace_add_stream_class(trace, sc1);
193 if (ret) {
194 goto error;
195 }
196
197 ret = bt_ctf_trace_add_stream_class(trace, sc2);
198 if (ret) {
199 goto error;
200 }
201 end:
202 BT_PUT(sc1);
203 BT_PUT(sc2);
204 BT_PUT(ec1);
205 BT_PUT(ec2);
206 BT_PUT(ec3);
207 return trace;
208 error:
209 BT_PUT(trace);
210 goto end;
211 }
212
213 int visitor(struct bt_ctf_object *object, void *data)
214 {
215 int ret = 0;
216 bool names_match;
217 const char *object_name;
218 struct visitor_state *state = data;
219 struct expected_result *expected = &expected_results[state->i++];
220
221 switch (bt_ctf_object_get_type(object)) {
222 case BT_CTF_OBJECT_TYPE_TRACE:
223 object_name = NULL;
224 names_match = expected->object_name == NULL;
225 break;
226 case BT_CTF_OBJECT_TYPE_STREAM_CLASS:
227 object_name = bt_ctf_stream_class_get_name(
228 bt_ctf_object_get_object(object));
229 if (!object_name) {
230 ret = -1;
231 goto end;
232 }
233
234 names_match = !strcmp(object_name, expected->object_name);
235 break;
236 case BT_CTF_OBJECT_TYPE_EVENT_CLASS:
237 object_name = bt_ctf_event_class_get_name(
238 bt_ctf_object_get_object(object));
239 if (!object_name) {
240 ret = -1;
241 goto end;
242 }
243
244 names_match = !strcmp(object_name, expected->object_name);
245 break;
246 default:
247 diag("Encountered an unexpected type while visiting trace");
248 ret = -1;
249 goto end;
250 }
251
252 ok(expected->object_type == bt_ctf_object_get_type(object),
253 "Encoutered object type %s, expected %s",
254 object_type_str(expected->object_type),
255 object_type_str(bt_ctf_object_get_type(object)));
256 ok(names_match, "Element name is %s, expected %s",
257 object_name ? : "NULL",
258 expected->object_name ? : "NULL");
259 end:
260 return ret;
261 }
262
263 int main(int argc, char **argv)
264 {
265 int ret;
266 struct bt_ctf_trace *trace;
267 struct visitor_state state = { 0 };
268
269 plan_tests(NR_TESTS);
270
271 /*
272 * Initialize a reference trace which we'll walk using the
273 * bt_ctf_*_visit() interface.
274 */
275 trace = init_trace();
276 if (!trace) {
277 diag("Failed to initialize reference trace, aborting.");
278 exit(-1);
279 }
280
281 ret = bt_ctf_trace_visit(trace, visitor, &state);
282 ok(!ret, "bt_ctf_trace_visit returned success");
283
284 BT_PUT(trace);
285 return exit_status();
286 }
287
This page took 0.035557 seconds and 3 git commands to generate.