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 | ||
33 | #define NR_TESTS 33 | |
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"); | |
77 | ok(!bt_plugin_get_author(NULL), | |
78 | "bt_plugin_get_author() handles NULL correctly"); | |
79 | ok(!bt_plugin_get_license(NULL), | |
80 | "bt_plugin_get_license() handles NULL correctly"); | |
81 | ok(!bt_plugin_get_path(NULL), | |
82 | "bt_plugin_get_path() handles NULL correctly"); | |
83 | ok(bt_plugin_get_component_class_count(NULL) < 0, | |
84 | "bt_plugin_get_component_class_count() handles NULL correctly"); | |
85 | ok(!bt_plugin_get_component_class(NULL, 0), | |
86 | "bt_plugin_get_component_class() handles NULL correctly"); | |
87 | ok(!bt_plugin_get_component_class_by_name_and_type(NULL, NULL, 0), | |
88 | "bt_plugin_get_component_class_by_name_and_type() handles NULL correctly"); | |
cbb9e0b1 PP |
89 | } |
90 | ||
91 | static void test_minimal(const char *plugin_dir) | |
92 | { | |
6ba0b073 | 93 | struct bt_plugin **plugins; |
cbb9e0b1 PP |
94 | struct bt_plugin *plugin; |
95 | char *minimal_path = get_test_plugin_path(plugin_dir, "minimal"); | |
96 | ||
97 | assert(minimal_path); | |
98 | diag("minimal plugin test below"); | |
99 | ||
100 | reset_test_plugin_symbols(); | |
6ba0b073 PP |
101 | plugins = bt_plugin_create_all_from_file(minimal_path); |
102 | ok(plugins && plugins[0], "bt_plugin_create_all_from_file() succeeds with a valid file"); | |
103 | ok(test_plugin_init_called, "plugin's initialization function is called during bt_plugin_create_all_from_file()"); | |
104 | ok(plugins && plugins[0] && !plugins[1], | |
105 | "bt_plugin_create_all_from_file() returns the expected number of plugins"); | |
106 | plugin = plugins[0]; | |
107 | ok(strcmp(bt_plugin_get_name(plugin), "test_minimal") == 0, | |
cbb9e0b1 PP |
108 | "bt_plugin_get_name() returns the expected name"); |
109 | ok(strcmp(bt_plugin_get_description(plugin), | |
110 | "Minimal Babeltrace plugin with no component classes") == 0, | |
111 | "bt_plugin_get_description() returns the expected description"); | |
112 | ok(strcmp(bt_plugin_get_author(plugin), "Janine Sutto") == 0, | |
113 | "bt_plugin_get_author() returns the expected author"); | |
114 | ok(strcmp(bt_plugin_get_license(plugin), "Beerware") == 0, | |
115 | "bt_plugin_get_license() returns the expected license"); | |
116 | ok(strcmp(bt_plugin_get_path(plugin), minimal_path) == 0, | |
117 | "bt_plugin_get_path() returns the expected path"); | |
118 | ok(bt_plugin_get_component_class_count(plugin) == 0, | |
119 | "bt_plugin_get_component_class_count() returns the expected value"); | |
120 | BT_PUT(plugin); | |
121 | ok(test_plugin_exit_called, "plugin's exit function is called when the plugin is destroyed"); | |
122 | ||
123 | free(minimal_path); | |
6ba0b073 | 124 | free(plugins); |
cbb9e0b1 PP |
125 | } |
126 | ||
127 | static void test_sfs(const char *plugin_dir) | |
128 | { | |
6ba0b073 | 129 | struct bt_plugin **plugins; |
cbb9e0b1 PP |
130 | struct bt_plugin *plugin; |
131 | struct bt_component_class *sink_comp_class; | |
132 | struct bt_component_class *source_comp_class; | |
133 | struct bt_component_class *filter_comp_class; | |
134 | struct bt_component *sink_component; | |
135 | char *sfs_path = get_test_plugin_path(plugin_dir, "sfs"); | |
136 | ||
137 | assert(sfs_path); | |
138 | diag("sfs plugin test below"); | |
139 | ||
6ba0b073 PP |
140 | plugins = bt_plugin_create_all_from_file(sfs_path); |
141 | assert(plugins && plugins[0]); | |
142 | plugin = plugins[0]; | |
cbb9e0b1 PP |
143 | ok(bt_plugin_get_component_class_count(plugin) == 3, |
144 | "bt_plugin_get_component_class_count() returns the expected value"); | |
145 | ||
146 | source_comp_class = bt_plugin_get_component_class_by_name_and_type( | |
d3e4dcd8 | 147 | plugin, "source", BT_COMPONENT_CLASS_TYPE_SOURCE); |
cbb9e0b1 PP |
148 | ok(source_comp_class, |
149 | "bt_plugin_get_component_class_by_name_and_type() finds a source component class"); | |
150 | ||
151 | sink_comp_class = bt_plugin_get_component_class_by_name_and_type( | |
d3e4dcd8 | 152 | plugin, "sink", BT_COMPONENT_CLASS_TYPE_SINK); |
cbb9e0b1 PP |
153 | |
154 | ok(sink_comp_class, | |
155 | "bt_plugin_get_component_class_by_name_and_type() finds a sink component class"); | |
156 | filter_comp_class = bt_plugin_get_component_class_by_name_and_type( | |
d3e4dcd8 | 157 | plugin, "filter", BT_COMPONENT_CLASS_TYPE_FILTER); |
cbb9e0b1 PP |
158 | |
159 | ok(filter_comp_class, | |
160 | "bt_plugin_get_component_class_by_name_and_type() finds a filter component class"); | |
161 | ok(!bt_plugin_get_component_class_by_name_and_type(plugin, "filter", | |
d3e4dcd8 | 162 | BT_COMPONENT_CLASS_TYPE_SOURCE), |
cbb9e0b1 PP |
163 | "bt_plugin_get_component_class_by_name_and_type() does not find a component class given the wrong type"); |
164 | ||
165 | diag("> putting the plugin object here"); | |
166 | BT_PUT(plugin); | |
167 | sink_component = bt_component_create(sink_comp_class, NULL, bt_value_null); | |
168 | ok(sink_component, "bt_component_create() still works after the plugin object is destroyed"); | |
169 | BT_PUT(sink_component); | |
170 | BT_PUT(source_comp_class); | |
171 | sink_component = bt_component_create(sink_comp_class, NULL, bt_value_null); | |
172 | ok(sink_component, "bt_component_create() still works after the source component class object is destroyed"); | |
173 | BT_PUT(sink_component); | |
174 | BT_PUT(filter_comp_class); | |
175 | sink_component = bt_component_create(sink_comp_class, NULL, bt_value_null); | |
176 | ok(sink_component, "bt_component_create() still works after the filter component class object is destroyed"); | |
177 | BT_PUT(sink_comp_class); | |
178 | BT_PUT(sink_component); | |
179 | ||
180 | free(sfs_path); | |
6ba0b073 | 181 | free(plugins); |
cbb9e0b1 PP |
182 | } |
183 | ||
184 | static void test_create_all_from_dir(const char *plugin_dir) | |
185 | { | |
186 | struct bt_plugin **plugins; | |
187 | struct bt_plugin *plugin; | |
188 | int i; | |
189 | ||
190 | diag("create from all test below"); | |
191 | ||
192 | plugins = bt_plugin_create_all_from_dir(NON_EXISTING_PATH, false); | |
193 | ok(!plugins, | |
194 | "bt_plugin_create_all_from_dir() fails with an invalid path"); | |
195 | ||
196 | plugins = bt_plugin_create_all_from_dir(plugin_dir, false); | |
197 | ok(plugins, "bt_plugin_create_all_from_dir() succeeds with a valid path"); | |
198 | ||
199 | i = 0; | |
200 | while ((plugin = plugins[i])) { | |
201 | BT_PUT(plugin); | |
202 | i++; | |
203 | } | |
204 | ||
205 | /* 2 or 4, if `.la` files are considered or not */ | |
206 | ok(i == 2 || i == 4, "bt_plugin_create_all_from_dir() returns the expected number of plugin objects"); | |
207 | ||
208 | free(plugins); | |
209 | } | |
210 | ||
211 | int main(int argc, char **argv) | |
212 | { | |
213 | int ret; | |
214 | const char *plugin_dir; | |
215 | ||
216 | if (argc != 2) { | |
217 | puts("Usage: test_plugin plugin_directory"); | |
218 | ret = 1; | |
219 | goto end; | |
220 | } | |
221 | ||
222 | plugin_dir = argv[1]; | |
223 | plan_tests(NR_TESTS); | |
224 | test_invalid(plugin_dir); | |
225 | test_minimal(plugin_dir); | |
226 | test_sfs(plugin_dir); | |
227 | test_create_all_from_dir(plugin_dir); | |
228 | ret = exit_status(); | |
229 | end: | |
230 | return ret; | |
231 | } |