From a6a87506877939fee54bdc7eca70d47fc7d893d4 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sat, 17 Aug 2013 15:18:29 -0400 Subject: [PATCH] Add a way to make assertions non-fatal When using test harnesses other than gtester (e.g. using TAP), it can be suboptimal to have the very first failed assertion abort the test suite. This commit adds a g_test_set_nonfatal_assertions() that can be called in a test binary to change the behaviour of most assert macros to just call g_test_fail() and continue. We don't change the behavior of g_assert() and g_assert_not_reached(), since these to assertion macros are older than GTest, are widely used outside of testsuites, and will cause compiler warnings if they loose their noreturn annotation. https://bugzilla.gnome.org/show_bug.cgi?id=692125 --- glib/gtestutils.c | 27 +++++++++++++++++++++++++++ glib/gtestutils.h | 10 ++++++---- 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/glib/gtestutils.c b/glib/gtestutils.c index 948f57ccf..3aec27e6e 100644 --- a/glib/gtestutils.c +++ b/glib/gtestutils.c @@ -598,6 +598,7 @@ static char *test_trap_last_stderr = NULL; static char *test_uri_base = NULL; static gboolean test_debug_log = FALSE; static gboolean test_tap_log = FALSE; +static gboolean test_nonfatal_assertions = FALSE; static DestroyEntry *test_destroy_queue = NULL; static char *test_argv0 = NULL; static char *test_argv0_dirname; @@ -1725,6 +1726,31 @@ g_test_failed (void) return test_run_success != G_TEST_RUN_SUCCESS; } +/** + * g_test_set_nonfatal_assertions: + * + * Changes the behaviour of g_assert_cmpstr(), g_assert_cmpint(), + * g_assert_cmpuint(), g_assert_cmphex(), g_assert_cmpfloat(), + * g_assert_true(), g_assert_false(), g_assert_null(), g_assert_no_error(), + * g_assert_error(), g_test_assert_expected_messages() and the various + * g_test_trap_assert_*() macros to not abort to program, but instead + * call g_test_fail() and continue. + * + * Note that the g_assert_not_reached() and g_assert() are not + * affected by this. + * + * This function can only be called after g_test_init(). + * + * Since: 2.38 + */ +void +g_test_set_nonfatal_assertions (void) +{ + if (!g_test_config_vars->test_initialized) + g_error ("g_test_set_nonfatal_assertions called without g_test_init"); + test_nonfatal_assertions = TRUE; +} + /** * GTestFunc: * @@ -2252,6 +2278,7 @@ g_assertion_message_expr (const char *domain, s = g_strconcat ("assertion failed: (", expr, ")", NULL); g_assertion_message (domain, file, line, func, s); g_free (s); + abort (); } void diff --git a/glib/gtestutils.h b/glib/gtestutils.h index 65a8c0987..889df44ac 100644 --- a/glib/gtestutils.h +++ b/glib/gtestutils.h @@ -148,6 +148,8 @@ GLIB_AVAILABLE_IN_2_38 void g_test_skip (const gchar *msg); GLIB_AVAILABLE_IN_2_38 gboolean g_test_failed (void); +GLIB_AVAILABLE_IN_2_38 +void g_test_set_nonfatal_assertions (void); /* hook up a test with fixture under test path */ #define g_test_add(testpath, Fixture, tdata, fsetup, ftest, fteardown) \ @@ -265,7 +267,7 @@ void g_assertion_message (const char *domain, const char *file, int line, const char *func, - const char *message) G_GNUC_NORETURN; + const char *message); GLIB_AVAILABLE_IN_ALL void g_assertion_message_expr (const char *domain, const char *file, @@ -280,7 +282,7 @@ void g_assertion_message_cmpstr (const char *domain, const char *expr, const char *arg1, const char *cmp, - const char *arg2) G_GNUC_NORETURN; + const char *arg2); GLIB_AVAILABLE_IN_ALL void g_assertion_message_cmpnum (const char *domain, const char *file, @@ -290,7 +292,7 @@ void g_assertion_message_cmpnum (const char *domain, long double arg1, const char *cmp, long double arg2, - char numtype) G_GNUC_NORETURN; + char numtype); GLIB_AVAILABLE_IN_ALL void g_assertion_message_error (const char *domain, const char *file, @@ -299,7 +301,7 @@ void g_assertion_message_error (const char *domain, const char *expr, const GError *error, GQuark error_domain, - int error_code) G_GNUC_NORETURN; + int error_code); GLIB_AVAILABLE_IN_ALL void g_test_add_vtable (const char *testpath, gsize data_size,