Commit | Line | Data |
---|---|---|
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> | |
30 | #include "tap/tap.h" | |
31 | #include "common.h" | |
32 | ||
458e8e1d | 33 | #define NR_TESTS 40 |
cbb9e0b1 PP |
34 | #define NON_EXISTING_PATH "/this/hopefully/does/not/exist/5bc75f8d-0dba-4043-a509-d7984b97e42b.so" |
35 | ||
36 | /* Those symbols are written to by some test plugins */ | |
37 | int test_plugin_init_called; | |
38 | int test_plugin_exit_called; | |
39 | ||
40 | static void reset_test_plugin_symbols(void) | |
41 | { | |
42 | test_plugin_init_called = 0; | |
43 | test_plugin_exit_called = 0; | |
44 | } | |
45 | ||
46 | static char *get_test_plugin_path(const char *plugin_dir, | |
47 | const char *plugin_name) | |
48 | { | |
49 | GString *path = g_string_new(plugin_dir); | |
50 | char *ret; | |
51 | ||
52 | assert(path); | |
53 | g_string_append_printf(path, "/plugin-%s.so", plugin_name); | |
54 | ret = path->str; | |
55 | g_string_free(path, FALSE); | |
56 | return ret; | |
57 | } | |
58 | ||
59 | static void test_invalid(const char *plugin_dir) | |
60 | { | |
6ba0b073 | 61 | struct bt_plugin **plugins; |
cbb9e0b1 | 62 | |
6ba0b073 PP |
63 | plugins = bt_plugin_create_all_from_file(NON_EXISTING_PATH); |
64 | ok(!plugins, "bt_plugin_create_all_from_file() fails with a non-existing file"); | |
cbb9e0b1 | 65 | |
6ba0b073 PP |
66 | plugins = bt_plugin_create_all_from_file(plugin_dir); |
67 | ok(!plugins, "bt_plugin_create_all_from_file() fails with a directory"); | |
cbb9e0b1 | 68 | |
6ba0b073 PP |
69 | ok(!bt_plugin_create_all_from_file(NULL), |
70 | "bt_plugin_create_all_from_file() handles NULL correctly"); | |
cbb9e0b1 PP |
71 | ok(!bt_plugin_create_all_from_dir(NULL, false), |
72 | "bt_plugin_create_all_from_dir() handles NULL correctly"); | |
73 | ok(!bt_plugin_get_name(NULL), | |
74 | "bt_plugin_get_name() handles NULL correctly"); | |
75 | ok(!bt_plugin_get_description(NULL), | |
76 | "bt_plugin_get_description() handles NULL correctly"); | |
458e8e1d PP |
77 | ok(bt_plugin_get_version(NULL, NULL, NULL, NULL, NULL) != |
78 | BT_PLUGIN_STATUS_OK, | |
79 | "bt_plugin_get_version() handles NULL correctly"); | |
cbb9e0b1 PP |
80 | ok(!bt_plugin_get_author(NULL), |
81 | "bt_plugin_get_author() handles NULL correctly"); | |
82 | ok(!bt_plugin_get_license(NULL), | |
83 | "bt_plugin_get_license() handles NULL correctly"); | |
84 | ok(!bt_plugin_get_path(NULL), | |
85 | "bt_plugin_get_path() handles NULL correctly"); | |
86 | ok(bt_plugin_get_component_class_count(NULL) < 0, | |
87 | "bt_plugin_get_component_class_count() handles NULL correctly"); | |
88 | ok(!bt_plugin_get_component_class(NULL, 0), | |
89 | "bt_plugin_get_component_class() handles NULL correctly"); | |
90 | ok(!bt_plugin_get_component_class_by_name_and_type(NULL, NULL, 0), | |
91 | "bt_plugin_get_component_class_by_name_and_type() handles NULL correctly"); | |
cbb9e0b1 PP |
92 | } |
93 | ||
94 | static void test_minimal(const char *plugin_dir) | |
95 | { | |
6ba0b073 | 96 | struct bt_plugin **plugins; |
cbb9e0b1 PP |
97 | struct bt_plugin *plugin; |
98 | char *minimal_path = get_test_plugin_path(plugin_dir, "minimal"); | |
99 | ||
100 | assert(minimal_path); | |
101 | diag("minimal plugin test below"); | |
102 | ||
103 | reset_test_plugin_symbols(); | |
6ba0b073 PP |
104 | plugins = bt_plugin_create_all_from_file(minimal_path); |
105 | ok(plugins && plugins[0], "bt_plugin_create_all_from_file() succeeds with a valid file"); | |
106 | ok(test_plugin_init_called, "plugin's initialization function is called during bt_plugin_create_all_from_file()"); | |
107 | ok(plugins && plugins[0] && !plugins[1], | |
108 | "bt_plugin_create_all_from_file() returns the expected number of plugins"); | |
109 | plugin = plugins[0]; | |
110 | ok(strcmp(bt_plugin_get_name(plugin), "test_minimal") == 0, | |
cbb9e0b1 PP |
111 | "bt_plugin_get_name() returns the expected name"); |
112 | ok(strcmp(bt_plugin_get_description(plugin), | |
113 | "Minimal Babeltrace plugin with no component classes") == 0, | |
114 | "bt_plugin_get_description() returns the expected description"); | |
458e8e1d PP |
115 | ok(bt_plugin_get_version(plugin, NULL, NULL, NULL, NULL) != |
116 | BT_PLUGIN_STATUS_OK, | |
117 | "bt_plugin_get_version() fails when there's no version"); | |
cbb9e0b1 PP |
118 | ok(strcmp(bt_plugin_get_author(plugin), "Janine Sutto") == 0, |
119 | "bt_plugin_get_author() returns the expected author"); | |
120 | ok(strcmp(bt_plugin_get_license(plugin), "Beerware") == 0, | |
121 | "bt_plugin_get_license() returns the expected license"); | |
122 | ok(strcmp(bt_plugin_get_path(plugin), minimal_path) == 0, | |
123 | "bt_plugin_get_path() returns the expected path"); | |
124 | ok(bt_plugin_get_component_class_count(plugin) == 0, | |
125 | "bt_plugin_get_component_class_count() returns the expected value"); | |
126 | BT_PUT(plugin); | |
127 | ok(test_plugin_exit_called, "plugin's exit function is called when the plugin is destroyed"); | |
128 | ||
129 | free(minimal_path); | |
6ba0b073 | 130 | free(plugins); |
cbb9e0b1 PP |
131 | } |
132 | ||
133 | static void test_sfs(const char *plugin_dir) | |
134 | { | |
6ba0b073 | 135 | struct bt_plugin **plugins; |
cbb9e0b1 PP |
136 | struct bt_plugin *plugin; |
137 | struct bt_component_class *sink_comp_class; | |
138 | struct bt_component_class *source_comp_class; | |
139 | struct bt_component_class *filter_comp_class; | |
140 | struct bt_component *sink_component; | |
141 | char *sfs_path = get_test_plugin_path(plugin_dir, "sfs"); | |
458e8e1d PP |
142 | unsigned int major, minor, patch; |
143 | const char *extra; | |
cbb9e0b1 PP |
144 | |
145 | assert(sfs_path); | |
146 | diag("sfs plugin test below"); | |
147 | ||
6ba0b073 PP |
148 | plugins = bt_plugin_create_all_from_file(sfs_path); |
149 | assert(plugins && plugins[0]); | |
150 | plugin = plugins[0]; | |
458e8e1d PP |
151 | ok(bt_plugin_get_version(plugin, &major, &minor, &patch, &extra) == |
152 | BT_PLUGIN_STATUS_OK, | |
153 | "bt_plugin_get_version() succeeds when there's a version"); | |
154 | ok(major == 1, | |
155 | "bt_plugin_get_version() returns the expected major version"); | |
156 | ok(minor == 2, | |
157 | "bt_plugin_get_version() returns the expected minor version"); | |
158 | ok(patch == 3, | |
159 | "bt_plugin_get_version() returns the expected patch version"); | |
160 | ok(strcmp(extra, "yes") == 0, | |
161 | "bt_plugin_get_version() returns the expected extra version"); | |
cbb9e0b1 PP |
162 | ok(bt_plugin_get_component_class_count(plugin) == 3, |
163 | "bt_plugin_get_component_class_count() returns the expected value"); | |
164 | ||
165 | source_comp_class = bt_plugin_get_component_class_by_name_and_type( | |
d3e4dcd8 | 166 | plugin, "source", BT_COMPONENT_CLASS_TYPE_SOURCE); |
cbb9e0b1 PP |
167 | ok(source_comp_class, |
168 | "bt_plugin_get_component_class_by_name_and_type() finds a source component class"); | |
169 | ||
170 | sink_comp_class = bt_plugin_get_component_class_by_name_and_type( | |
d3e4dcd8 | 171 | plugin, "sink", BT_COMPONENT_CLASS_TYPE_SINK); |
cbb9e0b1 PP |
172 | |
173 | ok(sink_comp_class, | |
174 | "bt_plugin_get_component_class_by_name_and_type() finds a sink component class"); | |
175 | filter_comp_class = bt_plugin_get_component_class_by_name_and_type( | |
d3e4dcd8 | 176 | plugin, "filter", BT_COMPONENT_CLASS_TYPE_FILTER); |
cbb9e0b1 PP |
177 | |
178 | ok(filter_comp_class, | |
179 | "bt_plugin_get_component_class_by_name_and_type() finds a filter component class"); | |
180 | ok(!bt_plugin_get_component_class_by_name_and_type(plugin, "filter", | |
d3e4dcd8 | 181 | BT_COMPONENT_CLASS_TYPE_SOURCE), |
cbb9e0b1 PP |
182 | "bt_plugin_get_component_class_by_name_and_type() does not find a component class given the wrong type"); |
183 | ||
184 | diag("> putting the plugin object here"); | |
185 | BT_PUT(plugin); | |
186 | sink_component = bt_component_create(sink_comp_class, NULL, bt_value_null); | |
187 | ok(sink_component, "bt_component_create() still works after the plugin object is destroyed"); | |
188 | BT_PUT(sink_component); | |
189 | BT_PUT(source_comp_class); | |
190 | sink_component = bt_component_create(sink_comp_class, NULL, bt_value_null); | |
191 | ok(sink_component, "bt_component_create() still works after the source component class object is destroyed"); | |
192 | BT_PUT(sink_component); | |
193 | BT_PUT(filter_comp_class); | |
194 | sink_component = bt_component_create(sink_comp_class, NULL, bt_value_null); | |
195 | ok(sink_component, "bt_component_create() still works after the filter component class object is destroyed"); | |
196 | BT_PUT(sink_comp_class); | |
197 | BT_PUT(sink_component); | |
198 | ||
199 | free(sfs_path); | |
6ba0b073 | 200 | free(plugins); |
cbb9e0b1 PP |
201 | } |
202 | ||
203 | static void test_create_all_from_dir(const char *plugin_dir) | |
204 | { | |
205 | struct bt_plugin **plugins; | |
206 | struct bt_plugin *plugin; | |
207 | int i; | |
208 | ||
209 | diag("create from all test below"); | |
210 | ||
211 | plugins = bt_plugin_create_all_from_dir(NON_EXISTING_PATH, false); | |
212 | ok(!plugins, | |
213 | "bt_plugin_create_all_from_dir() fails with an invalid path"); | |
214 | ||
215 | plugins = bt_plugin_create_all_from_dir(plugin_dir, false); | |
216 | ok(plugins, "bt_plugin_create_all_from_dir() succeeds with a valid path"); | |
217 | ||
218 | i = 0; | |
219 | while ((plugin = plugins[i])) { | |
220 | BT_PUT(plugin); | |
221 | i++; | |
222 | } | |
223 | ||
224 | /* 2 or 4, if `.la` files are considered or not */ | |
225 | ok(i == 2 || i == 4, "bt_plugin_create_all_from_dir() returns the expected number of plugin objects"); | |
226 | ||
227 | free(plugins); | |
228 | } | |
229 | ||
230 | int main(int argc, char **argv) | |
231 | { | |
232 | int ret; | |
233 | const char *plugin_dir; | |
234 | ||
235 | if (argc != 2) { | |
236 | puts("Usage: test_plugin plugin_directory"); | |
237 | ret = 1; | |
238 | goto end; | |
239 | } | |
240 | ||
241 | plugin_dir = argv[1]; | |
242 | plan_tests(NR_TESTS); | |
243 | test_invalid(plugin_dir); | |
244 | test_minimal(plugin_dir); | |
245 | test_sfs(plugin_dir); | |
246 | test_create_all_from_dir(plugin_dir); | |
247 | ret = exit_status(); | |
248 | end: | |
249 | return ret; | |
250 | } |