Add query info API tests
[babeltrace.git] / tests / lib / test_plugin.c
1 /*
2 * test_plugin.c
3 *
4 * CTF IR Reference Count test
5 *
6 * Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; under version 2 of the License.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 */
21
22 #include <babeltrace/plugin/plugin.h>
23 #include <babeltrace/ref.h>
24 #include <babeltrace/values.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <stdio.h>
28 #include <assert.h>
29 #include <glib.h>
30 #include <linux/limits.h>
31 #include "tap/tap.h"
32 #include "common.h"
33
34 #define NR_TESTS 51
35 #define NON_EXISTING_PATH "/this/hopefully/does/not/exist/5bc75f8d-0dba-4043-a509-d7984b97e42b.so"
36
37 /* Those symbols are written to by some test plugins */
38 int test_plugin_init_called;
39 int test_plugin_exit_called;
40
41 static void reset_test_plugin_symbols(void)
42 {
43 test_plugin_init_called = 0;
44 test_plugin_exit_called = 0;
45 }
46
47 static char *get_test_plugin_path(const char *plugin_dir,
48 const char *plugin_name)
49 {
50 GString *path = g_string_new(plugin_dir);
51 char *ret;
52
53 assert(path);
54 g_string_append_printf(path, "/plugin-%s.so", plugin_name);
55 ret = path->str;
56 g_string_free(path, FALSE);
57 return ret;
58 }
59
60 static void test_invalid(const char *plugin_dir)
61 {
62 struct bt_plugin **plugins;
63
64 plugins = bt_plugin_create_all_from_file(NON_EXISTING_PATH);
65 ok(!plugins, "bt_plugin_create_all_from_file() fails with a non-existing file");
66
67 plugins = bt_plugin_create_all_from_file(plugin_dir);
68 ok(!plugins, "bt_plugin_create_all_from_file() fails with a directory");
69
70 ok(!bt_plugin_create_all_from_file(NULL),
71 "bt_plugin_create_all_from_file() handles NULL correctly");
72 ok(!bt_plugin_create_all_from_dir(NULL, false),
73 "bt_plugin_create_all_from_dir() handles NULL correctly");
74 ok(!bt_plugin_get_name(NULL),
75 "bt_plugin_get_name() handles NULL correctly");
76 ok(!bt_plugin_get_description(NULL),
77 "bt_plugin_get_description() handles NULL correctly");
78 ok(bt_plugin_get_version(NULL, NULL, NULL, NULL, NULL) !=
79 BT_PLUGIN_STATUS_OK,
80 "bt_plugin_get_version() handles NULL correctly");
81 ok(!bt_plugin_get_author(NULL),
82 "bt_plugin_get_author() handles NULL correctly");
83 ok(!bt_plugin_get_license(NULL),
84 "bt_plugin_get_license() handles NULL correctly");
85 ok(!bt_plugin_get_path(NULL),
86 "bt_plugin_get_path() handles NULL correctly");
87 ok(bt_plugin_get_component_class_count(NULL) < 0,
88 "bt_plugin_get_component_class_count() handles NULL correctly");
89 ok(!bt_plugin_get_component_class(NULL, 0),
90 "bt_plugin_get_component_class() handles NULL correctly");
91 ok(!bt_plugin_get_component_class_by_name_and_type(NULL, NULL, 0),
92 "bt_plugin_get_component_class_by_name_and_type() handles NULL correctly");
93 }
94
95 static void test_minimal(const char *plugin_dir)
96 {
97 struct bt_plugin **plugins;
98 struct bt_plugin *plugin;
99 char *minimal_path = get_test_plugin_path(plugin_dir, "minimal");
100
101 assert(minimal_path);
102 diag("minimal plugin test below");
103
104 reset_test_plugin_symbols();
105 plugins = bt_plugin_create_all_from_file(minimal_path);
106 ok(plugins && plugins[0], "bt_plugin_create_all_from_file() succeeds with a valid file");
107 ok(test_plugin_init_called, "plugin's initialization function is called during bt_plugin_create_all_from_file()");
108 ok(plugins && plugins[0] && !plugins[1],
109 "bt_plugin_create_all_from_file() returns the expected number of plugins");
110 plugin = plugins[0];
111 ok(strcmp(bt_plugin_get_name(plugin), "test_minimal") == 0,
112 "bt_plugin_get_name() returns the expected name");
113 ok(strcmp(bt_plugin_get_description(plugin),
114 "Minimal Babeltrace plugin with no component classes") == 0,
115 "bt_plugin_get_description() returns the expected description");
116 ok(bt_plugin_get_version(plugin, NULL, NULL, NULL, NULL) !=
117 BT_PLUGIN_STATUS_OK,
118 "bt_plugin_get_version() fails when there's no version");
119 ok(strcmp(bt_plugin_get_author(plugin), "Janine Sutto") == 0,
120 "bt_plugin_get_author() returns the expected author");
121 ok(strcmp(bt_plugin_get_license(plugin), "Beerware") == 0,
122 "bt_plugin_get_license() returns the expected license");
123 ok(strcmp(bt_plugin_get_path(plugin), minimal_path) == 0,
124 "bt_plugin_get_path() returns the expected path");
125 ok(bt_plugin_get_component_class_count(plugin) == 0,
126 "bt_plugin_get_component_class_count() returns the expected value");
127 BT_PUT(plugin);
128 ok(test_plugin_exit_called, "plugin's exit function is called when the plugin is destroyed");
129
130 free(minimal_path);
131 free(plugins);
132 }
133
134 static void test_sfs(const char *plugin_dir)
135 {
136 struct bt_plugin **plugins;
137 struct bt_plugin *plugin;
138 struct bt_component_class *sink_comp_class;
139 struct bt_component_class *source_comp_class;
140 struct bt_component_class *filter_comp_class;
141 struct bt_component *sink_component;
142 char *sfs_path = get_test_plugin_path(plugin_dir, "sfs");
143 unsigned int major, minor, patch;
144 const char *extra;
145 struct bt_value *params;
146 struct bt_value *results;
147 struct bt_value *action;
148 struct bt_value *res_params;
149 const char *action_str;
150 int ret;
151
152 assert(sfs_path);
153 diag("sfs plugin test below");
154
155 plugins = bt_plugin_create_all_from_file(sfs_path);
156 assert(plugins && plugins[0]);
157 plugin = plugins[0];
158 ok(bt_plugin_get_version(plugin, &major, &minor, &patch, &extra) ==
159 BT_PLUGIN_STATUS_OK,
160 "bt_plugin_get_version() succeeds when there's a version");
161 ok(major == 1,
162 "bt_plugin_get_version() returns the expected major version");
163 ok(minor == 2,
164 "bt_plugin_get_version() returns the expected minor version");
165 ok(patch == 3,
166 "bt_plugin_get_version() returns the expected patch version");
167 ok(strcmp(extra, "yes") == 0,
168 "bt_plugin_get_version() returns the expected extra version");
169 ok(bt_plugin_get_component_class_count(plugin) == 3,
170 "bt_plugin_get_component_class_count() returns the expected value");
171
172 source_comp_class = bt_plugin_get_component_class_by_name_and_type(
173 plugin, "source", BT_COMPONENT_CLASS_TYPE_SOURCE);
174 ok(source_comp_class,
175 "bt_plugin_get_component_class_by_name_and_type() finds a source component class");
176
177 sink_comp_class = bt_plugin_get_component_class_by_name_and_type(
178 plugin, "sink", BT_COMPONENT_CLASS_TYPE_SINK);
179 ok(sink_comp_class,
180 "bt_plugin_get_component_class_by_name_and_type() finds a sink component class");
181 ok(strcmp(bt_component_class_get_help(sink_comp_class),
182 "Bacon ipsum dolor amet strip steak cupim pastrami venison shoulder.\n"
183 "Prosciutto beef ribs flank meatloaf pancetta brisket kielbasa drumstick\n"
184 "venison tenderloin cow tail. Beef short loin shoulder meatball, sirloin\n"
185 "ground round brisket salami cupim pork bresaola turkey bacon boudin.\n") == 0,
186 "bt_component_class_get_help() returns the expected help text");
187
188 filter_comp_class = bt_plugin_get_component_class_by_name_and_type(
189 plugin, "filter", BT_COMPONENT_CLASS_TYPE_FILTER);
190 ok(filter_comp_class,
191 "bt_plugin_get_component_class_by_name_and_type() finds a filter component class");
192 ok(!bt_plugin_get_component_class_by_name_and_type(plugin, "filter",
193 BT_COMPONENT_CLASS_TYPE_SOURCE),
194 "bt_plugin_get_component_class_by_name_and_type() does not find a component class given the wrong type");
195 params = bt_value_integer_create_init(23);
196 assert(params);
197 ok (!bt_component_class_query_info(NULL, "get-something", params),
198 "bt_component_class_query_info() handles NULL (component class)");
199 ok (!bt_component_class_query_info(filter_comp_class, NULL, params),
200 "bt_component_class_query_info() handles NULL (action)");
201 ok (!bt_component_class_query_info(filter_comp_class, "get-something", NULL),
202 "bt_component_class_query_info() handles NULL (parameters)");
203 results = bt_component_class_query_info(filter_comp_class,
204 "get-something", params);
205 ok(results, "bt_component_class_query_info() succeeds");
206 assert(bt_value_is_array(results) && bt_value_array_size(results) == 2);
207 action = bt_value_array_get(results, 0);
208 assert(action && bt_value_is_string(action));
209 ret = bt_value_string_get(action, &action_str);
210 assert(ret == 0);
211 ok(strcmp(action_str, "get-something") == 0,
212 "bt_component_class_query_info() receives the expected action name");
213 res_params = bt_value_array_get(results, 1);
214 ok(res_params == params,
215 "bt_component_class_query_info() receives the expected parameters");
216
217 diag("> putting the plugin object here");
218 BT_PUT(plugin);
219 sink_component = bt_component_create(sink_comp_class, NULL, bt_value_null);
220 ok(sink_component, "bt_component_create() still works after the plugin object is destroyed");
221 BT_PUT(sink_component);
222 BT_PUT(source_comp_class);
223 sink_component = bt_component_create(sink_comp_class, NULL, bt_value_null);
224 ok(sink_component, "bt_component_create() still works after the source component class object is destroyed");
225 BT_PUT(sink_component);
226 BT_PUT(filter_comp_class);
227 sink_component = bt_component_create(sink_comp_class, NULL, bt_value_null);
228 ok(sink_component, "bt_component_create() still works after the filter component class object is destroyed");
229 BT_PUT(sink_comp_class);
230 BT_PUT(sink_component);
231
232 free(sfs_path);
233 free(plugins);
234 bt_put(action);
235 bt_put(res_params);
236 bt_put(results);
237 bt_put(params);
238 }
239
240 static void test_create_all_from_dir(const char *plugin_dir)
241 {
242 struct bt_plugin **plugins;
243 struct bt_plugin *plugin;
244 int i;
245
246 diag("create from all test below");
247
248 plugins = bt_plugin_create_all_from_dir(NON_EXISTING_PATH, false);
249 ok(!plugins,
250 "bt_plugin_create_all_from_dir() fails with an invalid path");
251
252 plugins = bt_plugin_create_all_from_dir(plugin_dir, false);
253 ok(plugins, "bt_plugin_create_all_from_dir() succeeds with a valid path");
254
255 i = 0;
256 while ((plugin = plugins[i])) {
257 BT_PUT(plugin);
258 i++;
259 }
260
261 /* 2 or 4, if `.la` files are considered or not */
262 ok(i == 2 || i == 4, "bt_plugin_create_all_from_dir() returns the expected number of plugin objects");
263
264 free(plugins);
265 }
266
267 static void test_create_from_name(const char *plugin_dir)
268 {
269 struct bt_plugin *plugin;
270 char *plugin_path;
271
272 ok(!bt_plugin_create_from_name(NULL),
273 "bt_plugin_create_from_name() handles NULL");
274 ok(!bt_plugin_create_from_name(NON_EXISTING_PATH),
275 "bt_plugin_create_from_name() returns NULL with an unknown plugin name");
276 plugin_path = malloc(PATH_MAX * 5);
277 assert(plugin_path);
278 sprintf(plugin_path, "%s:/ec1d09e5-696c-442e-b1c3-f9c6cf7f5958:::%s:8db46494-a398-466a-9649-c765ae077629:",
279 NON_EXISTING_PATH, plugin_dir);
280 setenv("BABELTRACE_PLUGIN_PATH", plugin_path, 1);
281 plugin = bt_plugin_create_from_name("test_minimal");
282 ok(plugin,
283 "bt_plugin_create_from_name() succeeds with a plugin name it can find");
284 ok(strcmp(bt_plugin_get_author(plugin), "Janine Sutto") == 0,
285 "bt_plugin_create_from_name() finds the correct plugin for a given name");
286 BT_PUT(plugin);
287 free(plugin_path);
288 }
289
290 int main(int argc, char **argv)
291 {
292 int ret;
293 const char *plugin_dir;
294
295 if (argc != 2) {
296 puts("Usage: test_plugin plugin_directory");
297 ret = 1;
298 goto end;
299 }
300
301 plugin_dir = argv[1];
302 plan_tests(NR_TESTS);
303 test_invalid(plugin_dir);
304 test_minimal(plugin_dir);
305 test_sfs(plugin_dir);
306 test_create_all_from_dir(plugin_dir);
307 test_create_from_name(plugin_dir);
308 ret = exit_status();
309 end:
310 return ret;
311 }
This page took 0.03975 seconds and 5 git commands to generate.