tests: merge branch 'th/leak-test-data'

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1492
This commit is contained in:
Thomas Haller 2023-01-17 16:27:41 +01:00
commit a45029b7b0
No known key found for this signature in database
GPG key ID: 29C2366E4DFC5728
2 changed files with 137 additions and 35 deletions

View file

@ -1004,12 +1004,14 @@ nm_dedup_multi_index_new(void)
{
NMDedupMultiIndex *self;
self = g_slice_new0(NMDedupMultiIndex);
self->ref_count = 1;
self->idx_entries =
g_hash_table_new((GHashFunc) _dict_idx_entries_hash, (GEqualFunc) _dict_idx_entries_equal);
self->idx_objs =
g_hash_table_new((GHashFunc) _dict_idx_objs_hash, (GEqualFunc) _dict_idx_objs_equal);
self = g_slice_new(NMDedupMultiIndex);
*self = (NMDedupMultiIndex){
.ref_count = 1,
.idx_entries = g_hash_table_new((GHashFunc) _dict_idx_entries_hash,
(GEqualFunc) _dict_idx_entries_equal),
.idx_objs =
g_hash_table_new((GHashFunc) _dict_idx_objs_hash, (GEqualFunc) _dict_idx_objs_equal),
};
return self;
}
@ -1018,6 +1020,7 @@ nm_dedup_multi_index_ref(NMDedupMultiIndex *self)
{
g_return_val_if_fail(self, NULL);
g_return_val_if_fail(self->ref_count > 0, NULL);
nm_assert(self->ref_count < G_MAXINT32);
self->ref_count++;
return self;

View file

@ -224,17 +224,24 @@
/*****************************************************************************/
struct __nmtst_testdata_track {
gpointer data;
GDestroyNotify destroy_notify;
};
struct __nmtst_internal {
GRand *rand0;
guint32 rand_seed;
GRand *rand;
gboolean is_debug;
gboolean assert_logging;
gboolean no_expect_message;
gboolean test_quick;
gboolean test_tap_log;
char *sudo_cmd;
char **orig_argv;
GRand *rand0;
guint32 rand_seed;
GRand *rand;
gboolean is_debug;
gboolean assert_logging;
gboolean no_expect_message;
gboolean test_quick;
gboolean test_tap_log;
char *sudo_cmd;
char **orig_argv;
const char *testpath;
GArray *testdata_track_array;
};
extern struct __nmtst_internal __nmtst_internal;
@ -255,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 \
{ \
@ -323,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);
@ -579,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 */
@ -777,15 +847,12 @@ typedef struct _NmtstTestData NmtstTestData;
typedef void (*NmtstTestHandler)(const NmtstTestData *test_data);
struct _NmtstTestData {
union {
const char *testpath;
char *_testpath;
};
const char *testpath;
gsize n_args;
gpointer *args;
NmtstTestHandler _func_setup;
GTestDataFunc _func_test;
NmtstTestHandler _func_teardown;
gpointer args[];
};
static inline void
@ -810,15 +877,20 @@ _nmtst_test_data_unpack(const NmtstTestData *test_data, gsize n_args, ...)
#define nmtst_test_data_unpack(test_data, ...) \
_nmtst_test_data_unpack(test_data, NM_NARG(__VA_ARGS__), ##__VA_ARGS__)
static inline void
_nmtst_test_data_free(gpointer data)
static inline const char *
nmtst_test_get_path(void)
{
NmtstTestData *test_data = data;
g_assert(nmtst_initialized());
g_assert(__nmtst_internal.testpath);
g_assert(test_data);
/* Similar to g_test_get_path() (which only exists since glib 2.68).
*
* This is the test name while running the test added with
* nmtst_add_test_func*().
*
* You are only allowed to call this from inside such a test. */
g_free(test_data->_testpath);
g_free(test_data);
return __nmtst_internal.testpath;
}
static inline void
@ -826,6 +898,13 @@ _nmtst_test_run(gconstpointer data)
{
const NmtstTestData *test_data = data;
g_assert(test_data);
g_assert(nmtst_initialized());
g_assert(test_data->testpath);
g_assert(!__nmtst_internal.testpath);
__nmtst_internal.testpath = test_data->testpath;
if (test_data->_func_setup)
test_data->_func_setup(test_data);
@ -833,6 +912,10 @@ _nmtst_test_run(gconstpointer data)
if (test_data->_func_teardown)
test_data->_func_teardown(test_data);
g_assert(__nmtst_internal.testpath);
g_assert(__nmtst_internal.testpath == test_data->testpath);
__nmtst_internal.testpath = NULL;
}
static inline void
@ -846,26 +929,41 @@ _nmtst_add_test_func_full(const char *testpath,
gsize i;
NmtstTestData *data;
va_list ap;
gsize testpath_len;
g_assert(testpath && testpath[0]);
g_assert(func_test);
data = g_malloc0(sizeof(NmtstTestData) + (sizeof(gpointer) * (n_args + 1)));
testpath_len = strlen(testpath) + 1u;
data = g_malloc(G_STRUCT_OFFSET(NmtstTestData, args)
+ (sizeof(gpointer) * (n_args + 1u) + testpath_len));
*data = (NmtstTestData){
.testpath = (gpointer) &data->args[n_args + 1u],
._func_test = func_test,
._func_setup = func_setup,
._func_teardown = func_teardown,
.n_args = n_args,
};
data->_testpath = g_strdup(testpath);
data->_func_test = func_test;
data->_func_setup = func_setup;
data->_func_teardown = func_teardown;
data->n_args = n_args;
data->args = (gpointer) &data[1];
va_start(ap, n_args);
for (i = 0; i < n_args; i++)
data->args[i] = va_arg(ap, gpointer);
data->args[i] = NULL;
va_end(ap);
g_test_add_data_func_full(testpath, data, _nmtst_test_run, _nmtst_test_data_free);
g_assert(data->testpath == (gpointer) &data->args[i + 1]);
memcpy((char *) data->testpath, testpath, testpath_len);
_nmtst_testdata_track_add(data, g_free);
g_test_add_data_func_full(testpath,
data,
_nmtst_test_run,
_nmtst_testdata_track_steal_and_free);
}
#define nmtst_add_test_func_full(testpath, func_test, func_setup, func_teardown, ...) \
_nmtst_add_test_func_full(testpath, \
func_test, \
@ -873,6 +971,7 @@ _nmtst_add_test_func_full(const char *testpath,
func_teardown, \
NM_NARG(__VA_ARGS__), \
##__VA_ARGS__)
#define nmtst_add_test_func(testpath, func_test, ...) \
nmtst_add_test_func_full(testpath, func_test, NULL, NULL, ##__VA_ARGS__)