fc055bb7f3cbd80bed340e605c496a7e4243005e
[strongswan.git] / src / libstrongswan / tests / test_linked_list.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 <collections/linked_list.h>
19
20 /*******************************************************************************
21 * test fixture
22 */
23
24 static linked_list_t *list;
25
26 START_SETUP(setup_list)
27 {
28 void *x = NULL;
29
30 list = linked_list_create();
31 ck_assert_int_eq(list->get_count(list), 0);
32 ck_assert(list->get_first(list, &x) == NOT_FOUND);
33 ck_assert(list->get_last(list, &x) == NOT_FOUND);
34 }
35 END_SETUP
36
37 START_TEARDOWN(teardown_list)
38 {
39 list->destroy(list);
40 }
41 END_TEARDOWN
42
43 /*******************************************************************************
44 * insert first/last
45 */
46
47 START_TEST(test_insert_first)
48 {
49 void *a = (void*)1, *b = (void*)2, *x = NULL;
50
51 list->insert_first(list, a);
52 ck_assert_int_eq(list->get_count(list), 1);
53 ck_assert(list->get_first(list, &x) == SUCCESS);
54 ck_assert(x == a);
55 ck_assert(list->get_last(list, &x) == SUCCESS);
56 ck_assert(x == a);
57
58 list->insert_first(list, b);
59 ck_assert_int_eq(list->get_count(list), 2);
60 ck_assert(list->get_first(list, &x) == SUCCESS);
61 ck_assert(x == b);
62 ck_assert(list->get_last(list, &x) == SUCCESS);
63 ck_assert(x == a);
64 }
65 END_TEST
66
67 START_TEST(test_insert_last)
68 {
69 void *a = (void*)1, *b = (void*)2, *x = NULL;
70
71 list->insert_last(list, a);
72 ck_assert_int_eq(list->get_count(list), 1);
73 ck_assert(list->get_first(list, &x) == SUCCESS);
74 ck_assert(x == a);
75 ck_assert(list->get_last(list, &x) == SUCCESS);
76 ck_assert(x == a);
77
78 list->insert_last(list, b);
79 ck_assert_int_eq(list->get_count(list), 2);
80 ck_assert(list->get_first(list, &x) == SUCCESS);
81 ck_assert(x == a);
82 ck_assert(list->get_last(list, &x) == SUCCESS);
83 ck_assert(x == b);
84 }
85 END_TEST
86
87 /*******************************************************************************
88 * remove first/last
89 */
90
91 START_TEST(test_remove_first)
92 {
93 void *a = (void*)1, *b = (void*)2, *x = NULL;
94
95 list->insert_first(list, a);
96 list->insert_first(list, b);
97 ck_assert(list->remove_first(list, &x) == SUCCESS);
98 ck_assert_int_eq(list->get_count(list), 1);
99 ck_assert(x == b);
100 ck_assert(list->remove_first(list, &x) == SUCCESS);
101 ck_assert_int_eq(list->get_count(list), 0);
102 ck_assert(x == a);
103 ck_assert(list->remove_first(list, &x) == NOT_FOUND);
104 ck_assert(list->remove_last(list, &x) == NOT_FOUND);
105 }
106 END_TEST
107
108 START_TEST(test_remove_last)
109 {
110 void *a = (void*)1, *b = (void*)2, *x = NULL;
111
112 list->insert_first(list, a);
113 list->insert_first(list, b);
114 ck_assert(list->remove_last(list, &x) == SUCCESS);
115 ck_assert_int_eq(list->get_count(list), 1);
116 ck_assert(x == a);
117 ck_assert(list->remove_last(list, &x) == SUCCESS);
118 ck_assert_int_eq(list->get_count(list), 0);
119 ck_assert(x == b);
120 ck_assert(list->remove_first(list, &x) == NOT_FOUND);
121 ck_assert(list->remove_last(list, &x) == NOT_FOUND);
122 }
123 END_TEST
124
125 /*******************************************************************************
126 * helper function for remove and find tests
127 */
128
129 static bool match_a(void *item, void *a)
130 {
131 ck_assert(a == (void*)1);
132 return item == a;
133 }
134
135 static bool match_b(void *item, void *b)
136 {
137 ck_assert(b == (void*)2);
138 return item == b;
139 }
140
141 /*******************************************************************************
142 * remove
143 */
144
145 START_TEST(test_remove)
146 {
147 void *a = (void*)1, *b = (void*)2;
148
149 list->insert_first(list, a);
150 ck_assert(list->remove(list, a, NULL) == 1);
151 ck_assert_int_eq(list->get_count(list), 0);
152
153 list->insert_last(list, a);
154 list->insert_last(list, a);
155 list->insert_last(list, a);
156 list->insert_last(list, b);
157 ck_assert(list->remove(list, a, NULL) == 3);
158 ck_assert(list->remove(list, a, NULL) == 0);
159 ck_assert_int_eq(list->get_count(list), 1);
160 ck_assert(list->remove(list, b, NULL) == 1);
161 ck_assert(list->remove(list, b, NULL) == 0);
162 }
163 END_TEST
164
165 START_TEST(test_remove_callback)
166 {
167 void *a = (void*)1, *b = (void*)2;
168
169 list->insert_last(list, a);
170 list->insert_last(list, b);
171 list->insert_last(list, a);
172 list->insert_last(list, b);
173 ck_assert(list->remove(list, a, match_a) == 2);
174 ck_assert(list->remove(list, a, match_a) == 0);
175 ck_assert_int_eq(list->get_count(list), 2);
176 ck_assert(list->remove(list, b, match_b) == 2);
177 ck_assert(list->remove(list, b, match_b) == 0);
178 ck_assert_int_eq(list->get_count(list), 0);
179 }
180 END_TEST
181
182 /*******************************************************************************
183 * find
184 */
185
186 static bool match_a_b(void *item, void *a, void *b)
187 {
188 ck_assert(a == (void*)1);
189 ck_assert(b == (void*)2);
190 return item == a || item == b;
191 }
192
193 START_TEST(test_find)
194 {
195 void *a = (void*)1, *b = (void*)2;
196
197 ck_assert(list->find_first(list, NULL, &a) == NOT_FOUND);
198 ck_assert(list->find_last(list, NULL, &a) == NOT_FOUND);
199 list->insert_last(list, a);
200 ck_assert(list->find_first(list, NULL, &a) == SUCCESS);
201 ck_assert(list->find_first(list, NULL, &b) == NOT_FOUND);
202 ck_assert(list->find_last(list, NULL, &a) == SUCCESS);
203 ck_assert(list->find_last(list, NULL, &b) == NOT_FOUND);
204 list->insert_last(list, b);
205 ck_assert(list->find_first(list, NULL, &a) == SUCCESS);
206 ck_assert(list->find_first(list, NULL, &b) == SUCCESS);
207 ck_assert(list->find_last(list, NULL, &a) == SUCCESS);
208 ck_assert(list->find_last(list, NULL, &b) == SUCCESS);
209
210 ck_assert(list->find_first(list, NULL, NULL) == NOT_FOUND);
211 ck_assert(list->find_last(list, NULL, NULL) == NOT_FOUND);
212 }
213 END_TEST
214
215 START_TEST(test_find_callback)
216 {
217 void *a = (void*)1, *b = (void*)2, *x = NULL;
218
219 ck_assert(list->find_first(list, (linked_list_match_t)match_a_b, &x, a, b) == NOT_FOUND);
220 list->insert_last(list, a);
221 ck_assert(list->find_first(list, (linked_list_match_t)match_a, NULL, a) == SUCCESS);
222 x = NULL;
223 ck_assert(list->find_first(list, (linked_list_match_t)match_a, &x, a) == SUCCESS);
224 ck_assert(a == x);
225 ck_assert(list->find_first(list, (linked_list_match_t)match_b, &x, b) == NOT_FOUND);
226 ck_assert(a == x);
227 x = NULL;
228 ck_assert(list->find_first(list, (linked_list_match_t)match_a_b, &x, a, b) == SUCCESS);
229 ck_assert(a == x);
230
231 ck_assert(list->find_last(list, (linked_list_match_t)match_a, NULL, a) == SUCCESS);
232 x = NULL;
233 ck_assert(list->find_last(list, (linked_list_match_t)match_a, &x, a) == SUCCESS);
234 ck_assert(a == x);
235 ck_assert(list->find_last(list, (linked_list_match_t)match_b, &x, b) == NOT_FOUND);
236 ck_assert(a == x);
237 x = NULL;
238 ck_assert(list->find_last(list, (linked_list_match_t)match_a_b, &x, a, b) == SUCCESS);
239 ck_assert(a == x);
240
241 list->insert_last(list, b);
242 ck_assert(list->find_first(list, (linked_list_match_t)match_a, &x, a) == SUCCESS);
243 ck_assert(a == x);
244 ck_assert(list->find_first(list, (linked_list_match_t)match_b, &x, b) == SUCCESS);
245 ck_assert(b == x);
246 ck_assert(list->find_last(list, (linked_list_match_t)match_a, &x, a) == SUCCESS);
247 ck_assert(a == x);
248 ck_assert(list->find_last(list, (linked_list_match_t)match_b, &x, b) == SUCCESS);
249 ck_assert(b == x);
250 x = NULL;
251 ck_assert(list->find_first(list, (linked_list_match_t)match_a_b, &x, a, b) == SUCCESS);
252 ck_assert(a == x);
253 x = NULL;
254 ck_assert(list->find_last(list, (linked_list_match_t)match_a_b, &x, a, b) == SUCCESS);
255 ck_assert(b == x);
256 }
257 END_TEST
258
259 /*******************************************************************************
260 * invoke
261 */
262
263 typedef struct invoke_t invoke_t;
264
265 struct invoke_t {
266 int val;
267 void (*invoke)(invoke_t *item, void *a, void *b, void *c, void *d, int *sum);
268 };
269
270 static void invoke(intptr_t item, void *a, void *b, void *c, void *d, int *sum)
271 {
272 ck_assert(a == (void*)1);
273 ck_assert(b == (void*)2);
274 ck_assert(c == (void*)3);
275 ck_assert(d == (void*)4);
276 *sum += item;
277 }
278
279 static void invoke_offset(invoke_t *item, void *a, void *b, void *c, void *d, int *sum)
280 {
281 invoke(item->val, a, b, c, d, sum);
282 }
283
284 START_TEST(test_invoke_function)
285 {
286 int sum = 0;
287
288 list->insert_last(list, (void*)1);
289 list->insert_last(list, (void*)2);
290 list->insert_last(list, (void*)3);
291 list->insert_last(list, (void*)4);
292 list->insert_last(list, (void*)5);
293 list->invoke_function(list, (linked_list_invoke_t)invoke, 1, 2, 3, 4, &sum);
294 ck_assert_int_eq(sum, 15);
295 }
296 END_TEST
297
298 START_TEST(test_invoke_offset)
299 {
300 invoke_t items[] = {
301 { .val = 1, .invoke = invoke_offset, },
302 { .val = 2, .invoke = invoke_offset, },
303 { .val = 3, .invoke = invoke_offset, },
304 { .val = 4, .invoke = invoke_offset, },
305 { .val = 5, .invoke = invoke_offset, },
306 };
307 int i, sum = 0;
308
309 for (i = 0; i < countof(items); i++)
310 {
311 list->insert_last(list, &items[i]);
312 }
313 list->invoke_offset(list, offsetof(invoke_t, invoke), 1, 2, 3, 4, &sum);
314 ck_assert_int_eq(sum, 15);
315 }
316 END_TEST
317
318 /*******************************************************************************
319 * clone
320 */
321
322 typedef struct clone_t clone_t;
323
324 struct clone_t {
325 void *val;
326 void *(*clone)(clone_t *item);
327 };
328
329 static void *clone(void *item)
330 {
331 return item;
332 }
333
334 static void *clone_offset(clone_t *item)
335 {
336 return clone(item->val);
337 }
338
339 static void test_clone(linked_list_t *list)
340 {
341 intptr_t x;
342 int round = 1;
343
344 ck_assert_int_eq(list->get_count(list), 5);
345 while (list->remove_first(list, (void*)&x) == SUCCESS)
346 {
347 ck_assert_int_eq(round, x);
348 round++;
349 }
350 ck_assert_int_eq(round, 6);
351 }
352
353 START_TEST(test_clone_function)
354 {
355 linked_list_t *other;
356
357 list->insert_last(list, (void*)1);
358 list->insert_last(list, (void*)2);
359 list->insert_last(list, (void*)3);
360 list->insert_last(list, (void*)4);
361 list->insert_last(list, (void*)5);
362
363 other = list->clone_function(list, clone);
364 test_clone(other);
365 other->destroy(other);
366 }
367 END_TEST
368
369 START_TEST(test_clone_offset)
370 {
371 linked_list_t *other;
372 clone_t items[] = {
373 { .val = (void*)1, .clone = clone_offset, },
374 { .val = (void*)2, .clone = clone_offset, },
375 { .val = (void*)3, .clone = clone_offset, },
376 { .val = (void*)4, .clone = clone_offset, },
377 { .val = (void*)5, .clone = clone_offset, },
378 };
379 int i;
380
381 for (i = 0; i < countof(items); i++)
382 {
383 list->insert_last(list, &items[i]);
384 }
385 other = list->clone_offset(list, offsetof(clone_t, clone));
386 test_clone(other);
387 other->destroy(other);
388 }
389 END_TEST
390
391 Suite *linked_list_suite_create()
392 {
393 Suite *s;
394 TCase *tc;
395
396 s = suite_create("linked list");
397
398 tc = tcase_create("insert/get");
399 tcase_add_checked_fixture(tc, setup_list, teardown_list);
400 tcase_add_test(tc, test_insert_first);
401 tcase_add_test(tc, test_insert_last);
402 suite_add_tcase(s, tc);
403
404 tc = tcase_create("remove");
405 tcase_add_checked_fixture(tc, setup_list, teardown_list);
406 tcase_add_test(tc, test_remove_first);
407 tcase_add_test(tc, test_remove_last);
408 tcase_add_test(tc, test_remove);
409 tcase_add_test(tc, test_remove_callback);
410 suite_add_tcase(s, tc);
411
412 tc = tcase_create("find");
413 tcase_add_checked_fixture(tc, setup_list, teardown_list);
414 tcase_add_test(tc, test_find);
415 tcase_add_test(tc, test_find_callback);
416 suite_add_tcase(s, tc);
417
418 tc = tcase_create("invoke");
419 tcase_add_checked_fixture(tc, setup_list, teardown_list);
420 tcase_add_test(tc, test_invoke_function);
421 tcase_add_test(tc, test_invoke_offset);
422 suite_add_tcase(s, tc);
423
424 tc = tcase_create("clone");
425 tcase_add_checked_fixture(tc, setup_list, teardown_list);
426 tcase_add_test(tc, test_clone_function);
427 tcase_add_test(tc, test_clone_offset);
428 suite_add_tcase(s, tc);
429
430 return s;
431 }