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