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