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>
65300d60 19#include <babeltrace/object.h>
cbb9e0b1 20#include <babeltrace/values.h>
da91b29a 21#include <babeltrace/private-values.h>
cc469c42 22#include <babeltrace/graph/component.h>
a2d06fd5 23#include <babeltrace/graph/private-graph.h>
36712f1d 24#include <babeltrace/graph/graph.h>
c7eee084 25#include <babeltrace/graph/query-executor.h>
cbb9e0b1
PP
26#include <stdlib.h>
27#include <string.h>
28#include <stdio.h>
25583cd0 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 */
df5b5d01
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
df5b5d01 49static void reset_test_plugin_env_vars(void)
cbb9e0b1 50{
fbb2f0da
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;
84095ea4
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
84095ea4
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
25583cd0 115 BT_ASSERT(minimal_path);
cbb9e0b1
PP
116 diag("minimal plugin test below");
117
df5b5d01 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");
df5b5d01
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");
65300d60
PP
143 bt_object_put_ref(plugin);
144 bt_object_put_ref(plugin_set);
df5b5d01
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;
da91b29a 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;
a2d06fd5 166 struct bt_private_graph *graph;
a67681c1 167 const char *object_str;
c3c69044 168 enum bt_graph_status graph_ret;
c7eee084
PP
169 struct bt_query_executor *query_exec = bt_query_executor_create();
170 int ret;
cbb9e0b1 171
25583cd0
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);
25583cd0 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");
da91b29a 216 params = bt_private_value_integer_create_init(23);
25583cd0 217 BT_ASSERT(params);
c7eee084 218 ret = bt_query_executor_query(NULL, filter_comp_class, "object",
da91b29a 219 bt_value_borrow_from_private(params), &results);
c7eee084
PP
220 ok (ret, "bt_query_executor_query() handles NULL (query executor)");
221 ret = bt_query_executor_query(query_exec, NULL, "object",
da91b29a 222 bt_value_borrow_from_private(params), &results);
c7eee084
PP
223 ok (ret, "bt_query_executor_query() handles NULL (component class)");
224 ret = bt_query_executor_query(query_exec, filter_comp_class, NULL,
da91b29a 225 bt_value_borrow_from_private(params), &results);
c7eee084
PP
226 ok (ret, "bt_query_executor_query() handles NULL (object)");
227 ret = bt_query_executor_query(query_exec, filter_comp_class,
da91b29a
PP
228 "get-something", bt_value_borrow_from_private(params),
229 &results);
c7eee084 230 ok(ret == 0 && results, "bt_query_executor_query() succeeds");
07208d85
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);
25583cd0 233 BT_ASSERT(object && bt_value_is_string(object));
601b0d3c 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");
07208d85 237 res_params = bt_value_array_borrow_element_by_index(results, 1);
da91b29a 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");
65300d60 242 BT_OBJECT_PUT_REF_AND_RESET(plugin);
a2d06fd5 243 graph = bt_private_graph_create();
25583cd0 244 BT_ASSERT(graph);
a2d06fd5 245 graph_ret = bt_private_graph_add_component(graph, sink_comp_class, "the-sink",
c3c69044
MD
246 NULL, &sink_component);
247 ok(graph_ret == BT_GRAPH_STATUS_OK && sink_component,
a2d06fd5 248 "bt_private_graph_add_component() still works after the plugin object is destroyed");
65300d60
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);
a2d06fd5 252 graph = bt_private_graph_create();
25583cd0 253 BT_ASSERT(graph);
a2d06fd5 254 graph_ret = bt_private_graph_add_component(graph, sink_comp_class, "the-sink",
c3c69044
MD
255 NULL, &sink_component);
256 ok(graph_ret == BT_GRAPH_STATUS_OK && sink_component,
a2d06fd5 257 "bt_private_graph_add_component() still works after the source component class object is destroyed");
65300d60
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);
a2d06fd5 261 graph = bt_private_graph_create();
25583cd0 262 BT_ASSERT(graph);
a2d06fd5 263 graph_ret = bt_private_graph_add_component(graph, sink_comp_class, "the-sink",
c3c69044
MD
264 NULL, &sink_component);
265 ok(graph_ret == BT_GRAPH_STATUS_OK && sink_component,
a2d06fd5 266 "bt_private_graph_add_component() still works after the filter component class object is destroyed");
65300d60
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);
65300d60
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
65300d60 296 bt_object_put_ref(plugin_set);
cbb9e0b1
PP
297}
298
2b43acf9 299static void test_find(const char *plugin_dir)
a8b3f23b 300{
8a6001c5 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");
84095ea4
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);
25583cd0 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");
65300d60 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)");
65300d60
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.052679 seconds and 4 git commands to generate.