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