Standardize *get_*() functions
[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 <babeltrace/graph/component.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <stdio.h>
29 #include <assert.h>
30 #include <glib.h>
31 #include <linux/limits.h>
32 #include "tap/tap.h"
33 #include "common.h"
34
35 #define NR_TESTS 58
36 #define NON_EXISTING_PATH "/this/hopefully/does/not/exist/5bc75f8d-0dba-4043-a509-d7984b97e42b.so"
37
38 /* Those symbols are written to by some test plugins */
39 int test_plugin_init_called;
40 int test_plugin_exit_called;
41
42 static void reset_test_plugin_symbols(void)
43 {
44 test_plugin_init_called = 0;
45 test_plugin_exit_called = 0;
46 }
47
48 static char *get_test_plugin_path(const char *plugin_dir,
49 const char *plugin_name)
50 {
51 GString *path = g_string_new(plugin_dir);
52 char *ret;
53
54 assert(path);
55 g_string_append_printf(path, "/plugin-%s.so", plugin_name);
56 ret = path->str;
57 g_string_free(path, FALSE);
58 return ret;
59 }
60
61 static void test_invalid(const char *plugin_dir)
62 {
63 struct bt_plugin_set *plugin_set;
64
65 plugin_set = bt_plugin_create_all_from_file(NON_EXISTING_PATH);
66 ok(!plugin_set, "bt_plugin_create_all_from_file() fails with a non-existing file");
67
68 plugin_set = bt_plugin_create_all_from_file(plugin_dir);
69 ok(!plugin_set, "bt_plugin_create_all_from_file() fails with a directory");
70
71 ok(!bt_plugin_create_all_from_file(NULL),
72 "bt_plugin_create_all_from_file() handles NULL correctly");
73 ok(!bt_plugin_create_all_from_dir(NULL, false),
74 "bt_plugin_create_all_from_dir() handles NULL correctly");
75 ok(!bt_plugin_get_name(NULL),
76 "bt_plugin_get_name() handles NULL correctly");
77 ok(!bt_plugin_get_description(NULL),
78 "bt_plugin_get_description() handles NULL correctly");
79 ok(bt_plugin_get_version(NULL, NULL, NULL, NULL, NULL) !=
80 BT_PLUGIN_STATUS_OK,
81 "bt_plugin_get_version() handles NULL correctly");
82 ok(!bt_plugin_get_author(NULL),
83 "bt_plugin_get_author() handles NULL correctly");
84 ok(!bt_plugin_get_license(NULL),
85 "bt_plugin_get_license() handles NULL correctly");
86 ok(!bt_plugin_get_path(NULL),
87 "bt_plugin_get_path() handles NULL correctly");
88 ok(bt_plugin_get_component_class_count(NULL) < 0,
89 "bt_plugin_get_component_class_count() handles NULL correctly");
90 ok(!bt_plugin_get_component_class_by_index(NULL, 0),
91 "bt_plugin_get_component_class_by_index() handles NULL correctly");
92 ok(!bt_plugin_get_component_class_by_name_and_type(NULL, NULL, 0),
93 "bt_plugin_get_component_class_by_name_and_type() handles NULL correctly");
94 }
95
96 static void test_minimal(const char *plugin_dir)
97 {
98 struct bt_plugin_set *plugin_set;
99 struct bt_plugin *plugin;
100 char *minimal_path = get_test_plugin_path(plugin_dir, "minimal");
101
102 assert(minimal_path);
103 diag("minimal plugin test below");
104
105 reset_test_plugin_symbols();
106 plugin_set = bt_plugin_create_all_from_file(minimal_path);
107 ok(plugin_set && bt_plugin_set_get_plugin_count(plugin_set) == 1,
108 "bt_plugin_create_all_from_file() succeeds with a valid file");
109 ok(test_plugin_init_called, "plugin's initialization function is called during bt_plugin_create_all_from_file()");
110 ok(bt_plugin_set_get_plugin_count(plugin_set) == 1,
111 "bt_plugin_create_all_from_file() returns the expected number of plugins");
112 plugin = bt_plugin_set_get_plugin(plugin_set, 0);
113 ok(strcmp(bt_plugin_get_name(plugin), "test_minimal") == 0,
114 "bt_plugin_get_name() returns the expected name");
115 ok(strcmp(bt_plugin_get_description(plugin),
116 "Minimal Babeltrace plugin with no component classes") == 0,
117 "bt_plugin_get_description() returns the expected description");
118 ok(bt_plugin_get_version(plugin, NULL, NULL, NULL, NULL) !=
119 BT_PLUGIN_STATUS_OK,
120 "bt_plugin_get_version() fails when there's no version");
121 ok(strcmp(bt_plugin_get_author(plugin), "Janine Sutto") == 0,
122 "bt_plugin_get_author() returns the expected author");
123 ok(strcmp(bt_plugin_get_license(plugin), "Beerware") == 0,
124 "bt_plugin_get_license() returns the expected license");
125 ok(strcmp(bt_plugin_get_path(plugin), minimal_path) == 0,
126 "bt_plugin_get_path() returns the expected path");
127 ok(bt_plugin_get_component_class_count(plugin) == 0,
128 "bt_plugin_get_component_class_count() returns the expected value");
129 bt_put(plugin);
130 bt_put(plugin_set);
131 ok(test_plugin_exit_called, "plugin's exit function is called when the plugin is destroyed");
132
133 free(minimal_path);
134 }
135
136 static void test_sfs(const char *plugin_dir)
137 {
138 struct bt_plugin_set *plugin_set;
139 struct bt_plugin *plugin;
140 struct bt_component_class *sink_comp_class;
141 struct bt_component_class *source_comp_class;
142 struct bt_component_class *filter_comp_class;
143 struct bt_component *sink_component;
144 char *sfs_path = get_test_plugin_path(plugin_dir, "sfs");
145 unsigned int major, minor, patch;
146 const char *extra;
147 struct bt_value *params;
148 struct bt_value *results;
149 struct bt_value *object;
150 struct bt_value *res_params;
151 const char *object_str;
152 int ret;
153
154 assert(sfs_path);
155 diag("sfs plugin test below");
156
157 plugin_set = bt_plugin_create_all_from_file(sfs_path);
158 assert(plugin_set && bt_plugin_set_get_plugin_count(plugin_set) == 1);
159 plugin = bt_plugin_set_get_plugin(plugin_set, 0);
160 ok(bt_plugin_get_version(plugin, &major, &minor, &patch, &extra) ==
161 BT_PLUGIN_STATUS_OK,
162 "bt_plugin_get_version() succeeds when there's a version");
163 ok(major == 1,
164 "bt_plugin_get_version() returns the expected major version");
165 ok(minor == 2,
166 "bt_plugin_get_version() returns the expected minor version");
167 ok(patch == 3,
168 "bt_plugin_get_version() returns the expected patch version");
169 ok(strcmp(extra, "yes") == 0,
170 "bt_plugin_get_version() returns the expected extra version");
171 ok(bt_plugin_get_component_class_count(plugin) == 3,
172 "bt_plugin_get_component_class_count() returns the expected value");
173
174 source_comp_class = bt_plugin_get_component_class_by_name_and_type(
175 plugin, "source", BT_COMPONENT_CLASS_TYPE_SOURCE);
176 ok(source_comp_class,
177 "bt_plugin_get_component_class_by_name_and_type() finds a source component class");
178
179 sink_comp_class = bt_plugin_get_component_class_by_name_and_type(
180 plugin, "sink", BT_COMPONENT_CLASS_TYPE_SINK);
181 ok(sink_comp_class,
182 "bt_plugin_get_component_class_by_name_and_type() finds a sink component class");
183 ok(strcmp(bt_component_class_get_help(sink_comp_class),
184 "Bacon ipsum dolor amet strip steak cupim pastrami venison shoulder.\n"
185 "Prosciutto beef ribs flank meatloaf pancetta brisket kielbasa drumstick\n"
186 "venison tenderloin cow tail. Beef short loin shoulder meatball, sirloin\n"
187 "ground round brisket salami cupim pork bresaola turkey bacon boudin.\n") == 0,
188 "bt_component_class_get_help() returns the expected help text");
189
190 filter_comp_class = bt_plugin_get_component_class_by_name_and_type(
191 plugin, "filter", BT_COMPONENT_CLASS_TYPE_FILTER);
192 ok(filter_comp_class,
193 "bt_plugin_get_component_class_by_name_and_type() finds a filter component class");
194 ok(!bt_plugin_get_component_class_by_name_and_type(plugin, "filter",
195 BT_COMPONENT_CLASS_TYPE_SOURCE),
196 "bt_plugin_get_component_class_by_name_and_type() does not find a component class given the wrong type");
197 params = bt_value_integer_create_init(23);
198 assert(params);
199 ok (!bt_component_class_query(NULL, "get-something", params),
200 "bt_component_class_query() handles NULL (component class)");
201 ok (!bt_component_class_query(filter_comp_class, NULL, params),
202 "bt_component_class_query() handles NULL (object)");
203 ok (!bt_component_class_query(filter_comp_class, "get-something", NULL),
204 "bt_component_class_query() handles NULL (parameters)");
205 results = bt_component_class_query(filter_comp_class,
206 "get-something", params);
207 ok(results, "bt_component_class_query() succeeds");
208 assert(bt_value_is_array(results) && bt_value_array_size(results) == 2);
209 object = bt_value_array_get(results, 0);
210 assert(object && bt_value_is_string(object));
211 ret = bt_value_string_get(object, &object_str);
212 assert(ret == 0);
213 ok(strcmp(object_str, "get-something") == 0,
214 "bt_component_class_query() receives the expected object name");
215 res_params = bt_value_array_get(results, 1);
216 ok(res_params == params,
217 "bt_component_class_query() receives the expected parameters");
218
219 diag("> putting the plugin object here");
220 BT_PUT(plugin);
221 sink_component = bt_component_create(sink_comp_class, NULL, NULL);
222 ok(sink_component, "bt_component_create() still works after the plugin object is destroyed");
223 BT_PUT(sink_component);
224 BT_PUT(source_comp_class);
225 sink_component = bt_component_create(sink_comp_class, NULL, NULL);
226 ok(sink_component, "bt_component_create() still works after the source component class object is destroyed");
227 BT_PUT(sink_component);
228 BT_PUT(filter_comp_class);
229 sink_component = bt_component_create(sink_comp_class, NULL, NULL);
230 ok(sink_component, "bt_component_create() still works after the filter component class object is destroyed");
231 BT_PUT(sink_comp_class);
232 BT_PUT(sink_component);
233
234 free(sfs_path);
235 bt_put(plugin_set);
236 bt_put(object);
237 bt_put(res_params);
238 bt_put(results);
239 bt_put(params);
240 }
241
242 static void test_create_all_from_dir(const char *plugin_dir)
243 {
244 struct bt_plugin_set *plugin_set;
245
246 diag("create from all test below");
247
248 plugin_set = bt_plugin_create_all_from_dir(NON_EXISTING_PATH, false);
249 ok(!plugin_set,
250 "bt_plugin_create_all_from_dir() fails with an invalid path");
251
252 plugin_set = bt_plugin_create_all_from_dir(plugin_dir, false);
253 ok(plugin_set, "bt_plugin_create_all_from_dir() succeeds with a valid path");
254
255 /* 2 or 4, if `.la` files are considered or not */
256 ok(bt_plugin_set_get_plugin_count(plugin_set) == 2 ||
257 bt_plugin_set_get_plugin_count(plugin_set) == 4,
258 "bt_plugin_create_all_from_dir() returns the expected number of plugin objects");
259
260 bt_put(plugin_set);
261 }
262
263 static void test_find(const char *plugin_dir)
264 {
265 struct bt_plugin *plugin;
266 struct bt_component_class *comp_cls_sink;
267 struct bt_component_class *comp_cls_source;
268 char *plugin_path;
269
270 ok(!bt_plugin_find(NULL),
271 "bt_plugin_find() handles NULL");
272 ok(!bt_plugin_find(NON_EXISTING_PATH),
273 "bt_plugin_find() returns NULL with an unknown plugin name");
274 plugin_path = malloc(PATH_MAX * 5);
275 assert(plugin_path);
276 sprintf(plugin_path, "%s:/ec1d09e5-696c-442e-b1c3-f9c6cf7f5958:::%s:8db46494-a398-466a-9649-c765ae077629:",
277 NON_EXISTING_PATH, plugin_dir);
278 setenv("BABELTRACE_PLUGIN_PATH", plugin_path, 1);
279 plugin = bt_plugin_find("test_minimal");
280 ok(plugin,
281 "bt_plugin_find() succeeds with a plugin name it can find");
282 ok(strcmp(bt_plugin_get_author(plugin), "Janine Sutto") == 0,
283 "bt_plugin_find() finds the correct plugin for a given name");
284 BT_PUT(plugin);
285 comp_cls_sink = bt_plugin_find_component_class(NULL, "sink",
286 BT_COMPONENT_CLASS_TYPE_SINK);
287 ok(!comp_cls_sink, "bt_plugin_find_component_class() handles NULL (plugin name)");
288 comp_cls_sink = bt_plugin_find_component_class("test_sfs", NULL,
289 BT_COMPONENT_CLASS_TYPE_SINK);
290 ok(!comp_cls_sink, "bt_plugin_find_component_class() handles NULL (component class name)");
291 comp_cls_sink = bt_plugin_find_component_class("test_sfs", "sink2",
292 BT_COMPONENT_CLASS_TYPE_SINK);
293 ok(!comp_cls_sink, "bt_plugin_find_component_class() fails with an unknown component class name");
294 comp_cls_sink = bt_plugin_find_component_class("test_sfs", "sink",
295 BT_COMPONENT_CLASS_TYPE_SINK);
296 ok(comp_cls_sink, "bt_plugin_find_component_class() succeeds with valid parameters");
297 ok(strcmp(bt_component_class_get_name(comp_cls_sink), "sink") == 0,
298 "bt_plugin_find_component_class() returns the appropriate component class (sink)");
299 comp_cls_source = bt_plugin_find_component_class("test_sfs", "source",
300 BT_COMPONENT_CLASS_TYPE_SOURCE);
301 ok(comp_cls_sink, "bt_plugin_find_component_class() succeeds with another component class name (same plugin)");
302 ok(strcmp(bt_component_class_get_name(comp_cls_source), "source") == 0,
303 "bt_plugin_find_component_class() returns the appropriate component class (source)");
304 BT_PUT(comp_cls_sink);
305 BT_PUT(comp_cls_source);
306 free(plugin_path);
307 }
308
309 int main(int argc, char **argv)
310 {
311 int ret;
312 const char *plugin_dir;
313
314 if (argc != 2) {
315 puts("Usage: test_plugin plugin_directory");
316 ret = 1;
317 goto end;
318 }
319
320 plugin_dir = argv[1];
321 plan_tests(NR_TESTS);
322 test_invalid(plugin_dir);
323 test_minimal(plugin_dir);
324 test_sfs(plugin_dir);
325 test_create_all_from_dir(plugin_dir);
326 test_find(plugin_dir);
327 ret = exit_status();
328 end:
329 return ret;
330 }
This page took 0.040146 seconds and 5 git commands to generate.