Cleanup: mixing enum types
[babeltrace.git] / tests / lib / test_plugin.c
1 /*
2 * test_plugin.c
3 *
4 * CTF IR Reference Count test
5 *
6 * Copyright (c) 2017 Philippe Proulx <pproulx@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 <babeltrace/plugin/plugin.h>
23 #include <babeltrace/ref.h>
24 #include <babeltrace/values.h>
25 #include <babeltrace/graph/component.h>
26 #include <babeltrace/graph/graph.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <stdio.h>
30 #include <assert.h>
31 #include <glib.h>
32 #include "tap/tap.h"
33 #include "common.h"
34
35 #define NR_TESTS 58
36 #define NON_EXISTING_PATH "/this/hopefully/does/not/exist/5bc75f8d-0dba-4043-a509-d7984b97e42b.so"
37
38 /* Those symbols are written to by some test plugins */
39 static int check_env_var(const char *name)
40 {
41 const char *val = getenv(name);
42
43 if (!val) {
44 return -1;
45 }
46
47 return atoi(val);
48 }
49
50 static void reset_test_plugin_env_vars(void)
51 {
52 g_setenv("BT_TEST_PLUGIN_INIT_CALLED", "0", 1);
53 g_setenv("BT_TEST_PLUGIN_EXIT_CALLED", "0", 1);
54 }
55
56 static char *get_test_plugin_path(const char *plugin_dir,
57 const char *plugin_name)
58 {
59 GString *path = g_string_new(plugin_dir);
60 char *ret;
61
62 assert(path);
63 g_string_append_printf(path, "/plugin-%s.so", plugin_name);
64 ret = path->str;
65 g_string_free(path, FALSE);
66 return ret;
67 }
68
69 static void test_invalid(const char *plugin_dir)
70 {
71 struct bt_plugin_set *plugin_set;
72
73 plugin_set = bt_plugin_create_all_from_file(NON_EXISTING_PATH);
74 ok(!plugin_set, "bt_plugin_create_all_from_file() fails with a non-existing file");
75
76 plugin_set = bt_plugin_create_all_from_file(plugin_dir);
77 ok(!plugin_set, "bt_plugin_create_all_from_file() fails with a directory");
78
79 ok(!bt_plugin_create_all_from_file(NULL),
80 "bt_plugin_create_all_from_file() handles NULL correctly");
81 ok(!bt_plugin_create_all_from_dir(NULL, BT_FALSE),
82 "bt_plugin_create_all_from_dir() handles NULL correctly");
83 ok(!bt_plugin_get_name(NULL),
84 "bt_plugin_get_name() handles NULL correctly");
85 ok(!bt_plugin_get_description(NULL),
86 "bt_plugin_get_description() handles NULL correctly");
87 ok(bt_plugin_get_version(NULL, NULL, NULL, NULL, NULL) !=
88 BT_PLUGIN_STATUS_OK,
89 "bt_plugin_get_version() handles NULL correctly");
90 ok(!bt_plugin_get_author(NULL),
91 "bt_plugin_get_author() handles NULL correctly");
92 ok(!bt_plugin_get_license(NULL),
93 "bt_plugin_get_license() handles NULL correctly");
94 ok(!bt_plugin_get_path(NULL),
95 "bt_plugin_get_path() handles NULL correctly");
96 ok(bt_plugin_get_component_class_count(NULL) < 0,
97 "bt_plugin_get_component_class_count() handles NULL correctly");
98 ok(!bt_plugin_get_component_class_by_index(NULL, 0),
99 "bt_plugin_get_component_class_by_index() handles NULL correctly");
100 ok(!bt_plugin_get_component_class_by_name_and_type(NULL, NULL, 0),
101 "bt_plugin_get_component_class_by_name_and_type() handles NULL correctly");
102 }
103
104 static void test_minimal(const char *plugin_dir)
105 {
106 struct bt_plugin_set *plugin_set;
107 struct bt_plugin *plugin;
108 char *minimal_path = get_test_plugin_path(plugin_dir, "minimal");
109
110 assert(minimal_path);
111 diag("minimal plugin test below");
112
113 reset_test_plugin_env_vars();
114 plugin_set = bt_plugin_create_all_from_file(minimal_path);
115 ok(plugin_set && bt_plugin_set_get_plugin_count(plugin_set) == 1,
116 "bt_plugin_create_all_from_file() succeeds with a valid file");
117 ok(check_env_var("BT_TEST_PLUGIN_INIT_CALLED") == 1,
118 "plugin's initialization function is called during bt_plugin_create_all_from_file()");
119 ok(bt_plugin_set_get_plugin_count(plugin_set) == 1,
120 "bt_plugin_create_all_from_file() returns the expected number of plugins");
121 plugin = bt_plugin_set_get_plugin(plugin_set, 0);
122 ok(strcmp(bt_plugin_get_name(plugin), "test_minimal") == 0,
123 "bt_plugin_get_name() returns the expected name");
124 ok(strcmp(bt_plugin_get_description(plugin),
125 "Minimal Babeltrace plugin with no component classes") == 0,
126 "bt_plugin_get_description() returns the expected description");
127 ok(bt_plugin_get_version(plugin, NULL, NULL, NULL, NULL) !=
128 BT_PLUGIN_STATUS_OK,
129 "bt_plugin_get_version() fails when there's no version");
130 ok(strcmp(bt_plugin_get_author(plugin), "Janine Sutto") == 0,
131 "bt_plugin_get_author() returns the expected author");
132 ok(strcmp(bt_plugin_get_license(plugin), "Beerware") == 0,
133 "bt_plugin_get_license() returns the expected license");
134 ok(strcmp(bt_plugin_get_path(plugin), minimal_path) == 0,
135 "bt_plugin_get_path() returns the expected path");
136 ok(bt_plugin_get_component_class_count(plugin) == 0,
137 "bt_plugin_get_component_class_count() returns the expected value");
138 bt_put(plugin);
139 bt_put(plugin_set);
140 ok(check_env_var("BT_TEST_PLUGIN_EXIT_CALLED") == 1,
141 "plugin's exit function is called when the plugin is destroyed");
142
143 free(minimal_path);
144 }
145
146 static void test_sfs(const char *plugin_dir)
147 {
148 struct bt_plugin_set *plugin_set;
149 struct bt_plugin *plugin;
150 struct bt_component_class *sink_comp_class;
151 struct bt_component_class *source_comp_class;
152 struct bt_component_class *filter_comp_class;
153 struct bt_component *sink_component;
154 char *sfs_path = get_test_plugin_path(plugin_dir, "sfs");
155 unsigned int major, minor, patch;
156 const char *extra;
157 struct bt_value *params;
158 struct bt_value *results;
159 struct bt_value *object;
160 struct bt_value *res_params;
161 struct bt_graph *graph;
162 const char *object_str;
163 enum bt_value_status value_ret;
164 enum bt_graph_status graph_ret;
165
166 assert(sfs_path);
167 diag("sfs plugin test below");
168
169 plugin_set = bt_plugin_create_all_from_file(sfs_path);
170 assert(plugin_set && bt_plugin_set_get_plugin_count(plugin_set) == 1);
171 plugin = bt_plugin_set_get_plugin(plugin_set, 0);
172 ok(bt_plugin_get_version(plugin, &major, &minor, &patch, &extra) ==
173 BT_PLUGIN_STATUS_OK,
174 "bt_plugin_get_version() succeeds when there's a version");
175 ok(major == 1,
176 "bt_plugin_get_version() returns the expected major version");
177 ok(minor == 2,
178 "bt_plugin_get_version() returns the expected minor version");
179 ok(patch == 3,
180 "bt_plugin_get_version() returns the expected patch version");
181 ok(strcmp(extra, "yes") == 0,
182 "bt_plugin_get_version() returns the expected extra version");
183 ok(bt_plugin_get_component_class_count(plugin) == 3,
184 "bt_plugin_get_component_class_count() returns the expected value");
185
186 source_comp_class = bt_plugin_get_component_class_by_name_and_type(
187 plugin, "source", BT_COMPONENT_CLASS_TYPE_SOURCE);
188 ok(source_comp_class,
189 "bt_plugin_get_component_class_by_name_and_type() finds a source component class");
190
191 sink_comp_class = bt_plugin_get_component_class_by_name_and_type(
192 plugin, "sink", BT_COMPONENT_CLASS_TYPE_SINK);
193 ok(sink_comp_class,
194 "bt_plugin_get_component_class_by_name_and_type() finds a sink component class");
195 ok(strcmp(bt_component_class_get_help(sink_comp_class),
196 "Bacon ipsum dolor amet strip steak cupim pastrami venison shoulder.\n"
197 "Prosciutto beef ribs flank meatloaf pancetta brisket kielbasa drumstick\n"
198 "venison tenderloin cow tail. Beef short loin shoulder meatball, sirloin\n"
199 "ground round brisket salami cupim pork bresaola turkey bacon boudin.\n") == 0,
200 "bt_component_class_get_help() returns the expected help text");
201
202 filter_comp_class = bt_plugin_get_component_class_by_name_and_type(
203 plugin, "filter", BT_COMPONENT_CLASS_TYPE_FILTER);
204 ok(filter_comp_class,
205 "bt_plugin_get_component_class_by_name_and_type() finds a filter component class");
206 ok(!bt_plugin_get_component_class_by_name_and_type(plugin, "filter",
207 BT_COMPONENT_CLASS_TYPE_SOURCE),
208 "bt_plugin_get_component_class_by_name_and_type() does not find a component class given the wrong type");
209 params = bt_value_integer_create_init(23);
210 assert(params);
211 ok (!bt_component_class_query(NULL, "get-something", params),
212 "bt_component_class_query() handles NULL (component class)");
213 ok (!bt_component_class_query(filter_comp_class, NULL, params),
214 "bt_component_class_query() handles NULL (object)");
215 ok (!bt_component_class_query(filter_comp_class, "get-something", NULL),
216 "bt_component_class_query() handles NULL (parameters)");
217 results = bt_component_class_query(filter_comp_class,
218 "get-something", params);
219 ok(results, "bt_component_class_query() succeeds");
220 assert(bt_value_is_array(results) && bt_value_array_size(results) == 2);
221 object = bt_value_array_get(results, 0);
222 assert(object && bt_value_is_string(object));
223 value_ret = bt_value_string_get(object, &object_str);
224 assert(value_ret == BT_VALUE_STATUS_OK);
225 ok(strcmp(object_str, "get-something") == 0,
226 "bt_component_class_query() receives the expected object name");
227 res_params = bt_value_array_get(results, 1);
228 ok(res_params == params,
229 "bt_component_class_query() receives the expected parameters");
230
231 diag("> putting the plugin object here");
232 BT_PUT(plugin);
233 graph = bt_graph_create();
234 assert(graph);
235 graph_ret = bt_graph_add_component(graph, sink_comp_class, "the-sink",
236 NULL, &sink_component);
237 ok(graph_ret == BT_GRAPH_STATUS_OK && sink_component,
238 "bt_graph_add_component() still works after the plugin object is destroyed");
239 BT_PUT(sink_component);
240 BT_PUT(source_comp_class);
241 bt_put(graph);
242 graph = bt_graph_create();
243 assert(graph);
244 graph_ret = bt_graph_add_component(graph, sink_comp_class, "the-sink",
245 NULL, &sink_component);
246 ok(graph_ret == BT_GRAPH_STATUS_OK && sink_component,
247 "bt_graph_add_component() still works after the source component class object is destroyed");
248 BT_PUT(sink_component);
249 BT_PUT(filter_comp_class);
250 bt_put(graph);
251 graph = bt_graph_create();
252 assert(graph);
253 graph_ret = bt_graph_add_component(graph, sink_comp_class, "the-sink",
254 NULL, &sink_component);
255 ok(graph_ret == BT_GRAPH_STATUS_OK && sink_component,
256 "bt_graph_add_component() still works after the filter component class object is destroyed");
257 BT_PUT(sink_comp_class);
258 BT_PUT(sink_component);
259
260 free(sfs_path);
261 bt_put(graph);
262 bt_put(plugin_set);
263 bt_put(object);
264 bt_put(res_params);
265 bt_put(results);
266 bt_put(params);
267 }
268
269 static void test_create_all_from_dir(const char *plugin_dir)
270 {
271 struct bt_plugin_set *plugin_set;
272
273 diag("create from all test below");
274
275 plugin_set = bt_plugin_create_all_from_dir(NON_EXISTING_PATH, BT_FALSE);
276 ok(!plugin_set,
277 "bt_plugin_create_all_from_dir() fails with an invalid path");
278
279 plugin_set = bt_plugin_create_all_from_dir(plugin_dir, BT_FALSE);
280 ok(plugin_set, "bt_plugin_create_all_from_dir() succeeds with a valid path");
281
282 /* 2 or 4, if `.la` files are considered or not */
283 ok(bt_plugin_set_get_plugin_count(plugin_set) == 2 ||
284 bt_plugin_set_get_plugin_count(plugin_set) == 4,
285 "bt_plugin_create_all_from_dir() returns the expected number of plugin objects");
286
287 bt_put(plugin_set);
288 }
289
290 static void test_find(const char *plugin_dir)
291 {
292 int ret;
293 struct bt_plugin *plugin;
294 struct bt_component_class *comp_cls_sink;
295 struct bt_component_class *comp_cls_source;
296 char *plugin_path;
297
298 ok(!bt_plugin_find(NULL),
299 "bt_plugin_find() handles NULL");
300 ok(!bt_plugin_find(NON_EXISTING_PATH),
301 "bt_plugin_find() returns NULL with an unknown plugin name");
302 ret = asprintf(&plugin_path, "%s:/ec1d09e5-696c-442e-b1c3-f9c6cf7f5958:::%s:8db46494-a398-466a-9649-c765ae077629:",
303 NON_EXISTING_PATH, plugin_dir);
304 assert(ret > 0 && plugin_path);
305 g_setenv("BABELTRACE_PLUGIN_PATH", plugin_path, 1);
306 plugin = bt_plugin_find("test_minimal");
307 ok(plugin,
308 "bt_plugin_find() succeeds with a plugin name it can find");
309 ok(strcmp(bt_plugin_get_author(plugin), "Janine Sutto") == 0,
310 "bt_plugin_find() finds the correct plugin for a given name");
311 BT_PUT(plugin);
312 comp_cls_sink = bt_plugin_find_component_class(NULL, "sink",
313 BT_COMPONENT_CLASS_TYPE_SINK);
314 ok(!comp_cls_sink, "bt_plugin_find_component_class() handles NULL (plugin name)");
315 comp_cls_sink = bt_plugin_find_component_class("test_sfs", NULL,
316 BT_COMPONENT_CLASS_TYPE_SINK);
317 ok(!comp_cls_sink, "bt_plugin_find_component_class() handles NULL (component class name)");
318 comp_cls_sink = bt_plugin_find_component_class("test_sfs", "sink2",
319 BT_COMPONENT_CLASS_TYPE_SINK);
320 ok(!comp_cls_sink, "bt_plugin_find_component_class() fails with an unknown component class name");
321 comp_cls_sink = bt_plugin_find_component_class("test_sfs", "sink",
322 BT_COMPONENT_CLASS_TYPE_SINK);
323 ok(comp_cls_sink, "bt_plugin_find_component_class() succeeds with valid parameters");
324 ok(strcmp(bt_component_class_get_name(comp_cls_sink), "sink") == 0,
325 "bt_plugin_find_component_class() returns the appropriate component class (sink)");
326 comp_cls_source = bt_plugin_find_component_class("test_sfs", "source",
327 BT_COMPONENT_CLASS_TYPE_SOURCE);
328 ok(comp_cls_sink, "bt_plugin_find_component_class() succeeds with another component class name (same plugin)");
329 ok(strcmp(bt_component_class_get_name(comp_cls_source), "source") == 0,
330 "bt_plugin_find_component_class() returns the appropriate component class (source)");
331 BT_PUT(comp_cls_sink);
332 BT_PUT(comp_cls_source);
333 free(plugin_path);
334 }
335
336 int main(int argc, char **argv)
337 {
338 int ret;
339 const char *plugin_dir;
340
341 if (argc != 2) {
342 puts("Usage: test_plugin plugin_directory");
343 ret = 1;
344 goto end;
345 }
346
347 plugin_dir = argv[1];
348 plan_tests(NR_TESTS);
349 test_invalid(plugin_dir);
350 test_minimal(plugin_dir);
351 test_sfs(plugin_dir);
352 test_create_all_from_dir(plugin_dir);
353 test_find(plugin_dir);
354 ret = exit_status();
355 end:
356 return ret;
357 }
This page took 0.038066 seconds and 4 git commands to generate.