mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-11-10 03:16:17 +01:00
Bug 579050 Allow making selected critical and warning messages non-fatal
Implement g_test_log_set_fatal_handler which is a function similar to g_log_set_default_handler but for use in unit tests where certain errors have to be ignored because it is not possible to fix or avoid them otherwise. A unit test is added.
This commit is contained in:
parent
4b1217b7e0
commit
278ac0a45d
@ -1332,6 +1332,9 @@ g_thread_pool_set_sort_function
|
||||
#endif
|
||||
|
||||
#if IN_HEADER(__G_TEST_UTILS_H__)
|
||||
#if IN_FILE(__G_MESSAGES_C__)
|
||||
g_test_log_set_fatal_handler
|
||||
#endif
|
||||
#if IN_FILE(__G_TEST_UTILS_C__)
|
||||
g_assertion_message G_GNUC_NORETURN
|
||||
g_assertion_message_cmpnum G_GNUC_NORETURN
|
||||
|
@ -86,6 +86,8 @@ static GPrivate *g_log_depth = NULL;
|
||||
static GLogLevelFlags g_log_msg_prefix = G_LOG_LEVEL_ERROR | G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_DEBUG;
|
||||
static GLogFunc default_log_func = g_log_default_handler;
|
||||
static gpointer default_log_data = NULL;
|
||||
static GTestLogFatalFunc fatal_log_func = NULL;
|
||||
static gpointer fatal_log_data;
|
||||
|
||||
/* --- functions --- */
|
||||
#ifdef G_OS_WIN32
|
||||
@ -346,6 +348,39 @@ g_log_set_default_handler (GLogFunc log_func,
|
||||
return old_log_func;
|
||||
}
|
||||
|
||||
/**
|
||||
* g_test_log_set_fatal_handler:
|
||||
* @log_func: the log handler function.
|
||||
* @user_data: data passed to the log handler.
|
||||
*
|
||||
* Installs a non-error fatal log handler which can be
|
||||
* used to decide whether log messages which are counted
|
||||
* as fatal abort the program.
|
||||
*
|
||||
* The use case here is that you are running a test case
|
||||
* that depends on particular libraries or circumstances
|
||||
* and cannot prevent certain known critical or warning
|
||||
* messages. So you install a handler that compares the
|
||||
* domain and message to precisely not abort in such a case.
|
||||
*
|
||||
* Note that the handler is reset at the beginning of
|
||||
* any test case, so you have to set it inside each test
|
||||
* function which needs the special behavior.
|
||||
*
|
||||
* This handler has no effect on g_error messages.
|
||||
*
|
||||
* Since: 2.22
|
||||
**/
|
||||
void
|
||||
g_test_log_set_fatal_handler (GTestLogFatalFunc log_func,
|
||||
gpointer user_data)
|
||||
{
|
||||
g_mutex_lock (g_messages_lock);
|
||||
fatal_log_func = log_func;
|
||||
fatal_log_data = user_data;
|
||||
g_mutex_unlock (g_messages_lock);
|
||||
}
|
||||
|
||||
void
|
||||
g_log_remove_handler (const gchar *log_domain,
|
||||
guint handler_id)
|
||||
@ -456,6 +491,7 @@ g_logv (const gchar *log_domain,
|
||||
}
|
||||
}
|
||||
|
||||
gboolean masquerade_fatal = FALSE;
|
||||
if (test_level & G_LOG_FLAG_RECURSION)
|
||||
{
|
||||
/* we use a stack buffer of fixed size, since we're likely
|
||||
@ -482,11 +518,18 @@ g_logv (const gchar *log_domain,
|
||||
|
||||
log_func (log_domain, test_level, msg, data);
|
||||
|
||||
if ((test_level & G_LOG_FLAG_FATAL)
|
||||
&& !(test_level & G_LOG_LEVEL_ERROR))
|
||||
{
|
||||
masquerade_fatal = fatal_log_func
|
||||
&& !fatal_log_func (log_domain, test_level, msg, data);
|
||||
}
|
||||
|
||||
g_free (msg);
|
||||
}
|
||||
|
||||
if (test_level & G_LOG_FLAG_FATAL)
|
||||
{
|
||||
if ((test_level & G_LOG_FLAG_FATAL) && !masquerade_fatal)
|
||||
{
|
||||
#ifdef G_OS_WIN32
|
||||
gchar *locale_msg = g_locale_from_utf8 (fatal_msg_buf, -1, NULL, NULL, NULL);
|
||||
|
||||
|
@ -1122,6 +1122,7 @@ test_case_run (GTestCase *tc)
|
||||
void *fixture;
|
||||
g_test_log (G_TEST_LOG_START_CASE, test_run_name, NULL, 0, NULL);
|
||||
test_run_forks = 0;
|
||||
g_test_log_set_fatal_handler (NULL, NULL);
|
||||
g_timer_start (test_run_timer);
|
||||
fixture = tc->fixture_size ? g_malloc0 (tc->fixture_size) : tc->test_data;
|
||||
test_run_seed (test_run_seedstr);
|
||||
|
@ -262,6 +262,27 @@ void g_test_log_buffer_push (GTestLogBuffer *tbuffer,
|
||||
GTestLogMsg* g_test_log_buffer_pop (GTestLogBuffer *tbuffer);
|
||||
void g_test_log_msg_free (GTestLogMsg *tmsg);
|
||||
|
||||
/**
|
||||
* GTestLogFatalFunc:
|
||||
* @log_domain: the log domain of the message
|
||||
* @log_level: the log level of the message (including the fatal and recursion flags)
|
||||
* @message: the message to process
|
||||
* @user_data: user data, set in g_test_log_set_fatal_handler()
|
||||
*
|
||||
* Specifies the prototype of fatal log handler functions.
|
||||
*
|
||||
* Return value: %TRUE if the program should abort, %FALSE otherwise
|
||||
*
|
||||
* Since: 2.22
|
||||
*/
|
||||
typedef gboolean (*GTestLogFatalFunc) (const gchar *log_domain,
|
||||
GLogLevelFlags log_level,
|
||||
const gchar *message,
|
||||
gpointer user_data);
|
||||
void
|
||||
g_test_log_set_fatal_handler (GTestLogFatalFunc log_func,
|
||||
gpointer user_data);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __G_TEST_UTILS_H__ */
|
||||
|
@ -191,6 +191,32 @@ test_random_conversions (void)
|
||||
g_free (str);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fatal_handler (const gchar *log_domain,
|
||||
GLogLevelFlags log_level,
|
||||
const gchar *message,
|
||||
gpointer user_data)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
test_log_handler (void)
|
||||
{
|
||||
g_test_log_set_fatal_handler (fatal_handler, NULL);
|
||||
g_str_has_prefix (NULL, "file://");
|
||||
g_critical ("Test passing");
|
||||
|
||||
g_test_log_set_fatal_handler (NULL, NULL);
|
||||
if (g_test_trap_fork (0, 0))
|
||||
g_error ("Test failing");
|
||||
g_test_trap_assert_failed ();
|
||||
|
||||
if (g_test_trap_fork (0, 0))
|
||||
g_str_has_prefix (NULL, "file://");
|
||||
g_test_trap_assert_failed ();
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc,
|
||||
char *argv[])
|
||||
@ -209,6 +235,7 @@ main (int argc,
|
||||
g_test_add_func ("/forking/patterns", test_fork_patterns);
|
||||
if (g_test_slow())
|
||||
g_test_add_func ("/forking/timeout", test_fork_timeout);
|
||||
g_test_add_func ("/misc/log-handler", test_log_handler);
|
||||
|
||||
return g_test_run();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user