Values API: split into private and public APIs
[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
MD
171 enum bt_value_status value_ret;
172 enum bt_graph_status graph_ret;
c7eee084
PP
173 struct bt_query_executor *query_exec = bt_query_executor_create();
174 int ret;
cbb9e0b1 175
25583cd0
PP
176 BT_ASSERT(query_exec);
177 BT_ASSERT(sfs_path);
cbb9e0b1
PP
178 diag("sfs plugin test below");
179
a8ff38ef 180 plugin_set = bt_plugin_create_all_from_file(sfs_path);
25583cd0 181 BT_ASSERT(plugin_set && bt_plugin_set_get_plugin_count(plugin_set) == 1);
a8ff38ef 182 plugin = bt_plugin_set_get_plugin(plugin_set, 0);
458e8e1d
PP
183 ok(bt_plugin_get_version(plugin, &major, &minor, &patch, &extra) ==
184 BT_PLUGIN_STATUS_OK,
185 "bt_plugin_get_version() succeeds when there's a version");
186 ok(major == 1,
187 "bt_plugin_get_version() returns the expected major version");
188 ok(minor == 2,
189 "bt_plugin_get_version() returns the expected minor version");
190 ok(patch == 3,
191 "bt_plugin_get_version() returns the expected patch version");
192 ok(strcmp(extra, "yes") == 0,
193 "bt_plugin_get_version() returns the expected extra version");
cbb9e0b1
PP
194 ok(bt_plugin_get_component_class_count(plugin) == 3,
195 "bt_plugin_get_component_class_count() returns the expected value");
196
197 source_comp_class = bt_plugin_get_component_class_by_name_and_type(
d3e4dcd8 198 plugin, "source", BT_COMPONENT_CLASS_TYPE_SOURCE);
cbb9e0b1
PP
199 ok(source_comp_class,
200 "bt_plugin_get_component_class_by_name_and_type() finds a source component class");
201
202 sink_comp_class = bt_plugin_get_component_class_by_name_and_type(
d3e4dcd8 203 plugin, "sink", BT_COMPONENT_CLASS_TYPE_SINK);
cbb9e0b1
PP
204 ok(sink_comp_class,
205 "bt_plugin_get_component_class_by_name_and_type() finds a sink component class");
a889b89f
PP
206 ok(strcmp(bt_component_class_get_help(sink_comp_class),
207 "Bacon ipsum dolor amet strip steak cupim pastrami venison shoulder.\n"
208 "Prosciutto beef ribs flank meatloaf pancetta brisket kielbasa drumstick\n"
209 "venison tenderloin cow tail. Beef short loin shoulder meatball, sirloin\n"
210 "ground round brisket salami cupim pork bresaola turkey bacon boudin.\n") == 0,
211 "bt_component_class_get_help() returns the expected help text");
212
cbb9e0b1 213 filter_comp_class = bt_plugin_get_component_class_by_name_and_type(
d3e4dcd8 214 plugin, "filter", BT_COMPONENT_CLASS_TYPE_FILTER);
cbb9e0b1
PP
215 ok(filter_comp_class,
216 "bt_plugin_get_component_class_by_name_and_type() finds a filter component class");
217 ok(!bt_plugin_get_component_class_by_name_and_type(plugin, "filter",
d3e4dcd8 218 BT_COMPONENT_CLASS_TYPE_SOURCE),
cbb9e0b1 219 "bt_plugin_get_component_class_by_name_and_type() does not find a component class given the wrong type");
da91b29a 220 params = bt_private_value_integer_create_init(23);
25583cd0 221 BT_ASSERT(params);
c7eee084 222 ret = bt_query_executor_query(NULL, filter_comp_class, "object",
da91b29a 223 bt_value_borrow_from_private(params), &results);
c7eee084
PP
224 ok (ret, "bt_query_executor_query() handles NULL (query executor)");
225 ret = bt_query_executor_query(query_exec, NULL, "object",
da91b29a 226 bt_value_borrow_from_private(params), &results);
c7eee084
PP
227 ok (ret, "bt_query_executor_query() handles NULL (component class)");
228 ret = bt_query_executor_query(query_exec, filter_comp_class, NULL,
da91b29a 229 bt_value_borrow_from_private(params), &results);
c7eee084
PP
230 ok (ret, "bt_query_executor_query() handles NULL (object)");
231 ret = bt_query_executor_query(query_exec, filter_comp_class,
da91b29a
PP
232 "get-something", bt_value_borrow_from_private(params),
233 &results);
c7eee084 234 ok(ret == 0 && results, "bt_query_executor_query() succeeds");
07208d85
PP
235 BT_ASSERT(bt_value_is_array(results) && bt_value_array_get_size(results) == 2);
236 object = bt_value_array_borrow_element_by_index(results, 0);
25583cd0 237 BT_ASSERT(object && bt_value_is_string(object));
c3c69044 238 value_ret = bt_value_string_get(object, &object_str);
25583cd0 239 BT_ASSERT(value_ret == BT_VALUE_STATUS_OK);
a67681c1
PP
240 ok(strcmp(object_str, "get-something") == 0,
241 "bt_component_class_query() receives the expected object name");
07208d85 242 res_params = bt_value_array_borrow_element_by_index(results, 1);
da91b29a 243 ok(res_params == bt_value_borrow_from_private(params),
a67681c1 244 "bt_component_class_query() receives the expected parameters");
cbb9e0b1
PP
245
246 diag("> putting the plugin object here");
65300d60 247 BT_OBJECT_PUT_REF_AND_RESET(plugin);
36712f1d 248 graph = bt_graph_create();
25583cd0 249 BT_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 plugin object is destroyed");
65300d60
PP
254 BT_OBJECT_PUT_REF_AND_RESET(sink_component);
255 BT_OBJECT_PUT_REF_AND_RESET(source_comp_class);
256 bt_object_put_ref(graph);
36712f1d 257 graph = bt_graph_create();
25583cd0 258 BT_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 source component class object is destroyed");
65300d60
PP
263 BT_OBJECT_PUT_REF_AND_RESET(sink_component);
264 BT_OBJECT_PUT_REF_AND_RESET(filter_comp_class);
265 bt_object_put_ref(graph);
36712f1d 266 graph = bt_graph_create();
25583cd0 267 BT_ASSERT(graph);
c3c69044
MD
268 graph_ret = bt_graph_add_component(graph, sink_comp_class, "the-sink",
269 NULL, &sink_component);
270 ok(graph_ret == BT_GRAPH_STATUS_OK && sink_component,
36712f1d 271 "bt_graph_add_component() still works after the filter component class object is destroyed");
65300d60
PP
272 BT_OBJECT_PUT_REF_AND_RESET(sink_comp_class);
273 BT_OBJECT_PUT_REF_AND_RESET(sink_component);
cbb9e0b1
PP
274
275 free(sfs_path);
65300d60
PP
276 bt_object_put_ref(graph);
277 bt_object_put_ref(plugin_set);
278 bt_object_put_ref(results);
279 bt_object_put_ref(params);
280 bt_object_put_ref(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
65300d60 301 bt_object_put_ref(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");
65300d60 330 BT_OBJECT_PUT_REF_AND_RESET(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)");
65300d60
PP
350 BT_OBJECT_PUT_REF_AND_RESET(comp_cls_sink);
351 BT_OBJECT_PUT_REF_AND_RESET(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.060689 seconds and 4 git commands to generate.