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