4 * Trace 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>
27 #include <babeltrace/graph/query-executor.h>
31 #include <babeltrace/assert-internal.h>
37 #define NON_EXISTING_PATH "/this/hopefully/does/not/exist/5bc75f8d-0dba-4043-a509-d7984b97e42b.so"
39 /* Those symbols are written to by some test plugins */
40 static int check_env_var(const char *name
)
42 const char *val
= getenv(name
);
51 static void reset_test_plugin_env_vars(void)
53 g_setenv("BT_TEST_PLUGIN_INIT_CALLED", "0", 1);
54 g_setenv("BT_TEST_PLUGIN_EXIT_CALLED", "0", 1);
57 static char *get_test_plugin_path(const char *plugin_dir
,
58 const char *plugin_name
)
61 char *plugin_file_name
;
63 if (asprintf(&plugin_file_name
, "plugin-%s." G_MODULE_SUFFIX
,
68 ret
= g_build_filename(plugin_dir
, plugin_file_name
, NULL
);
69 free(plugin_file_name
);
74 static void test_invalid(const char *plugin_dir
)
76 struct bt_plugin_set
*plugin_set
;
78 diag("invalid plugin test below");
80 plugin_set
= bt_plugin_create_all_from_file(NON_EXISTING_PATH
);
81 ok(!plugin_set
, "bt_plugin_create_all_from_file() fails with a non-existing file");
83 plugin_set
= bt_plugin_create_all_from_file(plugin_dir
);
84 ok(!plugin_set
, "bt_plugin_create_all_from_file() fails with a directory");
86 ok(!bt_plugin_create_all_from_file(NULL
),
87 "bt_plugin_create_all_from_file() handles NULL correctly");
88 ok(!bt_plugin_create_all_from_dir(NULL
, BT_FALSE
),
89 "bt_plugin_create_all_from_dir() handles NULL correctly");
90 ok(!bt_plugin_get_name(NULL
),
91 "bt_plugin_get_name() handles NULL correctly");
92 ok(!bt_plugin_get_description(NULL
),
93 "bt_plugin_get_description() handles NULL correctly");
94 ok(bt_plugin_get_version(NULL
, NULL
, NULL
, NULL
, NULL
) !=
96 "bt_plugin_get_version() handles NULL correctly");
97 ok(!bt_plugin_get_author(NULL
),
98 "bt_plugin_get_author() handles NULL correctly");
99 ok(!bt_plugin_get_license(NULL
),
100 "bt_plugin_get_license() handles NULL correctly");
101 ok(!bt_plugin_get_path(NULL
),
102 "bt_plugin_get_path() handles NULL correctly");
103 ok(bt_plugin_get_component_class_count(NULL
) < 0,
104 "bt_plugin_get_component_class_count() handles NULL correctly");
105 ok(!bt_plugin_get_component_class_by_index(NULL
, 0),
106 "bt_plugin_get_component_class_by_index() handles NULL correctly");
107 ok(!bt_plugin_get_component_class_by_name_and_type(NULL
, NULL
, 0),
108 "bt_plugin_get_component_class_by_name_and_type() handles NULL correctly");
111 static void test_minimal(const char *plugin_dir
)
113 struct bt_plugin_set
*plugin_set
;
114 struct bt_plugin
*plugin
;
115 char *minimal_path
= get_test_plugin_path(plugin_dir
, "minimal");
117 BT_ASSERT(minimal_path
);
118 diag("minimal plugin test below");
120 reset_test_plugin_env_vars();
121 plugin_set
= bt_plugin_create_all_from_file(minimal_path
);
122 ok(plugin_set
&& bt_plugin_set_get_plugin_count(plugin_set
) == 1,
123 "bt_plugin_create_all_from_file() succeeds with a valid file");
124 ok(check_env_var("BT_TEST_PLUGIN_INIT_CALLED") == 1,
125 "plugin's initialization function is called during bt_plugin_create_all_from_file()");
126 ok(bt_plugin_set_get_plugin_count(plugin_set
) == 1,
127 "bt_plugin_create_all_from_file() returns the expected number of plugins");
128 plugin
= bt_plugin_set_get_plugin(plugin_set
, 0);
129 ok(strcmp(bt_plugin_get_name(plugin
), "test_minimal") == 0,
130 "bt_plugin_get_name() returns the expected name");
131 ok(strcmp(bt_plugin_get_description(plugin
),
132 "Minimal Babeltrace plugin with no component classes") == 0,
133 "bt_plugin_get_description() returns the expected description");
134 ok(bt_plugin_get_version(plugin
, NULL
, NULL
, NULL
, NULL
) !=
136 "bt_plugin_get_version() fails when there's no version");
137 ok(strcmp(bt_plugin_get_author(plugin
), "Janine Sutto") == 0,
138 "bt_plugin_get_author() returns the expected author");
139 ok(strcmp(bt_plugin_get_license(plugin
), "Beerware") == 0,
140 "bt_plugin_get_license() returns the expected license");
141 ok(strcmp(bt_plugin_get_path(plugin
), minimal_path
) == 0,
142 "bt_plugin_get_path() returns the expected path");
143 ok(bt_plugin_get_component_class_count(plugin
) == 0,
144 "bt_plugin_get_component_class_count() returns the expected value");
147 ok(check_env_var("BT_TEST_PLUGIN_EXIT_CALLED") == 1,
148 "plugin's exit function is called when the plugin is destroyed");
153 static void test_sfs(const char *plugin_dir
)
155 struct bt_plugin_set
*plugin_set
;
156 struct bt_plugin
*plugin
;
157 struct bt_component_class
*sink_comp_class
;
158 struct bt_component_class
*source_comp_class
;
159 struct bt_component_class
*filter_comp_class
;
160 struct bt_component
*sink_component
;
161 char *sfs_path
= get_test_plugin_path(plugin_dir
, "sfs");
162 unsigned int major
, minor
, patch
;
164 struct bt_value
*params
;
165 struct bt_value
*results
;
166 struct bt_value
*object
;
167 struct bt_value
*res_params
;
168 struct bt_graph
*graph
;
169 const char *object_str
;
170 enum bt_value_status value_ret
;
171 enum bt_graph_status graph_ret
;
172 struct bt_query_executor
*query_exec
= bt_query_executor_create();
175 BT_ASSERT(query_exec
);
177 diag("sfs plugin test below");
179 plugin_set
= bt_plugin_create_all_from_file(sfs_path
);
180 BT_ASSERT(plugin_set
&& bt_plugin_set_get_plugin_count(plugin_set
) == 1);
181 plugin
= bt_plugin_set_get_plugin(plugin_set
, 0);
182 ok(bt_plugin_get_version(plugin
, &major
, &minor
, &patch
, &extra
) ==
184 "bt_plugin_get_version() succeeds when there's a version");
186 "bt_plugin_get_version() returns the expected major version");
188 "bt_plugin_get_version() returns the expected minor version");
190 "bt_plugin_get_version() returns the expected patch version");
191 ok(strcmp(extra
, "yes") == 0,
192 "bt_plugin_get_version() returns the expected extra version");
193 ok(bt_plugin_get_component_class_count(plugin
) == 3,
194 "bt_plugin_get_component_class_count() returns the expected value");
196 source_comp_class
= bt_plugin_get_component_class_by_name_and_type(
197 plugin
, "source", BT_COMPONENT_CLASS_TYPE_SOURCE
);
198 ok(source_comp_class
,
199 "bt_plugin_get_component_class_by_name_and_type() finds a source component class");
201 sink_comp_class
= bt_plugin_get_component_class_by_name_and_type(
202 plugin
, "sink", BT_COMPONENT_CLASS_TYPE_SINK
);
204 "bt_plugin_get_component_class_by_name_and_type() finds a sink component class");
205 ok(strcmp(bt_component_class_get_help(sink_comp_class
),
206 "Bacon ipsum dolor amet strip steak cupim pastrami venison shoulder.\n"
207 "Prosciutto beef ribs flank meatloaf pancetta brisket kielbasa drumstick\n"
208 "venison tenderloin cow tail. Beef short loin shoulder meatball, sirloin\n"
209 "ground round brisket salami cupim pork bresaola turkey bacon boudin.\n") == 0,
210 "bt_component_class_get_help() returns the expected help text");
212 filter_comp_class
= bt_plugin_get_component_class_by_name_and_type(
213 plugin
, "filter", BT_COMPONENT_CLASS_TYPE_FILTER
);
214 ok(filter_comp_class
,
215 "bt_plugin_get_component_class_by_name_and_type() finds a filter component class");
216 ok(!bt_plugin_get_component_class_by_name_and_type(plugin
, "filter",
217 BT_COMPONENT_CLASS_TYPE_SOURCE
),
218 "bt_plugin_get_component_class_by_name_and_type() does not find a component class given the wrong type");
219 params
= bt_value_integer_create_init(23);
221 ret
= bt_query_executor_query(NULL
, filter_comp_class
, "object",
223 ok (ret
, "bt_query_executor_query() handles NULL (query executor)");
224 ret
= bt_query_executor_query(query_exec
, NULL
, "object",
226 ok (ret
, "bt_query_executor_query() handles NULL (component class)");
227 ret
= bt_query_executor_query(query_exec
, filter_comp_class
, NULL
,
229 ok (ret
, "bt_query_executor_query() handles NULL (object)");
230 ret
= bt_query_executor_query(query_exec
, filter_comp_class
,
231 "get-something", params
, &results
);
232 ok(ret
== 0 && results
, "bt_query_executor_query() succeeds");
233 BT_ASSERT(bt_value_is_array(results
) && bt_value_array_size(results
) == 2);
234 object
= bt_value_array_get(results
, 0);
235 BT_ASSERT(object
&& bt_value_is_string(object
));
236 value_ret
= bt_value_string_get(object
, &object_str
);
237 BT_ASSERT(value_ret
== BT_VALUE_STATUS_OK
);
238 ok(strcmp(object_str
, "get-something") == 0,
239 "bt_component_class_query() receives the expected object name");
240 res_params
= bt_value_array_get(results
, 1);
241 ok(res_params
== params
,
242 "bt_component_class_query() receives the expected parameters");
244 diag("> putting the plugin object here");
246 graph
= bt_graph_create();
248 graph_ret
= bt_graph_add_component(graph
, sink_comp_class
, "the-sink",
249 NULL
, &sink_component
);
250 ok(graph_ret
== BT_GRAPH_STATUS_OK
&& sink_component
,
251 "bt_graph_add_component() still works after the plugin object is destroyed");
252 BT_PUT(sink_component
);
253 BT_PUT(source_comp_class
);
255 graph
= bt_graph_create();
257 graph_ret
= bt_graph_add_component(graph
, sink_comp_class
, "the-sink",
258 NULL
, &sink_component
);
259 ok(graph_ret
== BT_GRAPH_STATUS_OK
&& sink_component
,
260 "bt_graph_add_component() still works after the source component class object is destroyed");
261 BT_PUT(sink_component
);
262 BT_PUT(filter_comp_class
);
264 graph
= bt_graph_create();
266 graph_ret
= bt_graph_add_component(graph
, sink_comp_class
, "the-sink",
267 NULL
, &sink_component
);
268 ok(graph_ret
== BT_GRAPH_STATUS_OK
&& sink_component
,
269 "bt_graph_add_component() still works after the filter component class object is destroyed");
270 BT_PUT(sink_comp_class
);
271 BT_PUT(sink_component
);
283 static void test_create_all_from_dir(const char *plugin_dir
)
285 struct bt_plugin_set
*plugin_set
;
287 diag("create from all test below");
289 plugin_set
= bt_plugin_create_all_from_dir(NON_EXISTING_PATH
, BT_FALSE
);
291 "bt_plugin_create_all_from_dir() fails with an invalid path");
293 plugin_set
= bt_plugin_create_all_from_dir(plugin_dir
, BT_FALSE
);
294 ok(plugin_set
, "bt_plugin_create_all_from_dir() succeeds with a valid path");
296 /* 2 or 4, if `.la` files are considered or not */
297 ok(bt_plugin_set_get_plugin_count(plugin_set
) == 2 ||
298 bt_plugin_set_get_plugin_count(plugin_set
) == 4,
299 "bt_plugin_create_all_from_dir() returns the expected number of plugin objects");
304 static void test_find(const char *plugin_dir
)
307 struct bt_plugin
*plugin
;
308 struct bt_component_class
*comp_cls_sink
;
309 struct bt_component_class
*comp_cls_source
;
312 ok(!bt_plugin_find(NULL
),
313 "bt_plugin_find() handles NULL");
314 ok(!bt_plugin_find(NON_EXISTING_PATH
),
315 "bt_plugin_find() returns NULL with an unknown plugin name");
316 ret
= asprintf(&plugin_path
, "%s" G_SEARCHPATH_SEPARATOR_S
317 G_DIR_SEPARATOR_S
"ec1d09e5-696c-442e-b1c3-f9c6cf7f5958"
318 G_SEARCHPATH_SEPARATOR_S G_SEARCHPATH_SEPARATOR_S
319 G_SEARCHPATH_SEPARATOR_S
"%s" G_SEARCHPATH_SEPARATOR_S
320 "8db46494-a398-466a-9649-c765ae077629"
321 G_SEARCHPATH_SEPARATOR_S
,
322 NON_EXISTING_PATH
, plugin_dir
);
323 BT_ASSERT(ret
> 0 && plugin_path
);
324 g_setenv("BABELTRACE_PLUGIN_PATH", plugin_path
, 1);
325 plugin
= bt_plugin_find("test_minimal");
327 "bt_plugin_find() succeeds with a plugin name it can find");
328 ok(strcmp(bt_plugin_get_author(plugin
), "Janine Sutto") == 0,
329 "bt_plugin_find() finds the correct plugin for a given name");
331 comp_cls_sink
= bt_plugin_find_component_class(NULL
, "sink",
332 BT_COMPONENT_CLASS_TYPE_SINK
);
333 ok(!comp_cls_sink
, "bt_plugin_find_component_class() handles NULL (plugin name)");
334 comp_cls_sink
= bt_plugin_find_component_class("test_sfs", NULL
,
335 BT_COMPONENT_CLASS_TYPE_SINK
);
336 ok(!comp_cls_sink
, "bt_plugin_find_component_class() handles NULL (component class name)");
337 comp_cls_sink
= bt_plugin_find_component_class("test_sfs", "sink2",
338 BT_COMPONENT_CLASS_TYPE_SINK
);
339 ok(!comp_cls_sink
, "bt_plugin_find_component_class() fails with an unknown component class name");
340 comp_cls_sink
= bt_plugin_find_component_class("test_sfs", "sink",
341 BT_COMPONENT_CLASS_TYPE_SINK
);
342 ok(comp_cls_sink
, "bt_plugin_find_component_class() succeeds with valid parameters");
343 ok(strcmp(bt_component_class_get_name(comp_cls_sink
), "sink") == 0,
344 "bt_plugin_find_component_class() returns the appropriate component class (sink)");
345 comp_cls_source
= bt_plugin_find_component_class("test_sfs", "source",
346 BT_COMPONENT_CLASS_TYPE_SOURCE
);
347 ok(comp_cls_sink
, "bt_plugin_find_component_class() succeeds with another component class name (same plugin)");
348 ok(strcmp(bt_component_class_get_name(comp_cls_source
), "source") == 0,
349 "bt_plugin_find_component_class() returns the appropriate component class (source)");
350 BT_PUT(comp_cls_sink
);
351 BT_PUT(comp_cls_source
);
355 int main(int argc
, char **argv
)
358 const char *plugin_dir
;
361 puts("Usage: test_plugin plugin_directory");
366 plugin_dir
= argv
[1];
367 plan_tests(NR_TESTS
);
368 test_invalid(plugin_dir
);
369 test_minimal(plugin_dir
);
370 test_sfs(plugin_dir
);
371 test_create_all_from_dir(plugin_dir
);
372 test_find(plugin_dir
);