test_vector.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536
  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. * \file
  20. * \brief Vector tests
  21. *
  22. * \author George Joseph <george.joseph@fairview5.com>
  23. *
  24. * This module will run some vector tests.
  25. *
  26. * \ingroup tests
  27. */
  28. /*** MODULEINFO
  29. <depend>TEST_FRAMEWORK</depend>
  30. <support_level>core</support_level>
  31. ***/
  32. #include "asterisk.h"
  33. #include "asterisk/test.h"
  34. #include "asterisk/utils.h"
  35. #include "asterisk/strings.h"
  36. #include "asterisk/module.h"
  37. #include "asterisk/vector.h"
  38. static int cleanup_count;
  39. static void cleanup(char *element)
  40. {
  41. cleanup_count++;
  42. }
  43. #define STRING_CMP(a, b) ({ \
  44. ((a) == NULL || (b) == NULL) ? -1 : (strcmp((a), (b)) == 0); \
  45. })
  46. AST_TEST_DEFINE(basic_ops)
  47. {
  48. AST_VECTOR(test_struct, char *) sv1;
  49. int rc = AST_TEST_PASS;
  50. char *AAA = "AAA";
  51. char *BBB = "BBB";
  52. char *CCC = "CCC";
  53. char *YYY = "YYY";
  54. char *ZZZ = "ZZZ";
  55. char CCC2[4];
  56. strcpy(CCC2, "CCC");
  57. switch (cmd) {
  58. case TEST_INIT:
  59. info->name = "basic";
  60. info->category = "/main/vector/";
  61. info->summary = "Test vector basic ops";
  62. info->description = "Test vector basic ops";
  63. return AST_TEST_NOT_RUN;
  64. case TEST_EXECUTE:
  65. break;
  66. }
  67. ast_test_validate(test, AST_VECTOR_INIT(&sv1, 3) == 0);
  68. ast_test_validate_cleanup(test, sv1.max == 3, rc, cleanup);
  69. ast_test_validate_cleanup(test, AST_VECTOR_SIZE(&sv1) == 0, rc, cleanup);
  70. /* there should be no vector growth for the 3 appends */
  71. ast_test_validate_cleanup(test, AST_VECTOR_APPEND(&sv1, AAA) == 0, rc, cleanup);
  72. ast_test_validate_cleanup(test, sv1.max == 3, rc, cleanup);
  73. ast_test_validate_cleanup(test, AST_VECTOR_APPEND(&sv1, BBB) == 0, rc, cleanup);
  74. ast_test_validate_cleanup(test, sv1.max == 3, rc, cleanup);
  75. ast_test_validate_cleanup(test, AST_VECTOR_APPEND(&sv1, CCC) == 0, rc, cleanup);
  76. ast_test_validate_cleanup(test, AST_VECTOR_SIZE(&sv1) == 3, rc, cleanup);
  77. ast_test_validate_cleanup(test, sv1.max >= 3, rc, cleanup);
  78. ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 0) == AAA, rc, cleanup);
  79. ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 1) == BBB, rc, cleanup);
  80. ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 2) == CCC, rc, cleanup);
  81. ast_test_validate_cleanup(test, sv1.max == sv1.current, rc, cleanup);
  82. ast_test_validate_cleanup(test, AST_VECTOR_INSERT_AT(&sv1, 1, ZZZ) == 0, rc, cleanup);
  83. /* The vector should have grown */
  84. ast_test_validate_cleanup(test, sv1.max == 8, rc, cleanup);
  85. ast_test_validate_cleanup(test, AST_VECTOR_SIZE(&sv1) == 4, rc, cleanup);
  86. ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 0) == AAA, rc, cleanup);
  87. ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 1) == ZZZ, rc, cleanup);
  88. ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 2) == BBB, rc, cleanup);
  89. ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 3) == CCC, rc, cleanup);
  90. /* Test inserting > current but < max */
  91. ast_test_validate_cleanup(test, AST_VECTOR_INSERT_AT(&sv1, 6, YYY) == 0, rc, cleanup);
  92. ast_test_validate_cleanup(test, sv1.current == 7, rc, cleanup);
  93. /* The vector should not have grown */
  94. ast_test_validate_cleanup(test, sv1.max == 8, rc, cleanup);
  95. ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 6) == YYY, rc, cleanup);
  96. ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 4) == NULL, rc, cleanup);
  97. ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 5) == NULL, rc, cleanup);
  98. ast_test_validate_cleanup(test, *(char **)AST_VECTOR_GET_CMP(&sv1, "AAA", STRING_CMP) == AAA, rc, cleanup);
  99. ast_test_validate_cleanup(test, *(char **)AST_VECTOR_GET_CMP(&sv1, "ZZZ", STRING_CMP) == ZZZ, rc, cleanup);
  100. /* Test inserting > max */
  101. ast_test_validate_cleanup(test, AST_VECTOR_INSERT_AT(&sv1, 12, AAA) == 0, rc, cleanup);
  102. ast_test_validate_cleanup(test, sv1.current == 13, rc, cleanup);
  103. /* The vector should have grown */
  104. ast_test_validate_cleanup(test, sv1.max == 26, rc, cleanup);
  105. /* RESET */
  106. AST_VECTOR_FREE(&sv1);
  107. ast_test_validate(test, sv1.elems == NULL);
  108. ast_test_validate(test, sv1.current == 0);
  109. ast_test_validate(test, sv1.max == 0);
  110. /* Test with initial size = 0 */
  111. ast_test_validate(test, AST_VECTOR_INIT(&sv1, 0) == 0);
  112. ast_test_validate_cleanup(test, sv1.max == 0, rc, cleanup);
  113. ast_test_validate_cleanup(test, AST_VECTOR_SIZE(&sv1) == 0, rc, cleanup);
  114. ast_test_validate_cleanup(test, AST_VECTOR_APPEND(&sv1, AAA) == 0, rc, cleanup);
  115. ast_test_validate_cleanup(test, AST_VECTOR_APPEND(&sv1, BBB) == 0, rc, cleanup);
  116. ast_test_validate_cleanup(test, AST_VECTOR_APPEND(&sv1, CCC) == 0, rc, cleanup);
  117. ast_test_validate_cleanup(test, sv1.max >= 3, rc, cleanup);
  118. ast_test_validate_cleanup(test, AST_VECTOR_SIZE(&sv1) == 3, rc, cleanup);
  119. ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 0) == AAA, rc, cleanup);
  120. ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 1) == BBB, rc, cleanup);
  121. ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 2) == CCC, rc, cleanup);
  122. /* Overwrite index 1 */
  123. ast_test_validate_cleanup(test, AST_VECTOR_REPLACE(&sv1, 1, ZZZ) == 0, rc, cleanup);
  124. ast_test_validate_cleanup(test, sv1.current == 3, rc, cleanup);
  125. ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 0) == AAA, rc, cleanup);
  126. ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 1) == ZZZ, rc, cleanup);
  127. ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 2) == CCC, rc, cleanup);
  128. /* Replace beyond current */
  129. ast_test_validate_cleanup(test, AST_VECTOR_REPLACE(&sv1, 10, YYY) == 0, rc, cleanup);
  130. ast_test_validate_cleanup(test, sv1.current == 11, rc, cleanup);
  131. ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 0) == AAA, rc, cleanup);
  132. ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 1) == ZZZ, rc, cleanup);
  133. ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 2) == CCC, rc, cleanup);
  134. ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 5) == NULL, rc, cleanup);
  135. ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 10) == YYY, rc, cleanup);
  136. /* Replace beyond max */
  137. ast_test_validate_cleanup(test, AST_VECTOR_REPLACE(&sv1, 100, YYY) == 0, rc, cleanup);
  138. ast_test_validate_cleanup(test, sv1.current == 101, rc, cleanup);
  139. ast_test_validate_cleanup(test, sv1.max >= 101, rc, cleanup);
  140. /* Remove index 0 and bring the last entry (10/YYY) into it's empty slot */
  141. ast_test_validate_cleanup(test, AST_VECTOR_REMOVE_UNORDERED(&sv1, 0) == AAA, rc, cleanup);
  142. ast_test_validate_cleanup(test, sv1.current == 100, rc, cleanup);
  143. ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 0) == YYY, rc, cleanup);
  144. ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 1) == ZZZ, rc, cleanup);
  145. /* Replace 0 and 2 leaving 1 alone */
  146. ast_test_validate_cleanup(test, AST_VECTOR_REPLACE(&sv1, 0, AAA) == 0, rc, cleanup);
  147. ast_test_validate_cleanup(test, AST_VECTOR_REPLACE(&sv1, 2, CCC) == 0, rc, cleanup);
  148. ast_test_validate_cleanup(test, sv1.current == 100, rc, cleanup);
  149. ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 0) == AAA, rc, cleanup);
  150. ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 1) == ZZZ, rc, cleanup);
  151. ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 2) == CCC, rc, cleanup);
  152. /* Remove 1 and compact preserving order */
  153. ast_test_validate_cleanup(test, AST_VECTOR_REMOVE_ORDERED(&sv1, 1) == ZZZ, rc, cleanup);
  154. ast_test_validate_cleanup(test, sv1.current == 99, rc, cleanup);
  155. ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 0) == AAA, rc, cleanup);
  156. ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 1) == CCC, rc, cleanup);
  157. ast_test_validate_cleanup(test, AST_VECTOR_INSERT_AT(&sv1, 0, ZZZ) == 0, rc, cleanup);
  158. ast_test_validate_cleanup(test, sv1.current == 100, rc, cleanup);
  159. /* This should fail because comparison is by pointer */
  160. ast_test_validate_cleanup(test, AST_VECTOR_REMOVE_ELEM_ORDERED(&sv1, "ZZZ", cleanup) != 0, rc, cleanup);
  161. /* This should work because we passing in the specific object to be removed */
  162. cleanup_count = 0;
  163. ast_test_validate_cleanup(test, AST_VECTOR_REMOVE_ELEM_ORDERED(&sv1, ZZZ, cleanup) == 0, rc, cleanup);
  164. ast_test_validate_cleanup(test, sv1.current == 99, rc, cleanup);
  165. ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 0) == AAA, rc, cleanup);
  166. ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 1) == CCC, rc, cleanup);
  167. ast_test_validate_cleanup(test, cleanup_count == 1, rc, cleanup);
  168. /* If we want a comparison by value, we need to pass in a comparison
  169. * function.
  170. */
  171. cleanup_count = 0;
  172. ast_test_validate_cleanup(test, AST_VECTOR_REMOVE_CMP_ORDERED(&sv1, "AAA", STRING_CMP, cleanup) == 0, rc, cleanup);
  173. ast_test_validate_cleanup(test, AST_VECTOR_SIZE(&sv1) == 98, rc, cleanup);
  174. ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 0) == CCC, rc, cleanup);
  175. ast_test_validate_cleanup(test, cleanup_count == 1, rc, cleanup);
  176. /* Test INSERT_SORTED */
  177. AST_VECTOR_FREE(&sv1);
  178. ast_test_validate(test, AST_VECTOR_INIT(&sv1, 0) == 0);
  179. ast_test_validate_cleanup(test, AST_VECTOR_ADD_SORTED(&sv1, BBB, strcmp) == 0, rc, cleanup);
  180. ast_test_validate_cleanup(test, AST_VECTOR_ADD_SORTED(&sv1, ZZZ, strcmp) == 0, rc, cleanup);
  181. ast_test_validate_cleanup(test, AST_VECTOR_ADD_SORTED(&sv1, CCC, strcmp) == 0, rc, cleanup);
  182. ast_test_validate_cleanup(test, AST_VECTOR_ADD_SORTED(&sv1, AAA, strcmp) == 0, rc, cleanup);
  183. ast_test_validate_cleanup(test, AST_VECTOR_ADD_SORTED(&sv1, (char*)CCC2, strcmp) == 0, rc, cleanup);
  184. ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 0) == AAA, rc, cleanup);
  185. ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 1) == BBB, rc, cleanup);
  186. ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 2) == CCC, rc, cleanup);
  187. ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 3) == CCC2, rc, cleanup);
  188. ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 4) == ZZZ, rc, cleanup);
  189. cleanup_count = 0;
  190. AST_VECTOR_RESET(&sv1, cleanup);
  191. ast_test_validate_cleanup(test, AST_VECTOR_SIZE(&sv1) == 0, rc, cleanup);
  192. ast_test_validate_cleanup(test, sv1.max >= 5, rc, cleanup);
  193. ast_test_validate_cleanup(test, sv1.elems != NULL, rc, cleanup);
  194. ast_test_validate_cleanup(test, cleanup_count == 5, rc, cleanup);
  195. cleanup:
  196. AST_VECTOR_FREE(&sv1);
  197. return rc;
  198. }
  199. static void cleanup_int(int element)
  200. {
  201. cleanup_count++;
  202. }
  203. AST_TEST_DEFINE(basic_ops_integer)
  204. {
  205. AST_VECTOR(test_struct, int) sv1;
  206. int rc = AST_TEST_PASS;
  207. int AAA = 1;
  208. int BBB = 3;
  209. int CCC = 5;
  210. int ZZZ = 26;
  211. switch (cmd) {
  212. case TEST_INIT:
  213. info->name = "basic_integer";
  214. info->category = "/main/vector/";
  215. info->summary = "Test integer vector basic ops";
  216. info->description = "Test integer vector basic ops";
  217. return AST_TEST_NOT_RUN;
  218. case TEST_EXECUTE:
  219. break;
  220. }
  221. ast_test_validate(test, AST_VECTOR_INIT(&sv1, 3) == 0);
  222. ast_test_validate_cleanup(test, sv1.max == 3, rc, cleanup);
  223. ast_test_validate_cleanup(test, AST_VECTOR_SIZE(&sv1) == 0, rc, cleanup);
  224. ast_test_validate_cleanup(test, AST_VECTOR_APPEND(&sv1, AAA) == 0, rc, cleanup);
  225. ast_test_validate_cleanup(test, sv1.max == 3, rc, cleanup);
  226. ast_test_validate_cleanup(test, AST_VECTOR_APPEND(&sv1, BBB) == 0, rc, cleanup);
  227. ast_test_validate_cleanup(test, sv1.max == 3, rc, cleanup);
  228. ast_test_validate_cleanup(test, AST_VECTOR_APPEND(&sv1, CCC) == 0, rc, cleanup);
  229. ast_test_validate_cleanup(test, AST_VECTOR_SIZE(&sv1) == 3, rc, cleanup);
  230. ast_test_validate_cleanup(test, sv1.max == 3, rc, cleanup);
  231. ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 0) == AAA, rc, cleanup);
  232. ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 1) == BBB, rc, cleanup);
  233. ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 2) == CCC, rc, cleanup);
  234. ast_test_validate_cleanup(test, AST_VECTOR_INSERT_AT(&sv1, 1, ZZZ) == 0, rc, cleanup);
  235. ast_test_validate_cleanup(test, sv1.max >= 4, rc, cleanup);
  236. ast_test_validate_cleanup(test, AST_VECTOR_SIZE(&sv1) == 4, rc, cleanup);
  237. ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 0) == AAA, rc, cleanup);
  238. ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 1) == ZZZ, rc, cleanup);
  239. ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 2) == BBB, rc, cleanup);
  240. ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 3) == CCC, rc, cleanup);
  241. ast_test_validate_cleanup(test, *(int *)AST_VECTOR_GET_CMP(&sv1, AAA, AST_VECTOR_ELEM_DEFAULT_CMP) == AAA, rc, cleanup);
  242. ast_test_validate_cleanup(test, *(int *)AST_VECTOR_GET_CMP(&sv1, ZZZ, AST_VECTOR_ELEM_DEFAULT_CMP) == ZZZ, rc, cleanup);
  243. /* Default first value */
  244. ast_test_validate_cleanup(test, AST_VECTOR_DEFAULT(&sv1, 1, CCC) == 0, rc, cleanup);
  245. ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 0) == CCC, rc, cleanup);
  246. ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 1) == ZZZ, rc, cleanup);
  247. /* Default all values */
  248. ast_test_validate_cleanup(test, AST_VECTOR_DEFAULT(&sv1, 0, AAA) == 0, rc, cleanup);
  249. ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 0) == AAA, rc, cleanup);
  250. ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 1) == AAA, rc, cleanup);
  251. ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 2) == AAA, rc, cleanup);
  252. ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 3) == AAA, rc, cleanup);
  253. /* Default more values than are currently in the vector */
  254. ast_test_validate_cleanup(test, AST_VECTOR_DEFAULT(&sv1, 5, BBB) == 0, rc, cleanup);
  255. ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 4) == BBB, rc, cleanup);
  256. /* Check getting index(es) */
  257. ast_test_validate_cleanup(test, AST_VECTOR_GET_INDEX(&sv1, BBB, AST_VECTOR_ELEM_DEFAULT_CMP) == 0, rc, cleanup);
  258. ast_test_validate_cleanup(test, AST_VECTOR_GET_INDEX_NTH(&sv1, 2, BBB, AST_VECTOR_ELEM_DEFAULT_CMP) == 1, rc, cleanup);
  259. ast_test_validate_cleanup(test, AST_VECTOR_GET_INDEX_NTH(&sv1, 4, BBB, AST_VECTOR_ELEM_DEFAULT_CMP) == 3, rc, cleanup);
  260. AST_VECTOR_FREE(&sv1);
  261. ast_test_validate(test, sv1.elems == NULL);
  262. ast_test_validate(test, sv1.current == 0);
  263. ast_test_validate(test, sv1.max == 0);
  264. ast_test_validate(test, AST_VECTOR_INIT(&sv1, 0) == 0);
  265. ast_test_validate_cleanup(test, sv1.max == 0, rc, cleanup);
  266. ast_test_validate_cleanup(test, AST_VECTOR_SIZE(&sv1) == 0, rc, cleanup);
  267. ast_test_validate_cleanup(test, AST_VECTOR_APPEND(&sv1, AAA) == 0, rc, cleanup);
  268. ast_test_validate_cleanup(test, AST_VECTOR_APPEND(&sv1, BBB) == 0, rc, cleanup);
  269. ast_test_validate_cleanup(test, AST_VECTOR_APPEND(&sv1, CCC) == 0, rc, cleanup);
  270. ast_test_validate_cleanup(test, sv1.max >= 3, rc, cleanup);
  271. ast_test_validate_cleanup(test, AST_VECTOR_SIZE(&sv1) == 3, rc, cleanup);
  272. ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 0) == AAA, rc, cleanup);
  273. ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 1) == BBB, rc, cleanup);
  274. ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 2) == CCC, rc, cleanup);
  275. /* Overwrite index 1 */
  276. ast_test_validate_cleanup(test, AST_VECTOR_REPLACE(&sv1, 1, ZZZ) == 0, rc, cleanup);
  277. ast_test_validate_cleanup(test, AST_VECTOR_SIZE(&sv1) == 3, rc, cleanup);
  278. ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 0) == AAA, rc, cleanup);
  279. ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 1) == ZZZ, rc, cleanup);
  280. ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 2) == CCC, rc, cleanup);
  281. /* Remove index 0 and bring the last entry into it's empty slot */
  282. ast_test_validate_cleanup(test, AST_VECTOR_REMOVE_UNORDERED(&sv1, 0) == 1, rc, cleanup);
  283. ast_test_validate_cleanup(test, AST_VECTOR_SIZE(&sv1) == 2, rc, cleanup);
  284. ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 0) == CCC, rc, cleanup);
  285. ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 1) == ZZZ, rc, cleanup);
  286. /* Replace 0 and 2 leaving 1 alone */
  287. ast_test_validate_cleanup(test, AST_VECTOR_REPLACE(&sv1, 0, AAA) == 0, rc, cleanup);
  288. ast_test_validate_cleanup(test, AST_VECTOR_REPLACE(&sv1, 2, CCC) == 0, rc, cleanup);
  289. ast_test_validate_cleanup(test, AST_VECTOR_SIZE(&sv1) == 3, rc, cleanup);
  290. ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 0) == AAA, rc, cleanup);
  291. ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 1) == ZZZ, rc, cleanup);
  292. ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 2) == CCC, rc, cleanup);
  293. /* Remove 1 and compact preserving order */
  294. ast_test_validate_cleanup(test, AST_VECTOR_REMOVE_ORDERED(&sv1, 1) == ZZZ, rc, cleanup);
  295. ast_test_validate_cleanup(test, AST_VECTOR_SIZE(&sv1) == 2, rc, cleanup);
  296. ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 0) == AAA, rc, cleanup);
  297. ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 1) == CCC, rc, cleanup);
  298. /* Equivalent of APPEND */
  299. ast_test_validate_cleanup(test, AST_VECTOR_REPLACE(&sv1, 2, ZZZ) == 0, rc, cleanup);
  300. ast_test_validate_cleanup(test, AST_VECTOR_SIZE(&sv1) == 3, rc, cleanup);
  301. /* This should work because we passing in the specific object to be removed */
  302. cleanup_count = 0;
  303. ast_test_validate_cleanup(test, AST_VECTOR_REMOVE_ELEM_ORDERED(&sv1, ZZZ, cleanup_int) == 0, rc, cleanup);
  304. ast_test_validate_cleanup(test, AST_VECTOR_SIZE(&sv1) == 2, rc, cleanup);
  305. ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 0) == AAA, rc, cleanup);
  306. ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 1) == CCC, rc, cleanup);
  307. ast_test_validate_cleanup(test, cleanup_count == 1, rc, cleanup);
  308. /* If we want a comparison by value, we need to pass in a comparison
  309. * function.
  310. */
  311. cleanup_count = 0;
  312. ast_test_validate_cleanup(test, AST_VECTOR_REMOVE_CMP_ORDERED(&sv1, AAA, AST_VECTOR_ELEM_DEFAULT_CMP, cleanup_int) == 0, rc, cleanup);
  313. ast_test_validate_cleanup(test, AST_VECTOR_SIZE(&sv1) == 1, rc, cleanup);
  314. ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 0) == CCC, rc, cleanup);
  315. ast_test_validate_cleanup(test, cleanup_count == 1, rc, cleanup);
  316. /* This element is gone so we shouldn't be able to find it or delete it again. */
  317. ast_test_validate_cleanup(test, AST_VECTOR_GET_CMP(&sv1, AAA, AST_VECTOR_ELEM_DEFAULT_CMP) == NULL, rc, cleanup);
  318. ast_test_validate_cleanup(test, AST_VECTOR_REMOVE_CMP_ORDERED(&sv1, AAA, AST_VECTOR_ELEM_DEFAULT_CMP, cleanup_int) != 0, rc, cleanup);
  319. /* CCC should still be there though */
  320. ast_test_validate_cleanup(test, *(int *)AST_VECTOR_GET_CMP(&sv1, CCC, AST_VECTOR_ELEM_DEFAULT_CMP) == CCC, rc, cleanup);
  321. cleanup:
  322. AST_VECTOR_FREE(&sv1);
  323. return rc;
  324. }
  325. static int visits;
  326. static int cb_match(void *obj, void *arg)
  327. {
  328. visits++;
  329. return strcmp(arg, obj) == 0 ? CMP_MATCH : 0;
  330. }
  331. static int cb_visits(void *obj, int v)
  332. {
  333. visits++;
  334. return visits == v ? CMP_STOP : 0;
  335. }
  336. AST_TEST_DEFINE(callbacks)
  337. {
  338. AST_VECTOR(, char *) sv1;
  339. typeof(sv1) *sv2 = NULL;
  340. int rc = AST_TEST_PASS;
  341. char *AAA = "AAA";
  342. char *AAA2 = "AAA";
  343. char *BBB = "BBB";
  344. char *CCC = "CCC";
  345. char *DEF = "default_value";
  346. switch (cmd) {
  347. case TEST_INIT:
  348. info->name = "callbacks";
  349. info->category = "/main/vector/";
  350. info->summary = "Test vector callback ops";
  351. info->description = "Test vector callback ops";
  352. return AST_TEST_NOT_RUN;
  353. case TEST_EXECUTE:
  354. break;
  355. }
  356. AST_VECTOR_INIT(&sv1, 32);
  357. AST_VECTOR_APPEND(&sv1, AAA);
  358. AST_VECTOR_APPEND(&sv1, BBB);
  359. AST_VECTOR_APPEND(&sv1, CCC);
  360. AST_VECTOR_APPEND(&sv1, AAA2);
  361. visits = 0;
  362. ast_test_validate_cleanup(test, AST_VECTOR_CALLBACK(&sv1, cb_match, DEF, "AAA") == AAA, rc, cleanup);
  363. ast_test_validate_cleanup(test, visits == 1, rc, cleanup);
  364. visits = 0;
  365. ast_test_validate_cleanup(test, AST_VECTOR_CALLBACK(&sv1, cb_match, DEF, "XYZ") == DEF, rc, cleanup);
  366. ast_test_validate_cleanup(test, visits == 4, rc, cleanup);
  367. visits = 0;
  368. ast_test_validate_cleanup(test, AST_VECTOR_CALLBACK(&sv1, cb_visits, DEF, 2) == DEF, rc, cleanup);
  369. ast_test_validate_cleanup(test, visits == 2, rc, cleanup);
  370. sv2 = AST_VECTOR_CALLBACK_MULTIPLE(&sv1, AST_VECTOR_MATCH_ALL);
  371. ast_test_validate_cleanup(test, AST_VECTOR_SIZE(sv2) == 4, rc, cleanup);
  372. ast_test_validate_cleanup(test, AST_VECTOR_GET(sv2, 0) == AAA, rc, cleanup);
  373. ast_test_validate_cleanup(test, AST_VECTOR_GET(sv2, 1) == BBB, rc, cleanup);
  374. ast_test_validate_cleanup(test, AST_VECTOR_GET(sv2, 2) == CCC, rc, cleanup);
  375. ast_test_validate_cleanup(test, AST_VECTOR_GET(sv2, 3) == AAA2, rc, cleanup);
  376. AST_VECTOR_PTR_FREE(sv2);
  377. AST_VECTOR_APPEND(&sv1, AAA);
  378. AST_VECTOR_APPEND(&sv1, BBB);
  379. AST_VECTOR_APPEND(&sv1, CCC);
  380. ast_test_validate_cleanup(test, AST_VECTOR_SIZE(&sv1) == 7, rc, cleanup);
  381. sv2 = AST_VECTOR_CALLBACK_MULTIPLE(&sv1, cb_match, "AAA");
  382. ast_test_validate_cleanup(test, AST_VECTOR_SIZE(sv2) == 3, rc, cleanup);
  383. ast_test_validate_cleanup(test, AST_VECTOR_GET(sv2, 0) == AAA, rc, cleanup);
  384. ast_test_validate_cleanup(test, AST_VECTOR_GET(sv2, 1) == AAA2, rc, cleanup);
  385. ast_test_validate_cleanup(test, AST_VECTOR_GET(sv2, 2) == AAA, rc, cleanup);
  386. cleanup:
  387. AST_VECTOR_FREE(&sv1);
  388. AST_VECTOR_PTR_FREE(sv2);
  389. return rc;
  390. }
  391. AST_TEST_DEFINE(locks)
  392. {
  393. AST_VECTOR_RW(, char *) sv1;
  394. int rc = AST_TEST_PASS;
  395. struct timespec ts;
  396. switch (cmd) {
  397. case TEST_INIT:
  398. info->name = "locks";
  399. info->category = "/main/vector/";
  400. info->summary = "Test vector locking ops";
  401. info->description = "Test vector locking ops";
  402. return AST_TEST_NOT_RUN;
  403. case TEST_EXECUTE:
  404. break;
  405. }
  406. /* We're not actually checking that locking works,
  407. * just that the macro expansions work
  408. */
  409. AST_VECTOR_RW_INIT(&sv1, 0);
  410. ast_test_validate_cleanup(test, AST_VECTOR_RW_RDLOCK(&sv1) == 0, rc, cleanup);
  411. ast_test_validate_cleanup(test, AST_VECTOR_RW_UNLOCK(&sv1) == 0, rc, cleanup);
  412. ast_test_validate_cleanup(test, AST_VECTOR_RW_WRLOCK(&sv1) == 0, rc, cleanup);
  413. ast_test_validate_cleanup(test, AST_VECTOR_RW_UNLOCK(&sv1) == 0, rc, cleanup);
  414. ast_test_validate_cleanup(test, AST_VECTOR_RW_RDLOCK_TRY(&sv1) == 0, rc, cleanup);
  415. ast_test_validate_cleanup(test, AST_VECTOR_RW_WRLOCK_TRY(&sv1) != 0, rc, cleanup);
  416. ast_test_validate_cleanup(test, AST_VECTOR_RW_UNLOCK(&sv1) == 0, rc, cleanup);
  417. ast_test_validate_cleanup(test, AST_VECTOR_RW_WRLOCK_TRY(&sv1) == 0, rc, cleanup);
  418. ast_test_validate_cleanup(test, AST_VECTOR_RW_UNLOCK(&sv1) == 0, rc, cleanup);
  419. ts.tv_nsec = 0;
  420. ts.tv_sec = 2;
  421. ast_test_validate_cleanup(test, AST_VECTOR_RW_RDLOCK_TIMED(&sv1, &ts) == 0, rc, cleanup);
  422. ast_test_validate_cleanup(test, AST_VECTOR_RW_WRLOCK_TIMED(&sv1, &ts) != 0, rc, cleanup);
  423. ast_test_validate_cleanup(test, AST_VECTOR_RW_UNLOCK(&sv1) == 0, rc, cleanup);
  424. ast_test_validate_cleanup(test, AST_VECTOR_RW_WRLOCK_TIMED(&sv1, &ts) == 0, rc, cleanup);
  425. ast_test_validate_cleanup(test, AST_VECTOR_RW_UNLOCK(&sv1) == 0, rc, cleanup);
  426. cleanup:
  427. AST_VECTOR_RW_FREE(&sv1);
  428. return rc;
  429. }
  430. static int unload_module(void)
  431. {
  432. AST_TEST_UNREGISTER(locks);
  433. AST_TEST_UNREGISTER(callbacks);
  434. AST_TEST_UNREGISTER(basic_ops_integer);
  435. AST_TEST_UNREGISTER(basic_ops);
  436. return 0;
  437. }
  438. static int load_module(void)
  439. {
  440. AST_TEST_REGISTER(locks);
  441. AST_TEST_REGISTER(callbacks);
  442. AST_TEST_REGISTER(basic_ops_integer);
  443. AST_TEST_REGISTER(basic_ops);
  444. return AST_MODULE_LOAD_SUCCESS;
  445. }
  446. AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Vector test module");