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