talloc/tests: avoid some unused variable warnings
[samba.git] / 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 3 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, see <http://www.gnu.org/licenses/>.
24 */
25
26 #include "replace.h"
27 #include "system/time.h"
28 #include <talloc.h>
29
30 #include "talloc_testsuite.h"
31
32 static struct timeval timeval_current(void)
33 {
34         struct timeval tv;
35         gettimeofday(&tv, NULL);
36         return tv;
37 }
38
39 static double timeval_elapsed(struct timeval *tv)
40 {
41         struct timeval tv2 = timeval_current();
42         return (tv2.tv_sec - tv->tv_sec) + 
43                (tv2.tv_usec - tv->tv_usec)*1.0e-6;
44 }
45
46 #define torture_assert(test, expr, str) if (!(expr)) { \
47         printf("failure: %s [\n%s: Expression %s failed: %s\n]\n", \
48                 test, __location__, #expr, str); \
49         return false; \
50 }
51
52 #define torture_assert_str_equal(test, arg1, arg2, desc) \
53         if (arg1 == NULL && arg2 == NULL) {                             \
54         } else if (strcmp(arg1, arg2)) {                        \
55                 printf("failure: %s [\n%s: Expected %s, got %s: %s\n]\n", \
56                    test, __location__, arg1, arg2, desc); \
57                 return false; \
58         }
59
60 #define CHECK_SIZE(test, ptr, tsize) do { \
61         if (talloc_total_size(ptr) != (tsize)) { \
62                 printf("failed: %s [\n%s: wrong '%s' tree size: got %u  expected %u\n]\n", \
63                        test, __location__, #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(test, ptr, tblocks) do { \
72         if (talloc_total_blocks(ptr) != (tblocks)) { \
73                 printf("failed: %s [\n%s: wrong '%s' tree blocks: got %u  expected %u\n]\n", \
74                        test, __location__, #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 #define CHECK_PARENT(test, ptr, parent) do { \
83         if (talloc_parent(ptr) != (parent)) { \
84                 printf("failed: %s [\n%s: '%s' has wrong parent: got %p  expected %p\n]\n", \
85                        test, __location__, #ptr, \
86                        talloc_parent(ptr), \
87                        (parent)); \
88                 talloc_report_full(ptr, stdout); \
89                 talloc_report_full(parent, stdout); \
90                 talloc_report_full(NULL, stdout); \
91                 return false; \
92         } \
93 } while (0)
94
95 static unsigned int test_abort_count;
96
97 #if 0
98 static void test_abort_fn(const char *reason)
99 {
100         printf("# test_abort_fn(%s)\n", reason);
101         test_abort_count++;
102 }
103
104 static void test_abort_start(void)
105 {
106         test_abort_count = 0;
107         talloc_set_abort_fn(test_abort_fn);
108 }
109 #endif
110
111 static void test_abort_stop(void)
112 {
113         test_abort_count = 0;
114         talloc_set_abort_fn(NULL);
115 }
116
117 static void test_log_stdout(const char *message)
118 {
119         fprintf(stdout, "%s", message);
120 }
121
122 /*
123   test references 
124 */
125 static bool test_ref1(void)
126 {
127         void *root, *p1, *p2, *ref, *r1;
128
129         printf("test: ref1\n# SINGLE REFERENCE FREE\n");
130
131         root = talloc_named_const(NULL, 0, "root");
132         p1 = talloc_named_const(root, 1, "p1");
133         p2 = talloc_named_const(p1, 1, "p2");
134         talloc_named_const(p1, 1, "x1");
135         talloc_named_const(p1, 2, "x2");
136         talloc_named_const(p1, 3, "x3");
137
138         r1 = talloc_named_const(root, 1, "r1"); 
139         ref = talloc_reference(r1, p2);
140         talloc_report_full(root, stderr);
141
142         CHECK_BLOCKS("ref1", p1, 5);
143         CHECK_BLOCKS("ref1", p2, 1);
144         CHECK_BLOCKS("ref1", ref, 1);
145         CHECK_BLOCKS("ref1", r1, 2);
146
147         fprintf(stderr, "Freeing p2\n");
148         talloc_unlink(r1, p2);
149         talloc_report_full(root, stderr);
150
151         CHECK_BLOCKS("ref1", p1, 5);
152         CHECK_BLOCKS("ref1", p2, 1);
153         CHECK_BLOCKS("ref1", r1, 1);
154
155         fprintf(stderr, "Freeing p1\n");
156         talloc_free(p1);
157         talloc_report_full(root, stderr);
158
159         CHECK_BLOCKS("ref1", r1, 1);
160
161         fprintf(stderr, "Freeing r1\n");
162         talloc_free(r1);
163         talloc_report_full(NULL, stderr);
164
165         fprintf(stderr, "Testing NULL\n");
166         if (talloc_reference(root, NULL)) {
167                 return false;
168         }
169
170         CHECK_BLOCKS("ref1", root, 1);
171
172         CHECK_SIZE("ref1", root, 0);
173
174         talloc_free(root);
175         printf("success: ref1\n");
176         return true;
177 }
178
179 /*
180   test references 
181 */
182 static bool test_ref2(void)
183 {
184         void *root, *p1, *p2, *ref, *r1;
185
186         printf("test: ref2\n# DOUBLE REFERENCE FREE\n");
187         root = talloc_named_const(NULL, 0, "root");
188         p1 = talloc_named_const(root, 1, "p1");
189         talloc_named_const(p1, 1, "x1");
190         talloc_named_const(p1, 1, "x2");
191         talloc_named_const(p1, 1, "x3");
192         p2 = talloc_named_const(p1, 1, "p2");
193
194         r1 = talloc_named_const(root, 1, "r1"); 
195         ref = talloc_reference(r1, p2);
196         talloc_report_full(root, stderr);
197
198         CHECK_BLOCKS("ref2", p1, 5);
199         CHECK_BLOCKS("ref2", p2, 1);
200         CHECK_BLOCKS("ref2", r1, 2);
201
202         fprintf(stderr, "Freeing ref\n");
203         talloc_unlink(r1, ref);
204         talloc_report_full(root, stderr);
205
206         CHECK_BLOCKS("ref2", p1, 5);
207         CHECK_BLOCKS("ref2", p2, 1);
208         CHECK_BLOCKS("ref2", r1, 1);
209
210         fprintf(stderr, "Freeing p2\n");
211         talloc_free(p2);
212         talloc_report_full(root, stderr);
213
214         CHECK_BLOCKS("ref2", p1, 4);
215         CHECK_BLOCKS("ref2", r1, 1);
216
217         fprintf(stderr, "Freeing p1\n");
218         talloc_free(p1);
219         talloc_report_full(root, stderr);
220
221         CHECK_BLOCKS("ref2", r1, 1);
222
223         fprintf(stderr, "Freeing r1\n");
224         talloc_free(r1);
225         talloc_report_full(root, stderr);
226
227         CHECK_SIZE("ref2", root, 0);
228
229         talloc_free(root);
230         printf("success: ref2\n");
231         return true;
232 }
233
234 /*
235   test references 
236 */
237 static bool test_ref3(void)
238 {
239         void *root, *p1, *p2, *ref, *r1;
240
241         printf("test: ref3\n# PARENT REFERENCE FREE\n");
242
243         root = talloc_named_const(NULL, 0, "root");
244         p1 = talloc_named_const(root, 1, "p1");
245         p2 = talloc_named_const(root, 1, "p2");
246         r1 = talloc_named_const(p1, 1, "r1");
247         ref = talloc_reference(p2, r1);
248         talloc_report_full(root, stderr);
249
250         CHECK_BLOCKS("ref3", p1, 2);
251         CHECK_BLOCKS("ref3", p2, 2);
252         CHECK_BLOCKS("ref3", r1, 1);
253         CHECK_BLOCKS("ref3", ref, 1);
254
255         fprintf(stderr, "Freeing p1\n");
256         talloc_free(p1);
257         talloc_report_full(root, stderr);
258
259         CHECK_BLOCKS("ref3", p2, 2);
260         CHECK_BLOCKS("ref3", r1, 1);
261
262         fprintf(stderr, "Freeing p2\n");
263         talloc_free(p2);
264         talloc_report_full(root, stderr);
265
266         CHECK_SIZE("ref3", root, 0);
267
268         talloc_free(root);
269
270         printf("success: ref3\n");
271         return true;
272 }
273
274 /*
275   test references 
276 */
277 static bool test_ref4(void)
278 {
279         void *root, *p1, *p2, *ref, *r1;
280
281         printf("test: ref4\n# REFERRER REFERENCE FREE\n");
282
283         root = talloc_named_const(NULL, 0, "root");
284         p1 = talloc_named_const(root, 1, "p1");
285         talloc_named_const(p1, 1, "x1");
286         talloc_named_const(p1, 1, "x2");
287         talloc_named_const(p1, 1, "x3");
288         p2 = talloc_named_const(p1, 1, "p2");
289
290         r1 = talloc_named_const(root, 1, "r1"); 
291         ref = talloc_reference(r1, p2);
292         talloc_report_full(root, stderr);
293
294         CHECK_BLOCKS("ref4", p1, 5);
295         CHECK_BLOCKS("ref4", p2, 1);
296         CHECK_BLOCKS("ref4", ref, 1);
297         CHECK_BLOCKS("ref4", r1, 2);
298
299         fprintf(stderr, "Freeing r1\n");
300         talloc_free(r1);
301         talloc_report_full(root, stderr);
302
303         CHECK_BLOCKS("ref4", p1, 5);
304         CHECK_BLOCKS("ref4", p2, 1);
305
306         fprintf(stderr, "Freeing p2\n");
307         talloc_free(p2);
308         talloc_report_full(root, stderr);
309
310         CHECK_BLOCKS("ref4", p1, 4);
311
312         fprintf(stderr, "Freeing p1\n");
313         talloc_free(p1);
314         talloc_report_full(root, stderr);
315
316         CHECK_SIZE("ref4", root, 0);
317
318         talloc_free(root);
319
320         printf("success: ref4\n");
321         return true;
322 }
323
324
325 /*
326   test references 
327 */
328 static bool test_unlink1(void)
329 {
330         void *root, *p1, *p2, *ref, *r1;
331
332         printf("test: unlink\n# UNLINK\n");
333
334         root = talloc_named_const(NULL, 0, "root");
335         p1 = talloc_named_const(root, 1, "p1");
336         talloc_named_const(p1, 1, "x1");
337         talloc_named_const(p1, 1, "x2");
338         talloc_named_const(p1, 1, "x3");
339         p2 = talloc_named_const(p1, 1, "p2");
340
341         r1 = talloc_named_const(p1, 1, "r1");   
342         ref = talloc_reference(r1, p2);
343         talloc_report_full(root, stderr);
344
345         CHECK_BLOCKS("unlink", p1, 7);
346         CHECK_BLOCKS("unlink", p2, 1);
347         CHECK_BLOCKS("unlink", ref, 1);
348         CHECK_BLOCKS("unlink", r1, 2);
349
350         fprintf(stderr, "Unreferencing r1\n");
351         talloc_unlink(r1, p2);
352         talloc_report_full(root, stderr);
353
354         CHECK_BLOCKS("unlink", p1, 6);
355         CHECK_BLOCKS("unlink", p2, 1);
356         CHECK_BLOCKS("unlink", r1, 1);
357
358         fprintf(stderr, "Freeing p1\n");
359         talloc_free(p1);
360         talloc_report_full(root, stderr);
361
362         CHECK_SIZE("unlink", root, 0);
363
364         talloc_free(root);
365
366         printf("success: unlink\n");
367         return true;
368 }
369
370 static int fail_destructor(void *ptr)
371 {
372         return -1;
373 }
374
375 /*
376   miscellaneous tests to try to get a higher test coverage percentage
377 */
378 static bool test_misc(void)
379 {
380         void *root, *p1;
381         char *p2;
382         double *d;
383         const char *name;
384
385         printf("test: misc\n# MISCELLANEOUS\n");
386
387         root = talloc_new(NULL);
388
389         p1 = talloc_size(root, 0x7fffffff);
390         torture_assert("misc", !p1, "failed: large talloc allowed\n");
391
392         p1 = talloc_strdup(root, "foo");
393         talloc_increase_ref_count(p1);
394         talloc_increase_ref_count(p1);
395         talloc_increase_ref_count(p1);
396         CHECK_BLOCKS("misc", p1, 1);
397         CHECK_BLOCKS("misc", root, 2);
398         talloc_unlink(NULL, p1);
399         CHECK_BLOCKS("misc", p1, 1);
400         CHECK_BLOCKS("misc", root, 2);
401         talloc_unlink(NULL, p1);
402         CHECK_BLOCKS("misc", p1, 1);
403         CHECK_BLOCKS("misc", root, 2);
404         p2 = talloc_strdup(p1, "foo");
405         torture_assert("misc", talloc_unlink(root, p2) == -1,
406                                    "failed: talloc_unlink() of non-reference context should return -1\n");
407         torture_assert("misc", talloc_unlink(p1, p2) == 0,
408                 "failed: talloc_unlink() of parent should succeed\n");
409         talloc_unlink(NULL, p1);
410         CHECK_BLOCKS("misc", p1, 1);
411         CHECK_BLOCKS("misc", root, 2);
412
413         name = talloc_set_name(p1, "my name is %s", "foo");
414         torture_assert_str_equal("misc", talloc_get_name(p1), "my name is foo",
415                 "failed: wrong name after talloc_set_name(my name is foo)");
416         torture_assert_str_equal("misc", talloc_get_name(p1), name,
417                 "failed: wrong name after talloc_set_name(my name is foo)");
418         CHECK_BLOCKS("misc", p1, 2);
419         CHECK_BLOCKS("misc", root, 3);
420
421         talloc_set_name_const(p1, NULL);
422         torture_assert_str_equal ("misc", talloc_get_name(p1), "UNNAMED",
423                 "failed: wrong name after talloc_set_name(NULL)");
424         CHECK_BLOCKS("misc", p1, 2);
425         CHECK_BLOCKS("misc", root, 3);
426
427         torture_assert("misc", talloc_free(NULL) == -1, 
428                                    "talloc_free(NULL) should give -1\n");
429
430         talloc_set_destructor(p1, fail_destructor);
431         torture_assert("misc", talloc_free(p1) == -1, 
432                 "Failed destructor should cause talloc_free to fail\n");
433         talloc_set_destructor(p1, NULL);
434
435         talloc_report(root, stderr);
436
437
438         p2 = (char *)talloc_zero_size(p1, 20);
439         torture_assert("misc", p2[19] == 0, "Failed to give zero memory\n");
440         talloc_free(p2);
441
442         torture_assert("misc", talloc_strdup(root, NULL) == NULL,
443                 "failed: strdup on NULL should give NULL\n");
444
445         p2 = talloc_strndup(p1, "foo", 2);
446         torture_assert("misc", strcmp("fo", p2) == 0, 
447                                    "strndup doesn't work\n");
448         p2 = talloc_asprintf_append_buffer(p2, "o%c", 'd');
449         torture_assert("misc", strcmp("food", p2) == 0, 
450                                    "talloc_asprintf_append_buffer doesn't work\n");
451         CHECK_BLOCKS("misc", p2, 1);
452         CHECK_BLOCKS("misc", p1, 3);
453
454         p2 = talloc_asprintf_append_buffer(NULL, "hello %s", "world");
455         torture_assert("misc", strcmp("hello world", p2) == 0,
456                 "talloc_asprintf_append_buffer doesn't work\n");
457         CHECK_BLOCKS("misc", p2, 1);
458         CHECK_BLOCKS("misc", p1, 3);
459         talloc_free(p2);
460
461         d = talloc_array(p1, double, 0x20000000);
462         torture_assert("misc", !d, "failed: integer overflow not detected\n");
463
464         d = talloc_realloc(p1, d, double, 0x20000000);
465         torture_assert("misc", !d, "failed: integer overflow not detected\n");
466
467         talloc_free(p1);
468         CHECK_BLOCKS("misc", root, 1);
469
470         p1 = talloc_named(root, 100, "%d bytes", 100);
471         CHECK_BLOCKS("misc", p1, 2);
472         CHECK_BLOCKS("misc", root, 3);
473         talloc_unlink(root, p1);
474
475         p1 = talloc_init("%d bytes", 200);
476         p2 = talloc_asprintf(p1, "my test '%s'", "string");
477         torture_assert_str_equal("misc", p2, "my test 'string'",
478                 "failed: talloc_asprintf(\"my test '%%s'\", \"string\") gave: \"%s\"");
479         CHECK_BLOCKS("misc", p1, 3);
480         CHECK_SIZE("misc", p2, 17);
481         CHECK_BLOCKS("misc", root, 1);
482         talloc_unlink(NULL, p1);
483
484         p1 = talloc_named_const(root, 10, "p1");
485         p2 = (char *)talloc_named_const(root, 20, "p2");
486         (void)talloc_reference(p1, p2);
487         talloc_report_full(root, stderr);
488         talloc_unlink(root, p2);
489         talloc_report_full(root, stderr);
490         CHECK_BLOCKS("misc", p2, 1);
491         CHECK_BLOCKS("misc", p1, 2);
492         CHECK_BLOCKS("misc", root, 3);
493         talloc_unlink(p1, p2);
494         talloc_unlink(root, p1);
495
496         p1 = talloc_named_const(root, 10, "p1");
497         p2 = (char *)talloc_named_const(root, 20, "p2");
498         (void)talloc_reference(NULL, p2);
499         talloc_report_full(root, stderr);
500         talloc_unlink(root, p2);
501         talloc_report_full(root, stderr);
502         CHECK_BLOCKS("misc", p2, 1);
503         CHECK_BLOCKS("misc", p1, 1);
504         CHECK_BLOCKS("misc", root, 2);
505         talloc_unlink(NULL, p2);
506         talloc_unlink(root, p1);
507
508         /* Test that talloc_unlink is a no-op */
509
510         torture_assert("misc", talloc_unlink(root, NULL) == -1,
511                 "failed: talloc_unlink(root, NULL) == -1\n");
512
513         talloc_report(root, stderr);
514         talloc_report(NULL, stderr);
515
516         CHECK_SIZE("misc", root, 0);
517
518         talloc_free(root);
519
520         CHECK_SIZE("misc", NULL, 0);
521
522         talloc_enable_null_tracking_no_autofree();
523         talloc_enable_leak_report();
524         talloc_enable_leak_report_full();
525
526         printf("success: misc\n");
527
528         return true;
529 }
530
531
532 /*
533   test realloc
534 */
535 static bool test_realloc(void)
536 {
537         void *root, *p1, *p2;
538
539         printf("test: realloc\n# REALLOC\n");
540
541         root = talloc_new(NULL);
542
543         p1 = talloc_size(root, 10);
544         CHECK_SIZE("realloc", p1, 10);
545
546         p1 = talloc_realloc_size(NULL, p1, 20);
547         CHECK_SIZE("realloc", p1, 20);
548
549         talloc_new(p1);
550
551         p2 = talloc_realloc_size(p1, NULL, 30);
552
553         talloc_new(p1);
554
555         p2 = talloc_realloc_size(p1, p2, 40);
556
557         CHECK_SIZE("realloc", p2, 40);
558         CHECK_SIZE("realloc", root, 60);
559         CHECK_BLOCKS("realloc", p1, 4);
560
561         p1 = talloc_realloc_size(NULL, p1, 20);
562         CHECK_SIZE("realloc", p1, 60);
563
564         talloc_increase_ref_count(p2);
565         torture_assert("realloc", talloc_realloc_size(NULL, p2, 5) == NULL,
566                 "failed: talloc_realloc() on a referenced pointer should fail\n");
567         CHECK_BLOCKS("realloc", p1, 4);
568
569         talloc_realloc_size(NULL, p2, 0);
570         talloc_realloc_size(NULL, p2, 0);
571         CHECK_BLOCKS("realloc", p1, 4);
572         talloc_realloc_size(p1, p2, 0);
573         CHECK_BLOCKS("realloc", p1, 3);
574
575         torture_assert("realloc", talloc_realloc_size(NULL, p1, 0x7fffffff) == NULL,
576                 "failed: oversize talloc should fail\n");
577
578         talloc_realloc_size(NULL, p1, 0);
579         CHECK_BLOCKS("realloc", root, 4);
580         talloc_realloc_size(root, p1, 0);
581         CHECK_BLOCKS("realloc", root, 1);
582
583         CHECK_SIZE("realloc", root, 0);
584
585         talloc_free(root);
586
587         printf("success: realloc\n");
588
589         return true;
590 }
591
592 /*
593   test realloc with a child
594 */
595 static bool test_realloc_child(void)
596 {
597         void *root;
598         struct el2 {
599                 const char *name;
600         } *el2; 
601         struct el1 {
602                 int count;
603                 struct el2 **list, **list2, **list3;
604         } *el1;
605
606         printf("test: REALLOC WITH CHILD\n");
607
608         root = talloc_new(NULL);
609
610         el1 = talloc(root, struct el1);
611         el1->list = talloc(el1, struct el2 *);
612         el1->list[0] = talloc(el1->list, struct el2);
613         el1->list[0]->name = talloc_strdup(el1->list[0], "testing");
614
615         el1->list2 = talloc(el1, struct el2 *);
616         el1->list2[0] = talloc(el1->list2, struct el2);
617         el1->list2[0]->name = talloc_strdup(el1->list2[0], "testing2");
618
619         el1->list3 = talloc(el1, struct el2 *);
620         el1->list3[0] = talloc(el1->list3, struct el2);
621         el1->list3[0]->name = talloc_strdup(el1->list3[0], "testing2");
622         
623         el2 = talloc(el1->list, struct el2);
624         el2 = talloc(el1->list2, struct el2);
625         el2 = talloc(el1->list3, struct el2);
626         (void)el2;
627
628         el1->list = talloc_realloc(el1, el1->list, struct el2 *, 100);
629         el1->list2 = talloc_realloc(el1, el1->list2, struct el2 *, 200);
630         el1->list3 = talloc_realloc(el1, el1->list3, struct el2 *, 300);
631
632         talloc_free(root);
633
634         printf("success: REALLOC WITH CHILD\n");
635         return true;
636 }
637
638 /*
639   test type checking
640 */
641 static bool test_type(void)
642 {
643         void *root;
644         struct el1 {
645                 int count;
646         };
647         struct el2 {
648                 int count;
649         };
650         struct el1 *el1;
651
652         printf("test: type\n# talloc type checking\n");
653
654         root = talloc_new(NULL);
655
656         el1 = talloc(root, struct el1);
657
658         el1->count = 1;
659
660         torture_assert("type", talloc_get_type(el1, struct el1) == el1,
661                 "type check failed on el1\n");
662         torture_assert("type", talloc_get_type(el1, struct el2) == NULL,
663                 "type check failed on el1 with el2\n");
664         talloc_set_type(el1, struct el2);
665         torture_assert("type", talloc_get_type(el1, struct el2) == (struct el2 *)el1,
666                 "type set failed on el1 with el2\n");
667
668         talloc_free(root);
669
670         printf("success: type\n");
671         return true;
672 }
673
674 /*
675   test steal
676 */
677 static bool test_steal(void)
678 {
679         void *root, *p1, *p2;
680
681         printf("test: steal\n# STEAL\n");
682
683         root = talloc_new(NULL);
684
685         p1 = talloc_array(root, char, 10);
686         CHECK_SIZE("steal", p1, 10);
687
688         p2 = talloc_realloc(root, NULL, char, 20);
689         CHECK_SIZE("steal", p1, 10);
690         CHECK_SIZE("steal", root, 30);
691
692         torture_assert("steal", talloc_steal(p1, NULL) == NULL,
693                 "failed: stealing NULL should give NULL\n");
694
695         torture_assert("steal", talloc_steal(p1, p1) == p1,
696                 "failed: stealing to ourselves is a nop\n");
697         CHECK_BLOCKS("steal", root, 3);
698         CHECK_SIZE("steal", root, 30);
699
700         talloc_steal(NULL, p1);
701         talloc_steal(NULL, p2);
702         CHECK_BLOCKS("steal", root, 1);
703         CHECK_SIZE("steal", root, 0);
704
705         talloc_free(p1);
706         talloc_steal(root, p2);
707         CHECK_BLOCKS("steal", root, 2);
708         CHECK_SIZE("steal", root, 20);
709         
710         talloc_free(p2);
711
712         CHECK_BLOCKS("steal", root, 1);
713         CHECK_SIZE("steal", root, 0);
714
715         talloc_free(root);
716
717         p1 = talloc_size(NULL, 3);
718         talloc_report_full(NULL, stderr);
719         CHECK_SIZE("steal", NULL, 3);
720         talloc_free(p1);
721
722         printf("success: steal\n");
723         return true;
724 }
725
726 /*
727   test move
728 */
729 static bool test_move(void)
730 {
731         void *root;
732         struct t_move {
733                 char *p;
734                 int *x;
735         } *t1, *t2;
736
737         printf("test: move\n# MOVE\n");
738
739         root = talloc_new(NULL);
740
741         t1 = talloc(root, struct t_move);
742         t2 = talloc(root, struct t_move);
743         t1->p = talloc_strdup(t1, "foo");
744         t1->x = talloc(t1, int);
745         *t1->x = 42;
746
747         t2->p = talloc_move(t2, &t1->p);
748         t2->x = talloc_move(t2, &t1->x);
749         torture_assert("move", t1->p == NULL && t1->x == NULL &&
750             strcmp(t2->p, "foo") == 0 && *t2->x == 42,
751                 "talloc move failed");
752
753         talloc_free(root);
754
755         printf("success: move\n");
756
757         return true;
758 }
759
760 /*
761   test talloc_realloc_fn
762 */
763 static bool test_realloc_fn(void)
764 {
765         void *root, *p1;
766
767         printf("test: realloc_fn\n# talloc_realloc_fn\n");
768
769         root = talloc_new(NULL);
770
771         p1 = talloc_realloc_fn(root, NULL, 10);
772         CHECK_BLOCKS("realloc_fn", root, 2);
773         CHECK_SIZE("realloc_fn", root, 10);
774         p1 = talloc_realloc_fn(root, p1, 20);
775         CHECK_BLOCKS("realloc_fn", root, 2);
776         CHECK_SIZE("realloc_fn", root, 20);
777         p1 = talloc_realloc_fn(root, p1, 0);
778         CHECK_BLOCKS("realloc_fn", root, 1);
779         CHECK_SIZE("realloc_fn", root, 0);
780
781         talloc_free(root);
782
783         printf("success: realloc_fn\n");
784         return true;
785 }
786
787
788 static bool test_unref_reparent(void)
789 {
790         void *root, *p1, *p2, *c1;
791
792         printf("test: unref_reparent\n# UNREFERENCE AFTER PARENT FREED\n");
793
794         root = talloc_named_const(NULL, 0, "root");
795         p1 = talloc_named_const(root, 1, "orig parent");
796         p2 = talloc_named_const(root, 1, "parent by reference");
797
798         c1 = talloc_named_const(p1, 1, "child");
799         talloc_reference(p2, c1);
800
801         CHECK_PARENT("unref_reparent", c1, p1);
802
803         talloc_free(p1);
804
805         CHECK_PARENT("unref_reparent", c1, p2);
806
807         talloc_unlink(p2, c1);
808
809         CHECK_SIZE("unref_reparent", root, 1);
810
811         talloc_free(p2);
812         talloc_free(root);
813
814         printf("success: unref_reparent\n");
815         return true;
816 }
817
818 /*
819   measure the speed of talloc versus malloc
820 */
821 static bool test_speed(void)
822 {
823         void *ctx = talloc_new(NULL);
824         unsigned count;
825         const int loop = 1000;
826         int i;
827         struct timeval tv;
828
829         printf("test: speed\n# TALLOC VS MALLOC SPEED\n");
830
831         tv = timeval_current();
832         count = 0;
833         do {
834                 void *p1, *p2, *p3;
835                 for (i=0;i<loop;i++) {
836                         p1 = talloc_size(ctx, loop % 100);
837                         p2 = talloc_strdup(p1, "foo bar");
838                         p3 = talloc_size(p1, 300);
839                         (void)p2;
840                         (void)p3;
841                         talloc_free(p1);
842                 }
843                 count += 3 * loop;
844         } while (timeval_elapsed(&tv) < 5.0);
845
846         fprintf(stderr, "talloc: %.0f ops/sec\n", count/timeval_elapsed(&tv));
847
848         talloc_free(ctx);
849
850         ctx = talloc_pool(NULL, 1024);
851
852         tv = timeval_current();
853         count = 0;
854         do {
855                 void *p1, *p2, *p3;
856                 for (i=0;i<loop;i++) {
857                         p1 = talloc_size(ctx, loop % 100);
858                         p2 = talloc_strdup(p1, "foo bar");
859                         p3 = talloc_size(p1, 300);
860                         (void)p2;
861                         (void)p3;
862                         talloc_free(p1);
863                 }
864                 count += 3 * loop;
865         } while (timeval_elapsed(&tv) < 5.0);
866
867         talloc_free(ctx);
868
869         fprintf(stderr, "talloc_pool: %.0f ops/sec\n", count/timeval_elapsed(&tv));
870
871         tv = timeval_current();
872         count = 0;
873         do {
874                 void *p1, *p2, *p3;
875                 for (i=0;i<loop;i++) {
876                         p1 = malloc(loop % 100);
877                         p2 = strdup("foo bar");
878                         p3 = malloc(300);
879                         free(p1);
880                         free(p2);
881                         free(p3);
882                 }
883                 count += 3 * loop;
884         } while (timeval_elapsed(&tv) < 5.0);
885         fprintf(stderr, "malloc: %.0f ops/sec\n", count/timeval_elapsed(&tv));
886
887         printf("success: speed\n");
888
889         return true;
890 }
891
892 static bool test_lifeless(void)
893 {
894         void *top = talloc_new(NULL);
895         char *parent, *child; 
896         void *child_owner = talloc_new(NULL);
897
898         printf("test: lifeless\n# TALLOC_UNLINK LOOP\n");
899
900         parent = talloc_strdup(top, "parent");
901         child = talloc_strdup(parent, "child");  
902         (void)talloc_reference(child, parent);
903         (void)talloc_reference(child_owner, child); 
904         talloc_report_full(top, stderr);
905         talloc_unlink(top, parent);
906         talloc_unlink(top, child);
907         talloc_report_full(top, stderr);
908         talloc_free(top);
909         talloc_free(child_owner);
910         talloc_free(child);
911
912         printf("success: lifeless\n");
913         return true;
914 }
915
916 static int loop_destructor_count;
917
918 static int test_loop_destructor(char *ptr)
919 {
920         loop_destructor_count++;
921         return 0;
922 }
923
924 static bool test_loop(void)
925 {
926         void *top = talloc_new(NULL);
927         char *parent;
928         struct req1 {
929                 char *req2, *req3;
930         } *req1;
931
932         printf("test: loop\n# TALLOC LOOP DESTRUCTION\n");
933
934         parent = talloc_strdup(top, "parent");
935         req1 = talloc(parent, struct req1);
936         req1->req2 = talloc_strdup(req1, "req2");  
937         talloc_set_destructor(req1->req2, test_loop_destructor);
938         req1->req3 = talloc_strdup(req1, "req3");
939         (void)talloc_reference(req1->req3, req1);
940         talloc_report_full(top, stderr);
941         talloc_free(parent);
942         talloc_report_full(top, stderr);
943         talloc_report_full(NULL, stderr);
944         talloc_free(top);
945
946         torture_assert("loop", loop_destructor_count == 1, 
947                                    "FAILED TO FIRE LOOP DESTRUCTOR\n");
948         loop_destructor_count = 0;
949
950         printf("success: loop\n");
951         return true;
952 }
953
954 static int fail_destructor_str(char *ptr)
955 {
956         return -1;
957 }
958
959 static bool test_free_parent_deny_child(void)
960 {
961         void *top = talloc_new(NULL);
962         char *level1;
963         char *level2;
964         char *level3;
965
966         printf("test: free_parent_deny_child\n# TALLOC FREE PARENT DENY CHILD\n");
967
968         level1 = talloc_strdup(top, "level1");
969         level2 = talloc_strdup(level1, "level2");
970         level3 = talloc_strdup(level2, "level3");
971
972         talloc_set_destructor(level3, fail_destructor_str);
973         talloc_free(level1);
974         talloc_set_destructor(level3, NULL);
975
976         CHECK_PARENT("free_parent_deny_child", level3, top);
977
978         talloc_free(top);
979
980         printf("success: free_parent_deny_child\n");
981         return true;
982 }
983
984 static bool test_talloc_ptrtype(void)
985 {
986         void *top = talloc_new(NULL);
987         struct struct1 {
988                 int foo;
989                 int bar;
990         } *s1, *s2, **s3, ***s4;
991         const char *location1;
992         const char *location2;
993         const char *location3;
994         const char *location4;
995
996         printf("test: ptrtype\n# TALLOC PTRTYPE\n");
997
998         s1 = talloc_ptrtype(top, s1);location1 = __location__;
999
1000         if (talloc_get_size(s1) != sizeof(struct struct1)) {
1001                 printf("failure: ptrtype [\n"
1002                   "talloc_ptrtype() allocated the wrong size %lu (should be %lu)\n"
1003                   "]\n", (unsigned long)talloc_get_size(s1),
1004                            (unsigned long)sizeof(struct struct1));
1005                 return false;
1006         }
1007
1008         if (strcmp(location1, talloc_get_name(s1)) != 0) {
1009                 printf("failure: ptrtype [\n"
1010                   "talloc_ptrtype() sets the wrong name '%s' (should be '%s')\n]\n",
1011                         talloc_get_name(s1), location1);
1012                 return false;
1013         }
1014
1015         s2 = talloc_array_ptrtype(top, s2, 10);location2 = __location__;
1016
1017         if (talloc_get_size(s2) != (sizeof(struct struct1) * 10)) {
1018                 printf("failure: ptrtype [\n"
1019                            "talloc_array_ptrtype() allocated the wrong size "
1020                        "%lu (should be %lu)\n]\n",
1021                         (unsigned long)talloc_get_size(s2),
1022                     (unsigned long)(sizeof(struct struct1)*10));
1023                 return false;
1024         }
1025
1026         if (strcmp(location2, talloc_get_name(s2)) != 0) {
1027                 printf("failure: ptrtype [\n"
1028                 "talloc_array_ptrtype() sets the wrong name '%s' (should be '%s')\n]\n",
1029                         talloc_get_name(s2), location2);
1030                 return false;
1031         }
1032
1033         s3 = talloc_array_ptrtype(top, s3, 10);location3 = __location__;
1034
1035         if (talloc_get_size(s3) != (sizeof(struct struct1 *) * 10)) {
1036                 printf("failure: ptrtype [\n"
1037                            "talloc_array_ptrtype() allocated the wrong size "
1038                        "%lu (should be %lu)\n]\n",
1039                            (unsigned long)talloc_get_size(s3),
1040                        (unsigned long)(sizeof(struct struct1 *)*10));
1041                 return false;
1042         }
1043
1044         torture_assert_str_equal("ptrtype", location3, talloc_get_name(s3),
1045                 "talloc_array_ptrtype() sets the wrong name");
1046
1047         s4 = talloc_array_ptrtype(top, s4, 10);location4 = __location__;
1048
1049         if (talloc_get_size(s4) != (sizeof(struct struct1 **) * 10)) {
1050                 printf("failure: ptrtype [\n"
1051                       "talloc_array_ptrtype() allocated the wrong size "
1052                        "%lu (should be %lu)\n]\n",
1053                            (unsigned long)talloc_get_size(s4),
1054                        (unsigned long)(sizeof(struct struct1 **)*10));
1055                 return false;
1056         }
1057
1058         torture_assert_str_equal("ptrtype", location4, talloc_get_name(s4),
1059                 "talloc_array_ptrtype() sets the wrong name");
1060
1061         talloc_free(top);
1062
1063         printf("success: ptrtype\n");
1064         return true;
1065 }
1066
1067 static int _test_talloc_free_in_destructor(void **ptr)
1068 {
1069         talloc_free(*ptr);
1070         return 0;
1071 }
1072
1073 static bool test_talloc_free_in_destructor(void)
1074 {
1075         void *level0;
1076         void *level1;
1077         void *level2;
1078         void *level3;
1079         void *level4;
1080         void **level5;
1081
1082         printf("test: free_in_destructor\n# TALLOC FREE IN DESTRUCTOR\n");
1083
1084         level0 = talloc_new(NULL);
1085         level1 = talloc_new(level0);
1086         level2 = talloc_new(level1);
1087         level3 = talloc_new(level2);
1088         level4 = talloc_new(level3);
1089         level5 = talloc(level4, void *);
1090
1091         *level5 = level3;
1092         (void)talloc_reference(level0, level3);
1093         (void)talloc_reference(level3, level3);
1094         (void)talloc_reference(level5, level3);
1095
1096         talloc_set_destructor(level5, _test_talloc_free_in_destructor);
1097
1098         talloc_free(level1);
1099
1100         talloc_free(level0);
1101
1102         printf("success: free_in_destructor\n");
1103         return true;
1104 }
1105
1106 static bool test_autofree(void)
1107 {
1108 #if _SAMBA_BUILD_ < 4
1109         /* autofree test would kill smbtorture */
1110         void *p;
1111         printf("test: autofree\n# TALLOC AUTOFREE CONTEXT\n");
1112
1113         p = talloc_autofree_context();
1114         talloc_free(p);
1115
1116         p = talloc_autofree_context();
1117         talloc_free(p);
1118
1119         printf("success: autofree\n");
1120 #endif
1121         return true;
1122 }
1123
1124 static bool test_pool(void)
1125 {
1126         void *pool;
1127         void *p1, *p2, *p3, *p4;
1128         void *p2_2;
1129
1130         pool = talloc_pool(NULL, 1024);
1131
1132         p1 = talloc_size(pool, 80);
1133         memset(p1, 0x11, talloc_get_size(p1));
1134         p2 = talloc_size(pool, 20);
1135         memset(p2, 0x11, talloc_get_size(p2));
1136         p3 = talloc_size(p1, 50);
1137         memset(p3, 0x11, talloc_get_size(p3));
1138         p4 = talloc_size(p3, 1000);
1139         memset(p4, 0x11, talloc_get_size(p4));
1140
1141 #if 1 /* this relies on ALWAYS_REALLOC == 0 in talloc.c */
1142         p2_2 = talloc_realloc_size(pool, p2, 20+1);
1143         torture_assert("pool realloc 20+1", p2_2 == p2, "failed: pointer changed");
1144         memset(p2, 0x11, talloc_get_size(p2));
1145         p2_2 = talloc_realloc_size(pool, p2, 20-1);
1146         torture_assert("pool realloc 20-1", p2_2 == p2, "failed: pointer changed");
1147         memset(p2, 0x11, talloc_get_size(p2));
1148         p2_2 = talloc_realloc_size(pool, p2, 20-1);
1149         torture_assert("pool realloc 20-1", p2_2 == p2, "failed: pointer changed");
1150         memset(p2, 0x11, talloc_get_size(p2));
1151
1152         talloc_free(p3);
1153
1154         /* this should reclaim the memory of p4 and p3 */
1155         p2_2 = talloc_realloc_size(pool, p2, 400);
1156         torture_assert("pool realloc 400", p2_2 == p2, "failed: pointer changed");
1157         memset(p2, 0x11, talloc_get_size(p2));
1158
1159         talloc_free(p1);
1160
1161         /* this should reclaim the memory of p1 */
1162         p2_2 = talloc_realloc_size(pool, p2, 800);
1163         torture_assert("pool realloc 800", p2_2 == p1, "failed: pointer not changed");
1164         p2 = p2_2;
1165         memset(p2, 0x11, talloc_get_size(p2));
1166
1167         /* this should do a malloc */
1168         p2_2 = talloc_realloc_size(pool, p2, 1800);
1169         torture_assert("pool realloc 1800", p2_2 != p2, "failed: pointer not changed");
1170         p2 = p2_2;
1171         memset(p2, 0x11, talloc_get_size(p2));
1172
1173         /* this should reclaim the memory from the pool */
1174         p3 = talloc_size(pool, 80);
1175         torture_assert("pool alloc 80", p3 == p1, "failed: pointer changed");
1176         memset(p3, 0x11, talloc_get_size(p3));
1177
1178         talloc_free(p2);
1179         talloc_free(p3);
1180
1181         p1 = talloc_size(pool, 80);
1182         memset(p1, 0x11, talloc_get_size(p1));
1183         p2 = talloc_size(pool, 20);
1184         memset(p2, 0x11, talloc_get_size(p2));
1185
1186         talloc_free(p1);
1187
1188         p2_2 = talloc_realloc_size(pool, p2, 20-1);
1189         torture_assert("pool realloc 20-1", p2_2 == p2, "failed: pointer changed");
1190         memset(p2, 0x11, talloc_get_size(p2));
1191         p2_2 = talloc_realloc_size(pool, p2, 20-1);
1192         torture_assert("pool realloc 20-1", p2_2 == p2, "failed: pointer changed");
1193         memset(p2, 0x11, talloc_get_size(p2));
1194
1195         /* this should do a malloc */
1196         p2_2 = talloc_realloc_size(pool, p2, 1800);
1197         torture_assert("pool realloc 1800", p2_2 != p2, "failed: pointer not changed");
1198         p2 = p2_2;
1199         memset(p2, 0x11, talloc_get_size(p2));
1200
1201         /* this should reclaim the memory from the pool */
1202         p3 = talloc_size(pool, 800);
1203         torture_assert("pool alloc 800", p3 == p1, "failed: pointer changed");
1204         memset(p3, 0x11, talloc_get_size(p3));
1205
1206 #endif /* this relies on ALWAYS_REALLOC == 0 in talloc.c */
1207
1208         talloc_free(pool);
1209
1210         return true;
1211 }
1212
1213 static bool test_pool_steal(void)
1214 {
1215         void *root;
1216         void *pool;
1217         void *p1, *p2;
1218         void *p1_2, *p2_2;
1219         size_t hdr;
1220         size_t ofs1, ofs2;
1221
1222         root = talloc_new(NULL);
1223         pool = talloc_pool(root, 1024);
1224
1225         p1 = talloc_size(pool, 4 * 16);
1226         torture_assert("pool allocate 4 * 16", p1 != NULL, "failed ");
1227         memset(p1, 0x11, talloc_get_size(p1));
1228         p2 = talloc_size(pool, 4 * 16);
1229         torture_assert("pool allocate 4 * 16", p2 > p1, "failed: !(p2 > p1) ");
1230         memset(p2, 0x11, talloc_get_size(p2));
1231
1232         ofs1 = PTR_DIFF(p2, p1);
1233         hdr = ofs1 - talloc_get_size(p1);
1234
1235         talloc_steal(root, p1);
1236         talloc_steal(root, p2);
1237
1238         talloc_free(pool);
1239
1240         p1_2 = p1;
1241
1242 #if 1 /* this relies on ALWAYS_REALLOC == 0 in talloc.c */
1243         p1_2 = talloc_realloc_size(root, p1, 5 * 16);
1244         torture_assert("pool realloc 5 * 16", p1_2 > p2, "failed: pointer not changed");
1245         memset(p1_2, 0x11, talloc_get_size(p1_2));
1246         ofs1 = PTR_DIFF(p1_2, p2);
1247         ofs2 = talloc_get_size(p2) + hdr;
1248
1249         torture_assert("pool realloc ", ofs1 == ofs2, "failed: pointer offset unexpected");
1250
1251         p2_2 = talloc_realloc_size(root, p2, 3 * 16);
1252         torture_assert("pool realloc 5 * 16", p2_2 == p2, "failed: pointer changed");
1253         memset(p2_2, 0x11, talloc_get_size(p2_2));
1254 #endif /* this relies on ALWAYS_REALLOC == 0 in talloc.c */
1255
1256         talloc_free(p1_2);
1257
1258         p2_2 = p2;
1259
1260 #if 1 /* this relies on ALWAYS_REALLOC == 0 in talloc.c */
1261         /* now we should reclaim the full pool */
1262         p2_2 = talloc_realloc_size(root, p2, 8 * 16);
1263         torture_assert("pool realloc 8 * 16", p2_2 == p1, "failed: pointer not expected");
1264         p2 = p2_2;
1265         memset(p2_2, 0x11, talloc_get_size(p2_2));
1266
1267         /* now we malloc and free the full pool space */
1268         p2_2 = talloc_realloc_size(root, p2, 2 * 1024);
1269         torture_assert("pool realloc 2 * 1024", p2_2 != p1, "failed: pointer not expected");
1270         memset(p2_2, 0x11, talloc_get_size(p2_2));
1271
1272 #endif /* this relies on ALWAYS_REALLOC == 0 in talloc.c */
1273
1274         talloc_free(p2_2);
1275
1276         talloc_free(root);
1277
1278         return true;
1279 }
1280
1281 static bool test_pool_nest(void)
1282 {
1283         void *p1, *p2, *p3;
1284         void *e = talloc_new(NULL);
1285
1286         p1 = talloc_pool(NULL, 1024);
1287         torture_assert("talloc_pool", p1 != NULL, "failed");
1288
1289         p2 = talloc_pool(p1, 500);
1290         torture_assert("talloc_pool", p2 != NULL, "failed");
1291
1292         p3 = talloc_size(p2, 10);
1293
1294         talloc_steal(e, p3);
1295
1296         talloc_free(p2);
1297
1298         talloc_free(p3);
1299
1300         talloc_free(p1);
1301
1302         return true;
1303 }
1304
1305 struct pooled {
1306         char *s1;
1307         char *s2;
1308         char *s3;
1309 };
1310
1311 static bool test_pooled_object(void)
1312 {
1313         struct pooled *p;
1314         const char *s1 = "hello";
1315         const char *s2 = "world";
1316         const char *s3 = "";
1317
1318         p = talloc_pooled_object(NULL, struct pooled, 3,
1319                         strlen(s1)+strlen(s2)+strlen(s3)+3);
1320
1321         if (talloc_get_size(p) != sizeof(struct pooled)) {
1322                 return false;
1323         }
1324
1325         p->s1 = talloc_strdup(p, s1);
1326
1327         TALLOC_FREE(p->s1);
1328         p->s1 = talloc_strdup(p, s2);
1329         TALLOC_FREE(p->s1);
1330
1331         p->s1 = talloc_strdup(p, s1);
1332         p->s2 = talloc_strdup(p, s2);
1333         p->s3 = talloc_strdup(p, s3);
1334
1335         TALLOC_FREE(p);
1336         return true;
1337 }
1338
1339 static bool test_free_ref_null_context(void)
1340 {
1341         void *p1, *p2, *p3;
1342         int ret;
1343
1344         talloc_disable_null_tracking();
1345         p1 = talloc_new(NULL);
1346         p2 = talloc_new(NULL);
1347
1348         p3 = talloc_reference(p2, p1);
1349         torture_assert("reference", p3 == p1, "failed: reference on null");
1350
1351         ret = talloc_free(p1);
1352         torture_assert("ref free with null parent", ret == 0, "failed: free with null parent");
1353         talloc_free(p2);
1354
1355         talloc_enable_null_tracking_no_autofree();
1356         p1 = talloc_new(NULL);
1357         p2 = talloc_new(NULL);
1358
1359         p3 = talloc_reference(p2, p1);
1360         torture_assert("reference", p3 == p1, "failed: reference on null");
1361
1362         ret = talloc_free(p1);
1363         torture_assert("ref free with null tracked parent", ret == 0, "failed: free with null parent");
1364         talloc_free(p2);
1365
1366         return true;
1367 }
1368
1369 static bool test_rusty(void)
1370 {
1371         void *root;
1372         const char *p1;
1373
1374         talloc_enable_null_tracking();
1375         root = talloc_new(NULL);
1376         p1 = talloc_strdup(root, "foo");
1377         talloc_increase_ref_count(p1);
1378         talloc_report_full(root, stdout);
1379         talloc_free(root);
1380         CHECK_BLOCKS("null_context", NULL, 2);
1381         return true;
1382 }
1383
1384 static bool test_free_children(void)
1385 {
1386         void *root;
1387         char *p1, *p2;
1388         const char *name, *name2;
1389
1390         talloc_enable_null_tracking();
1391         root = talloc_new(NULL);
1392         p1 = talloc_strdup(root, "foo1");
1393         p2 = talloc_strdup(p1, "foo2");
1394         (void)p2;
1395
1396         talloc_set_name(p1, "%s", "testname");
1397         talloc_free_children(p1);
1398         /* check its still a valid talloc ptr */
1399         talloc_get_size(talloc_get_name(p1));
1400         if (strcmp(talloc_get_name(p1), "testname") != 0) {
1401                 return false;
1402         }
1403
1404         talloc_set_name(p1, "%s", "testname");
1405         name = talloc_get_name(p1);
1406         talloc_free_children(p1);
1407         /* check its still a valid talloc ptr */
1408         talloc_get_size(talloc_get_name(p1));
1409         torture_assert("name", name == talloc_get_name(p1), "name ptr changed");
1410         torture_assert("namecheck", strcmp(talloc_get_name(p1), "testname") == 0,
1411                        "wrong name");
1412         CHECK_BLOCKS("name1", p1, 2);
1413
1414         /* note that this does not free the old child name */
1415         talloc_set_name_const(p1, "testname2");
1416         name2 = talloc_get_name(p1);
1417         /* but this does */
1418         talloc_free_children(p1);
1419         (void)name2;
1420         torture_assert("namecheck", strcmp(talloc_get_name(p1), "testname2") == 0,
1421                        "wrong name");
1422         CHECK_BLOCKS("name1", p1, 1);
1423
1424         talloc_report_full(root, stdout);
1425         talloc_free(root);
1426         return true;
1427 }
1428
1429 static bool test_memlimit(void)
1430 {
1431         void *root;
1432         char *l1, *l2, *l3, *l4, *l5, *t;
1433         char *pool;
1434         int i;
1435
1436         printf("test: memlimit\n# MEMORY LIMITS\n");
1437
1438         printf("==== talloc_new(NULL)\n");
1439         root = talloc_new(NULL);
1440
1441         talloc_report_full(root, stdout);
1442
1443         printf("==== talloc_size(root, 2048)\n");
1444         l1 = talloc_size(root, 2048);
1445         torture_assert("memlimit", l1 != NULL,
1446                 "failed: alloc should not fail due to memory limit\n");
1447
1448         talloc_report_full(root, stdout);
1449
1450         printf("==== talloc_free(l1)\n");
1451         talloc_free(l1);
1452
1453         talloc_report_full(root, stdout);
1454
1455         printf("==== talloc_strdup(root, level 1)\n");
1456         l1 = talloc_strdup(root, "level 1");
1457         torture_assert("memlimit", l1 != NULL,
1458                 "failed: alloc should not fail due to memory limit\n");
1459
1460         talloc_report_full(root, stdout);
1461
1462         printf("==== talloc_set_memlimit(l1, 2048)\n");
1463         torture_assert("memlimit", talloc_set_memlimit(l1, 2048) == 0,
1464                 "failed: setting memlimit should never fail\n");
1465
1466         talloc_report_full(root, stdout);
1467
1468         printf("==== talloc_size(root, 2048)\n");
1469         l2 = talloc_size(l1, 2048);
1470         torture_assert("memlimit", l2 == NULL,
1471                 "failed: alloc should fail due to memory limit\n");
1472
1473         talloc_report_full(root, stdout);
1474
1475         printf("==== talloc_strdup(l1, level 2)\n");
1476         l2 = talloc_strdup(l1, "level 2");
1477         torture_assert("memlimit", l2 != NULL,
1478                 "failed: alloc should not fail due to memory limit\n");
1479
1480         talloc_report_full(root, stdout);
1481
1482         printf("==== talloc_free(l2)\n");
1483         talloc_free(l2);
1484
1485         talloc_report_full(root, stdout);
1486
1487         printf("==== talloc_size(NULL, 2048)\n");
1488         l2 = talloc_size(NULL, 2048);
1489
1490         talloc_report_full(root, stdout);
1491
1492         printf("==== talloc_steal(l1, l2)\n");
1493         talloc_steal(l1, l2);
1494
1495         talloc_report_full(root, stdout);
1496
1497         printf("==== talloc_strdup(l2, level 3)\n");
1498         l3 = talloc_strdup(l2, "level 3");
1499         torture_assert("memlimit", l3 == NULL,
1500                 "failed: alloc should fail due to memory limit\n");
1501
1502         talloc_report_full(root, stdout);
1503
1504         printf("==== talloc_free(l2)\n");
1505         talloc_free(l2);
1506
1507         talloc_report_full(root, stdout);
1508
1509         printf("==== talloc_strdup(NULL, level 2)\n");
1510         l2 = talloc_strdup(NULL, "level 2");
1511         talloc_steal(l1, l2);
1512
1513         talloc_report_full(root, stdout);
1514
1515         printf("==== talloc_strdup(l2, level 3)\n");
1516         l3 = talloc_strdup(l2, "level 3");
1517         torture_assert("memlimit", l3 != NULL,
1518                 "failed: alloc should not fail due to memory limit\n");
1519
1520         talloc_report_full(root, stdout);
1521
1522         printf("==== talloc_set_memlimit(l3, 1024)\n");
1523         torture_assert("memlimit", talloc_set_memlimit(l3, 1024) == 0,
1524                 "failed: setting memlimit should never fail\n");
1525
1526         talloc_report_full(root, stdout);
1527
1528         printf("==== talloc_strdup(l3, level 4)\n");
1529         l4 = talloc_strdup(l3, "level 4");
1530         torture_assert("memlimit", l4 != NULL,
1531                 "failed: alloc should not fail due to memory limit\n");
1532
1533         talloc_report_full(root, stdout);
1534
1535         printf("==== talloc_set_memlimit(l4, 512)\n");
1536         torture_assert("memlimit", talloc_set_memlimit(l4, 512) == 0,
1537                 "failed: setting memlimit should never fail\n");
1538
1539         talloc_report_full(root, stdout);
1540
1541         printf("==== talloc_strdup(l4, level 5)\n");
1542         l5 = talloc_strdup(l4, "level 5");
1543         torture_assert("memlimit", l5 != NULL,
1544                 "failed: alloc should not fail due to memory limit\n");
1545
1546         talloc_report_full(root, stdout);
1547
1548         printf("==== talloc_realloc(NULL, l5, char, 600)\n");
1549         t = talloc_realloc(NULL, l5, char, 600);
1550         torture_assert("memlimit", t == NULL,
1551                 "failed: alloc should fail due to memory limit\n");
1552
1553         talloc_report_full(root, stdout);
1554
1555         printf("==== talloc_realloc(NULL, l5, char, 5)\n");
1556         l5 = talloc_realloc(NULL, l5, char, 5);
1557         torture_assert("memlimit", l5 != NULL,
1558                 "failed: alloc should not fail due to memory limit\n");
1559
1560         talloc_report_full(root, stdout);
1561
1562         printf("==== talloc_strdup(l3, level 4)\n");
1563         l4 = talloc_strdup(l3, "level 4");
1564         torture_assert("memlimit", l4 != NULL,
1565                 "failed: alloc should not fail due to memory limit\n");
1566
1567         talloc_report_full(root, stdout);
1568
1569         printf("==== talloc_set_memlimit(l4, 512)\n");
1570         torture_assert("memlimit", talloc_set_memlimit(l4, 512) == 0,
1571                 "failed: setting memlimit should never fail\n");
1572
1573         talloc_report_full(root, stdout);
1574
1575         printf("==== talloc_strdup(l4, level 5)\n");
1576         l5 = talloc_strdup(l4, "level 5");
1577         torture_assert("memlimit", l5 != NULL,
1578                 "failed: alloc should not fail due to memory limit\n");
1579
1580         talloc_report_full(root, stdout);
1581
1582         printf("==== Make new temp context and steal l5\n");
1583         t = talloc_new(root);
1584         talloc_steal(t, l5);
1585
1586         talloc_report_full(root, stdout);
1587
1588         printf("==== talloc_size(t, 2048)\n");
1589         l1 = talloc_size(t, 2048);
1590         torture_assert("memlimit", l1 != NULL,
1591                 "failed: alloc should not fail due to memory limit\n");
1592
1593         talloc_report_full(root, stdout);
1594         talloc_free(root);
1595
1596         /* Test memlimits with pools. */
1597         pool = talloc_pool(NULL, 10*1024);
1598         torture_assert("memlimit", pool != NULL,
1599                 "failed: alloc should not fail due to memory limit\n");
1600         talloc_set_memlimit(pool, 10*1024);
1601         for (i = 0; i < 9; i++) {
1602                 l1 = talloc_size(pool, 1024);
1603                 torture_assert("memlimit", l1 != NULL,
1604                         "failed: alloc should not fail due to memory limit\n");
1605         }
1606         /* The next alloc should fail. */
1607         l2 = talloc_size(pool, 1024);
1608         torture_assert("memlimit", l2 == NULL,
1609                         "failed: alloc should fail due to memory limit\n");
1610
1611         /* Moving one of the children shouldn't change the limit,
1612            as it's still inside the pool. */
1613         root = talloc_new(NULL);
1614         talloc_steal(root, l1);
1615         l2 = talloc_size(pool, 1024);
1616         torture_assert("memlimit", l2 == NULL,
1617                         "failed: alloc should fail due to memory limit\n");
1618
1619         talloc_free(pool);
1620         talloc_free(root);
1621         printf("success: memlimit\n");
1622
1623         return true;
1624 }
1625
1626 static void test_reset(void)
1627 {
1628         talloc_set_log_fn(test_log_stdout);
1629         test_abort_stop();
1630         talloc_disable_null_tracking();
1631         talloc_enable_null_tracking_no_autofree();
1632 }
1633
1634 bool torture_local_talloc(struct torture_context *tctx)
1635 {
1636         bool ret = true;
1637
1638         setlinebuf(stdout);
1639
1640         test_reset();
1641         ret &= test_pooled_object();
1642         test_reset();
1643         ret &= test_pool_nest();
1644         test_reset();
1645         ret &= test_ref1();
1646         test_reset();
1647         ret &= test_ref2();
1648         test_reset();
1649         ret &= test_ref3();
1650         test_reset();
1651         ret &= test_ref4();
1652         test_reset();
1653         ret &= test_unlink1(); 
1654         test_reset();
1655         ret &= test_misc();
1656         test_reset();
1657         ret &= test_realloc();
1658         test_reset();
1659         ret &= test_realloc_child(); 
1660         test_reset();
1661         ret &= test_steal(); 
1662         test_reset();
1663         ret &= test_move(); 
1664         test_reset();
1665         ret &= test_unref_reparent();
1666         test_reset();
1667         ret &= test_realloc_fn(); 
1668         test_reset();
1669         ret &= test_type();
1670         test_reset();
1671         ret &= test_lifeless(); 
1672         test_reset();
1673         ret &= test_loop();
1674         test_reset();
1675         ret &= test_free_parent_deny_child(); 
1676         test_reset();
1677         ret &= test_talloc_ptrtype();
1678         test_reset();
1679         ret &= test_talloc_free_in_destructor();
1680         test_reset();
1681         ret &= test_pool();
1682         test_reset();
1683         ret &= test_pool_steal();
1684         test_reset();
1685         ret &= test_free_ref_null_context();
1686         test_reset();
1687         ret &= test_rusty();
1688         test_reset();
1689         ret &= test_free_children();
1690         test_reset();
1691         ret &= test_memlimit();
1692
1693
1694         if (ret) {
1695                 test_reset();
1696                 ret &= test_speed();
1697         }
1698         test_reset();
1699         ret &= test_autofree();
1700
1701         test_reset();
1702         talloc_disable_null_tracking();
1703         return ret;
1704 }