📄 talloctort.c
字号:
/* Unix SMB/CIFS implementation. local testing of talloc routines. Copyright (C) Andrew Tridgell 2004 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.*/#ifdef _SAMBA_BUILD_#include "includes.h"#else#include <stdio.h>#include <stdlib.h>#include <string.h>#include <stdarg.h>#include <sys/time.h>#include <time.h>#include "talloc.h"#endif/* the test suite can be built standalone, or as part of Samba */#ifndef _SAMBA_BUILD_typedef enum {False=0,True=1} BOOL;#endif/* Samba3 does not define the timeval functions below */#if !defined(_SAMBA_BUILD_) || ((SAMBA_VERSION_MAJOR==3)&&(SAMBA_VERSION_MINOR<9))static double timeval_elapsed(struct timeval *tv){ struct timeval tv2 = timeval_current(); return (tv2.tv_sec - tv->tv_sec) + (tv2.tv_usec - tv->tv_usec)*1.0e-6;}#endif /* _SAMBA_BUILD_ */#if SAMBA_VERSION_MAJOR<4#ifdef malloc#undef malloc#endif#ifdef strdup#undef strdup#endif#endif#define CHECK_SIZE(ptr, tsize) do { \ if (talloc_total_size(ptr) != (tsize)) { \ printf(__location__ " failed: wrong '%s' tree size: got %u expected %u\n", \ #ptr, \ (unsigned)talloc_total_size(ptr), \ (unsigned)tsize); \ talloc_report_full(ptr, stdout); \ return False; \ } \} while (0)#define CHECK_BLOCKS(ptr, tblocks) do { \ if (talloc_total_blocks(ptr) != (tblocks)) { \ printf(__location__ " failed: wrong '%s' tree blocks: got %u expected %u\n", \ #ptr, \ (unsigned)talloc_total_blocks(ptr), \ (unsigned)tblocks); \ talloc_report_full(ptr, stdout); \ return False; \ } \} while (0)/* test references */static BOOL test_ref1(void){ void *root, *p1, *p2, *ref, *r1; printf("TESTING SINGLE REFERENCE FREE\n"); root = talloc_named_const(NULL, 0, "root"); p1 = talloc_named_const(root, 1, "p1"); p2 = talloc_named_const(p1, 1, "p2"); talloc_named_const(p1, 1, "x1"); talloc_named_const(p1, 2, "x2"); talloc_named_const(p1, 3, "x3"); r1 = talloc_named_const(root, 1, "r1"); ref = talloc_reference(r1, p2); talloc_report_full(root, stdout); CHECK_BLOCKS(p1, 5); CHECK_BLOCKS(p2, 1); CHECK_BLOCKS(r1, 2); printf("Freeing p2\n"); talloc_free(p2); talloc_report_full(root, stdout); CHECK_BLOCKS(p1, 5); CHECK_BLOCKS(p2, 1); CHECK_BLOCKS(r1, 1); printf("Freeing p1\n"); talloc_free(p1); talloc_report_full(root, stdout); CHECK_BLOCKS(r1, 1); printf("Freeing r1\n"); talloc_free(r1); talloc_report_full(NULL, stdout); printf("Testing NULL\n"); if (talloc_reference(root, NULL)) { return False; } CHECK_BLOCKS(root, 1); CHECK_SIZE(root, 0); talloc_free(root); return True;}/* test references */static BOOL test_ref2(void){ void *root, *p1, *p2, *ref, *r1; printf("TESTING DOUBLE REFERENCE FREE\n"); root = talloc_named_const(NULL, 0, "root"); p1 = talloc_named_const(root, 1, "p1"); talloc_named_const(p1, 1, "x1"); talloc_named_const(p1, 1, "x2"); talloc_named_const(p1, 1, "x3"); p2 = talloc_named_const(p1, 1, "p2"); r1 = talloc_named_const(root, 1, "r1"); ref = talloc_reference(r1, p2); talloc_report_full(root, stdout); CHECK_BLOCKS(p1, 5); CHECK_BLOCKS(p2, 1); CHECK_BLOCKS(r1, 2); printf("Freeing ref\n"); talloc_free(ref); talloc_report_full(root, stdout); CHECK_BLOCKS(p1, 5); CHECK_BLOCKS(p2, 1); CHECK_BLOCKS(r1, 1); printf("Freeing p2\n"); talloc_free(p2); talloc_report_full(root, stdout); CHECK_BLOCKS(p1, 4); CHECK_BLOCKS(r1, 1); printf("Freeing p1\n"); talloc_free(p1); talloc_report_full(root, stdout); CHECK_BLOCKS(r1, 1); printf("Freeing r1\n"); talloc_free(r1); talloc_report_full(root, stdout); CHECK_SIZE(root, 0); talloc_free(root); return True;}/* test references */static BOOL test_ref3(void){ void *root, *p1, *p2, *ref, *r1; printf("TESTING PARENT REFERENCE FREE\n"); root = talloc_named_const(NULL, 0, "root"); p1 = talloc_named_const(root, 1, "p1"); p2 = talloc_named_const(root, 1, "p2"); r1 = talloc_named_const(p1, 1, "r1"); ref = talloc_reference(p2, r1); talloc_report_full(root, stdout); CHECK_BLOCKS(p1, 2); CHECK_BLOCKS(p2, 2); CHECK_BLOCKS(r1, 1); printf("Freeing p1\n"); talloc_free(p1); talloc_report_full(root, stdout); CHECK_BLOCKS(p2, 2); CHECK_BLOCKS(r1, 1); printf("Freeing p2\n"); talloc_free(p2); talloc_report_full(root, stdout); CHECK_SIZE(root, 0); talloc_free(root); return True;}/* test references */static BOOL test_ref4(void){ void *root, *p1, *p2, *ref, *r1; printf("TESTING REFERRER REFERENCE FREE\n"); root = talloc_named_const(NULL, 0, "root"); p1 = talloc_named_const(root, 1, "p1"); talloc_named_const(p1, 1, "x1"); talloc_named_const(p1, 1, "x2"); talloc_named_const(p1, 1, "x3"); p2 = talloc_named_const(p1, 1, "p2"); r1 = talloc_named_const(root, 1, "r1"); ref = talloc_reference(r1, p2); talloc_report_full(root, stdout); CHECK_BLOCKS(p1, 5); CHECK_BLOCKS(p2, 1); CHECK_BLOCKS(r1, 2); printf("Freeing r1\n"); talloc_free(r1); talloc_report_full(root, stdout); CHECK_BLOCKS(p1, 5); CHECK_BLOCKS(p2, 1); printf("Freeing p2\n"); talloc_free(p2); talloc_report_full(root, stdout); CHECK_BLOCKS(p1, 4); printf("Freeing p1\n"); talloc_free(p1); talloc_report_full(root, stdout); CHECK_SIZE(root, 0); talloc_free(root); return True;}/* test references */static BOOL test_unlink1(void){ void *root, *p1, *p2, *ref, *r1; printf("TESTING UNLINK\n"); root = talloc_named_const(NULL, 0, "root"); p1 = talloc_named_const(root, 1, "p1"); talloc_named_const(p1, 1, "x1"); talloc_named_const(p1, 1, "x2"); talloc_named_const(p1, 1, "x3"); p2 = talloc_named_const(p1, 1, "p2"); r1 = talloc_named_const(p1, 1, "r1"); ref = talloc_reference(r1, p2); talloc_report_full(root, stdout); CHECK_BLOCKS(p1, 7); CHECK_BLOCKS(p2, 1); CHECK_BLOCKS(r1, 2); printf("Unreferencing r1\n"); talloc_unlink(r1, p2); talloc_report_full(root, stdout); CHECK_BLOCKS(p1, 6); CHECK_BLOCKS(p2, 1); CHECK_BLOCKS(r1, 1); printf("Freeing p1\n"); talloc_free(p1); talloc_report_full(root, stdout); CHECK_SIZE(root, 0); talloc_free(root); return True;}static int fail_destructor(void *ptr){ return -1;}/* miscellaneous tests to try to get a higher test coverage percentage*/static BOOL test_misc(void){ void *root, *p1; char *p2; double *d; printf("TESTING MISCELLANEOUS\n"); root = talloc_new(NULL); p1 = talloc_size(root, 0x7fffffff); if (p1) { printf("failed: large talloc allowed\n"); return False; } p1 = talloc_strdup(root, "foo"); talloc_increase_ref_count(p1); talloc_increase_ref_count(p1); talloc_increase_ref_count(p1); CHECK_BLOCKS(p1, 1); CHECK_BLOCKS(root, 2); talloc_free(p1); CHECK_BLOCKS(p1, 1); CHECK_BLOCKS(root, 2); talloc_unlink(NULL, p1); CHECK_BLOCKS(p1, 1); CHECK_BLOCKS(root, 2); p2 = talloc_strdup(p1, "foo"); if (talloc_unlink(root, p2) != -1) { printf("failed: talloc_unlink() of non-reference context should return -1\n"); return False; } if (talloc_unlink(p1, p2) != 0) { printf("failed: talloc_unlink() of parent should succeed\n"); return False; } talloc_free(p1); CHECK_BLOCKS(p1, 1); CHECK_BLOCKS(root, 2); talloc_set_name(p1, "my name is %s", "foo"); if (strcmp(talloc_get_name(p1), "my name is foo") != 0) { printf("failed: wrong name after talloc_set_name\n"); return False; } CHECK_BLOCKS(p1, 2); CHECK_BLOCKS(root, 3); talloc_set_name_const(p1, NULL); if (strcmp(talloc_get_name(p1), "UNNAMED") != 0) { printf("failed: wrong name after talloc_set_name(NULL)\n"); return False; } CHECK_BLOCKS(p1, 2); CHECK_BLOCKS(root, 3); if (talloc_free(NULL) != -1) { printf("talloc_free(NULL) should give -1\n"); return False; } talloc_set_destructor(p1, fail_destructor); if (talloc_free(p1) != -1) { printf("Failed destructor should cause talloc_free to fail\n"); return False; } talloc_set_destructor(p1, NULL); talloc_report(root, stdout); p2 = talloc_zero_size(p1, 20); if (p2[19] != 0) { printf("Failed to give zero memory\n"); return False; } talloc_free(p2); if (talloc_strdup(root, NULL) != NULL) { printf("failed: strdup on NULL should give NULL\n"); return False; } p2 = talloc_strndup(p1, "foo", 2); if (strcmp("fo", p2) != 0) { printf("failed: strndup doesn't work\n"); return False; } p2 = talloc_asprintf_append(p2, "o%c", 'd');
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -