Asterisk - The Open Source Telephony Project GIT-master-f36a736
test_vector.c
Go to the documentation of this file.
1/*
2 * Asterisk -- An open source telephony toolkit.
3 *
4 * Copyright (C) 2015, Fairview 5 Engineering, LLC
5 *
6 * George Joseph <george.joseph@fairview5.com>
7 *
8 * See http://www.asterisk.org for more information about
9 * the Asterisk project. Please do not directly contact
10 * any of the maintainers of this project for assistance;
11 * the project provides a web site, mailing lists and IRC
12 * channels for your use.
13 *
14 * This program is free software, distributed under the terms of
15 * the GNU General Public License Version 2. See the LICENSE file
16 * at the top of the source tree.
17 */
18
19/*!
20 * \file
21 * \brief Vector tests
22 *
23 * \author George Joseph <george.joseph@fairview5.com>
24 *
25 * This module will run some vector tests.
26 *
27 * \ingroup tests
28 */
29
30/*** MODULEINFO
31 <depend>TEST_FRAMEWORK</depend>
32 <support_level>core</support_level>
33 ***/
34
35#include "asterisk.h"
36
37#include "asterisk/test.h"
38#include "asterisk/utils.h"
39#include "asterisk/strings.h"
40#include "asterisk/module.h"
41#include "asterisk/vector.h"
42
43static int cleanup_count;
44
45static void cleanup(char *element)
46{
48}
49
50#define STRING_CMP(a, b) ({ \
51 ((void *)(a) == (void *)NULL || (void *)(b) == (void *)NULL) ? -1 : (strcmp((a), (b)) == 0); \
52})
53
55{
56 AST_VECTOR(test_struct, char *) sv1;
57 int rc = AST_TEST_PASS;
58
59 char *AAA = "AAA";
60 char *BBB = "BBB";
61 char *CCC = "CCC";
62 char *YYY = "YYY";
63 char *ZZZ = "ZZZ";
64 char CCC2[4];
65
66 strcpy(CCC2, "CCC");
67 switch (cmd) {
68 case TEST_INIT:
69 info->name = "basic";
70 info->category = "/main/vector/";
71 info->summary = "Test vector basic ops";
72 info->description = "Test vector basic ops";
73 return AST_TEST_NOT_RUN;
74 case TEST_EXECUTE:
75 break;
76 }
77
78 ast_test_validate(test, AST_VECTOR_INIT(&sv1, 3) == 0);
79 ast_test_validate_cleanup(test, sv1.max == 3, rc, cleanup);
80 ast_test_validate_cleanup(test, AST_VECTOR_SIZE(&sv1) == 0, rc, cleanup);
81 /* there should be no vector growth for the 3 appends */
82 ast_test_validate_cleanup(test, AST_VECTOR_APPEND(&sv1, AAA) == 0, rc, cleanup);
83 ast_test_validate_cleanup(test, sv1.max == 3, rc, cleanup);
84 ast_test_validate_cleanup(test, AST_VECTOR_APPEND(&sv1, BBB) == 0, rc, cleanup);
85 ast_test_validate_cleanup(test, sv1.max == 3, rc, cleanup);
86 ast_test_validate_cleanup(test, AST_VECTOR_APPEND(&sv1, CCC) == 0, rc, cleanup);
87 ast_test_validate_cleanup(test, AST_VECTOR_SIZE(&sv1) == 3, rc, cleanup);
88 ast_test_validate_cleanup(test, sv1.max >= 3, rc, cleanup);
89 ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 0) == AAA, rc, cleanup);
90 ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 1) == BBB, rc, cleanup);
91 ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 2) == CCC, rc, cleanup);
92 ast_test_validate_cleanup(test, sv1.max == sv1.current, rc, cleanup);
93
94 ast_test_validate_cleanup(test, AST_VECTOR_INSERT_AT(&sv1, 1, ZZZ) == 0, rc, cleanup);
95 /* The vector should have grown */
96 ast_test_validate_cleanup(test, sv1.max == 8, rc, cleanup);
97 ast_test_validate_cleanup(test, AST_VECTOR_SIZE(&sv1) == 4, rc, cleanup);
98 ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 0) == AAA, rc, cleanup);
99 ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 1) == ZZZ, rc, cleanup);
100 ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 2) == BBB, rc, cleanup);
101 ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 3) == CCC, rc, cleanup);
102
103 /* Test inserting > current but < max */
104 ast_test_validate_cleanup(test, AST_VECTOR_INSERT_AT(&sv1, 6, YYY) == 0, rc, cleanup);
105 ast_test_validate_cleanup(test, sv1.current == 7, rc, cleanup);
106 /* The vector should not have grown */
107 ast_test_validate_cleanup(test, sv1.max == 8, rc, cleanup);
108 ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 6) == YYY, rc, cleanup);
109 ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 4) == NULL, rc, cleanup);
110 ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 5) == NULL, rc, cleanup);
111 ast_test_validate_cleanup(test, *(char **)AST_VECTOR_GET_CMP(&sv1, "AAA", STRING_CMP) == AAA, rc, cleanup);
112 ast_test_validate_cleanup(test, *(char **)AST_VECTOR_GET_CMP(&sv1, "ZZZ", STRING_CMP) == ZZZ, rc, cleanup);
113
114 /* Test inserting > max */
115 ast_test_validate_cleanup(test, AST_VECTOR_INSERT_AT(&sv1, 12, AAA) == 0, rc, cleanup);
116 ast_test_validate_cleanup(test, sv1.current == 13, rc, cleanup);
117 /* The vector should have grown */
118 ast_test_validate_cleanup(test, sv1.max == 26, rc, cleanup);
119
120 /* RESET */
121 AST_VECTOR_FREE(&sv1);
122 ast_test_validate(test, sv1.elems == NULL);
123 ast_test_validate(test, sv1.current == 0);
124 ast_test_validate(test, sv1.max == 0);
125
126 /* Test with initial size = 0 */
127 ast_test_validate(test, AST_VECTOR_INIT(&sv1, 0) == 0);
128 ast_test_validate_cleanup(test, sv1.max == 0, rc, cleanup);
129 ast_test_validate_cleanup(test, AST_VECTOR_SIZE(&sv1) == 0, rc, cleanup);
130
131 ast_test_validate_cleanup(test, AST_VECTOR_APPEND(&sv1, AAA) == 0, rc, cleanup);
132 ast_test_validate_cleanup(test, AST_VECTOR_APPEND(&sv1, BBB) == 0, rc, cleanup);
133 ast_test_validate_cleanup(test, AST_VECTOR_APPEND(&sv1, CCC) == 0, rc, cleanup);
134 ast_test_validate_cleanup(test, sv1.max >= 3, rc, cleanup);
135 ast_test_validate_cleanup(test, AST_VECTOR_SIZE(&sv1) == 3, rc, cleanup);
136
137 ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 0) == AAA, rc, cleanup);
138 ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 1) == BBB, rc, cleanup);
139 ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 2) == CCC, rc, cleanup);
140
141 /* Overwrite index 1 */
142 ast_test_validate_cleanup(test, AST_VECTOR_REPLACE(&sv1, 1, ZZZ) == 0, rc, cleanup);
143 ast_test_validate_cleanup(test, sv1.current == 3, rc, cleanup);
144 ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 0) == AAA, rc, cleanup);
145 ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 1) == ZZZ, rc, cleanup);
146 ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 2) == CCC, rc, cleanup);
147
148 /* Replace beyond current */
149 ast_test_validate_cleanup(test, AST_VECTOR_REPLACE(&sv1, 10, YYY) == 0, rc, cleanup);
150 ast_test_validate_cleanup(test, sv1.current == 11, rc, cleanup);
151 ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 0) == AAA, rc, cleanup);
152 ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 1) == ZZZ, rc, cleanup);
153 ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 2) == CCC, rc, cleanup);
154 ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 5) == NULL, rc, cleanup);
155 ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 10) == YYY, rc, cleanup);
156
157 /* Replace beyond max */
158 ast_test_validate_cleanup(test, AST_VECTOR_REPLACE(&sv1, 100, YYY) == 0, rc, cleanup);
159 ast_test_validate_cleanup(test, sv1.current == 101, rc, cleanup);
160 ast_test_validate_cleanup(test, sv1.max >= 101, rc, cleanup);
161
162 /* Remove index 0 and bring the last entry (10/YYY) into it's empty slot */
163 ast_test_validate_cleanup(test, AST_VECTOR_REMOVE_UNORDERED(&sv1, 0) == AAA, rc, cleanup);
164 ast_test_validate_cleanup(test, sv1.current == 100, rc, cleanup);
165 ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 0) == YYY, rc, cleanup);
166 ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 1) == ZZZ, rc, cleanup);
167
168 /* Replace 0 and 2 leaving 1 alone */
169 ast_test_validate_cleanup(test, AST_VECTOR_REPLACE(&sv1, 0, AAA) == 0, rc, cleanup);
170 ast_test_validate_cleanup(test, AST_VECTOR_REPLACE(&sv1, 2, CCC) == 0, rc, cleanup);
171 ast_test_validate_cleanup(test, sv1.current == 100, rc, cleanup);
172 ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 0) == AAA, rc, cleanup);
173 ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 1) == ZZZ, rc, cleanup);
174 ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 2) == CCC, rc, cleanup);
175
176 /* Remove 1 and compact preserving order */
177 ast_test_validate_cleanup(test, AST_VECTOR_REMOVE_ORDERED(&sv1, 1) == ZZZ, rc, cleanup);
178 ast_test_validate_cleanup(test, sv1.current == 99, rc, cleanup);
179 ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 0) == AAA, rc, cleanup);
180 ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 1) == CCC, rc, cleanup);
181
182 ast_test_validate_cleanup(test, AST_VECTOR_INSERT_AT(&sv1, 0, ZZZ) == 0, rc, cleanup);
183 ast_test_validate_cleanup(test, sv1.current == 100, rc, cleanup);
184
185 /* This should fail because comparison is by pointer */
186 ast_test_validate_cleanup(test, AST_VECTOR_REMOVE_ELEM_ORDERED(&sv1, "ZZZ", cleanup) != 0, rc, cleanup);
187
188 /* This should work because we passing in the specific object to be removed */
189 cleanup_count = 0;
190 ast_test_validate_cleanup(test, AST_VECTOR_REMOVE_ELEM_ORDERED(&sv1, ZZZ, cleanup) == 0, rc, cleanup);
191 ast_test_validate_cleanup(test, sv1.current == 99, rc, cleanup);
192 ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 0) == AAA, rc, cleanup);
193 ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 1) == CCC, rc, cleanup);
194 ast_test_validate_cleanup(test, cleanup_count == 1, rc, cleanup);
195
196 /* If we want a comparison by value, we need to pass in a comparison
197 * function.
198 */
199 cleanup_count = 0;
200 ast_test_validate_cleanup(test, AST_VECTOR_REMOVE_CMP_ORDERED(&sv1, "AAA", STRING_CMP, cleanup) == 0, rc, cleanup);
201 ast_test_validate_cleanup(test, AST_VECTOR_SIZE(&sv1) == 98, rc, cleanup);
202 ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 0) == CCC, rc, cleanup);
203 ast_test_validate_cleanup(test, cleanup_count == 1, rc, cleanup);
204
205 /* Test INSERT_SORTED */
206 AST_VECTOR_FREE(&sv1);
207 ast_test_validate(test, AST_VECTOR_INIT(&sv1, 0) == 0);
208
209 ast_test_validate_cleanup(test, AST_VECTOR_ADD_SORTED(&sv1, BBB, strcmp) == 0, rc, cleanup);
210 ast_test_validate_cleanup(test, AST_VECTOR_ADD_SORTED(&sv1, ZZZ, strcmp) == 0, rc, cleanup);
211 ast_test_validate_cleanup(test, AST_VECTOR_ADD_SORTED(&sv1, CCC, strcmp) == 0, rc, cleanup);
212 ast_test_validate_cleanup(test, AST_VECTOR_ADD_SORTED(&sv1, AAA, strcmp) == 0, rc, cleanup);
213 ast_test_validate_cleanup(test, AST_VECTOR_ADD_SORTED(&sv1, (char*)CCC2, strcmp) == 0, rc, cleanup);
214
215 ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 0) == AAA, rc, cleanup);
216 ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 1) == BBB, rc, cleanup);
217 ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 2) == CCC, rc, cleanup);
218 ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 3) == CCC2, rc, cleanup);
219 ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 4) == ZZZ, rc, cleanup);
220
221 cleanup_count = 0;
223 ast_test_validate_cleanup(test, AST_VECTOR_SIZE(&sv1) == 0, rc, cleanup);
224 ast_test_validate_cleanup(test, sv1.max >= 5, rc, cleanup);
225 ast_test_validate_cleanup(test, sv1.elems != NULL, rc, cleanup);
226 ast_test_validate_cleanup(test, cleanup_count == 5, rc, cleanup);
227
228cleanup:
229 AST_VECTOR_FREE(&sv1);
230 return rc;
231}
232
233static void cleanup_int(int element)
234{
236}
237
238AST_TEST_DEFINE(basic_ops_integer)
239{
240 AST_VECTOR(test_struct, int) sv1;
241 int rc = AST_TEST_PASS;
242
243 int AAA = 1;
244 int BBB = 3;
245 int CCC = 5;
246 int ZZZ = 26;
247
248 switch (cmd) {
249 case TEST_INIT:
250 info->name = "basic_integer";
251 info->category = "/main/vector/";
252 info->summary = "Test integer vector basic ops";
253 info->description = "Test integer vector basic ops";
254 return AST_TEST_NOT_RUN;
255 case TEST_EXECUTE:
256 break;
257 }
258
259 ast_test_validate(test, AST_VECTOR_INIT(&sv1, 3) == 0);
260 ast_test_validate_cleanup(test, sv1.max == 3, rc, cleanup);
261 ast_test_validate_cleanup(test, AST_VECTOR_SIZE(&sv1) == 0, rc, cleanup);
262
263 ast_test_validate_cleanup(test, AST_VECTOR_APPEND(&sv1, AAA) == 0, rc, cleanup);
264 ast_test_validate_cleanup(test, sv1.max == 3, rc, cleanup);
265 ast_test_validate_cleanup(test, AST_VECTOR_APPEND(&sv1, BBB) == 0, rc, cleanup);
266 ast_test_validate_cleanup(test, sv1.max == 3, rc, cleanup);
267 ast_test_validate_cleanup(test, AST_VECTOR_APPEND(&sv1, CCC) == 0, rc, cleanup);
268 ast_test_validate_cleanup(test, AST_VECTOR_SIZE(&sv1) == 3, rc, cleanup);
269 ast_test_validate_cleanup(test, sv1.max == 3, rc, cleanup);
270 ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 0) == AAA, rc, cleanup);
271 ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 1) == BBB, rc, cleanup);
272 ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 2) == CCC, rc, cleanup);
273
274 ast_test_validate_cleanup(test, AST_VECTOR_INSERT_AT(&sv1, 1, ZZZ) == 0, rc, cleanup);
275 ast_test_validate_cleanup(test, sv1.max >= 4, rc, cleanup);
276 ast_test_validate_cleanup(test, AST_VECTOR_SIZE(&sv1) == 4, rc, cleanup);
277 ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 0) == AAA, rc, cleanup);
278 ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 1) == ZZZ, rc, cleanup);
279 ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 2) == BBB, rc, cleanup);
280 ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 3) == CCC, rc, cleanup);
281
282 ast_test_validate_cleanup(test, *(int *)AST_VECTOR_GET_CMP(&sv1, AAA, AST_VECTOR_ELEM_DEFAULT_CMP) == AAA, rc, cleanup);
283 ast_test_validate_cleanup(test, *(int *)AST_VECTOR_GET_CMP(&sv1, ZZZ, AST_VECTOR_ELEM_DEFAULT_CMP) == ZZZ, rc, cleanup);
284
285 /* Default first value */
286 ast_test_validate_cleanup(test, AST_VECTOR_DEFAULT(&sv1, 1, CCC) == 0, rc, cleanup);
287 ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 0) == CCC, rc, cleanup);
288 ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 1) == ZZZ, rc, cleanup);
289 /* Default all values */
290 ast_test_validate_cleanup(test, AST_VECTOR_DEFAULT(&sv1, 0, AAA) == 0, rc, cleanup);
291 ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 0) == AAA, rc, cleanup);
292 ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 1) == AAA, rc, cleanup);
293 ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 2) == AAA, rc, cleanup);
294 ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 3) == AAA, rc, cleanup);
295 /* Default more values than are currently in the vector */
296 ast_test_validate_cleanup(test, AST_VECTOR_DEFAULT(&sv1, 5, BBB) == 0, rc, cleanup);
297 ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 4) == BBB, rc, cleanup);
298
299 /* Check getting index(es) */
300 ast_test_validate_cleanup(test, AST_VECTOR_GET_INDEX(&sv1, BBB, AST_VECTOR_ELEM_DEFAULT_CMP) == 0, rc, cleanup);
301 ast_test_validate_cleanup(test, AST_VECTOR_GET_INDEX_NTH(&sv1, 2, BBB, AST_VECTOR_ELEM_DEFAULT_CMP) == 1, rc, cleanup);
302 ast_test_validate_cleanup(test, AST_VECTOR_GET_INDEX_NTH(&sv1, 4, BBB, AST_VECTOR_ELEM_DEFAULT_CMP) == 3, rc, cleanup);
303
304 AST_VECTOR_FREE(&sv1);
305 ast_test_validate(test, sv1.elems == NULL);
306 ast_test_validate(test, sv1.current == 0);
307 ast_test_validate(test, sv1.max == 0);
308
309 ast_test_validate(test, AST_VECTOR_INIT(&sv1, 0) == 0);
310 ast_test_validate_cleanup(test, sv1.max == 0, rc, cleanup);
311 ast_test_validate_cleanup(test, AST_VECTOR_SIZE(&sv1) == 0, rc, cleanup);
312
313 ast_test_validate_cleanup(test, AST_VECTOR_APPEND(&sv1, AAA) == 0, rc, cleanup);
314 ast_test_validate_cleanup(test, AST_VECTOR_APPEND(&sv1, BBB) == 0, rc, cleanup);
315 ast_test_validate_cleanup(test, AST_VECTOR_APPEND(&sv1, CCC) == 0, rc, cleanup);
316 ast_test_validate_cleanup(test, sv1.max >= 3, rc, cleanup);
317 ast_test_validate_cleanup(test, AST_VECTOR_SIZE(&sv1) == 3, rc, cleanup);
318
319 ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 0) == AAA, rc, cleanup);
320 ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 1) == BBB, rc, cleanup);
321 ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 2) == CCC, rc, cleanup);
322
323 /* Overwrite index 1 */
324 ast_test_validate_cleanup(test, AST_VECTOR_REPLACE(&sv1, 1, ZZZ) == 0, rc, cleanup);
325 ast_test_validate_cleanup(test, AST_VECTOR_SIZE(&sv1) == 3, rc, cleanup);
326 ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 0) == AAA, rc, cleanup);
327 ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 1) == ZZZ, rc, cleanup);
328 ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 2) == CCC, rc, cleanup);
329
330 /* Remove index 0 and bring the last entry into it's empty slot */
331 ast_test_validate_cleanup(test, AST_VECTOR_REMOVE_UNORDERED(&sv1, 0) == 1, rc, cleanup);
332 ast_test_validate_cleanup(test, AST_VECTOR_SIZE(&sv1) == 2, rc, cleanup);
333 ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 0) == CCC, rc, cleanup);
334 ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 1) == ZZZ, rc, cleanup);
335
336 /* Replace 0 and 2 leaving 1 alone */
337 ast_test_validate_cleanup(test, AST_VECTOR_REPLACE(&sv1, 0, AAA) == 0, rc, cleanup);
338 ast_test_validate_cleanup(test, AST_VECTOR_REPLACE(&sv1, 2, CCC) == 0, rc, cleanup);
339 ast_test_validate_cleanup(test, AST_VECTOR_SIZE(&sv1) == 3, rc, cleanup);
340 ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 0) == AAA, rc, cleanup);
341 ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 1) == ZZZ, rc, cleanup);
342 ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 2) == CCC, rc, cleanup);
343
344 /* Remove 1 and compact preserving order */
345 ast_test_validate_cleanup(test, AST_VECTOR_REMOVE_ORDERED(&sv1, 1) == ZZZ, rc, cleanup);
346 ast_test_validate_cleanup(test, AST_VECTOR_SIZE(&sv1) == 2, rc, cleanup);
347 ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 0) == AAA, rc, cleanup);
348 ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 1) == CCC, rc, cleanup);
349
350 /* Equivalent of APPEND */
351 ast_test_validate_cleanup(test, AST_VECTOR_REPLACE(&sv1, 2, ZZZ) == 0, rc, cleanup);
352 ast_test_validate_cleanup(test, AST_VECTOR_SIZE(&sv1) == 3, rc, cleanup);
353
354 /* This should work because we passing in the specific object to be removed */
355 cleanup_count = 0;
356 ast_test_validate_cleanup(test, AST_VECTOR_REMOVE_ELEM_ORDERED(&sv1, ZZZ, cleanup_int) == 0, rc, cleanup);
357 ast_test_validate_cleanup(test, AST_VECTOR_SIZE(&sv1) == 2, rc, cleanup);
358 ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 0) == AAA, rc, cleanup);
359 ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 1) == CCC, rc, cleanup);
360 ast_test_validate_cleanup(test, cleanup_count == 1, rc, cleanup);
361
362 /* If we want a comparison by value, we need to pass in a comparison
363 * function.
364 */
365 cleanup_count = 0;
366 ast_test_validate_cleanup(test, AST_VECTOR_REMOVE_CMP_ORDERED(&sv1, AAA, AST_VECTOR_ELEM_DEFAULT_CMP, cleanup_int) == 0, rc, cleanup);
367 ast_test_validate_cleanup(test, AST_VECTOR_SIZE(&sv1) == 1, rc, cleanup);
368 ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 0) == CCC, rc, cleanup);
369 ast_test_validate_cleanup(test, cleanup_count == 1, rc, cleanup);
370
371 /* This element is gone so we shouldn't be able to find it or delete it again. */
372 ast_test_validate_cleanup(test, AST_VECTOR_GET_CMP(&sv1, AAA, AST_VECTOR_ELEM_DEFAULT_CMP) == NULL, rc, cleanup);
373 ast_test_validate_cleanup(test, AST_VECTOR_REMOVE_CMP_ORDERED(&sv1, AAA, AST_VECTOR_ELEM_DEFAULT_CMP, cleanup_int) != 0, rc, cleanup);
374
375 /* CCC should still be there though */
376 ast_test_validate_cleanup(test, *(int *)AST_VECTOR_GET_CMP(&sv1, CCC, AST_VECTOR_ELEM_DEFAULT_CMP) == CCC, rc, cleanup);
377
378cleanup:
379 AST_VECTOR_FREE(&sv1);
380 return rc;
381}
382
383static int visits;
384
385static int cb_match(void *obj, void *arg)
386{
387 visits++;
388 return strcmp(arg, obj) == 0 ? CMP_MATCH : 0;
389}
390
391static int cb_visits(void *obj, int v)
392{
393 visits++;
394 return visits == v ? CMP_STOP : 0;
395}
396
398{
399 AST_VECTOR(, char *) sv1;
400 typeof(sv1) *sv2 = NULL;
401
402 int rc = AST_TEST_PASS;
403 char *AAA = "AAA";
404 char *AAA2 = "AAA";
405 char *BBB = "BBB";
406 char *CCC = "CCC";
407 char *DEF = "default_value";
408
409 switch (cmd) {
410 case TEST_INIT:
411 info->name = "callbacks";
412 info->category = "/main/vector/";
413 info->summary = "Test vector callback ops";
414 info->description = "Test vector callback ops";
415 return AST_TEST_NOT_RUN;
416 case TEST_EXECUTE:
417 break;
418 }
419
420 AST_VECTOR_INIT(&sv1, 32);
421
422 AST_VECTOR_APPEND(&sv1, AAA);
423 AST_VECTOR_APPEND(&sv1, BBB);
424 AST_VECTOR_APPEND(&sv1, CCC);
425 AST_VECTOR_APPEND(&sv1, AAA2);
426
427 visits = 0;
428 ast_test_validate_cleanup(test, AST_VECTOR_CALLBACK(&sv1, cb_match, DEF, "AAA") == AAA, rc, cleanup);
429 ast_test_validate_cleanup(test, visits == 1, rc, cleanup);
430
431 visits = 0;
432 ast_test_validate_cleanup(test, AST_VECTOR_CALLBACK(&sv1, cb_match, DEF, "XYZ") == DEF, rc, cleanup);
433 ast_test_validate_cleanup(test, visits == 4, rc, cleanup);
434
435 visits = 0;
436 ast_test_validate_cleanup(test, AST_VECTOR_CALLBACK(&sv1, cb_visits, DEF, 2) == DEF, rc, cleanup);
437 ast_test_validate_cleanup(test, visits == 2, rc, cleanup);
438
439
441 ast_test_validate_cleanup(test, AST_VECTOR_SIZE(sv2) == 4, rc, cleanup);
442 ast_test_validate_cleanup(test, AST_VECTOR_GET(sv2, 0) == AAA, rc, cleanup);
443 ast_test_validate_cleanup(test, AST_VECTOR_GET(sv2, 1) == BBB, rc, cleanup);
444 ast_test_validate_cleanup(test, AST_VECTOR_GET(sv2, 2) == CCC, rc, cleanup);
445 ast_test_validate_cleanup(test, AST_VECTOR_GET(sv2, 3) == AAA2, rc, cleanup);
446
448
449 AST_VECTOR_APPEND(&sv1, AAA);
450 AST_VECTOR_APPEND(&sv1, BBB);
451 AST_VECTOR_APPEND(&sv1, CCC);
452 ast_test_validate_cleanup(test, AST_VECTOR_SIZE(&sv1) == 7, rc, cleanup);
453
454 sv2 = AST_VECTOR_CALLBACK_MULTIPLE(&sv1, cb_match, "AAA");
455 ast_test_validate_cleanup(test, AST_VECTOR_SIZE(sv2) == 3, rc, cleanup);
456 ast_test_validate_cleanup(test, AST_VECTOR_GET(sv2, 0) == AAA, rc, cleanup);
457 ast_test_validate_cleanup(test, AST_VECTOR_GET(sv2, 1) == AAA2, rc, cleanup);
458 ast_test_validate_cleanup(test, AST_VECTOR_GET(sv2, 2) == AAA, rc, cleanup);
459
460cleanup:
461 AST_VECTOR_FREE(&sv1);
463
464 return rc;
465}
466
468{
469 AST_VECTOR_RW(, char *) sv1;
470 int rc = AST_TEST_PASS;
471 struct timespec ts;
472
473 switch (cmd) {
474 case TEST_INIT:
475 info->name = "locks";
476 info->category = "/main/vector/";
477 info->summary = "Test vector locking ops";
478 info->description = "Test vector locking ops";
479 return AST_TEST_NOT_RUN;
480 case TEST_EXECUTE:
481 break;
482 }
483
484 /* We're not actually checking that locking works,
485 * just that the macro expansions work
486 */
487
488 AST_VECTOR_RW_INIT(&sv1, 0);
489
490 ast_test_validate_cleanup(test, AST_VECTOR_RW_RDLOCK(&sv1) == 0, rc, cleanup);
491 ast_test_validate_cleanup(test, AST_VECTOR_RW_UNLOCK(&sv1) == 0, rc, cleanup);
492 ast_test_validate_cleanup(test, AST_VECTOR_RW_WRLOCK(&sv1) == 0, rc, cleanup);
493 ast_test_validate_cleanup(test, AST_VECTOR_RW_UNLOCK(&sv1) == 0, rc, cleanup);
494
495 ast_test_validate_cleanup(test, AST_VECTOR_RW_RDLOCK_TRY(&sv1) == 0, rc, cleanup);
496 ast_test_validate_cleanup(test, AST_VECTOR_RW_WRLOCK_TRY(&sv1) != 0, rc, cleanup);
497 ast_test_validate_cleanup(test, AST_VECTOR_RW_UNLOCK(&sv1) == 0, rc, cleanup);
498 ast_test_validate_cleanup(test, AST_VECTOR_RW_WRLOCK_TRY(&sv1) == 0, rc, cleanup);
499 ast_test_validate_cleanup(test, AST_VECTOR_RW_UNLOCK(&sv1) == 0, rc, cleanup);
500
501 ts.tv_nsec = 0;
502 ts.tv_sec = 2;
503
504 ast_test_validate_cleanup(test, AST_VECTOR_RW_RDLOCK_TIMED(&sv1, &ts) == 0, rc, cleanup);
505 ast_test_validate_cleanup(test, AST_VECTOR_RW_WRLOCK_TIMED(&sv1, &ts) != 0, rc, cleanup);
506 ast_test_validate_cleanup(test, AST_VECTOR_RW_UNLOCK(&sv1) == 0, rc, cleanup);
507 ast_test_validate_cleanup(test, AST_VECTOR_RW_WRLOCK_TIMED(&sv1, &ts) == 0, rc, cleanup);
508 ast_test_validate_cleanup(test, AST_VECTOR_RW_UNLOCK(&sv1) == 0, rc, cleanup);
509
510cleanup:
511 AST_VECTOR_RW_FREE(&sv1);
512
513 return rc;
514}
515
516static int unload_module(void)
517{
518 AST_TEST_UNREGISTER(locks);
520 AST_TEST_UNREGISTER(basic_ops_integer);
521 AST_TEST_UNREGISTER(basic_ops);
522
523 return 0;
524}
525
526static int load_module(void)
527{
528 AST_TEST_REGISTER(locks);
530 AST_TEST_REGISTER(basic_ops_integer);
531 AST_TEST_REGISTER(basic_ops);
532
534}
535
Asterisk main include file. File version handling, generic pbx functions.
@ CMP_MATCH
Definition: astobj2.h:1027
@ CMP_STOP
Definition: astobj2.h:1028
Asterisk module definitions.
#define AST_MODULE_INFO_STANDARD(keystr, desc)
Definition: module.h:581
#define ASTERISK_GPL_KEY
The text the key() function should return.
Definition: module.h:46
@ AST_MODULE_LOAD_SUCCESS
Definition: module.h:70
def info(msg)
struct @468 callbacks
#define NULL
Definition: resample.c:96
String manipulation functions.
Test Framework API.
@ TEST_INIT
Definition: test.h:200
@ TEST_EXECUTE
Definition: test.h:201
#define AST_TEST_REGISTER(cb)
Definition: test.h:127
#define AST_TEST_UNREGISTER(cb)
Definition: test.h:128
@ AST_TEST_PASS
Definition: test.h:195
@ AST_TEST_NOT_RUN
Definition: test.h:194
static void cleanup_int(int element)
Definition: test_vector.c:233
AST_TEST_DEFINE(basic_ops)
Definition: test_vector.c:54
static int visits
Definition: test_vector.c:383
static int cb_visits(void *obj, int v)
Definition: test_vector.c:391
static void cleanup(char *element)
Definition: test_vector.c:45
#define STRING_CMP(a, b)
Definition: test_vector.c:50
static int cb_match(void *obj, void *arg)
Definition: test_vector.c:385
static int load_module(void)
Definition: test_vector.c:526
static int unload_module(void)
Definition: test_vector.c:516
static int cleanup_count
Definition: test_vector.c:43
typedef typeof(dummy_tv_var_for_types.tv_sec) ast_time_t
Utility functions.
Vector container support.
#define AST_VECTOR_REMOVE_ORDERED(vec, idx)
Remove an element from a vector by index while maintaining order.
Definition: vector.h:448
#define AST_VECTOR_REPLACE(vec, idx, elem)
Replace an element at a specific position in a vector, growing the vector if needed.
Definition: vector.h:284
#define AST_VECTOR_RW_WRLOCK_TRY(vec)
Try to obtain write lock on vector failing immediately if unable.
Definition: vector.h:917
#define AST_VECTOR_RESET(vec, cleanup)
Reset vector.
Definition: vector.h:625
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:609
#define AST_VECTOR_GET_INDEX(vec, value, cmp)
Get the 1st index from a vector that matches the given comparison.
Definition: vector.h:719
#define AST_VECTOR_GET_INDEX_NTH(vec, nth, value, cmp)
Get the nth index from a vector that matches the given comparison.
Definition: vector.h:696
#define AST_VECTOR_INSERT_AT(vec, idx, elem)
Insert an element at a specific position in a vector, growing the vector if needed.
Definition: vector.h:338
#define AST_VECTOR_RW_WRLOCK(vec)
Obtain write lock on vector.
Definition: vector.h:887
#define AST_VECTOR_REMOVE_CMP_ORDERED(vec, value, cmp, cleanup)
Remove an element from a vector that matches the given comparison while maintaining order.
Definition: vector.h:540
#define AST_VECTOR_REMOVE_ELEM_ORDERED(vec, elem, cleanup)
Remove an element from a vector while maintaining order.
Definition: vector.h:598
#define AST_VECTOR_RW_UNLOCK(vec)
Unlock vector.
Definition: vector.h:897
#define AST_VECTOR_FREE(vec)
Deallocates this vector.
Definition: vector.h:174
#define AST_VECTOR_GET_CMP(vec, value, cmp)
Get an element from a vector that matches the given comparison.
Definition: vector.h:731
#define AST_VECTOR_RW_FREE(vec)
Deallocates this locked vector.
Definition: vector.h:202
#define AST_VECTOR_RW_WRLOCK_TIMED(vec, timespec)
Try to obtain write lock on vector failing after timeout if unable.
Definition: vector.h:939
#define AST_VECTOR_ELEM_DEFAULT_CMP(elem, value)
Default comparator for AST_VECTOR_REMOVE_ELEM_UNORDERED()
Definition: vector.h:564
#define AST_VECTOR_ADD_SORTED(vec, elem, cmp)
Add an element into a sorted vector.
Definition: vector.h:371
#define AST_VECTOR_REMOVE_UNORDERED(vec, idx)
Remove an element from an unordered vector by index.
Definition: vector.h:438
#define AST_VECTOR_DEFAULT(vec, size, value)
Default a vector up to size with the given value.
Definition: vector.h:309
#define AST_VECTOR_RW(name, type)
Define a vector structure with a read/write lock.
Definition: vector.h:93
#define AST_VECTOR_RW_RDLOCK_TRY(vec)
Try to obtain read lock on vector failing immediately if unable.
Definition: vector.h:907
#define AST_VECTOR_CALLBACK_MULTIPLE(vec, callback,...)
Execute a callback on every element in a vector returning the matching elements in a new vector.
Definition: vector.h:829
#define AST_VECTOR_CALLBACK(vec, callback, default_value,...)
Execute a callback on every element in a vector returning the first matched.
Definition: vector.h:765
#define AST_VECTOR_RW_RDLOCK_TIMED(vec, timespec)
Try to obtain read lock on vector failing after timeout if unable.
Definition: vector.h:928
#define AST_VECTOR_RW_RDLOCK(vec)
Obtain read lock on vector.
Definition: vector.h:877
#define AST_VECTOR_PTR_FREE(vec)
Deallocates this vector pointer.
Definition: vector.h:189
#define AST_VECTOR_INIT(vec, size)
Initialize a vector.
Definition: vector.h:113
#define AST_VECTOR_MATCH_ALL(element)
Default callback for AST_VECTOR_CALLBACK()
Definition: vector.h:751
#define AST_VECTOR_APPEND(vec, elem)
Append an element to a vector, growing the vector if needed.
Definition: vector.h:256
#define AST_VECTOR(name, type)
Define a vector structure.
Definition: vector.h:44
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition: vector.h:680
#define AST_VECTOR_RW_INIT(vec, size)
Initialize a vector with a read/write lock.
Definition: vector.h:158