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