d5a21808fbbfdda25c4176525f7600c562c25484
[babeltrace.git] / tests / lib / plugin.c
1 /*
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
18 #include <babeltrace2/babeltrace.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include <stdio.h>
22 #include "common/assert.h"
23 #include <glib.h>
24 #include "tap/tap.h"
25 #include "common.h"
26
27 #define NR_TESTS 38
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 */
31 static 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 }
41
42 static void reset_test_plugin_env_vars(void)
43 {
44 g_setenv("BT_TEST_PLUGIN_INITIALIZE_CALLED", "0", 1);
45 g_setenv("BT_TEST_PLUGIN_FINALIZE_CALLED", "0", 1);
46 }
47
48 static char *get_test_plugin_path(const char *plugin_dir,
49 const char *plugin_name)
50 {
51 char *ret;
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);
61
62 return ret;
63 }
64
65 static void test_minimal(const char *plugin_dir)
66 {
67 const bt_plugin_set *plugin_set = NULL;
68 const bt_plugin *plugin;
69 char *minimal_path = get_test_plugin_path(plugin_dir, "minimal");
70 bt_plugin_find_all_from_file_status status;
71
72 BT_ASSERT(minimal_path);
73 diag("minimal plugin test below");
74
75 reset_test_plugin_env_vars();
76 status = bt_plugin_find_all_from_file(minimal_path, BT_FALSE,
77 &plugin_set);
78 ok(status == BT_PLUGIN_FIND_ALL_FROM_FILE_STATUS_OK,
79 "bt_plugin_find_all_from_file() succeeds with a valid file");
80 ok(plugin_set,
81 "bt_plugin_find_all_from_file() returns a plugin set");
82 ok(check_env_var("BT_TEST_PLUGIN_INITIALIZE_CALLED") == 1,
83 "plugin's initialization function is called during bt_plugin_find_all_from_file()");
84 ok(bt_plugin_set_get_plugin_count(plugin_set) == 1,
85 "bt_plugin_find_all_from_file() returns the expected number of plugins");
86 plugin = bt_plugin_set_borrow_plugin_by_index_const(plugin_set, 0);
87 ok(strcmp(bt_plugin_get_name(plugin), "test_minimal") == 0,
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");
92 ok(bt_plugin_get_version(plugin, NULL, NULL, NULL, NULL) ==
93 BT_PROPERTY_AVAILABILITY_NOT_AVAILABLE,
94 "bt_plugin_get_version() fails when there's no version");
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");
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");
107 bt_plugin_set_put_ref(plugin_set);
108 ok(check_env_var("BT_TEST_PLUGIN_FINALIZE_CALLED") == 1,
109 "plugin's finalize function is called when the plugin is destroyed");
110
111 free(minimal_path);
112 }
113
114 static void test_sfs(const char *plugin_dir)
115 {
116 const bt_plugin_set *plugin_set = NULL;
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;
122 char *sfs_path = get_test_plugin_path(plugin_dir, "sfs");
123 unsigned int major, minor, patch;
124 const char *extra;
125 bt_value *params;
126 const bt_value *results;
127 const bt_value *object;
128 const bt_value *res_params;
129 bt_graph *graph;
130 const char *object_str;
131 bt_graph_add_component_status graph_ret;
132 bt_query_executor *query_exec;
133 int ret;
134 bt_plugin_find_all_from_file_status status;
135
136 BT_ASSERT(sfs_path);
137 diag("sfs plugin test below");
138
139 status = bt_plugin_find_all_from_file(sfs_path, BT_FALSE, &plugin_set);
140 BT_ASSERT(status == BT_PLUGIN_FIND_ALL_FROM_FILE_STATUS_OK &&
141 plugin_set && bt_plugin_set_get_plugin_count(plugin_set) == 1);
142 plugin = bt_plugin_set_borrow_plugin_by_index_const(plugin_set, 0);
143 ok(bt_plugin_get_version(plugin, &major, &minor, &patch, &extra) ==
144 BT_PROPERTY_AVAILABILITY_AVAILABLE,
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");
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
161 source_comp_class = bt_plugin_borrow_source_component_class_by_name_const(
162 plugin, "source");
163 ok(source_comp_class,
164 "bt_plugin_borrow_source_component_class_by_name_const() finds a source component class");
165
166 sink_comp_class = bt_plugin_borrow_sink_component_class_by_name_const(
167 plugin, "sink");
168 ok(sink_comp_class,
169 "bt_plugin_borrow_sink_component_class_by_name_const() finds a sink component class");
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,
175 "bt_component_class_get_help() returns the expected help text");
176
177 filter_comp_class = bt_plugin_borrow_filter_component_class_by_name_const(
178 plugin, "filter");
179 ok(filter_comp_class,
180 "bt_plugin_borrow_filter_component_class_by_name_const() finds a filter component class");
181 params = bt_value_integer_signed_create_init(23);
182 BT_ASSERT(params);
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);
188 ok(ret == 0 && results, "bt_query_executor_query() succeeds");
189 BT_ASSERT(bt_value_is_array(results) && bt_value_array_get_length(results) == 2);
190 object = bt_value_array_borrow_element_by_index_const(results, 0);
191 BT_ASSERT(object && bt_value_is_string(object));
192 object_str = bt_value_string_get(object);
193 ok(strcmp(object_str, "get-something") == 0,
194 "bt_component_class_query() receives the expected object name");
195 res_params = bt_value_array_borrow_element_by_index_const(results, 1);
196 ok(bt_value_compare(res_params, params),
197 "bt_component_class_query() receives the expected parameters");
198
199 bt_component_class_sink_get_ref(sink_comp_class);
200 diag("> putting the plugin set object here");
201 BT_PLUGIN_SET_PUT_REF_AND_RESET(plugin_set);
202 graph = bt_graph_create(0);
203 BT_ASSERT(graph);
204 graph_ret = bt_graph_add_sink_component(graph, sink_comp_class,
205 "the-sink", NULL, BT_LOGGING_LEVEL_NONE, &sink_component);
206 ok(graph_ret == BT_GRAPH_ADD_COMPONENT_STATUS_OK && sink_component,
207 "bt_graph_add_sink_component() still works after the plugin object is destroyed");
208 BT_COMPONENT_SINK_PUT_REF_AND_RESET(sink_component);
209 bt_graph_put_ref(graph);
210
211 free(sfs_path);
212 bt_component_class_sink_put_ref(sink_comp_class);
213 bt_value_put_ref(results);
214 bt_value_put_ref(params);
215 bt_query_executor_put_ref(query_exec);
216 }
217
218 static void test_create_all_from_dir(const char *plugin_dir)
219 {
220 const bt_plugin_set *plugin_set;
221 bt_plugin_find_all_from_dir_status status;
222
223 diag("create from all test below");
224
225 status = bt_plugin_find_all_from_dir(NON_EXISTING_PATH, BT_FALSE,
226 BT_FALSE, &plugin_set);
227 ok(status == BT_PLUGIN_FIND_ALL_FROM_DIR_STATUS_ERROR,
228 "bt_plugin_find_all_from_dir() fails with an invalid path");
229 bt_current_thread_clear_error();
230
231 plugin_set = NULL;
232 status = bt_plugin_find_all_from_dir(plugin_dir, BT_FALSE, BT_FALSE,
233 &plugin_set);
234 ok(status == BT_PLUGIN_FIND_ALL_FROM_DIR_STATUS_OK,
235 "bt_plugin_find_all_from_dir() succeeds with a valid path");
236 ok(plugin_set,
237 "bt_plugin_find_all_from_dir() returns a plugin set with a valid path");
238
239 /* 2 or 4, if `.la` files are considered or not */
240 ok(bt_plugin_set_get_plugin_count(plugin_set) == 2 ||
241 bt_plugin_set_get_plugin_count(plugin_set) == 4,
242 "bt_plugin_find_all_from_dir() returns the expected number of plugin objects");
243
244 bt_plugin_set_put_ref(plugin_set);
245 }
246
247 static void test_find(const char *plugin_dir)
248 {
249 int ret;
250 const bt_plugin *plugin;
251 char *plugin_path;
252 bt_plugin_find_status status;
253
254 ok(bt_plugin_find(NON_EXISTING_PATH, BT_TRUE, BT_FALSE, BT_FALSE,
255 BT_FALSE, BT_FALSE, &plugin) == BT_PLUGIN_FIND_STATUS_NOT_FOUND,
256 "bt_plugin_find() returns BT_PLUGIN_STATUS_NOT_FOUND with an unknown plugin name");
257 ret = asprintf(&plugin_path, "%s" G_SEARCHPATH_SEPARATOR_S
258 G_DIR_SEPARATOR_S "ec1d09e5-696c-442e-b1c3-f9c6cf7f5958"
259 G_SEARCHPATH_SEPARATOR_S G_SEARCHPATH_SEPARATOR_S
260 G_SEARCHPATH_SEPARATOR_S "%s" G_SEARCHPATH_SEPARATOR_S
261 "8db46494-a398-466a-9649-c765ae077629"
262 G_SEARCHPATH_SEPARATOR_S,
263 NON_EXISTING_PATH, plugin_dir);
264 BT_ASSERT(ret > 0 && plugin_path);
265 g_setenv("BABELTRACE_PLUGIN_PATH", plugin_path, 1);
266 plugin = NULL;
267 status = bt_plugin_find("test_minimal", BT_TRUE, BT_FALSE, BT_FALSE,
268 BT_FALSE, BT_FALSE, &plugin);
269 ok(status == BT_PLUGIN_FIND_STATUS_OK,
270 "bt_plugin_find() succeeds with a plugin name it can find");
271 ok(plugin, "bt_plugin_find() returns a plugin object");
272 ok(strcmp(bt_plugin_get_author(plugin), "Janine Sutto") == 0,
273 "bt_plugin_find() finds the correct plugin for a given name");
274 BT_PLUGIN_PUT_REF_AND_RESET(plugin);
275 free(plugin_path);
276 }
277
278 int main(int argc, char **argv)
279 {
280 int ret;
281 const char *plugin_dir;
282
283 if (argc != 2) {
284 puts("Usage: test_plugin plugin_directory");
285 ret = 1;
286 goto end;
287 }
288
289 plugin_dir = argv[1];
290 plan_tests(NR_TESTS);
291 test_minimal(plugin_dir);
292 test_sfs(plugin_dir);
293 test_create_all_from_dir(plugin_dir);
294 test_find(plugin_dir);
295 ret = exit_status();
296 end:
297 return ret;
298 }
This page took 0.035705 seconds and 3 git commands to generate.