]> git.ipfire.org Git - thirdparty/strongswan.git/blob - src/libstrongswan/tests/test_utils.c
3ca0412b4b15962665ea7be49a6023fc89c52ebc
[thirdparty/strongswan.git] / src / libstrongswan / tests / test_utils.c
1 /*
2 * Copyright (C) 2013 Tobias Brunner
3 * Hochschule fuer Technik Rapperswil
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 */
15
16 #include "test_suite.h"
17
18 #include <library.h>
19 #include <utils/utils.h>
20 #include <ipsec/ipsec_types.h>
21
22 #include <time.h>
23
24 /*******************************************************************************
25 * object storage on lib
26 */
27
28 START_TEST(test_objects)
29 {
30 char *k1 = "key1", *k2 = "key2";
31 char *v1 = "val1", *val;
32
33 ck_assert(lib->get(lib, k1) == NULL);
34
35 ck_assert(lib->set(lib, k1, v1));
36 ck_assert(!lib->set(lib, k1, v1));
37
38 val = lib->get(lib, k1);
39 ck_assert(val != NULL);
40 ck_assert(streq(val, v1));
41
42 ck_assert(lib->set(lib, k1, NULL));
43 ck_assert(!lib->set(lib, k2, NULL));
44
45 ck_assert(lib->get(lib, k1) == NULL);
46 }
47 END_TEST
48
49 /*******************************************************************************
50 * test return_... functions
51 */
52
53 START_TEST(test_return_functions)
54 {
55 ck_assert(return_null() == NULL);
56 ck_assert(return_null("asdf", 5, NULL, 1, "qwer") == NULL);
57
58 ck_assert(return_true() == TRUE);
59 ck_assert(return_true("asdf", 5, NULL, 1, "qwer") == TRUE);
60
61 ck_assert(return_false() == FALSE);
62 ck_assert(return_false("asdf", 5, NULL, 1, "qwer") == FALSE);
63
64 ck_assert(return_failed() == FAILED);
65 ck_assert(return_failed("asdf", 5, NULL, 1, "qwer") == FAILED);
66
67 ck_assert(return_success() == SUCCESS);
68 ck_assert(return_success("asdf", 5, NULL, 1, "qwer") == SUCCESS);
69
70 /* just make sure this works */
71 nop();
72 nop("asdf", 5, NULL, 1, "qwer");
73 }
74 END_TEST
75
76 /*******************************************************************************
77 * timeval_add_ms
78 */
79
80 START_TEST(test_timeval_add_ms)
81 {
82 timeval_t tv;
83
84 tv.tv_sec = 0;
85 tv.tv_usec = 0;
86 timeval_add_ms(&tv, 0);
87 ck_assert_int_eq(tv.tv_sec, 0);
88 ck_assert_int_eq(tv.tv_usec, 0);
89
90 timeval_add_ms(&tv, 1);
91 ck_assert_int_eq(tv.tv_sec, 0);
92 ck_assert_int_eq(tv.tv_usec, 1000);
93
94 timeval_add_ms(&tv, 0);
95 ck_assert_int_eq(tv.tv_sec, 0);
96 ck_assert_int_eq(tv.tv_usec, 1000);
97
98 timeval_add_ms(&tv, 999);
99 ck_assert_int_eq(tv.tv_sec, 1);
100 ck_assert_int_eq(tv.tv_usec, 0);
101
102 timeval_add_ms(&tv, 0);
103 ck_assert_int_eq(tv.tv_sec, 1);
104 ck_assert_int_eq(tv.tv_usec, 0);
105
106 timeval_add_ms(&tv, 1000);
107 ck_assert_int_eq(tv.tv_sec, 2);
108 ck_assert_int_eq(tv.tv_usec, 0);
109
110 timeval_add_ms(&tv, 1500);
111 ck_assert_int_eq(tv.tv_sec, 3);
112 ck_assert_int_eq(tv.tv_usec, 500000);
113 }
114 END_TEST
115
116 /*******************************************************************************
117 * htoun/untoh
118 */
119
120 START_TEST(test_htoun)
121 {
122 chunk_t net64, expected;
123 u_int16_t host16 = 513;
124 u_int32_t net16 = 0, host32 = 67305985;
125 u_int64_t net32 = 0, host64 = 578437695752307201ULL;
126
127 net64 = chunk_alloca(16);
128 memset(net64.ptr, 0, net64.len);
129
130 expected = chunk_from_chars(0x00, 0x02, 0x01, 0x00);
131 htoun16((char*)&net16 + 1, host16);
132 ck_assert(chunk_equals(expected, chunk_from_thing(net16)));
133
134 expected = chunk_from_chars(0x00, 0x00, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00);
135 htoun32((u_int16_t*)&net32 + 1, host32);
136 ck_assert(chunk_equals(expected, chunk_from_thing(net32)));
137
138 expected = chunk_from_chars(0x00, 0x00, 0x00, 0x00,
139 0x08, 0x07, 0x06, 0x05,
140 0x04, 0x03, 0x02, 0x01,
141 0x00, 0x00, 0x00, 0x00);
142 htoun64((u_int32_t*)net64.ptr + 1, host64);
143 ck_assert(chunk_equals(expected, net64));
144 }
145 END_TEST
146
147 START_TEST(test_untoh)
148 {
149 chunk_t net;
150 u_int16_t host16;
151 u_int32_t host32;
152 u_int64_t host64;
153
154 net = chunk_from_chars(0x00, 0x02, 0x01, 0x00);
155 host16 = untoh16(net.ptr + 1);
156 ck_assert(host16 == 513);
157
158 net = chunk_from_chars(0x00, 0x00, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00);
159 host32 = untoh32(net.ptr + 2);
160 ck_assert(host32 == 67305985);
161
162 net = chunk_from_chars(0x00, 0x00, 0x00, 0x00, 0x08, 0x07, 0x06, 0x05,
163 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00);
164 host64 = untoh64(net.ptr + 4);
165 ck_assert(host64 == 578437695752307201ULL);
166 }
167 END_TEST
168
169 /*******************************************************************************
170 * pad_len/round_up/down
171 */
172
173 START_TEST(test_round)
174 {
175 ck_assert_int_eq(pad_len(0, 4), 0);
176 ck_assert_int_eq(pad_len(1, 4), 3);
177 ck_assert_int_eq(pad_len(2, 4), 2);
178 ck_assert_int_eq(pad_len(3, 4), 1);
179 ck_assert_int_eq(pad_len(4, 4), 0);
180 ck_assert_int_eq(pad_len(5, 4), 3);
181
182 ck_assert_int_eq(round_up(0, 4), 0);
183 ck_assert_int_eq(round_up(1, 4), 4);
184 ck_assert_int_eq(round_up(2, 4), 4);
185 ck_assert_int_eq(round_up(3, 4), 4);
186 ck_assert_int_eq(round_up(4, 4), 4);
187 ck_assert_int_eq(round_up(5, 4), 8);
188
189 ck_assert_int_eq(round_down(0, 4), 0);
190 ck_assert_int_eq(round_down(1, 4), 0);
191 ck_assert_int_eq(round_down(2, 4), 0);
192 ck_assert_int_eq(round_down(3, 4), 0);
193 ck_assert_int_eq(round_down(4, 4), 4);
194 ck_assert_int_eq(round_down(5, 4), 4);
195 }
196 END_TEST
197
198 /*******************************************************************************
199 * strpfx
200 */
201
202 static struct {
203 char *str;
204 char *pfx;
205 bool prefix;
206 bool case_prefix;
207 } strpfx_data[] = {
208 {"", "", TRUE, TRUE},
209 {"abc", "", TRUE, TRUE},
210 {"abc", "a", TRUE, TRUE},
211 {"abc", "ab", TRUE, TRUE},
212 {"abc", "abc", TRUE, TRUE},
213 {"abc", "abcd", FALSE, FALSE},
214 {"abc", "AB", FALSE, TRUE},
215 {"ABC", "ab", FALSE, TRUE},
216 {" abc", "abc", FALSE, FALSE},
217 };
218
219 START_TEST(test_strpfx)
220 {
221 bool prefix;
222
223 prefix = strpfx(strpfx_data[_i].str, strpfx_data[_i].pfx);
224 ck_assert(prefix == strpfx_data[_i].prefix);
225 prefix = strcasepfx(strpfx_data[_i].str, strpfx_data[_i].pfx);
226 ck_assert(prefix == strpfx_data[_i].case_prefix);
227 }
228 END_TEST
229
230 /*******************************************************************************
231 * memxor
232 */
233
234 static void do_memxor(chunk_t a, chunk_t b, chunk_t exp)
235 {
236 chunk_t dst;
237
238 dst = chunk_clonea(a);
239 dst.len = b.len;
240 memxor(dst.ptr, b.ptr, b.len);
241 ck_assert(chunk_equals(dst, exp));
242 }
243
244 START_TEST(test_memxor)
245 {
246 chunk_t a, b, dst;
247 int i;
248
249 a = chunk_alloca(64);
250 memset(a.ptr, 0, a.len);
251 b = chunk_alloca(64);
252 for (i = 0; i < 64; i++)
253 {
254 b.ptr[i] = i;
255 b.len = i;
256 do_memxor(a, b, b);
257 }
258 b.len = 64;
259 do_memxor(a, b, b);
260
261 dst = chunk_clonea(a);
262 memxor(dst.ptr, b.ptr, b.len);
263 ck_assert(chunk_equals(dst, b));
264
265 memxor(dst.ptr, b.ptr, 0);
266 memxor(dst.ptr, b.ptr, 1);
267 memxor(dst.ptr + 1, b.ptr + 1, 1);
268 memxor(dst.ptr + 2, b.ptr + 2, b.len - 2);
269 ck_assert(chunk_equals(dst, a));
270 }
271 END_TEST
272
273 START_TEST(test_memxor_aligned)
274 {
275 u_int64_t a = 0, b = 0;
276 chunk_t ca, cb;
277 int i;
278
279 ca = chunk_from_thing(a);
280 cb = chunk_from_thing(b);
281
282 for (i = 0; i < 8; i++)
283 {
284 cb.ptr[i] = i + 1;
285 }
286
287 /* 64-bit aligned */
288 memxor(ca.ptr, cb.ptr, 8);
289 ck_assert(a == b);
290 /* 32-bit aligned source */
291 a = 0;
292 memxor(ca.ptr, cb.ptr + 4, 4);
293 ck_assert(chunk_equals(ca, chunk_from_chars(0x05, 0x06, 0x07, 0x08,
294 0x00, 0x00, 0x00, 0x00)));
295 /* 16-bit aligned source */
296 a = 0;
297 memxor(ca.ptr, cb.ptr + 2, 6);
298 ck_assert(chunk_equals(ca, chunk_from_chars(0x03, 0x04, 0x05, 0x06,
299 0x07, 0x08, 0x00, 0x00)));
300 /* 8-bit aligned source */
301 a = 0;
302 memxor(ca.ptr, cb.ptr + 1, 7);
303 ck_assert(chunk_equals(ca, chunk_from_chars(0x02, 0x03, 0x04, 0x05,
304 0x06, 0x07, 0x08, 0x00)));
305 }
306 END_TEST
307
308 /*******************************************************************************
309 * memstr
310 */
311
312 static struct {
313 char *haystack;
314 char *needle;
315 size_t n;
316 int offset;
317 } memstr_data[] = {
318 {NULL, NULL, 0, -1},
319 {NULL, NULL, 3, -1},
320 {NULL, "abc", 0, -1},
321 {NULL, "abc", 3, -1},
322 {"", "", 0, -1},
323 {"abc", NULL, 3, -1},
324 {"abc", "", 3, -1},
325 {"abc", "abc", 3, 0},
326 {" abc", "abc", 4, 1},
327 {" abc", "abc", 3, -1},
328 {"abcabc", "abc", 6, 0},
329 {" abc ", "abc", 5, 1},
330 };
331
332 START_TEST(test_memstr)
333 {
334 char *ret;
335
336 ret = memstr(memstr_data[_i].haystack, memstr_data[_i].needle, memstr_data[_i].n);
337 if (memstr_data[_i].offset >= 0)
338 {
339 ck_assert(ret == memstr_data[_i].haystack + memstr_data[_i].offset);
340 }
341 else
342 {
343 ck_assert(ret == NULL);
344 }
345 }
346 END_TEST
347
348 /*******************************************************************************
349 * translate
350 */
351
352 static struct {
353 char *in;
354 char *from;
355 char *to;
356 char *out;
357 } translate_data[] = {
358 {NULL, "", "", NULL},
359 {"abc", "", "", "abc"},
360 {"abc", "", "x", "abc"},
361 {"abc", "x", "", "abc"},
362 {"abc", "abc", "xyz", "xyz"},
363 {"aabbcc", "abc", "xyz", "xxyyzz"},
364 {"abbaccb", "abc", "xyz", "xyyxzzy"},
365 {"abxyzc", "abc", "xyz", "xyxyzz"},
366 {"abcdef", "abc", "xyz", "xyzdef"},
367 {"aaa", "abc", "xyz", "xxx"},
368 {"abc", "aaa", "xyz", "xbc"},
369 {"abc", "abc", "xxx", "xxx"},
370 };
371
372 START_TEST(test_translate)
373 {
374 char *str, *ret;
375
376 str = strdupnull(translate_data[_i].in);
377 ret = translate(str, translate_data[_i].from, translate_data[_i].to);
378 ck_assert(ret == str);
379 if (ret != translate_data[_i].out)
380 {
381 ck_assert_str_eq(str, translate_data[_i].out);
382 }
383 free(str);
384 }
385 END_TEST
386
387 /*******************************************************************************
388 * time_printf_hook
389 */
390
391 static struct {
392 time_t in;
393 bool utc;
394 char *out;
395 } time_data[] = {
396 {UNDEFINED_TIME, FALSE, "--- -- --:--:-- ----"},
397 {UNDEFINED_TIME, TRUE , "--- -- --:--:-- UTC ----"},
398 {1, FALSE, "Jan 01 01:00:01 1970"},
399 {1, TRUE , "Jan 01 00:00:01 UTC 1970"},
400 {1341150196, FALSE, "Jul 01 15:43:16 2012"},
401 {1341150196, TRUE , "Jul 01 13:43:16 UTC 2012"},
402 };
403
404 START_TEST(test_time_printf_hook)
405 {
406 char buf[32];
407 int len;
408
409 len = snprintf(buf, sizeof(buf), "%T", &time_data[_i].in, time_data[_i].utc);
410 ck_assert(len >= 0 && len < sizeof(buf));
411 ck_assert_str_eq(buf, time_data[_i].out);
412 }
413 END_TEST
414
415 /*******************************************************************************
416 * time_delta_printf_hook
417 */
418
419 static struct {
420 time_t a;
421 time_t b;
422 char *out;
423 } time_delta_data[] = {
424 {0, 0, "0 seconds"},
425 {0, 1, "1 second"},
426 {0, -1, "1 second"},
427 {1, 0, "1 second"},
428 {0, 2, "2 seconds"},
429 {2, 0, "2 seconds"},
430 {0, 60, "60 seconds"},
431 {0, 120, "120 seconds"},
432 {0, 121, "2 minutes"},
433 {0, 3600, "60 minutes"},
434 {0, 7200, "120 minutes"},
435 {0, 7201, "2 hours"},
436 {0, 86400, "24 hours"},
437 {0, 172800, "48 hours"},
438 {0, 172801, "2 days"},
439 {172801, 86400, "24 hours"},
440 };
441
442 START_TEST(test_time_delta_printf_hook)
443 {
444 char buf[16];
445 int len;
446
447 len = snprintf(buf, sizeof(buf), "%V", &time_delta_data[_i].a, &time_delta_data[_i].b);
448 ck_assert(len >= 0 && len < sizeof(buf));
449 ck_assert_str_eq(buf, time_delta_data[_i].out);
450 }
451 END_TEST
452
453 /*******************************************************************************
454 * mark_from_string
455 */
456
457 static struct {
458 char *s;
459 bool ok;
460 mark_t m;
461 } mark_data[] = {
462 {NULL, FALSE, { 0 }},
463 {"", TRUE, { 0, 0xffffffff }},
464 {"/", TRUE, { 0, 0 }},
465 {"42", TRUE, { 42, 0xffffffff }},
466 {"0x42", TRUE, { 0x42, 0xffffffff }},
467 {"x", FALSE, { 0 }},
468 {"42/", TRUE, { 0, 0 }},
469 {"42/0", TRUE, { 0, 0 }},
470 {"42/x", FALSE, { 0 }},
471 {"42/42", TRUE, { 42, 42 }},
472 {"42/0xff", TRUE, { 42, 0xff }},
473 {"0x42/0xff", TRUE, { 0x42, 0xff }},
474 {"/0xff", TRUE, { 0, 0xff }},
475 {"/x", FALSE, { 0 }},
476 {"x/x", FALSE, { 0 }},
477 {"0xffffffff/0x0000ffff", TRUE, { 0x0000ffff, 0x0000ffff }},
478 {"0xffffffff/0xffffffff", TRUE, { 0xffffffff, 0xffffffff }},
479 };
480
481 START_TEST(test_mark_from_string)
482 {
483 mark_t mark;
484
485 if (mark_from_string(mark_data[_i].s, &mark))
486 {
487 ck_assert_int_eq(mark.value, mark_data[_i].m.value);
488 ck_assert_int_eq(mark.mask, mark_data[_i].m.mask);
489 }
490 else
491 {
492 ck_assert(!mark_data[_i].ok);
493 }
494 }
495 END_TEST
496
497 Suite *utils_suite_create()
498 {
499 Suite *s;
500 TCase *tc;
501
502 /* force a timezone to match non-UTC conversions */
503 setenv("TZ", "Europe/Zurich", 1);
504 tzset();
505
506 s = suite_create("utils");
507
508 tc = tcase_create("objects");
509 tcase_add_test(tc, test_objects);
510 suite_add_tcase(s, tc);
511
512 tc = tcase_create("return functions");
513 tcase_add_test(tc, test_return_functions);
514 suite_add_tcase(s, tc);
515
516 tc = tcase_create("timeval_add_ms");
517 tcase_add_test(tc, test_timeval_add_ms);
518 suite_add_tcase(s, tc);
519
520 tc = tcase_create("htoun,untoh");
521 tcase_add_test(tc, test_htoun);
522 tcase_add_test(tc, test_untoh);
523 suite_add_tcase(s, tc);
524
525 tc = tcase_create("round");
526 tcase_add_test(tc, test_round);
527 suite_add_tcase(s, tc);
528
529 tc = tcase_create("string helper");
530 tcase_add_loop_test(tc, test_strpfx, 0, countof(strpfx_data));
531 suite_add_tcase(s, tc);
532
533 tc = tcase_create("memxor");
534 tcase_add_test(tc, test_memxor);
535 tcase_add_test(tc, test_memxor_aligned);
536 suite_add_tcase(s, tc);
537
538 tc = tcase_create("memstr");
539 tcase_add_loop_test(tc, test_memstr, 0, countof(memstr_data));
540 suite_add_tcase(s, tc);
541
542 tc = tcase_create("translate");
543 tcase_add_loop_test(tc, test_translate, 0, countof(translate_data));
544 suite_add_tcase(s, tc);
545
546 tc = tcase_create("printf_hooks");
547 tcase_add_loop_test(tc, test_time_printf_hook, 0, countof(time_data));
548 tcase_add_loop_test(tc, test_time_delta_printf_hook, 0, countof(time_delta_data));
549 suite_add_tcase(s, tc);
550
551 tc = tcase_create("mark_from_string");
552 tcase_add_loop_test(tc, test_mark_from_string, 0, countof(mark_data));
553 suite_add_tcase(s, tc);
554
555 return s;
556 }