linked-list: Remove barely used find_last() method
[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(void *item)
307 {
308 return item;
309 }
310
311 static void *clone_offset(clone_t *item)
312 {
313 return clone(item->val);
314 }
315
316 static void test_clone(linked_list_t *list)
317 {
318 intptr_t x;
319 int round = 1;
320
321 ck_assert_int_eq(list->get_count(list), 5);
322 while (list->remove_first(list, (void*)&x) == SUCCESS)
323 {
324 ck_assert_int_eq(round, x);
325 round++;
326 }
327 ck_assert_int_eq(round, 6);
328 }
329
330 START_TEST(test_clone_function)
331 {
332 linked_list_t *other;
333
334 list->insert_last(list, (void*)1);
335 list->insert_last(list, (void*)2);
336 list->insert_last(list, (void*)3);
337 list->insert_last(list, (void*)4);
338 list->insert_last(list, (void*)5);
339
340 other = list->clone_function(list, clone);
341 test_clone(other);
342 other->destroy(other);
343 }
344 END_TEST
345
346 START_TEST(test_clone_offset)
347 {
348 linked_list_t *other;
349 clone_t items[] = {
350 { .val = (void*)1, .clone = clone_offset, },
351 { .val = (void*)2, .clone = clone_offset, },
352 { .val = (void*)3, .clone = clone_offset, },
353 { .val = (void*)4, .clone = clone_offset, },
354 { .val = (void*)5, .clone = clone_offset, },
355 };
356 int i;
357
358 for (i = 0; i < countof(items); i++)
359 {
360 list->insert_last(list, &items[i]);
361 }
362 other = list->clone_offset(list, offsetof(clone_t, clone));
363 test_clone(other);
364 other->destroy(other);
365 }
366 END_TEST
367
368 Suite *linked_list_suite_create()
369 {
370 Suite *s;
371 TCase *tc;
372
373 s = suite_create("linked list");
374
375 tc = tcase_create("insert/get");
376 tcase_add_checked_fixture(tc, setup_list, teardown_list);
377 tcase_add_test(tc, test_insert_first);
378 tcase_add_test(tc, test_insert_last);
379 suite_add_tcase(s, tc);
380
381 tc = tcase_create("remove");
382 tcase_add_checked_fixture(tc, setup_list, teardown_list);
383 tcase_add_test(tc, test_remove_first);
384 tcase_add_test(tc, test_remove_last);
385 tcase_add_test(tc, test_remove);
386 tcase_add_test(tc, test_remove_callback);
387 suite_add_tcase(s, tc);
388
389 tc = tcase_create("find");
390 tcase_add_checked_fixture(tc, setup_list, teardown_list);
391 tcase_add_test(tc, test_find);
392 tcase_add_test(tc, test_find_callback);
393 suite_add_tcase(s, tc);
394
395 tc = tcase_create("invoke");
396 tcase_add_checked_fixture(tc, setup_list, teardown_list);
397 tcase_add_test(tc, test_invoke_function);
398 tcase_add_test(tc, test_invoke_offset);
399 suite_add_tcase(s, tc);
400
401 tc = tcase_create("clone");
402 tcase_add_checked_fixture(tc, setup_list, teardown_list);
403 tcase_add_test(tc, test_clone_function);
404 tcase_add_test(tc, test_clone_offset);
405 suite_add_tcase(s, tc);
406
407 return s;
408 }