summaryrefslogtreecommitdiff
path: root/source4/torture
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2004-09-29 06:31:14 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 12:59:29 -0500
commit4f13ebef5d6711ac121b9c41e2fbbe2cd3b6da0e (patch)
tree9c97145fdcde8e5e7d9d2736b0571caae530db7e /source4/torture
parent173b61817b23c7338a30cae819cc63879543587f (diff)
downloadsamba-4f13ebef5d6711ac121b9c41e2fbbe2cd3b6da0e.tar.gz
samba-4f13ebef5d6711ac121b9c41e2fbbe2cd3b6da0e.tar.bz2
samba-4f13ebef5d6711ac121b9c41e2fbbe2cd3b6da0e.zip
r2744: ben elliston taught me about gcov today, which allows you to measure
the % coverage in terms of lines of code of a test suite. I thought a good first place to start with gcov was the talloc test suite. When I started the test suite covered about 60% of all lines of code in talloc.c, and now it covers about 99%. The only lines not covered are talloc corruption errors, as that would cause smb_panic() to fire. It will be interesting to try gcov on the main Samba test suite for smbd. We won't achieve 100% coverage, but it would be nice to get to 90% or more. I also modified the talloc.c sources to be able to be build standalone, using: gcc -c -D_STANDALONE_ -Iinlcude lib/talloc.c that should make it much easier to re-use talloc in other projects (This used to be commit 8d4dc99b82efdf24b6811851c7bdd4af5a4c52c9)
Diffstat (limited to 'source4/torture')
-rw-r--r--source4/torture/local/talloc.c320
1 files changed, 300 insertions, 20 deletions
diff --git a/source4/torture/local/talloc.c b/source4/torture/local/talloc.c
index e046ae8dc5..a3bfb45f54 100644
--- a/source4/torture/local/talloc.c
+++ b/source4/torture/local/talloc.c
@@ -24,8 +24,8 @@
#define CHECK_BLOCKS(ptr, tblocks) do { \
if (talloc_total_blocks(ptr) != (tblocks)) { \
- printf("(%d) failed: wrong '%s' tree size: got %u expected %u\n", \
- __LINE__, #ptr, \
+ 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); \
@@ -33,6 +33,17 @@
} \
} while (0)
+#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)
+
/*
test references
*/
@@ -77,10 +88,7 @@ static BOOL test_ref1(void)
CHECK_BLOCKS(root, 1);
- if (talloc_total_size(root) != 0) {
- printf("failed: non-zero total size\n");
- return False;
- }
+ CHECK_SIZE(root, 0);
talloc_free(root);
@@ -136,10 +144,7 @@ static BOOL test_ref2(void)
talloc_free(r1);
talloc_report_full(root, stdout);
- if (talloc_total_size(root) != 0) {
- printf("failed: non-zero total size\n");
- return False;
- }
+ CHECK_SIZE(root, 0);
talloc_free(root);
@@ -177,10 +182,7 @@ static BOOL test_ref3(void)
talloc_free(p2);
talloc_report_full(root, stdout);
- if (talloc_total_size(root) != 0) {
- printf("failed: non-zero total size\n");
- return False;
- }
+ CHECK_SIZE(root, 0);
talloc_free(root);
@@ -228,10 +230,7 @@ static BOOL test_ref4(void)
talloc_free(p1);
talloc_report_full(root, stdout);
- if (talloc_total_size(root) != 0) {
- printf("failed: non-zero total size\n");
- return False;
- }
+ CHECK_SIZE(root, 0);
talloc_free(root);
@@ -275,10 +274,206 @@ static BOOL test_unref1(void)
talloc_free(p1);
talloc_report_full(root, stdout);
- if (talloc_total_size(root) != 0) {
- printf("failed: non-zero total size\n");
+ 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(NULL, 0);
+
+ p1 = talloc(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_unreference(NULL, p1);
+ CHECK_BLOCKS(p1, 1);
+ CHECK_BLOCKS(root, 2);
+ if (talloc_unreference(root, p1) != NULL) {
+ printf("failed: talloc_unreference() of non-reference context should return NULL\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(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');
+ if (strcmp("food", p2) != 0) {
+ printf("failed: talloc_asprintf_append doesn't work\n");
+ return False;
+ }
+ CHECK_BLOCKS(p2, 1);
+ CHECK_BLOCKS(p1, 3);
+
+ p2 = talloc_asprintf_append(NULL, "hello %s", "world");
+ if (strcmp("hello world", p2) != 0) {
+ printf("failed: talloc_asprintf_append doesn't work\n");
+ return False;
+ }
+ CHECK_BLOCKS(p2, 1);
+ CHECK_BLOCKS(p1, 3);
+ talloc_free(p2);
+
+ d = talloc_array_p(p1, double, 0x20000000);
+ if (d) {
+ printf("failed: integer overflow not detected\n");
+ return False;
+ }
+
+ d = talloc_realloc_p(p1, d, double, 0x20000000);
+ if (d) {
+ printf("failed: integer overflow not detected\n");
+ return False;
+ }
+
+ talloc_free(p1);
+ CHECK_BLOCKS(root, 1);
+
+ talloc_report(root, stdout);
+ talloc_report(NULL, stdout);
+
+ CHECK_SIZE(root, 0);
+
+ talloc_free(root);
+
+ CHECK_SIZE(NULL, 0);
+
+ talloc_enable_leak_report();
+ talloc_enable_leak_report_full();
+
+ return True;
+}
+
+
+/*
+ test realloc
+*/
+static BOOL test_realloc(void)
+{
+ void *root, *p1, *p2;
+
+ printf("TESTING REALLOC\n");
+
+ root = talloc(NULL, 0);
+
+ p1 = talloc(root, 10);
+ CHECK_SIZE(p1, 10);
+
+ p1 = talloc_realloc(NULL, p1, 20);
+ CHECK_SIZE(p1, 20);
+
+ talloc(p1, 0);
+
+ p2 = talloc_realloc(p1, NULL, 30);
+
+ talloc(p1, 0);
+
+ p2 = talloc_realloc(p1, p2, 40);
+
+ CHECK_SIZE(p2, 40);
+ CHECK_SIZE(root, 60);
+ CHECK_BLOCKS(p1, 4);
+
+ p1 = talloc_realloc(NULL, p1, 20);
+ CHECK_SIZE(p1, 60);
+
+ talloc_increase_ref_count(p2);
+ if (talloc_realloc(NULL, p2, 5) != NULL) {
+ printf("failed: talloc_realloc() on a referenced pointer should fail\n");
return False;
}
+ CHECK_BLOCKS(p1, 4);
+
+ talloc_realloc(NULL, p2, 0);
+ talloc_realloc(NULL, p2, 0);
+ CHECK_BLOCKS(p1, 3);
+
+ if (talloc_realloc(NULL, p1, 0x7fffffff) != NULL) {
+ printf("failed: oversize talloc should fail\n");
+ return False;
+ }
+
+ talloc_realloc(NULL, p1, 0);
+
+ CHECK_BLOCKS(root, 1);
+ CHECK_SIZE(root, 0);
talloc_free(root);
@@ -286,6 +481,87 @@ static BOOL test_unref1(void)
}
/*
+ test steal
+*/
+static BOOL test_steal(void)
+{
+ void *root, *p1, *p2;
+
+ printf("TESTING STEAL\n");
+
+ root = talloc(NULL, 0);
+
+ p1 = talloc_array_p(root, char, 10);
+ CHECK_SIZE(p1, 10);
+
+ p2 = talloc_realloc_p(root, NULL, char, 20);
+ CHECK_SIZE(p1, 10);
+ CHECK_SIZE(root, 30);
+
+ if (talloc_steal(p1, NULL) != NULL) {
+ printf("failed: stealing NULL should give NULL\n");
+ return False;
+ }
+
+ if (talloc_steal(p1, p1) != p1) {
+ printf("failed: stealing to ourselves is a nop\n");
+ return False;
+ }
+ CHECK_BLOCKS(root, 3);
+ CHECK_SIZE(root, 30);
+
+ talloc_steal(NULL, p1);
+ talloc_steal(NULL, p2);
+ CHECK_BLOCKS(root, 1);
+ CHECK_SIZE(root, 0);
+
+ talloc_free(p1);
+ talloc_steal(root, p2);
+ CHECK_BLOCKS(root, 2);
+ CHECK_SIZE(root, 20);
+
+ talloc_free(p2);
+
+ CHECK_BLOCKS(root, 1);
+ CHECK_SIZE(root, 0);
+
+ talloc_free(root);
+
+ p1 = talloc(NULL, 3);
+ CHECK_SIZE(NULL, 3);
+ talloc_free(p1);
+
+ return True;
+}
+
+/*
+ test ldb alloc fn
+*/
+static BOOL test_ldb(void)
+{
+ void *root, *p1;
+
+ printf("TESTING LDB\n");
+
+ root = talloc(NULL, 0);
+
+ p1 = talloc_ldb_alloc(root, NULL, 10);
+ CHECK_BLOCKS(root, 2);
+ CHECK_SIZE(root, 10);
+ p1 = talloc_ldb_alloc(root, p1, 20);
+ CHECK_BLOCKS(root, 2);
+ CHECK_SIZE(root, 20);
+ p1 = talloc_ldb_alloc(root, p1, 0);
+ CHECK_BLOCKS(root, 1);
+ CHECK_SIZE(root, 0);
+
+ talloc_free(root);
+
+
+ return True;
+}
+
+/*
measure the speed of talloc versus malloc
*/
static BOOL test_speed(void)
@@ -340,6 +616,10 @@ BOOL torture_local_talloc(int dummy)
ret &= test_ref3();
ret &= test_ref4();
ret &= test_unref1();
+ ret &= test_misc();
+ ret &= test_realloc();
+ ret &= test_steal();
+ ret &= test_ldb();
ret &= test_speed();
return ret;