Pass CPPFLAGS onto configure to enable hardening.
[abartlet/talloc-debian.git] / 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 struct new_parent {
985         void *new_parent;
986         char val[20];
987 };
988
989 static int reparenting_destructor(struct new_parent *np)
990 {
991         talloc_set_destructor(np, NULL);
992         (void)talloc_move(np->new_parent, &np);
993         return -1;
994 }
995
996 static bool test_free_parent_reparent_child(void)
997 {
998         void *top = talloc_new(NULL);
999         char *level1;
1000         char *alternate_level1;
1001         char *level2;
1002         struct new_parent *level3;
1003
1004         printf("test: free_parent_reparent_child\n# "
1005                 "TALLOC FREE PARENT REPARENT CHILD\n");
1006
1007         level1 = talloc_strdup(top, "level1");
1008         alternate_level1 = talloc_strdup(top, "alternate_level1");
1009         level2 = talloc_strdup(level1, "level2");
1010         level3 = talloc(level2, struct new_parent);
1011         level3->new_parent = alternate_level1;
1012         memset(level3->val, 'x', sizeof(level3->val));
1013
1014         talloc_set_destructor(level3, reparenting_destructor);
1015         talloc_free(level1);
1016
1017         CHECK_PARENT("free_parent_reparent_child",
1018                 level3, alternate_level1);
1019
1020         talloc_free(top);
1021
1022         printf("success: free_parent_reparent_child\n");
1023         return true;
1024 }
1025
1026 static bool test_free_parent_reparent_child_in_pool(void)
1027 {
1028         void *top = talloc_new(NULL);
1029         char *level1;
1030         char *alternate_level1;
1031         char *level2;
1032         void *pool;
1033         struct new_parent *level3;
1034
1035         printf("test: free_parent_reparent_child_in_pool\n# "
1036                 "TALLOC FREE PARENT REPARENT CHILD IN POOL\n");
1037
1038         pool = talloc_pool(top, 1024);
1039         level1 = talloc_strdup(pool, "level1");
1040         alternate_level1 = talloc_strdup(top, "alternate_level1");
1041         level2 = talloc_strdup(level1, "level2");
1042         level3 = talloc(level2, struct new_parent);
1043         level3->new_parent = alternate_level1;
1044         memset(level3->val, 'x', sizeof(level3->val));
1045
1046         talloc_set_destructor(level3, reparenting_destructor);
1047         talloc_free(level1);
1048         talloc_set_destructor(level3, NULL);
1049
1050         CHECK_PARENT("free_parent_reparent_child_in_pool",
1051                 level3, alternate_level1);
1052
1053         /* Even freeing alternate_level1 should leave pool alone. */
1054         talloc_free(alternate_level1);
1055         talloc_free(top);
1056
1057         printf("success: free_parent_reparent_child_in_pool\n");
1058         return true;
1059 }
1060
1061
1062 static bool test_talloc_ptrtype(void)
1063 {
1064         void *top = talloc_new(NULL);
1065         struct struct1 {
1066                 int foo;
1067                 int bar;
1068         } *s1, *s2, **s3, ***s4;
1069         const char *location1;
1070         const char *location2;
1071         const char *location3;
1072         const char *location4;
1073
1074         printf("test: ptrtype\n# TALLOC PTRTYPE\n");
1075
1076         s1 = talloc_ptrtype(top, s1);location1 = __location__;
1077
1078         if (talloc_get_size(s1) != sizeof(struct struct1)) {
1079                 printf("failure: ptrtype [\n"
1080                   "talloc_ptrtype() allocated the wrong size %lu (should be %lu)\n"
1081                   "]\n", (unsigned long)talloc_get_size(s1),
1082                            (unsigned long)sizeof(struct struct1));
1083                 return false;
1084         }
1085
1086         if (strcmp(location1, talloc_get_name(s1)) != 0) {
1087                 printf("failure: ptrtype [\n"
1088                   "talloc_ptrtype() sets the wrong name '%s' (should be '%s')\n]\n",
1089                         talloc_get_name(s1), location1);
1090                 return false;
1091         }
1092
1093         s2 = talloc_array_ptrtype(top, s2, 10);location2 = __location__;
1094
1095         if (talloc_get_size(s2) != (sizeof(struct struct1) * 10)) {
1096                 printf("failure: ptrtype [\n"
1097                            "talloc_array_ptrtype() allocated the wrong size "
1098                        "%lu (should be %lu)\n]\n",
1099                         (unsigned long)talloc_get_size(s2),
1100                     (unsigned long)(sizeof(struct struct1)*10));
1101                 return false;
1102         }
1103
1104         if (strcmp(location2, talloc_get_name(s2)) != 0) {
1105                 printf("failure: ptrtype [\n"
1106                 "talloc_array_ptrtype() sets the wrong name '%s' (should be '%s')\n]\n",
1107                         talloc_get_name(s2), location2);
1108                 return false;
1109         }
1110
1111         s3 = talloc_array_ptrtype(top, s3, 10);location3 = __location__;
1112
1113         if (talloc_get_size(s3) != (sizeof(struct struct1 *) * 10)) {
1114                 printf("failure: ptrtype [\n"
1115                            "talloc_array_ptrtype() allocated the wrong size "
1116                        "%lu (should be %lu)\n]\n",
1117                            (unsigned long)talloc_get_size(s3),
1118                        (unsigned long)(sizeof(struct struct1 *)*10));
1119                 return false;
1120         }
1121
1122         torture_assert_str_equal("ptrtype", location3, talloc_get_name(s3),
1123                 "talloc_array_ptrtype() sets the wrong name");
1124
1125         s4 = talloc_array_ptrtype(top, s4, 10);location4 = __location__;
1126
1127         if (talloc_get_size(s4) != (sizeof(struct struct1 **) * 10)) {
1128                 printf("failure: ptrtype [\n"
1129                       "talloc_array_ptrtype() allocated the wrong size "
1130                        "%lu (should be %lu)\n]\n",
1131                            (unsigned long)talloc_get_size(s4),
1132                        (unsigned long)(sizeof(struct struct1 **)*10));
1133                 return false;
1134         }
1135
1136         torture_assert_str_equal("ptrtype", location4, talloc_get_name(s4),
1137                 "talloc_array_ptrtype() sets the wrong name");
1138
1139         talloc_free(top);
1140
1141         printf("success: ptrtype\n");
1142         return true;
1143 }
1144
1145 static int _test_talloc_free_in_destructor(void **ptr)
1146 {
1147         talloc_free(*ptr);
1148         return 0;
1149 }
1150
1151 static bool test_talloc_free_in_destructor(void)
1152 {
1153         void *level0;
1154         void *level1;
1155         void *level2;
1156         void *level3;
1157         void *level4;
1158         void **level5;
1159
1160         printf("test: free_in_destructor\n# TALLOC FREE IN DESTRUCTOR\n");
1161
1162         level0 = talloc_new(NULL);
1163         level1 = talloc_new(level0);
1164         level2 = talloc_new(level1);
1165         level3 = talloc_new(level2);
1166         level4 = talloc_new(level3);
1167         level5 = talloc(level4, void *);
1168
1169         *level5 = level3;
1170         (void)talloc_reference(level0, level3);
1171         (void)talloc_reference(level3, level3);
1172         (void)talloc_reference(level5, level3);
1173
1174         talloc_set_destructor(level5, _test_talloc_free_in_destructor);
1175
1176         talloc_free(level1);
1177
1178         talloc_free(level0);
1179
1180         printf("success: free_in_destructor\n");
1181         return true;
1182 }
1183
1184 static bool test_autofree(void)
1185 {
1186 #if _SAMBA_BUILD_ < 4
1187         /* autofree test would kill smbtorture */
1188         void *p;
1189         printf("test: autofree\n# TALLOC AUTOFREE CONTEXT\n");
1190
1191         p = talloc_autofree_context();
1192         talloc_free(p);
1193
1194         p = talloc_autofree_context();
1195         talloc_free(p);
1196
1197         printf("success: autofree\n");
1198 #endif
1199         return true;
1200 }
1201
1202 static bool test_pool(void)
1203 {
1204         void *pool;
1205         void *p1, *p2, *p3, *p4;
1206         void *p2_2;
1207
1208         pool = talloc_pool(NULL, 1024);
1209
1210         p1 = talloc_size(pool, 80);
1211         memset(p1, 0x11, talloc_get_size(p1));
1212         p2 = talloc_size(pool, 20);
1213         memset(p2, 0x11, talloc_get_size(p2));
1214         p3 = talloc_size(p1, 50);
1215         memset(p3, 0x11, talloc_get_size(p3));
1216         p4 = talloc_size(p3, 1000);
1217         memset(p4, 0x11, talloc_get_size(p4));
1218
1219 #if 1 /* this relies on ALWAYS_REALLOC == 0 in talloc.c */
1220         p2_2 = talloc_realloc_size(pool, p2, 20+1);
1221         torture_assert("pool realloc 20+1", p2_2 == p2, "failed: pointer changed");
1222         memset(p2, 0x11, talloc_get_size(p2));
1223         p2_2 = talloc_realloc_size(pool, p2, 20-1);
1224         torture_assert("pool realloc 20-1", p2_2 == p2, "failed: pointer changed");
1225         memset(p2, 0x11, talloc_get_size(p2));
1226         p2_2 = talloc_realloc_size(pool, p2, 20-1);
1227         torture_assert("pool realloc 20-1", p2_2 == p2, "failed: pointer changed");
1228         memset(p2, 0x11, talloc_get_size(p2));
1229
1230         talloc_free(p3);
1231
1232         /* this should reclaim the memory of p4 and p3 */
1233         p2_2 = talloc_realloc_size(pool, p2, 400);
1234         torture_assert("pool realloc 400", p2_2 == p2, "failed: pointer changed");
1235         memset(p2, 0x11, talloc_get_size(p2));
1236
1237         talloc_free(p1);
1238
1239         /* this should reclaim the memory of p1 */
1240         p2_2 = talloc_realloc_size(pool, p2, 800);
1241         torture_assert("pool realloc 800", p2_2 == p1, "failed: pointer not changed");
1242         p2 = p2_2;
1243         memset(p2, 0x11, talloc_get_size(p2));
1244
1245         /* this should do a malloc */
1246         p2_2 = talloc_realloc_size(pool, p2, 1800);
1247         torture_assert("pool realloc 1800", p2_2 != p2, "failed: pointer not changed");
1248         p2 = p2_2;
1249         memset(p2, 0x11, talloc_get_size(p2));
1250
1251         /* this should reclaim the memory from the pool */
1252         p3 = talloc_size(pool, 80);
1253         torture_assert("pool alloc 80", p3 == p1, "failed: pointer changed");
1254         memset(p3, 0x11, talloc_get_size(p3));
1255
1256         talloc_free(p2);
1257         talloc_free(p3);
1258
1259         p1 = talloc_size(pool, 80);
1260         memset(p1, 0x11, talloc_get_size(p1));
1261         p2 = talloc_size(pool, 20);
1262         memset(p2, 0x11, talloc_get_size(p2));
1263
1264         talloc_free(p1);
1265
1266         p2_2 = talloc_realloc_size(pool, p2, 20-1);
1267         torture_assert("pool realloc 20-1", p2_2 == p2, "failed: pointer changed");
1268         memset(p2, 0x11, talloc_get_size(p2));
1269         p2_2 = talloc_realloc_size(pool, p2, 20-1);
1270         torture_assert("pool realloc 20-1", p2_2 == p2, "failed: pointer changed");
1271         memset(p2, 0x11, talloc_get_size(p2));
1272
1273         /* this should do a malloc */
1274         p2_2 = talloc_realloc_size(pool, p2, 1800);
1275         torture_assert("pool realloc 1800", p2_2 != p2, "failed: pointer not changed");
1276         p2 = p2_2;
1277         memset(p2, 0x11, talloc_get_size(p2));
1278
1279         /* this should reclaim the memory from the pool */
1280         p3 = talloc_size(pool, 800);
1281         torture_assert("pool alloc 800", p3 == p1, "failed: pointer changed");
1282         memset(p3, 0x11, talloc_get_size(p3));
1283
1284 #endif /* this relies on ALWAYS_REALLOC == 0 in talloc.c */
1285
1286         talloc_free(pool);
1287
1288         return true;
1289 }
1290
1291 static bool test_pool_steal(void)
1292 {
1293         void *root;
1294         void *pool;
1295         void *p1, *p2;
1296         void *p1_2, *p2_2;
1297         size_t hdr;
1298         size_t ofs1, ofs2;
1299
1300         root = talloc_new(NULL);
1301         pool = talloc_pool(root, 1024);
1302
1303         p1 = talloc_size(pool, 4 * 16);
1304         torture_assert("pool allocate 4 * 16", p1 != NULL, "failed ");
1305         memset(p1, 0x11, talloc_get_size(p1));
1306         p2 = talloc_size(pool, 4 * 16);
1307         torture_assert("pool allocate 4 * 16", p2 > p1, "failed: !(p2 > p1) ");
1308         memset(p2, 0x11, talloc_get_size(p2));
1309
1310         ofs1 = PTR_DIFF(p2, p1);
1311         hdr = ofs1 - talloc_get_size(p1);
1312
1313         talloc_steal(root, p1);
1314         talloc_steal(root, p2);
1315
1316         talloc_free(pool);
1317
1318         p1_2 = p1;
1319
1320 #if 1 /* this relies on ALWAYS_REALLOC == 0 in talloc.c */
1321         p1_2 = talloc_realloc_size(root, p1, 5 * 16);
1322         torture_assert("pool realloc 5 * 16", p1_2 > p2, "failed: pointer not changed");
1323         memset(p1_2, 0x11, talloc_get_size(p1_2));
1324         ofs1 = PTR_DIFF(p1_2, p2);
1325         ofs2 = talloc_get_size(p2) + hdr;
1326
1327         torture_assert("pool realloc ", ofs1 == ofs2, "failed: pointer offset unexpected");
1328
1329         p2_2 = talloc_realloc_size(root, p2, 3 * 16);
1330         torture_assert("pool realloc 5 * 16", p2_2 == p2, "failed: pointer changed");
1331         memset(p2_2, 0x11, talloc_get_size(p2_2));
1332 #endif /* this relies on ALWAYS_REALLOC == 0 in talloc.c */
1333
1334         talloc_free(p1_2);
1335
1336         p2_2 = p2;
1337
1338 #if 1 /* this relies on ALWAYS_REALLOC == 0 in talloc.c */
1339         /* now we should reclaim the full pool */
1340         p2_2 = talloc_realloc_size(root, p2, 8 * 16);
1341         torture_assert("pool realloc 8 * 16", p2_2 == p1, "failed: pointer not expected");
1342         p2 = p2_2;
1343         memset(p2_2, 0x11, talloc_get_size(p2_2));
1344
1345         /* now we malloc and free the full pool space */
1346         p2_2 = talloc_realloc_size(root, p2, 2 * 1024);
1347         torture_assert("pool realloc 2 * 1024", p2_2 != p1, "failed: pointer not expected");
1348         memset(p2_2, 0x11, talloc_get_size(p2_2));
1349
1350 #endif /* this relies on ALWAYS_REALLOC == 0 in talloc.c */
1351
1352         talloc_free(p2_2);
1353
1354         talloc_free(root);
1355
1356         return true;
1357 }
1358
1359 static bool test_pool_nest(void)
1360 {
1361         void *p1, *p2, *p3;
1362         void *e = talloc_new(NULL);
1363
1364         p1 = talloc_pool(NULL, 1024);
1365         torture_assert("talloc_pool", p1 != NULL, "failed");
1366
1367         p2 = talloc_pool(p1, 500);
1368         torture_assert("talloc_pool", p2 != NULL, "failed");
1369
1370         p3 = talloc_size(p2, 10);
1371
1372         talloc_steal(e, p3);
1373
1374         talloc_free(p2);
1375
1376         talloc_free(p3);
1377
1378         talloc_free(p1);
1379
1380         return true;
1381 }
1382
1383 struct pooled {
1384         char *s1;
1385         char *s2;
1386         char *s3;
1387 };
1388
1389 static bool test_pooled_object(void)
1390 {
1391         struct pooled *p;
1392         const char *s1 = "hello";
1393         const char *s2 = "world";
1394         const char *s3 = "";
1395
1396         p = talloc_pooled_object(NULL, struct pooled, 3,
1397                         strlen(s1)+strlen(s2)+strlen(s3)+3);
1398
1399         if (talloc_get_size(p) != sizeof(struct pooled)) {
1400                 return false;
1401         }
1402
1403         p->s1 = talloc_strdup(p, s1);
1404
1405         TALLOC_FREE(p->s1);
1406         p->s1 = talloc_strdup(p, s2);
1407         TALLOC_FREE(p->s1);
1408
1409         p->s1 = talloc_strdup(p, s1);
1410         p->s2 = talloc_strdup(p, s2);
1411         p->s3 = talloc_strdup(p, s3);
1412
1413         TALLOC_FREE(p);
1414         return true;
1415 }
1416
1417 static bool test_free_ref_null_context(void)
1418 {
1419         void *p1, *p2, *p3;
1420         int ret;
1421
1422         talloc_disable_null_tracking();
1423         p1 = talloc_new(NULL);
1424         p2 = talloc_new(NULL);
1425
1426         p3 = talloc_reference(p2, p1);
1427         torture_assert("reference", p3 == p1, "failed: reference on null");
1428
1429         ret = talloc_free(p1);
1430         torture_assert("ref free with null parent", ret == 0, "failed: free with null parent");
1431         talloc_free(p2);
1432
1433         talloc_enable_null_tracking_no_autofree();
1434         p1 = talloc_new(NULL);
1435         p2 = talloc_new(NULL);
1436
1437         p3 = talloc_reference(p2, p1);
1438         torture_assert("reference", p3 == p1, "failed: reference on null");
1439
1440         ret = talloc_free(p1);
1441         torture_assert("ref free with null tracked parent", ret == 0, "failed: free with null parent");
1442         talloc_free(p2);
1443
1444         return true;
1445 }
1446
1447 static bool test_rusty(void)
1448 {
1449         void *root;
1450         const char *p1;
1451
1452         talloc_enable_null_tracking();
1453         root = talloc_new(NULL);
1454         p1 = talloc_strdup(root, "foo");
1455         talloc_increase_ref_count(p1);
1456         talloc_report_full(root, stdout);
1457         talloc_free(root);
1458         CHECK_BLOCKS("null_context", NULL, 2);
1459         return true;
1460 }
1461
1462 static bool test_free_children(void)
1463 {
1464         void *root;
1465         char *p1, *p2;
1466         const char *name, *name2;
1467
1468         talloc_enable_null_tracking();
1469         root = talloc_new(NULL);
1470         p1 = talloc_strdup(root, "foo1");
1471         p2 = talloc_strdup(p1, "foo2");
1472         (void)p2;
1473
1474         talloc_set_name(p1, "%s", "testname");
1475         talloc_free_children(p1);
1476         /* check its still a valid talloc ptr */
1477         talloc_get_size(talloc_get_name(p1));
1478         if (strcmp(talloc_get_name(p1), "testname") != 0) {
1479                 return false;
1480         }
1481
1482         talloc_set_name(p1, "%s", "testname");
1483         name = talloc_get_name(p1);
1484         talloc_free_children(p1);
1485         /* check its still a valid talloc ptr */
1486         talloc_get_size(talloc_get_name(p1));
1487         torture_assert("name", name == talloc_get_name(p1), "name ptr changed");
1488         torture_assert("namecheck", strcmp(talloc_get_name(p1), "testname") == 0,
1489                        "wrong name");
1490         CHECK_BLOCKS("name1", p1, 2);
1491
1492         /* note that this does not free the old child name */
1493         talloc_set_name_const(p1, "testname2");
1494         name2 = talloc_get_name(p1);
1495         /* but this does */
1496         talloc_free_children(p1);
1497         (void)name2;
1498         torture_assert("namecheck", strcmp(talloc_get_name(p1), "testname2") == 0,
1499                        "wrong name");
1500         CHECK_BLOCKS("name1", p1, 1);
1501
1502         talloc_report_full(root, stdout);
1503         talloc_free(root);
1504         return true;
1505 }
1506
1507 static bool test_memlimit(void)
1508 {
1509         void *root;
1510         char *l1, *l2, *l3, *l4, *l5, *t;
1511         char *pool;
1512         int i;
1513
1514         printf("test: memlimit\n# MEMORY LIMITS\n");
1515
1516         printf("==== talloc_new(NULL)\n");
1517         root = talloc_new(NULL);
1518
1519         talloc_report_full(root, stdout);
1520
1521         printf("==== talloc_size(root, 2048)\n");
1522         l1 = talloc_size(root, 2048);
1523         torture_assert("memlimit", l1 != NULL,
1524                 "failed: alloc should not fail due to memory limit\n");
1525
1526         talloc_report_full(root, stdout);
1527
1528         printf("==== talloc_free(l1)\n");
1529         talloc_free(l1);
1530
1531         talloc_report_full(root, stdout);
1532
1533         printf("==== talloc_strdup(root, level 1)\n");
1534         l1 = talloc_strdup(root, "level 1");
1535         torture_assert("memlimit", l1 != NULL,
1536                 "failed: alloc should not fail due to memory limit\n");
1537
1538         talloc_report_full(root, stdout);
1539
1540         printf("==== talloc_set_memlimit(l1, 2048)\n");
1541         torture_assert("memlimit", talloc_set_memlimit(l1, 2048) == 0,
1542                 "failed: setting memlimit should never fail\n");
1543
1544         talloc_report_full(root, stdout);
1545
1546         printf("==== talloc_size(root, 2048)\n");
1547         l2 = talloc_size(l1, 2048);
1548         torture_assert("memlimit", l2 == NULL,
1549                 "failed: alloc should fail due to memory limit\n");
1550
1551         talloc_report_full(root, stdout);
1552
1553         printf("==== talloc_strdup(l1, level 2)\n");
1554         l2 = talloc_strdup(l1, "level 2");
1555         torture_assert("memlimit", l2 != NULL,
1556                 "failed: alloc should not fail due to memory limit\n");
1557
1558         talloc_report_full(root, stdout);
1559
1560         printf("==== talloc_free(l2)\n");
1561         talloc_free(l2);
1562
1563         talloc_report_full(root, stdout);
1564
1565         printf("==== talloc_size(NULL, 2048)\n");
1566         l2 = talloc_size(NULL, 2048);
1567
1568         talloc_report_full(root, stdout);
1569
1570         printf("==== talloc_steal(l1, l2)\n");
1571         talloc_steal(l1, l2);
1572
1573         talloc_report_full(root, stdout);
1574
1575         printf("==== talloc_strdup(l2, level 3)\n");
1576         l3 = talloc_strdup(l2, "level 3");
1577         torture_assert("memlimit", l3 == NULL,
1578                 "failed: alloc should fail due to memory limit\n");
1579
1580         talloc_report_full(root, stdout);
1581
1582         printf("==== talloc_free(l2)\n");
1583         talloc_free(l2);
1584
1585         talloc_report_full(root, stdout);
1586
1587         printf("==== talloc_strdup(NULL, level 2)\n");
1588         l2 = talloc_strdup(NULL, "level 2");
1589         talloc_steal(l1, l2);
1590
1591         talloc_report_full(root, stdout);
1592
1593         printf("==== talloc_strdup(l2, level 3)\n");
1594         l3 = talloc_strdup(l2, "level 3");
1595         torture_assert("memlimit", l3 != NULL,
1596                 "failed: alloc should not fail due to memory limit\n");
1597
1598         talloc_report_full(root, stdout);
1599
1600         printf("==== talloc_set_memlimit(l3, 1024)\n");
1601         torture_assert("memlimit", talloc_set_memlimit(l3, 1024) == 0,
1602                 "failed: setting memlimit should never fail\n");
1603
1604         talloc_report_full(root, stdout);
1605
1606         printf("==== talloc_strdup(l3, level 4)\n");
1607         l4 = talloc_strdup(l3, "level 4");
1608         torture_assert("memlimit", l4 != NULL,
1609                 "failed: alloc should not fail due to memory limit\n");
1610
1611         talloc_report_full(root, stdout);
1612
1613         printf("==== talloc_set_memlimit(l4, 512)\n");
1614         torture_assert("memlimit", talloc_set_memlimit(l4, 512) == 0,
1615                 "failed: setting memlimit should never fail\n");
1616
1617         talloc_report_full(root, stdout);
1618
1619         printf("==== talloc_strdup(l4, level 5)\n");
1620         l5 = talloc_strdup(l4, "level 5");
1621         torture_assert("memlimit", l5 != NULL,
1622                 "failed: alloc should not fail due to memory limit\n");
1623
1624         talloc_report_full(root, stdout);
1625
1626         printf("==== talloc_realloc(NULL, l5, char, 600)\n");
1627         t = talloc_realloc(NULL, l5, char, 600);
1628         torture_assert("memlimit", t == NULL,
1629                 "failed: alloc should fail due to memory limit\n");
1630
1631         talloc_report_full(root, stdout);
1632
1633         printf("==== talloc_realloc(NULL, l5, char, 5)\n");
1634         l5 = talloc_realloc(NULL, l5, char, 5);
1635         torture_assert("memlimit", l5 != NULL,
1636                 "failed: alloc should not fail due to memory limit\n");
1637
1638         talloc_report_full(root, stdout);
1639
1640         printf("==== talloc_strdup(l3, level 4)\n");
1641         l4 = talloc_strdup(l3, "level 4");
1642         torture_assert("memlimit", l4 != NULL,
1643                 "failed: alloc should not fail due to memory limit\n");
1644
1645         talloc_report_full(root, stdout);
1646
1647         printf("==== talloc_set_memlimit(l4, 512)\n");
1648         torture_assert("memlimit", talloc_set_memlimit(l4, 512) == 0,
1649                 "failed: setting memlimit should never fail\n");
1650
1651         talloc_report_full(root, stdout);
1652
1653         printf("==== talloc_strdup(l4, level 5)\n");
1654         l5 = talloc_strdup(l4, "level 5");
1655         torture_assert("memlimit", l5 != NULL,
1656                 "failed: alloc should not fail due to memory limit\n");
1657
1658         talloc_report_full(root, stdout);
1659
1660         printf("==== Make new temp context and steal l5\n");
1661         t = talloc_new(root);
1662         talloc_steal(t, l5);
1663
1664         talloc_report_full(root, stdout);
1665
1666         printf("==== talloc_size(t, 2048)\n");
1667         l1 = talloc_size(t, 2048);
1668         torture_assert("memlimit", l1 != NULL,
1669                 "failed: alloc should not fail due to memory limit\n");
1670
1671         talloc_report_full(root, stdout);
1672         talloc_free(root);
1673
1674         /* Test memlimits with pools. */
1675         pool = talloc_pool(NULL, 10*1024);
1676         torture_assert("memlimit", pool != NULL,
1677                 "failed: alloc should not fail due to memory limit\n");
1678         talloc_set_memlimit(pool, 10*1024);
1679         for (i = 0; i < 9; i++) {
1680                 l1 = talloc_size(pool, 1024);
1681                 torture_assert("memlimit", l1 != NULL,
1682                         "failed: alloc should not fail due to memory limit\n");
1683         }
1684         /* The next alloc should fail. */
1685         l2 = talloc_size(pool, 1024);
1686         torture_assert("memlimit", l2 == NULL,
1687                         "failed: alloc should fail due to memory limit\n");
1688
1689         /* Moving one of the children shouldn't change the limit,
1690            as it's still inside the pool. */
1691         root = talloc_new(NULL);
1692         talloc_steal(root, l1);
1693         l2 = talloc_size(pool, 1024);
1694         torture_assert("memlimit", l2 == NULL,
1695                         "failed: alloc should fail due to memory limit\n");
1696
1697         talloc_free(pool);
1698         talloc_free(root);
1699         printf("success: memlimit\n");
1700
1701         return true;
1702 }
1703
1704 static void test_reset(void)
1705 {
1706         talloc_set_log_fn(test_log_stdout);
1707         test_abort_stop();
1708         talloc_disable_null_tracking();
1709         talloc_enable_null_tracking_no_autofree();
1710 }
1711
1712 bool torture_local_talloc(struct torture_context *tctx)
1713 {
1714         bool ret = true;
1715
1716         setlinebuf(stdout);
1717
1718         test_reset();
1719         ret &= test_pooled_object();
1720         test_reset();
1721         ret &= test_pool_nest();
1722         test_reset();
1723         ret &= test_ref1();
1724         test_reset();
1725         ret &= test_ref2();
1726         test_reset();
1727         ret &= test_ref3();
1728         test_reset();
1729         ret &= test_ref4();
1730         test_reset();
1731         ret &= test_unlink1(); 
1732         test_reset();
1733         ret &= test_misc();
1734         test_reset();
1735         ret &= test_realloc();
1736         test_reset();
1737         ret &= test_realloc_child(); 
1738         test_reset();
1739         ret &= test_steal(); 
1740         test_reset();
1741         ret &= test_move(); 
1742         test_reset();
1743         ret &= test_unref_reparent();
1744         test_reset();
1745         ret &= test_realloc_fn(); 
1746         test_reset();
1747         ret &= test_type();
1748         test_reset();
1749         ret &= test_lifeless(); 
1750         test_reset();
1751         ret &= test_loop();
1752         test_reset();
1753         ret &= test_free_parent_deny_child(); 
1754         test_reset();
1755         ret &= test_free_parent_reparent_child();
1756         test_reset();
1757         ret &= test_free_parent_reparent_child_in_pool();
1758         test_reset();
1759         ret &= test_talloc_ptrtype();
1760         test_reset();
1761         ret &= test_talloc_free_in_destructor();
1762         test_reset();
1763         ret &= test_pool();
1764         test_reset();
1765         ret &= test_pool_steal();
1766         test_reset();
1767         ret &= test_free_ref_null_context();
1768         test_reset();
1769         ret &= test_rusty();
1770         test_reset();
1771         ret &= test_free_children();
1772         test_reset();
1773         ret &= test_memlimit();
1774
1775
1776         if (ret) {
1777                 test_reset();
1778                 ret &= test_speed();
1779         }
1780         test_reset();
1781         ret &= test_autofree();
1782
1783         test_reset();
1784         talloc_disable_null_tracking();
1785         return ret;
1786 }