[SSSD] [PATCH] Make leak checks usable in tests that do not utilize check
Jakub Hrozek
jhrozek at redhat.com
Thu Apr 11 07:52:59 UTC 2013
I am using the leak check to make sure the dyndns requests do not leak,
but the leak checks were only usable in conjunction with check. This
patch does the following:
* Remove check-specific failure reporting from common_check.c
* Add check-specific abstraction over memleak checks
* Rename common_check.c to leak_check.c
-------------- next part --------------
>From 1fb506be4110b9a9360bd2a1062a43d9e31b9c33 Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek at redhat.com>
Date: Mon, 1 Apr 2013 13:22:49 +0200
Subject: [PATCH] Make leak checks usable in tests that do not utilize check
* Remove check-specific failure reporting from common_check.c
* Check-specific abstraction over memleak checks
* Rename common_check.c to leak_check.c
---
Makefile.am | 4 +-
src/tests/common.h | 9 ++--
src/tests/common_check.c | 86 +++---------------------------
src/tests/common_check.h | 36 +++++++++++++
src/tests/crypto-tests.c | 8 +--
src/tests/fail_over-tests.c | 12 ++---
src/tests/ipa_hbac-tests.c | 6 +--
src/tests/{common_check.c => leak_check.c} | 49 ++++++++++++-----
src/tests/pac_responder-tests.c | 6 +--
src/tests/refcount-tests.c | 8 +--
src/tests/resolv-tests.c | 4 +-
src/tests/sss_idmap-tests.c | 18 +++----
src/tests/util-tests.c | 6 +--
13 files changed, 122 insertions(+), 130 deletions(-)
create mode 100644 src/tests/common_check.h
copy src/tests/{common_check.c => leak_check.c} (69%)
diff --git a/Makefile.am b/Makefile.am
index 332669551a781263e44fd855a920d370b5898c15..09056b5d9fec1d23213132940d11c312bcbfc23d 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -474,6 +474,7 @@ dist_noinst_HEADERS = \
src/resolv/ares/ares_parse_txt_reply.h \
src/resolv/ares/ares_data.h \
src/tests/common.h \
+ src/tests/common_check.h \
src/tests/cmocka/common_mock.h \
src/tests/cmocka/common_mock_resp.h \
src/sss_client/ssh/sss_ssh_client.h \
@@ -848,7 +849,8 @@ libsss_test_common_la_SOURCES = \
if HAVE_CHECK
libsss_test_common_la_SOURCES += \
- src/tests/common_check.c
+ src/tests/common_check.c \
+ src/tests/leak_check.c
sysdb_tests_DEPENDENCIES = \
$(ldblib_LTLIBRARIES)
diff --git a/src/tests/common.h b/src/tests/common.h
index 61dcbf41fb99312f68e5f06100c3fe25049038f0..e7fc812c7803cd5a5b85bb466f781e4a8efc3012 100644
--- a/src/tests/common.h
+++ b/src/tests/common.h
@@ -33,17 +33,18 @@
extern TALLOC_CTX *global_talloc_context;
#define check_leaks(ctx, bytes) _check_leaks((ctx), (bytes), __location__)
-void _check_leaks(TALLOC_CTX *ctx,
+bool _check_leaks(TALLOC_CTX *ctx,
size_t bytes,
const char *location);
void check_leaks_push(TALLOC_CTX *ctx);
#define check_leaks_pop(ctx) _check_leaks_pop((ctx), __location__)
-void _check_leaks_pop(TALLOC_CTX *ctx, const char *location);
+bool _check_leaks_pop(TALLOC_CTX *ctx, const char *location);
-void leak_check_setup(void);
-void leak_check_teardown(void);
+bool leak_check_setup(void);
+bool leak_check_teardown(void);
+const char *check_leaks_err_msg(void);
void tests_set_cwd(void);
diff --git a/src/tests/common_check.c b/src/tests/common_check.c
index d845923fb1792a5cddb948a4fca5048296eb51c6..94ca40ffe28543e2fee28a56ccc62e77831b2b67 100644
--- a/src/tests/common_check.c
+++ b/src/tests/common_check.c
@@ -1,7 +1,7 @@
/*
SSSD
- Common utilities for check-based tests using talloc.
+ Memory leak/growth checks for check-based tests using talloc.
Authors:
Martin Nagy <mnagy at redhat.com>
@@ -22,88 +22,18 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <stdio.h>
#include <check.h>
+
#include "tests/common.h"
-#include "util/util.h"
-#include "util/dlinklist.h"
-TALLOC_CTX *global_talloc_context = NULL;
-
-
-struct size_snapshot {
- struct size_snapshot *prev;
- struct size_snapshot *next;
-
- TALLOC_CTX *ctx;
- size_t bytes_allocated;
-};
-
-static struct size_snapshot *snapshot_stack;
-
-void
-_check_leaks(TALLOC_CTX *ctx, size_t bytes, const char *location)
-{
- size_t bytes_allocated;
-
- bytes_allocated = talloc_total_size(ctx);
- if (bytes_allocated != bytes) {
- fprintf(stderr, "Leak report for %s:\n", location);
- talloc_report_full(ctx, stderr);
- fail("%s: memory leaks detected, %d bytes still allocated",
- location, bytes_allocated - bytes);
- }
-}
-
-void
-check_leaks_push(TALLOC_CTX *ctx)
-{
- struct size_snapshot *snapshot;
-
- snapshot = talloc(NULL, struct size_snapshot);
- snapshot->ctx = ctx;
- snapshot->bytes_allocated = talloc_total_size(ctx);
- DLIST_ADD(snapshot_stack, snapshot);
-}
-
-void
-_check_leaks_pop(TALLOC_CTX *ctx, const char *location)
-{
- struct size_snapshot *snapshot;
- TALLOC_CTX *old_ctx;
- size_t bytes_allocated;
-
- if (snapshot_stack == NULL) {
- fail("%s: trying to pop an empty stack");
- }
-
- snapshot = snapshot_stack;
- DLIST_REMOVE(snapshot_stack, snapshot);
-
- old_ctx = snapshot->ctx;
- bytes_allocated = snapshot->bytes_allocated;
-
- fail_if(old_ctx != ctx, "Bad push/pop order");
-
- talloc_zfree(snapshot);
- _check_leaks(old_ctx, bytes_allocated, location);
-}
-
-void
-leak_check_setup(void)
+void ck_leak_check_setup(void)
{
- talloc_enable_null_tracking();
- global_talloc_context = talloc_new(NULL);
- fail_unless(global_talloc_context != NULL, "talloc_new failed");
- check_leaks_push(global_talloc_context);
+ fail_unless(leak_check_setup() == true,
+ "Cannot set up leaks test: %s\n", check_leaks_err_msg());
}
-void
-leak_check_teardown(void)
+void ck_leak_check_teardown(void)
{
- check_leaks_pop(global_talloc_context);
- if (snapshot_stack != NULL) {
- fail("Exiting with a non-empty stack");
- }
- check_leaks(global_talloc_context, 0);
+ fail_unless(leak_check_teardown() == true,
+ "Cannot tear down leaks test: %s\n", check_leaks_err_msg());
}
diff --git a/src/tests/common_check.h b/src/tests/common_check.h
new file mode 100644
index 0000000000000000000000000000000000000000..51c3c3f4989091a6d472c4635bbbb8c61ffafdb4
--- /dev/null
+++ b/src/tests/common_check.h
@@ -0,0 +1,36 @@
+/*
+ SSSD
+
+ Memory leak/growth checks for check-based tests using talloc.
+
+ Authors:
+ Martin Nagy <mnagy at redhat.com>
+
+ Copyright (C) Red Hat, Inc 2009
+
+ 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __TESTS_COMMON_CHECK_H__
+#define __TESTS_COMMON_CHECK_H__
+
+#include "tests/common.h"
+
+void ck_leak_check_setup(void);
+void ck_leak_check_teardown(void);
+
+#define ck_leaks_push(ctx) check_leaks_push(ctx)
+#define ck_leaks_pop(ctx) fail_unless(check_leaks_pop(ctx) == true, check_leaks_err_msg())
+
+#endif /* __TESTS_COMMON_CHECK_H__ */
diff --git a/src/tests/crypto-tests.c b/src/tests/crypto-tests.c
index 8932d8f5662647329bd1520fd9f40cf84df64a6e..87184594e2fb7cedc234350b56aa341d9de62713 100644
--- a/src/tests/crypto-tests.c
+++ b/src/tests/crypto-tests.c
@@ -26,7 +26,7 @@
#include <check.h>
#include "util/util.h"
-#include "tests/common.h"
+#include "tests/common_check.h"
/* interfaces under test */
#include "util/crypto/sss_crypto.h"
@@ -68,7 +68,7 @@ START_TEST(test_encrypt_decrypt)
test_ctx = talloc_new(NULL);
fail_if(test_ctx == NULL);
- check_leaks_push(test_ctx);
+ ck_leaks_push(test_ctx);
for (i=0; password[i]; i++) {
ret = sss_password_encrypt(test_ctx, password[i], strlen(password[i])+1,
@@ -84,7 +84,7 @@ START_TEST(test_encrypt_decrypt)
talloc_free(ctpwd);
}
- check_leaks_pop(test_ctx);
+ ck_leaks_pop(test_ctx);
talloc_free(test_ctx);
}
END_TEST
@@ -163,7 +163,7 @@ Suite *crypto_suite(void)
Suite *s = suite_create("sss_crypto");
TCase *tc = tcase_create("sss crypto tests");
- tcase_add_checked_fixture(tc, leak_check_setup, leak_check_teardown);
+ tcase_add_checked_fixture(tc, ck_leak_check_setup, ck_leak_check_teardown);
/* Do some testing */
#ifdef HAVE_NSS
tcase_add_test(tc, test_nss_init);
diff --git a/src/tests/fail_over-tests.c b/src/tests/fail_over-tests.c
index 93dda3a77aef9c7e000051dccf8b1b6e2ba83dff..c00025960f9ee593eb7f33a1bb13df056a702816 100644
--- a/src/tests/fail_over-tests.c
+++ b/src/tests/fail_over-tests.c
@@ -32,7 +32,7 @@
#include <tevent.h>
#include "resolv/async_resolv.h"
-#include "tests/common.h"
+#include "tests/common_check.h"
#include "util/util.h"
/* Interface under test */
@@ -107,13 +107,13 @@ START_TEST(test_fo_new_service)
struct fo_service *services[10];
ctx = setup_test();
- check_leaks_push(ctx);
+ ck_leaks_push(ctx);
for (i = 0; i < 10; i++) {
char buf[16];
sprintf(buf, "service_%d", i);
- check_leaks_push(ctx);
+ ck_leaks_push(ctx);
ret = fo_new_service(ctx->fo_ctx, buf, NULL, &services[i]);
fail_if(ret != EOK);
}
@@ -129,13 +129,13 @@ START_TEST(test_fo_new_service)
fail_if(ret != EOK);
fail_if(service != services[i]);
talloc_free(service);
- check_leaks_pop(ctx);
+ ck_leaks_pop(ctx);
ret = fo_get_service(ctx->fo_ctx, buf, &service);
fail_if(ret != ENOENT);
}
- check_leaks_pop(ctx);
+ ck_leaks_pop(ctx);
talloc_free(ctx);
}
END_TEST
@@ -264,7 +264,7 @@ create_suite(void)
TCase *tc = tcase_create("FAIL_OVER Tests");
- tcase_add_checked_fixture(tc, leak_check_setup, leak_check_teardown);
+ tcase_add_checked_fixture(tc, ck_leak_check_setup, ck_leak_check_teardown);
/* Do some testing */
tcase_add_test(tc, test_fo_new_service);
tcase_add_test(tc, test_fo_resolve_service);
diff --git a/src/tests/ipa_hbac-tests.c b/src/tests/ipa_hbac-tests.c
index 330e49e7c5570e02937b558701ed96df5d4e32c4..3c64fe044a2902622ae46b56687da920e8872c33 100644
--- a/src/tests/ipa_hbac-tests.c
+++ b/src/tests/ipa_hbac-tests.c
@@ -26,7 +26,7 @@
#include <sys/stat.h>
#include <talloc.h>
-#include "tests/common.h"
+#include "tests/common_check.h"
#include "providers/ipa/ipa_hbac.h"
#define HBAC_TEST_USER "testuser"
@@ -815,8 +815,8 @@ Suite *hbac_test_suite (void)
TCase *tc_hbac = tcase_create("HBAC_rules");
tcase_add_checked_fixture(tc_hbac,
- leak_check_setup,
- leak_check_teardown);
+ ck_leak_check_setup,
+ ck_leak_check_teardown);
tcase_add_test(tc_hbac, ipa_hbac_test_allow_all);
tcase_add_test(tc_hbac, ipa_hbac_test_allow_user);
diff --git a/src/tests/common_check.c b/src/tests/leak_check.c
similarity index 69%
copy from src/tests/common_check.c
copy to src/tests/leak_check.c
index d845923fb1792a5cddb948a4fca5048296eb51c6..89dac357bea6929cdc4eed9c4fbab214e249730c 100644
--- a/src/tests/common_check.c
+++ b/src/tests/leak_check.c
@@ -29,7 +29,7 @@
#include "util/dlinklist.h"
TALLOC_CTX *global_talloc_context = NULL;
-
+char leak_err_msg[256];
struct size_snapshot {
struct size_snapshot *prev;
@@ -41,7 +41,17 @@ struct size_snapshot {
static struct size_snapshot *snapshot_stack;
-void
+#define _set_leak_err_msg(fmt, ...) do { \
+ snprintf(leak_err_msg, sizeof(leak_err_msg), \
+ fmt, ##__VA_ARGS__); \
+} while(0);
+
+const char *check_leaks_err_msg(void)
+{
+ return leak_err_msg;
+}
+
+bool
_check_leaks(TALLOC_CTX *ctx, size_t bytes, const char *location)
{
size_t bytes_allocated;
@@ -50,9 +60,12 @@ _check_leaks(TALLOC_CTX *ctx, size_t bytes, const char *location)
if (bytes_allocated != bytes) {
fprintf(stderr, "Leak report for %s:\n", location);
talloc_report_full(ctx, stderr);
- fail("%s: memory leaks detected, %d bytes still allocated",
- location, bytes_allocated - bytes);
+ _set_leak_err_msg("%s: memory leaks detected, %zd bytes still allocated",
+ location, bytes_allocated - bytes);
+ return false;
}
+
+ return true;
}
void
@@ -66,7 +79,7 @@ check_leaks_push(TALLOC_CTX *ctx)
DLIST_ADD(snapshot_stack, snapshot);
}
-void
+bool
_check_leaks_pop(TALLOC_CTX *ctx, const char *location)
{
struct size_snapshot *snapshot;
@@ -74,7 +87,8 @@ _check_leaks_pop(TALLOC_CTX *ctx, const char *location)
size_t bytes_allocated;
if (snapshot_stack == NULL) {
- fail("%s: trying to pop an empty stack");
+ _set_leak_err_msg("%s: trying to pop an empty stack", location);
+ return false;
}
snapshot = snapshot_stack;
@@ -83,27 +97,36 @@ _check_leaks_pop(TALLOC_CTX *ctx, const char *location)
old_ctx = snapshot->ctx;
bytes_allocated = snapshot->bytes_allocated;
- fail_if(old_ctx != ctx, "Bad push/pop order");
+ if (old_ctx != ctx) {
+ _set_leak_err_msg("Bad push/pop order");
+ return false;
+ }
talloc_zfree(snapshot);
- _check_leaks(old_ctx, bytes_allocated, location);
+ return _check_leaks(old_ctx, bytes_allocated, location);
}
-void
+bool
leak_check_setup(void)
{
talloc_enable_null_tracking();
global_talloc_context = talloc_new(NULL);
- fail_unless(global_talloc_context != NULL, "talloc_new failed");
+ if (global_talloc_context == NULL) {
+ _set_leak_err_msg("talloc_new failed");
+ return false;
+ }
+
check_leaks_push(global_talloc_context);
+ return true;
}
-void
+bool
leak_check_teardown(void)
{
check_leaks_pop(global_talloc_context);
if (snapshot_stack != NULL) {
- fail("Exiting with a non-empty stack");
+ _set_leak_err_msg("Exiting with a non-empty stack");
+ return false;
}
- check_leaks(global_talloc_context, 0);
+ return check_leaks(global_talloc_context, 0);
}
diff --git a/src/tests/pac_responder-tests.c b/src/tests/pac_responder-tests.c
index 4b6f03f555b593f96c970eb6989a616fcb6ce1d7..ed8c9170d3cfe181fca24b8a31e30ee30d960e77 100644
--- a/src/tests/pac_responder-tests.c
+++ b/src/tests/pac_responder-tests.c
@@ -27,7 +27,7 @@
#include <util/data_blob.h>
#include <gen_ndr/security.h>
-#include "tests/common.h"
+#include "tests/common_check.h"
#include "responder/pac/pacsrv.h"
#include "lib/idmap/sss_idmap.h"
@@ -488,8 +488,8 @@ Suite *idmap_test_suite (void)
TCase *tc_pac = tcase_create("PAC responder tests");
tcase_add_checked_fixture(tc_pac,
- leak_check_setup,
- leak_check_teardown);
+ ck_leak_check_setup,
+ ck_leak_check_teardown);
tcase_add_checked_fixture(tc_pac,
pac_setup,
diff --git a/src/tests/refcount-tests.c b/src/tests/refcount-tests.c
index d93f1561f3ba753f9cf730fa8bcef003a6f106b2..9713d4783d5ea39c1550a56c048ff1fdc6852ea8 100644
--- a/src/tests/refcount-tests.c
+++ b/src/tests/refcount-tests.c
@@ -28,7 +28,7 @@
#include <tevent.h>
#include <popt.h>
-#include "tests/common.h"
+#include "tests/common_check.h"
#include "util/util.h"
/* Interface under test */
@@ -146,7 +146,7 @@ START_TEST(test_refcount_swap)
tmp_ctx = talloc_new(NULL);
- check_leaks_push(tmp_ctx);
+ ck_leaks_push(tmp_ctx);
container1 = talloc(tmp_ctx, struct container);
container2 = talloc(tmp_ctx, struct container);
@@ -170,7 +170,7 @@ START_TEST(test_refcount_swap)
CHECK_FILLER(container2->foo);
talloc_free(container2);
- check_leaks_pop(tmp_ctx);
+ ck_leaks_pop(tmp_ctx);
talloc_free(tmp_ctx);
}
END_TEST
@@ -182,7 +182,7 @@ Suite *create_suite(void)
TCase *tc = tcase_create("REFCOUNT Tests");
/* Do some testing */
- tcase_add_checked_fixture(tc, leak_check_setup, leak_check_teardown);
+ tcase_add_checked_fixture(tc, ck_leak_check_setup, ck_leak_check_teardown);
tcase_add_test(tc, test_refcount_basic);
tcase_add_test(tc, test_refcount_swap);
diff --git a/src/tests/resolv-tests.c b/src/tests/resolv-tests.c
index 61308e3827ceefff662649335a6e4da032886ce0..2480cf49eee6bee329e2d6a29a645a3cbfde8855 100644
--- a/src/tests/resolv-tests.c
+++ b/src/tests/resolv-tests.c
@@ -33,7 +33,7 @@
#include "tests/common.h"
#include "util/util.h"
-#include "tests/common.h"
+#include "tests/common_check.h"
/* Interface under test */
#include "resolv/async_resolv.h"
@@ -788,7 +788,7 @@ Suite *create_resolv_suite(void)
TCase *tc_resolv = tcase_create("RESOLV Tests");
- tcase_add_checked_fixture(tc_resolv, leak_check_setup, leak_check_teardown);
+ tcase_add_checked_fixture(tc_resolv, ck_leak_check_setup, ck_leak_check_teardown);
/* Do some testing */
tcase_add_test(tc_resolv, test_copy_hostent);
tcase_add_test(tc_resolv, test_resolv_ip_addr);
diff --git a/src/tests/sss_idmap-tests.c b/src/tests/sss_idmap-tests.c
index e6d75372a14535ae2f64904214f48d8b2669858c..eb204137aaa402403159ed653819756d515e1ace 100644
--- a/src/tests/sss_idmap-tests.c
+++ b/src/tests/sss_idmap-tests.c
@@ -24,7 +24,7 @@
#include "lib/idmap/sss_idmap.h"
#include "lib/idmap/sss_idmap_private.h"
-#include "tests/common.h"
+#include "tests/common_check.h"
#define IDMAP_RANGE_MIN 1234
#define IDMAP_RANGE_MAX 9876
@@ -492,8 +492,8 @@ Suite *idmap_test_suite (void)
TCase *tc_init = tcase_create("IDMAP init tests");
tcase_add_checked_fixture(tc_init,
- leak_check_setup,
- leak_check_teardown);
+ ck_leak_check_setup,
+ ck_leak_check_teardown);
tcase_add_test(tc_init, idmap_test_init_malloc);
tcase_add_test(tc_init, idmap_test_init_talloc);
@@ -503,8 +503,8 @@ Suite *idmap_test_suite (void)
TCase *tc_dom = tcase_create("IDMAP domain tests");
tcase_add_checked_fixture(tc_dom,
- leak_check_setup,
- leak_check_teardown);
+ ck_leak_check_setup,
+ ck_leak_check_teardown);
tcase_add_checked_fixture(tc_dom,
idmap_ctx_setup,
idmap_ctx_teardown);
@@ -515,8 +515,8 @@ Suite *idmap_test_suite (void)
TCase *tc_conv = tcase_create("IDMAP SID conversion tests");
tcase_add_checked_fixture(tc_conv,
- leak_check_setup,
- leak_check_teardown);
+ ck_leak_check_setup,
+ ck_leak_check_teardown);
tcase_add_checked_fixture(tc_conv,
idmap_ctx_setup,
idmap_ctx_teardown);
@@ -536,8 +536,8 @@ Suite *idmap_test_suite (void)
TCase *tc_map = tcase_create("IDMAP mapping tests");
tcase_add_checked_fixture(tc_map,
- leak_check_setup,
- leak_check_teardown);
+ ck_leak_check_setup,
+ ck_leak_check_teardown);
tcase_add_checked_fixture(tc_map,
idmap_ctx_setup,
idmap_ctx_teardown);
diff --git a/src/tests/util-tests.c b/src/tests/util-tests.c
index e7e04e6574f02c47f45de7bd36168c6d5d8bcd74..4b0d5009c7c65f259f66aa66eb68281098164b74 100644
--- a/src/tests/util-tests.c
+++ b/src/tests/util-tests.c
@@ -31,7 +31,7 @@
#include "util/util.h"
#include "util/sss_utf8.h"
#include "util/murmurhash3.h"
-#include "tests/common.h"
+#include "tests/common_check.h"
#define FILENAME_TEMPLATE "tests-atomicio-XXXXXX"
char *filename;
@@ -815,8 +815,8 @@ Suite *util_suite(void)
TCase *tc_util = tcase_create("util");
tcase_add_checked_fixture(tc_util,
- leak_check_setup,
- leak_check_teardown);
+ ck_leak_check_setup,
+ ck_leak_check_teardown);
tcase_add_test (tc_util, test_diff_string_lists);
tcase_add_test (tc_util, test_sss_filter_sanitize);
tcase_add_test (tc_util, test_size_t_overflow);
--
1.8.1.4
More information about the sssd-devel
mailing list