rbtree: fix memory leak in tests
[ccan] / ccan / rbtree / test / run.c
1 #include <ccan/rbtree/rbtree.c>
2 #include <ccan/tap/tap.h>
3 #include <ccan/talloc/talloc.h>
4 #include <string.h>
5
6 static void *insert_callback(void *param, void *data)
7 {
8         ok1(data == param);
9         return talloc_strdup(NULL, "insert_callback");
10 }
11
12 int main(void)
13 {
14         trbt_tree_t *rb;
15         void *ctx = talloc_strdup(NULL, "toplevel");
16         char *data, *data2;
17
18         /* This is how many tests you plan to run */
19         plan_tests(19);
20
21         rb = trbt_create(ctx, 0);
22         ok1(rb);
23         ok1(talloc_is_parent(rb, ctx));
24
25         /* Failed lookup. */
26         ok1(trbt_lookup32(rb, 0) == NULL);
27         ok1(trbt_lookup32(rb, -1) == NULL);
28
29         /* Insert, should steal node onto data. */
30         data = talloc_strdup(NULL, "data");
31         ok1(trbt_insert32(rb, 0, data) == NULL);
32         ok1(trbt_lookup32(rb, 0) == data);
33         ok1(trbt_lookup32(rb, -1) == NULL);
34
35         /* Thus, freeing the data will delete the node. */
36         talloc_free(data);
37         ok1(trbt_lookup32(rb, 0) == NULL);
38
39         /* Try again. */
40         data = talloc_strdup(NULL, "data");
41         ok1(trbt_insert32(rb, 0, data) == NULL);
42
43         /* Another insert should return old one. */
44         data2 = talloc_strdup(NULL, "data2");
45         ok1(trbt_insert32(rb, 0, data2) == data);
46         ok1(trbt_lookup32(rb, 0) == data2);
47
48         /* Freeing old data has no effect. */
49         talloc_free(data);
50         ok1(trbt_lookup32(rb, 0) == data2);
51
52         /* Insert with callback on non-existing. */
53         trbt_insert32_callback(rb, 1, insert_callback, NULL);
54         ok1(strcmp(trbt_lookup32(rb, 1), "insert_callback") == 0);
55         /* Insert with callback on existing. */
56         trbt_insert32_callback(rb, 0, insert_callback, data2);
57         ok1(strcmp(trbt_lookup32(rb, 0), "insert_callback") == 0);
58         talloc_free(data2);
59
60         /* Delete. */
61         data2 = trbt_lookup32(rb, 1);
62         trbt_delete32(rb, 1);
63         ok1(trbt_lookup32(rb, 1) == NULL);
64         ok1(trbt_lookup32(rb, 0));
65         talloc_free(data2);
66
67         /* This should free everything. */
68         talloc_free(trbt_lookup32(rb, 0));
69         talloc_free(rb);
70
71         /* No memory leaks? */
72         ok1(talloc_total_blocks(ctx) == 1);
73         talloc_free(ctx);
74
75         /* This exits depending on whether all tests passed */
76         return exit_status();
77 }