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
)
59 GString
*path
= g_string_new(plugin_dir
);
63 g_string_append_printf(path
, "/plugin-%s.so", plugin_name
);
65 g_string_free(path
, FALSE
);
69 static void test_invalid(const char *plugin_dir
)
71 struct bt_plugin_set
*plugin_set
;
73 plugin_set
= bt_plugin_create_all_from_file(NON_EXISTING_PATH
);
74 ok(!plugin_set
, "bt_plugin_create_all_from_file() fails with a non-existing file");
76 plugin_set
= bt_plugin_create_all_from_file(plugin_dir
);
77 ok(!plugin_set
, "bt_plugin_create_all_from_file() fails with a directory");
79 ok(!bt_plugin_create_all_from_file(NULL
),
80 "bt_plugin_create_all_from_file() handles NULL correctly");
81 ok(!bt_plugin_create_all_from_dir(NULL
, BT_FALSE
),
82 "bt_plugin_create_all_from_dir() handles NULL correctly");
83 ok(!bt_plugin_get_name(NULL
),
84 "bt_plugin_get_name() handles NULL correctly");
85 ok(!bt_plugin_get_description(NULL
),
86 "bt_plugin_get_description() handles NULL correctly");
87 ok(bt_plugin_get_version(NULL
, NULL
, NULL
, NULL
, NULL
) !=
89 "bt_plugin_get_version() handles NULL correctly");
90 ok(!bt_plugin_get_author(NULL
),
91 "bt_plugin_get_author() handles NULL correctly");
92 ok(!bt_plugin_get_license(NULL
),
93 "bt_plugin_get_license() handles NULL correctly");
94 ok(!bt_plugin_get_path(NULL
),
95 "bt_plugin_get_path() handles NULL correctly");
96 ok(bt_plugin_get_component_class_count(NULL
) < 0,
97 "bt_plugin_get_component_class_count() handles NULL correctly");
98 ok(!bt_plugin_get_component_class_by_index(NULL
, 0),
99 "bt_plugin_get_component_class_by_index() handles NULL correctly");
100 ok(!bt_plugin_get_component_class_by_name_and_type(NULL
, NULL
, 0),
101 "bt_plugin_get_component_class_by_name_and_type() handles NULL correctly");
104 static void test_minimal(const char *plugin_dir
)
106 struct bt_plugin_set
*plugin_set
;
107 struct bt_plugin
*plugin
;
108 char *minimal_path
= get_test_plugin_path(plugin_dir
, "minimal");
110 assert(minimal_path
);
111 diag("minimal plugin test below");
113 reset_test_plugin_env_vars();
114 plugin_set
= bt_plugin_create_all_from_file(minimal_path
);
115 ok(plugin_set
&& bt_plugin_set_get_plugin_count(plugin_set
) == 1,
116 "bt_plugin_create_all_from_file() succeeds with a valid file");
117 ok(check_env_var("BT_TEST_PLUGIN_INIT_CALLED") == 1,
118 "plugin's initialization function is called during bt_plugin_create_all_from_file()");
119 ok(bt_plugin_set_get_plugin_count(plugin_set
) == 1,
120 "bt_plugin_create_all_from_file() returns the expected number of plugins");
121 plugin
= bt_plugin_set_get_plugin(plugin_set
, 0);
122 ok(strcmp(bt_plugin_get_name(plugin
), "test_minimal") == 0,
123 "bt_plugin_get_name() returns the expected name");
124 ok(strcmp(bt_plugin_get_description(plugin
),
125 "Minimal Babeltrace plugin with no component classes") == 0,
126 "bt_plugin_get_description() returns the expected description");
127 ok(bt_plugin_get_version(plugin
, NULL
, NULL
, NULL
, NULL
) !=
129 "bt_plugin_get_version() fails when there's no version");
130 ok(strcmp(bt_plugin_get_author(plugin
), "Janine Sutto") == 0,
131 "bt_plugin_get_author() returns the expected author");
132 ok(strcmp(bt_plugin_get_license(plugin
), "Beerware") == 0,
133 "bt_plugin_get_license() returns the expected license");
134 ok(strcmp(bt_plugin_get_path(plugin
), minimal_path
) == 0,
135 "bt_plugin_get_path() returns the expected path");
136 ok(bt_plugin_get_component_class_count(plugin
) == 0,
137 "bt_plugin_get_component_class_count() returns the expected value");
140 ok(check_env_var("BT_TEST_PLUGIN_EXIT_CALLED") == 1,
141 "plugin's exit function is called when the plugin is destroyed");
146 static void test_sfs(const char *plugin_dir
)
148 struct bt_plugin_set
*plugin_set
;
149 struct bt_plugin
*plugin
;
150 struct bt_component_class
*sink_comp_class
;
151 struct bt_component_class
*source_comp_class
;
152 struct bt_component_class
*filter_comp_class
;
153 struct bt_component
*sink_component
;
154 char *sfs_path
= get_test_plugin_path(plugin_dir
, "sfs");
155 unsigned int major
, minor
, patch
;
157 struct bt_value
*params
;
158 struct bt_value
*results
;
159 struct bt_value
*object
;
160 struct bt_value
*res_params
;
161 struct bt_graph
*graph
;
162 const char *object_str
;
163 enum bt_value_status value_ret
;
164 enum bt_graph_status graph_ret
;
167 diag("sfs plugin test below");
169 plugin_set
= bt_plugin_create_all_from_file(sfs_path
);
170 assert(plugin_set
&& bt_plugin_set_get_plugin_count(plugin_set
) == 1);
171 plugin
= bt_plugin_set_get_plugin(plugin_set
, 0);
172 ok(bt_plugin_get_version(plugin
, &major
, &minor
, &patch
, &extra
) ==
174 "bt_plugin_get_version() succeeds when there's a version");
176 "bt_plugin_get_version() returns the expected major version");
178 "bt_plugin_get_version() returns the expected minor version");
180 "bt_plugin_get_version() returns the expected patch version");
181 ok(strcmp(extra
, "yes") == 0,
182 "bt_plugin_get_version() returns the expected extra version");
183 ok(bt_plugin_get_component_class_count(plugin
) == 3,
184 "bt_plugin_get_component_class_count() returns the expected value");
186 source_comp_class
= bt_plugin_get_component_class_by_name_and_type(
187 plugin
, "source", BT_COMPONENT_CLASS_TYPE_SOURCE
);
188 ok(source_comp_class
,
189 "bt_plugin_get_component_class_by_name_and_type() finds a source component class");
191 sink_comp_class
= bt_plugin_get_component_class_by_name_and_type(
192 plugin
, "sink", BT_COMPONENT_CLASS_TYPE_SINK
);
194 "bt_plugin_get_component_class_by_name_and_type() finds a sink component class");
195 ok(strcmp(bt_component_class_get_help(sink_comp_class
),
196 "Bacon ipsum dolor amet strip steak cupim pastrami venison shoulder.\n"
197 "Prosciutto beef ribs flank meatloaf pancetta brisket kielbasa drumstick\n"
198 "venison tenderloin cow tail. Beef short loin shoulder meatball, sirloin\n"
199 "ground round brisket salami cupim pork bresaola turkey bacon boudin.\n") == 0,
200 "bt_component_class_get_help() returns the expected help text");
202 filter_comp_class
= bt_plugin_get_component_class_by_name_and_type(
203 plugin
, "filter", BT_COMPONENT_CLASS_TYPE_FILTER
);
204 ok(filter_comp_class
,
205 "bt_plugin_get_component_class_by_name_and_type() finds a filter component class");
206 ok(!bt_plugin_get_component_class_by_name_and_type(plugin
, "filter",
207 BT_COMPONENT_CLASS_TYPE_SOURCE
),
208 "bt_plugin_get_component_class_by_name_and_type() does not find a component class given the wrong type");
209 params
= bt_value_integer_create_init(23);
211 ok (!bt_component_class_query(NULL
, "get-something", params
),
212 "bt_component_class_query() handles NULL (component class)");
213 ok (!bt_component_class_query(filter_comp_class
, NULL
, params
),
214 "bt_component_class_query() handles NULL (object)");
215 ok (!bt_component_class_query(filter_comp_class
, "get-something", NULL
),
216 "bt_component_class_query() handles NULL (parameters)");
217 results
= bt_component_class_query(filter_comp_class
,
218 "get-something", params
);
219 ok(results
, "bt_component_class_query() succeeds");
220 assert(bt_value_is_array(results
) && bt_value_array_size(results
) == 2);
221 object
= bt_value_array_get(results
, 0);
222 assert(object
&& bt_value_is_string(object
));
223 value_ret
= bt_value_string_get(object
, &object_str
);
224 assert(value_ret
== BT_VALUE_STATUS_OK
);
225 ok(strcmp(object_str
, "get-something") == 0,
226 "bt_component_class_query() receives the expected object name");
227 res_params
= bt_value_array_get(results
, 1);
228 ok(res_params
== params
,
229 "bt_component_class_query() receives the expected parameters");
231 diag("> putting the plugin object here");
233 graph
= bt_graph_create();
235 graph_ret
= bt_graph_add_component(graph
, sink_comp_class
, "the-sink",
236 NULL
, &sink_component
);
237 ok(graph_ret
== BT_GRAPH_STATUS_OK
&& sink_component
,
238 "bt_graph_add_component() still works after the plugin object is destroyed");
239 BT_PUT(sink_component
);
240 BT_PUT(source_comp_class
);
242 graph
= bt_graph_create();
244 graph_ret
= bt_graph_add_component(graph
, sink_comp_class
, "the-sink",
245 NULL
, &sink_component
);
246 ok(graph_ret
== BT_GRAPH_STATUS_OK
&& sink_component
,
247 "bt_graph_add_component() still works after the source component class object is destroyed");
248 BT_PUT(sink_component
);
249 BT_PUT(filter_comp_class
);
251 graph
= bt_graph_create();
253 graph_ret
= bt_graph_add_component(graph
, sink_comp_class
, "the-sink",
254 NULL
, &sink_component
);
255 ok(graph_ret
== BT_GRAPH_STATUS_OK
&& sink_component
,
256 "bt_graph_add_component() still works after the filter component class object is destroyed");
257 BT_PUT(sink_comp_class
);
258 BT_PUT(sink_component
);
269 static void test_create_all_from_dir(const char *plugin_dir
)
271 struct bt_plugin_set
*plugin_set
;
273 diag("create from all test below");
275 plugin_set
= bt_plugin_create_all_from_dir(NON_EXISTING_PATH
, BT_FALSE
);
277 "bt_plugin_create_all_from_dir() fails with an invalid path");
279 plugin_set
= bt_plugin_create_all_from_dir(plugin_dir
, BT_FALSE
);
280 ok(plugin_set
, "bt_plugin_create_all_from_dir() succeeds with a valid path");
282 /* 2 or 4, if `.la` files are considered or not */
283 ok(bt_plugin_set_get_plugin_count(plugin_set
) == 2 ||
284 bt_plugin_set_get_plugin_count(plugin_set
) == 4,
285 "bt_plugin_create_all_from_dir() returns the expected number of plugin objects");
290 static void test_find(const char *plugin_dir
)
293 struct bt_plugin
*plugin
;
294 struct bt_component_class
*comp_cls_sink
;
295 struct bt_component_class
*comp_cls_source
;
298 ok(!bt_plugin_find(NULL
),
299 "bt_plugin_find() handles NULL");
300 ok(!bt_plugin_find(NON_EXISTING_PATH
),
301 "bt_plugin_find() returns NULL with an unknown plugin name");
302 ret
= asprintf(&plugin_path
, "%s:/ec1d09e5-696c-442e-b1c3-f9c6cf7f5958:::%s:8db46494-a398-466a-9649-c765ae077629:",
303 NON_EXISTING_PATH
, plugin_dir
);
304 assert(ret
> 0 && plugin_path
);
305 g_setenv("BABELTRACE_PLUGIN_PATH", plugin_path
, 1);
306 plugin
= bt_plugin_find("test_minimal");
308 "bt_plugin_find() succeeds with a plugin name it can find");
309 ok(strcmp(bt_plugin_get_author(plugin
), "Janine Sutto") == 0,
310 "bt_plugin_find() finds the correct plugin for a given name");
312 comp_cls_sink
= bt_plugin_find_component_class(NULL
, "sink",
313 BT_COMPONENT_CLASS_TYPE_SINK
);
314 ok(!comp_cls_sink
, "bt_plugin_find_component_class() handles NULL (plugin name)");
315 comp_cls_sink
= bt_plugin_find_component_class("test_sfs", NULL
,
316 BT_COMPONENT_CLASS_TYPE_SINK
);
317 ok(!comp_cls_sink
, "bt_plugin_find_component_class() handles NULL (component class name)");
318 comp_cls_sink
= bt_plugin_find_component_class("test_sfs", "sink2",
319 BT_COMPONENT_CLASS_TYPE_SINK
);
320 ok(!comp_cls_sink
, "bt_plugin_find_component_class() fails with an unknown component class name");
321 comp_cls_sink
= bt_plugin_find_component_class("test_sfs", "sink",
322 BT_COMPONENT_CLASS_TYPE_SINK
);
323 ok(comp_cls_sink
, "bt_plugin_find_component_class() succeeds with valid parameters");
324 ok(strcmp(bt_component_class_get_name(comp_cls_sink
), "sink") == 0,
325 "bt_plugin_find_component_class() returns the appropriate component class (sink)");
326 comp_cls_source
= bt_plugin_find_component_class("test_sfs", "source",
327 BT_COMPONENT_CLASS_TYPE_SOURCE
);
328 ok(comp_cls_sink
, "bt_plugin_find_component_class() succeeds with another component class name (same plugin)");
329 ok(strcmp(bt_component_class_get_name(comp_cls_source
), "source") == 0,
330 "bt_plugin_find_component_class() returns the appropriate component class (source)");
331 BT_PUT(comp_cls_sink
);
332 BT_PUT(comp_cls_source
);
336 int main(int argc
, char **argv
)
339 const char *plugin_dir
;
342 puts("Usage: test_plugin plugin_directory");
347 plugin_dir
= argv
[1];
348 plan_tests(NR_TESTS
);
349 test_invalid(plugin_dir
);
350 test_minimal(plugin_dir
);
351 test_sfs(plugin_dir
);
352 test_create_all_from_dir(plugin_dir
);
353 test_find(plugin_dir
);