lib: strictly type function return status enumerations
[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_INIT_CALLED", "0", 1);
45 g_setenv("BT_TEST_PLUGIN_EXIT_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_INIT_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_EXIT_CALLED") == 1,
109 "plugin's exit 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 = bt_query_executor_create();
133 int ret;
134 bt_plugin_find_all_from_file_status status;
135
136 BT_ASSERT(query_exec);
137 BT_ASSERT(sfs_path);
138 diag("sfs plugin test below");
139
140 status = bt_plugin_find_all_from_file(sfs_path, BT_FALSE, &plugin_set);
141 BT_ASSERT(status == BT_PLUGIN_FIND_ALL_FROM_FILE_STATUS_OK &&
142 plugin_set && bt_plugin_set_get_plugin_count(plugin_set) == 1);
143 plugin = bt_plugin_set_borrow_plugin_by_index_const(plugin_set, 0);
144 ok(bt_plugin_get_version(plugin, &major, &minor, &patch, &extra) ==
145 BT_PROPERTY_AVAILABILITY_AVAILABLE,
146 "bt_plugin_get_version() succeeds when there's a version");
147 ok(major == 1,
148 "bt_plugin_get_version() returns the expected major version");
149 ok(minor == 2,
150 "bt_plugin_get_version() returns the expected minor version");
151 ok(patch == 3,
152 "bt_plugin_get_version() returns the expected patch version");
153 ok(strcmp(extra, "yes") == 0,
154 "bt_plugin_get_version() returns the expected extra version");
155 ok(bt_plugin_get_source_component_class_count(plugin) == 1,
156 "bt_plugin_get_source_component_class_count() returns the expected value");
157 ok(bt_plugin_get_filter_component_class_count(plugin) == 1,
158 "bt_plugin_get_filter_component_class_count() returns the expected value");
159 ok(bt_plugin_get_sink_component_class_count(plugin) == 1,
160 "bt_plugin_get_sink_component_class_count() returns the expected value");
161
162 source_comp_class = bt_plugin_borrow_source_component_class_by_name_const(
163 plugin, "source");
164 ok(source_comp_class,
165 "bt_plugin_borrow_source_component_class_by_name_const() finds a source component class");
166
167 sink_comp_class = bt_plugin_borrow_sink_component_class_by_name_const(
168 plugin, "sink");
169 ok(sink_comp_class,
170 "bt_plugin_borrow_sink_component_class_by_name_const() finds a sink component class");
171 ok(strcmp(bt_component_class_get_help(bt_component_class_sink_as_component_class_const(sink_comp_class)),
172 "Bacon ipsum dolor amet strip steak cupim pastrami venison shoulder.\n"
173 "Prosciutto beef ribs flank meatloaf pancetta brisket kielbasa drumstick\n"
174 "venison tenderloin cow tail. Beef short loin shoulder meatball, sirloin\n"
175 "ground round brisket salami cupim pork bresaola turkey bacon boudin.\n") == 0,
176 "bt_component_class_get_help() returns the expected help text");
177
178 filter_comp_class = bt_plugin_borrow_filter_component_class_by_name_const(
179 plugin, "filter");
180 ok(filter_comp_class,
181 "bt_plugin_borrow_filter_component_class_by_name_const() finds a filter component class");
182 params = bt_value_signed_integer_create_init(23);
183 BT_ASSERT(params);
184 ret = bt_query_executor_query(query_exec,
185 bt_component_class_filter_as_component_class_const(filter_comp_class),
186 "get-something", params, BT_LOGGING_LEVEL_NONE, &results);
187 ok(ret == 0 && results, "bt_query_executor_query() succeeds");
188 BT_ASSERT(bt_value_is_array(results) && bt_value_array_get_size(results) == 2);
189 object = bt_value_array_borrow_element_by_index_const(results, 0);
190 BT_ASSERT(object && bt_value_is_string(object));
191 object_str = bt_value_string_get(object);
192 ok(strcmp(object_str, "get-something") == 0,
193 "bt_component_class_query() receives the expected object name");
194 res_params = bt_value_array_borrow_element_by_index_const(results, 1);
195 ok(bt_value_compare(res_params, params),
196 "bt_component_class_query() receives the expected parameters");
197
198 bt_component_class_sink_get_ref(sink_comp_class);
199 diag("> putting the plugin set object here");
200 BT_PLUGIN_SET_PUT_REF_AND_RESET(plugin_set);
201 graph = bt_graph_create();
202 BT_ASSERT(graph);
203 graph_ret = bt_graph_add_sink_component(graph, sink_comp_class,
204 "the-sink", NULL, BT_LOGGING_LEVEL_NONE, &sink_component);
205 ok(graph_ret == BT_GRAPH_ADD_COMPONENT_STATUS_OK && sink_component,
206 "bt_graph_add_sink_component() still works after the plugin object is destroyed");
207 BT_COMPONENT_SINK_PUT_REF_AND_RESET(sink_component);
208 bt_graph_put_ref(graph);
209
210 free(sfs_path);
211 bt_component_class_sink_put_ref(sink_comp_class);
212 bt_value_put_ref(results);
213 bt_value_put_ref(params);
214 bt_query_executor_put_ref(query_exec);
215 }
216
217 static void test_create_all_from_dir(const char *plugin_dir)
218 {
219 const bt_plugin_set *plugin_set;
220 bt_plugin_find_all_from_dir_status status;
221
222 diag("create from all test below");
223
224 status = bt_plugin_find_all_from_dir(NON_EXISTING_PATH, BT_FALSE,
225 BT_FALSE, &plugin_set);
226 ok(status == BT_PLUGIN_FIND_ALL_FROM_DIR_STATUS_ERROR,
227 "bt_plugin_find_all_from_dir() fails with an invalid path");
228
229 plugin_set = NULL;
230 status = bt_plugin_find_all_from_dir(plugin_dir, BT_FALSE, BT_FALSE,
231 &plugin_set);
232 ok(status == BT_PLUGIN_FIND_ALL_FROM_DIR_STATUS_OK,
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");
236
237 /* 2 or 4, if `.la` files are considered or not */
238 ok(bt_plugin_set_get_plugin_count(plugin_set) == 2 ||
239 bt_plugin_set_get_plugin_count(plugin_set) == 4,
240 "bt_plugin_find_all_from_dir() returns the expected number of plugin objects");
241
242 bt_plugin_set_put_ref(plugin_set);
243 }
244
245 static void test_find(const char *plugin_dir)
246 {
247 int ret;
248 const bt_plugin *plugin;
249 char *plugin_path;
250 bt_plugin_find_status status;
251
252 ok(bt_plugin_find(NON_EXISTING_PATH, BT_FALSE, &plugin) ==
253 BT_PLUGIN_FIND_STATUS_NOT_FOUND,
254 "bt_plugin_find() returns BT_PLUGIN_STATUS_NOT_FOUND with an unknown plugin name");
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,
261 NON_EXISTING_PATH, plugin_dir);
262 BT_ASSERT(ret > 0 && plugin_path);
263 g_setenv("BABELTRACE_PLUGIN_PATH", plugin_path, 1);
264 plugin = NULL;
265 status = bt_plugin_find("test_minimal", BT_FALSE, &plugin);
266 ok(status == BT_PLUGIN_FIND_STATUS_OK,
267 "bt_plugin_find() succeeds with a plugin name it can find");
268 ok(plugin, "bt_plugin_find() returns a plugin object");
269 ok(strcmp(bt_plugin_get_author(plugin), "Janine Sutto") == 0,
270 "bt_plugin_find() finds the correct plugin for a given name");
271 BT_PLUGIN_PUT_REF_AND_RESET(plugin);
272 free(plugin_path);
273 }
274
275 int main(int argc, char **argv)
276 {
277 int ret;
278 const char *plugin_dir;
279
280 if (argc != 2) {
281 puts("Usage: test_plugin plugin_directory");
282 ret = 1;
283 goto end;
284 }
285
286 plugin_dir = argv[1];
287 plan_tests(NR_TESTS);
288 test_minimal(plugin_dir);
289 test_sfs(plugin_dir);
290 test_create_all_from_dir(plugin_dir);
291 test_find(plugin_dir);
292 ret = exit_status();
293 end:
294 return ret;
295 }
This page took 0.035437 seconds and 4 git commands to generate.