Line data Source code
1 : /*
2 : SSSD
3 :
4 : util-tests.c
5 :
6 : Authors:
7 : Stephen Gallagher <sgallagh@redhat.com>
8 :
9 : Copyright (C) 2010 Red Hat
10 :
11 : This program is free software; you can redistribute it and/or modify
12 : it under the terms of the GNU General Public License as published by
13 : the Free Software Foundation; either version 3 of the License, or
14 : (at your option) any later version.
15 :
16 : This program is distributed in the hope that it will be useful,
17 : but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : GNU General Public License for more details.
20 :
21 : You should have received a copy of the GNU General Public License
22 : along with this program. If not, see <http://www.gnu.org/licenses/>.
23 : */
24 :
25 : #include <popt.h>
26 : #include <talloc.h>
27 : #include <check.h>
28 : #include <sys/types.h>
29 : #include <sys/stat.h>
30 : #include <fcntl.h>
31 : #include <stdlib.h>
32 : #include <ctype.h>
33 :
34 : #include "util/util.h"
35 : #include "util/sss_utf8.h"
36 : #include "util/murmurhash3.h"
37 : #include "tests/common_check.h"
38 :
39 : #define FILENAME_TEMPLATE "tests-atomicio-XXXXXX"
40 : char *filename;
41 : int atio_fd;
42 :
43 1 : START_TEST(test_add_string_to_list)
44 : {
45 : int ret;
46 :
47 1 : char **list = NULL;
48 :
49 1 : ret = add_string_to_list(NULL, NULL, NULL);
50 1 : fail_unless(ret == EINVAL, "NULL input accepted");
51 :
52 1 : ret = add_string_to_list(global_talloc_context, "ABC", &list);
53 1 : fail_unless(ret == EOK, "Adding string to non-existing list failed.");
54 1 : fail_unless(list != NULL, "No new list created.");
55 1 : fail_unless(list[0] != NULL, "String not added to new list.");
56 1 : fail_unless(strcmp(list[0], "ABC") == 0,
57 : "Wrong string added to newly created list.");
58 1 : fail_unless(list[1] == NULL,
59 : "Missing terminating NULL in newly created list.");
60 :
61 1 : ret = add_string_to_list(global_talloc_context, "DEF", &list);
62 1 : fail_unless(ret == EOK, "Adding string to list failed.");
63 1 : fail_unless(list != NULL, "No list returned.");
64 1 : fail_unless(strcmp(list[0], "ABC") == 0, "Wrong first string in new list.");
65 1 : fail_unless(strcmp(list[1], "DEF") == 0, "Wrong string added to list.");
66 1 : fail_unless(list[2] == NULL, "Missing terminating NULL.");
67 :
68 1 : list[0] = NULL;
69 1 : ret = add_string_to_list(global_talloc_context, "ABC", &list);
70 1 : fail_unless(ret == EOK, "Adding string to empty list failed.");
71 1 : fail_unless(list != NULL, "No list returned.");
72 1 : fail_unless(list[0] != NULL, "String not added to empty list.");
73 1 : fail_unless(strcmp(list[0], "ABC") == 0,
74 : "Wrong string added to empty list.");
75 1 : fail_unless(list[1] == NULL,
76 : "Missing terminating NULL in newly created list.");
77 :
78 1 : talloc_free(list);
79 : }
80 1 : END_TEST
81 :
82 1 : START_TEST(test_string_in_list)
83 : {
84 : bool is_in;
85 1 : char *empty_list[] = {NULL};
86 1 : char *list[] = {discard_const("ABC"),
87 : discard_const("DEF"),
88 : discard_const("GHI"),
89 : NULL};
90 :
91 1 : is_in = string_in_list(NULL, NULL, false);
92 1 : fail_unless(!is_in, "NULL string is in NULL list.");
93 :
94 1 : is_in = string_in_list(NULL, empty_list, false);
95 1 : fail_unless(!is_in, "NULL string is in empty list.");
96 :
97 1 : is_in = string_in_list(NULL, list, false);
98 1 : fail_unless(!is_in, "NULL string is in list.");
99 :
100 1 : is_in = string_in_list("ABC", NULL, false);
101 1 : fail_unless(!is_in, "String is in NULL list.");
102 :
103 1 : is_in = string_in_list("ABC", empty_list, false);
104 1 : fail_unless(!is_in, "String is in empty list.");
105 :
106 1 : is_in = string_in_list("ABC", list, false);
107 1 : fail_unless(is_in, "String is not list.");
108 :
109 1 : is_in = string_in_list("abc", list, false);
110 1 : fail_unless(is_in, "String is not case in-sensitive list.");
111 :
112 1 : is_in = string_in_list("abc", list, true);
113 1 : fail_unless(!is_in, "Wrong string found in case sensitive list.");
114 :
115 1 : is_in = string_in_list("123", list, false);
116 1 : fail_unless(!is_in, "Wrong string found in list.");
117 :
118 : }
119 1 : END_TEST
120 :
121 1 : START_TEST(test_parse_args)
122 : {
123 : struct pa_testcase {
124 : const char *argstr;
125 : const char **parsed;
126 : };
127 :
128 : TALLOC_CTX *test_ctx;
129 : int i, ii;
130 : int ret;
131 : char **parsed;
132 : char **only_ret;
133 : char **only_exp;
134 : char **both;
135 :
136 1 : test_ctx = talloc_new(NULL);
137 :
138 : /* Positive tests */
139 1 : const char *parsed1[] = { "foo", NULL };
140 1 : const char *parsed2[] = { "foo", "a", NULL };
141 1 : const char *parsed3[] = { "foo", "b", NULL };
142 1 : const char *parsed4[] = { "foo", "a c", NULL };
143 1 : const char *parsed5[] = { "foo", "a", "d", NULL };
144 1 : const char *parsed6[] = { "foo", "a", "e", NULL };
145 1 : const char *parsed7[] = { "foo", "a", "f", NULL };
146 1 : const char *parsed8[] = { "foo", "a\tg", NULL };
147 1 : const char *parsed9[] = { "foo", NULL };
148 1 : const char *parsed10[] = { " ", "foo", "\t", "\\'", NULL };
149 1 : const char *parsed11[] = { "a", NULL };
150 1 : struct pa_testcase tc[] = {
151 : { "foo", parsed1 },
152 : { "foo a", parsed2 },
153 : { "foo b", parsed3 },
154 : { "foo a\\ c", parsed4 },
155 : { "foo a d ", parsed5 },
156 : { "foo a e ", parsed6 },
157 : { "foo\ta\t \tf \t", parsed7 },
158 : { "foo a\\\tg", parsed8 },
159 : { " foo ", parsed9 },
160 : { "\\ foo \\\t \\' ", parsed10 },
161 : { "a", parsed11 },
162 : { " ", NULL },
163 : { "", NULL },
164 : { " \t ", NULL },
165 : { NULL, NULL }
166 : };
167 :
168 15 : for (i=0; tc[i].argstr != NULL; i++) {
169 14 : parsed = parse_args(tc[i].argstr);
170 14 : fail_if(parsed == NULL && tc[i].parsed != NULL,
171 : "Could not parse correct %d argument string '%s'\n",
172 : i, tc[i].argstr);
173 :
174 14 : ret = diff_string_lists(test_ctx, parsed, discard_const(tc[i].parsed),
175 : &only_ret, &only_exp, &both);
176 14 : fail_unless(ret == EOK, "diff_string_lists returned error [%d]", ret);
177 14 : fail_unless(only_ret[0] == NULL, "The parser returned more data than expected\n");
178 14 : fail_unless(only_exp[0] == NULL, "The parser returned less data than expected\n");
179 :
180 14 : if (parsed) {
181 : int parsed_len;
182 : int expected_len;
183 :
184 11 : for (parsed_len=0; parsed[parsed_len]; ++parsed_len);
185 11 : for (expected_len=0; tc[i].parsed[expected_len]; ++expected_len);
186 :
187 11 : fail_unless(parsed_len == expected_len,
188 : "Test %d: length of 1st array [%d] != length of 2nd "
189 : "array[%d]\n", i, parsed_len, expected_len);
190 :
191 11 : for (ii = 0; parsed[ii]; ii++) free(parsed[ii]);
192 11 : free(parsed);
193 : }
194 : }
195 :
196 1 : talloc_free(test_ctx);
197 : }
198 1 : END_TEST
199 :
200 1 : START_TEST(test_diff_string_lists)
201 : {
202 : TALLOC_CTX *test_ctx;
203 : char **l1;
204 : char **l2;
205 : char **l3;
206 : char **only_l1;
207 : char **only_l2;
208 : char **both;
209 : int ret;
210 :
211 1 : test_ctx = talloc_new(NULL);
212 :
213 : /* Test with all values returned */
214 1 : l1 = talloc_array(test_ctx, char *, 4);
215 1 : l1[0] = talloc_strdup(l1, "a");
216 1 : l1[1] = talloc_strdup(l1, "b");
217 1 : l1[2] = talloc_strdup(l1, "c");
218 1 : l1[3] = NULL;
219 :
220 1 : l2 = talloc_array(test_ctx, char *, 4);
221 1 : l2[0] = talloc_strdup(l1, "d");
222 1 : l2[1] = talloc_strdup(l1, "c");
223 1 : l2[2] = talloc_strdup(l1, "b");
224 1 : l2[3] = NULL;
225 :
226 1 : ret = diff_string_lists(test_ctx,
227 : l1, l2,
228 : &only_l1, &only_l2, &both);
229 :
230 1 : fail_unless(ret == EOK, "diff_string_lists returned error [%d]", ret);
231 1 : fail_unless(strcmp(only_l1[0], "a") == 0, "Missing \"a\" from only_l1");
232 1 : fail_unless(only_l1[1] == NULL, "only_l1 not NULL-terminated");
233 1 : fail_unless(strcmp(only_l2[0], "d") == 0, "Missing \"d\" from only_l2");
234 1 : fail_unless(only_l2[1] == NULL, "only_l2 not NULL-terminated");
235 1 : fail_unless(strcmp(both[0], "c") == 0, "Missing \"c\" from both");
236 1 : fail_unless(strcmp(both[1], "b") == 0, "Missing \"b\" from both");
237 1 : fail_unless(both[2] == NULL, "both not NULL-terminated");
238 :
239 1 : talloc_zfree(only_l1);
240 1 : talloc_zfree(only_l2);
241 1 : talloc_zfree(both);
242 :
243 : /* Test with restricted return values */
244 1 : ret = diff_string_lists(test_ctx,
245 : l1, l2,
246 : &only_l1, &only_l2, NULL);
247 :
248 1 : fail_unless(ret == EOK, "diff_string_lists returned error [%d]", ret);
249 1 : fail_unless(strcmp(only_l1[0], "a") == 0, "Missing \"a\" from only_l1");
250 1 : fail_unless(only_l1[1] == NULL, "only_l1 not NULL-terminated");
251 1 : fail_unless(strcmp(only_l2[0], "d") == 0, "Missing \"d\" from only_l2");
252 1 : fail_unless(only_l2[1] == NULL, "only_l2 not NULL-terminated");
253 1 : fail_unless(both == NULL, "Nothing returned to both");
254 :
255 1 : talloc_zfree(only_l1);
256 1 : talloc_zfree(only_l2);
257 1 : talloc_zfree(both);
258 :
259 1 : ret = diff_string_lists(test_ctx,
260 : l1, l2,
261 : &only_l1, NULL, NULL);
262 :
263 1 : fail_unless(ret == EOK, "diff_string_lists returned error [%d]", ret);
264 1 : fail_unless(strcmp(only_l1[0], "a") == 0, "Missing \"a\" from only_l1");
265 1 : fail_unless(only_l1[1] == NULL, "only_l1 not NULL-terminated");
266 1 : fail_unless(only_l2 == NULL, "Nothing returned to only_l2");
267 1 : fail_unless(both == NULL, "Nothing returned to both");
268 :
269 1 : talloc_zfree(only_l1);
270 1 : talloc_zfree(only_l2);
271 1 : talloc_zfree(both);
272 :
273 1 : ret = diff_string_lists(test_ctx,
274 : l1, l2,
275 : NULL, &only_l2, NULL);
276 :
277 1 : fail_unless(ret == EOK, "diff_string_lists returned error [%d]", ret);
278 1 : fail_unless(strcmp(only_l2[0], "d") == 0, "Missing \"d\" from only_l2");
279 1 : fail_unless(only_l2[1] == NULL, "only_l2 not NULL-terminated");
280 1 : fail_unless(only_l1 == NULL, "Nothing returned to only_l1");
281 1 : fail_unless(both == NULL, "Nothing returned to both");
282 :
283 1 : talloc_zfree(only_l1);
284 1 : talloc_zfree(only_l2);
285 1 : talloc_zfree(both);
286 :
287 : /* Test with no overlap */
288 1 : l3 = talloc_array(test_ctx, char *, 4);
289 1 : l3[0] = talloc_strdup(l1, "d");
290 1 : l3[1] = talloc_strdup(l1, "e");
291 1 : l3[2] = talloc_strdup(l1, "f");
292 1 : l3[3] = NULL;
293 :
294 1 : ret = diff_string_lists(test_ctx,
295 : l1, l3,
296 : &only_l1, &only_l2, &both);
297 :
298 1 : fail_unless(ret == EOK, "diff_string_lists returned error [%d]", ret);
299 1 : fail_unless(strcmp(only_l1[0], "a") == 0, "Missing \"a\" from only_l1");
300 1 : fail_unless(strcmp(only_l1[1], "b") == 0, "Missing \"b\" from only_l1");
301 1 : fail_unless(strcmp(only_l1[2], "c") == 0, "Missing \"c\" from only_l1");
302 1 : fail_unless(only_l1[3] == NULL, "only_l1 not NULL-terminated");
303 1 : fail_unless(strcmp(only_l2[0], "d") == 0, "Missing \"f\" from only_l2");
304 1 : fail_unless(strcmp(only_l2[1], "e") == 0, "Missing \"e\" from only_l2");
305 1 : fail_unless(strcmp(only_l2[2], "f") == 0, "Missing \"d\" from only_l2");
306 1 : fail_unless(only_l2[3] == NULL, "only_l2 not NULL-terminated");
307 1 : fail_unless(both[0] == NULL, "both should have zero entries");
308 :
309 1 : talloc_zfree(only_l1);
310 1 : talloc_zfree(only_l2);
311 1 : talloc_zfree(both);
312 :
313 : /* Test with 100% overlap */
314 1 : ret = diff_string_lists(test_ctx,
315 : l1, l1,
316 : &only_l1, &only_l2, &both);
317 :
318 1 : fail_unless(ret == EOK, "diff_string_lists returned error [%d]", ret);
319 1 : fail_unless(only_l1[0] == NULL, "only_l1 should have zero entries");
320 1 : fail_unless(only_l2[0] == NULL, "only_l2 should have zero entries");
321 1 : fail_unless(strcmp(both[0], "a") == 0, "Missing \"a\" from both");
322 1 : fail_unless(strcmp(both[1], "b") == 0, "Missing \"b\" from both");
323 1 : fail_unless(strcmp(both[2], "c") == 0, "Missing \"c\" from both");
324 1 : fail_unless(both[3] == NULL, "both is not NULL-terminated");
325 :
326 1 : talloc_zfree(only_l1);
327 1 : talloc_zfree(only_l2);
328 1 : talloc_zfree(both);
329 :
330 : /* Test with no second list */
331 1 : ret = diff_string_lists(test_ctx,
332 : l1, NULL,
333 : &only_l1, &only_l2, &both);
334 :
335 1 : fail_unless(ret == EOK, "diff_string_lists returned error [%d]", ret);
336 1 : fail_unless(strcmp(only_l1[0], "a") == 0, "Missing \"a\" from only_l1");
337 1 : fail_unless(strcmp(only_l1[1], "b") == 0, "Missing \"b\" from only_l1");
338 1 : fail_unless(strcmp(only_l1[2], "c") == 0, "Missing \"c\" from only_l1");
339 1 : fail_unless(only_l1[3] == NULL, "only_l1 not NULL-terminated");
340 1 : fail_unless(only_l2[0] == NULL, "only_l2 should have zero entries");
341 1 : fail_unless(both[0] == NULL, "both should have zero entries");
342 :
343 1 : talloc_free(test_ctx);
344 : }
345 1 : END_TEST
346 :
347 :
348 1 : START_TEST(test_sss_filter_sanitize)
349 : {
350 : errno_t ret;
351 1 : char *sanitized = NULL;
352 :
353 1 : TALLOC_CTX *test_ctx = talloc_new(NULL);
354 1 : fail_if (test_ctx == NULL, "Out of memory");
355 :
356 1 : const char no_specials[] = "username";
357 1 : ret = sss_filter_sanitize(test_ctx, no_specials, &sanitized);
358 1 : fail_unless(ret == EOK, "no_specials error [%d][%s]",
359 : ret, strerror(ret));
360 1 : fail_unless(strcmp(no_specials, sanitized)==0,
361 : "Expected [%s], got [%s]",
362 : no_specials, sanitized);
363 :
364 1 : const char has_asterisk[] = "*username";
365 1 : const char has_asterisk_expected[] = "\\2ausername";
366 1 : ret = sss_filter_sanitize(test_ctx, has_asterisk, &sanitized);
367 1 : fail_unless(ret == EOK, "has_asterisk error [%d][%s]",
368 : ret, strerror(ret));
369 1 : fail_unless(strcmp(has_asterisk_expected, sanitized)==0,
370 : "Expected [%s], got [%s]",
371 : has_asterisk_expected, sanitized);
372 :
373 1 : const char has_lparen[] = "user(name";
374 1 : const char has_lparen_expected[] = "user\\28name";
375 1 : ret = sss_filter_sanitize(test_ctx, has_lparen, &sanitized);
376 1 : fail_unless(ret == EOK, "has_lparen error [%d][%s]",
377 : ret, strerror(ret));
378 1 : fail_unless(strcmp(has_lparen_expected, sanitized)==0,
379 : "Expected [%s], got [%s]",
380 : has_lparen_expected, sanitized);
381 :
382 1 : const char has_rparen[] = "user)name";
383 1 : const char has_rparen_expected[] = "user\\29name";
384 1 : ret = sss_filter_sanitize(test_ctx, has_rparen, &sanitized);
385 1 : fail_unless(ret == EOK, "has_rparen error [%d][%s]",
386 : ret, strerror(ret));
387 1 : fail_unless(strcmp(has_rparen_expected, sanitized)==0,
388 : "Expected [%s], got [%s]",
389 : has_rparen_expected, sanitized);
390 :
391 1 : const char has_backslash[] = "username\\";
392 1 : const char has_backslash_expected[] = "username\\5c";
393 1 : ret = sss_filter_sanitize(test_ctx, has_backslash, &sanitized);
394 1 : fail_unless(ret == EOK, "has_backslash error [%d][%s]",
395 : ret, strerror(ret));
396 1 : fail_unless(strcmp(has_backslash_expected, sanitized)==0,
397 : "Expected [%s], got [%s]",
398 : has_backslash_expected, sanitized);
399 :
400 1 : const char has_all[] = "\\(user)*name";
401 1 : const char has_all_expected[] = "\\5c\\28user\\29\\2aname";
402 1 : ret = sss_filter_sanitize(test_ctx, has_all, &sanitized);
403 1 : fail_unless(ret == EOK, "has_all error [%d][%s]",
404 : ret, strerror(ret));
405 1 : fail_unless(strcmp(has_all_expected, sanitized)==0,
406 : "Expected [%s], got [%s]",
407 : has_all_expected, sanitized);
408 :
409 : /* Input is reused from previous test - "\\(user)*name" */
410 1 : const char has_all_allow_asterisk_expected[] = "\\5c\\28user\\29*name";
411 1 : ret = sss_filter_sanitize_ex(test_ctx, has_all, &sanitized, "*");
412 1 : fail_unless(ret == EOK, "has_all error [%d][%s]",
413 : ret, strerror(ret));
414 1 : fail_unless(strcmp(has_all_allow_asterisk_expected, sanitized)==0,
415 : "Expected [%s], got [%s]",
416 : has_all_expected, sanitized);
417 :
418 1 : talloc_free(test_ctx);
419 : }
420 1 : END_TEST
421 :
422 1 : START_TEST(test_fd_nonblocking)
423 : {
424 : int fd;
425 : int flags;
426 : errno_t ret;
427 :
428 1 : fd = open("/dev/null", O_RDONLY);
429 1 : fail_unless(fd > 0);
430 :
431 1 : flags = fcntl(fd, F_GETFL, 0);
432 1 : fail_if(flags & O_NONBLOCK);
433 :
434 1 : ret = sss_fd_nonblocking(fd);
435 1 : fail_unless(ret == EOK);
436 1 : flags = fcntl(fd, F_GETFL, 0);
437 1 : fail_unless(flags & O_NONBLOCK);
438 1 : close(fd);
439 : }
440 1 : END_TEST
441 :
442 1 : START_TEST(test_size_t_overflow)
443 : {
444 1 : fail_unless(!SIZE_T_OVERFLOW(1, 1), "unexpected overflow");
445 1 : fail_unless(!SIZE_T_OVERFLOW(SIZE_MAX, 0), "unexpected overflow");
446 1 : fail_unless(!SIZE_T_OVERFLOW(SIZE_MAX-10, 10), "unexpected overflow");
447 1 : fail_unless(SIZE_T_OVERFLOW(SIZE_MAX, 1), "overflow not detected");
448 1 : fail_unless(SIZE_T_OVERFLOW(SIZE_MAX, SIZE_MAX),
449 : "overflow not detected");
450 1 : fail_unless(SIZE_T_OVERFLOW(SIZE_MAX, ULLONG_MAX),
451 : "overflow not detected");
452 1 : fail_unless(SIZE_T_OVERFLOW(SIZE_MAX, -10), "overflow not detected");
453 : }
454 1 : END_TEST
455 :
456 1 : START_TEST(test_utf8_lowercase)
457 : {
458 1 : const uint8_t munchen_utf8_upcase[] = { 'M', 0xC3, 0x9C, 'N', 'C', 'H', 'E', 'N', 0x0 };
459 1 : const uint8_t munchen_utf8_lowcase[] = { 'm', 0xC3, 0xBC, 'n', 'c', 'h', 'e', 'n', 0x0 };
460 : uint8_t *lcase;
461 : size_t nlen;
462 :
463 1 : lcase = sss_utf8_tolower(munchen_utf8_upcase,
464 : strlen((const char *)munchen_utf8_upcase),
465 : &nlen);
466 1 : fail_if(strlen((const char *) munchen_utf8_upcase) != nlen); /* This is not true for utf8 strings in general */
467 1 : fail_if(memcmp(lcase, munchen_utf8_lowcase, nlen));
468 1 : sss_utf8_free(lcase);
469 : }
470 1 : END_TEST
471 :
472 1 : START_TEST(test_utf8_talloc_lowercase)
473 : {
474 1 : const uint8_t munchen_utf8_upcase[] = { 'M', 0xC3, 0x9C, 'N', 'C', 'H', 'E', 'N', 0x0 };
475 1 : const uint8_t munchen_utf8_lowcase[] = { 'm', 0xC3, 0xBC, 'n', 'c', 'h', 'e', 'n', 0x0 };
476 : uint8_t *lcase;
477 : size_t nsize;
478 :
479 : TALLOC_CTX *test_ctx;
480 1 : test_ctx = talloc_new(NULL);
481 1 : fail_if(test_ctx == NULL);
482 :
483 1 : lcase = sss_tc_utf8_tolower(test_ctx, munchen_utf8_upcase,
484 : strlen((const char *) munchen_utf8_upcase),
485 : &nsize);
486 1 : fail_if(memcmp(lcase, munchen_utf8_lowcase, nsize));
487 1 : talloc_free(test_ctx);
488 : }
489 1 : END_TEST
490 :
491 1 : START_TEST(test_utf8_talloc_str_lowercase)
492 : {
493 1 : const uint8_t munchen_utf8_upcase[] = { 'M', 0xC3, 0x9C, 'N', 'C', 'H', 'E', 'N', 0x0 };
494 1 : const uint8_t munchen_utf8_lowcase[] = { 'm', 0xC3, 0xBC, 'n', 'c', 'h', 'e', 'n', 0x0 };
495 : char *lcase;
496 :
497 : TALLOC_CTX *test_ctx;
498 1 : test_ctx = talloc_new(NULL);
499 1 : fail_if(test_ctx == NULL);
500 :
501 1 : lcase = sss_tc_utf8_str_tolower(test_ctx, (const char *) munchen_utf8_upcase);
502 1 : fail_if(memcmp(lcase, munchen_utf8_lowcase, strlen(lcase)));
503 1 : talloc_free(test_ctx);
504 : }
505 1 : END_TEST
506 :
507 1 : START_TEST(test_utf8_caseeq)
508 : {
509 1 : const uint8_t munchen_utf8_upcase[] = { 'M', 0xC3, 0x9C, 'N', 'C', 'H', 'E', 'N', 0x0 };
510 1 : const uint8_t munchen_utf8_lowcase[] = { 'm', 0xC3, 0xBC, 'n', 'c', 'h', 'e', 'n', 0x0 };
511 1 : const uint8_t czech_utf8_lowcase[] = { 0xC4, 0x8D, 'e', 'c', 'h', 0x0 };
512 1 : const uint8_t czech_utf8_upcase[] = { 0xC4, 0x8C, 'e', 'c', 'h', 0x0 };
513 1 : const uint8_t czech_utf8_lowcase_neg[] = { 0xC4, 0x8E, 'e', 'c', 'h', 0x0 };
514 : errno_t ret;
515 :
516 1 : ret = sss_utf8_case_eq(munchen_utf8_upcase, munchen_utf8_lowcase);
517 1 : fail_unless(ret == EOK, "Latin 1 Supplement comparison failed\n");
518 :
519 1 : ret = sss_utf8_case_eq(czech_utf8_upcase, czech_utf8_lowcase);
520 1 : fail_unless(ret == EOK, "Latin Extended A comparison failed\n");
521 :
522 1 : ret = sss_utf8_case_eq(czech_utf8_upcase, czech_utf8_lowcase_neg);
523 1 : fail_if(ret == EOK, "Negative test succeeded\n");
524 : }
525 1 : END_TEST
526 :
527 1 : START_TEST(test_utf8_check)
528 : {
529 1 : const char *invalid = "ad\351la\357d";
530 1 : const uint8_t valid[] = { 'M', 0xC3, 0x9C, 'N', 'C', 'H', 'E', 'N', 0x0 };
531 : bool ret;
532 :
533 1 : ret = sss_utf8_check(valid, strlen((const char *) valid));
534 1 : fail_unless(ret == true, "Positive test failed\n");
535 :
536 1 : ret = sss_utf8_check((const uint8_t *) invalid, strlen(invalid));
537 1 : fail_unless(ret == false, "Negative test succeeded\n");
538 : }
539 1 : END_TEST
540 :
541 1 : START_TEST(test_murmurhash3_check)
542 : {
543 1 : const char *tests[6] = { "1052800007", "1052800008", "1052800000",
544 : "abcdefghijk", "abcdefghili", "abcdefgh000" };
545 : uint32_t results[6];
546 : int i, j;
547 :
548 7 : for (i = 0; i< 6; i++) {
549 6 : results[i] = murmurhash3(tests[i],
550 6 : strlen(tests[i]),
551 : 0xdeadbeef);
552 21 : for (j = 0; j < i; j++) {
553 15 : fail_if(results[i] == results[j]);
554 : }
555 : }
556 : }
557 1 : END_TEST
558 :
559 1 : START_TEST(test_murmurhash3_random)
560 : {
561 : char test[16];
562 : uint32_t result1;
563 : uint32_t result2;
564 : unsigned int init_seed;
565 : unsigned int seed;
566 : size_t len;
567 : int i;
568 :
569 : /* generate a random string so each time we test with different values */
570 1 : init_seed = time(0);
571 1 : seed = init_seed;
572 : /* use also random length (min len = 1) */
573 1 : len = 1 + rand_r(&seed) % 14;
574 4 : for (i = 0; i < len; i++) {
575 3 : test[i] = 1 + rand_r(&seed) % 254;
576 : }
577 1 : test[len] = '\0'; /* null terminate */
578 :
579 1 : fprintf(stdout, "test_murmurhash3_random seed: %u\n", init_seed);
580 :
581 1 : result1 = murmurhash3(test, len + 1, init_seed);
582 1 : result2 = murmurhash3(test, len + 1, init_seed);
583 1 : fail_if(result1 != result2);
584 : }
585 1 : END_TEST
586 :
587 5 : void setup_atomicio(void)
588 : {
589 : int ret;
590 : mode_t old_umask;
591 :
592 5 : filename = strdup(FILENAME_TEMPLATE);
593 5 : fail_unless(filename != NULL, "strdup failed");
594 :
595 5 : atio_fd = -1;
596 5 : old_umask = umask(SSS_DFL_UMASK);
597 5 : ret = mkstemp(filename);
598 5 : umask(old_umask);
599 5 : fail_unless(ret != -1, "mkstemp failed [%d][%s]", errno, strerror(errno));
600 5 : atio_fd = ret;
601 5 : }
602 :
603 5 : void teardown_atomicio(void)
604 : {
605 : int ret;
606 :
607 5 : if (atio_fd != -1) {
608 5 : ret = close(atio_fd);
609 5 : fail_unless(ret == 0, "close failed [%d][%s]", errno, strerror(errno));
610 : }
611 :
612 5 : fail_unless(filename != NULL, "unknown filename");
613 5 : ret = unlink(filename);
614 5 : free(filename);
615 5 : fail_unless(ret == 0, "unlink failed [%d][%s]", errno, strerror(errno));
616 5 : }
617 :
618 1 : START_TEST(test_atomicio_read_from_file)
619 : {
620 1 : const ssize_t bufsize = 64;
621 : char buf[64];
622 : int fd;
623 : ssize_t numread;
624 : errno_t ret;
625 :
626 1 : fd = open("/dev/zero", O_RDONLY);
627 1 : fail_if(fd == -1, "Cannot open /dev/zero");
628 :
629 1 : errno = 0;
630 1 : numread = sss_atomic_read_s(fd, buf, bufsize);
631 1 : ret = errno;
632 :
633 1 : fail_unless(ret == 0, "Error %d while reading\n", ret);
634 1 : fail_unless(numread == bufsize,
635 : "Read %d bytes expected %d\n", numread, bufsize);
636 1 : close(fd);
637 : }
638 1 : END_TEST
639 :
640 1 : START_TEST(test_atomicio_read_from_small_file)
641 : {
642 1 : char wbuf[] = "foobar";
643 1 : ssize_t wsize = strlen(wbuf)+1;
644 : ssize_t numwritten;
645 : char rbuf[64];
646 : ssize_t numread;
647 : errno_t ret;
648 :
649 1 : fail_if(atio_fd < 0, "No fd to test?\n");
650 :
651 1 : errno = 0;
652 1 : numwritten = sss_atomic_write_s(atio_fd, wbuf, wsize);
653 1 : ret = errno;
654 :
655 1 : fail_unless(ret == 0, "Error %d while writing\n", ret);
656 1 : fail_unless(numwritten == wsize,
657 : "Wrote %d bytes expected %d\n", numwritten, wsize);
658 :
659 1 : fsync(atio_fd);
660 1 : lseek(atio_fd, 0, SEEK_SET);
661 :
662 1 : errno = 0;
663 1 : numread = sss_atomic_read_s(atio_fd, rbuf, 64);
664 1 : ret = errno;
665 :
666 1 : fail_unless(ret == 0, "Error %d while reading\n", ret);
667 1 : fail_unless(numread == numwritten,
668 : "Read %d bytes expected %d\n", numread, numwritten);
669 : }
670 1 : END_TEST
671 :
672 1 : START_TEST(test_atomicio_read_from_large_file)
673 : {
674 1 : char wbuf[] = "123456781234567812345678";
675 1 : ssize_t wsize = strlen(wbuf)+1;
676 : ssize_t numwritten;
677 : char rbuf[8];
678 : ssize_t numread;
679 : ssize_t total;
680 : errno_t ret;
681 :
682 1 : fail_if(atio_fd < 0, "No fd to test?\n");
683 :
684 1 : errno = 0;
685 1 : numwritten = sss_atomic_write_s(atio_fd, wbuf, wsize);
686 1 : ret = errno;
687 :
688 1 : fail_unless(ret == 0, "Error %d while writing\n", ret);
689 1 : fail_unless(numwritten == wsize,
690 : "Wrote %d bytes expected %d\n", numwritten, wsize);
691 :
692 1 : fsync(atio_fd);
693 1 : lseek(atio_fd, 0, SEEK_SET);
694 :
695 1 : total = 0;
696 : do {
697 5 : errno = 0;
698 5 : numread = sss_atomic_read_s(atio_fd, rbuf, 8);
699 5 : ret = errno;
700 :
701 5 : fail_if(numread == -1, "Read error %d: %s\n", ret, strerror(ret));
702 5 : total += numread;
703 5 : } while (numread != 0);
704 :
705 1 : fail_unless(ret == 0, "Error %d while reading\n", ret);
706 1 : fail_unless(total == numwritten,
707 : "Read %d bytes expected %d\n", numread, numwritten);
708 : }
709 1 : END_TEST
710 :
711 1 : START_TEST(test_atomicio_read_exact_sized_file)
712 : {
713 1 : char wbuf[] = "12345678";
714 1 : ssize_t wsize = strlen(wbuf)+1;
715 : ssize_t numwritten;
716 : char rbuf[9];
717 : ssize_t numread;
718 : errno_t ret;
719 :
720 1 : fail_if(atio_fd < 0, "No fd to test?\n");
721 :
722 1 : errno = 0;
723 1 : numwritten = sss_atomic_write_s(atio_fd, wbuf, wsize);
724 1 : ret = errno;
725 :
726 1 : fail_unless(ret == 0, "Error %d while writing\n", ret);
727 1 : fail_unless(numwritten == wsize,
728 : "Wrote %d bytes expected %d\n", numwritten, wsize);
729 :
730 1 : fsync(atio_fd);
731 1 : lseek(atio_fd, 0, SEEK_SET);
732 :
733 1 : errno = 0;
734 1 : numread = sss_atomic_read_s(atio_fd, rbuf, 9);
735 1 : ret = errno;
736 :
737 1 : fail_unless(ret == 0, "Error %d while reading\n", ret);
738 1 : fail_unless(numread == numwritten,
739 : "Read %d bytes expected %d\n", numread, numwritten);
740 :
741 1 : fail_unless(rbuf[8] == '\0', "String not NULL terminated?");
742 1 : fail_unless(strcmp(wbuf, rbuf) == 0, "Read something else than wrote?");
743 :
744 : /* We've reached end-of-file, next read must return 0 */
745 1 : errno = 0;
746 1 : numread = sss_atomic_read_s(atio_fd, rbuf, 9);
747 1 : ret = errno;
748 :
749 1 : fail_unless(ret == 0, "Error %d while reading\n", ret);
750 1 : fail_unless(numread == 0, "More data to read?");
751 : }
752 1 : END_TEST
753 :
754 1 : START_TEST(test_atomicio_read_from_empty_file)
755 : {
756 : char buf[64];
757 : int fd;
758 : ssize_t numread;
759 : errno_t ret;
760 :
761 1 : fd = open("/dev/null", O_RDONLY);
762 1 : fail_if(fd == -1, "Cannot open /dev/null");
763 :
764 1 : errno = 0;
765 1 : numread = sss_atomic_read_s(fd, buf, 64);
766 1 : ret = errno;
767 :
768 1 : fail_unless(ret == 0, "Error %d while reading\n", ret);
769 1 : fail_unless(numread == 0,
770 : "Read %d bytes expected 0\n", numread);
771 1 : close(fd);
772 : }
773 1 : END_TEST
774 :
775 : struct split_data {
776 : const char *input;
777 : const char **expected_list;
778 : bool trim;
779 : bool skip_empty;
780 : int expected_size;
781 : int expected_ret;
782 : };
783 :
784 1 : START_TEST(test_split_on_separator)
785 : {
786 1 : TALLOC_CTX *mem = global_talloc_context;
787 : errno_t ret;
788 1 : char **list = NULL;
789 : int size;
790 : const char *str_ref;
791 : const char *str_out;
792 : int i;
793 : int a;
794 : int num_of_tests;
795 7 : struct split_data sts[] = {
796 : {
797 : "one,two,three", /* input string */
798 1 : (const char *[]){"one", "two", "three", NULL}, /* expec. output list */
799 : false, false, /* trim, skip_empty */
800 : 3, 0 /* expec. size, expec. retval */
801 : },
802 : {
803 : "one,two,three",
804 1 : (const char *[]){"one", "two", "three", NULL},
805 : true, true,
806 : 3, 0
807 : },
808 : {
809 : " one, two ,three ",
810 1 : (const char*[]){"one", "two", "three", NULL},
811 : true, true,
812 : 3, 0
813 : },
814 : {
815 : /* If skip empty is false, single comma means "empty,empty" */
816 : ",",
817 1 : (const char*[]){"", "", NULL, NULL},
818 : false, false,
819 : 2, 0
820 : },
821 : {
822 : "one, ,",
823 1 : (const char*[]){"one", " ", "NULL", "NULL"},
824 : false, true,
825 : 2, 0
826 : },
827 : {
828 : ", ,,",
829 1 : (const char*[]){NULL},
830 : true, true,
831 : 0, 0
832 : },
833 : {
834 : NULL,
835 : NULL,
836 : false, false,
837 : 0, EINVAL
838 : },
839 : };
840 1 : num_of_tests = sizeof(sts) / sizeof(struct split_data);
841 :
842 8 : for (a = 0; a < num_of_tests; a++) {
843 7 : ret = split_on_separator(mem, sts[a].input, ',', sts[a].trim,
844 7 : sts[a].skip_empty, &list, &size);
845 :
846 7 : fail_unless(ret == sts[a].expected_ret,
847 : "split_on_separator failed [%d]: %s\n", ret,
848 : strerror(ret));
849 7 : if (ret) {
850 1 : continue;
851 : }
852 6 : fail_unless(size == sts[a].expected_size, "Returned wrong size %d "
853 : "(expected %d).\n", size, sts[a].expected_size);
854 :
855 19 : for (i = 0; str_ref = sts[a].expected_list[i], str_out = list[i]; i++) {
856 13 : fail_unless(strcmp(str_ref, str_out) == 0,
857 : "Expected:%s Got:%s\n", str_ref, str_out);
858 : }
859 6 : talloc_free(list);
860 6 : list = NULL;
861 : }
862 : }
863 1 : END_TEST
864 :
865 : struct check_ip_test_data {
866 : const char *str_ipaddr;
867 : uint8_t flags;
868 : bool expected_ret;
869 : };
870 :
871 1 : START_TEST(test_check_ipv4_addr)
872 : {
873 : int a;
874 : int num_of_tests;
875 : int ret;
876 : bool bret;
877 : struct in_addr addr;
878 1 : struct check_ip_test_data tst_data[] = {
879 : {
880 : "192.168.100.1", /* input IPv4 address */
881 : 0, /* flags value */
882 : true /* Expected return value */
883 : },
884 : {
885 : "224.0.0.22", /* multicast address */
886 : SSS_NO_MULTICAST,
887 : false
888 : },
889 : {
890 : "192.186.0.224",
891 : SSS_NO_MULTICAST,
892 : true
893 : },
894 : {
895 : "127.0.0.1",
896 : SSS_NO_LOOPBACK,
897 : false
898 : },
899 : {
900 : "169.254.0.11",
901 : SSS_NO_LINKLOCAL,
902 : false
903 : },
904 : {
905 : "255.255.255.255",
906 : SSS_NO_BROADCAST,
907 : false
908 : },
909 : {
910 : "255.255.255.255",
911 : SSS_NO_SPECIAL,
912 : false
913 : },
914 : {
915 : "192.168.254.169",
916 : SSS_NO_SPECIAL,
917 : true
918 : },
919 : };
920 :
921 1 : num_of_tests = sizeof(tst_data) / sizeof(struct check_ip_test_data);
922 :
923 9 : for (a = 0; a < num_of_tests; a++) {
924 : /* fill sockaddr_in structure */
925 :
926 8 : ret = inet_pton(AF_INET, tst_data[a].str_ipaddr, &addr);
927 8 : fail_if(ret != 1, "inet_pton failed.");
928 :
929 8 : bret = check_ipv4_addr(&addr, tst_data[a].flags);
930 8 : fail_unless(bret == tst_data[a].expected_ret,
931 : "check_ipv4_addr failed (iteration %d)", a);
932 : }
933 : }
934 1 : END_TEST
935 :
936 1 : START_TEST(test_check_ipv6_addr)
937 : {
938 : int a;
939 : int num_of_tests;
940 : int ret;
941 : bool bret;
942 : struct in6_addr addr;
943 1 : struct check_ip_test_data tst_data[] = {
944 : {
945 : "fde9:7e3f:1ed3:24a5::4", /* input IPv6 address */
946 : 0, /* flags value */
947 : true /* Expected return value */
948 : },
949 : {
950 : "fe80::f2de:f1ff:fefa:67f0",
951 : SSS_NO_LINKLOCAL,
952 : false
953 : },
954 : {
955 : "::1",
956 : SSS_NO_LOOPBACK,
957 : false
958 : },
959 : {
960 : "ff00::123",
961 : SSS_NO_MULTICAST,
962 : false
963 : },
964 : {
965 : "ff00::321",
966 : SSS_NO_SPECIAL,
967 : false
968 : },
969 : };
970 :
971 1 : num_of_tests = sizeof(tst_data) / sizeof(struct check_ip_test_data);
972 :
973 6 : for (a = 0; a < num_of_tests; a++) {
974 : /* fill sockaddr_in structure */
975 :
976 5 : ret = inet_pton(AF_INET6, tst_data[a].str_ipaddr, &addr);
977 5 : fail_if(ret != 1, "inet_pton failed.");
978 :
979 5 : bret = check_ipv6_addr(&addr, tst_data[a].flags);
980 5 : fail_unless(bret == tst_data[a].expected_ret,
981 : "check_ipv6_addr failed (iteration %d)", a);
982 :
983 : }
984 : }
985 1 : END_TEST
986 :
987 1 : START_TEST(test_is_host_in_domain)
988 : {
989 : struct {
990 : const char *host;
991 : const char *domain;
992 : bool expected;
993 1 : } data[] = {{"example.com", "example.com", true},
994 : {"client.example.com", "example.com", true},
995 : {"client.child.example.com", "example.com", true},
996 : {"example.com", "child.example.com", false},
997 : {"client.example.com", "child.example.com", false},
998 : {"client.child.example.com", "child.example.com", true},
999 : {"my.com", "example.com", false},
1000 : {"myexample.com", "example.com", false},
1001 : {NULL, NULL, false}};
1002 : bool ret;
1003 : int i;
1004 :
1005 9 : for (i = 0; data[i].host != NULL; i++) {
1006 8 : ret = is_host_in_domain(data[i].host, data[i].domain);
1007 8 : fail_if(ret != data[i].expected, "Host: %s, Domain: %s, Expected: %d, "
1008 : "Got: %d\n", data[i].host, data[i].domain,
1009 : data[i].expected, ret);
1010 : }
1011 : }
1012 1 : END_TEST
1013 :
1014 1 : START_TEST(test_known_service)
1015 : {
1016 : const char * const * svcs;
1017 1 : bool found_nss = false;
1018 : int i;
1019 :
1020 : /* Just make sure we can't find a bogus service and nss
1021 : * is always available
1022 : */
1023 1 : svcs = get_known_services();
1024 8 : for (i = 0; svcs[i]; i++) {
1025 7 : ck_assert_str_ne(svcs[i], "nosuchservice");
1026 7 : if (strcmp(svcs[i], "nss") == 0) {
1027 1 : found_nss = true;
1028 : }
1029 : }
1030 :
1031 1 : ck_assert(found_nss == true);
1032 : }
1033 1 : END_TEST
1034 :
1035 3 : static void convert_time_tz(const char* tz)
1036 : {
1037 : errno_t ret, ret2;
1038 : time_t unix_time;
1039 3 : const char *orig_tz = NULL;
1040 :
1041 3 : orig_tz = getenv("TZ");
1042 3 : if (orig_tz == NULL) {
1043 1 : orig_tz = "";
1044 : }
1045 :
1046 3 : if (tz) {
1047 2 : ret = setenv("TZ", tz, 1);
1048 2 : fail_if(ret == -1);
1049 : }
1050 :
1051 3 : ret = sss_utc_to_time_t("20140801115742Z", "%Y%m%d%H%M%SZ", &unix_time);
1052 :
1053 : /* restore */
1054 3 : if (orig_tz != NULL) {
1055 3 : ret2 = setenv("TZ", orig_tz, 1);
1056 3 : fail_if(ret2 == -1);
1057 : }
1058 3 : fail_unless(ret == EOK && difftime(1406894262, unix_time) == 0);
1059 3 : }
1060 :
1061 1 : START_TEST(test_convert_time)
1062 : {
1063 1 : const char *format = "%Y%m%d%H%M%SZ";
1064 : time_t unix_time;
1065 : errno_t ret;
1066 :
1067 1 : ret = sss_utc_to_time_t("20150127133540P", format, &unix_time);
1068 1 : fail_unless(ret == ERR_TIMESPEC_NOT_SUPPORTED);
1069 1 : ret = sss_utc_to_time_t("0Z", format, &unix_time);
1070 1 : fail_unless(ret == EINVAL);
1071 1 : ret = sss_utc_to_time_t("000001010000Z", format, &unix_time);
1072 1 : fail_unless(ret == EINVAL);
1073 :
1074 : /* test that results are still same no matter what timezone is set */
1075 1 : convert_time_tz(NULL);
1076 :
1077 1 : convert_time_tz("GST-1");
1078 :
1079 1 : convert_time_tz("GST-2");
1080 : }
1081 1 : END_TEST
1082 :
1083 1 : START_TEST(test_sss_strerror_err_last)
1084 : {
1085 1 : ck_assert_str_eq(sss_strerror(ERR_LAST), "ERR_LAST");
1086 : }
1087 1 : END_TEST
1088 :
1089 1 : START_TEST(test_sss_strerror_string_validation)
1090 : {
1091 : enum sssd_errors idx;
1092 : const char *error;
1093 : size_t len;
1094 : char last_character;
1095 :
1096 58 : for (idx = ERR_BASE; idx < ERR_LAST; ++idx) {
1097 57 : error = sss_strerror(idx);
1098 57 : fail_if(error == NULL, "sss_strerror returned NULL for valid index");
1099 :
1100 57 : len = strlen(error);
1101 57 : fail_if(len == 0, "sss_strerror returned empty string");
1102 :
1103 57 : last_character = error[len - 1];
1104 57 : fail_if(isalpha(last_character) == 0 && last_character != ')',
1105 : "Error string [%s] must finish with alphabetic character\n",
1106 : error);
1107 : }
1108 : }
1109 1 : END_TEST
1110 :
1111 1 : Suite *util_suite(void)
1112 : {
1113 1 : Suite *s = suite_create("util");
1114 :
1115 1 : TCase *tc_util = tcase_create("util");
1116 :
1117 1 : tcase_add_checked_fixture(tc_util,
1118 : ck_leak_check_setup,
1119 : ck_leak_check_teardown);
1120 1 : tcase_add_test (tc_util, test_diff_string_lists);
1121 1 : tcase_add_test (tc_util, test_sss_filter_sanitize);
1122 1 : tcase_add_test (tc_util, test_size_t_overflow);
1123 1 : tcase_add_test (tc_util, test_parse_args);
1124 1 : tcase_add_test (tc_util, test_add_string_to_list);
1125 1 : tcase_add_test (tc_util, test_string_in_list);
1126 1 : tcase_add_test (tc_util, test_split_on_separator);
1127 1 : tcase_add_test (tc_util, test_check_ipv4_addr);
1128 1 : tcase_add_test (tc_util, test_check_ipv6_addr);
1129 1 : tcase_add_test (tc_util, test_is_host_in_domain);
1130 1 : tcase_add_test (tc_util, test_known_service);
1131 1 : tcase_add_test (tc_util, test_fd_nonblocking);
1132 1 : tcase_set_timeout(tc_util, 60);
1133 :
1134 1 : TCase *tc_utf8 = tcase_create("utf8");
1135 1 : tcase_add_test (tc_utf8, test_utf8_lowercase);
1136 1 : tcase_add_test (tc_utf8, test_utf8_talloc_lowercase);
1137 1 : tcase_add_test (tc_utf8, test_utf8_talloc_str_lowercase);
1138 1 : tcase_add_test (tc_utf8, test_utf8_caseeq);
1139 1 : tcase_add_test (tc_utf8, test_utf8_check);
1140 :
1141 1 : tcase_set_timeout(tc_utf8, 60);
1142 :
1143 1 : TCase *tc_mh3 = tcase_create("murmurhash3");
1144 1 : tcase_add_test (tc_mh3, test_murmurhash3_check);
1145 1 : tcase_add_test (tc_mh3, test_murmurhash3_random);
1146 1 : tcase_set_timeout(tc_mh3, 60);
1147 :
1148 1 : TCase *tc_atomicio = tcase_create("atomicio");
1149 1 : tcase_add_checked_fixture (tc_atomicio,
1150 : setup_atomicio,
1151 : teardown_atomicio);
1152 1 : tcase_add_test(tc_atomicio, test_atomicio_read_from_file);
1153 1 : tcase_add_test(tc_atomicio, test_atomicio_read_from_small_file);
1154 1 : tcase_add_test(tc_atomicio, test_atomicio_read_from_large_file);
1155 1 : tcase_add_test(tc_atomicio, test_atomicio_read_exact_sized_file);
1156 1 : tcase_add_test(tc_atomicio, test_atomicio_read_from_empty_file);
1157 :
1158 1 : TCase *tc_convert_time = tcase_create("convert_time");
1159 1 : tcase_add_checked_fixture(tc_convert_time,
1160 : ck_leak_check_setup,
1161 : ck_leak_check_teardown);
1162 1 : tcase_add_test(tc_convert_time, test_convert_time);
1163 :
1164 1 : TCase *tc_sss_strerror = tcase_create("sss_strerror");
1165 1 : tcase_add_test(tc_sss_strerror, test_sss_strerror_err_last);
1166 1 : tcase_add_test(tc_sss_strerror, test_sss_strerror_string_validation);
1167 :
1168 1 : suite_add_tcase (s, tc_util);
1169 1 : suite_add_tcase (s, tc_utf8);
1170 1 : suite_add_tcase (s, tc_mh3);
1171 1 : suite_add_tcase (s, tc_atomicio);
1172 1 : suite_add_tcase (s, tc_convert_time);
1173 1 : suite_add_tcase (s, tc_sss_strerror);
1174 :
1175 1 : return s;
1176 : }
1177 :
1178 1 : int main(int argc, const char *argv[])
1179 : {
1180 : int opt;
1181 : int failure_count;
1182 : poptContext pc;
1183 1 : Suite *s = util_suite();
1184 1 : SRunner *sr = srunner_create (s);
1185 :
1186 6 : struct poptOption long_options[] = {
1187 : POPT_AUTOHELP
1188 5 : SSSD_MAIN_OPTS
1189 : POPT_TABLEEND
1190 : };
1191 :
1192 : /* Set debug level to invalid value so we can deside if -d 0 was used. */
1193 1 : debug_level = SSSDBG_INVALID;
1194 :
1195 1 : pc = poptGetContext(argv[0], argc, argv, long_options, 0);
1196 1 : while((opt = poptGetNextOpt(pc)) != -1) {
1197 : switch(opt) {
1198 : default:
1199 0 : fprintf(stderr, "\nInvalid option %s: %s\n\n",
1200 : poptBadOption(pc, 0), poptStrerror(opt));
1201 0 : poptPrintUsage(pc, stderr, 0);
1202 0 : return 1;
1203 : }
1204 : }
1205 1 : poptFreeContext(pc);
1206 :
1207 1 : DEBUG_CLI_INIT(debug_level);
1208 :
1209 1 : tests_set_cwd();
1210 :
1211 1 : srunner_run_all(sr, CK_ENV);
1212 1 : failure_count = srunner_ntests_failed (sr);
1213 1 : srunner_free (sr);
1214 1 : if (failure_count == 0) {
1215 1 : return EXIT_SUCCESS;
1216 : }
1217 0 : return EXIT_FAILURE;
1218 : }
|