1 #include <ccan/tal/tal.h>
2 #include <ccan/tal/tal.c>
3 #include <ccan/tap/tap.h>
5 static int alloc_count, when_to_fail, err_count;
8 static void *failing_alloc(size_t len)
10 if (alloc_count++ == when_to_fail)
12 /* once we've failed once, it shouldn't ask again (steal can though). */
13 assert(stealing || alloc_count <= when_to_fail);
18 static void *failing_realloc(void *p, size_t len)
20 if (alloc_count++ == when_to_fail)
23 return realloc(p, len);
27 static void nofail_on_error(const char *msg)
29 diag("ERROR: %s", msg);
33 static void destroy_p(void *p)
44 tal_set_backend(failing_alloc, failing_realloc, NULL, nofail_on_error);
46 /* Fail at each possible point in an allocation. */
47 when_to_fail = err_count = 0;
53 ok1(alloc_count >= 1);
54 ok1(when_to_fail > 1);
55 ok1(err_count == when_to_fail - 1);
58 when_to_fail = err_count = 0;
64 ok1(alloc_count >= 1);
65 ok1(when_to_fail > 1);
66 ok1(err_count == when_to_fail - 1);
68 /* Now during resize. */
70 when_to_fail = err_count = 0;
73 if (tal_resize(&c1, 100))
75 /* Failing alloc will not change pointer. */
79 ok1(alloc_count == 1);
80 ok1(when_to_fail == 1);
82 /* Make sure it's really resized. */
85 /* Now for second child. */
86 when_to_fail = err_count = 0;
92 ok1(alloc_count >= 1);
93 ok1(when_to_fail > 1);
94 /* Note: adding a child will fall through if group alloc fails. */
95 ok1 (err_count == when_to_fail - 1 || err_count == when_to_fail);
97 /* Now while adding a destructor. */
98 when_to_fail = err_count = 0;
101 success = tal_add_destructor(p, destroy_p);
104 ok1(alloc_count >= 1);
105 ok1(when_to_fail > 1);
106 ok1(err_count == when_to_fail - 1);
108 /* Now while adding a name. */
109 when_to_fail = err_count = 0;
111 const char name[] = "some name";
113 success = tal_set_name(p, name);
116 ok1(alloc_count >= 1);
117 ok1(when_to_fail > 1);
118 ok1(err_count == when_to_fail - 1);
120 /* Now while stealing. */
122 when_to_fail = err_count = 0;
125 success = tal_steal(c2, c1) != NULL;
128 ok1(alloc_count >= 1);
129 ok1(when_to_fail > 1);
130 ok1(err_count == when_to_fail - 1);
132 /* Now stealing with more children (more coverage). */
139 /* Now steal again. */
140 when_to_fail = err_count = 0;
143 success = tal_steal(c2, c1) != NULL;
146 ok1(alloc_count >= 1);
147 ok1(when_to_fail > 1);
148 ok1(err_count == when_to_fail - 1);
151 return exit_status();