glib-aux/tests: add mechanims to track and free test data

This allows to free resources (a pointer) at the end of the test.
The purpose is to avoid valgrind warnings about leaks. While a leak
in the test is not a severe issue by itself, it does interfere with
checking for actual leaks. Thus every leak must be avoided.
This commit is contained in:
Thomas Haller 2022-12-20 17:49:10 +01:00
parent d0dff07687
commit 43860e2b74
No known key found for this signature in database
GPG key ID: 29C2366E4DFC5728

View file

@ -224,6 +224,11 @@
/*****************************************************************************/
struct __nmtst_testdata_track {
gpointer data;
GDestroyNotify destroy_notify;
};
struct __nmtst_internal {
GRand *rand0;
guint32 rand_seed;
@ -236,6 +241,7 @@ struct __nmtst_internal {
char *sudo_cmd;
char **orig_argv;
const char *testpath;
GArray *testdata_track_array;
};
extern struct __nmtst_internal __nmtst_internal;
@ -256,6 +262,62 @@ nmtst_initialized(void)
return !!__nmtst_internal.rand0;
}
/*****************************************************************************/
static inline void
_nmtst_testdata_track_clear_func(gpointer ptr)
{
struct __nmtst_testdata_track *d = ptr;
if (d->destroy_notify)
d->destroy_notify(d->data);
memset(d, 0, sizeof(*d));
}
static inline void
_nmtst_testdata_track_add(gpointer data, GDestroyNotify destroy_notify)
{
struct __nmtst_testdata_track d = {
.data = data,
.destroy_notify = destroy_notify,
};
g_assert(data);
g_assert(destroy_notify);
g_assert(__nmtst_internal.testdata_track_array);
g_array_append_val(__nmtst_internal.testdata_track_array, d);
}
static inline void
_nmtst_testdata_track_steal(gpointer data)
{
struct __nmtst_testdata_track *d;
guint i;
g_assert(data);
g_assert(__nmtst_internal.testdata_track_array);
for (i = 0; i < __nmtst_internal.testdata_track_array->len; i++) {
d = &g_array_index(__nmtst_internal.testdata_track_array, struct __nmtst_testdata_track, i);
if (d->data != data)
continue;
d->destroy_notify = NULL;
g_array_remove_index_fast(__nmtst_internal.testdata_track_array, i);
return;
}
g_assert_not_reached();
}
static inline void
_nmtst_testdata_track_steal_and_free(gpointer data)
{
_nmtst_testdata_track_steal(data);
g_free(data);
}
#define __NMTST_LOG(cmd, ...) \
G_STMT_START \
{ \
@ -324,6 +386,9 @@ nmtst_free(void)
if (!nmtst_initialized())
return;
g_array_set_size(__nmtst_internal.testdata_track_array, 0);
g_array_unref(__nmtst_internal.testdata_track_array);
g_rand_free(__nmtst_internal.rand0);
if (__nmtst_internal.rand)
g_rand_free(__nmtst_internal.rand);
@ -580,6 +645,10 @@ __nmtst_init(int *argc,
__nmtst_internal.sudo_cmd = sudo_cmd;
__nmtst_internal.no_expect_message = no_expect_message;
__nmtst_internal.testdata_track_array =
g_array_new(FALSE, FALSE, sizeof(struct __nmtst_testdata_track));
g_array_set_clear_func(__nmtst_internal.testdata_track_array, _nmtst_testdata_track_clear_func);
if (!log_level && log_domains) {
/* if the log level is not specified (but the domain is), we assume
* the caller wants to set it depending on is_debug */