r14720: Add torture_context argument to all torture tests
[kamenim/samba.git] / source4 / lib / talloc / testsuite.c
1 /* 
2    Unix SMB/CIFS implementation.
3
4    local testing of talloc routines.
5
6    Copyright (C) Andrew Tridgell 2004
7    
8      ** NOTE! The following LGPL license applies to the talloc
9      ** library. This does NOT imply that all of Samba is released
10      ** under the LGPL
11    
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 2 of the License, or (at your option) any later version.
16
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.
21
22    You should have received a copy of the GNU Lesser General Public
23    License along with this library; if not, write to the Free Software
24    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
25 */
26
27 #include "config.h"
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31
32 #ifdef HAVE_STDARG_H
33 #include <stdarg.h>
34 #endif
35
36 #include <sys/time.h>
37 #include <time.h>
38
39 #include "talloc.h"
40
41 #ifndef False
42 #define False 0
43 #endif
44 #ifndef True
45 #define True 1
46 #endif
47 #ifndef BOOL
48 #define BOOL int
49 #endif
50
51 struct torture_context;
52
53 static struct timeval timeval_current(void)
54 {
55         struct timeval tv;
56         gettimeofday(&tv, NULL);
57         return tv;
58 }
59
60 static double timeval_elapsed(struct timeval *tv)
61 {
62         struct timeval tv2 = timeval_current();
63         return (tv2.tv_sec - tv->tv_sec) + 
64                (tv2.tv_usec - tv->tv_usec)*1.0e-6;
65 }
66
67 #if SAMBA_VERSION_MAJOR<4
68 #ifdef malloc
69 #undef malloc
70 #endif
71 #ifdef strdup
72 #undef strdup
73 #endif
74 #endif
75
76 #define CHECK_SIZE(ptr, tsize) do { \
77         if (talloc_total_size(ptr) != (tsize)) { \
78                 printf(__location__ " failed: wrong '%s' tree size: got %u  expected %u\n", \
79                        #ptr, \
80                        (unsigned)talloc_total_size(ptr), \
81                        (unsigned)tsize); \
82                 talloc_report_full(ptr, stdout); \
83                 return False; \
84         } \
85 } while (0)
86
87 #define CHECK_BLOCKS(ptr, tblocks) do { \
88         if (talloc_total_blocks(ptr) != (tblocks)) { \
89                 printf(__location__ " failed: wrong '%s' tree blocks: got %u  expected %u\n", \
90                        #ptr, \
91                        (unsigned)talloc_total_blocks(ptr), \
92                        (unsigned)tblocks); \
93                 talloc_report_full(ptr, stdout); \
94                 return False; \
95         } \
96 } while (0)
97
98
99 /*
100   test references 
101 */
102 static BOOL test_ref1(void)
103 {
104         void *root, *p1, *p2, *ref, *r1;
105
106         printf("TESTING SINGLE REFERENCE FREE\n");
107
108         root = talloc_named_const(NULL, 0, "root");
109         p1 = talloc_named_const(root, 1, "p1");
110         p2 = talloc_named_const(p1, 1, "p2");
111         talloc_named_const(p1, 1, "x1");
112         talloc_named_const(p1, 2, "x2");
113         talloc_named_const(p1, 3, "x3");
114
115         r1 = talloc_named_const(root, 1, "r1"); 
116         ref = talloc_reference(r1, p2);
117         talloc_report_full(root, stdout);
118
119         CHECK_BLOCKS(p1, 5);
120         CHECK_BLOCKS(p2, 1);
121         CHECK_BLOCKS(r1, 2);
122
123         printf("Freeing p2\n");
124         talloc_free(p2);
125         talloc_report_full(root, stdout);
126
127         CHECK_BLOCKS(p1, 5);
128         CHECK_BLOCKS(p2, 1);
129         CHECK_BLOCKS(r1, 1);
130
131         printf("Freeing p1\n");
132         talloc_free(p1);
133         talloc_report_full(root, stdout);
134
135         CHECK_BLOCKS(r1, 1);
136
137         printf("Freeing r1\n");
138         talloc_free(r1);
139         talloc_report_full(NULL, stdout);
140
141         printf("Testing NULL\n");
142         if (talloc_reference(root, NULL)) {
143                 return False;
144         }
145
146         CHECK_BLOCKS(root, 1);
147
148         CHECK_SIZE(root, 0);
149
150         talloc_free(root);
151
152         return True;
153 }
154
155 /*
156   test references 
157 */
158 static BOOL test_ref2(void)
159 {
160         void *root, *p1, *p2, *ref, *r1;
161
162         printf("TESTING DOUBLE REFERENCE FREE\n");
163
164         root = talloc_named_const(NULL, 0, "root");
165         p1 = talloc_named_const(root, 1, "p1");
166         talloc_named_const(p1, 1, "x1");
167         talloc_named_const(p1, 1, "x2");
168         talloc_named_const(p1, 1, "x3");
169         p2 = talloc_named_const(p1, 1, "p2");
170
171         r1 = talloc_named_const(root, 1, "r1"); 
172         ref = talloc_reference(r1, p2);
173         talloc_report_full(root, stdout);
174
175         CHECK_BLOCKS(p1, 5);
176         CHECK_BLOCKS(p2, 1);
177         CHECK_BLOCKS(r1, 2);
178
179         printf("Freeing ref\n");
180         talloc_free(ref);
181         talloc_report_full(root, stdout);
182
183         CHECK_BLOCKS(p1, 5);
184         CHECK_BLOCKS(p2, 1);
185         CHECK_BLOCKS(r1, 1);
186
187         printf("Freeing p2\n");
188         talloc_free(p2);
189         talloc_report_full(root, stdout);
190
191         CHECK_BLOCKS(p1, 4);
192         CHECK_BLOCKS(r1, 1);
193
194         printf("Freeing p1\n");
195         talloc_free(p1);
196         talloc_report_full(root, stdout);
197
198         CHECK_BLOCKS(r1, 1);
199
200         printf("Freeing r1\n");
201         talloc_free(r1);
202         talloc_report_full(root, stdout);
203
204         CHECK_SIZE(root, 0);
205
206         talloc_free(root);
207
208         return True;
209 }
210
211 /*
212   test references 
213 */
214 static BOOL test_ref3(void)
215 {
216         void *root, *p1, *p2, *ref, *r1;
217
218         printf("TESTING PARENT REFERENCE FREE\n");
219
220         root = talloc_named_const(NULL, 0, "root");
221         p1 = talloc_named_const(root, 1, "p1");
222         p2 = talloc_named_const(root, 1, "p2");
223         r1 = talloc_named_const(p1, 1, "r1");
224         ref = talloc_reference(p2, r1);
225         talloc_report_full(root, stdout);
226
227         CHECK_BLOCKS(p1, 2);
228         CHECK_BLOCKS(p2, 2);
229         CHECK_BLOCKS(r1, 1);
230
231         printf("Freeing p1\n");
232         talloc_free(p1);
233         talloc_report_full(root, stdout);
234
235         CHECK_BLOCKS(p2, 2);
236         CHECK_BLOCKS(r1, 1);
237
238         printf("Freeing p2\n");
239         talloc_free(p2);
240         talloc_report_full(root, stdout);
241
242         CHECK_SIZE(root, 0);
243
244         talloc_free(root);
245
246         return True;
247 }
248
249 /*
250   test references 
251 */
252 static BOOL test_ref4(void)
253 {
254         void *root, *p1, *p2, *ref, *r1;
255
256         printf("TESTING REFERRER REFERENCE FREE\n");
257
258         root = talloc_named_const(NULL, 0, "root");
259         p1 = talloc_named_const(root, 1, "p1");
260         talloc_named_const(p1, 1, "x1");
261         talloc_named_const(p1, 1, "x2");
262         talloc_named_const(p1, 1, "x3");
263         p2 = talloc_named_const(p1, 1, "p2");
264
265         r1 = talloc_named_const(root, 1, "r1"); 
266         ref = talloc_reference(r1, p2);
267         talloc_report_full(root, stdout);
268
269         CHECK_BLOCKS(p1, 5);
270         CHECK_BLOCKS(p2, 1);
271         CHECK_BLOCKS(r1, 2);
272
273         printf("Freeing r1\n");
274         talloc_free(r1);
275         talloc_report_full(root, stdout);
276
277         CHECK_BLOCKS(p1, 5);
278         CHECK_BLOCKS(p2, 1);
279
280         printf("Freeing p2\n");
281         talloc_free(p2);
282         talloc_report_full(root, stdout);
283
284         CHECK_BLOCKS(p1, 4);
285
286         printf("Freeing p1\n");
287         talloc_free(p1);
288         talloc_report_full(root, stdout);
289
290         CHECK_SIZE(root, 0);
291
292         talloc_free(root);
293
294         return True;
295 }
296
297
298 /*
299   test references 
300 */
301 static BOOL test_unlink1(void)
302 {
303         void *root, *p1, *p2, *ref, *r1;
304
305         printf("TESTING UNLINK\n");
306
307         root = talloc_named_const(NULL, 0, "root");
308         p1 = talloc_named_const(root, 1, "p1");
309         talloc_named_const(p1, 1, "x1");
310         talloc_named_const(p1, 1, "x2");
311         talloc_named_const(p1, 1, "x3");
312         p2 = talloc_named_const(p1, 1, "p2");
313
314         r1 = talloc_named_const(p1, 1, "r1");   
315         ref = talloc_reference(r1, p2);
316         talloc_report_full(root, stdout);
317
318         CHECK_BLOCKS(p1, 7);
319         CHECK_BLOCKS(p2, 1);
320         CHECK_BLOCKS(r1, 2);
321
322         printf("Unreferencing r1\n");
323         talloc_unlink(r1, p2);
324         talloc_report_full(root, stdout);
325
326         CHECK_BLOCKS(p1, 6);
327         CHECK_BLOCKS(p2, 1);
328         CHECK_BLOCKS(r1, 1);
329
330         printf("Freeing p1\n");
331         talloc_free(p1);
332         talloc_report_full(root, stdout);
333
334         CHECK_SIZE(root, 0);
335
336         talloc_free(root);
337
338         return True;
339 }
340
341 static int fail_destructor(void *ptr)
342 {
343         return -1;
344 }
345
346 /*
347   miscellaneous tests to try to get a higher test coverage percentage
348 */
349 static BOOL test_misc(void)
350 {
351         void *root, *p1;
352         char *p2;
353         double *d;
354
355         printf("TESTING MISCELLANEOUS\n");
356
357         root = talloc_new(NULL);
358
359         p1 = talloc_size(root, 0x7fffffff);
360         if (p1) {
361                 printf("failed: large talloc allowed\n");
362                 return False;
363         }
364
365         p1 = talloc_strdup(root, "foo");
366         talloc_increase_ref_count(p1);
367         talloc_increase_ref_count(p1);
368         talloc_increase_ref_count(p1);
369         CHECK_BLOCKS(p1, 1);
370         CHECK_BLOCKS(root, 2);
371         talloc_free(p1);
372         CHECK_BLOCKS(p1, 1);
373         CHECK_BLOCKS(root, 2);
374         talloc_unlink(NULL, p1);
375         CHECK_BLOCKS(p1, 1);
376         CHECK_BLOCKS(root, 2);
377         p2 = talloc_strdup(p1, "foo");
378         if (talloc_unlink(root, p2) != -1) {
379                 printf("failed: talloc_unlink() of non-reference context should return -1\n");
380                 return False;
381         }
382         if (talloc_unlink(p1, p2) != 0) {
383                 printf("failed: talloc_unlink() of parent should succeed\n");
384                 return False;
385         }
386         talloc_free(p1);
387         CHECK_BLOCKS(p1, 1);
388         CHECK_BLOCKS(root, 2);
389
390         talloc_set_name(p1, "my name is %s", "foo");
391         if (strcmp(talloc_get_name(p1), "my name is foo") != 0) {
392                 printf("failed: wrong name after talloc_set_name\n");
393                 return False;
394         }
395         CHECK_BLOCKS(p1, 2);
396         CHECK_BLOCKS(root, 3);
397
398         talloc_set_name_const(p1, NULL);
399         if (strcmp(talloc_get_name(p1), "UNNAMED") != 0) {
400                 printf("failed: wrong name after talloc_set_name(NULL)\n");
401                 return False;
402         }
403         CHECK_BLOCKS(p1, 2);
404         CHECK_BLOCKS(root, 3);
405         
406
407         if (talloc_free(NULL) != -1) {
408                 printf("talloc_free(NULL) should give -1\n");
409                 return False;
410         }
411
412         talloc_set_destructor(p1, fail_destructor);
413         if (talloc_free(p1) != -1) {
414                 printf("Failed destructor should cause talloc_free to fail\n");
415                 return False;
416         }
417         talloc_set_destructor(p1, NULL);
418
419         talloc_report(root, stdout);
420
421
422         p2 = talloc_zero_size(p1, 20);
423         if (p2[19] != 0) {
424                 printf("Failed to give zero memory\n");
425                 return False;
426         }
427         talloc_free(p2);
428
429         if (talloc_strdup(root, NULL) != NULL) {
430                 printf("failed: strdup on NULL should give NULL\n");
431                 return False;
432         }
433
434         p2 = talloc_strndup(p1, "foo", 2);
435         if (strcmp("fo", p2) != 0) {
436                 printf("failed: strndup doesn't work\n");
437                 return False;
438         }
439         p2 = talloc_asprintf_append(p2, "o%c", 'd');
440         if (strcmp("food", p2) != 0) {
441                 printf("failed: talloc_asprintf_append doesn't work\n");
442                 return False;
443         }
444         CHECK_BLOCKS(p2, 1);
445         CHECK_BLOCKS(p1, 3);
446
447         p2 = talloc_asprintf_append(NULL, "hello %s", "world");
448         if (strcmp("hello world", p2) != 0) {
449                 printf("failed: talloc_asprintf_append doesn't work\n");
450                 return False;
451         }
452         CHECK_BLOCKS(p2, 1);
453         CHECK_BLOCKS(p1, 3);
454         talloc_free(p2);
455
456         d = talloc_array(p1, double, 0x20000000);
457         if (d) {
458                 printf("failed: integer overflow not detected\n");
459                 return False;
460         }
461
462         d = talloc_realloc(p1, d, double, 0x20000000);
463         if (d) {
464                 printf("failed: integer overflow not detected\n");
465                 return False;
466         }
467
468         talloc_free(p1);
469         CHECK_BLOCKS(root, 1);
470
471         p1 = talloc_named(root, 100, "%d bytes", 100);
472         CHECK_BLOCKS(p1, 2);
473         CHECK_BLOCKS(root, 3);
474         talloc_unlink(root, p1);
475
476         p1 = talloc_init("%d bytes", 200);
477         p2 = talloc_asprintf(p1, "my test '%s'", "string");
478         CHECK_BLOCKS(p1, 3);
479         CHECK_SIZE(p2, 17);
480         CHECK_BLOCKS(root, 1);
481         talloc_unlink(NULL, p1);
482
483         p1 = talloc_named_const(root, 10, "p1");
484         p2 = talloc_named_const(root, 20, "p2");
485         talloc_reference(p1, p2);
486         talloc_report_full(root, stdout);
487         talloc_unlink(root, p2);
488         talloc_report_full(root, stdout);
489         CHECK_BLOCKS(p2, 1);
490         CHECK_BLOCKS(p1, 2);
491         CHECK_BLOCKS(root, 3);
492         talloc_unlink(p1, p2);
493         talloc_unlink(root, p1);
494
495         p1 = talloc_named_const(root, 10, "p1");
496         p2 = talloc_named_const(root, 20, "p2");
497         talloc_reference(NULL, p2);
498         talloc_report_full(root, stdout);
499         talloc_unlink(root, p2);
500         talloc_report_full(root, stdout);
501         CHECK_BLOCKS(p2, 1);
502         CHECK_BLOCKS(p1, 1);
503         CHECK_BLOCKS(root, 2);
504         talloc_unlink(NULL, p2);
505         talloc_unlink(root, p1);
506
507         /* Test that talloc_unlink is a no-op */
508
509         if (talloc_unlink(root, NULL) != -1) {
510                 printf("failed: talloc_unlink(root, NULL) == -1\n");
511                 return False;
512         }
513
514         talloc_report(root, stdout);
515         talloc_report(NULL, stdout);
516
517         CHECK_SIZE(root, 0);
518
519         talloc_free(root);
520
521         CHECK_SIZE(NULL, 0);
522
523         talloc_enable_leak_report();
524         talloc_enable_leak_report_full();
525
526         return True;
527 }
528
529
530 /*
531   test realloc
532 */
533 static BOOL test_realloc(void)
534 {
535         void *root, *p1, *p2;
536
537         printf("TESTING REALLOC\n");
538
539         root = talloc_new(NULL);
540
541         p1 = talloc_size(root, 10);
542         CHECK_SIZE(p1, 10);
543
544         p1 = talloc_realloc_size(NULL, p1, 20);
545         CHECK_SIZE(p1, 20);
546
547         talloc_new(p1);
548
549         p2 = talloc_realloc_size(p1, NULL, 30);
550
551         talloc_new(p1);
552
553         p2 = talloc_realloc_size(p1, p2, 40);
554
555         CHECK_SIZE(p2, 40);
556         CHECK_SIZE(root, 60);
557         CHECK_BLOCKS(p1, 4);
558
559         p1 = talloc_realloc_size(NULL, p1, 20);
560         CHECK_SIZE(p1, 60);
561
562         talloc_increase_ref_count(p2);
563         if (talloc_realloc_size(NULL, p2, 5) != NULL) {
564                 printf("failed: talloc_realloc() on a referenced pointer should fail\n");
565                 return False;
566         }
567         CHECK_BLOCKS(p1, 4);
568
569         talloc_realloc_size(NULL, p2, 0);
570         talloc_realloc_size(NULL, p2, 0);
571         CHECK_BLOCKS(p1, 3);
572
573         if (talloc_realloc_size(NULL, p1, 0x7fffffff) != NULL) {
574                 printf("failed: oversize talloc should fail\n");
575                 return False;
576         }
577
578         talloc_realloc_size(NULL, p1, 0);
579
580         CHECK_BLOCKS(root, 1);
581         CHECK_SIZE(root, 0);
582
583         talloc_free(root);
584
585         return True;
586 }
587
588
589 /*
590   test realloc with a child
591 */
592 static BOOL test_realloc_child(void)
593 {
594         void *root;
595         struct el1 {
596                 int count;
597                 struct el2 {
598                         const char *name;
599                 } **list, **list2, **list3;
600         } *el1;
601         struct el2 *el2;
602
603         printf("TESTING REALLOC WITH CHILD\n");
604
605         root = talloc_new(NULL);
606
607         el1 = talloc(root, struct el1);
608         el1->list = talloc(el1, struct el2 *);
609         el1->list[0] = talloc(el1->list, struct el2);
610         el1->list[0]->name = talloc_strdup(el1->list[0], "testing");
611
612         el1->list2 = talloc(el1, struct el2 *);
613         el1->list2[0] = talloc(el1->list2, struct el2);
614         el1->list2[0]->name = talloc_strdup(el1->list2[0], "testing2");
615
616         el1->list3 = talloc(el1, struct el2 *);
617         el1->list3[0] = talloc(el1->list3, struct el2);
618         el1->list3[0]->name = talloc_strdup(el1->list3[0], "testing2");
619         
620         el2 = talloc(el1->list, struct el2);
621         el2 = talloc(el1->list2, struct el2);
622         el2 = talloc(el1->list3, struct el2);
623
624         el1->list = talloc_realloc(el1, el1->list, struct el2 *, 100);
625         el1->list2 = talloc_realloc(el1, el1->list2, struct el2 *, 200);
626         el1->list3 = talloc_realloc(el1, el1->list3, struct el2 *, 300);
627
628         talloc_free(root);
629
630         return True;
631 }
632
633
634 /*
635   test type checking
636 */
637 static BOOL test_type(void)
638 {
639         void *root;
640         struct el1 {
641                 int count;
642         };
643         struct el2 {
644                 int count;
645         };
646         struct el1 *el1;
647
648         printf("TESTING talloc type checking\n");
649
650         root = talloc_new(NULL);
651
652         el1 = talloc(root, struct el1);
653
654         el1->count = 1;
655
656         if (talloc_get_type(el1, struct el1) != el1) {
657                 printf("type check failed on el1\n");
658                 return False;
659         }
660         if (talloc_get_type(el1, struct el2) != NULL) {
661                 printf("type check failed on el1 with el2\n");
662                 return False;
663         }
664         talloc_set_type(el1, struct el2);
665         if (talloc_get_type(el1, struct el2) != (struct el2 *)el1) {
666                 printf("type set failed on el1 with el2\n");
667                 return False;
668         }
669
670         talloc_free(root);
671
672         return True;
673 }
674
675 /*
676   test steal
677 */
678 static BOOL test_steal(void)
679 {
680         void *root, *p1, *p2;
681
682         printf("TESTING STEAL\n");
683
684         root = talloc_new(NULL);
685
686         p1 = talloc_array(root, char, 10);
687         CHECK_SIZE(p1, 10);
688
689         p2 = talloc_realloc(root, NULL, char, 20);
690         CHECK_SIZE(p1, 10);
691         CHECK_SIZE(root, 30);
692
693         if (talloc_steal(p1, NULL) != NULL) {
694                 printf("failed: stealing NULL should give NULL\n");
695                 return False;
696         }
697
698         if (talloc_steal(p1, p1) != p1) {
699                 printf("failed: stealing to ourselves is a nop\n");
700                 return False;
701         }
702         CHECK_BLOCKS(root, 3);
703         CHECK_SIZE(root, 30);
704
705         talloc_steal(NULL, p1);
706         talloc_steal(NULL, p2);
707         CHECK_BLOCKS(root, 1);
708         CHECK_SIZE(root, 0);
709
710         talloc_free(p1);
711         talloc_steal(root, p2);
712         CHECK_BLOCKS(root, 2);
713         CHECK_SIZE(root, 20);
714         
715         talloc_free(p2);
716
717         CHECK_BLOCKS(root, 1);
718         CHECK_SIZE(root, 0);
719
720         talloc_free(root);
721
722         p1 = talloc_size(NULL, 3);
723         talloc_report_full(NULL, stdout);
724         CHECK_SIZE(NULL, 3);
725         talloc_free(p1);
726
727         return True;
728 }
729
730 /*
731   test talloc_realloc_fn
732 */
733 static BOOL test_realloc_fn(void)
734 {
735         void *root, *p1;
736
737         printf("TESTING talloc_realloc_fn\n");
738
739         root = talloc_new(NULL);
740
741         p1 = talloc_realloc_fn(root, NULL, 10);
742         CHECK_BLOCKS(root, 2);
743         CHECK_SIZE(root, 10);
744         p1 = talloc_realloc_fn(root, p1, 20);
745         CHECK_BLOCKS(root, 2);
746         CHECK_SIZE(root, 20);
747         p1 = talloc_realloc_fn(root, p1, 0);
748         CHECK_BLOCKS(root, 1);
749         CHECK_SIZE(root, 0);
750
751         talloc_free(root);
752
753
754         return True;
755 }
756
757
758 static BOOL test_unref_reparent(void)
759 {
760         void *root, *p1, *p2, *c1;
761
762         printf("TESTING UNREFERENCE AFTER PARENT FREED\n");
763
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");
767
768         c1 = talloc_named_const(p1, 1, "child");
769         talloc_reference(p2, c1);
770
771         talloc_free(p1);
772         talloc_unlink(p2, c1);
773
774         CHECK_SIZE(root, 1);
775
776         talloc_free(p2);
777         talloc_free(root);
778
779         return True;
780 }
781
782 /*
783   measure the speed of talloc versus malloc
784 */
785 static BOOL test_speed(void)
786 {
787         void *ctx = talloc_new(NULL);
788         unsigned count;
789         struct timeval tv;
790
791         printf("MEASURING TALLOC VS MALLOC SPEED\n");
792
793         tv = timeval_current();
794         count = 0;
795         do {
796                 void *p1, *p2, *p3;
797                 p1 = talloc_size(ctx, count);
798                 p2 = talloc_strdup(p1, "foo bar");
799                 p3 = talloc_size(p1, 300);
800                 talloc_free(p1);
801                 count += 3;
802         } while (timeval_elapsed(&tv) < 5.0);
803
804         printf("talloc: %.0f ops/sec\n", count/timeval_elapsed(&tv));
805
806         talloc_free(ctx);
807
808         tv = timeval_current();
809         count = 0;
810         do {
811                 void *p1, *p2, *p3;
812                 p1 = malloc(count);
813                 p2 = strdup("foo bar");
814                 p3 = malloc(300);
815                 free(p1);
816                 free(p2);
817                 free(p3);
818                 count += 3;
819         } while (timeval_elapsed(&tv) < 5.0);
820
821         printf("malloc: %.0f ops/sec\n", count/timeval_elapsed(&tv));
822
823         return True;    
824 }
825
826
827 BOOL test_lifeless(void)
828 {
829         char *top = talloc_new(NULL);
830         char *parent, *child; 
831         char *child_owner = talloc_new(NULL);
832
833         printf("TESTING TALLOC_UNLINK LOOP\n");
834
835         parent = talloc_strdup(top, "parent");
836         child = talloc_strdup(parent, "child");  
837         talloc_reference(child, parent);
838         talloc_reference(child_owner, child); 
839         talloc_unlink(top, parent);
840         talloc_free(child);
841         talloc_report_full(top, stdout);
842         talloc_free(top);
843         return True;
844 }
845
846
847 BOOL torture_local_talloc(struct torture_context *torture) 
848 {
849         BOOL ret = True;
850
851         ret &= test_ref1();
852         ret &= test_ref2();
853         ret &= test_ref3();
854         ret &= test_ref4();
855         ret &= test_unlink1();
856         ret &= test_misc();
857         ret &= test_realloc();
858         ret &= test_realloc_child();
859         ret &= test_steal();
860         ret &= test_unref_reparent();
861         ret &= test_realloc_fn();
862         ret &= test_type();
863         ret &= test_lifeless();
864         if (ret) {
865                 ret &= test_speed();
866         }
867
868         return ret;
869 }
870
871
872
873 #if !defined(_SAMBA_BUILD_) || ((SAMBA_VERSION_MAJOR==3)&&(SAMBA_VERSION_MINOR<9))
874  int main(void)
875 {
876         if (!torture_local_talloc(NULL)) {
877                 printf("ERROR: TESTSUITE FAILED\n");
878                 return -1;
879         }
880         return 0;
881 }
882 #endif