]> git.ipfire.org Git - thirdparty/strongswan.git/blob - src/libstrongswan/tests/test_linked_list.c
9e85c58d8c3ca3daf35419b48a2a6ddff4770cf2
[thirdparty/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 list->insert_last(list, a);
199 ck_assert(list->find_first(list, NULL, &a) == SUCCESS);
200 ck_assert(list->find_first(list, NULL, &b) == NOT_FOUND);
201 list->insert_last(list, b);
202 ck_assert(list->find_first(list, NULL, &a) == SUCCESS);
203 ck_assert(list->find_first(list, NULL, &b) == SUCCESS);
204
205 ck_assert(list->find_first(list, NULL, NULL) == NOT_FOUND);
206 }
207 END_TEST
208
209 START_TEST(test_find_callback)
210 {
211 void *a = (void*)1, *b = (void*)2, *x = NULL;
212
213 ck_assert(list->find_first(list, (linked_list_match_t)match_a_b, &x, a, b) == NOT_FOUND);
214 list->insert_last(list, a);
215 ck_assert(list->find_first(list, (linked_list_match_t)match_a, NULL, a) == SUCCESS);
216 x = NULL;
217 ck_assert(list->find_first(list, (linked_list_match_t)match_a, &x, a) == SUCCESS);
218 ck_assert(a == x);
219 ck_assert(list->find_first(list, (linked_list_match_t)match_b, &x, b) == NOT_FOUND);
220 ck_assert(a == x);
221 x = NULL;
222 ck_assert(list->find_first(list, (linked_list_match_t)match_a_b, &x, a, b) == SUCCESS);
223 ck_assert(a == x);
224
225 list->insert_last(list, b);
226 ck_assert(list->find_first(list, (linked_list_match_t)match_a, &x, a) == SUCCESS);
227 ck_assert(a == x);
228 ck_assert(list->find_first(list, (linked_list_match_t)match_b, &x, b) == SUCCESS);
229 ck_assert(b == x);
230 x = NULL;
231 ck_assert(list->find_first(list, (linked_list_match_t)match_a_b, &x, a, b) == SUCCESS);
232 ck_assert(a == x);
233 }
234 END_TEST
235
236 /*******************************************************************************
237 * invoke
238 */
239
240 typedef struct invoke_t invoke_t;
241
242 struct invoke_t {
243 int val;
244 void (*invoke)(invoke_t *item, void *a, void *b, void *c, void *d, int *sum);
245 };
246
247 static void invoke(intptr_t item, void *a, void *b, void *c, void *d, int *sum)
248 {
249 ck_assert(a == (void*)1);
250 ck_assert(b == (void*)2);
251 ck_assert(c == (void*)3);
252 ck_assert(d == (void*)4);
253 *sum += item;
254 }
255
256 static void invoke_offset(invoke_t *item, void *a, void *b, void *c, void *d, int *sum)
257 {
258 invoke(item->val, a, b, c, d, sum);
259 }
260
261 START_TEST(test_invoke_function)
262 {
263 int sum = 0;
264
265 list->insert_last(list, (void*)1);
266 list->insert_last(list, (void*)2);
267 list->insert_last(list, (void*)3);
268 list->insert_last(list, (void*)4);
269 list->insert_last(list, (void*)5);
270 list->invoke_function(list, (linked_list_invoke_t)invoke, 1, 2, 3, 4, &sum);
271 ck_assert_int_eq(sum, 15);
272 }
273 END_TEST
274
275 START_TEST(test_invoke_offset)
276 {
277 invoke_t items[] = {
278 { .val = 1, .invoke = invoke_offset, },
279 { .val = 2, .invoke = invoke_offset, },
280 { .val = 3, .invoke = invoke_offset, },
281 { .val = 4, .invoke = invoke_offset, },
282 { .val = 5, .invoke = invoke_offset, },
283 };
284 int i, sum = 0;
285
286 for (i = 0; i < countof(items); i++)
287 {
288 list->insert_last(list, &items[i]);
289 }
290 list->invoke_offset(list, offsetof(invoke_t, invoke), 1, 2, 3, 4, &sum);
291 ck_assert_int_eq(sum, 15);
292 }
293 END_TEST
294
295 /*******************************************************************************
296 * clone
297 */
298
299 typedef struct clone_t clone_t;
300
301 struct clone_t {
302 void *val;
303 void *(*clone)(clone_t *item);
304 };
305
306 static void *clone(clone_t *item)
307 {
308 return item->val;
309 }
310
311 static void test_clone(linked_list_t *list)
312 {
313 intptr_t x;
314 int round = 1;
315
316 ck_assert_int_eq(list->get_count(list), 5);
317 while (list->remove_first(list, (void*)&x) == SUCCESS)
318 {
319 ck_assert_int_eq(round, x);
320 round++;
321 }
322 ck_assert_int_eq(round, 6);
323 }
324
325 START_TEST(test_clone_offset)
326 {
327 linked_list_t *other;
328 clone_t items[] = {
329 { .val = (void*)1, .clone = clone, },
330 { .val = (void*)2, .clone = clone, },
331 { .val = (void*)3, .clone = clone, },
332 { .val = (void*)4, .clone = clone, },
333 { .val = (void*)5, .clone = clone, },
334 };
335 int i;
336
337 for (i = 0; i < countof(items); i++)
338 {
339 list->insert_last(list, &items[i]);
340 }
341 other = list->clone_offset(list, offsetof(clone_t, clone));
342 test_clone(other);
343 other->destroy(other);
344 }
345 END_TEST
346
347 Suite *linked_list_suite_create()
348 {
349 Suite *s;
350 TCase *tc;
351
352 s = suite_create("linked list");
353
354 tc = tcase_create("insert/get");
355 tcase_add_checked_fixture(tc, setup_list, teardown_list);
356 tcase_add_test(tc, test_insert_first);
357 tcase_add_test(tc, test_insert_last);
358 suite_add_tcase(s, tc);
359
360 tc = tcase_create("remove");
361 tcase_add_checked_fixture(tc, setup_list, teardown_list);
362 tcase_add_test(tc, test_remove_first);
363 tcase_add_test(tc, test_remove_last);
364 tcase_add_test(tc, test_remove);
365 tcase_add_test(tc, test_remove_callback);
366 suite_add_tcase(s, tc);
367
368 tc = tcase_create("find");
369 tcase_add_checked_fixture(tc, setup_list, teardown_list);
370 tcase_add_test(tc, test_find);
371 tcase_add_test(tc, test_find_callback);
372 suite_add_tcase(s, tc);
373
374 tc = tcase_create("invoke");
375 tcase_add_checked_fixture(tc, setup_list, teardown_list);
376 tcase_add_test(tc, test_invoke_function);
377 tcase_add_test(tc, test_invoke_offset);
378 suite_add_tcase(s, tc);
379
380 tc = tcase_create("clone");
381 tcase_add_checked_fixture(tc, setup_list, teardown_list);
382 tcase_add_test(tc, test_clone_offset);
383 suite_add_tcase(s, tc);
384
385 return s;
386 }