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