lib: private functions: do not repeat `private` word
[babeltrace.git] / tests / lib / test_plugin.c
CommitLineData
cbb9e0b1 1/*
cbb9e0b1
PP
2 * Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; under version 2 of the License.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
16 */
17
18#include <babeltrace/plugin/plugin.h>
8138bfe1 19#include <babeltrace/object.h>
cbb9e0b1 20#include <babeltrace/values.h>
17582c6d 21#include <babeltrace/private-values.h>
cc469c42 22#include <babeltrace/graph/component.h>
8d750b42 23#include <babeltrace/graph/private-graph.h>
36712f1d 24#include <babeltrace/graph/graph.h>
1286dcbb 25#include <babeltrace/graph/query-executor.h>
cbb9e0b1
PP
26#include <stdlib.h>
27#include <string.h>
28#include <stdio.h>
b8f13b8b 29#include <babeltrace/assert-internal.h>
cbb9e0b1
PP
30#include <glib.h>
31#include "tap/tap.h"
32#include "common.h"
33
2b43acf9 34#define NR_TESTS 58
cbb9e0b1
PP
35#define NON_EXISTING_PATH "/this/hopefully/does/not/exist/5bc75f8d-0dba-4043-a509-d7984b97e42b.so"
36
37/* Those symbols are written to by some test plugins */
edb2ec3c
PP
38static int check_env_var(const char *name)
39{
40 const char *val = getenv(name);
41
42 if (!val) {
43 return -1;
44 }
45
46 return atoi(val);
47}
cbb9e0b1 48
edb2ec3c 49static void reset_test_plugin_env_vars(void)
cbb9e0b1 50{
9be5a6e6
MJ
51 g_setenv("BT_TEST_PLUGIN_INIT_CALLED", "0", 1);
52 g_setenv("BT_TEST_PLUGIN_EXIT_CALLED", "0", 1);
cbb9e0b1
PP
53}
54
55static char *get_test_plugin_path(const char *plugin_dir,
56 const char *plugin_name)
57{
cbb9e0b1 58 char *ret;
d85ff846
MJ
59 char *plugin_file_name;
60
61 if (asprintf(&plugin_file_name, "plugin-%s." G_MODULE_SUFFIX,
62 plugin_name) == -1) {
63 abort();
64 }
65
66 ret = g_build_filename(plugin_dir, plugin_file_name, NULL);
67 free(plugin_file_name);
cbb9e0b1 68
cbb9e0b1
PP
69 return ret;
70}
71
72static void test_invalid(const char *plugin_dir)
73{
a8ff38ef 74 struct bt_plugin_set *plugin_set;
cbb9e0b1 75
d85ff846
MJ
76 diag("invalid plugin test below");
77
a8ff38ef
PP
78 plugin_set = bt_plugin_create_all_from_file(NON_EXISTING_PATH);
79 ok(!plugin_set, "bt_plugin_create_all_from_file() fails with a non-existing file");
cbb9e0b1 80
a8ff38ef
PP
81 plugin_set = bt_plugin_create_all_from_file(plugin_dir);
82 ok(!plugin_set, "bt_plugin_create_all_from_file() fails with a directory");
cbb9e0b1 83
6ba0b073
PP
84 ok(!bt_plugin_create_all_from_file(NULL),
85 "bt_plugin_create_all_from_file() handles NULL correctly");
c55a9f58 86 ok(!bt_plugin_create_all_from_dir(NULL, BT_FALSE),
cbb9e0b1
PP
87 "bt_plugin_create_all_from_dir() handles NULL correctly");
88 ok(!bt_plugin_get_name(NULL),
89 "bt_plugin_get_name() handles NULL correctly");
90 ok(!bt_plugin_get_description(NULL),
91 "bt_plugin_get_description() handles NULL correctly");
458e8e1d
PP
92 ok(bt_plugin_get_version(NULL, NULL, NULL, NULL, NULL) !=
93 BT_PLUGIN_STATUS_OK,
94 "bt_plugin_get_version() handles NULL correctly");
cbb9e0b1
PP
95 ok(!bt_plugin_get_author(NULL),
96 "bt_plugin_get_author() handles NULL correctly");
97 ok(!bt_plugin_get_license(NULL),
98 "bt_plugin_get_license() handles NULL correctly");
99 ok(!bt_plugin_get_path(NULL),
100 "bt_plugin_get_path() handles NULL correctly");
101 ok(bt_plugin_get_component_class_count(NULL) < 0,
102 "bt_plugin_get_component_class_count() handles NULL correctly");
9ac68eb1
PP
103 ok(!bt_plugin_get_component_class_by_index(NULL, 0),
104 "bt_plugin_get_component_class_by_index() handles NULL correctly");
cbb9e0b1
PP
105 ok(!bt_plugin_get_component_class_by_name_and_type(NULL, NULL, 0),
106 "bt_plugin_get_component_class_by_name_and_type() handles NULL correctly");
cbb9e0b1
PP
107}
108
109static void test_minimal(const char *plugin_dir)
110{
a8ff38ef 111 struct bt_plugin_set *plugin_set;
cbb9e0b1
PP
112 struct bt_plugin *plugin;
113 char *minimal_path = get_test_plugin_path(plugin_dir, "minimal");
114
b8f13b8b 115 BT_ASSERT(minimal_path);
cbb9e0b1
PP
116 diag("minimal plugin test below");
117
edb2ec3c 118 reset_test_plugin_env_vars();
a8ff38ef
PP
119 plugin_set = bt_plugin_create_all_from_file(minimal_path);
120 ok(plugin_set && bt_plugin_set_get_plugin_count(plugin_set) == 1,
121 "bt_plugin_create_all_from_file() succeeds with a valid file");
edb2ec3c
PP
122 ok(check_env_var("BT_TEST_PLUGIN_INIT_CALLED") == 1,
123 "plugin's initialization function is called during bt_plugin_create_all_from_file()");
a8ff38ef 124 ok(bt_plugin_set_get_plugin_count(plugin_set) == 1,
6ba0b073 125 "bt_plugin_create_all_from_file() returns the expected number of plugins");
a8ff38ef 126 plugin = bt_plugin_set_get_plugin(plugin_set, 0);
6ba0b073 127 ok(strcmp(bt_plugin_get_name(plugin), "test_minimal") == 0,
cbb9e0b1
PP
128 "bt_plugin_get_name() returns the expected name");
129 ok(strcmp(bt_plugin_get_description(plugin),
130 "Minimal Babeltrace plugin with no component classes") == 0,
131 "bt_plugin_get_description() returns the expected description");
458e8e1d
PP
132 ok(bt_plugin_get_version(plugin, NULL, NULL, NULL, NULL) !=
133 BT_PLUGIN_STATUS_OK,
134 "bt_plugin_get_version() fails when there's no version");
cbb9e0b1
PP
135 ok(strcmp(bt_plugin_get_author(plugin), "Janine Sutto") == 0,
136 "bt_plugin_get_author() returns the expected author");
137 ok(strcmp(bt_plugin_get_license(plugin), "Beerware") == 0,
138 "bt_plugin_get_license() returns the expected license");
139 ok(strcmp(bt_plugin_get_path(plugin), minimal_path) == 0,
140 "bt_plugin_get_path() returns the expected path");
141 ok(bt_plugin_get_component_class_count(plugin) == 0,
142 "bt_plugin_get_component_class_count() returns the expected value");
8138bfe1
PP
143 bt_object_put_ref(plugin);
144 bt_object_put_ref(plugin_set);
edb2ec3c
PP
145 ok(check_env_var("BT_TEST_PLUGIN_EXIT_CALLED") == 1,
146 "plugin's exit function is called when the plugin is destroyed");
cbb9e0b1
PP
147
148 free(minimal_path);
149}
150
151static void test_sfs(const char *plugin_dir)
152{
a8ff38ef 153 struct bt_plugin_set *plugin_set;
cbb9e0b1
PP
154 struct bt_plugin *plugin;
155 struct bt_component_class *sink_comp_class;
156 struct bt_component_class *source_comp_class;
157 struct bt_component_class *filter_comp_class;
158 struct bt_component *sink_component;
159 char *sfs_path = get_test_plugin_path(plugin_dir, "sfs");
458e8e1d
PP
160 unsigned int major, minor, patch;
161 const char *extra;
17582c6d 162 struct bt_private_value *params;
5933c0f2 163 struct bt_value *results;
a67681c1 164 struct bt_value *object;
5933c0f2 165 struct bt_value *res_params;
8d750b42 166 struct bt_private_graph *graph;
a67681c1 167 const char *object_str;
0d1e5c85 168 enum bt_graph_status graph_ret;
1286dcbb
PP
169 struct bt_query_executor *query_exec = bt_query_executor_create();
170 int ret;
cbb9e0b1 171
b8f13b8b
PP
172 BT_ASSERT(query_exec);
173 BT_ASSERT(sfs_path);
cbb9e0b1
PP
174 diag("sfs plugin test below");
175
a8ff38ef 176 plugin_set = bt_plugin_create_all_from_file(sfs_path);
b8f13b8b 177 BT_ASSERT(plugin_set && bt_plugin_set_get_plugin_count(plugin_set) == 1);
a8ff38ef 178 plugin = bt_plugin_set_get_plugin(plugin_set, 0);
458e8e1d
PP
179 ok(bt_plugin_get_version(plugin, &major, &minor, &patch, &extra) ==
180 BT_PLUGIN_STATUS_OK,
181 "bt_plugin_get_version() succeeds when there's a version");
182 ok(major == 1,
183 "bt_plugin_get_version() returns the expected major version");
184 ok(minor == 2,
185 "bt_plugin_get_version() returns the expected minor version");
186 ok(patch == 3,
187 "bt_plugin_get_version() returns the expected patch version");
188 ok(strcmp(extra, "yes") == 0,
189 "bt_plugin_get_version() returns the expected extra version");
cbb9e0b1
PP
190 ok(bt_plugin_get_component_class_count(plugin) == 3,
191 "bt_plugin_get_component_class_count() returns the expected value");
192
193 source_comp_class = bt_plugin_get_component_class_by_name_and_type(
d3e4dcd8 194 plugin, "source", BT_COMPONENT_CLASS_TYPE_SOURCE);
cbb9e0b1
PP
195 ok(source_comp_class,
196 "bt_plugin_get_component_class_by_name_and_type() finds a source component class");
197
198 sink_comp_class = bt_plugin_get_component_class_by_name_and_type(
d3e4dcd8 199 plugin, "sink", BT_COMPONENT_CLASS_TYPE_SINK);
cbb9e0b1
PP
200 ok(sink_comp_class,
201 "bt_plugin_get_component_class_by_name_and_type() finds a sink component class");
a889b89f
PP
202 ok(strcmp(bt_component_class_get_help(sink_comp_class),
203 "Bacon ipsum dolor amet strip steak cupim pastrami venison shoulder.\n"
204 "Prosciutto beef ribs flank meatloaf pancetta brisket kielbasa drumstick\n"
205 "venison tenderloin cow tail. Beef short loin shoulder meatball, sirloin\n"
206 "ground round brisket salami cupim pork bresaola turkey bacon boudin.\n") == 0,
207 "bt_component_class_get_help() returns the expected help text");
208
cbb9e0b1 209 filter_comp_class = bt_plugin_get_component_class_by_name_and_type(
d3e4dcd8 210 plugin, "filter", BT_COMPONENT_CLASS_TYPE_FILTER);
cbb9e0b1
PP
211 ok(filter_comp_class,
212 "bt_plugin_get_component_class_by_name_and_type() finds a filter component class");
213 ok(!bt_plugin_get_component_class_by_name_and_type(plugin, "filter",
d3e4dcd8 214 BT_COMPONENT_CLASS_TYPE_SOURCE),
cbb9e0b1 215 "bt_plugin_get_component_class_by_name_and_type() does not find a component class given the wrong type");
17582c6d 216 params = bt_private_value_integer_create_init(23);
b8f13b8b 217 BT_ASSERT(params);
1286dcbb 218 ret = bt_query_executor_query(NULL, filter_comp_class, "object",
17582c6d 219 bt_value_borrow_from_private(params), &results);
1286dcbb
PP
220 ok (ret, "bt_query_executor_query() handles NULL (query executor)");
221 ret = bt_query_executor_query(query_exec, NULL, "object",
17582c6d 222 bt_value_borrow_from_private(params), &results);
1286dcbb
PP
223 ok (ret, "bt_query_executor_query() handles NULL (component class)");
224 ret = bt_query_executor_query(query_exec, filter_comp_class, NULL,
17582c6d 225 bt_value_borrow_from_private(params), &results);
1286dcbb
PP
226 ok (ret, "bt_query_executor_query() handles NULL (object)");
227 ret = bt_query_executor_query(query_exec, filter_comp_class,
17582c6d
PP
228 "get-something", bt_value_borrow_from_private(params),
229 &results);
1286dcbb 230 ok(ret == 0 && results, "bt_query_executor_query() succeeds");
44514773
PP
231 BT_ASSERT(bt_value_is_array(results) && bt_value_array_get_size(results) == 2);
232 object = bt_value_array_borrow_element_by_index(results, 0);
b8f13b8b 233 BT_ASSERT(object && bt_value_is_string(object));
b5cdc106 234 object_str = bt_value_string_get(object);
a67681c1
PP
235 ok(strcmp(object_str, "get-something") == 0,
236 "bt_component_class_query() receives the expected object name");
44514773 237 res_params = bt_value_array_borrow_element_by_index(results, 1);
17582c6d 238 ok(res_params == bt_value_borrow_from_private(params),
a67681c1 239 "bt_component_class_query() receives the expected parameters");
cbb9e0b1
PP
240
241 diag("> putting the plugin object here");
8138bfe1 242 BT_OBJECT_PUT_REF_AND_RESET(plugin);
8d750b42 243 graph = bt_private_graph_create();
b8f13b8b 244 BT_ASSERT(graph);
8d750b42 245 graph_ret = bt_private_graph_add_component(graph, sink_comp_class, "the-sink",
0d1e5c85
MD
246 NULL, &sink_component);
247 ok(graph_ret == BT_GRAPH_STATUS_OK && sink_component,
8d750b42 248 "bt_private_graph_add_component() still works after the plugin object is destroyed");
8138bfe1
PP
249 BT_OBJECT_PUT_REF_AND_RESET(sink_component);
250 BT_OBJECT_PUT_REF_AND_RESET(source_comp_class);
251 bt_object_put_ref(graph);
8d750b42 252 graph = bt_private_graph_create();
b8f13b8b 253 BT_ASSERT(graph);
8d750b42 254 graph_ret = bt_private_graph_add_component(graph, sink_comp_class, "the-sink",
0d1e5c85
MD
255 NULL, &sink_component);
256 ok(graph_ret == BT_GRAPH_STATUS_OK && sink_component,
8d750b42 257 "bt_private_graph_add_component() still works after the source component class object is destroyed");
8138bfe1
PP
258 BT_OBJECT_PUT_REF_AND_RESET(sink_component);
259 BT_OBJECT_PUT_REF_AND_RESET(filter_comp_class);
260 bt_object_put_ref(graph);
8d750b42 261 graph = bt_private_graph_create();
b8f13b8b 262 BT_ASSERT(graph);
8d750b42 263 graph_ret = bt_private_graph_add_component(graph, sink_comp_class, "the-sink",
0d1e5c85
MD
264 NULL, &sink_component);
265 ok(graph_ret == BT_GRAPH_STATUS_OK && sink_component,
8d750b42 266 "bt_private_graph_add_component() still works after the filter component class object is destroyed");
8138bfe1
PP
267 BT_OBJECT_PUT_REF_AND_RESET(sink_comp_class);
268 BT_OBJECT_PUT_REF_AND_RESET(sink_component);
cbb9e0b1
PP
269
270 free(sfs_path);
8138bfe1
PP
271 bt_object_put_ref(graph);
272 bt_object_put_ref(plugin_set);
273 bt_object_put_ref(results);
274 bt_object_put_ref(params);
275 bt_object_put_ref(query_exec);
cbb9e0b1
PP
276}
277
278static void test_create_all_from_dir(const char *plugin_dir)
279{
a8ff38ef 280 struct bt_plugin_set *plugin_set;
cbb9e0b1
PP
281
282 diag("create from all test below");
283
c55a9f58 284 plugin_set = bt_plugin_create_all_from_dir(NON_EXISTING_PATH, BT_FALSE);
a8ff38ef 285 ok(!plugin_set,
cbb9e0b1
PP
286 "bt_plugin_create_all_from_dir() fails with an invalid path");
287
c55a9f58 288 plugin_set = bt_plugin_create_all_from_dir(plugin_dir, BT_FALSE);
a8ff38ef 289 ok(plugin_set, "bt_plugin_create_all_from_dir() succeeds with a valid path");
cbb9e0b1
PP
290
291 /* 2 or 4, if `.la` files are considered or not */
a8ff38ef
PP
292 ok(bt_plugin_set_get_plugin_count(plugin_set) == 2 ||
293 bt_plugin_set_get_plugin_count(plugin_set) == 4,
294 "bt_plugin_create_all_from_dir() returns the expected number of plugin objects");
cbb9e0b1 295
8138bfe1 296 bt_object_put_ref(plugin_set);
cbb9e0b1
PP
297}
298
2b43acf9 299static void test_find(const char *plugin_dir)
a8b3f23b 300{
4a7062f7 301 int ret;
a8b3f23b 302 struct bt_plugin *plugin;
2b43acf9
PP
303 struct bt_component_class *comp_cls_sink;
304 struct bt_component_class *comp_cls_source;
a8b3f23b
PP
305 char *plugin_path;
306
2b43acf9
PP
307 ok(!bt_plugin_find(NULL),
308 "bt_plugin_find() handles NULL");
309 ok(!bt_plugin_find(NON_EXISTING_PATH),
310 "bt_plugin_find() returns NULL with an unknown plugin name");
d85ff846
MJ
311 ret = asprintf(&plugin_path, "%s" G_SEARCHPATH_SEPARATOR_S
312 G_DIR_SEPARATOR_S "ec1d09e5-696c-442e-b1c3-f9c6cf7f5958"
313 G_SEARCHPATH_SEPARATOR_S G_SEARCHPATH_SEPARATOR_S
314 G_SEARCHPATH_SEPARATOR_S "%s" G_SEARCHPATH_SEPARATOR_S
315 "8db46494-a398-466a-9649-c765ae077629"
316 G_SEARCHPATH_SEPARATOR_S,
a8b3f23b 317 NON_EXISTING_PATH, plugin_dir);
b8f13b8b 318 BT_ASSERT(ret > 0 && plugin_path);
aacfaf40 319 g_setenv("BABELTRACE_PLUGIN_PATH", plugin_path, 1);
2b43acf9 320 plugin = bt_plugin_find("test_minimal");
a8b3f23b 321 ok(plugin,
2b43acf9 322 "bt_plugin_find() succeeds with a plugin name it can find");
a8b3f23b 323 ok(strcmp(bt_plugin_get_author(plugin), "Janine Sutto") == 0,
2b43acf9 324 "bt_plugin_find() finds the correct plugin for a given name");
8138bfe1 325 BT_OBJECT_PUT_REF_AND_RESET(plugin);
2b43acf9
PP
326 comp_cls_sink = bt_plugin_find_component_class(NULL, "sink",
327 BT_COMPONENT_CLASS_TYPE_SINK);
328 ok(!comp_cls_sink, "bt_plugin_find_component_class() handles NULL (plugin name)");
329 comp_cls_sink = bt_plugin_find_component_class("test_sfs", NULL,
330 BT_COMPONENT_CLASS_TYPE_SINK);
331 ok(!comp_cls_sink, "bt_plugin_find_component_class() handles NULL (component class name)");
332 comp_cls_sink = bt_plugin_find_component_class("test_sfs", "sink2",
333 BT_COMPONENT_CLASS_TYPE_SINK);
334 ok(!comp_cls_sink, "bt_plugin_find_component_class() fails with an unknown component class name");
335 comp_cls_sink = bt_plugin_find_component_class("test_sfs", "sink",
336 BT_COMPONENT_CLASS_TYPE_SINK);
337 ok(comp_cls_sink, "bt_plugin_find_component_class() succeeds with valid parameters");
338 ok(strcmp(bt_component_class_get_name(comp_cls_sink), "sink") == 0,
339 "bt_plugin_find_component_class() returns the appropriate component class (sink)");
340 comp_cls_source = bt_plugin_find_component_class("test_sfs", "source",
341 BT_COMPONENT_CLASS_TYPE_SOURCE);
342 ok(comp_cls_sink, "bt_plugin_find_component_class() succeeds with another component class name (same plugin)");
343 ok(strcmp(bt_component_class_get_name(comp_cls_source), "source") == 0,
344 "bt_plugin_find_component_class() returns the appropriate component class (source)");
8138bfe1
PP
345 BT_OBJECT_PUT_REF_AND_RESET(comp_cls_sink);
346 BT_OBJECT_PUT_REF_AND_RESET(comp_cls_source);
a8b3f23b
PP
347 free(plugin_path);
348}
349
cbb9e0b1
PP
350int main(int argc, char **argv)
351{
352 int ret;
353 const char *plugin_dir;
354
355 if (argc != 2) {
356 puts("Usage: test_plugin plugin_directory");
357 ret = 1;
358 goto end;
359 }
360
361 plugin_dir = argv[1];
362 plan_tests(NR_TESTS);
363 test_invalid(plugin_dir);
364 test_minimal(plugin_dir);
365 test_sfs(plugin_dir);
366 test_create_all_from_dir(plugin_dir);
2b43acf9 367 test_find(plugin_dir);
cbb9e0b1
PP
368 ret = exit_status();
369end:
370 return ret;
371}
This page took 0.051619 seconds and 4 git commands to generate.