4 * CTF IR Reference Count test
6 * Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
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.
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.
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.
22 #include <babeltrace/plugin/plugin.h>
23 #include <babeltrace/ref.h>
24 #include <babeltrace/values.h>
25 #include <babeltrace/graph/component.h>
26 #include <babeltrace/graph/graph.h>
36 #define NON_EXISTING_PATH "/this/hopefully/does/not/exist/5bc75f8d-0dba-4043-a509-d7984b97e42b.so"
38 /* Those symbols are written to by some test plugins */
39 static int check_env_var(const char *name
)
41 const char *val
= getenv(name
);
50 static void reset_test_plugin_env_vars(void)
52 g_setenv("BT_TEST_PLUGIN_INIT_CALLED", "0", 1);
53 g_setenv("BT_TEST_PLUGIN_EXIT_CALLED", "0", 1);
56 static char *get_test_plugin_path(const char *plugin_dir
,
57 const char *plugin_name
)
60 char *plugin_file_name
;
62 if (asprintf(&plugin_file_name
, "plugin-%s." G_MODULE_SUFFIX
,
67 ret
= g_build_filename(plugin_dir
, plugin_file_name
, NULL
);
68 free(plugin_file_name
);
73 static void test_invalid(const char *plugin_dir
)
75 struct bt_plugin_set
*plugin_set
;
77 diag("invalid plugin test below");
79 plugin_set
= bt_plugin_create_all_from_file(NON_EXISTING_PATH
);
80 ok(!plugin_set
, "bt_plugin_create_all_from_file() fails with a non-existing file");
82 plugin_set
= bt_plugin_create_all_from_file(plugin_dir
);
83 ok(!plugin_set
, "bt_plugin_create_all_from_file() fails with a directory");
85 ok(!bt_plugin_create_all_from_file(NULL
),
86 "bt_plugin_create_all_from_file() handles NULL correctly");
87 ok(!bt_plugin_create_all_from_dir(NULL
, BT_FALSE
),
88 "bt_plugin_create_all_from_dir() handles NULL correctly");
89 ok(!bt_plugin_get_name(NULL
),
90 "bt_plugin_get_name() handles NULL correctly");
91 ok(!bt_plugin_get_description(NULL
),
92 "bt_plugin_get_description() handles NULL correctly");
93 ok(bt_plugin_get_version(NULL
, NULL
, NULL
, NULL
, NULL
) !=
95 "bt_plugin_get_version() handles NULL correctly");
96 ok(!bt_plugin_get_author(NULL
),
97 "bt_plugin_get_author() handles NULL correctly");
98 ok(!bt_plugin_get_license(NULL
),
99 "bt_plugin_get_license() handles NULL correctly");
100 ok(!bt_plugin_get_path(NULL
),
101 "bt_plugin_get_path() handles NULL correctly");
102 ok(bt_plugin_get_component_class_count(NULL
) < 0,
103 "bt_plugin_get_component_class_count() handles NULL correctly");
104 ok(!bt_plugin_get_component_class_by_index(NULL
, 0),
105 "bt_plugin_get_component_class_by_index() handles NULL correctly");
106 ok(!bt_plugin_get_component_class_by_name_and_type(NULL
, NULL
, 0),
107 "bt_plugin_get_component_class_by_name_and_type() handles NULL correctly");
110 static void test_minimal(const char *plugin_dir
)
112 struct bt_plugin_set
*plugin_set
;
113 struct bt_plugin
*plugin
;
114 char *minimal_path
= get_test_plugin_path(plugin_dir
, "minimal");
116 assert(minimal_path
);
117 diag("minimal plugin test below");
119 reset_test_plugin_env_vars();
120 plugin_set
= bt_plugin_create_all_from_file(minimal_path
);
121 ok(plugin_set
&& bt_plugin_set_get_plugin_count(plugin_set
) == 1,
122 "bt_plugin_create_all_from_file() succeeds with a valid file");
123 ok(check_env_var("BT_TEST_PLUGIN_INIT_CALLED") == 1,
124 "plugin's initialization function is called during bt_plugin_create_all_from_file()");
125 ok(bt_plugin_set_get_plugin_count(plugin_set
) == 1,
126 "bt_plugin_create_all_from_file() returns the expected number of plugins");
127 plugin
= bt_plugin_set_get_plugin(plugin_set
, 0);
128 ok(strcmp(bt_plugin_get_name(plugin
), "test_minimal") == 0,
129 "bt_plugin_get_name() returns the expected name");
130 ok(strcmp(bt_plugin_get_description(plugin
),
131 "Minimal Babeltrace plugin with no component classes") == 0,
132 "bt_plugin_get_description() returns the expected description");
133 ok(bt_plugin_get_version(plugin
, NULL
, NULL
, NULL
, NULL
) !=
135 "bt_plugin_get_version() fails when there's no version");
136 ok(strcmp(bt_plugin_get_author(plugin
), "Janine Sutto") == 0,
137 "bt_plugin_get_author() returns the expected author");
138 ok(strcmp(bt_plugin_get_license(plugin
), "Beerware") == 0,
139 "bt_plugin_get_license() returns the expected license");
140 ok(strcmp(bt_plugin_get_path(plugin
), minimal_path
) == 0,
141 "bt_plugin_get_path() returns the expected path");
142 ok(bt_plugin_get_component_class_count(plugin
) == 0,
143 "bt_plugin_get_component_class_count() returns the expected value");
146 ok(check_env_var("BT_TEST_PLUGIN_EXIT_CALLED") == 1,
147 "plugin's exit function is called when the plugin is destroyed");
152 static void test_sfs(const char *plugin_dir
)
154 struct bt_plugin_set
*plugin_set
;
155 struct bt_plugin
*plugin
;
156 struct bt_component_class
*sink_comp_class
;
157 struct bt_component_class
*source_comp_class
;
158 struct bt_component_class
*filter_comp_class
;
159 struct bt_component
*sink_component
;
160 char *sfs_path
= get_test_plugin_path(plugin_dir
, "sfs");
161 unsigned int major
, minor
, patch
;
163 struct bt_value
*params
;
164 struct bt_value
*results
;
165 struct bt_value
*object
;
166 struct bt_value
*res_params
;
167 struct bt_graph
*graph
;
168 const char *object_str
;
169 enum bt_value_status value_ret
;
170 enum bt_graph_status graph_ret
;
173 diag("sfs plugin test below");
175 plugin_set
= bt_plugin_create_all_from_file(sfs_path
);
176 assert(plugin_set
&& bt_plugin_set_get_plugin_count(plugin_set
) == 1);
177 plugin
= bt_plugin_set_get_plugin(plugin_set
, 0);
178 ok(bt_plugin_get_version(plugin
, &major
, &minor
, &patch
, &extra
) ==
180 "bt_plugin_get_version() succeeds when there's a version");
182 "bt_plugin_get_version() returns the expected major version");
184 "bt_plugin_get_version() returns the expected minor version");
186 "bt_plugin_get_version() returns the expected patch version");
187 ok(strcmp(extra
, "yes") == 0,
188 "bt_plugin_get_version() returns the expected extra version");
189 ok(bt_plugin_get_component_class_count(plugin
) == 3,
190 "bt_plugin_get_component_class_count() returns the expected value");
192 source_comp_class
= bt_plugin_get_component_class_by_name_and_type(
193 plugin
, "source", BT_COMPONENT_CLASS_TYPE_SOURCE
);
194 ok(source_comp_class
,
195 "bt_plugin_get_component_class_by_name_and_type() finds a source component class");
197 sink_comp_class
= bt_plugin_get_component_class_by_name_and_type(
198 plugin
, "sink", BT_COMPONENT_CLASS_TYPE_SINK
);
200 "bt_plugin_get_component_class_by_name_and_type() finds a sink component class");
201 ok(strcmp(bt_component_class_get_help(sink_comp_class
),
202 "Bacon ipsum dolor amet strip steak cupim pastrami venison shoulder.\n"
203 "Prosciutto beef ribs flank meatloaf pancetta brisket kielbasa drumstick\n"
204 "venison tenderloin cow tail. Beef short loin shoulder meatball, sirloin\n"
205 "ground round brisket salami cupim pork bresaola turkey bacon boudin.\n") == 0,
206 "bt_component_class_get_help() returns the expected help text");
208 filter_comp_class
= bt_plugin_get_component_class_by_name_and_type(
209 plugin
, "filter", BT_COMPONENT_CLASS_TYPE_FILTER
);
210 ok(filter_comp_class
,
211 "bt_plugin_get_component_class_by_name_and_type() finds a filter component class");
212 ok(!bt_plugin_get_component_class_by_name_and_type(plugin
, "filter",
213 BT_COMPONENT_CLASS_TYPE_SOURCE
),
214 "bt_plugin_get_component_class_by_name_and_type() does not find a component class given the wrong type");
215 params
= bt_value_integer_create_init(23);
217 ok (!bt_component_class_query(NULL
, "get-something", params
),
218 "bt_component_class_query() handles NULL (component class)");
219 ok (!bt_component_class_query(filter_comp_class
, NULL
, params
),
220 "bt_component_class_query() handles NULL (object)");
221 ok (!bt_component_class_query(filter_comp_class
, "get-something", NULL
),
222 "bt_component_class_query() handles NULL (parameters)");
223 results
= bt_component_class_query(filter_comp_class
,
224 "get-something", params
);
225 ok(results
, "bt_component_class_query() succeeds");
226 assert(bt_value_is_array(results
) && bt_value_array_size(results
) == 2);
227 object
= bt_value_array_get(results
, 0);
228 assert(object
&& bt_value_is_string(object
));
229 value_ret
= bt_value_string_get(object
, &object_str
);
230 assert(value_ret
== BT_VALUE_STATUS_OK
);
231 ok(strcmp(object_str
, "get-something") == 0,
232 "bt_component_class_query() receives the expected object name");
233 res_params
= bt_value_array_get(results
, 1);
234 ok(res_params
== params
,
235 "bt_component_class_query() receives the expected parameters");
237 diag("> putting the plugin object here");
239 graph
= bt_graph_create();
241 graph_ret
= bt_graph_add_component(graph
, sink_comp_class
, "the-sink",
242 NULL
, &sink_component
);
243 ok(graph_ret
== BT_GRAPH_STATUS_OK
&& sink_component
,
244 "bt_graph_add_component() still works after the plugin object is destroyed");
245 BT_PUT(sink_component
);
246 BT_PUT(source_comp_class
);
248 graph
= bt_graph_create();
250 graph_ret
= bt_graph_add_component(graph
, sink_comp_class
, "the-sink",
251 NULL
, &sink_component
);
252 ok(graph_ret
== BT_GRAPH_STATUS_OK
&& sink_component
,
253 "bt_graph_add_component() still works after the source component class object is destroyed");
254 BT_PUT(sink_component
);
255 BT_PUT(filter_comp_class
);
257 graph
= bt_graph_create();
259 graph_ret
= bt_graph_add_component(graph
, sink_comp_class
, "the-sink",
260 NULL
, &sink_component
);
261 ok(graph_ret
== BT_GRAPH_STATUS_OK
&& sink_component
,
262 "bt_graph_add_component() still works after the filter component class object is destroyed");
263 BT_PUT(sink_comp_class
);
264 BT_PUT(sink_component
);
275 static void test_create_all_from_dir(const char *plugin_dir
)
277 struct bt_plugin_set
*plugin_set
;
279 diag("create from all test below");
281 plugin_set
= bt_plugin_create_all_from_dir(NON_EXISTING_PATH
, BT_FALSE
);
283 "bt_plugin_create_all_from_dir() fails with an invalid path");
285 plugin_set
= bt_plugin_create_all_from_dir(plugin_dir
, BT_FALSE
);
286 ok(plugin_set
, "bt_plugin_create_all_from_dir() succeeds with a valid path");
288 /* 2 or 4, if `.la` files are considered or not */
289 ok(bt_plugin_set_get_plugin_count(plugin_set
) == 2 ||
290 bt_plugin_set_get_plugin_count(plugin_set
) == 4,
291 "bt_plugin_create_all_from_dir() returns the expected number of plugin objects");
296 static void test_find(const char *plugin_dir
)
299 struct bt_plugin
*plugin
;
300 struct bt_component_class
*comp_cls_sink
;
301 struct bt_component_class
*comp_cls_source
;
304 ok(!bt_plugin_find(NULL
),
305 "bt_plugin_find() handles NULL");
306 ok(!bt_plugin_find(NON_EXISTING_PATH
),
307 "bt_plugin_find() returns NULL with an unknown plugin name");
308 ret
= asprintf(&plugin_path
, "%s" G_SEARCHPATH_SEPARATOR_S
309 G_DIR_SEPARATOR_S
"ec1d09e5-696c-442e-b1c3-f9c6cf7f5958"
310 G_SEARCHPATH_SEPARATOR_S G_SEARCHPATH_SEPARATOR_S
311 G_SEARCHPATH_SEPARATOR_S
"%s" G_SEARCHPATH_SEPARATOR_S
312 "8db46494-a398-466a-9649-c765ae077629"
313 G_SEARCHPATH_SEPARATOR_S
,
314 NON_EXISTING_PATH
, plugin_dir
);
315 assert(ret
> 0 && plugin_path
);
316 g_setenv("BABELTRACE_PLUGIN_PATH", plugin_path
, 1);
317 plugin
= bt_plugin_find("test_minimal");
319 "bt_plugin_find() succeeds with a plugin name it can find");
320 ok(strcmp(bt_plugin_get_author(plugin
), "Janine Sutto") == 0,
321 "bt_plugin_find() finds the correct plugin for a given name");
323 comp_cls_sink
= bt_plugin_find_component_class(NULL
, "sink",
324 BT_COMPONENT_CLASS_TYPE_SINK
);
325 ok(!comp_cls_sink
, "bt_plugin_find_component_class() handles NULL (plugin name)");
326 comp_cls_sink
= bt_plugin_find_component_class("test_sfs", NULL
,
327 BT_COMPONENT_CLASS_TYPE_SINK
);
328 ok(!comp_cls_sink
, "bt_plugin_find_component_class() handles NULL (component class name)");
329 comp_cls_sink
= bt_plugin_find_component_class("test_sfs", "sink2",
330 BT_COMPONENT_CLASS_TYPE_SINK
);
331 ok(!comp_cls_sink
, "bt_plugin_find_component_class() fails with an unknown component class name");
332 comp_cls_sink
= bt_plugin_find_component_class("test_sfs", "sink",
333 BT_COMPONENT_CLASS_TYPE_SINK
);
334 ok(comp_cls_sink
, "bt_plugin_find_component_class() succeeds with valid parameters");
335 ok(strcmp(bt_component_class_get_name(comp_cls_sink
), "sink") == 0,
336 "bt_plugin_find_component_class() returns the appropriate component class (sink)");
337 comp_cls_source
= bt_plugin_find_component_class("test_sfs", "source",
338 BT_COMPONENT_CLASS_TYPE_SOURCE
);
339 ok(comp_cls_sink
, "bt_plugin_find_component_class() succeeds with another component class name (same plugin)");
340 ok(strcmp(bt_component_class_get_name(comp_cls_source
), "source") == 0,
341 "bt_plugin_find_component_class() returns the appropriate component class (source)");
342 BT_PUT(comp_cls_sink
);
343 BT_PUT(comp_cls_source
);
347 int main(int argc
, char **argv
)
350 const char *plugin_dir
;
353 puts("Usage: test_plugin plugin_directory");
358 plugin_dir
= argv
[1];
359 plan_tests(NR_TESTS
);
360 test_invalid(plugin_dir
);
361 test_minimal(plugin_dir
);
362 test_sfs(plugin_dir
);
363 test_create_all_from_dir(plugin_dir
);
364 test_find(plugin_dir
);