diff options
author | Thomas Haller <thaller@redhat.com> | 2014-04-17 10:49:01 +0200 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2014-06-05 18:12:56 +0200 |
commit | 5a58afcec979c90e811d20afe60e20b9d0ebcc39 (patch) | |
tree | d45275c9076ed19be5016e6973e50bde09cb2480 /include/nm-test-utils.h | |
parent | 64d09e5afe45f981e8e61d7a138b5c8183fda9c4 (diff) | |
download | NetworkManager-5a58afcec979c90e811d20afe60e20b9d0ebcc39.tar.gz |
nmtst: add nmtst_is_debug() and interpret environment NMTST_DEBUG
Also enable "DEBUG" logging conditionally depending on is_debug().
Signed-off-by: Thomas Haller <thaller@redhat.com>
Diffstat (limited to 'include/nm-test-utils.h')
-rw-r--r-- | include/nm-test-utils.h | 130 |
1 files changed, 129 insertions, 1 deletions
diff --git a/include/nm-test-utils.h b/include/nm-test-utils.h index c55a467193..467e61ac54 100644 --- a/include/nm-test-utils.h +++ b/include/nm-test-utils.h @@ -26,6 +26,7 @@ #include <arpa/inet.h> #include <glib.h> #include <glib-object.h> +#include <string.h> struct __nmtst_internal @@ -33,6 +34,7 @@ struct __nmtst_internal GRand *rand0; guint32 rand_seed; GRand *rand; + gboolean is_debug; }; extern struct __nmtst_internal __nmtst_internal; @@ -47,14 +49,68 @@ nmtst_initialized (void) return !!__nmtst_internal.rand0; } +/* split the string inplace at specific delimiters, allowing escaping with '\\'. + * Returns a zero terminated array of pointers into @str. + * + * The caller must g_free() the returned argv array. + **/ +inline static char ** +nmtst_str_split (char *str, const char *delimiters) +{ + const char *d; + GArray *result = g_array_sized_new (TRUE, FALSE, sizeof (char *), 3); + + g_assert (str); + g_assert (delimiters && !strchr (delimiters, '\\')); + + while (*str) { + gsize i = 0, j = 0; + + while (TRUE) { + char c = str[i]; + + if (c == '\0') { + str[j++] = 0; + break; + } else if (c == '\\') { + str[j++] = str[++i]; + if (!str[i]) + break; + } else { + for (d = delimiters; *d; d++) { + if (c == *d) { + str[j++] = 0; + i++; + goto BREAK_INNER_LOOPS; + } + } + str[j++] = c; + } + i++; + } + +BREAK_INNER_LOOPS: + g_array_append_val (result, str); + str = &str[i]; + } + + return (char **) g_array_free (result, FALSE); +} + inline static void nmtst_init (int *argc, char ***argv, const char *log_level, const char *log_domains) { + const char *nmtst_debug; + gboolean is_debug = FALSE; + char *c_log_level = NULL, *c_log_domains = NULL; + GArray *debug_messages = g_array_new (TRUE, FALSE, sizeof (char *)); + int i; + g_assert (!nmtst_initialized ()); g_assert (!((!!argc) ^ (!!argv))); - if (argc) { + if (argc && !g_test_initialized ()) { /* g_test_init() is a variadic function, so we cannot pass it * (variadic) arguments. If you need to pass additional parameters, * call nmtst_init() with argc==NULL and call g_test_init() yourself. */ @@ -65,8 +121,65 @@ nmtst_init (int *argc, char ***argv, const char *log_level, const char *log_doma g_type_init (); #endif + is_debug = g_test_verbose (); + + nmtst_debug = g_getenv ("NMTST_DEBUG"); + if (nmtst_debug) { + char **d_argv, **i_argv, *nmtst_debug_copy; + + /* By setting then NMTST_DEBUG variable, @is_debug is set automatically. + * This can be reverted with no-debug (on command line or environment variable). */ + is_debug = TRUE; + + nmtst_debug_copy = g_strdup (nmtst_debug); + d_argv = nmtst_str_split (nmtst_debug_copy, ",; \t\r\n"); + + for (i_argv = d_argv; *i_argv; i_argv++) { + const char *debug = *i_argv; + + if (!g_ascii_strcasecmp (debug, "debug")) + is_debug = TRUE; + else if (!g_ascii_strcasecmp (debug, "no-debug")) { + /* when specifying the NMTST_DEBUG variable, we set is_debug to true. Use this flag to disable this + * (e.g. for only setting the log-level, but not is_debug). */ + is_debug = FALSE; + } else if (!g_ascii_strncasecmp (debug, "log-level=", strlen ("log-level="))) { + g_free (c_log_level); + log_level = c_log_level = g_strdup (&debug[strlen ("log-level=")]); + } else if (!g_ascii_strncasecmp (debug, "log-domains=", strlen ("log-domains="))) { + g_free (c_log_domains); + log_domains = c_log_domains = g_strdup (&debug[strlen ("log-domains=")]); + } else { + char *msg = g_strdup_printf (">>> nmtst: ignore unrecognized NMTST_DEBUG option \"%s\"", debug); + + g_array_append_val (debug_messages, msg); + } + } + + g_free (d_argv); + g_free (nmtst_debug_copy); + } + + if (argv && *argv) { + char **a = *argv; + + for (; *a; a++) { + if (!g_ascii_strcasecmp (*a, "--debug")) + is_debug = TRUE; + else if (!g_ascii_strcasecmp (*a, "--no-debug")) + is_debug = FALSE; + } + } + + __nmtst_internal.is_debug = is_debug; __nmtst_internal.rand0 = g_rand_new_with_seed (0); + 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 */ + log_level = is_debug ? "DEBUG" : "WARN"; + } + if (log_level || log_domains) { gboolean success = FALSE; #ifdef NM_LOGGING_H @@ -74,6 +187,21 @@ nmtst_init (int *argc, char ***argv, const char *log_level, const char *log_doma #endif g_assert (success); } + + /* Delay messages until we setup logging. */ + for (i = 0; i < debug_messages->len; i++) + g_message ("%s", g_array_index (debug_messages, const char *, i)); + + g_strfreev ((char **) g_array_free (debug_messages, FALSE)); + g_free (c_log_level); + g_free (c_log_domains); +} + +inline static gboolean +nmtst_is_debug (void) +{ + g_assert (nmtst_initialized ()); + return __nmtst_internal.is_debug; } inline static GRand * |