/* test references */ static bool test_ref3(void) { void *root, *p1, *p2, *ref, *r1; printf("test: ref3 [\nPARENT REFERENCE FREE\n]\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, stderr); CHECK_BLOCKS("ref3", p1, 2); CHECK_BLOCKS("ref3", p2, 2); CHECK_BLOCKS("ref3", r1, 1); fprintf(stderr, "Freeing p1\n"); talloc_free(p1); talloc_report_full(root, stderr); CHECK_BLOCKS("ref3", p2, 2); CHECK_BLOCKS("ref3", r1, 1); fprintf(stderr, "Freeing p2\n"); talloc_free(p2); talloc_report_full(root, stderr); CHECK_SIZE("ref3", root, 0); talloc_free(root); printf("success: ref3\n"); return true; }
/* test realloc */ static bool test_realloc(void) { void *root, *p1, *p2; printf("test: realloc [\nREALLOC\n]\n"); root = talloc_new(NULL); p1 = talloc_size(root, 10); CHECK_SIZE("realloc", p1, 10); p1 = talloc_realloc_size(NULL, p1, 20); CHECK_SIZE("realloc", p1, 20); talloc_new(p1); p2 = talloc_realloc_size(p1, NULL, 30); talloc_new(p1); p2 = talloc_realloc_size(p1, p2, 40); CHECK_SIZE("realloc", p2, 40); CHECK_SIZE("realloc", root, 60); CHECK_BLOCKS("realloc", p1, 4); p1 = talloc_realloc_size(NULL, p1, 20); CHECK_SIZE("realloc", p1, 60); talloc_increase_ref_count(p2); torture_assert("realloc", talloc_realloc_size(NULL, p2, 5) == NULL, "failed: talloc_realloc() on a referenced pointer should fail\n"); CHECK_BLOCKS("realloc", p1, 4); talloc_realloc_size(NULL, p2, 0); talloc_realloc_size(NULL, p2, 0); CHECK_BLOCKS("realloc", p1, 3); torture_assert("realloc", talloc_realloc_size(NULL, p1, 0x7fffffff) == NULL, "failed: oversize talloc should fail\n"); talloc_realloc_size(NULL, p1, 0); CHECK_BLOCKS("realloc", root, 1); CHECK_SIZE("realloc", root, 0); talloc_free(root); printf("success: REALLOC\n"); return true; }
/* test steal */ static bool test_steal(void) { void *root, *p1, *p2; printf("test: steal\n# STEAL\n"); root = talloc_new(NULL); p1 = talloc_array(root, char, 10); CHECK_SIZE("steal", p1, 10); p2 = talloc_realloc(root, NULL, char, 20); CHECK_SIZE("steal", p1, 10); CHECK_SIZE("steal", root, 30); torture_assert("steal", talloc_steal(p1, NULL) == NULL, "failed: stealing NULL should give NULL\n"); torture_assert("steal", talloc_steal(p1, p1) == p1, "failed: stealing to ourselves is a nop\n"); CHECK_BLOCKS("steal", root, 3); CHECK_SIZE("steal", root, 30); talloc_steal(NULL, p1); talloc_steal(NULL, p2); CHECK_BLOCKS("steal", root, 1); CHECK_SIZE("steal", root, 0); talloc_free(p1); talloc_steal(root, p2); CHECK_BLOCKS("steal", root, 2); CHECK_SIZE("steal", root, 20); talloc_free(p2); CHECK_BLOCKS("steal", root, 1); CHECK_SIZE("steal", root, 0); talloc_free(root); p1 = talloc_size(NULL, 3); talloc_report_full(NULL, stderr); CHECK_SIZE("steal", NULL, 3); talloc_free(p1); printf("success: steal\n"); return true; }
/* test references */ static bool test_ref1(void) { void *root, *p1, *p2, *ref, *r1; printf("test: ref1\n# 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, stderr); CHECK_BLOCKS("ref1", p1, 5); CHECK_BLOCKS("ref1", p2, 1); CHECK_BLOCKS("ref1", ref, 1); CHECK_BLOCKS("ref1", r1, 2); fprintf(stderr, "Freeing p2\n"); talloc_unlink(r1, p2); talloc_report_full(root, stderr); CHECK_BLOCKS("ref1", p1, 5); CHECK_BLOCKS("ref1", p2, 1); CHECK_BLOCKS("ref1", r1, 1); fprintf(stderr, "Freeing p1\n"); talloc_free(p1); talloc_report_full(root, stderr); CHECK_BLOCKS("ref1", r1, 1); fprintf(stderr, "Freeing r1\n"); talloc_free(r1); talloc_report_full(NULL, stderr); fprintf(stderr, "Testing NULL\n"); if (talloc_reference(root, NULL)) { return false; } CHECK_BLOCKS("ref1", root, 1); CHECK_SIZE("ref1", root, 0); talloc_free(root); printf("success: ref1\n"); return true; }
/* test references */ static bool test_ref2(void) { void *root, *p1, *p2, *ref, *r1; printf("test: ref2\n# 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, stderr); CHECK_BLOCKS("ref2", p1, 5); CHECK_BLOCKS("ref2", p2, 1); CHECK_BLOCKS("ref2", r1, 2); fprintf(stderr, "Freeing ref\n"); talloc_unlink(r1, ref); talloc_report_full(root, stderr); CHECK_BLOCKS("ref2", p1, 5); CHECK_BLOCKS("ref2", p2, 1); CHECK_BLOCKS("ref2", r1, 1); fprintf(stderr, "Freeing p2\n"); talloc_free(p2); talloc_report_full(root, stderr); CHECK_BLOCKS("ref2", p1, 4); CHECK_BLOCKS("ref2", r1, 1); fprintf(stderr, "Freeing p1\n"); talloc_free(p1); talloc_report_full(root, stderr); CHECK_BLOCKS("ref2", r1, 1); fprintf(stderr, "Freeing r1\n"); talloc_free(r1); talloc_report_full(root, stderr); CHECK_SIZE("ref2", root, 0); talloc_free(root); printf("success: ref2\n"); return true; }
static bool test_free_children(void) { void *root; const char *p1, *p2, *name, *name2; talloc_enable_null_tracking(); root = talloc_new(NULL); p1 = talloc_strdup(root, "foo1"); p2 = talloc_strdup(p1, "foo2"); talloc_set_name(p1, "%s", "testname"); talloc_free_children(p1); /* check its still a valid talloc ptr */ talloc_get_size(talloc_get_name(p1)); if (strcmp(talloc_get_name(p1), "testname") != 0) { return false; } talloc_set_name(p1, "%s", "testname"); name = talloc_get_name(p1); talloc_free_children(p1); /* check its still a valid talloc ptr */ talloc_get_size(talloc_get_name(p1)); torture_assert("name", name == talloc_get_name(p1), "name ptr changed"); torture_assert("namecheck", strcmp(talloc_get_name(p1), "testname") == 0, "wrong name"); CHECK_BLOCKS("name1", p1, 2); /* note that this does not free the old child name */ talloc_set_name_const(p1, "testname2"); name2 = talloc_get_name(p1); /* but this does */ talloc_free_children(p1); torture_assert("namecheck", strcmp(talloc_get_name(p1), "testname2") == 0, "wrong name"); CHECK_BLOCKS("name1", p1, 1); talloc_report_full(root, stdout); talloc_free(root); return true; }
/* test talloc_realloc_fn */ static bool test_realloc_fn(void) { void *root, *p1; printf("test: realloc_fn\n# talloc_realloc_fn\n"); root = talloc_new(NULL); p1 = talloc_realloc_fn(root, NULL, 10); CHECK_BLOCKS("realloc_fn", root, 2); CHECK_SIZE("realloc_fn", root, 10); p1 = talloc_realloc_fn(root, p1, 20); CHECK_BLOCKS("realloc_fn", root, 2); CHECK_SIZE("realloc_fn", root, 20); p1 = talloc_realloc_fn(root, p1, 0); CHECK_BLOCKS("realloc_fn", root, 1); CHECK_SIZE("realloc_fn", root, 0); talloc_free(root); printf("success: realloc_fn\n"); return true; }
static bool test_rusty(void) { void *root; const char *p1; talloc_enable_null_tracking(); root = talloc_new(NULL); p1 = talloc_strdup(root, "foo"); talloc_increase_ref_count(p1); talloc_report_full(root, stdout); talloc_free(root); CHECK_BLOCKS("null_context", NULL, 2); return true; }
/* test references */ static bool test_unlink1(void) { void *root, *p1, *p2, *ref, *r1; printf("test: unlink\n# 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, stderr); CHECK_BLOCKS("unlink", p1, 7); CHECK_BLOCKS("unlink", p2, 1); CHECK_BLOCKS("unlink", ref, 1); CHECK_BLOCKS("unlink", r1, 2); fprintf(stderr, "Unreferencing r1\n"); talloc_unlink(r1, p2); talloc_report_full(root, stderr); CHECK_BLOCKS("unlink", p1, 6); CHECK_BLOCKS("unlink", p2, 1); CHECK_BLOCKS("unlink", r1, 1); fprintf(stderr, "Freeing p1\n"); talloc_free(p1); talloc_report_full(root, stderr); CHECK_SIZE("unlink", root, 0); talloc_free(root); printf("success: unlink\n"); return true; }
/* miscellaneous tests to try to get a higher test coverage percentage */ static bool test_misc(void) { void *root, *p1; char *p2; double *d; const char *name; printf("test: misc\n# MISCELLANEOUS\n"); root = talloc_new(NULL); p1 = talloc_size(root, 0x7fffffff); torture_assert("misc", !p1, "failed: large talloc allowed\n"); p1 = talloc_strdup(root, "foo"); talloc_increase_ref_count(p1); talloc_increase_ref_count(p1); talloc_increase_ref_count(p1); CHECK_BLOCKS("misc", p1, 1); CHECK_BLOCKS("misc", root, 2); talloc_unlink(NULL, p1); CHECK_BLOCKS("misc", p1, 1); CHECK_BLOCKS("misc", root, 2); talloc_unlink(NULL, p1); CHECK_BLOCKS("misc", p1, 1); CHECK_BLOCKS("misc", root, 2); p2 = talloc_strdup(p1, "foo"); torture_assert("misc", talloc_unlink(root, p2) == -1, "failed: talloc_unlink() of non-reference context should return -1\n"); torture_assert("misc", talloc_unlink(p1, p2) == 0, "failed: talloc_unlink() of parent should succeed\n"); talloc_unlink(NULL, p1); CHECK_BLOCKS("misc", p1, 1); CHECK_BLOCKS("misc", root, 2); name = talloc_set_name(p1, "my name is %s", "foo"); torture_assert_str_equal("misc", talloc_get_name(p1), "my name is foo", "failed: wrong name after talloc_set_name(my name is foo)"); torture_assert_str_equal("misc", talloc_get_name(p1), name, "failed: wrong name after talloc_set_name(my name is foo)"); CHECK_BLOCKS("misc", p1, 2); CHECK_BLOCKS("misc", root, 3); talloc_set_name_const(p1, NULL); torture_assert_str_equal ("misc", talloc_get_name(p1), "UNNAMED", "failed: wrong name after talloc_set_name(NULL)"); CHECK_BLOCKS("misc", p1, 2); CHECK_BLOCKS("misc", root, 3); torture_assert("misc", talloc_free(NULL) == -1, "talloc_free(NULL) should give -1\n"); talloc_set_destructor(p1, fail_destructor); torture_assert("misc", talloc_free(p1) == -1, "Failed destructor should cause talloc_free to fail\n"); talloc_set_destructor(p1, NULL); talloc_report(root, stderr); p2 = (char *)talloc_zero_size(p1, 20); torture_assert("misc", p2[19] == 0, "Failed to give zero memory\n"); talloc_free(p2); torture_assert("misc", talloc_strdup(root, NULL) == NULL, "failed: strdup on NULL should give NULL\n"); p2 = talloc_strndup(p1, "foo", 2); torture_assert("misc", strcmp("fo", p2) == 0, "strndup doesn't work\n"); p2 = talloc_asprintf_append_buffer(p2, "o%c", 'd'); torture_assert("misc", strcmp("food", p2) == 0, "talloc_asprintf_append_buffer doesn't work\n"); CHECK_BLOCKS("misc", p2, 1); CHECK_BLOCKS("misc", p1, 3); p2 = talloc_asprintf_append_buffer(NULL, "hello %s", "world"); torture_assert("misc", strcmp("hello world", p2) == 0, "talloc_asprintf_append_buffer doesn't work\n"); CHECK_BLOCKS("misc", p2, 1); CHECK_BLOCKS("misc", p1, 3); talloc_free(p2); d = talloc_array(p1, double, 0x20000000); torture_assert("misc", !d, "failed: integer overflow not detected\n"); d = talloc_realloc(p1, d, double, 0x20000000); torture_assert("misc", !d, "failed: integer overflow not detected\n"); talloc_free(p1); CHECK_BLOCKS("misc", root, 1); p1 = talloc_named(root, 100, "%d bytes", 100); CHECK_BLOCKS("misc", p1, 2); CHECK_BLOCKS("misc", root, 3); talloc_unlink(root, p1); p1 = talloc_init("%d bytes", 200); p2 = talloc_asprintf(p1, "my test '%s'", "string"); torture_assert_str_equal("misc", p2, "my test 'string'", "failed: talloc_asprintf(\"my test '%%s'\", \"string\") gave: \"%s\""); CHECK_BLOCKS("misc", p1, 3); CHECK_SIZE("misc", p2, 17); CHECK_BLOCKS("misc", root, 1); talloc_unlink(NULL, p1); p1 = talloc_named_const(root, 10, "p1"); p2 = (char *)talloc_named_const(root, 20, "p2"); (void)talloc_reference(p1, p2); talloc_report_full(root, stderr); talloc_unlink(root, p2); talloc_report_full(root, stderr); CHECK_BLOCKS("misc", p2, 1); CHECK_BLOCKS("misc", p1, 2); CHECK_BLOCKS("misc", root, 3); talloc_unlink(p1, p2); talloc_unlink(root, p1); p1 = talloc_named_const(root, 10, "p1"); p2 = (char *)talloc_named_const(root, 20, "p2"); (void)talloc_reference(NULL, p2); talloc_report_full(root, stderr); talloc_unlink(root, p2); talloc_report_full(root, stderr); CHECK_BLOCKS("misc", p2, 1); CHECK_BLOCKS("misc", p1, 1); CHECK_BLOCKS("misc", root, 2); talloc_unlink(NULL, p2); talloc_unlink(root, p1); /* Test that talloc_unlink is a no-op */ torture_assert("misc", talloc_unlink(root, NULL) == -1, "failed: talloc_unlink(root, NULL) == -1\n"); talloc_report(root, stderr); talloc_report(NULL, stderr); CHECK_SIZE("misc", root, 0); talloc_free(root); CHECK_SIZE("misc", NULL, 0); talloc_enable_null_tracking_no_autofree(); talloc_enable_leak_report(); talloc_enable_leak_report_full(); printf("success: misc\n"); return true; }