2 Unix SMB/CIFS implementation.
4 local testing of talloc routines.
6 Copyright (C) Andrew Tridgell 2004
8 ** NOTE! The following LGPL license applies to the talloc
9 ** library. This does NOT imply that all of Samba is released
12 This library is free software; you can redistribute it and/or
13 modify it under the terms of the GNU Lesser General Public
14 License as published by the Free Software Foundation; either
15 version 3 of the License, or (at your option) any later version.
17 This library is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 Lesser General Public License for more details.
22 You should have received a copy of the GNU Lesser General Public
23 License along with this library; if not, see <http://www.gnu.org/licenses/>.
32 static struct timeval timeval_current(void)
35 gettimeofday(&tv, NULL);
39 static double timeval_elapsed(struct timeval *tv)
41 struct timeval tv2 = timeval_current();
42 return (tv2.tv_sec - tv->tv_sec) +
43 (tv2.tv_usec - tv->tv_usec)*1.0e-6;
46 #define torture_assert(test, expr, str) if (!(expr)) { \
47 printf("failure: %s [\n%s: Expression %s failed: %s\n]\n", \
48 test, __location__, #expr, str); \
52 #define torture_assert_str_equal(test, arg1, arg2, desc) \
53 if (strcmp(arg1, arg2)) { \
54 printf("failure: %s [\n%s: Expected %s, got %s: %s\n]\n", \
55 test, __location__, arg1, arg2, desc); \
68 #define CHECK_SIZE(test, ptr, tsize) do { \
69 if (talloc_total_size(ptr) != (tsize)) { \
70 printf("failed: %s [\nwrong '%s' tree size: got %u expected %u\n]\n", \
72 (unsigned)talloc_total_size(ptr), \
74 talloc_report_full(ptr, stdout); \
79 #define CHECK_BLOCKS(test, ptr, tblocks) do { \
80 if (talloc_total_blocks(ptr) != (tblocks)) { \
81 printf("failed: %s [\nwrong '%s' tree blocks: got %u expected %u\n]\n", \
83 (unsigned)talloc_total_blocks(ptr), \
85 talloc_report_full(ptr, stdout); \
90 #define CHECK_PARENT(test, ptr, parent) do { \
91 if (talloc_parent(ptr) != (parent)) { \
92 printf("failed: %s [\n'%s' has wrong parent: got %p expected %p\n]\n", \
96 talloc_report_full(ptr, stdout); \
97 talloc_report_full(parent, stdout); \
98 talloc_report_full(NULL, stdout); \
107 static bool test_ref1(void)
109 void *root, *p1, *p2, *ref, *r1;
111 printf("test: ref1\n# SINGLE REFERENCE FREE\n");
113 root = talloc_named_const(NULL, 0, "root");
114 p1 = talloc_named_const(root, 1, "p1");
115 p2 = talloc_named_const(p1, 1, "p2");
116 talloc_named_const(p1, 1, "x1");
117 talloc_named_const(p1, 2, "x2");
118 talloc_named_const(p1, 3, "x3");
120 r1 = talloc_named_const(root, 1, "r1");
121 ref = talloc_reference(r1, p2);
122 talloc_report_full(root, stderr);
124 CHECK_BLOCKS("ref1", p1, 5);
125 CHECK_BLOCKS("ref1", p2, 1);
126 CHECK_BLOCKS("ref1", r1, 2);
128 fprintf(stderr, "Freeing p2\n");
130 talloc_report_full(root, stderr);
132 CHECK_BLOCKS("ref1", p1, 5);
133 CHECK_BLOCKS("ref1", p2, 1);
134 CHECK_BLOCKS("ref1", r1, 1);
136 fprintf(stderr, "Freeing p1\n");
138 talloc_report_full(root, stderr);
140 CHECK_BLOCKS("ref1", r1, 1);
142 fprintf(stderr, "Freeing r1\n");
144 talloc_report_full(NULL, stderr);
146 fprintf(stderr, "Testing NULL\n");
147 if (talloc_reference(root, NULL)) {
151 CHECK_BLOCKS("ref1", root, 1);
153 CHECK_SIZE("ref1", root, 0);
156 printf("success: ref1\n");
163 static bool test_ref2(void)
165 void *root, *p1, *p2, *ref, *r1;
167 printf("test: ref2\n# DOUBLE REFERENCE FREE\n");
168 root = talloc_named_const(NULL, 0, "root");
169 p1 = talloc_named_const(root, 1, "p1");
170 talloc_named_const(p1, 1, "x1");
171 talloc_named_const(p1, 1, "x2");
172 talloc_named_const(p1, 1, "x3");
173 p2 = talloc_named_const(p1, 1, "p2");
175 r1 = talloc_named_const(root, 1, "r1");
176 ref = talloc_reference(r1, p2);
177 talloc_report_full(root, stderr);
179 CHECK_BLOCKS("ref2", p1, 5);
180 CHECK_BLOCKS("ref2", p2, 1);
181 CHECK_BLOCKS("ref2", r1, 2);
183 fprintf(stderr, "Freeing ref\n");
185 talloc_report_full(root, stderr);
187 CHECK_BLOCKS("ref2", p1, 5);
188 CHECK_BLOCKS("ref2", p2, 1);
189 CHECK_BLOCKS("ref2", r1, 1);
191 fprintf(stderr, "Freeing p2\n");
193 talloc_report_full(root, stderr);
195 CHECK_BLOCKS("ref2", p1, 4);
196 CHECK_BLOCKS("ref2", r1, 1);
198 fprintf(stderr, "Freeing p1\n");
200 talloc_report_full(root, stderr);
202 CHECK_BLOCKS("ref2", r1, 1);
204 fprintf(stderr, "Freeing r1\n");
206 talloc_report_full(root, stderr);
208 CHECK_SIZE("ref2", root, 0);
211 printf("success: ref2\n");
218 static bool test_ref3(void)
220 void *root, *p1, *p2, *ref, *r1;
222 printf("test: ref3\n# PARENT REFERENCE FREE\n");
224 root = talloc_named_const(NULL, 0, "root");
225 p1 = talloc_named_const(root, 1, "p1");
226 p2 = talloc_named_const(root, 1, "p2");
227 r1 = talloc_named_const(p1, 1, "r1");
228 ref = talloc_reference(p2, r1);
229 talloc_report_full(root, stderr);
231 CHECK_BLOCKS("ref3", p1, 2);
232 CHECK_BLOCKS("ref3", p2, 2);
233 CHECK_BLOCKS("ref3", r1, 1);
235 fprintf(stderr, "Freeing p1\n");
237 talloc_report_full(root, stderr);
239 CHECK_BLOCKS("ref3", p2, 2);
240 CHECK_BLOCKS("ref3", r1, 1);
242 fprintf(stderr, "Freeing p2\n");
244 talloc_report_full(root, stderr);
246 CHECK_SIZE("ref3", root, 0);
250 printf("success: ref3\n");
257 static bool test_ref4(void)
259 void *root, *p1, *p2, *ref, *r1;
261 printf("test: ref4\n# REFERRER REFERENCE FREE\n");
263 root = talloc_named_const(NULL, 0, "root");
264 p1 = talloc_named_const(root, 1, "p1");
265 talloc_named_const(p1, 1, "x1");
266 talloc_named_const(p1, 1, "x2");
267 talloc_named_const(p1, 1, "x3");
268 p2 = talloc_named_const(p1, 1, "p2");
270 r1 = talloc_named_const(root, 1, "r1");
271 ref = talloc_reference(r1, p2);
272 talloc_report_full(root, stderr);
274 CHECK_BLOCKS("ref4", p1, 5);
275 CHECK_BLOCKS("ref4", p2, 1);
276 CHECK_BLOCKS("ref4", r1, 2);
278 fprintf(stderr, "Freeing r1\n");
280 talloc_report_full(root, stderr);
282 CHECK_BLOCKS("ref4", p1, 5);
283 CHECK_BLOCKS("ref4", p2, 1);
285 fprintf(stderr, "Freeing p2\n");
287 talloc_report_full(root, stderr);
289 CHECK_BLOCKS("ref4", p1, 4);
291 fprintf(stderr, "Freeing p1\n");
293 talloc_report_full(root, stderr);
295 CHECK_SIZE("ref4", root, 0);
299 printf("success: ref4\n");
307 static bool test_unlink1(void)
309 void *root, *p1, *p2, *ref, *r1;
311 printf("test: unlink\n# UNLINK\n");
313 root = talloc_named_const(NULL, 0, "root");
314 p1 = talloc_named_const(root, 1, "p1");
315 talloc_named_const(p1, 1, "x1");
316 talloc_named_const(p1, 1, "x2");
317 talloc_named_const(p1, 1, "x3");
318 p2 = talloc_named_const(p1, 1, "p2");
320 r1 = talloc_named_const(p1, 1, "r1");
321 ref = talloc_reference(r1, p2);
322 talloc_report_full(root, stderr);
324 CHECK_BLOCKS("unlink", p1, 7);
325 CHECK_BLOCKS("unlink", p2, 1);
326 CHECK_BLOCKS("unlink", r1, 2);
328 fprintf(stderr, "Unreferencing r1\n");
329 talloc_unlink(r1, p2);
330 talloc_report_full(root, stderr);
332 CHECK_BLOCKS("unlink", p1, 6);
333 CHECK_BLOCKS("unlink", p2, 1);
334 CHECK_BLOCKS("unlink", r1, 1);
336 fprintf(stderr, "Freeing p1\n");
338 talloc_report_full(root, stderr);
340 CHECK_SIZE("unlink", root, 0);
344 printf("success: unlink\n");
348 static int fail_destructor(void *ptr)
354 miscellaneous tests to try to get a higher test coverage percentage
356 static bool test_misc(void)
363 printf("test: misc\n# MISCELLANEOUS\n");
365 root = talloc_new(NULL);
367 p1 = talloc_size(root, 0x7fffffff);
368 torture_assert("misc", !p1, "failed: large talloc allowed\n");
370 p1 = talloc_strdup(root, "foo");
371 talloc_increase_ref_count(p1);
372 talloc_increase_ref_count(p1);
373 talloc_increase_ref_count(p1);
374 CHECK_BLOCKS("misc", p1, 1);
375 CHECK_BLOCKS("misc", root, 2);
377 CHECK_BLOCKS("misc", p1, 1);
378 CHECK_BLOCKS("misc", root, 2);
379 talloc_unlink(NULL, p1);
380 CHECK_BLOCKS("misc", p1, 1);
381 CHECK_BLOCKS("misc", root, 2);
382 p2 = talloc_strdup(p1, "foo");
383 torture_assert("misc", talloc_unlink(root, p2) == -1,
384 "failed: talloc_unlink() of non-reference context should return -1\n");
385 torture_assert("misc", talloc_unlink(p1, p2) == 0,
386 "failed: talloc_unlink() of parent should succeed\n");
388 CHECK_BLOCKS("misc", p1, 1);
389 CHECK_BLOCKS("misc", root, 2);
391 name = talloc_set_name(p1, "my name is %s", "foo");
392 torture_assert_str_equal("misc", talloc_get_name(p1), "my name is foo",
393 "failed: wrong name after talloc_set_name(my name is foo)");
394 CHECK_BLOCKS("misc", p1, 2);
395 CHECK_BLOCKS("misc", root, 3);
397 talloc_set_name_const(p1, NULL);
398 torture_assert_str_equal ("misc", talloc_get_name(p1), "UNNAMED",
399 "failed: wrong name after talloc_set_name(NULL)");
400 CHECK_BLOCKS("misc", p1, 2);
401 CHECK_BLOCKS("misc", root, 3);
403 torture_assert("misc", talloc_free(NULL) == -1,
404 "talloc_free(NULL) should give -1\n");
406 talloc_set_destructor(p1, fail_destructor);
407 torture_assert("misc", talloc_free(p1) == -1,
408 "Failed destructor should cause talloc_free to fail\n");
409 talloc_set_destructor(p1, NULL);
411 talloc_report(root, stderr);
414 p2 = (char *)talloc_zero_size(p1, 20);
415 torture_assert("misc", p2[19] == 0, "Failed to give zero memory\n");
418 torture_assert("misc", talloc_strdup(root, NULL) == NULL,
419 "failed: strdup on NULL should give NULL\n");
421 p2 = talloc_strndup(p1, "foo", 2);
422 torture_assert("misc", strcmp("fo", p2) == 0,
423 "strndup doesn't work\n");
424 p2 = talloc_asprintf_append_buffer(p2, "o%c", 'd');
425 torture_assert("misc", strcmp("food", p2) == 0,
426 "talloc_asprintf_append_buffer doesn't work\n");
427 CHECK_BLOCKS("misc", p2, 1);
428 CHECK_BLOCKS("misc", p1, 3);
430 p2 = talloc_asprintf_append_buffer(NULL, "hello %s", "world");
431 torture_assert("misc", strcmp("hello world", p2) == 0,
432 "talloc_asprintf_append_buffer doesn't work\n");
433 CHECK_BLOCKS("misc", p2, 1);
434 CHECK_BLOCKS("misc", p1, 3);
437 d = talloc_array(p1, double, 0x20000000);
438 torture_assert("misc", !d, "failed: integer overflow not detected\n");
440 d = talloc_realloc(p1, d, double, 0x20000000);
441 torture_assert("misc", !d, "failed: integer overflow not detected\n");
444 CHECK_BLOCKS("misc", root, 1);
446 p1 = talloc_named(root, 100, "%d bytes", 100);
447 CHECK_BLOCKS("misc", p1, 2);
448 CHECK_BLOCKS("misc", root, 3);
449 talloc_unlink(root, p1);
451 p1 = talloc_init("%d bytes", 200);
452 p2 = talloc_asprintf(p1, "my test '%s'", "string");
453 torture_assert_str_equal("misc", p2, "my test 'string'",
454 "failed: talloc_asprintf(\"my test '%%s'\", \"string\") gave: \"%s\"");
455 CHECK_BLOCKS("misc", p1, 3);
456 CHECK_SIZE("misc", p2, 17);
457 CHECK_BLOCKS("misc", root, 1);
458 talloc_unlink(NULL, p1);
460 p1 = talloc_named_const(root, 10, "p1");
461 p2 = (char *)talloc_named_const(root, 20, "p2");
462 (void)talloc_reference(p1, p2);
463 talloc_report_full(root, stderr);
464 talloc_unlink(root, p2);
465 talloc_report_full(root, stderr);
466 CHECK_BLOCKS("misc", p2, 1);
467 CHECK_BLOCKS("misc", p1, 2);
468 CHECK_BLOCKS("misc", root, 3);
469 talloc_unlink(p1, p2);
470 talloc_unlink(root, p1);
472 p1 = talloc_named_const(root, 10, "p1");
473 p2 = (char *)talloc_named_const(root, 20, "p2");
474 (void)talloc_reference(NULL, p2);
475 talloc_report_full(root, stderr);
476 talloc_unlink(root, p2);
477 talloc_report_full(root, stderr);
478 CHECK_BLOCKS("misc", p2, 1);
479 CHECK_BLOCKS("misc", p1, 1);
480 CHECK_BLOCKS("misc", root, 2);
481 talloc_unlink(NULL, p2);
482 talloc_unlink(root, p1);
484 /* Test that talloc_unlink is a no-op */
486 torture_assert("misc", talloc_unlink(root, NULL) == -1,
487 "failed: talloc_unlink(root, NULL) == -1\n");
489 talloc_report(root, stderr);
490 talloc_report(NULL, stderr);
492 CHECK_SIZE("misc", root, 0);
496 CHECK_SIZE("misc", NULL, 0);
498 talloc_enable_leak_report();
499 talloc_enable_leak_report_full();
501 printf("success: misc\n");
510 static bool test_realloc(void)
512 void *root, *p1, *p2;
514 printf("test: realloc\n# REALLOC\n");
516 root = talloc_new(NULL);
518 p1 = talloc_size(root, 10);
519 CHECK_SIZE("realloc", p1, 10);
521 p1 = talloc_realloc_size(NULL, p1, 20);
522 CHECK_SIZE("realloc", p1, 20);
526 p2 = talloc_realloc_size(p1, NULL, 30);
530 p2 = talloc_realloc_size(p1, p2, 40);
532 CHECK_SIZE("realloc", p2, 40);
533 CHECK_SIZE("realloc", root, 60);
534 CHECK_BLOCKS("realloc", p1, 4);
536 p1 = talloc_realloc_size(NULL, p1, 20);
537 CHECK_SIZE("realloc", p1, 60);
539 talloc_increase_ref_count(p2);
540 torture_assert("realloc", talloc_realloc_size(NULL, p2, 5) == NULL,
541 "failed: talloc_realloc() on a referenced pointer should fail\n");
542 CHECK_BLOCKS("realloc", p1, 4);
544 talloc_realloc_size(NULL, p2, 0);
545 talloc_realloc_size(NULL, p2, 0);
546 CHECK_BLOCKS("realloc", p1, 3);
548 torture_assert("realloc", talloc_realloc_size(NULL, p1, 0x7fffffff) == NULL,
549 "failed: oversize talloc should fail\n");
551 talloc_realloc_size(NULL, p1, 0);
553 CHECK_BLOCKS("realloc", root, 1);
554 CHECK_SIZE("realloc", root, 0);
558 printf("success: realloc\n");
564 test realloc with a child
566 static bool test_realloc_child(void)
574 struct el2 **list, **list2, **list3;
577 printf("test: REALLOC WITH CHILD\n");
579 root = talloc_new(NULL);
581 el1 = talloc(root, struct el1);
582 el1->list = talloc(el1, struct el2 *);
583 el1->list[0] = talloc(el1->list, struct el2);
584 el1->list[0]->name = talloc_strdup(el1->list[0], "testing");
586 el1->list2 = talloc(el1, struct el2 *);
587 el1->list2[0] = talloc(el1->list2, struct el2);
588 el1->list2[0]->name = talloc_strdup(el1->list2[0], "testing2");
590 el1->list3 = talloc(el1, struct el2 *);
591 el1->list3[0] = talloc(el1->list3, struct el2);
592 el1->list3[0]->name = talloc_strdup(el1->list3[0], "testing2");
594 el2 = talloc(el1->list, struct el2);
595 el2 = talloc(el1->list2, struct el2);
596 el2 = talloc(el1->list3, struct el2);
598 el1->list = talloc_realloc(el1, el1->list, struct el2 *, 100);
599 el1->list2 = talloc_realloc(el1, el1->list2, struct el2 *, 200);
600 el1->list3 = talloc_realloc(el1, el1->list3, struct el2 *, 300);
604 printf("success: REALLOC WITH CHILD\n");
611 static bool test_type(void)
622 printf("test: type\n# talloc type checking\n");
624 root = talloc_new(NULL);
626 el1 = talloc(root, struct el1);
630 torture_assert("type", talloc_get_type(el1, struct el1) == el1,
631 "type check failed on el1\n");
632 torture_assert("type", talloc_get_type(el1, struct el2) == NULL,
633 "type check failed on el1 with el2\n");
634 talloc_set_type(el1, struct el2);
635 torture_assert("type", talloc_get_type(el1, struct el2) == (struct el2 *)el1,
636 "type set failed on el1 with el2\n");
640 printf("success: type\n");
647 static bool test_steal(void)
649 void *root, *p1, *p2;
651 printf("test: steal\n# STEAL\n");
653 root = talloc_new(NULL);
655 p1 = talloc_array(root, char, 10);
656 CHECK_SIZE("steal", p1, 10);
658 p2 = talloc_realloc(root, NULL, char, 20);
659 CHECK_SIZE("steal", p1, 10);
660 CHECK_SIZE("steal", root, 30);
662 torture_assert("steal", talloc_steal(p1, NULL) == NULL,
663 "failed: stealing NULL should give NULL\n");
665 torture_assert("steal", talloc_steal(p1, p1) == p1,
666 "failed: stealing to ourselves is a nop\n");
667 CHECK_BLOCKS("steal", root, 3);
668 CHECK_SIZE("steal", root, 30);
670 talloc_steal(NULL, p1);
671 talloc_steal(NULL, p2);
672 CHECK_BLOCKS("steal", root, 1);
673 CHECK_SIZE("steal", root, 0);
676 talloc_steal(root, p2);
677 CHECK_BLOCKS("steal", root, 2);
678 CHECK_SIZE("steal", root, 20);
682 CHECK_BLOCKS("steal", root, 1);
683 CHECK_SIZE("steal", root, 0);
687 p1 = talloc_size(NULL, 3);
688 talloc_report_full(NULL, stderr);
689 CHECK_SIZE("steal", NULL, 3);
692 printf("success: steal\n");
699 static bool test_move(void)
707 printf("test: move\n# MOVE\n");
709 root = talloc_new(NULL);
711 t1 = talloc(root, struct t_move);
712 t2 = talloc(root, struct t_move);
713 t1->p = talloc_strdup(t1, "foo");
714 t1->x = talloc(t1, int);
717 t2->p = talloc_move(t2, &t1->p);
718 t2->x = talloc_move(t2, &t1->x);
719 torture_assert("move", t1->p == NULL && t1->x == NULL &&
720 strcmp(t2->p, "foo") == 0 && *t2->x == 42,
721 "talloc move failed");
725 printf("success: move\n");
731 test talloc_realloc_fn
733 static bool test_realloc_fn(void)
737 printf("test: realloc_fn\n# talloc_realloc_fn\n");
739 root = talloc_new(NULL);
741 p1 = talloc_realloc_fn(root, NULL, 10);
742 CHECK_BLOCKS("realloc_fn", root, 2);
743 CHECK_SIZE("realloc_fn", root, 10);
744 p1 = talloc_realloc_fn(root, p1, 20);
745 CHECK_BLOCKS("realloc_fn", root, 2);
746 CHECK_SIZE("realloc_fn", root, 20);
747 p1 = talloc_realloc_fn(root, p1, 0);
748 CHECK_BLOCKS("realloc_fn", root, 1);
749 CHECK_SIZE("realloc_fn", root, 0);
753 printf("success: realloc_fn\n");
758 static bool test_unref_reparent(void)
760 void *root, *p1, *p2, *c1;
762 printf("test: unref_reparent\n# UNREFERENCE AFTER PARENT FREED\n");
764 root = talloc_named_const(NULL, 0, "root");
765 p1 = talloc_named_const(root, 1, "orig parent");
766 p2 = talloc_named_const(root, 1, "parent by reference");
768 c1 = talloc_named_const(p1, 1, "child");
769 talloc_reference(p2, c1);
771 CHECK_PARENT("unref_reparent", c1, p1);
775 CHECK_PARENT("unref_reparent", c1, p2);
777 talloc_unlink(p2, c1);
779 CHECK_SIZE("unref_reparent", root, 1);
784 printf("success: unref_reparent\n");
789 measure the speed of talloc versus malloc
791 static bool test_speed(void)
793 void *ctx = talloc_new(NULL);
795 const int loop = 1000;
799 printf("test: speed\n# TALLOC VS MALLOC SPEED\n");
801 tv = timeval_current();
805 for (i=0;i<loop;i++) {
806 p1 = talloc_size(ctx, loop % 100);
807 p2 = talloc_strdup(p1, "foo bar");
808 p3 = talloc_size(p1, 300);
812 } while (timeval_elapsed(&tv) < 5.0);
814 fprintf(stderr, "talloc: %.0f ops/sec\n", count/timeval_elapsed(&tv));
818 tv = timeval_current();
822 for (i=0;i<loop;i++) {
823 p1 = malloc(loop % 100);
824 p2 = strdup("foo bar");
831 } while (timeval_elapsed(&tv) < 5.0);
832 fprintf(stderr, "malloc: %.0f ops/sec\n", count/timeval_elapsed(&tv));
834 printf("success: speed\n");
839 static bool test_lifeless(void)
841 void *top = talloc_new(NULL);
842 char *parent, *child;
843 void *child_owner = talloc_new(NULL);
845 printf("test: lifeless\n# TALLOC_UNLINK LOOP\n");
847 parent = talloc_strdup(top, "parent");
848 child = talloc_strdup(parent, "child");
849 (void)talloc_reference(child, parent);
850 (void)talloc_reference(child_owner, child);
851 talloc_report_full(top, stderr);
852 talloc_unlink(top, parent);
854 talloc_report_full(top, stderr);
856 talloc_free(child_owner);
859 printf("success: lifeless\n");
863 static int loop_destructor_count;
865 static int test_loop_destructor(char *ptr)
867 loop_destructor_count++;
871 static bool test_loop(void)
873 void *top = talloc_new(NULL);
879 printf("test: loop\n# TALLOC LOOP DESTRUCTION\n");
881 parent = talloc_strdup(top, "parent");
882 req1 = talloc(parent, struct req1);
883 req1->req2 = talloc_strdup(req1, "req2");
884 talloc_set_destructor(req1->req2, test_loop_destructor);
885 req1->req3 = talloc_strdup(req1, "req3");
886 (void)talloc_reference(req1->req3, req1);
887 talloc_report_full(top, stderr);
889 talloc_report_full(top, stderr);
890 talloc_report_full(NULL, stderr);
893 torture_assert("loop", loop_destructor_count == 1,
894 "FAILED TO FIRE LOOP DESTRUCTOR\n");
895 loop_destructor_count = 0;
897 printf("success: loop\n");
901 static int fail_destructor_str(char *ptr)
906 static bool test_free_parent_deny_child(void)
908 void *top = talloc_new(NULL);
913 printf("test: free_parent_deny_child\n# TALLOC FREE PARENT DENY CHILD\n");
915 level1 = talloc_strdup(top, "level1");
916 level2 = talloc_strdup(level1, "level2");
917 level3 = talloc_strdup(level2, "level3");
919 talloc_set_destructor(level3, fail_destructor_str);
921 talloc_set_destructor(level3, NULL);
923 CHECK_PARENT("free_parent_deny_child", level3, top);
927 printf("success: free_parent_deny_child\n");
931 static bool test_talloc_ptrtype(void)
933 void *top = talloc_new(NULL);
937 } *s1, *s2, **s3, ***s4;
938 const char *location1;
939 const char *location2;
940 const char *location3;
941 const char *location4;
943 printf("test: ptrtype\n# TALLOC PTRTYPE\n");
945 s1 = talloc_ptrtype(top, s1);location1 = __location__;
947 if (talloc_get_size(s1) != sizeof(struct struct1)) {
948 printf("failure: ptrtype [\n"
949 "talloc_ptrtype() allocated the wrong size %lu (should be %lu)\n"
950 "]\n", (unsigned long)talloc_get_size(s1),
951 (unsigned long)sizeof(struct struct1));
955 if (strcmp(location1, talloc_get_name(s1)) != 0) {
956 printf("failure: ptrtype [\n"
957 "talloc_ptrtype() sets the wrong name '%s' (should be '%s')\n]\n",
958 talloc_get_name(s1), location1);
962 s2 = talloc_array_ptrtype(top, s2, 10);location2 = __location__;
964 if (talloc_get_size(s2) != (sizeof(struct struct1) * 10)) {
965 printf("failure: ptrtype [\n"
966 "talloc_array_ptrtype() allocated the wrong size "
967 "%lu (should be %lu)\n]\n",
968 (unsigned long)talloc_get_size(s2),
969 (unsigned long)(sizeof(struct struct1)*10));
973 if (strcmp(location2, talloc_get_name(s2)) != 0) {
974 printf("failure: ptrtype [\n"
975 "talloc_array_ptrtype() sets the wrong name '%s' (should be '%s')\n]\n",
976 talloc_get_name(s2), location2);
980 s3 = talloc_array_ptrtype(top, s3, 10);location3 = __location__;
982 if (talloc_get_size(s3) != (sizeof(struct struct1 *) * 10)) {
983 printf("failure: ptrtype [\n"
984 "talloc_array_ptrtype() allocated the wrong size "
985 "%lu (should be %lu)\n]\n",
986 (unsigned long)talloc_get_size(s3),
987 (unsigned long)(sizeof(struct struct1 *)*10));
991 torture_assert_str_equal("ptrtype", location3, talloc_get_name(s3),
992 "talloc_array_ptrtype() sets the wrong name");
994 s4 = talloc_array_ptrtype(top, s4, 10);location4 = __location__;
996 if (talloc_get_size(s4) != (sizeof(struct struct1 **) * 10)) {
997 printf("failure: ptrtype [\n"
998 "talloc_array_ptrtype() allocated the wrong size "
999 "%lu (should be %lu)\n]\n",
1000 (unsigned long)talloc_get_size(s4),
1001 (unsigned long)(sizeof(struct struct1 **)*10));
1005 torture_assert_str_equal("ptrtype", location4, talloc_get_name(s4),
1006 "talloc_array_ptrtype() sets the wrong name");
1010 printf("success: ptrtype\n");
1014 static int _test_talloc_free_in_destructor(void **ptr)
1020 static bool test_talloc_free_in_destructor(void)
1029 printf("test: free_in_destructor\n# TALLOC FREE IN DESTRUCTOR\n");
1031 level0 = talloc_new(NULL);
1032 level1 = talloc_new(level0);
1033 level2 = talloc_new(level1);
1034 level3 = talloc_new(level2);
1035 level4 = talloc_new(level3);
1036 level5 = talloc(level4, void *);
1039 (void)talloc_reference(level0, level3);
1040 (void)talloc_reference(level3, level3);
1041 (void)talloc_reference(level5, level3);
1043 talloc_set_destructor(level5, _test_talloc_free_in_destructor);
1045 talloc_free(level1);
1047 talloc_free(level0);
1049 printf("success: free_in_destructor\n");
1053 static bool test_autofree(void)
1055 #if _SAMBA_BUILD_ < 4
1056 /* autofree test would kill smbtorture */
1058 printf("test: autofree\n# TALLOC AUTOFREE CONTEXT\n");
1060 p = talloc_autofree_context();
1063 p = talloc_autofree_context();
1066 printf("success: autofree\n");
1071 struct torture_context;
1072 bool torture_local_talloc(struct torture_context *tctx)
1078 talloc_disable_null_tracking();
1079 talloc_enable_null_tracking();
1085 ret &= test_unlink1();
1087 ret &= test_realloc();
1088 ret &= test_realloc_child();
1089 ret &= test_steal();
1091 ret &= test_unref_reparent();
1092 ret &= test_realloc_fn();
1094 ret &= test_lifeless();
1096 ret &= test_free_parent_deny_child();
1097 ret &= test_talloc_ptrtype();
1098 ret &= test_talloc_free_in_destructor();
1101 ret &= test_speed();
1103 ret &= test_autofree();
1108 #if _SAMBA_BUILD_ < 4
1111 bool ret = torture_local_talloc(NULL);