lib: graph API: return borrowed references when adding to an object
[babeltrace.git] / tests / lib / plugin.c
CommitLineData
cbb9e0b1 1/*
cbb9e0b1
PP
2 * Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; under version 2 of the License.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
16 */
17
3fadfbc0 18#include <babeltrace2/babeltrace.h>
cbb9e0b1
PP
19#include <stdlib.h>
20#include <string.h>
21#include <stdio.h>
578e048b 22#include "common/assert.h"
cbb9e0b1
PP
23#include <glib.h>
24#include "tap/tap.h"
25#include "common.h"
26
9736d991 27#define NR_TESTS 38
cbb9e0b1
PP
28#define NON_EXISTING_PATH "/this/hopefully/does/not/exist/5bc75f8d-0dba-4043-a509-d7984b97e42b.so"
29
30/* Those symbols are written to by some test plugins */
df5b5d01
PP
31static int check_env_var(const char *name)
32{
33 const char *val = getenv(name);
34
35 if (!val) {
36 return -1;
37 }
38
39 return atoi(val);
40}
cbb9e0b1 41
df5b5d01 42static void reset_test_plugin_env_vars(void)
cbb9e0b1 43{
21a9f056 44 g_setenv("BT_TEST_PLUGIN_INITIALIZE_CALLED", "0", 1);
a71c9a60 45 g_setenv("BT_TEST_PLUGIN_FINALIZE_CALLED", "0", 1);
cbb9e0b1
PP
46}
47
48static char *get_test_plugin_path(const char *plugin_dir,
49 const char *plugin_name)
50{
cbb9e0b1 51 char *ret;
84095ea4
MJ
52 char *plugin_file_name;
53
54 if (asprintf(&plugin_file_name, "plugin-%s." G_MODULE_SUFFIX,
55 plugin_name) == -1) {
56 abort();
57 }
58
59 ret = g_build_filename(plugin_dir, plugin_file_name, NULL);
60 free(plugin_file_name);
cbb9e0b1 61
cbb9e0b1
PP
62 return ret;
63}
64
cbb9e0b1
PP
65static void test_minimal(const char *plugin_dir)
66{
9736d991 67 const bt_plugin_set *plugin_set = NULL;
b19ff26f 68 const bt_plugin *plugin;
cbb9e0b1 69 char *minimal_path = get_test_plugin_path(plugin_dir, "minimal");
d24d5663 70 bt_plugin_find_all_from_file_status status;
cbb9e0b1 71
25583cd0 72 BT_ASSERT(minimal_path);
cbb9e0b1
PP
73 diag("minimal plugin test below");
74
df5b5d01 75 reset_test_plugin_env_vars();
9736d991
PP
76 status = bt_plugin_find_all_from_file(minimal_path, BT_FALSE,
77 &plugin_set);
d24d5663 78 ok(status == BT_PLUGIN_FIND_ALL_FROM_FILE_STATUS_OK,
c8db3219 79 "bt_plugin_find_all_from_file() succeeds with a valid file");
9736d991
PP
80 ok(plugin_set,
81 "bt_plugin_find_all_from_file() returns a plugin set");
21a9f056 82 ok(check_env_var("BT_TEST_PLUGIN_INITIALIZE_CALLED") == 1,
c8db3219 83 "plugin's initialization function is called during bt_plugin_find_all_from_file()");
a8ff38ef 84 ok(bt_plugin_set_get_plugin_count(plugin_set) == 1,
c8db3219 85 "bt_plugin_find_all_from_file() returns the expected number of plugins");
92fed4e1 86 plugin = bt_plugin_set_borrow_plugin_by_index_const(plugin_set, 0);
6ba0b073 87 ok(strcmp(bt_plugin_get_name(plugin), "test_minimal") == 0,
cbb9e0b1
PP
88 "bt_plugin_get_name() returns the expected name");
89 ok(strcmp(bt_plugin_get_description(plugin),
90 "Minimal Babeltrace plugin with no component classes") == 0,
91 "bt_plugin_get_description() returns the expected description");
d94d92ac
PP
92 ok(bt_plugin_get_version(plugin, NULL, NULL, NULL, NULL) ==
93 BT_PROPERTY_AVAILABILITY_NOT_AVAILABLE,
458e8e1d 94 "bt_plugin_get_version() fails when there's no version");
cbb9e0b1
PP
95 ok(strcmp(bt_plugin_get_author(plugin), "Janine Sutto") == 0,
96 "bt_plugin_get_author() returns the expected author");
97 ok(strcmp(bt_plugin_get_license(plugin), "Beerware") == 0,
98 "bt_plugin_get_license() returns the expected license");
99 ok(strcmp(bt_plugin_get_path(plugin), minimal_path) == 0,
100 "bt_plugin_get_path() returns the expected path");
d94d92ac
PP
101 ok(bt_plugin_get_source_component_class_count(plugin) == 0,
102 "bt_plugin_get_source_component_class_count() returns the expected value");
103 ok(bt_plugin_get_filter_component_class_count(plugin) == 0,
104 "bt_plugin_get_filter_component_class_count() returns the expected value");
105 ok(bt_plugin_get_sink_component_class_count(plugin) == 0,
106 "bt_plugin_get_sink_component_class_count() returns the expected value");
c5b9b441 107 bt_plugin_set_put_ref(plugin_set);
a71c9a60
FD
108 ok(check_env_var("BT_TEST_PLUGIN_FINALIZE_CALLED") == 1,
109 "plugin's finalize function is called when the plugin is destroyed");
cbb9e0b1
PP
110
111 free(minimal_path);
112}
113
114static void test_sfs(const char *plugin_dir)
115{
9736d991 116 const bt_plugin_set *plugin_set = NULL;
b19ff26f
PP
117 const bt_plugin *plugin;
118 const bt_component_class_sink *sink_comp_class;
119 const bt_component_class_source *source_comp_class;
120 const bt_component_class_filter *filter_comp_class;
121 const bt_component_sink *sink_component;
cbb9e0b1 122 char *sfs_path = get_test_plugin_path(plugin_dir, "sfs");
458e8e1d
PP
123 unsigned int major, minor, patch;
124 const char *extra;
b19ff26f
PP
125 bt_value *params;
126 const bt_value *results;
127 const bt_value *object;
128 const bt_value *res_params;
129 bt_graph *graph;
a67681c1 130 const char *object_str;
d24d5663 131 bt_graph_add_component_status graph_ret;
3c729b9a 132 bt_query_executor *query_exec;
c7eee084 133 int ret;
d24d5663 134 bt_plugin_find_all_from_file_status status;
cbb9e0b1 135
25583cd0 136 BT_ASSERT(sfs_path);
cbb9e0b1
PP
137 diag("sfs plugin test below");
138
9736d991 139 status = bt_plugin_find_all_from_file(sfs_path, BT_FALSE, &plugin_set);
d24d5663
PP
140 BT_ASSERT(status == BT_PLUGIN_FIND_ALL_FROM_FILE_STATUS_OK &&
141 plugin_set && bt_plugin_set_get_plugin_count(plugin_set) == 1);
92fed4e1 142 plugin = bt_plugin_set_borrow_plugin_by_index_const(plugin_set, 0);
458e8e1d 143 ok(bt_plugin_get_version(plugin, &major, &minor, &patch, &extra) ==
d94d92ac 144 BT_PROPERTY_AVAILABILITY_AVAILABLE,
458e8e1d
PP
145 "bt_plugin_get_version() succeeds when there's a version");
146 ok(major == 1,
147 "bt_plugin_get_version() returns the expected major version");
148 ok(minor == 2,
149 "bt_plugin_get_version() returns the expected minor version");
150 ok(patch == 3,
151 "bt_plugin_get_version() returns the expected patch version");
152 ok(strcmp(extra, "yes") == 0,
153 "bt_plugin_get_version() returns the expected extra version");
d94d92ac
PP
154 ok(bt_plugin_get_source_component_class_count(plugin) == 1,
155 "bt_plugin_get_source_component_class_count() returns the expected value");
156 ok(bt_plugin_get_filter_component_class_count(plugin) == 1,
157 "bt_plugin_get_filter_component_class_count() returns the expected value");
158 ok(bt_plugin_get_sink_component_class_count(plugin) == 1,
159 "bt_plugin_get_sink_component_class_count() returns the expected value");
160
92fed4e1 161 source_comp_class = bt_plugin_borrow_source_component_class_by_name_const(
d94d92ac 162 plugin, "source");
cbb9e0b1 163 ok(source_comp_class,
92fed4e1 164 "bt_plugin_borrow_source_component_class_by_name_const() finds a source component class");
cbb9e0b1 165
92fed4e1 166 sink_comp_class = bt_plugin_borrow_sink_component_class_by_name_const(
d94d92ac 167 plugin, "sink");
cbb9e0b1 168 ok(sink_comp_class,
92fed4e1 169 "bt_plugin_borrow_sink_component_class_by_name_const() finds a sink component class");
0d72b8c3
PP
170 ok(strcmp(bt_component_class_get_help(bt_component_class_sink_as_component_class_const(sink_comp_class)),
171 "Bacon ipsum dolor amet strip steak cupim pastrami venison shoulder.\n"
172 "Prosciutto beef ribs flank meatloaf pancetta brisket kielbasa drumstick\n"
173 "venison tenderloin cow tail. Beef short loin shoulder meatball, sirloin\n"
174 "ground round brisket salami cupim pork bresaola turkey bacon boudin.\n") == 0,
a889b89f
PP
175 "bt_component_class_get_help() returns the expected help text");
176
92fed4e1 177 filter_comp_class = bt_plugin_borrow_filter_component_class_by_name_const(
d94d92ac 178 plugin, "filter");
cbb9e0b1 179 ok(filter_comp_class,
92fed4e1 180 "bt_plugin_borrow_filter_component_class_by_name_const() finds a filter component class");
9c08c816 181 params = bt_value_integer_signed_create_init(23);
25583cd0 182 BT_ASSERT(params);
3c729b9a
PP
183 query_exec = bt_query_executor_create(
184 bt_component_class_filter_as_component_class_const(
185 filter_comp_class), "get-something", params);
186 BT_ASSERT(query_exec);
187 ret = bt_query_executor_query(query_exec, &results);
0d72b8c3 188 ok(ret == 0 && results, "bt_query_executor_query() succeeds");
393729a6 189 BT_ASSERT(bt_value_is_array(results) && bt_value_array_get_length(results) == 2);
05e21286 190 object = bt_value_array_borrow_element_by_index_const(results, 0);
33f4e1fd 191 BT_ASSERT(bt_value_is_string(object));
601b0d3c 192 object_str = bt_value_string_get(object);
a67681c1
PP
193 ok(strcmp(object_str, "get-something") == 0,
194 "bt_component_class_query() receives the expected object name");
05e21286 195 res_params = bt_value_array_borrow_element_by_index_const(results, 1);
cd933d89 196 ok(bt_value_is_equal(res_params, params),
a67681c1 197 "bt_component_class_query() receives the expected parameters");
cbb9e0b1 198
c5b9b441 199 bt_component_class_sink_get_ref(sink_comp_class);
c5b9b441 200 BT_PLUGIN_SET_PUT_REF_AND_RESET(plugin_set);
056deb59 201 graph = bt_graph_create(0);
25583cd0 202 BT_ASSERT(graph);
0d72b8c3 203 graph_ret = bt_graph_add_sink_component(graph, sink_comp_class,
e874da19 204 "the-sink", NULL, BT_LOGGING_LEVEL_NONE, &sink_component);
d24d5663 205 ok(graph_ret == BT_GRAPH_ADD_COMPONENT_STATUS_OK && sink_component,
0d72b8c3 206 "bt_graph_add_sink_component() still works after the plugin object is destroyed");
c5b9b441 207 bt_graph_put_ref(graph);
cbb9e0b1
PP
208
209 free(sfs_path);
c5b9b441
PP
210 bt_component_class_sink_put_ref(sink_comp_class);
211 bt_value_put_ref(results);
212 bt_value_put_ref(params);
213 bt_query_executor_put_ref(query_exec);
cbb9e0b1
PP
214}
215
216static void test_create_all_from_dir(const char *plugin_dir)
217{
b19ff26f 218 const bt_plugin_set *plugin_set;
d24d5663 219 bt_plugin_find_all_from_dir_status status;
cbb9e0b1
PP
220
221 diag("create from all test below");
222
9736d991
PP
223 status = bt_plugin_find_all_from_dir(NON_EXISTING_PATH, BT_FALSE,
224 BT_FALSE, &plugin_set);
d24d5663 225 ok(status == BT_PLUGIN_FIND_ALL_FROM_DIR_STATUS_ERROR,
c8db3219 226 "bt_plugin_find_all_from_dir() fails with an invalid path");
758932ce 227 bt_current_thread_clear_error();
cbb9e0b1 228
9736d991
PP
229 plugin_set = NULL;
230 status = bt_plugin_find_all_from_dir(plugin_dir, BT_FALSE, BT_FALSE,
231 &plugin_set);
d24d5663 232 ok(status == BT_PLUGIN_FIND_ALL_FROM_DIR_STATUS_OK,
9736d991
PP
233 "bt_plugin_find_all_from_dir() succeeds with a valid path");
234 ok(plugin_set,
235 "bt_plugin_find_all_from_dir() returns a plugin set with a valid path");
cbb9e0b1
PP
236
237 /* 2 or 4, if `.la` files are considered or not */
a8ff38ef
PP
238 ok(bt_plugin_set_get_plugin_count(plugin_set) == 2 ||
239 bt_plugin_set_get_plugin_count(plugin_set) == 4,
c8db3219 240 "bt_plugin_find_all_from_dir() returns the expected number of plugin objects");
cbb9e0b1 241
c5b9b441 242 bt_plugin_set_put_ref(plugin_set);
cbb9e0b1
PP
243}
244
2b43acf9 245static void test_find(const char *plugin_dir)
a8b3f23b 246{
8a6001c5 247 int ret;
b19ff26f 248 const bt_plugin *plugin;
a8b3f23b 249 char *plugin_path;
d24d5663 250 bt_plugin_find_status status;
a8b3f23b 251
577fa92f
PP
252 ok(bt_plugin_find(NON_EXISTING_PATH, BT_TRUE, BT_FALSE, BT_FALSE,
253 BT_FALSE, BT_FALSE, &plugin) == BT_PLUGIN_FIND_STATUS_NOT_FOUND,
9736d991 254 "bt_plugin_find() returns BT_PLUGIN_STATUS_NOT_FOUND with an unknown plugin name");
84095ea4
MJ
255 ret = asprintf(&plugin_path, "%s" G_SEARCHPATH_SEPARATOR_S
256 G_DIR_SEPARATOR_S "ec1d09e5-696c-442e-b1c3-f9c6cf7f5958"
257 G_SEARCHPATH_SEPARATOR_S G_SEARCHPATH_SEPARATOR_S
258 G_SEARCHPATH_SEPARATOR_S "%s" G_SEARCHPATH_SEPARATOR_S
259 "8db46494-a398-466a-9649-c765ae077629"
260 G_SEARCHPATH_SEPARATOR_S,
a8b3f23b 261 NON_EXISTING_PATH, plugin_dir);
25583cd0 262 BT_ASSERT(ret > 0 && plugin_path);
aacfaf40 263 g_setenv("BABELTRACE_PLUGIN_PATH", plugin_path, 1);
9736d991 264 plugin = NULL;
577fa92f
PP
265 status = bt_plugin_find("test_minimal", BT_TRUE, BT_FALSE, BT_FALSE,
266 BT_FALSE, BT_FALSE, &plugin);
d24d5663 267 ok(status == BT_PLUGIN_FIND_STATUS_OK,
2b43acf9 268 "bt_plugin_find() succeeds with a plugin name it can find");
9736d991 269 ok(plugin, "bt_plugin_find() returns a plugin object");
a8b3f23b 270 ok(strcmp(bt_plugin_get_author(plugin), "Janine Sutto") == 0,
2b43acf9 271 "bt_plugin_find() finds the correct plugin for a given name");
c5b9b441 272 BT_PLUGIN_PUT_REF_AND_RESET(plugin);
a8b3f23b
PP
273 free(plugin_path);
274}
275
cbb9e0b1
PP
276int main(int argc, char **argv)
277{
278 int ret;
279 const char *plugin_dir;
280
281 if (argc != 2) {
282 puts("Usage: test_plugin plugin_directory");
283 ret = 1;
284 goto end;
285 }
286
287 plugin_dir = argv[1];
288 plan_tests(NR_TESTS);
cbb9e0b1
PP
289 test_minimal(plugin_dir);
290 test_sfs(plugin_dir);
291 test_create_all_from_dir(plugin_dir);
2b43acf9 292 test_find(plugin_dir);
cbb9e0b1
PP
293 ret = exit_status();
294end:
295 return ret;
296}
This page took 0.075321 seconds and 4 git commands to generate.