check_std_c_rbtree.c 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363
  1. /*
  2. * libcsync -- a library to sync a directory with another
  3. *
  4. * Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
  5. *
  6. * This library is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 2.1 of the License, or (at your option) any later version.
  10. *
  11. * This library is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public
  17. * License along with this library; if not, write to the Free Software
  18. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  19. */
  20. #include <errno.h>
  21. #include <time.h>
  22. #include "torture.h"
  23. #include "std/c_alloc.h"
  24. #include "std/c_rbtree.h"
  25. typedef struct test_s {
  26. int key;
  27. int number;
  28. } test_t;
  29. static int data_cmp(const void *key, const void *data) {
  30. test_t *a, *b;
  31. a = (test_t *) key;
  32. b = (test_t *) data;
  33. if (a->key < b->key) {
  34. return -1;
  35. } else if (a->key > b->key) {
  36. return 1;
  37. }
  38. return 0;
  39. }
  40. static int key_cmp(const void *key, const void *data) {
  41. int a;
  42. test_t *b;
  43. a = POINTER_TO_INT(key);
  44. b = (test_t *) data;
  45. if (a < b->key) {
  46. return -1;
  47. } else if (a > b->key) {
  48. return 1;
  49. }
  50. return 0;
  51. }
  52. static int visitor(void *obj, void *data) {
  53. test_t *a;
  54. test_t *b;
  55. a = (test_t *) obj;
  56. b = (test_t *) data;
  57. if (a->key == b->key) {
  58. a->number = 42;
  59. }
  60. return 0;
  61. }
  62. static void destructor(void *data) {
  63. test_t *freedata = NULL;
  64. freedata = (test_t *) data;
  65. SAFE_FREE(freedata);
  66. }
  67. static void setup(void **state) {
  68. c_rbtree_t *tree = NULL;
  69. c_rbtree_create(&tree, key_cmp, data_cmp);
  70. *state = tree;
  71. }
  72. static void setup_complete_tree(void **state) {
  73. c_rbtree_t *tree = NULL;
  74. int i = 0;
  75. int rc;
  76. c_rbtree_create(&tree, key_cmp, data_cmp);
  77. for (i = 0; i < 100; i++) {
  78. test_t *testdata = NULL;
  79. testdata = c_malloc(sizeof(test_t));
  80. assert_non_null(testdata);
  81. testdata->key = i;
  82. rc = c_rbtree_insert(tree, (void *) testdata);
  83. assert_int_equal(rc, 0);
  84. }
  85. *state = tree;
  86. }
  87. static void teardown(void **state) {
  88. c_rbtree_t *tree = *state;
  89. c_rbtree_destroy(tree, destructor);
  90. c_rbtree_free(tree);
  91. *state = NULL;
  92. }
  93. static void check_c_rbtree_create_free(void **state)
  94. {
  95. c_rbtree_t *tree = NULL;
  96. int rc;
  97. (void) state; /* unused */
  98. c_rbtree_create(&tree, key_cmp, data_cmp);
  99. assert_int_equal(tree->size, 0);
  100. rc = c_rbtree_free(tree);
  101. assert_int_equal(rc, 0);
  102. }
  103. static void check_c_rbtree_free_null(void **state)
  104. {
  105. int rc;
  106. (void) state; /* unused */
  107. rc = c_rbtree_free(NULL);
  108. assert_int_equal(rc, -1);
  109. }
  110. static void check_c_rbtree_insert_delete(void **state)
  111. {
  112. c_rbtree_t *tree = NULL;
  113. c_rbnode_t *node = NULL;
  114. test_t *testdata = NULL;
  115. int rc;
  116. (void) state; /* unused */
  117. c_rbtree_create(&tree, key_cmp, data_cmp);
  118. testdata = malloc(sizeof(test_t));
  119. testdata->key = 42;
  120. rc = c_rbtree_insert(tree, (void *) testdata);
  121. assert_int_equal(rc, 0);
  122. node = c_rbtree_head(tree);
  123. assert_non_null(node);
  124. testdata = c_rbtree_node_data(node);
  125. SAFE_FREE(testdata);
  126. rc = c_rbtree_node_delete(node);
  127. assert_int_equal(rc, 0);
  128. c_rbtree_free(tree);
  129. }
  130. static void check_c_rbtree_insert_random(void **state)
  131. {
  132. c_rbtree_t *tree = *state;
  133. int i = 0, rc;
  134. for (i = 0; i < 100; i++) {
  135. test_t *testdata = NULL;
  136. testdata = malloc(sizeof(test_t));
  137. assert_non_null(testdata);
  138. testdata->key = i;
  139. rc = c_rbtree_insert(tree, testdata);
  140. assert_int_equal(rc, 0);
  141. }
  142. rc = c_rbtree_check_sanity(tree);
  143. assert_int_equal(rc, 0);
  144. }
  145. static void check_c_rbtree_insert_duplicate(void **state)
  146. {
  147. c_rbtree_t *tree = *state;
  148. test_t *testdata;
  149. int rc;
  150. testdata = malloc(sizeof(test_t));
  151. assert_non_null(testdata);
  152. testdata->key = 42;
  153. rc = c_rbtree_insert(tree, (void *) testdata);
  154. assert_int_equal(rc, 0);
  155. /* add again */
  156. testdata = malloc(sizeof(test_t));
  157. assert_non_null(testdata);
  158. testdata->key = 42;
  159. /* check for duplicate */
  160. rc = c_rbtree_insert(tree, (void *) testdata);
  161. assert_int_equal(rc, 1);
  162. free(testdata);
  163. }
  164. static void check_c_rbtree_find(void **state)
  165. {
  166. c_rbtree_t *tree = *state;
  167. int rc, i = 42;
  168. c_rbnode_t *node;
  169. test_t *testdata;
  170. rc = c_rbtree_check_sanity(tree);
  171. assert_int_equal(rc, 0);
  172. /* find the node with the key 42 */
  173. node = c_rbtree_find(tree, (void *) &i);
  174. assert_non_null(node);
  175. testdata = (test_t *) c_rbtree_node_data(node);
  176. assert_int_equal(testdata->key, 42);
  177. }
  178. static void check_c_rbtree_delete(void **state)
  179. {
  180. c_rbtree_t *tree = *state;
  181. int rc, i = 42;
  182. c_rbnode_t *node = NULL;
  183. test_t *freedata = NULL;
  184. rc = c_rbtree_check_sanity(tree);
  185. assert_int_equal(rc, 0);
  186. node = c_rbtree_find(tree, (void *) &i);
  187. assert_non_null(node);
  188. freedata = (test_t *) c_rbtree_node_data(node);
  189. free(freedata);
  190. rc = c_rbtree_node_delete(node);
  191. assert_int_equal(rc, 0);
  192. rc = c_rbtree_check_sanity(tree);
  193. assert_int_equal(rc, 0);
  194. }
  195. static void check_c_rbtree_walk(void **state)
  196. {
  197. c_rbtree_t *tree = *state;
  198. int rc, i = 42;
  199. test_t *testdata;
  200. c_rbnode_t *node;
  201. rc = c_rbtree_check_sanity(tree);
  202. assert_int_equal(rc, 0);
  203. testdata = (test_t *) c_malloc(sizeof(test_t));
  204. testdata->key = 42;
  205. rc = c_rbtree_walk(tree, testdata, visitor);
  206. assert_int_equal(rc, 0);
  207. /* find the node with the key 42 */
  208. node = c_rbtree_find(tree, (void *) &i);
  209. assert_non_null(node);
  210. free(testdata);
  211. testdata = (test_t *) c_rbtree_node_data(node);
  212. assert_int_equal(testdata->number, 42);
  213. }
  214. static void check_c_rbtree_walk_null(void **state)
  215. {
  216. c_rbtree_t *tree = *state;
  217. int rc, i = 42;
  218. test_t *testdata;
  219. c_rbnode_t *node;
  220. rc = c_rbtree_check_sanity(tree);
  221. assert_int_equal(rc, 0);
  222. testdata = (test_t *) malloc(sizeof(test_t));
  223. testdata->key = 42;
  224. rc = c_rbtree_walk(NULL, testdata, visitor);
  225. assert_int_equal(rc, -1);
  226. assert_int_equal(errno, EINVAL);
  227. rc = c_rbtree_walk(tree, NULL, visitor);
  228. assert_int_equal(rc, -1);
  229. assert_int_equal(errno, EINVAL);
  230. rc = c_rbtree_walk(tree, testdata, NULL);
  231. assert_int_equal(rc, -1);
  232. assert_int_equal(errno, EINVAL);
  233. /* find the node with the key 42 */
  234. node = c_rbtree_find(tree, (void *) &i);
  235. assert_non_null(node);
  236. free(testdata);
  237. }
  238. static void check_c_rbtree_dup(void **state)
  239. {
  240. c_rbtree_t *tree = *state;
  241. c_rbtree_t *duptree = NULL;
  242. int rc = -1;
  243. duptree = c_rbtree_dup(tree);
  244. assert_non_null(duptree);
  245. rc = c_rbtree_check_sanity(duptree);
  246. assert_int_equal(rc, 0);
  247. c_rbtree_free(duptree);
  248. }
  249. #if 0
  250. static void check_c_rbtree_x)
  251. {
  252. int rc = -1;
  253. rc = c_rbtree_check_sanity(tree);
  254. fail_unless(rc == 0, "c_rbtree_check_sanity failed with return code %d", rc);
  255. }
  256. #endif
  257. int torture_run_tests(void)
  258. {
  259. const UnitTest tests[] = {
  260. unit_test(check_c_rbtree_create_free),
  261. unit_test(check_c_rbtree_free_null),
  262. unit_test(check_c_rbtree_insert_delete),
  263. unit_test_setup_teardown(check_c_rbtree_insert_random, setup, teardown),
  264. unit_test_setup_teardown(check_c_rbtree_insert_duplicate, setup, teardown),
  265. unit_test_setup_teardown(check_c_rbtree_find, setup_complete_tree, teardown),
  266. unit_test_setup_teardown(check_c_rbtree_delete, setup_complete_tree, teardown),
  267. unit_test_setup_teardown(check_c_rbtree_walk, setup_complete_tree, teardown),
  268. unit_test_setup_teardown(check_c_rbtree_walk_null, setup_complete_tree, teardown),
  269. unit_test_setup_teardown(check_c_rbtree_dup, setup_complete_tree, teardown),
  270. };
  271. return run_tests(tests);
  272. }