CTF IR -> Trace IR
[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>
23#include <babeltrace/ref.h>
24#include <babeltrace/values.h>
cc469c42 25#include <babeltrace/graph/component.h>
36712f1d 26#include <babeltrace/graph/graph.h>
c7eee084 27#include <babeltrace/graph/query-executor.h>
cbb9e0b1
PP
28#include <stdlib.h>
29#include <string.h>
30#include <stdio.h>
25583cd0 31#include <babeltrace/assert-internal.h>
cbb9e0b1
PP
32#include <glib.h>
33#include "tap/tap.h"
34#include "common.h"
35
2b43acf9 36#define NR_TESTS 58
cbb9e0b1
PP
37#define NON_EXISTING_PATH "/this/hopefully/does/not/exist/5bc75f8d-0dba-4043-a509-d7984b97e42b.so"
38
39/* Those symbols are written to by some test plugins */
df5b5d01
PP
40static int check_env_var(const char *name)
41{
42 const char *val = getenv(name);
43
44 if (!val) {
45 return -1;
46 }
47
48 return atoi(val);
49}
cbb9e0b1 50
df5b5d01 51static void reset_test_plugin_env_vars(void)
cbb9e0b1 52{
fbb2f0da
MJ
53 g_setenv("BT_TEST_PLUGIN_INIT_CALLED", "0", 1);
54 g_setenv("BT_TEST_PLUGIN_EXIT_CALLED", "0", 1);
cbb9e0b1
PP
55}
56
57static char *get_test_plugin_path(const char *plugin_dir,
58 const char *plugin_name)
59{
cbb9e0b1 60 char *ret;
84095ea4
MJ
61 char *plugin_file_name;
62
63 if (asprintf(&plugin_file_name, "plugin-%s." G_MODULE_SUFFIX,
64 plugin_name) == -1) {
65 abort();
66 }
67
68 ret = g_build_filename(plugin_dir, plugin_file_name, NULL);
69 free(plugin_file_name);
cbb9e0b1 70
cbb9e0b1
PP
71 return ret;
72}
73
74static void test_invalid(const char *plugin_dir)
75{
a8ff38ef 76 struct bt_plugin_set *plugin_set;
cbb9e0b1 77
84095ea4
MJ
78 diag("invalid plugin test below");
79
a8ff38ef
PP
80 plugin_set = bt_plugin_create_all_from_file(NON_EXISTING_PATH);
81 ok(!plugin_set, "bt_plugin_create_all_from_file() fails with a non-existing file");
cbb9e0b1 82
a8ff38ef
PP
83 plugin_set = bt_plugin_create_all_from_file(plugin_dir);
84 ok(!plugin_set, "bt_plugin_create_all_from_file() fails with a directory");
cbb9e0b1 85
6ba0b073
PP
86 ok(!bt_plugin_create_all_from_file(NULL),
87 "bt_plugin_create_all_from_file() handles NULL correctly");
c55a9f58 88 ok(!bt_plugin_create_all_from_dir(NULL, BT_FALSE),
cbb9e0b1
PP
89 "bt_plugin_create_all_from_dir() handles NULL correctly");
90 ok(!bt_plugin_get_name(NULL),
91 "bt_plugin_get_name() handles NULL correctly");
92 ok(!bt_plugin_get_description(NULL),
93 "bt_plugin_get_description() handles NULL correctly");
458e8e1d
PP
94 ok(bt_plugin_get_version(NULL, NULL, NULL, NULL, NULL) !=
95 BT_PLUGIN_STATUS_OK,
96 "bt_plugin_get_version() handles NULL correctly");
cbb9e0b1
PP
97 ok(!bt_plugin_get_author(NULL),
98 "bt_plugin_get_author() handles NULL correctly");
99 ok(!bt_plugin_get_license(NULL),
100 "bt_plugin_get_license() handles NULL correctly");
101 ok(!bt_plugin_get_path(NULL),
102 "bt_plugin_get_path() handles NULL correctly");
103 ok(bt_plugin_get_component_class_count(NULL) < 0,
104 "bt_plugin_get_component_class_count() handles NULL correctly");
9ac68eb1
PP
105 ok(!bt_plugin_get_component_class_by_index(NULL, 0),
106 "bt_plugin_get_component_class_by_index() handles NULL correctly");
cbb9e0b1
PP
107 ok(!bt_plugin_get_component_class_by_name_and_type(NULL, NULL, 0),
108 "bt_plugin_get_component_class_by_name_and_type() handles NULL correctly");
cbb9e0b1
PP
109}
110
111static void test_minimal(const char *plugin_dir)
112{
a8ff38ef 113 struct bt_plugin_set *plugin_set;
cbb9e0b1
PP
114 struct bt_plugin *plugin;
115 char *minimal_path = get_test_plugin_path(plugin_dir, "minimal");
116
25583cd0 117 BT_ASSERT(minimal_path);
cbb9e0b1
PP
118 diag("minimal plugin test below");
119
df5b5d01 120 reset_test_plugin_env_vars();
a8ff38ef
PP
121 plugin_set = bt_plugin_create_all_from_file(minimal_path);
122 ok(plugin_set && bt_plugin_set_get_plugin_count(plugin_set) == 1,
123 "bt_plugin_create_all_from_file() succeeds with a valid file");
df5b5d01
PP
124 ok(check_env_var("BT_TEST_PLUGIN_INIT_CALLED") == 1,
125 "plugin's initialization function is called during bt_plugin_create_all_from_file()");
a8ff38ef 126 ok(bt_plugin_set_get_plugin_count(plugin_set) == 1,
6ba0b073 127 "bt_plugin_create_all_from_file() returns the expected number of plugins");
a8ff38ef 128 plugin = bt_plugin_set_get_plugin(plugin_set, 0);
6ba0b073 129 ok(strcmp(bt_plugin_get_name(plugin), "test_minimal") == 0,
cbb9e0b1
PP
130 "bt_plugin_get_name() returns the expected name");
131 ok(strcmp(bt_plugin_get_description(plugin),
132 "Minimal Babeltrace plugin with no component classes") == 0,
133 "bt_plugin_get_description() returns the expected description");
458e8e1d
PP
134 ok(bt_plugin_get_version(plugin, NULL, NULL, NULL, NULL) !=
135 BT_PLUGIN_STATUS_OK,
136 "bt_plugin_get_version() fails when there's no version");
cbb9e0b1
PP
137 ok(strcmp(bt_plugin_get_author(plugin), "Janine Sutto") == 0,
138 "bt_plugin_get_author() returns the expected author");
139 ok(strcmp(bt_plugin_get_license(plugin), "Beerware") == 0,
140 "bt_plugin_get_license() returns the expected license");
141 ok(strcmp(bt_plugin_get_path(plugin), minimal_path) == 0,
142 "bt_plugin_get_path() returns the expected path");
143 ok(bt_plugin_get_component_class_count(plugin) == 0,
144 "bt_plugin_get_component_class_count() returns the expected value");
a8ff38ef
PP
145 bt_put(plugin);
146 bt_put(plugin_set);
df5b5d01
PP
147 ok(check_env_var("BT_TEST_PLUGIN_EXIT_CALLED") == 1,
148 "plugin's exit function is called when the plugin is destroyed");
cbb9e0b1
PP
149
150 free(minimal_path);
151}
152
153static void test_sfs(const char *plugin_dir)
154{
a8ff38ef 155 struct bt_plugin_set *plugin_set;
cbb9e0b1
PP
156 struct bt_plugin *plugin;
157 struct bt_component_class *sink_comp_class;
158 struct bt_component_class *source_comp_class;
159 struct bt_component_class *filter_comp_class;
160 struct bt_component *sink_component;
161 char *sfs_path = get_test_plugin_path(plugin_dir, "sfs");
458e8e1d
PP
162 unsigned int major, minor, patch;
163 const char *extra;
5933c0f2
PP
164 struct bt_value *params;
165 struct bt_value *results;
a67681c1 166 struct bt_value *object;
5933c0f2 167 struct bt_value *res_params;
36712f1d 168 struct bt_graph *graph;
a67681c1 169 const char *object_str;
c3c69044
MD
170 enum bt_value_status value_ret;
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");
5933c0f2 219 params = bt_value_integer_create_init(23);
25583cd0 220 BT_ASSERT(params);
c7eee084
PP
221 ret = bt_query_executor_query(NULL, filter_comp_class, "object",
222 params, &results);
223 ok (ret, "bt_query_executor_query() handles NULL (query executor)");
224 ret = bt_query_executor_query(query_exec, NULL, "object",
225 params, &results);
226 ok (ret, "bt_query_executor_query() handles NULL (component class)");
227 ret = bt_query_executor_query(query_exec, filter_comp_class, NULL,
228 params, &results);
229 ok (ret, "bt_query_executor_query() handles NULL (object)");
230 ret = bt_query_executor_query(query_exec, filter_comp_class,
231 "get-something", params, &results);
232 ok(ret == 0 && results, "bt_query_executor_query() succeeds");
25583cd0 233 BT_ASSERT(bt_value_is_array(results) && bt_value_array_size(results) == 2);
a67681c1 234 object = bt_value_array_get(results, 0);
25583cd0 235 BT_ASSERT(object && bt_value_is_string(object));
c3c69044 236 value_ret = bt_value_string_get(object, &object_str);
25583cd0 237 BT_ASSERT(value_ret == BT_VALUE_STATUS_OK);
a67681c1
PP
238 ok(strcmp(object_str, "get-something") == 0,
239 "bt_component_class_query() receives the expected object name");
5933c0f2
PP
240 res_params = bt_value_array_get(results, 1);
241 ok(res_params == params,
a67681c1 242 "bt_component_class_query() receives the expected parameters");
cbb9e0b1
PP
243
244 diag("> putting the plugin object here");
245 BT_PUT(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");
cbb9e0b1
PP
252 BT_PUT(sink_component);
253 BT_PUT(source_comp_class);
36712f1d
PP
254 bt_put(graph);
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");
cbb9e0b1
PP
261 BT_PUT(sink_component);
262 BT_PUT(filter_comp_class);
36712f1d
PP
263 bt_put(graph);
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");
cbb9e0b1
PP
270 BT_PUT(sink_comp_class);
271 BT_PUT(sink_component);
272
273 free(sfs_path);
36712f1d 274 bt_put(graph);
a8ff38ef 275 bt_put(plugin_set);
a67681c1 276 bt_put(object);
5933c0f2
PP
277 bt_put(res_params);
278 bt_put(results);
279 bt_put(params);
c7eee084 280 bt_put(query_exec);
cbb9e0b1
PP
281}
282
283static void test_create_all_from_dir(const char *plugin_dir)
284{
a8ff38ef 285 struct bt_plugin_set *plugin_set;
cbb9e0b1
PP
286
287 diag("create from all test below");
288
c55a9f58 289 plugin_set = bt_plugin_create_all_from_dir(NON_EXISTING_PATH, BT_FALSE);
a8ff38ef 290 ok(!plugin_set,
cbb9e0b1
PP
291 "bt_plugin_create_all_from_dir() fails with an invalid path");
292
c55a9f58 293 plugin_set = bt_plugin_create_all_from_dir(plugin_dir, BT_FALSE);
a8ff38ef 294 ok(plugin_set, "bt_plugin_create_all_from_dir() succeeds with a valid path");
cbb9e0b1
PP
295
296 /* 2 or 4, if `.la` files are considered or not */
a8ff38ef
PP
297 ok(bt_plugin_set_get_plugin_count(plugin_set) == 2 ||
298 bt_plugin_set_get_plugin_count(plugin_set) == 4,
299 "bt_plugin_create_all_from_dir() returns the expected number of plugin objects");
cbb9e0b1 300
a8ff38ef 301 bt_put(plugin_set);
cbb9e0b1
PP
302}
303
2b43acf9 304static void test_find(const char *plugin_dir)
a8b3f23b 305{
8a6001c5 306 int ret;
a8b3f23b 307 struct bt_plugin *plugin;
2b43acf9
PP
308 struct bt_component_class *comp_cls_sink;
309 struct bt_component_class *comp_cls_source;
a8b3f23b
PP
310 char *plugin_path;
311
2b43acf9
PP
312 ok(!bt_plugin_find(NULL),
313 "bt_plugin_find() handles NULL");
314 ok(!bt_plugin_find(NON_EXISTING_PATH),
315 "bt_plugin_find() returns NULL with an unknown plugin name");
84095ea4
MJ
316 ret = asprintf(&plugin_path, "%s" G_SEARCHPATH_SEPARATOR_S
317 G_DIR_SEPARATOR_S "ec1d09e5-696c-442e-b1c3-f9c6cf7f5958"
318 G_SEARCHPATH_SEPARATOR_S G_SEARCHPATH_SEPARATOR_S
319 G_SEARCHPATH_SEPARATOR_S "%s" G_SEARCHPATH_SEPARATOR_S
320 "8db46494-a398-466a-9649-c765ae077629"
321 G_SEARCHPATH_SEPARATOR_S,
a8b3f23b 322 NON_EXISTING_PATH, plugin_dir);
25583cd0 323 BT_ASSERT(ret > 0 && plugin_path);
aacfaf40 324 g_setenv("BABELTRACE_PLUGIN_PATH", plugin_path, 1);
2b43acf9 325 plugin = bt_plugin_find("test_minimal");
a8b3f23b 326 ok(plugin,
2b43acf9 327 "bt_plugin_find() succeeds with a plugin name it can find");
a8b3f23b 328 ok(strcmp(bt_plugin_get_author(plugin), "Janine Sutto") == 0,
2b43acf9 329 "bt_plugin_find() finds the correct plugin for a given name");
a8b3f23b 330 BT_PUT(plugin);
2b43acf9
PP
331 comp_cls_sink = bt_plugin_find_component_class(NULL, "sink",
332 BT_COMPONENT_CLASS_TYPE_SINK);
333 ok(!comp_cls_sink, "bt_plugin_find_component_class() handles NULL (plugin name)");
334 comp_cls_sink = bt_plugin_find_component_class("test_sfs", NULL,
335 BT_COMPONENT_CLASS_TYPE_SINK);
336 ok(!comp_cls_sink, "bt_plugin_find_component_class() handles NULL (component class name)");
337 comp_cls_sink = bt_plugin_find_component_class("test_sfs", "sink2",
338 BT_COMPONENT_CLASS_TYPE_SINK);
339 ok(!comp_cls_sink, "bt_plugin_find_component_class() fails with an unknown component class name");
340 comp_cls_sink = bt_plugin_find_component_class("test_sfs", "sink",
341 BT_COMPONENT_CLASS_TYPE_SINK);
342 ok(comp_cls_sink, "bt_plugin_find_component_class() succeeds with valid parameters");
343 ok(strcmp(bt_component_class_get_name(comp_cls_sink), "sink") == 0,
344 "bt_plugin_find_component_class() returns the appropriate component class (sink)");
345 comp_cls_source = bt_plugin_find_component_class("test_sfs", "source",
346 BT_COMPONENT_CLASS_TYPE_SOURCE);
347 ok(comp_cls_sink, "bt_plugin_find_component_class() succeeds with another component class name (same plugin)");
348 ok(strcmp(bt_component_class_get_name(comp_cls_source), "source") == 0,
349 "bt_plugin_find_component_class() returns the appropriate component class (source)");
350 BT_PUT(comp_cls_sink);
351 BT_PUT(comp_cls_source);
a8b3f23b
PP
352 free(plugin_path);
353}
354
cbb9e0b1
PP
355int main(int argc, char **argv)
356{
357 int ret;
358 const char *plugin_dir;
359
360 if (argc != 2) {
361 puts("Usage: test_plugin plugin_directory");
362 ret = 1;
363 goto end;
364 }
365
366 plugin_dir = argv[1];
367 plan_tests(NR_TESTS);
368 test_invalid(plugin_dir);
369 test_minimal(plugin_dir);
370 test_sfs(plugin_dir);
371 test_create_all_from_dir(plugin_dir);
2b43acf9 372 test_find(plugin_dir);
cbb9e0b1
PP
373 ret = exit_status();
374end:
375 return ret;
376}
This page took 0.05153 seconds and 4 git commands to generate.