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