2220d5a2b664363888d94fb6bccd5ba6238b8c61
[strongswan.git] / src / libstrongswan / tests / test_array.c
1 /*
2 * Copyright (C) 2013 Martin Willi
3 * Copyright (C) 2013 revosec AG
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/array.h>
19
20 START_TEST(test_append_ptr)
21 {
22 array_t *array;
23 uintptr_t x;
24 int i;
25
26 array = array_create(0, 0);
27
28 for (i = 0; i < 4; i++)
29 {
30 ck_assert_int_eq(array_count(array), 0);
31
32 array_insert(array, ARRAY_HEAD, (void*)(uintptr_t)3);
33 array_insert(array, ARRAY_TAIL, (void*)(uintptr_t)4);
34 ck_assert_int_eq(array_count(array), 2);
35
36 /* 3, 4 */
37
38 array_insert(array, ARRAY_HEAD, (void*)(uintptr_t)1);
39 array_insert(array, 1, (void*)(uintptr_t)2);
40 ck_assert_int_eq(array_count(array), 4);
41
42 /* 1, 2, 3, 4 */
43
44 array_insert(array, ARRAY_TAIL, (void*)(uintptr_t)5);
45 array_insert(array, ARRAY_HEAD, (void*)(uintptr_t)0);
46 ck_assert_int_eq(array_count(array), 6);
47
48 /* 0, 1, 2, 3, 4, 5 */
49
50 ck_assert(array_remove(array, ARRAY_TAIL, &x));
51 ck_assert_int_eq(x, 5);
52 ck_assert(array_remove(array, 4, &x));
53 ck_assert_int_eq(x, 4);
54
55 if (i < 3)
56 {
57 array_compress(array);
58 }
59
60 /* 0, 1, 2, 3 */
61
62 ck_assert(array_remove(array, 1, &x));
63 ck_assert_int_eq(x, 1);
64 ck_assert(array_remove(array, ARRAY_HEAD, &x));
65 ck_assert_int_eq(x, 0);
66
67 if (i < 2)
68 {
69 array_compress(array);
70 }
71
72 /* 2, 3 */
73
74 ck_assert(array_remove(array, ARRAY_TAIL, &x));
75 ck_assert_int_eq(x, 3);
76 ck_assert(array_remove(array, ARRAY_TAIL, &x));
77 ck_assert_int_eq(x, 2);
78
79 if (i < 1)
80 {
81 array_compress(array);
82 }
83
84 ck_assert_int_eq(array_count(array), 0);
85
86 ck_assert(array_remove(array, ARRAY_HEAD, NULL) == FALSE);
87 ck_assert(array_remove(array, ARRAY_TAIL, NULL) == FALSE);
88 }
89
90 array_destroy(array);
91 }
92 END_TEST
93
94 START_TEST(test_append_obj)
95 {
96 array_t *array;
97 int i, x, y[6] = {0, 1, 2, 3, 4, 5};
98
99 array = array_create(sizeof(y[0]), 0);
100
101 for (i = 0; i < 4; i++)
102 {
103 ck_assert_int_eq(array_count(array), 0);
104
105 array_insert(array, ARRAY_HEAD, &y[3]);
106 array_insert(array, ARRAY_TAIL, &y[4]);
107 ck_assert_int_eq(array_count(array), 2);;
108
109 /* 3, 4 */
110
111 array_insert(array, ARRAY_HEAD, &y[1]);
112 array_insert(array, 1, &y[2]);
113 ck_assert_int_eq(array_count(array), 4);
114
115 /* 1, 2, 3, 4 */
116
117 array_insert(array, ARRAY_TAIL, &y[5]);
118 array_insert(array, ARRAY_HEAD, &y[0]);
119 ck_assert_int_eq(array_count(array), 6);
120
121 /* 0, 1, 2, 3, 4, 5 */
122
123 ck_assert(array_remove(array, ARRAY_TAIL, &x));
124 ck_assert_int_eq(x, 5);
125 ck_assert(array_remove(array, 4, &x));
126 ck_assert_int_eq(x, 4);
127
128 if (i < 3)
129 {
130 array_compress(array);
131 }
132
133 /* 0, 1, 2, 3 */
134
135 ck_assert(array_remove(array, ARRAY_HEAD, &x));
136 ck_assert_int_eq(x, 0);
137 ck_assert(array_remove(array, ARRAY_HEAD, &x));
138 ck_assert_int_eq(x, 1);
139
140 if (i < 2)
141 {
142 array_compress(array);
143 }
144
145 /* 2, 3 */
146
147 ck_assert(array_remove(array, ARRAY_TAIL, &x));
148 ck_assert_int_eq(x, 3);
149 ck_assert(array_remove(array, ARRAY_HEAD, &x));
150 ck_assert_int_eq(x, 2);
151
152 if (i < 1)
153 {
154 array_compress(array);
155 }
156
157 ck_assert_int_eq(array_count(array), 0);
158
159 ck_assert(array_remove(array, ARRAY_HEAD, NULL) == FALSE);
160 ck_assert(array_remove(array, ARRAY_TAIL, NULL) == FALSE);
161 }
162
163 array_destroy(array);
164 }
165 END_TEST
166
167 START_TEST(test_enumerate)
168 {
169 array_t *array;
170 int i, *x, y[6] = {0, 1, 2, 3, 4, 5};
171 enumerator_t *enumerator;
172
173 array = array_create(sizeof(y[0]), 0);
174
175 array_insert(array, ARRAY_TAIL, &y[0]);
176 array_insert(array, ARRAY_TAIL, &y[1]);
177 array_insert(array, ARRAY_TAIL, &y[2]);
178 array_insert(array, ARRAY_TAIL, &y[3]);
179 array_insert(array, ARRAY_TAIL, &y[4]);
180 array_insert(array, ARRAY_TAIL, &y[5]);
181
182 ck_assert_int_eq(array_count(array), 6);
183
184 /* 0, 1, 2, 3, 4, 5 */
185
186 i = 0;
187 enumerator = array_create_enumerator(array);
188 while (enumerator->enumerate(enumerator, &x))
189 {
190 ck_assert_int_eq(*x, y[i]);
191 i++;
192 }
193 enumerator->destroy(enumerator);
194 ck_assert_int_eq(i, 6);
195
196 i = 0;
197 enumerator = array_create_enumerator(array);
198 while (enumerator->enumerate(enumerator, &x))
199 {
200 ck_assert_int_eq(*x, y[i]);
201 if (i == 0 || i == 3 || i == 5)
202 {
203 array_remove_at(array, enumerator);
204 }
205 i++;
206 }
207 enumerator->destroy(enumerator);
208 ck_assert_int_eq(i, 6);
209 ck_assert_int_eq(array_count(array), 3);
210
211 /* 1, 2, 4 */
212
213 i = 0;
214 enumerator = array_create_enumerator(array);
215 while (enumerator->enumerate(enumerator, &x))
216 {
217 switch (i++)
218 {
219 case 0:
220 ck_assert_int_eq(*x, y[1]);
221 break;
222 case 1:
223 ck_assert_int_eq(*x, y[2]);
224 break;
225 case 2:
226 ck_assert_int_eq(*x, y[4]);
227 break;
228 default:
229 ck_assert(0);
230 }
231 }
232 enumerator->destroy(enumerator);
233
234 array_compress(array);
235
236 i = 0;
237 enumerator = array_create_enumerator(array);
238 while (enumerator->enumerate(enumerator, &x))
239 {
240 switch (i++)
241 {
242 case 0:
243 ck_assert_int_eq(*x, y[1]);
244 break;
245 case 1:
246 ck_assert_int_eq(*x, y[2]);
247 break;
248 case 2:
249 ck_assert_int_eq(*x, y[4]);
250 break;
251 default:
252 ck_assert(0);
253 }
254 }
255 enumerator->destroy(enumerator);
256
257 array_destroy(array);
258 }
259 END_TEST
260
261 static void invoke(void *data, int idx, void *user)
262 {
263 int *y = user, *x = data;
264
265 ck_assert(idx < 3);
266
267 ck_assert_int_eq(y[idx], *x);
268 y[idx] = 0;
269 }
270
271 START_TEST(test_invoke)
272 {
273 array_t *array;
274 int y[] = {1, 2, 3};
275
276 array = array_create(sizeof(y[0]), 0);
277
278 array_insert(array, ARRAY_TAIL, &y[0]);
279 array_insert(array, ARRAY_TAIL, &y[1]);
280 array_insert(array, ARRAY_TAIL, &y[2]);
281
282 array_invoke(array, invoke, y);
283
284 ck_assert_int_eq(y[0], 0);
285 ck_assert_int_eq(y[0], 0);
286 ck_assert_int_eq(y[0], 0);
287
288 array_destroy(array);
289 }
290 END_TEST
291
292 typedef struct obj_t obj_t;
293
294 struct obj_t {
295 void (*fun)(obj_t *obj);
296 int x;
297 int *counter;
298 };
299
300 static void fun(obj_t *obj)
301 {
302 ck_assert(obj->x == (*obj->counter)++);
303 }
304
305 START_TEST(test_invoke_offset)
306 {
307 array_t *array;
308 obj_t objs[5];
309 int i, counter = 0;
310
311 array = array_create(0, 0);
312
313 for (i = 0; i < countof(objs); i++)
314 {
315 objs[i].x = i;
316 objs[i].counter = &counter;
317 objs[i].fun = fun;
318
319 array_insert(array, ARRAY_TAIL, &objs[i]);
320 }
321
322 ck_assert_int_eq(countof(objs), array_count(array));
323
324 array_invoke_offset(array, offsetof(obj_t, fun));
325
326 ck_assert_int_eq(counter, countof(objs));
327
328 array_destroy(array);
329 }
330 END_TEST
331
332 Suite *array_suite_create()
333 {
334 Suite *s;
335 TCase *tc;
336
337 s = suite_create("array");
338
339 tc = tcase_create("add/remove ptr");
340 tcase_add_test(tc, test_append_ptr);
341 suite_add_tcase(s, tc);
342
343 tc = tcase_create("add/remove obj");
344 tcase_add_test(tc, test_append_obj);
345 suite_add_tcase(s, tc);
346
347 tc = tcase_create("enumerate");
348 tcase_add_test(tc, test_enumerate);
349 suite_add_tcase(s, tc);
350
351 tc = tcase_create("invoke");
352 tcase_add_test(tc, test_invoke);
353 suite_add_tcase(s, tc);
354
355 tc = tcase_create("invoke offset");
356 tcase_add_test(tc, test_invoke_offset);
357 suite_add_tcase(s, tc);
358
359 return s;
360 }