Re: [spice-common v3 3/7] log: Add test case for logging code

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

Awesome work with this tests.

On Wed, Dec 16, 2015 at 02:27:09PM +0100, Christophe Fergeau wrote:
> This gives us a baseline of how the SPICE/glib integration is supposed
> to behave.

Could you also include that it does support the abort/debug env var
with different domains as well?

> ---
>  tests/Makefile.am    |  19 ++-
>  tests/test-logging.c | 410 +++++++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 427 insertions(+), 2 deletions(-)
>  create mode 100644 tests/test-logging.c
> 
> diff --git a/tests/Makefile.am b/tests/Makefile.am
> index d612d44..52c0809 100644
> --- a/tests/Makefile.am
> +++ b/tests/Makefile.am
> @@ -1,7 +1,22 @@
>  NULL =
>  
> -TESTS = test_marshallers
> -check_PROGRAMS = test_marshallers
> +TESTS = test_logging test_marshallers
> +check_PROGRAMS = $(TESTS)
> +
> +test_logging_SOURCES = test-logging.c
> +test_logging_CFLAGS =			\
> +	-I$(top_srcdir)			\
> +	$(GLIB2_CFLAGS)			\
> +	$(GIO_UNIX_CFLAGS)		\
> +	$(PROTOCOL_CFLAGS)		\
> +	$(NULL)
> +test_logging_LDADD =					\
> +	$(top_builddir)/common/libspice-common.la	\
> +	$(GLIB2_LIBS)			\
> +	$(GIO_UNIX_LIBS)		\
> +	$(NULL)
> +
> +
>  test_marshallers_SOURCES =		\
>  	generated_test_marshallers.c	\
>  	generated_test_marshallers.h	\
> diff --git a/tests/test-logging.c b/tests/test-logging.c
> new file mode 100644
> index 0000000..cf05016
> --- /dev/null
> +++ b/tests/test-logging.c
> @@ -0,0 +1,410 @@
> +/*
> +   Copyright (C) 2015 Red Hat, Inc.
> +
> +   This library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   This library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with this library; if not, see <http://www.gnu.org/licenses/>.
> +*/
> +#ifdef HAVE_CONFIG_H
> +#include <config.h>
> +#endif
> +
> +#define G_LOG_DOMAIN "Spice"
> +#define SPICE_LOG_DOMAIN G_LOG_DOMAIN
> +
> +#include <glib.h>
> +
> +#include "common/log.h"
> +
> +#define OTHER_LOG_DOMAIN "Other"
> +#define LOG_OTHER_HELPER(suffix, level)                                          \
> +    static void G_PASTE(other_, suffix)(const gchar *format, ...)                \
> +    {                                                                            \
> +        va_list args;                                                            \
> +                                                                                 \
> +        va_start (args, format);                                                 \
> +        g_logv(OTHER_LOG_DOMAIN, G_PASTE(G_LOG_LEVEL_, level), format, args);    \
> +        va_end (args);                                                           \
> +    }
> +
> +/* Set of helpers to log in a different log domain than "Spice" */
> +LOG_OTHER_HELPER(debug, DEBUG)
> +LOG_OTHER_HELPER(info, INFO)
> +LOG_OTHER_HELPER(message, MESSAGE)
> +LOG_OTHER_HELPER(warning, WARNING)
> +LOG_OTHER_HELPER(critical, CRITICAL)
> +
> +/* Helper for use with g_test_log_set_fatal_handler() as uncaught
> + * warnings/criticals automatically cause test failures
> + */
> +static gboolean non_fatal_warnings_criticals(const gchar *log_domain,
> +                                             GLogLevelFlags log_level,
> +                                             const gchar *message,
> +                                             gpointer user_data)
> +{
> +    char *pattern = user_data;
> +
> +    if ((log_level = G_LOG_LEVEL_WARNING)
> +            && g_str_has_suffix(message, "_warning")) {
> +        return FALSE;
> +    }
> +    if ((log_level = G_LOG_LEVEL_CRITICAL)
> +            && g_str_has_suffix(message, "_critical")) {
> +        return FALSE;
> +    }
> +    if (pattern != NULL) {
> +        if (g_pattern_match_simple(pattern, message)) {
> +            return FALSE;
> +        }
> +    }
> +
> +    return TRUE;
> +}
> +
> +
> +/* Checks that spice_warning() aborts after changing SPICE_ABORT_LEVEL */
> +static void test_spice_abort_level(void)
> +{
> +    if (g_test_subprocess()) {
> +        /* 2 = SPICE_LOG_LEVEL_WARNING  */
> +        g_setenv("SPICE_ABORT_LEVEL", "2", TRUE);
> +        g_test_expect_message(NULL,
> +                              G_LOG_LEVEL_WARNING,
> +                              "*SPICE_ABORT_LEVEL*deprecated*");
> +        spice_debug("trigger deprecation warning");
> +        g_test_assert_expected_messages();
> +        spice_warning("spice_warning");
> +        return;
> +    }
> +    g_test_trap_subprocess(NULL, 0, 0);
> +    g_test_trap_assert_failed();
> +    g_test_trap_assert_stderr("*spice_warning*");
> +}
> +
> +/* Checks that g_warning() aborts after changing SPICE_ABORT_LEVEL */
> +static void test_spice_abort_level_g_warning(void)
> +{
> +    if (g_test_subprocess()) {
> +        /* 2 = SPICE_LOG_LEVEL_WARNING  */
> +        g_setenv("SPICE_ABORT_LEVEL", "2", TRUE);
> +        g_test_expect_message(NULL,
> +                              G_LOG_LEVEL_WARNING,
> +                              "*SPICE_ABORT_LEVEL*deprecated*");
> +        spice_debug("trigger deprecation warning");
> +        g_test_assert_expected_messages();
> +        g_warning("g_warning");
> +        return;
> +    }
> +    g_test_trap_subprocess(NULL, 0, 0);
> +    g_test_trap_assert_failed();
> +    g_test_trap_assert_stderr("*g_warning*");
> +}
> +
> +/* Checks that spice_warning() aborts after setting G_DEBUG=fatal-warnings */
> +static void test_spice_fatal_warning(void)
> +{
> +    if (g_test_subprocess()) {
> +        g_setenv("G_DEBUG", "fatal-warnings", TRUE);
> +        spice_warning("spice_warning");
> +        return;
> +    }
> +    g_test_trap_subprocess(NULL, 0, 0);
> +    g_test_trap_assert_failed();
> +    g_test_trap_assert_stderr("*spice_warning*");
> +}
> +
> +/* Checks that spice_critical() aborts by default */
> +static void test_spice_fatal_critical(void)
> +{
> +    if (g_test_subprocess()) {
> +        spice_critical("spice_critical");
> +        return;
> +    }
> +    g_test_trap_subprocess(NULL, 0, 0);
> +    g_test_trap_assert_failed();
> +    g_test_trap_assert_stderr("*spice_critical*");
> +}
> +
> +/* Checks that g_critical() does not abort by default */
> +static void test_spice_non_fatal_g_critical(void)
> +{
> +    if (g_test_subprocess()) {
> +        g_test_expect_message(G_LOG_DOMAIN,
> +                              G_LOG_LEVEL_CRITICAL,
> +                              "*g_critical");
> +        g_critical("g_critical");
> +        g_test_assert_expected_messages();
> +        return;
> +    }
> +    g_test_trap_subprocess(NULL, 0, 0);
> +    g_test_trap_assert_passed();
> +}
> +
> +/* Checks that spice_return_if_fail() aborts by default */
> +static void test_spice_fatal_return_if_fail(void)
> +{
> +    if (g_test_subprocess()) {
> +        spice_return_if_fail(FALSE);
> +        return;
> +    }
> +    g_test_trap_subprocess(NULL, 0, 0);
> +    g_test_trap_assert_failed();
> +}
> +
> +/* Checks that g_return_if_fail() does not abort by default */
> +static void test_spice_non_fatal_g_return_if_fail(void)
> +{
> +    char *pattern = g_strconcat ("*", G_STRFUNC, "*", NULL);
> +    g_test_log_set_fatal_handler(non_fatal_warnings_criticals, pattern);
> +
> +    if (g_test_subprocess()) {
> +        g_return_if_fail(FALSE);

pattern leaks here

Acked-by: Victor Toso <victortoso@xxxxxxxxxx>

thanks,
  toso

> +        return;
> +    }
> +    g_test_trap_subprocess(NULL, 0, 0);
> +    g_test_trap_assert_passed();
> +    g_free(pattern);
> +}
> +
> +/* Checks that spice_*, g_* and other_* (different log domain as g_*) all
> + * go through g_log() with the correct domain/log level. This then checks
> + * that only logs with level 'message' or higher are shown by default.
> + */
> +static void test_log_levels(void)
> +{
> +    g_test_log_set_fatal_handler(non_fatal_warnings_criticals, NULL);
> +
> +    if (g_test_subprocess()) {
> +        g_test_expect_message(SPICE_LOG_DOMAIN,
> +                              G_LOG_LEVEL_WARNING,
> +                              "*spice_warning");
> +        spice_warning("spice_warning");
> +        g_test_expect_message(SPICE_LOG_DOMAIN,
> +                              G_LOG_LEVEL_INFO,
> +                              "*spice_info");
> +        spice_info("spice_info");
> +        g_test_expect_message(SPICE_LOG_DOMAIN,
> +                              G_LOG_LEVEL_DEBUG,
> +                              "*spice_debug");
> +        spice_debug("spice_debug");
> +
> +        g_test_expect_message(G_LOG_DOMAIN,
> +                              G_LOG_LEVEL_CRITICAL,
> +                              "*g_critical");
> +        g_critical("g_critical");
> +        g_test_expect_message(G_LOG_DOMAIN,
> +                              G_LOG_LEVEL_WARNING,
> +                              "*g_warning");
> +        g_warning("g_warning");
> +        g_test_expect_message(G_LOG_DOMAIN,
> +                              G_LOG_LEVEL_MESSAGE,
> +                              "*g_message");
> +        g_message("g_message");
> +        g_test_expect_message(G_LOG_DOMAIN,
> +                              G_LOG_LEVEL_INFO,
> +                              "*g_info");
> +        g_info("g_info");
> +        g_test_expect_message(G_LOG_DOMAIN,
> +                              G_LOG_LEVEL_DEBUG,
> +                              "*g_debug");
> +        g_debug("g_debug");
> +
> +        g_test_expect_message(OTHER_LOG_DOMAIN,
> +                              G_LOG_LEVEL_CRITICAL,
> +                              "*other_critical");
> +        other_critical("other_critical");
> +        g_test_expect_message(OTHER_LOG_DOMAIN,
> +                              G_LOG_LEVEL_WARNING,
> +                              "*other_warning");
> +        other_warning("other_warning");
> +        g_test_expect_message(OTHER_LOG_DOMAIN,
> +                              G_LOG_LEVEL_MESSAGE,
> +                              "*other_message");
> +        other_message("other_message");
> +        g_test_expect_message(OTHER_LOG_DOMAIN,
> +                              G_LOG_LEVEL_INFO,
> +                              "*other_info");
> +        other_info("other_info");
> +        g_test_expect_message(OTHER_LOG_DOMAIN,
> +                              G_LOG_LEVEL_DEBUG,
> +                              "*other_debug");
> +        other_debug("other_debug");
> +
> +        g_test_assert_expected_messages();
> +
> +
> +        /* g_test_expected_message only checks whether the appropriate messages got up to g_log()
> +         * The following calls will be caught by the parent process to check what was (not) printed
> +         * to stdout/stderr
> +         */
> +        spice_warning("spice_warning");
> +        spice_info("spice_info");
> +        spice_debug("spice_debug");
> +
> +        g_critical("g_critical");
> +        g_warning("g_warning");
> +        g_message("g_message");
> +        g_info("g_info");
> +        g_debug("g_debug");
> +
> +        other_critical("other_critical");
> +        other_warning("other_warning");
> +        other_message("other_message");
> +        other_info("other_info");
> +        other_debug("other_debug");
> +
> +        return;
> +    }
> +    g_test_trap_subprocess(NULL, 0, 0);
> +    g_test_trap_assert_passed();
> +    g_test_trap_assert_stderr("*spice_warning\n*g_critical\n*g_warning\n*g_message\n*other_critical\n*other_warning\n*other_message\n");
> +}
> +
> +/* Checks that SPICE_DEBUG_LEVEL impacts spice_debug(), g_debug() but not other_debug() */
> +static void test_spice_debug_level(void)
> +{
> +    if (g_test_subprocess()) {
> +        g_setenv("SPICE_DEBUG_LEVEL", "5", TRUE);
> +        g_test_expect_message(NULL,
> +                              G_LOG_LEVEL_WARNING,
> +                              "*SPICE_DEBUG_LEVEL*deprecated*");
> +        spice_debug("trigger deprecation warning");
> +        g_test_assert_expected_messages();
> +
> +        /* g_test_expected_message only checks whether the appropriate messages got up to g_log()
> +         * The following calls will be caught by the parent process to check what was (not) printed
> +         * to stdout/stderr
> +         */
> +        spice_info("spice_info");
> +        g_debug("g_debug");
> +        spice_debug("spice_debug");
> +        other_debug("other_debug");
> +
> +        return;
> +    }
> +
> +    g_test_trap_subprocess(NULL, 0, 0);
> +    g_test_trap_assert_passed();
> +    g_test_trap_assert_stdout("*spice_info\n*g_debug\n*spice_debug\n");
> +}
> +
> +/* Checks that raising SPICE_DEBUG_LEVEL allows to only show spice_warning() and spice_critical()
> + * messages, as well as g_warning() and g_critical(), but does not impact other_message()
> + */
> +static void test_spice_debug_level_warning(void)
> +{
> +    g_test_log_set_fatal_handler(non_fatal_warnings_criticals, NULL);
> +
> +    if (g_test_subprocess()) {
> +        g_setenv("SPICE_ABORT_LEVEL", "0", TRUE);
> +        g_setenv("SPICE_DEBUG_LEVEL", "1", TRUE);
> +        g_test_expect_message(NULL,
> +                              G_LOG_LEVEL_WARNING,
> +                              "*SPICE_DEBUG_LEVEL*deprecated*");
> +        g_test_expect_message(NULL,
> +                              G_LOG_LEVEL_WARNING,
> +                              "*SPICE_ABORT_LEVEL*deprecated*");
> +        spice_debug("trigger deprecation warning");
> +        g_test_assert_expected_messages();
> +
> +        spice_info("spice_info");
> +        spice_debug("spice_debug");
> +        spice_warning("spice_warning");
> +        spice_critical("spice_critical");
> +        g_debug("g_debug");
> +        g_info("g_info");
> +        g_message("g_message");
> +        g_warning("g_warning");
> +        g_critical("g_critical");
> +        other_debug("other_debug");
> +        other_info("other_info");
> +        other_message("other_message");
> +        other_warning("other_warning");
> +        other_critical("other_critical");
> +
> +        return;
> +    }
> +
> +    g_test_trap_subprocess(NULL, 0, 0);
> +    g_test_trap_assert_passed();
> +    g_test_trap_assert_stderr("*spice_critical\n*g_critical\n*other_message\n*other_warning\n*other_critical\n");
> +}
> +
> +/* Checks that setting G_MESSAGES_DEBUG to 'Spice' impacts spice_debug() and
> + * g_debug() but not other_debug() */
> +static void test_spice_g_messages_debug(void)
> +{
> +    if (g_test_subprocess()) {
> +        g_setenv("G_MESSAGES_DEBUG", "Spice", TRUE);
> +
> +        spice_debug("spice_debug");
> +        spice_info("spice_info");
> +        g_debug("g_debug");
> +        g_info("g_info");
> +        g_message("g_message");
> +        other_debug("other_debug");
> +        other_info("other_info");
> +        other_message("other_message");
> +
> +        return;
> +    }
> +
> +    g_test_trap_subprocess(NULL, 0, 0);
> +    g_test_trap_assert_passed();
> +    g_test_trap_assert_stdout("*spice_debug\n*spice_info\n*g_debug\n*g_info\n");
> +    g_test_trap_assert_stderr("*g_message\n*other_message\n");
> +}
> +
> +/* Checks that setting G_MESSAGES_DEBUG to 'all' impacts spice_debug(),
> + * g_debug() and other_debug() */
> +static void test_spice_g_messages_debug_all(void)
> +{
> +    if (g_test_subprocess()) {
> +        g_setenv("G_MESSAGES_DEBUG", "all", TRUE);
> +
> +        spice_debug("spice_debug");
> +        spice_info("spice_info");
> +        g_debug("g_debug");
> +        g_info("g_info");
> +        g_message("g_message");
> +        other_debug("other_debug");
> +        other_info("other_info");
> +        other_message("other_message");
> +
> +        return;
> +    }
> +
> +    g_test_trap_subprocess(NULL, 0, 0);
> +    g_test_trap_assert_passed();
> +    g_test_trap_assert_stdout("*spice_debug\n*spice_info\n*g_debug\n*g_info\n*other_debug\n*other_info\n");
> +    g_test_trap_assert_stderr("*g_message\n*other_message\n");
> +}
> +
> +int main(int argc, char **argv)
> +{
> +    g_test_init(&argc, &argv, NULL);
> +
> +    g_test_add_func("/spice-common/spice-abort-level", test_spice_abort_level);
> +    g_test_add_func("/spice-common/spice-abort-level-gwarning", test_spice_abort_level_g_warning);
> +    g_test_add_func("/spice-common/spice-debug-level", test_spice_debug_level);
> +    g_test_add_func("/spice-common/spice-debug-level-warning", test_spice_debug_level_warning);
> +    g_test_add_func("/spice-common/spice-g-messages-debug", test_spice_g_messages_debug);
> +    g_test_add_func("/spice-common/spice-g-messages-debug-all", test_spice_g_messages_debug_all);
> +    g_test_add_func("/spice-common/spice-log-levels", test_log_levels);
> +    g_test_add_func("/spice-common/spice-fatal-critical", test_spice_fatal_critical);
> +    g_test_add_func("/spice-common/spice-non-fatal-gcritical", test_spice_non_fatal_g_critical);
> +    g_test_add_func("/spice-common/spice-fatal-return-if-fail", test_spice_fatal_return_if_fail);
> +    g_test_add_func("/spice-common/spice-non-fatal-greturn-if-fail", test_spice_non_fatal_g_return_if_fail);
> +    g_test_add_func("/spice-common/spice-fatal-warning", test_spice_fatal_warning);
> +
> +    return g_test_run();
> +}
> -- 
> 2.5.0
> 
> _______________________________________________
> Spice-devel mailing list
> Spice-devel@xxxxxxxxxxxxxxxxxxxxx
> http://lists.freedesktop.org/mailman/listinfo/spice-devel
_______________________________________________
Spice-devel mailing list
Spice-devel@xxxxxxxxxxxxxxxxxxxxx
http://lists.freedesktop.org/mailman/listinfo/spice-devel




[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux]     [Linux OMAP]     [Linux MIPS]     [ECOS]     [Asterisk Internet PBX]     [Linux API]     [Monitors]