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