lib: prepare the ground for stateful query operations
[babeltrace.git] / tests / lib / plugin.c
CommitLineData
cbb9e0b1 1/*
cbb9e0b1
PP
2 * Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; under version 2 of the License.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
16 */
17
71c5da58 18#include <babeltrace2/babeltrace.h>
cbb9e0b1
PP
19#include <stdlib.h>
20#include <string.h>
21#include <stdio.h>
57952005 22#include "common/assert.h"
cbb9e0b1
PP
23#include <glib.h>
24#include "tap/tap.h"
25#include "common.h"
26
01f50d54 27#define NR_TESTS 38
cbb9e0b1
PP
28#define NON_EXISTING_PATH "/this/hopefully/does/not/exist/5bc75f8d-0dba-4043-a509-d7984b97e42b.so"
29
30/* Those symbols are written to by some test plugins */
edb2ec3c
PP
31static int check_env_var(const char *name)
32{
33 const char *val = getenv(name);
34
35 if (!val) {
36 return -1;
37 }
38
39 return atoi(val);
40}
cbb9e0b1 41
edb2ec3c 42static void reset_test_plugin_env_vars(void)
cbb9e0b1 43{
9be5a6e6
MJ
44 g_setenv("BT_TEST_PLUGIN_INIT_CALLED", "0", 1);
45 g_setenv("BT_TEST_PLUGIN_EXIT_CALLED", "0", 1);
cbb9e0b1
PP
46}
47
48static char *get_test_plugin_path(const char *plugin_dir,
49 const char *plugin_name)
50{
cbb9e0b1 51 char *ret;
d85ff846
MJ
52 char *plugin_file_name;
53
54 if (asprintf(&plugin_file_name, "plugin-%s." G_MODULE_SUFFIX,
55 plugin_name) == -1) {
56 abort();
57 }
58
59 ret = g_build_filename(plugin_dir, plugin_file_name, NULL);
60 free(plugin_file_name);
cbb9e0b1 61
cbb9e0b1
PP
62 return ret;
63}
64
cbb9e0b1
PP
65static void test_minimal(const char *plugin_dir)
66{
01f50d54 67 const bt_plugin_set *plugin_set = NULL;
8eee8ea2 68 const bt_plugin *plugin;
cbb9e0b1 69 char *minimal_path = get_test_plugin_path(plugin_dir, "minimal");
fb25b9e3 70 bt_plugin_find_all_from_file_status status;
cbb9e0b1 71
b8f13b8b 72 BT_ASSERT(minimal_path);
cbb9e0b1
PP
73 diag("minimal plugin test below");
74
edb2ec3c 75 reset_test_plugin_env_vars();
01f50d54
PP
76 status = bt_plugin_find_all_from_file(minimal_path, BT_FALSE,
77 &plugin_set);
fb25b9e3 78 ok(status == BT_PLUGIN_FIND_ALL_FROM_FILE_STATUS_OK,
781ae911 79 "bt_plugin_find_all_from_file() succeeds with a valid file");
01f50d54
PP
80 ok(plugin_set,
81 "bt_plugin_find_all_from_file() returns a plugin set");
edb2ec3c 82 ok(check_env_var("BT_TEST_PLUGIN_INIT_CALLED") == 1,
781ae911 83 "plugin's initialization function is called during bt_plugin_find_all_from_file()");
a8ff38ef 84 ok(bt_plugin_set_get_plugin_count(plugin_set) == 1,
781ae911 85 "bt_plugin_find_all_from_file() returns the expected number of plugins");
3a2cb327 86 plugin = bt_plugin_set_borrow_plugin_by_index_const(plugin_set, 0);
6ba0b073 87 ok(strcmp(bt_plugin_get_name(plugin), "test_minimal") == 0,
cbb9e0b1
PP
88 "bt_plugin_get_name() returns the expected name");
89 ok(strcmp(bt_plugin_get_description(plugin),
90 "Minimal Babeltrace plugin with no component classes") == 0,
91 "bt_plugin_get_description() returns the expected description");
834e9996
PP
92 ok(bt_plugin_get_version(plugin, NULL, NULL, NULL, NULL) ==
93 BT_PROPERTY_AVAILABILITY_NOT_AVAILABLE,
458e8e1d 94 "bt_plugin_get_version() fails when there's no version");
cbb9e0b1
PP
95 ok(strcmp(bt_plugin_get_author(plugin), "Janine Sutto") == 0,
96 "bt_plugin_get_author() returns the expected author");
97 ok(strcmp(bt_plugin_get_license(plugin), "Beerware") == 0,
98 "bt_plugin_get_license() returns the expected license");
99 ok(strcmp(bt_plugin_get_path(plugin), minimal_path) == 0,
100 "bt_plugin_get_path() returns the expected path");
834e9996
PP
101 ok(bt_plugin_get_source_component_class_count(plugin) == 0,
102 "bt_plugin_get_source_component_class_count() returns the expected value");
103 ok(bt_plugin_get_filter_component_class_count(plugin) == 0,
104 "bt_plugin_get_filter_component_class_count() returns the expected value");
105 ok(bt_plugin_get_sink_component_class_count(plugin) == 0,
106 "bt_plugin_get_sink_component_class_count() returns the expected value");
8c6884d9 107 bt_plugin_set_put_ref(plugin_set);
edb2ec3c
PP
108 ok(check_env_var("BT_TEST_PLUGIN_EXIT_CALLED") == 1,
109 "plugin's exit function is called when the plugin is destroyed");
cbb9e0b1
PP
110
111 free(minimal_path);
112}
113
114static void test_sfs(const char *plugin_dir)
115{
01f50d54 116 const bt_plugin_set *plugin_set = NULL;
8eee8ea2
PP
117 const bt_plugin *plugin;
118 const bt_component_class_sink *sink_comp_class;
119 const bt_component_class_source *source_comp_class;
120 const bt_component_class_filter *filter_comp_class;
121 const bt_component_sink *sink_component;
cbb9e0b1 122 char *sfs_path = get_test_plugin_path(plugin_dir, "sfs");
458e8e1d
PP
123 unsigned int major, minor, patch;
124 const char *extra;
8eee8ea2
PP
125 bt_value *params;
126 const bt_value *results;
127 const bt_value *object;
128 const bt_value *res_params;
129 bt_graph *graph;
a67681c1 130 const char *object_str;
fb25b9e3 131 bt_graph_add_component_status graph_ret;
bf403eb2 132 bt_query_executor *query_exec;
1286dcbb 133 int ret;
fb25b9e3 134 bt_plugin_find_all_from_file_status status;
cbb9e0b1 135
b8f13b8b 136 BT_ASSERT(sfs_path);
cbb9e0b1
PP
137 diag("sfs plugin test below");
138
01f50d54 139 status = bt_plugin_find_all_from_file(sfs_path, BT_FALSE, &plugin_set);
fb25b9e3
PP
140 BT_ASSERT(status == BT_PLUGIN_FIND_ALL_FROM_FILE_STATUS_OK &&
141 plugin_set && bt_plugin_set_get_plugin_count(plugin_set) == 1);
3a2cb327 142 plugin = bt_plugin_set_borrow_plugin_by_index_const(plugin_set, 0);
458e8e1d 143 ok(bt_plugin_get_version(plugin, &major, &minor, &patch, &extra) ==
834e9996 144 BT_PROPERTY_AVAILABILITY_AVAILABLE,
458e8e1d
PP
145 "bt_plugin_get_version() succeeds when there's a version");
146 ok(major == 1,
147 "bt_plugin_get_version() returns the expected major version");
148 ok(minor == 2,
149 "bt_plugin_get_version() returns the expected minor version");
150 ok(patch == 3,
151 "bt_plugin_get_version() returns the expected patch version");
152 ok(strcmp(extra, "yes") == 0,
153 "bt_plugin_get_version() returns the expected extra version");
834e9996
PP
154 ok(bt_plugin_get_source_component_class_count(plugin) == 1,
155 "bt_plugin_get_source_component_class_count() returns the expected value");
156 ok(bt_plugin_get_filter_component_class_count(plugin) == 1,
157 "bt_plugin_get_filter_component_class_count() returns the expected value");
158 ok(bt_plugin_get_sink_component_class_count(plugin) == 1,
159 "bt_plugin_get_sink_component_class_count() returns the expected value");
160
3a2cb327 161 source_comp_class = bt_plugin_borrow_source_component_class_by_name_const(
834e9996 162 plugin, "source");
cbb9e0b1 163 ok(source_comp_class,
3a2cb327 164 "bt_plugin_borrow_source_component_class_by_name_const() finds a source component class");
cbb9e0b1 165
3a2cb327 166 sink_comp_class = bt_plugin_borrow_sink_component_class_by_name_const(
834e9996 167 plugin, "sink");
cbb9e0b1 168 ok(sink_comp_class,
3a2cb327 169 "bt_plugin_borrow_sink_component_class_by_name_const() finds a sink component class");
7b53201c
PP
170 ok(strcmp(bt_component_class_get_help(bt_component_class_sink_as_component_class_const(sink_comp_class)),
171 "Bacon ipsum dolor amet strip steak cupim pastrami venison shoulder.\n"
172 "Prosciutto beef ribs flank meatloaf pancetta brisket kielbasa drumstick\n"
173 "venison tenderloin cow tail. Beef short loin shoulder meatball, sirloin\n"
174 "ground round brisket salami cupim pork bresaola turkey bacon boudin.\n") == 0,
a889b89f
PP
175 "bt_component_class_get_help() returns the expected help text");
176
3a2cb327 177 filter_comp_class = bt_plugin_borrow_filter_component_class_by_name_const(
834e9996 178 plugin, "filter");
cbb9e0b1 179 ok(filter_comp_class,
3a2cb327 180 "bt_plugin_borrow_filter_component_class_by_name_const() finds a filter component class");
60bbfc7c 181 params = bt_value_integer_signed_create_init(23);
b8f13b8b 182 BT_ASSERT(params);
bf403eb2
PP
183 query_exec = bt_query_executor_create(
184 bt_component_class_filter_as_component_class_const(
185 filter_comp_class), "get-something", params);
186 BT_ASSERT(query_exec);
187 ret = bt_query_executor_query(query_exec, &results);
7b53201c 188 ok(ret == 0 && results, "bt_query_executor_query() succeeds");
44514773 189 BT_ASSERT(bt_value_is_array(results) && bt_value_array_get_size(results) == 2);
ce141536 190 object = bt_value_array_borrow_element_by_index_const(results, 0);
b8f13b8b 191 BT_ASSERT(object && bt_value_is_string(object));
b5cdc106 192 object_str = bt_value_string_get(object);
a67681c1
PP
193 ok(strcmp(object_str, "get-something") == 0,
194 "bt_component_class_query() receives the expected object name");
ce141536
PP
195 res_params = bt_value_array_borrow_element_by_index_const(results, 1);
196 ok(bt_value_compare(res_params, params),
a67681c1 197 "bt_component_class_query() receives the expected parameters");
cbb9e0b1 198
8c6884d9 199 bt_component_class_sink_get_ref(sink_comp_class);
834e9996 200 diag("> putting the plugin set object here");
8c6884d9 201 BT_PLUGIN_SET_PUT_REF_AND_RESET(plugin_set);
7b53201c 202 graph = bt_graph_create();
b8f13b8b 203 BT_ASSERT(graph);
7b53201c 204 graph_ret = bt_graph_add_sink_component(graph, sink_comp_class,
cc81b5ab 205 "the-sink", NULL, BT_LOGGING_LEVEL_NONE, &sink_component);
fb25b9e3 206 ok(graph_ret == BT_GRAPH_ADD_COMPONENT_STATUS_OK && sink_component,
7b53201c 207 "bt_graph_add_sink_component() still works after the plugin object is destroyed");
8c6884d9
PP
208 BT_COMPONENT_SINK_PUT_REF_AND_RESET(sink_component);
209 bt_graph_put_ref(graph);
cbb9e0b1
PP
210
211 free(sfs_path);
8c6884d9
PP
212 bt_component_class_sink_put_ref(sink_comp_class);
213 bt_value_put_ref(results);
214 bt_value_put_ref(params);
215 bt_query_executor_put_ref(query_exec);
cbb9e0b1
PP
216}
217
218static void test_create_all_from_dir(const char *plugin_dir)
219{
8eee8ea2 220 const bt_plugin_set *plugin_set;
fb25b9e3 221 bt_plugin_find_all_from_dir_status status;
cbb9e0b1
PP
222
223 diag("create from all test below");
224
01f50d54
PP
225 status = bt_plugin_find_all_from_dir(NON_EXISTING_PATH, BT_FALSE,
226 BT_FALSE, &plugin_set);
fb25b9e3 227 ok(status == BT_PLUGIN_FIND_ALL_FROM_DIR_STATUS_ERROR,
781ae911 228 "bt_plugin_find_all_from_dir() fails with an invalid path");
a651b97c 229 bt_current_thread_clear_error();
cbb9e0b1 230
01f50d54
PP
231 plugin_set = NULL;
232 status = bt_plugin_find_all_from_dir(plugin_dir, BT_FALSE, BT_FALSE,
233 &plugin_set);
fb25b9e3 234 ok(status == BT_PLUGIN_FIND_ALL_FROM_DIR_STATUS_OK,
01f50d54
PP
235 "bt_plugin_find_all_from_dir() succeeds with a valid path");
236 ok(plugin_set,
237 "bt_plugin_find_all_from_dir() returns a plugin set with a valid path");
cbb9e0b1
PP
238
239 /* 2 or 4, if `.la` files are considered or not */
a8ff38ef
PP
240 ok(bt_plugin_set_get_plugin_count(plugin_set) == 2 ||
241 bt_plugin_set_get_plugin_count(plugin_set) == 4,
781ae911 242 "bt_plugin_find_all_from_dir() returns the expected number of plugin objects");
cbb9e0b1 243
8c6884d9 244 bt_plugin_set_put_ref(plugin_set);
cbb9e0b1
PP
245}
246
2b43acf9 247static void test_find(const char *plugin_dir)
a8b3f23b 248{
4a7062f7 249 int ret;
8eee8ea2 250 const bt_plugin *plugin;
a8b3f23b 251 char *plugin_path;
fb25b9e3 252 bt_plugin_find_status status;
a8b3f23b 253
7d8f15e6
PP
254 ok(bt_plugin_find(NON_EXISTING_PATH, BT_TRUE, BT_FALSE, BT_FALSE,
255 BT_FALSE, BT_FALSE, &plugin) == BT_PLUGIN_FIND_STATUS_NOT_FOUND,
01f50d54 256 "bt_plugin_find() returns BT_PLUGIN_STATUS_NOT_FOUND with an unknown plugin name");
d85ff846
MJ
257 ret = asprintf(&plugin_path, "%s" G_SEARCHPATH_SEPARATOR_S
258 G_DIR_SEPARATOR_S "ec1d09e5-696c-442e-b1c3-f9c6cf7f5958"
259 G_SEARCHPATH_SEPARATOR_S G_SEARCHPATH_SEPARATOR_S
260 G_SEARCHPATH_SEPARATOR_S "%s" G_SEARCHPATH_SEPARATOR_S
261 "8db46494-a398-466a-9649-c765ae077629"
262 G_SEARCHPATH_SEPARATOR_S,
a8b3f23b 263 NON_EXISTING_PATH, plugin_dir);
b8f13b8b 264 BT_ASSERT(ret > 0 && plugin_path);
aacfaf40 265 g_setenv("BABELTRACE_PLUGIN_PATH", plugin_path, 1);
01f50d54 266 plugin = NULL;
7d8f15e6
PP
267 status = bt_plugin_find("test_minimal", BT_TRUE, BT_FALSE, BT_FALSE,
268 BT_FALSE, BT_FALSE, &plugin);
fb25b9e3 269 ok(status == BT_PLUGIN_FIND_STATUS_OK,
2b43acf9 270 "bt_plugin_find() succeeds with a plugin name it can find");
01f50d54 271 ok(plugin, "bt_plugin_find() returns a plugin object");
a8b3f23b 272 ok(strcmp(bt_plugin_get_author(plugin), "Janine Sutto") == 0,
2b43acf9 273 "bt_plugin_find() finds the correct plugin for a given name");
8c6884d9 274 BT_PLUGIN_PUT_REF_AND_RESET(plugin);
a8b3f23b
PP
275 free(plugin_path);
276}
277
cbb9e0b1
PP
278int main(int argc, char **argv)
279{
280 int ret;
281 const char *plugin_dir;
282
283 if (argc != 2) {
284 puts("Usage: test_plugin plugin_directory");
285 ret = 1;
286 goto end;
287 }
288
289 plugin_dir = argv[1];
290 plan_tests(NR_TESTS);
cbb9e0b1
PP
291 test_minimal(plugin_dir);
292 test_sfs(plugin_dir);
293 test_create_all_from_dir(plugin_dir);
2b43acf9 294 test_find(plugin_dir);
cbb9e0b1
PP
295 ret = exit_status();
296end:
297 return ret;
298}
This page took 0.085396 seconds and 4 git commands to generate.