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