Merge branch 'param-leak' into 'main'

gtestutils: Ensure test_data is freed even if a test is skipped

See merge request GNOME/glib!3887
This commit is contained in:
Michael Catanzaro 2024-02-06 18:33:23 +00:00
commit a040562d6c
2 changed files with 43 additions and 16 deletions

View File

@ -2885,12 +2885,13 @@ g_test_queue_free (gpointer gfree_pointer)
* @destroy_func: Destroy callback for teardown phase.
* @destroy_data: Destroy callback data.
*
* This function enqueus a callback @destroy_func to be executed
* during the next test case teardown phase. This is most useful
* to auto destruct allocated test resources at the end of a test run.
* Resources are released in reverse queue order, that means enqueueing
* callback A before callback B will cause B() to be called before
* A() during teardown.
* Enqueues a callback @destroy_func to be executed during the next test case
* teardown phase.
*
* This is most useful to auto destroy allocated test resources at the end of a
* test run. Resources are released in reverse queue order, that means
* enqueueing callback `A` before callback `B` will cause `B()` to be called
* before `A()` during teardown.
*
* Since: 2.16
*/
@ -2925,17 +2926,30 @@ test_has_prefix (gconstpointer a,
return g_strcmp0 (test_run_name_local, test_path_skipped_local);
}
static gboolean test_should_run (const char *test_path,
const char *cmp_path);
static gboolean
test_case_run (GTestCase *tc)
test_case_run (GTestCase *tc,
const char *test_run_name,
const char *path)
{
gchar *old_base = g_strdup (test_uri_base);
gchar *old_base = NULL;
GSList **old_free_list, *filename_free_list = NULL;
gboolean success = G_TEST_RUN_SUCCESS;
gboolean free_test_data = TRUE;
old_base = g_strdup (test_uri_base);
old_free_list = test_filename_free_list;
test_filename_free_list = &filename_free_list;
if (++test_run_count <= test_startup_skip_count)
if (!test_should_run (test_run_name, path))
{
/* Silently skip the test and return success. This happens if its a
* /subprocess path. */
success = G_TEST_RUN_SKIPPED;
}
else if (++test_run_count <= test_startup_skip_count)
g_test_log (G_TEST_LOG_SKIP_CASE, test_run_name, NULL, 0, NULL);
else if (test_run_list)
{
@ -2982,6 +2996,7 @@ test_case_run (GTestCase *tc)
}
if (tc->fixture_teardown)
tc->fixture_teardown (fixture, tc->test_data);
free_test_data = FALSE;
if (tc->fixture_size)
g_free (fixture);
g_timer_stop (test_run_timer);
@ -2999,6 +3014,13 @@ test_case_run (GTestCase *tc)
g_timer_destroy (test_run_timer);
}
/* In case the test didnt run (due to being skipped or an error), the test
* data may still need to be freed, as the clients main() function may have
* passed ownership of it into g_test_add_data_func_full() with a
* #GDestroyNotify. */
if (free_test_data && tc->fixture_size == 0 && tc->fixture_teardown != NULL)
tc->fixture_teardown (tc->test_data, tc->test_data);
g_slist_free_full (filename_free_list, g_free);
test_filename_free_list = old_free_list;
g_free (test_uri_base);
@ -3064,11 +3086,10 @@ g_test_run_suite_internal (GTestSuite *suite,
test_run_name = g_build_path ("/", old_name, tc->name, NULL);
test_run_name_path = g_build_path (G_DIR_SEPARATOR_S, old_name_path, tc->name, NULL);
if (test_should_run (test_run_name, path))
{
if (!test_case_run (tc))
n_bad++;
}
if (!test_case_run (tc, test_run_name, path))
n_bad++;
g_free (test_run_name);
g_free (test_run_name_path);
}

View File

@ -1397,6 +1397,13 @@ test_param_implement (void)
{
gchar *test_path;
/* This test is slow. */
if (!g_test_slow ())
{
g_test_skip ("Skipping slow /param/implement test");
return;
}
for (change_this_flag = 0; change_this_flag < 16; change_this_flag++)
for (change_this_type = 0; change_this_type < 3; change_this_type++)
for (use_this_flag = 0; use_this_flag < 16; use_this_flag++)
@ -1658,8 +1665,7 @@ main (int argc, char *argv[])
g_test_add_func ("/param/validate", test_param_validate);
g_test_add_func ("/param/convert", test_param_convert);
if (g_test_slow ())
g_test_add_func ("/param/implement", test_param_implement);
g_test_add_func ("/param/implement", test_param_implement);
for (data.change_this_flag = 0; data.change_this_flag < 16; data.change_this_flag++)
for (data.change_this_type = 0; data.change_this_type < 3; data.change_this_type++)