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