Imported Upstream version 0.8.4
[platform/upstream/multipath-tools.git] / tests / uevent.c
1 /*
2  * Copyright (c) 2018 SUSE Linux GmbH
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
16  *
17  */
18
19 #include <stdbool.h>
20 #include <stdarg.h>
21 #include <stddef.h>
22 #include <setjmp.h>
23 #include <stdlib.h>
24 #include <cmocka.h>
25 #include "list.h"
26 #include "uevent.h"
27
28 #include "globals.c"
29
30 /* Private prototypes missing in uevent.h */
31 struct uevent * alloc_uevent(void);
32 void uevent_get_wwid(struct uevent *uev);
33
34 /* Stringify helpers */
35 #define _str_(x) #x
36 #define str(x) _str_(x)
37
38 #define MAJOR 17
39 #define MINOR 217
40 #define DISK_RO 0
41 #define DM_NAME "spam"
42 #define WWID "foo"
43
44 static int setup_uev(void **state)
45 {
46         static char test_uid_attrs[] =
47                 "dasd:ID_SPAM   sd:ID_BOGUS nvme:ID_EGGS    ";
48
49         struct uevent *uev = alloc_uevent();
50         struct config *conf;
51
52         if (uev == NULL)
53                 return -1;
54
55         *state = uev;
56         uev->kernel = "sdo";
57         uev->envp[0] = "MAJOR=" str(MAJOR);
58         uev->envp[1] = "ID_SPAM=nonsense";
59         uev->envp[1] = "ID_BOGUS=" WWID;
60         uev->envp[2] = "MINOR=" str(MINOR);
61         uev->envp[3] = "DM_NAME=" DM_NAME;
62         uev->envp[4] = "DISK_RO=" str(DISK_RO);
63         uev->envp[5] = NULL;
64
65         conf = get_multipath_config();
66         parse_uid_attrs(test_uid_attrs, conf);
67         put_multipath_config(conf);
68         return 0;
69 }
70
71 static int teardown(void **state)
72 {
73         free(*state);
74         return 0;
75 }
76
77 static void test_major_good(void **state)
78 {
79         struct uevent *uev = *state;
80
81         assert_int_equal(uevent_get_major(uev), MAJOR);
82 }
83
84 static void test_minor_good(void **state)
85 {
86         struct uevent *uev = *state;
87
88         assert_int_equal(uevent_get_minor(uev), MINOR);
89 }
90
91 static void test_ro_good(void **state)
92 {
93         struct uevent *uev = *state;
94
95         assert_int_equal(uevent_get_disk_ro(uev), DISK_RO);
96 }
97
98 static void test_uid_attrs(void **state)
99 {
100         /* see test_uid_attrs above */
101         struct config *conf = get_multipath_config();
102         vector attrs = &conf->uid_attrs;
103
104         assert_int_equal(VECTOR_SIZE(attrs), 3);
105         assert_null(get_uid_attribute_by_attrs(conf, "hda"));
106         assert_string_equal("ID_BOGUS",
107                             get_uid_attribute_by_attrs(conf, "sdaw"));
108         assert_string_equal("ID_SPAM",
109                             get_uid_attribute_by_attrs(conf, "dasdu"));
110         assert_string_equal("ID_EGGS",
111                             get_uid_attribute_by_attrs(conf, "nvme2n4"));
112         put_multipath_config(conf);
113 }
114
115 static void test_wwid(void **state)
116 {
117         struct uevent *uev = *state;
118         uevent_get_wwid(uev);
119
120         assert_string_equal(uev->wwid, WWID);
121 }
122
123 static void test_major_bad_0(void **state)
124 {
125         struct uevent *uev = *state;
126
127         uev->envp[0] = "MAJOR" str(MAJOR);
128         assert_int_equal(uevent_get_major(uev), -1);
129 }
130
131 static void test_major_bad_1(void **state)
132 {
133         struct uevent *uev = *state;
134
135         uev->envp[0] = "MAJOr=" str(MAJOR);
136         assert_int_equal(uevent_get_major(uev), -1);
137 }
138
139 static void test_major_bad_2(void **state)
140 {
141         struct uevent *uev = *state;
142
143         uev->envp[0] = "MAJORIE=" str(MAJOR);
144         assert_int_equal(uevent_get_major(uev), -1);
145 }
146
147 static void test_major_bad_3(void **state)
148 {
149         struct uevent *uev = *state;
150
151         uev->envp[0] = "MAJOR=max";
152         assert_int_equal(uevent_get_major(uev), -1);
153 }
154
155 static void test_major_bad_4(void **state)
156 {
157         struct uevent *uev = *state;
158
159         uev->envp[0] = "MAJOR=0x10";
160         assert_int_equal(uevent_get_major(uev), -1);
161 }
162
163 static void test_major_bad_5(void **state)
164 {
165         struct uevent *uev = *state;
166
167         uev->envp[0] = "MAJO=" str(MAJOR);
168         assert_int_equal(uevent_get_major(uev), -1);
169 }
170
171 static void test_major_bad_6(void **state)
172 {
173         struct uevent *uev = *state;
174
175         uev->envp[0] = "MAJOR=" str(-MAJOR);
176         assert_int_equal(uevent_get_major(uev), -1);
177 }
178
179 static void test_major_bad_7(void **state)
180 {
181         struct uevent *uev = *state;
182
183         uev->envp[0] = "MAJOR=";
184         assert_int_equal(uevent_get_major(uev), -1);
185 }
186
187 static void test_major_bad_8(void **state)
188 {
189         struct uevent *uev = *state;
190
191         uev->envp[0] = "MAJOR";
192         assert_int_equal(uevent_get_major(uev), -1);
193 }
194
195 static void test_dm_name_good(void **state)
196 {
197         struct uevent *uev = *state;
198         char *name = uevent_get_dm_name(uev);
199
200         assert_string_equal(name, DM_NAME);
201         FREE(name);
202 }
203
204 static void test_dm_name_bad_0(void **state)
205 {
206         struct uevent *uev = *state;
207         char *name;
208
209         uev->envp[3] = "DM_NAME" DM_NAME;
210         name = uevent_get_dm_name(uev);
211         assert_ptr_equal(name, NULL);
212         FREE(name);
213 }
214
215 static void test_dm_name_bad_1(void **state)
216 {
217         struct uevent *uev = *state;
218         char *name;
219
220         uev->envp[3] = "DM_NAMES=" DM_NAME;
221         name = uevent_get_dm_name(uev);
222         assert_ptr_equal(name, NULL);
223         FREE(name);
224 }
225
226 static void test_dm_name_good_1(void **state)
227 {
228         struct uevent *uev = *state;
229         char *name;
230
231         /* Note we change index 2 here */
232         uev->envp[2] = "DM_NAME=" DM_NAME;
233         name = uevent_get_dm_name(uev);
234         assert_string_equal(name, DM_NAME);
235         FREE(name);
236 }
237
238 static void test_dm_uuid_false_0(void **state)
239 {
240         struct uevent *uev = *state;
241
242         assert_false(uevent_is_mpath(uev));
243 }
244
245 static void test_dm_uuid_true_0(void **state)
246 {
247         struct uevent *uev = *state;
248
249         uev->envp[3] = "DM_UUID=mpath-foo";
250         assert_true(uevent_is_mpath(uev));
251 }
252
253 static void test_dm_uuid_false_1(void **state)
254 {
255         struct uevent *uev = *state;
256
257         uev->envp[3] = "DM_UUID.mpath-foo";
258         assert_false(uevent_is_mpath(uev));
259 }
260
261 static void test_dm_uuid_false_2(void **state)
262 {
263         struct uevent *uev = *state;
264
265         uev->envp[3] = "DM_UUID=mpath-";
266         assert_false(uevent_is_mpath(uev));
267 }
268
269 static void test_dm_uuid_false_3(void **state)
270 {
271         struct uevent *uev = *state;
272
273         uev->envp[3] = "DM_UU=mpath-foo";
274         assert_false(uevent_is_mpath(uev));
275 }
276
277 static void test_dm_uuid_false_4(void **state)
278 {
279         struct uevent *uev = *state;
280
281         uev->envp[3] = "DM_UUID=mpathfoo";
282         assert_false(uevent_is_mpath(uev));
283 }
284
285 static void test_dm_uuid_false_5(void **state)
286 {
287         struct uevent *uev = *state;
288
289         uev->envp[3] = "DM_UUID=";
290         assert_false(uevent_is_mpath(uev));
291 }
292
293 int test_uevent_get_XXX(void)
294 {
295         const struct CMUnitTest tests[] = {
296                 cmocka_unit_test(test_major_good),
297                 cmocka_unit_test(test_minor_good),
298                 cmocka_unit_test(test_ro_good),
299                 cmocka_unit_test(test_dm_name_good),
300                 cmocka_unit_test(test_uid_attrs),
301                 cmocka_unit_test(test_wwid),
302                 cmocka_unit_test(test_major_bad_0),
303                 cmocka_unit_test(test_major_bad_1),
304                 cmocka_unit_test(test_major_bad_2),
305                 cmocka_unit_test(test_major_bad_3),
306                 cmocka_unit_test(test_major_bad_4),
307                 cmocka_unit_test(test_major_bad_5),
308                 cmocka_unit_test(test_major_bad_6),
309                 cmocka_unit_test(test_major_bad_7),
310                 cmocka_unit_test(test_major_bad_8),
311                 cmocka_unit_test(test_dm_name_bad_0),
312                 cmocka_unit_test(test_dm_name_bad_1),
313                 cmocka_unit_test(test_dm_name_good_1),
314                 cmocka_unit_test(test_dm_uuid_false_0),
315                 cmocka_unit_test(test_dm_uuid_true_0),
316                 cmocka_unit_test(test_dm_uuid_false_1),
317                 cmocka_unit_test(test_dm_uuid_false_2),
318                 cmocka_unit_test(test_dm_uuid_false_3),
319                 cmocka_unit_test(test_dm_uuid_false_4),
320                 cmocka_unit_test(test_dm_uuid_false_5),
321         };
322         return cmocka_run_group_tests(tests, setup_uev, teardown);
323 }
324
325 int main(void)
326 {
327         int ret = 0;
328
329         ret += test_uevent_get_XXX();
330         return ret;
331 }