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