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