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