2 Unix SMB/CIFS implementation.
4 local testing of talloc routines.
6 Copyright (C) Andrew Tridgell 2004
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
35 /* the test suite can be built standalone, or as part of Samba */
37 typedef enum {False=0,True=1} BOOL;
39 static struct timeval current_time(void)
46 static double elapsed_time(struct timeval *tv)
48 struct timeval tv2 = current_time();
49 return (tv2.tv_sec - tv->tv_sec) +
50 (tv2.tv_usec - tv->tv_usec)*1.0e-6;
52 #endif /* _STANDALONE_ */
55 #define CHECK_SIZE(ptr, tsize) do { \
56 if (talloc_total_size(ptr) != (tsize)) { \
57 printf(__location__ " failed: wrong '%s' tree size: got %u expected %u\n", \
59 (unsigned)talloc_total_size(ptr), \
61 talloc_report_full(ptr, stdout); \
66 #define CHECK_BLOCKS(ptr, tblocks) do { \
67 if (talloc_total_blocks(ptr) != (tblocks)) { \
68 printf(__location__ " failed: wrong '%s' tree blocks: got %u expected %u\n", \
70 (unsigned)talloc_total_blocks(ptr), \
72 talloc_report_full(ptr, stdout); \
81 static BOOL test_ref1(void)
83 void *root, *p1, *p2, *ref, *r1;
85 printf("TESTING SINGLE REFERENCE FREE\n");
87 root = talloc_named_const(NULL, 0, "root");
88 p1 = talloc_named_const(root, 1, "p1");
89 p2 = talloc_named_const(p1, 1, "p2");
90 talloc_named_const(p1, 1, "x1");
91 talloc_named_const(p1, 2, "x2");
92 talloc_named_const(p1, 3, "x3");
94 r1 = talloc_named_const(root, 1, "r1");
95 ref = talloc_reference(r1, p2);
96 talloc_report_full(root, stdout);
102 printf("Freeing p2\n");
104 talloc_report_full(root, stdout);
110 printf("Freeing p1\n");
112 talloc_report_full(root, stdout);
116 printf("Freeing r1\n");
118 talloc_report_full(NULL, stdout);
120 CHECK_BLOCKS(root, 1);
132 static BOOL test_ref2(void)
134 void *root, *p1, *p2, *ref, *r1;
136 printf("TESTING DOUBLE REFERENCE FREE\n");
138 root = talloc_named_const(NULL, 0, "root");
139 p1 = talloc_named_const(root, 1, "p1");
140 talloc_named_const(p1, 1, "x1");
141 talloc_named_const(p1, 1, "x2");
142 talloc_named_const(p1, 1, "x3");
143 p2 = talloc_named_const(p1, 1, "p2");
145 r1 = talloc_named_const(root, 1, "r1");
146 ref = talloc_reference(r1, p2);
147 talloc_report_full(root, stdout);
153 printf("Freeing ref\n");
155 talloc_report_full(root, stdout);
161 printf("Freeing p2\n");
163 talloc_report_full(root, stdout);
168 printf("Freeing p1\n");
170 talloc_report_full(root, stdout);
174 printf("Freeing r1\n");
176 talloc_report_full(root, stdout);
188 static BOOL test_ref3(void)
190 void *root, *p1, *p2, *ref, *r1;
192 printf("TESTING PARENT REFERENCE FREE\n");
194 root = talloc_named_const(NULL, 0, "root");
195 p1 = talloc_named_const(root, 1, "p1");
196 p2 = talloc_named_const(root, 1, "p2");
197 r1 = talloc_named_const(p1, 1, "r1");
198 ref = talloc_reference(p2, r1);
199 talloc_report_full(root, stdout);
205 printf("Freeing p1\n");
207 talloc_report_full(root, stdout);
212 printf("Freeing p2\n");
214 talloc_report_full(root, stdout);
226 static BOOL test_ref4(void)
228 void *root, *p1, *p2, *ref, *r1;
230 printf("TESTING REFERRER REFERENCE FREE\n");
232 root = talloc_named_const(NULL, 0, "root");
233 p1 = talloc_named_const(root, 1, "p1");
234 talloc_named_const(p1, 1, "x1");
235 talloc_named_const(p1, 1, "x2");
236 talloc_named_const(p1, 1, "x3");
237 p2 = talloc_named_const(p1, 1, "p2");
239 r1 = talloc_named_const(root, 1, "r1");
240 ref = talloc_reference(r1, p2);
241 talloc_report_full(root, stdout);
247 printf("Freeing r1\n");
249 talloc_report_full(root, stdout);
254 printf("Freeing p2\n");
256 talloc_report_full(root, stdout);
260 printf("Freeing p1\n");
262 talloc_report_full(root, stdout);
275 static BOOL test_unlink1(void)
277 void *root, *p1, *p2, *ref, *r1;
279 printf("TESTING UNLINK\n");
281 root = talloc_named_const(NULL, 0, "root");
282 p1 = talloc_named_const(root, 1, "p1");
283 talloc_named_const(p1, 1, "x1");
284 talloc_named_const(p1, 1, "x2");
285 talloc_named_const(p1, 1, "x3");
286 p2 = talloc_named_const(p1, 1, "p2");
288 r1 = talloc_named_const(p1, 1, "r1");
289 ref = talloc_reference(r1, p2);
290 talloc_report_full(root, stdout);
296 printf("Unreferencing r1\n");
297 talloc_unlink(r1, p2);
298 talloc_report_full(root, stdout);
304 printf("Freeing p1\n");
306 talloc_report_full(root, stdout);
315 static int fail_destructor(void *ptr)
321 miscellaneous tests to try to get a higher test coverage percentage
323 static BOOL test_misc(void)
329 printf("TESTING MISCELLANEOUS\n");
331 root = talloc(NULL, 0);
333 p1 = talloc(root, 0x7fffffff);
335 printf("failed: large talloc allowed\n");
339 p1 = talloc_strdup(root, "foo");
340 talloc_increase_ref_count(p1);
341 talloc_increase_ref_count(p1);
342 talloc_increase_ref_count(p1);
344 CHECK_BLOCKS(root, 2);
347 CHECK_BLOCKS(root, 2);
348 talloc_unlink(NULL, p1);
350 CHECK_BLOCKS(root, 2);
351 p2 = talloc_strdup(p1, "foo");
352 if (talloc_unlink(root, p2) != -1) {
353 printf("failed: talloc_unlink() of non-reference context should return -1\n");
356 if (talloc_unlink(p1, p2) != 0) {
357 printf("failed: talloc_unlink() of parent should succeed\n");
362 CHECK_BLOCKS(root, 2);
364 talloc_set_name(p1, "my name is %s", "foo");
365 if (strcmp(talloc_get_name(p1), "my name is foo") != 0) {
366 printf("failed: wrong name after talloc_set_name\n");
370 CHECK_BLOCKS(root, 3);
372 talloc_set_name_const(p1, NULL);
373 if (strcmp(talloc_get_name(p1), "UNNAMED") != 0) {
374 printf("failed: wrong name after talloc_set_name(NULL)\n");
378 CHECK_BLOCKS(root, 3);
381 if (talloc_free(NULL) != -1) {
382 printf("talloc_free(NULL) should give -1\n");
386 talloc_set_destructor(p1, fail_destructor);
387 if (talloc_free(p1) != -1) {
388 printf("Failed destructor should cause talloc_free to fail\n");
391 talloc_set_destructor(p1, NULL);
393 talloc_report(root, stdout);
396 p2 = talloc_zero(p1, 20);
398 printf("Failed to give zero memory\n");
403 if (talloc_strdup(root, NULL) != NULL) {
404 printf("failed: strdup on NULL should give NULL\n");
408 p2 = talloc_strndup(p1, "foo", 2);
409 if (strcmp("fo", p2) != 0) {
410 printf("failed: strndup doesn't work\n");
413 p2 = talloc_asprintf_append(p2, "o%c", 'd');
414 if (strcmp("food", p2) != 0) {
415 printf("failed: talloc_asprintf_append doesn't work\n");
421 p2 = talloc_asprintf_append(NULL, "hello %s", "world");
422 if (strcmp("hello world", p2) != 0) {
423 printf("failed: talloc_asprintf_append doesn't work\n");
430 d = talloc_array_p(p1, double, 0x20000000);
432 printf("failed: integer overflow not detected\n");
436 d = talloc_realloc_p(p1, d, double, 0x20000000);
438 printf("failed: integer overflow not detected\n");
443 CHECK_BLOCKS(root, 1);
445 p1 = talloc_named(root, 100, "%d bytes", 100);
447 CHECK_BLOCKS(root, 3);
448 talloc_unlink(root, p1);
450 p1 = talloc_init("%d bytes", 200);
451 p2 = talloc_asprintf(p1, "my test '%s'", "string");
454 CHECK_BLOCKS(root, 1);
455 talloc_unlink(NULL, p1);
457 p1 = talloc_named_const(root, 10, "p1");
458 p2 = talloc_named_const(root, 20, "p2");
459 talloc_reference(p1, p2);
460 talloc_report_full(root, stdout);
461 talloc_unlink(root, p2);
462 talloc_report_full(root, stdout);
465 CHECK_BLOCKS(root, 3);
466 talloc_unlink(p1, p2);
467 talloc_unlink(root, p1);
469 p1 = talloc_named_const(root, 10, "p1");
470 p2 = talloc_named_const(root, 20, "p2");
471 talloc_reference(NULL, p2);
472 talloc_report_full(root, stdout);
473 talloc_unlink(root, p2);
474 talloc_report_full(root, stdout);
477 CHECK_BLOCKS(root, 2);
478 talloc_unlink(NULL, p2);
479 talloc_unlink(root, p1);
483 talloc_report(root, stdout);
484 talloc_report(NULL, stdout);
492 talloc_enable_leak_report();
493 talloc_enable_leak_report_full();
502 static BOOL test_realloc(void)
504 void *root, *p1, *p2;
506 printf("TESTING REALLOC\n");
508 root = talloc(NULL, 0);
510 p1 = talloc(root, 10);
513 p1 = talloc_realloc(NULL, p1, 20);
518 p2 = talloc_realloc(p1, NULL, 30);
522 p2 = talloc_realloc(p1, p2, 40);
525 CHECK_SIZE(root, 60);
528 p1 = talloc_realloc(NULL, p1, 20);
531 talloc_increase_ref_count(p2);
532 if (talloc_realloc(NULL, p2, 5) != NULL) {
533 printf("failed: talloc_realloc() on a referenced pointer should fail\n");
538 talloc_realloc(NULL, p2, 0);
539 talloc_realloc(NULL, p2, 0);
542 if (talloc_realloc(NULL, p1, 0x7fffffff) != NULL) {
543 printf("failed: oversize talloc should fail\n");
547 talloc_realloc(NULL, p1, 0);
549 CHECK_BLOCKS(root, 1);
560 static BOOL test_steal(void)
562 void *root, *p1, *p2;
564 printf("TESTING STEAL\n");
566 root = talloc(NULL, 0);
568 p1 = talloc_array_p(root, char, 10);
571 p2 = talloc_realloc_p(root, NULL, char, 20);
573 CHECK_SIZE(root, 30);
575 if (talloc_steal(p1, NULL) != NULL) {
576 printf("failed: stealing NULL should give NULL\n");
580 if (talloc_steal(p1, p1) != p1) {
581 printf("failed: stealing to ourselves is a nop\n");
584 CHECK_BLOCKS(root, 3);
585 CHECK_SIZE(root, 30);
587 talloc_steal(NULL, p1);
588 talloc_steal(NULL, p2);
589 CHECK_BLOCKS(root, 1);
593 talloc_steal(root, p2);
594 CHECK_BLOCKS(root, 2);
595 CHECK_SIZE(root, 20);
599 CHECK_BLOCKS(root, 1);
604 p1 = talloc(NULL, 3);
614 static BOOL test_ldb(void)
618 printf("TESTING LDB\n");
620 root = talloc(NULL, 0);
622 p1 = talloc_realloc_fn(root, NULL, 10);
623 CHECK_BLOCKS(root, 2);
624 CHECK_SIZE(root, 10);
625 p1 = talloc_realloc_fn(root, p1, 20);
626 CHECK_BLOCKS(root, 2);
627 CHECK_SIZE(root, 20);
628 p1 = talloc_realloc_fn(root, p1, 0);
629 CHECK_BLOCKS(root, 1);
639 measure the speed of talloc versus malloc
641 static BOOL test_speed(void)
643 void *ctx = talloc(NULL, 0);
647 printf("MEASURING TALLOC VS MALLOC SPEED\n");
649 tv = timeval_current();
653 p1 = talloc(ctx, count);
654 p2 = talloc_strdup(p1, "foo bar");
655 p3 = talloc(p1, 300);
658 } while (timeval_elapsed(&tv) < 5.0);
660 printf("talloc: %.0f ops/sec\n", count/timeval_elapsed(&tv));
664 tv = timeval_current();
669 p2 = strdup("foo bar");
675 } while (timeval_elapsed(&tv) < 5.0);
677 printf("malloc: %.0f ops/sec\n", count/timeval_elapsed(&tv));
683 BOOL torture_local_talloc(void)
691 ret &= test_unlink1();
693 ret &= test_realloc();
708 if (!torture_local_talloc(0)) {
709 printf("ERROR: TESTSUIE FAILED\n");