lib: make public reference count functions have strict types
[babeltrace.git] / tests / lib / test_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 <babeltrace/babeltrace.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include <stdio.h>
22 #include <babeltrace/assert-internal.h>
23 #include <glib.h>
24 #include "tap/tap.h"
25 #include "common.h"
26
27 #define NR_TESTS 35
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 struct bt_plugin_set *plugin_set;
68 const struct bt_plugin *plugin;
69 char *minimal_path = get_test_plugin_path(plugin_dir, "minimal");
70
71 BT_ASSERT(minimal_path);
72 diag("minimal plugin test below");
73
74 reset_test_plugin_env_vars();
75 plugin_set = bt_plugin_create_all_from_file(minimal_path);
76 ok(plugin_set && bt_plugin_set_get_plugin_count(plugin_set) == 1,
77 "bt_plugin_create_all_from_file() succeeds with a valid file");
78 ok(check_env_var("BT_TEST_PLUGIN_INIT_CALLED") == 1,
79 "plugin's initialization function is called during bt_plugin_create_all_from_file()");
80 ok(bt_plugin_set_get_plugin_count(plugin_set) == 1,
81 "bt_plugin_create_all_from_file() returns the expected number of plugins");
82 plugin = bt_plugin_set_borrow_plugin_by_index_const(plugin_set, 0);
83 ok(strcmp(bt_plugin_get_name(plugin), "test_minimal") == 0,
84 "bt_plugin_get_name() returns the expected name");
85 ok(strcmp(bt_plugin_get_description(plugin),
86 "Minimal Babeltrace plugin with no component classes") == 0,
87 "bt_plugin_get_description() returns the expected description");
88 ok(bt_plugin_get_version(plugin, NULL, NULL, NULL, NULL) ==
89 BT_PROPERTY_AVAILABILITY_NOT_AVAILABLE,
90 "bt_plugin_get_version() fails when there's no version");
91 ok(strcmp(bt_plugin_get_author(plugin), "Janine Sutto") == 0,
92 "bt_plugin_get_author() returns the expected author");
93 ok(strcmp(bt_plugin_get_license(plugin), "Beerware") == 0,
94 "bt_plugin_get_license() returns the expected license");
95 ok(strcmp(bt_plugin_get_path(plugin), minimal_path) == 0,
96 "bt_plugin_get_path() returns the expected path");
97 ok(bt_plugin_get_source_component_class_count(plugin) == 0,
98 "bt_plugin_get_source_component_class_count() returns the expected value");
99 ok(bt_plugin_get_filter_component_class_count(plugin) == 0,
100 "bt_plugin_get_filter_component_class_count() returns the expected value");
101 ok(bt_plugin_get_sink_component_class_count(plugin) == 0,
102 "bt_plugin_get_sink_component_class_count() returns the expected value");
103 bt_plugin_set_put_ref(plugin_set);
104 ok(check_env_var("BT_TEST_PLUGIN_EXIT_CALLED") == 1,
105 "plugin's exit function is called when the plugin is destroyed");
106
107 free(minimal_path);
108 }
109
110 static void test_sfs(const char *plugin_dir)
111 {
112 const struct bt_plugin_set *plugin_set;
113 const struct bt_plugin *plugin;
114 const struct bt_component_class_sink *sink_comp_class;
115 const struct bt_component_class_source *source_comp_class;
116 const struct bt_component_class_filter *filter_comp_class;
117 const struct bt_component_sink *sink_component;
118 char *sfs_path = get_test_plugin_path(plugin_dir, "sfs");
119 unsigned int major, minor, patch;
120 const char *extra;
121 struct bt_value *params;
122 const struct bt_value *results;
123 const struct bt_value *object;
124 const struct bt_value *res_params;
125 struct bt_graph *graph;
126 const char *object_str;
127 enum bt_graph_status graph_ret;
128 struct bt_query_executor *query_exec = bt_query_executor_create();
129 int ret;
130
131 BT_ASSERT(query_exec);
132 BT_ASSERT(sfs_path);
133 diag("sfs plugin test below");
134
135 plugin_set = bt_plugin_create_all_from_file(sfs_path);
136 BT_ASSERT(plugin_set && bt_plugin_set_get_plugin_count(plugin_set) == 1);
137 plugin = bt_plugin_set_borrow_plugin_by_index_const(plugin_set, 0);
138 ok(bt_plugin_get_version(plugin, &major, &minor, &patch, &extra) ==
139 BT_PROPERTY_AVAILABILITY_AVAILABLE,
140 "bt_plugin_get_version() succeeds when there's a version");
141 ok(major == 1,
142 "bt_plugin_get_version() returns the expected major version");
143 ok(minor == 2,
144 "bt_plugin_get_version() returns the expected minor version");
145 ok(patch == 3,
146 "bt_plugin_get_version() returns the expected patch version");
147 ok(strcmp(extra, "yes") == 0,
148 "bt_plugin_get_version() returns the expected extra version");
149 ok(bt_plugin_get_source_component_class_count(plugin) == 1,
150 "bt_plugin_get_source_component_class_count() returns the expected value");
151 ok(bt_plugin_get_filter_component_class_count(plugin) == 1,
152 "bt_plugin_get_filter_component_class_count() returns the expected value");
153 ok(bt_plugin_get_sink_component_class_count(plugin) == 1,
154 "bt_plugin_get_sink_component_class_count() returns the expected value");
155
156 source_comp_class = bt_plugin_borrow_source_component_class_by_name_const(
157 plugin, "source");
158 ok(source_comp_class,
159 "bt_plugin_borrow_source_component_class_by_name_const() finds a source component class");
160
161 sink_comp_class = bt_plugin_borrow_sink_component_class_by_name_const(
162 plugin, "sink");
163 ok(sink_comp_class,
164 "bt_plugin_borrow_sink_component_class_by_name_const() finds a sink component class");
165 ok(strcmp(bt_component_class_get_help(bt_component_class_sink_as_component_class_const(sink_comp_class)),
166 "Bacon ipsum dolor amet strip steak cupim pastrami venison shoulder.\n"
167 "Prosciutto beef ribs flank meatloaf pancetta brisket kielbasa drumstick\n"
168 "venison tenderloin cow tail. Beef short loin shoulder meatball, sirloin\n"
169 "ground round brisket salami cupim pork bresaola turkey bacon boudin.\n") == 0,
170 "bt_component_class_get_help() returns the expected help text");
171
172 filter_comp_class = bt_plugin_borrow_filter_component_class_by_name_const(
173 plugin, "filter");
174 ok(filter_comp_class,
175 "bt_plugin_borrow_filter_component_class_by_name_const() finds a filter component class");
176 params = bt_value_integer_create_init(23);
177 BT_ASSERT(params);
178 ret = bt_query_executor_query(query_exec,
179 bt_component_class_filter_as_component_class_const(filter_comp_class),
180 "get-something", params, &results);
181 ok(ret == 0 && results, "bt_query_executor_query() succeeds");
182 BT_ASSERT(bt_value_is_array(results) && bt_value_array_get_size(results) == 2);
183 object = bt_value_array_borrow_element_by_index_const(results, 0);
184 BT_ASSERT(object && bt_value_is_string(object));
185 object_str = bt_value_string_get(object);
186 ok(strcmp(object_str, "get-something") == 0,
187 "bt_component_class_query() receives the expected object name");
188 res_params = bt_value_array_borrow_element_by_index_const(results, 1);
189 ok(bt_value_compare(res_params, params),
190 "bt_component_class_query() receives the expected parameters");
191
192 bt_component_class_sink_get_ref(sink_comp_class);
193 diag("> putting the plugin set object here");
194 BT_PLUGIN_SET_PUT_REF_AND_RESET(plugin_set);
195 graph = bt_graph_create();
196 BT_ASSERT(graph);
197 graph_ret = bt_graph_add_sink_component(graph, sink_comp_class,
198 "the-sink", NULL, &sink_component);
199 ok(graph_ret == BT_GRAPH_STATUS_OK && sink_component,
200 "bt_graph_add_sink_component() still works after the plugin object is destroyed");
201 BT_COMPONENT_SINK_PUT_REF_AND_RESET(sink_component);
202 bt_graph_put_ref(graph);
203
204 free(sfs_path);
205 bt_component_class_sink_put_ref(sink_comp_class);
206 bt_value_put_ref(results);
207 bt_value_put_ref(params);
208 bt_query_executor_put_ref(query_exec);
209 }
210
211 static void test_create_all_from_dir(const char *plugin_dir)
212 {
213 const struct bt_plugin_set *plugin_set;
214
215 diag("create from all test below");
216
217 plugin_set = bt_plugin_create_all_from_dir(NON_EXISTING_PATH, BT_FALSE);
218 ok(!plugin_set,
219 "bt_plugin_create_all_from_dir() fails with an invalid path");
220
221 plugin_set = bt_plugin_create_all_from_dir(plugin_dir, BT_FALSE);
222 ok(plugin_set, "bt_plugin_create_all_from_dir() succeeds with a valid path");
223
224 /* 2 or 4, if `.la` files are considered or not */
225 ok(bt_plugin_set_get_plugin_count(plugin_set) == 2 ||
226 bt_plugin_set_get_plugin_count(plugin_set) == 4,
227 "bt_plugin_create_all_from_dir() returns the expected number of plugin objects");
228
229 bt_plugin_set_put_ref(plugin_set);
230 }
231
232 static void test_find(const char *plugin_dir)
233 {
234 int ret;
235 const struct bt_plugin *plugin;
236 char *plugin_path;
237
238 ok(!bt_plugin_find(NON_EXISTING_PATH),
239 "bt_plugin_find() returns NULL with an unknown plugin name");
240 ret = asprintf(&plugin_path, "%s" G_SEARCHPATH_SEPARATOR_S
241 G_DIR_SEPARATOR_S "ec1d09e5-696c-442e-b1c3-f9c6cf7f5958"
242 G_SEARCHPATH_SEPARATOR_S G_SEARCHPATH_SEPARATOR_S
243 G_SEARCHPATH_SEPARATOR_S "%s" G_SEARCHPATH_SEPARATOR_S
244 "8db46494-a398-466a-9649-c765ae077629"
245 G_SEARCHPATH_SEPARATOR_S,
246 NON_EXISTING_PATH, plugin_dir);
247 BT_ASSERT(ret > 0 && plugin_path);
248 g_setenv("BABELTRACE_PLUGIN_PATH", plugin_path, 1);
249 plugin = bt_plugin_find("test_minimal");
250 ok(plugin,
251 "bt_plugin_find() succeeds with a plugin name it can find");
252 ok(strcmp(bt_plugin_get_author(plugin), "Janine Sutto") == 0,
253 "bt_plugin_find() finds the correct plugin for a given name");
254 BT_PLUGIN_PUT_REF_AND_RESET(plugin);
255 free(plugin_path);
256 }
257
258 int main(int argc, char **argv)
259 {
260 int ret;
261 const char *plugin_dir;
262
263 if (argc != 2) {
264 puts("Usage: test_plugin plugin_directory");
265 ret = 1;
266 goto end;
267 }
268
269 plugin_dir = argv[1];
270 plan_tests(NR_TESTS);
271 test_minimal(plugin_dir);
272 test_sfs(plugin_dir);
273 test_create_all_from_dir(plugin_dir);
274 test_find(plugin_dir);
275 ret = exit_status();
276 end:
277 return ret;
278 }
This page took 0.034744 seconds and 4 git commands to generate.