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