Port: replace setenv() by g_setenv()
[babeltrace.git] / tests / lib / test_plugin.c
CommitLineData
cbb9e0b1
PP
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>
cc469c42 25#include <babeltrace/graph/component.h>
36712f1d 26#include <babeltrace/graph/graph.h>
cbb9e0b1
PP
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
2b43acf9 35#define NR_TESTS 58
cbb9e0b1
PP
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 */
df5b5d01
PP
39static 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}
cbb9e0b1 49
df5b5d01 50static void reset_test_plugin_env_vars(void)
cbb9e0b1 51{
fbb2f0da
MJ
52 g_setenv("BT_TEST_PLUGIN_INIT_CALLED", "0", 1);
53 g_setenv("BT_TEST_PLUGIN_EXIT_CALLED", "0", 1);
cbb9e0b1
PP
54}
55
56static 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
69static void test_invalid(const char *plugin_dir)
70{
a8ff38ef 71 struct bt_plugin_set *plugin_set;
cbb9e0b1 72
a8ff38ef
PP
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");
cbb9e0b1 75
a8ff38ef
PP
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");
cbb9e0b1 78
6ba0b073
PP
79 ok(!bt_plugin_create_all_from_file(NULL),
80 "bt_plugin_create_all_from_file() handles NULL correctly");
c55a9f58 81 ok(!bt_plugin_create_all_from_dir(NULL, BT_FALSE),
cbb9e0b1
PP
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");
458e8e1d
PP
87 ok(bt_plugin_get_version(NULL, NULL, NULL, NULL, NULL) !=
88 BT_PLUGIN_STATUS_OK,
89 "bt_plugin_get_version() handles NULL correctly");
cbb9e0b1
PP
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");
9ac68eb1
PP
98 ok(!bt_plugin_get_component_class_by_index(NULL, 0),
99 "bt_plugin_get_component_class_by_index() handles NULL correctly");
cbb9e0b1
PP
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");
cbb9e0b1
PP
102}
103
104static void test_minimal(const char *plugin_dir)
105{
a8ff38ef 106 struct bt_plugin_set *plugin_set;
cbb9e0b1
PP
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
df5b5d01 113 reset_test_plugin_env_vars();
a8ff38ef
PP
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");
df5b5d01
PP
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()");
a8ff38ef 119 ok(bt_plugin_set_get_plugin_count(plugin_set) == 1,
6ba0b073 120 "bt_plugin_create_all_from_file() returns the expected number of plugins");
a8ff38ef 121 plugin = bt_plugin_set_get_plugin(plugin_set, 0);
6ba0b073 122 ok(strcmp(bt_plugin_get_name(plugin), "test_minimal") == 0,
cbb9e0b1
PP
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");
458e8e1d
PP
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");
cbb9e0b1
PP
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");
a8ff38ef
PP
138 bt_put(plugin);
139 bt_put(plugin_set);
df5b5d01
PP
140 ok(check_env_var("BT_TEST_PLUGIN_EXIT_CALLED") == 1,
141 "plugin's exit function is called when the plugin is destroyed");
cbb9e0b1
PP
142
143 free(minimal_path);
144}
145
146static void test_sfs(const char *plugin_dir)
147{
a8ff38ef 148 struct bt_plugin_set *plugin_set;
cbb9e0b1
PP
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");
458e8e1d
PP
155 unsigned int major, minor, patch;
156 const char *extra;
5933c0f2
PP
157 struct bt_value *params;
158 struct bt_value *results;
a67681c1 159 struct bt_value *object;
5933c0f2 160 struct bt_value *res_params;
36712f1d 161 struct bt_graph *graph;
a67681c1 162 const char *object_str;
5933c0f2 163 int ret;
cbb9e0b1
PP
164
165 assert(sfs_path);
166 diag("sfs plugin test below");
167
a8ff38ef
PP
168 plugin_set = bt_plugin_create_all_from_file(sfs_path);
169 assert(plugin_set && bt_plugin_set_get_plugin_count(plugin_set) == 1);
170 plugin = bt_plugin_set_get_plugin(plugin_set, 0);
458e8e1d
PP
171 ok(bt_plugin_get_version(plugin, &major, &minor, &patch, &extra) ==
172 BT_PLUGIN_STATUS_OK,
173 "bt_plugin_get_version() succeeds when there's a version");
174 ok(major == 1,
175 "bt_plugin_get_version() returns the expected major version");
176 ok(minor == 2,
177 "bt_plugin_get_version() returns the expected minor version");
178 ok(patch == 3,
179 "bt_plugin_get_version() returns the expected patch version");
180 ok(strcmp(extra, "yes") == 0,
181 "bt_plugin_get_version() returns the expected extra version");
cbb9e0b1
PP
182 ok(bt_plugin_get_component_class_count(plugin) == 3,
183 "bt_plugin_get_component_class_count() returns the expected value");
184
185 source_comp_class = bt_plugin_get_component_class_by_name_and_type(
d3e4dcd8 186 plugin, "source", BT_COMPONENT_CLASS_TYPE_SOURCE);
cbb9e0b1
PP
187 ok(source_comp_class,
188 "bt_plugin_get_component_class_by_name_and_type() finds a source component class");
189
190 sink_comp_class = bt_plugin_get_component_class_by_name_and_type(
d3e4dcd8 191 plugin, "sink", BT_COMPONENT_CLASS_TYPE_SINK);
cbb9e0b1
PP
192 ok(sink_comp_class,
193 "bt_plugin_get_component_class_by_name_and_type() finds a sink component class");
a889b89f
PP
194 ok(strcmp(bt_component_class_get_help(sink_comp_class),
195 "Bacon ipsum dolor amet strip steak cupim pastrami venison shoulder.\n"
196 "Prosciutto beef ribs flank meatloaf pancetta brisket kielbasa drumstick\n"
197 "venison tenderloin cow tail. Beef short loin shoulder meatball, sirloin\n"
198 "ground round brisket salami cupim pork bresaola turkey bacon boudin.\n") == 0,
199 "bt_component_class_get_help() returns the expected help text");
200
cbb9e0b1 201 filter_comp_class = bt_plugin_get_component_class_by_name_and_type(
d3e4dcd8 202 plugin, "filter", BT_COMPONENT_CLASS_TYPE_FILTER);
cbb9e0b1
PP
203 ok(filter_comp_class,
204 "bt_plugin_get_component_class_by_name_and_type() finds a filter component class");
205 ok(!bt_plugin_get_component_class_by_name_and_type(plugin, "filter",
d3e4dcd8 206 BT_COMPONENT_CLASS_TYPE_SOURCE),
cbb9e0b1 207 "bt_plugin_get_component_class_by_name_and_type() does not find a component class given the wrong type");
5933c0f2
PP
208 params = bt_value_integer_create_init(23);
209 assert(params);
a67681c1
PP
210 ok (!bt_component_class_query(NULL, "get-something", params),
211 "bt_component_class_query() handles NULL (component class)");
212 ok (!bt_component_class_query(filter_comp_class, NULL, params),
213 "bt_component_class_query() handles NULL (object)");
214 ok (!bt_component_class_query(filter_comp_class, "get-something", NULL),
215 "bt_component_class_query() handles NULL (parameters)");
216 results = bt_component_class_query(filter_comp_class,
5933c0f2 217 "get-something", params);
a67681c1 218 ok(results, "bt_component_class_query() succeeds");
5933c0f2 219 assert(bt_value_is_array(results) && bt_value_array_size(results) == 2);
a67681c1
PP
220 object = bt_value_array_get(results, 0);
221 assert(object && bt_value_is_string(object));
222 ret = bt_value_string_get(object, &object_str);
5933c0f2 223 assert(ret == 0);
a67681c1
PP
224 ok(strcmp(object_str, "get-something") == 0,
225 "bt_component_class_query() receives the expected object name");
5933c0f2
PP
226 res_params = bt_value_array_get(results, 1);
227 ok(res_params == params,
a67681c1 228 "bt_component_class_query() receives the expected parameters");
cbb9e0b1
PP
229
230 diag("> putting the plugin object here");
231 BT_PUT(plugin);
36712f1d
PP
232 graph = bt_graph_create();
233 assert(graph);
234 ret = bt_graph_add_component(graph, sink_comp_class, "the-sink", NULL,
235 &sink_component);
236 ok(ret == 0 && sink_component,
237 "bt_graph_add_component() still works after the plugin object is destroyed");
cbb9e0b1
PP
238 BT_PUT(sink_component);
239 BT_PUT(source_comp_class);
36712f1d
PP
240 bt_put(graph);
241 graph = bt_graph_create();
242 assert(graph);
243 ret = bt_graph_add_component(graph, sink_comp_class, "the-sink", NULL,
244 &sink_component);
245 ok(ret == 0 && sink_component,
246 "bt_graph_add_component() still works after the source component class object is destroyed");
cbb9e0b1
PP
247 BT_PUT(sink_component);
248 BT_PUT(filter_comp_class);
36712f1d
PP
249 bt_put(graph);
250 graph = bt_graph_create();
251 assert(graph);
252 ret = bt_graph_add_component(graph, sink_comp_class, "the-sink", NULL,
253 &sink_component);
254 ok(ret == 0 && sink_component,
255 "bt_graph_add_component() still works after the filter component class object is destroyed");
cbb9e0b1
PP
256 BT_PUT(sink_comp_class);
257 BT_PUT(sink_component);
258
259 free(sfs_path);
36712f1d 260 bt_put(graph);
a8ff38ef 261 bt_put(plugin_set);
a67681c1 262 bt_put(object);
5933c0f2
PP
263 bt_put(res_params);
264 bt_put(results);
265 bt_put(params);
cbb9e0b1
PP
266}
267
268static void test_create_all_from_dir(const char *plugin_dir)
269{
a8ff38ef 270 struct bt_plugin_set *plugin_set;
cbb9e0b1
PP
271
272 diag("create from all test below");
273
c55a9f58 274 plugin_set = bt_plugin_create_all_from_dir(NON_EXISTING_PATH, BT_FALSE);
a8ff38ef 275 ok(!plugin_set,
cbb9e0b1
PP
276 "bt_plugin_create_all_from_dir() fails with an invalid path");
277
c55a9f58 278 plugin_set = bt_plugin_create_all_from_dir(plugin_dir, BT_FALSE);
a8ff38ef 279 ok(plugin_set, "bt_plugin_create_all_from_dir() succeeds with a valid path");
cbb9e0b1
PP
280
281 /* 2 or 4, if `.la` files are considered or not */
a8ff38ef
PP
282 ok(bt_plugin_set_get_plugin_count(plugin_set) == 2 ||
283 bt_plugin_set_get_plugin_count(plugin_set) == 4,
284 "bt_plugin_create_all_from_dir() returns the expected number of plugin objects");
cbb9e0b1 285
a8ff38ef 286 bt_put(plugin_set);
cbb9e0b1
PP
287}
288
2b43acf9 289static void test_find(const char *plugin_dir)
a8b3f23b 290{
8a6001c5 291 int ret;
a8b3f23b 292 struct bt_plugin *plugin;
2b43acf9
PP
293 struct bt_component_class *comp_cls_sink;
294 struct bt_component_class *comp_cls_source;
a8b3f23b
PP
295 char *plugin_path;
296
2b43acf9
PP
297 ok(!bt_plugin_find(NULL),
298 "bt_plugin_find() handles NULL");
299 ok(!bt_plugin_find(NON_EXISTING_PATH),
300 "bt_plugin_find() returns NULL with an unknown plugin name");
8a6001c5 301 ret = asprintf(&plugin_path, "%s:/ec1d09e5-696c-442e-b1c3-f9c6cf7f5958:::%s:8db46494-a398-466a-9649-c765ae077629:",
a8b3f23b 302 NON_EXISTING_PATH, plugin_dir);
8a6001c5 303 assert(ret > 0 && plugin_path);
aacfaf40 304 g_setenv("BABELTRACE_PLUGIN_PATH", plugin_path, 1);
2b43acf9 305 plugin = bt_plugin_find("test_minimal");
a8b3f23b 306 ok(plugin,
2b43acf9 307 "bt_plugin_find() succeeds with a plugin name it can find");
a8b3f23b 308 ok(strcmp(bt_plugin_get_author(plugin), "Janine Sutto") == 0,
2b43acf9 309 "bt_plugin_find() finds the correct plugin for a given name");
a8b3f23b 310 BT_PUT(plugin);
2b43acf9
PP
311 comp_cls_sink = bt_plugin_find_component_class(NULL, "sink",
312 BT_COMPONENT_CLASS_TYPE_SINK);
313 ok(!comp_cls_sink, "bt_plugin_find_component_class() handles NULL (plugin name)");
314 comp_cls_sink = bt_plugin_find_component_class("test_sfs", NULL,
315 BT_COMPONENT_CLASS_TYPE_SINK);
316 ok(!comp_cls_sink, "bt_plugin_find_component_class() handles NULL (component class name)");
317 comp_cls_sink = bt_plugin_find_component_class("test_sfs", "sink2",
318 BT_COMPONENT_CLASS_TYPE_SINK);
319 ok(!comp_cls_sink, "bt_plugin_find_component_class() fails with an unknown component class name");
320 comp_cls_sink = bt_plugin_find_component_class("test_sfs", "sink",
321 BT_COMPONENT_CLASS_TYPE_SINK);
322 ok(comp_cls_sink, "bt_plugin_find_component_class() succeeds with valid parameters");
323 ok(strcmp(bt_component_class_get_name(comp_cls_sink), "sink") == 0,
324 "bt_plugin_find_component_class() returns the appropriate component class (sink)");
325 comp_cls_source = bt_plugin_find_component_class("test_sfs", "source",
326 BT_COMPONENT_CLASS_TYPE_SOURCE);
327 ok(comp_cls_sink, "bt_plugin_find_component_class() succeeds with another component class name (same plugin)");
328 ok(strcmp(bt_component_class_get_name(comp_cls_source), "source") == 0,
329 "bt_plugin_find_component_class() returns the appropriate component class (source)");
330 BT_PUT(comp_cls_sink);
331 BT_PUT(comp_cls_source);
a8b3f23b
PP
332 free(plugin_path);
333}
334
cbb9e0b1
PP
335int main(int argc, char **argv)
336{
337 int ret;
338 const char *plugin_dir;
339
340 if (argc != 2) {
341 puts("Usage: test_plugin plugin_directory");
342 ret = 1;
343 goto end;
344 }
345
346 plugin_dir = argv[1];
347 plan_tests(NR_TESTS);
348 test_invalid(plugin_dir);
349 test_minimal(plugin_dir);
350 test_sfs(plugin_dir);
351 test_create_all_from_dir(plugin_dir);
2b43acf9 352 test_find(plugin_dir);
cbb9e0b1
PP
353 ret = exit_status();
354end:
355 return ret;
356}
This page took 0.046452 seconds and 4 git commands to generate.