Merge branch 'meson-use-tap-protocol' into 'main'

meson: Use 'tap' test protocol and support TAP 13/14

See merge request GNOME/glib!3140
This commit is contained in:
Philip Withnall 2023-01-20 13:45:12 +00:00
commit e6fbd2afa6
20 changed files with 1838 additions and 155 deletions

View File

@ -125,6 +125,8 @@ main (gint argc, gchar *argv[])
GMainLoop *loop; GMainLoop *loop;
guint id; guint id;
g_log_writer_default_set_use_stderr (TRUE);
loop = g_main_loop_new (NULL, FALSE); loop = g_main_loop_new (NULL, FALSE);
id = g_bus_own_name (G_BUS_TYPE_SESSION, id = g_bus_own_name (G_BUS_TYPE_SESSION,

View File

@ -98,6 +98,8 @@ main (gint argc, gchar *argv[])
{ {
guint id; guint id;
g_log_writer_default_set_use_stderr (TRUE);
loop = g_main_loop_new (NULL, FALSE); loop = g_main_loop_new (NULL, FALSE);
introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, NULL); introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, NULL);
g_assert (introspection_data != NULL); g_assert (introspection_data != NULL);

View File

@ -1686,6 +1686,8 @@ main (int argc, char **argv)
{ {
g_setenv ("LC_ALL", "C", TRUE); g_setenv ("LC_ALL", "C", TRUE);
g_log_writer_default_set_use_stderr (TRUE);
g_test_init (&argc, &argv, NULL); g_test_init (&argc, &argv, NULL);
if (!g_test_subprocess ()) if (!g_test_subprocess ())

View File

@ -843,6 +843,8 @@ main (int argc, char *argv[])
{ {
guint owner_id; guint owner_id;
g_log_writer_default_set_use_stderr (TRUE);
introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, NULL); introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, NULL);
properties = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify)g_variant_unref); properties = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify)g_variant_unref);
g_hash_table_insert (properties, g_strdup ("y"), g_variant_ref_sink (g_variant_new_byte (1))); g_hash_table_insert (properties, g_strdup ("y"), g_variant_ref_sink (g_variant_new_byte (1)));

View File

@ -798,7 +798,9 @@ test_l10n (void)
str = NULL; str = NULL;
} }
else else
g_printerr ("warning: translation is not working... skipping test. "); {
g_test_skip ("translation is not working");
}
g_setenv ("LC_MESSAGES", locale, TRUE); g_setenv ("LC_MESSAGES", locale, TRUE);
setlocale (LC_MESSAGES, locale); setlocale (LC_MESSAGES, locale);
@ -843,7 +845,7 @@ test_l10n_context (void)
if (g_str_equal (dgettext ("test", "\"Unnamed\""), "\"Unbenannt\"")) if (g_str_equal (dgettext ("test", "\"Unnamed\""), "\"Unbenannt\""))
settings_assert_cmpstr (settings, "backspace", ==, "Löschen"); settings_assert_cmpstr (settings, "backspace", ==, "Löschen");
else else
g_printerr ("warning: translation is not working... skipping test. "); g_test_skip ("translation is not working");
g_setenv ("LC_MESSAGES", locale, TRUE); g_setenv ("LC_MESSAGES", locale, TRUE);
setlocale (LC_MESSAGES, locale); setlocale (LC_MESSAGES, locale);
@ -3017,6 +3019,8 @@ main (int argc, char *argv[])
if (!g_test_subprocess ()) if (!g_test_subprocess ())
{ {
GError *local_error = NULL; GError *local_error = NULL;
char *subprocess_stdout = NULL;
/* A GVDB header is 6 guint32s, and requires a magic number in the first /* A GVDB header is 6 guint32s, and requires a magic number in the first
* two guint32s. A set of zero bytes of a greater length is considered * two guint32s. A set of zero bytes of a greater length is considered
* corrupt. */ * corrupt. */
@ -3056,14 +3060,20 @@ main (int argc, char *argv[])
"--schema-file=org.gtk.test.enums.xml " "--schema-file=org.gtk.test.enums.xml "
"--schema-file=org.gtk.test.gschema.xml " "--schema-file=org.gtk.test.gschema.xml "
"--override-file=org.gtk.test.gschema.override", "--override-file=org.gtk.test.gschema.override",
NULL, NULL, &result, NULL)); &subprocess_stdout, NULL, &result, NULL));
if (subprocess_stdout && *g_strstrip (subprocess_stdout) != '\0')
g_test_message ("%s", subprocess_stdout);
g_clear_pointer (&subprocess_stdout, g_free);
g_assert_cmpint (result, ==, 0); g_assert_cmpint (result, ==, 0);
g_remove ("schema-source/gschemas.compiled"); g_remove ("schema-source/gschemas.compiled");
g_mkdir ("schema-source", 0777); g_mkdir ("schema-source", 0777);
g_assert_true (g_spawn_command_line_sync (GLIB_COMPILE_SCHEMAS " --targetdir=schema-source " g_assert_true (g_spawn_command_line_sync (GLIB_COMPILE_SCHEMAS " --targetdir=schema-source "
"--schema-file=" SRCDIR "/org.gtk.schemasourcecheck.gschema.xml", "--schema-file=" SRCDIR "/org.gtk.schemasourcecheck.gschema.xml",
NULL, NULL, &result, NULL)); &subprocess_stdout, NULL, &result, NULL));
if (subprocess_stdout && *g_strstrip (subprocess_stdout) != '\0')
g_test_message ("%s", subprocess_stdout);
g_clear_pointer (&subprocess_stdout, g_free);
g_assert_cmpint (result, ==, 0); g_assert_cmpint (result, ==, 0);
g_remove ("schema-source-corrupt/gschemas.compiled"); g_remove ("schema-source-corrupt/gschemas.compiled");

View File

@ -144,14 +144,16 @@ gio_tests = {
if have_cxx if have_cxx
gio_tests += { gio_tests += {
'cxx' : { 'cxx' : {
'protocol': 'exitcode',
'source' : ['cxx.cpp'], 'source' : ['cxx.cpp'],
'suite': ['C++'], 'suite': ['cpp'],
}, },
} }
foreach std, arg: cxx_standards foreach std, arg: cxx_standards
gio_tests += { gio_tests += {
'cxx-@0@'.format(std) : { 'cxx-@0@'.format(std) : {
'protocol': 'exitcode',
'source' : ['cxx.cpp'], 'source' : ['cxx.cpp'],
'suite' : ['cpp'], 'suite' : ['cpp'],
'cpp_args' : [arg], 'cpp_args' : [arg],
@ -1035,6 +1037,7 @@ foreach test_name, extra_args : gio_tests
endif endif
test(test_name, exe, test(test_name, exe,
protocol : extra_args.get('protocol', test_protocol),
env : local_test_env, env : local_test_env,
timeout : timeout, timeout : timeout,
suite : suite, suite : suite,
@ -1059,6 +1062,7 @@ foreach test_name, extra_args : python_tests
test( test(
test_name, test_name,
python, python,
protocol : extra_args.get('protocol', test_protocol),
depends: depends, depends: depends,
args: ['-B', files(test_name)], args: ['-B', files(test_name)],
env: test_env, env: test_env,

View File

@ -501,12 +501,14 @@ struct _GLogHandler
GLogHandler *next; GLogHandler *next;
}; };
static void g_default_print_func (const gchar *string);
static void g_default_printerr_func (const gchar *string);
/* --- variables --- */ /* --- variables --- */
static GMutex g_messages_lock; static GMutex g_messages_lock;
static GLogDomain *g_log_domains = NULL; static GLogDomain *g_log_domains = NULL;
static GPrintFunc glib_print_func = NULL; static GPrintFunc glib_print_func = g_default_print_func;
static GPrintFunc glib_printerr_func = NULL; static GPrintFunc glib_printerr_func = g_default_printerr_func;
static GPrivate g_log_depth; static GPrivate g_log_depth;
static GPrivate g_log_structured_depth; static GPrivate g_log_structured_depth;
static GLogFunc default_log_func = g_log_default_handler; static GLogFunc default_log_func = g_log_default_handler;
@ -525,6 +527,7 @@ static inline const char * format_string (const char *format,
va_list args, va_list args,
char **out_allocated_string) char **out_allocated_string)
G_GNUC_PRINTF (1, 0); G_GNUC_PRINTF (1, 0);
static inline FILE * log_level_to_file (GLogLevelFlags log_level);
static void static void
_g_log_abort (gboolean breakpoint) _g_log_abort (gboolean breakpoint)
@ -1206,8 +1209,6 @@ mklevel_prefix (gchar level_prefix[STRING_BUFFER_SIZE],
GLogLevelFlags log_level, GLogLevelFlags log_level,
gboolean use_color) gboolean use_color)
{ {
gboolean to_stdout = !gmessages_use_stderr;
/* we may not call _any_ GLib functions here */ /* we may not call _any_ GLib functions here */
strcpy (level_prefix, log_level_to_color (log_level, use_color)); strcpy (level_prefix, log_level_to_color (log_level, use_color));
@ -1216,19 +1217,15 @@ mklevel_prefix (gchar level_prefix[STRING_BUFFER_SIZE],
{ {
case G_LOG_LEVEL_ERROR: case G_LOG_LEVEL_ERROR:
strcat (level_prefix, "ERROR"); strcat (level_prefix, "ERROR");
to_stdout = FALSE;
break; break;
case G_LOG_LEVEL_CRITICAL: case G_LOG_LEVEL_CRITICAL:
strcat (level_prefix, "CRITICAL"); strcat (level_prefix, "CRITICAL");
to_stdout = FALSE;
break; break;
case G_LOG_LEVEL_WARNING: case G_LOG_LEVEL_WARNING:
strcat (level_prefix, "WARNING"); strcat (level_prefix, "WARNING");
to_stdout = FALSE;
break; break;
case G_LOG_LEVEL_MESSAGE: case G_LOG_LEVEL_MESSAGE:
strcat (level_prefix, "Message"); strcat (level_prefix, "Message");
to_stdout = FALSE;
break; break;
case G_LOG_LEVEL_INFO: case G_LOG_LEVEL_INFO:
strcat (level_prefix, "INFO"); strcat (level_prefix, "INFO");
@ -1258,7 +1255,7 @@ mklevel_prefix (gchar level_prefix[STRING_BUFFER_SIZE],
if ((log_level & G_LOG_FLAG_FATAL) != 0 && !g_test_initialized ()) if ((log_level & G_LOG_FLAG_FATAL) != 0 && !g_test_initialized ())
win32_keep_fatal_message = TRUE; win32_keep_fatal_message = TRUE;
#endif #endif
return to_stdout ? stdout : stderr; return log_level_to_file (log_level);
} }
typedef struct { typedef struct {
@ -1487,7 +1484,7 @@ log_level_to_priority (GLogLevelFlags log_level)
return "5"; return "5";
} }
static FILE * static inline FILE *
log_level_to_file (GLogLevelFlags log_level) log_level_to_file (GLogLevelFlags log_level)
{ {
if (gmessages_use_stderr) if (gmessages_use_stderr)
@ -3289,9 +3286,11 @@ g_log_default_handler (const gchar *log_domain,
/** /**
* g_set_print_handler: * g_set_print_handler:
* @func: the new print handler * @func: (nullable): the new print handler or %NULL to
* reset to the default
* *
* Sets the print handler. * Sets the print handler to @func, or resets it to the
* default GLib handler if %NULL.
* *
* Any messages passed to g_print() will be output via * Any messages passed to g_print() will be output via
* the new handler. The default handler simply outputs * the new handler. The default handler simply outputs
@ -3299,7 +3298,14 @@ g_log_default_handler (const gchar *log_domain,
* you can redirect the output, to a GTK+ widget or a * you can redirect the output, to a GTK+ widget or a
* log file for example. * log file for example.
* *
* Returns: the old print handler * Since 2.76 this functions always returns a valid
* #GPrintFunc, and never returns %NULL. If no custom
* print handler was set, it will return the GLib
* default print handler and that can be re-used to
* decorate its output and/or to write to stderr
* in all platforms. Before GLib 2.76, this was %NULL.
*
* Returns: (not nullable): the old print handler
*/ */
GPrintFunc GPrintFunc
g_set_print_handler (GPrintFunc func) g_set_print_handler (GPrintFunc func)
@ -3308,7 +3314,7 @@ g_set_print_handler (GPrintFunc func)
g_mutex_lock (&g_messages_lock); g_mutex_lock (&g_messages_lock);
old_print_func = glib_print_func; old_print_func = glib_print_func;
glib_print_func = func; glib_print_func = func ? func : g_default_print_func;
g_mutex_unlock (&g_messages_lock); g_mutex_unlock (&g_messages_lock);
return old_print_func; return old_print_func;
@ -3365,6 +3371,18 @@ format_string (const char *format,
} }
} }
static void
g_default_print_func (const gchar *string)
{
print_string (stdout, string);
}
static void
g_default_printerr_func (const gchar *string)
{
print_string (stderr, string);
}
/** /**
* g_print: * g_print:
* @format: the message format. See the printf() documentation * @format: the message format. See the printf() documentation
@ -3400,19 +3418,17 @@ g_print (const gchar *format,
local_glib_print_func = glib_print_func; local_glib_print_func = glib_print_func;
g_mutex_unlock (&g_messages_lock); g_mutex_unlock (&g_messages_lock);
if (local_glib_print_func) local_glib_print_func (string);
local_glib_print_func (string);
else
print_string (stdout, string);
g_free (free_me); g_free (free_me);
} }
/** /**
* g_set_printerr_handler: * g_set_printerr_handler:
* @func: the new error message handler * @func: (nullable): he new error message handler or %NULL
* to reset to the default
* *
* Sets the handler for printing error messages. * Sets the handler for printing error messages to @func,
* or resets it to the default GLib handler if %NULL.
* *
* Any messages passed to g_printerr() will be output via * Any messages passed to g_printerr() will be output via
* the new handler. The default handler simply outputs the * the new handler. The default handler simply outputs the
@ -3420,7 +3436,14 @@ g_print (const gchar *format,
* redirect the output, to a GTK+ widget or a log file for * redirect the output, to a GTK+ widget or a log file for
* example. * example.
* *
* Returns: the old error message handler * Since 2.76 this functions always returns a valid
* #GPrintFunc, and never returns %NULL. If no custom error
* print handler was set, it will return the GLib default
* error print handler and that can be re-used to decorate
* its output and/or to write to stderr in all platforms.
* Before GLib 2.76, this was %NULL.
*
* Returns: (not nullable): the old error message handler
*/ */
GPrintFunc GPrintFunc
g_set_printerr_handler (GPrintFunc func) g_set_printerr_handler (GPrintFunc func)
@ -3429,7 +3452,7 @@ g_set_printerr_handler (GPrintFunc func)
g_mutex_lock (&g_messages_lock); g_mutex_lock (&g_messages_lock);
old_printerr_func = glib_printerr_func; old_printerr_func = glib_printerr_func;
glib_printerr_func = func; glib_printerr_func = func ? func : g_default_printerr_func;
g_mutex_unlock (&g_messages_lock); g_mutex_unlock (&g_messages_lock);
return old_printerr_func; return old_printerr_func;
@ -3468,11 +3491,7 @@ g_printerr (const gchar *format,
local_glib_printerr_func = glib_printerr_func; local_glib_printerr_func = glib_printerr_func;
g_mutex_unlock (&g_messages_lock); g_mutex_unlock (&g_messages_lock);
if (local_glib_printerr_func) local_glib_printerr_func (string);
local_glib_printerr_func (string);
else
print_string (stderr, string);
g_free (free_me); g_free (free_me);
} }

View File

@ -58,6 +58,9 @@
#include "glib-private.h" #include "glib-private.h"
#include "gutilsprivate.h" #include "gutilsprivate.h"
/* FIXME: Remove '#' prefix when we'll depend on a meson version supporting TAP 14
* See https://gitlab.gnome.org/GNOME/glib/-/issues/2885 */
#define TAP_SUBTEST_PREFIX "# " /* a 4-space indented line */
/** /**
* SECTION:testing * SECTION:testing
@ -845,7 +848,10 @@ static void gtest_default_log_handler (const gchar *log_domain,
GLogLevelFlags log_level, GLogLevelFlags log_level,
const gchar *message, const gchar *message,
gpointer unused_data); gpointer unused_data);
static void g_test_tap_print (unsigned subtest_level,
gboolean commented,
const char *format,
...) G_GNUC_PRINTF (3, 4);
static const char * const g_test_result_names[] = { static const char * const g_test_result_names[] = {
"OK", "OK",
@ -901,6 +907,7 @@ static const char *test_built_files_dir; /* points into test_argv0_dirnam
static char *test_initial_cwd = NULL; static char *test_initial_cwd = NULL;
static gboolean test_in_forked_child = FALSE; static gboolean test_in_forked_child = FALSE;
static gboolean test_in_subprocess = FALSE; static gboolean test_in_subprocess = FALSE;
static gboolean test_is_subtest = FALSE;
static GTestConfig mutable_test_config_vars = { static GTestConfig mutable_test_config_vars = {
FALSE, /* test_initialized */ FALSE, /* test_initialized */
TRUE, /* test_quick */ TRUE, /* test_quick */
@ -911,8 +918,90 @@ static GTestConfig mutable_test_config_vars = {
}; };
const GTestConfig * const g_test_config_vars = &mutable_test_config_vars; const GTestConfig * const g_test_config_vars = &mutable_test_config_vars;
static gboolean no_g_set_prgname = FALSE; static gboolean no_g_set_prgname = FALSE;
static GPrintFunc g_default_print_func = NULL;
/* --- functions --- */ /* --- functions --- */
static inline gboolean
is_subtest (void)
{
return test_is_subtest || test_in_forked_child || test_in_subprocess;
}
static void
g_test_print_handler_full (const gchar *string,
gboolean use_tap_format,
gboolean is_tap_comment,
unsigned subtest_level)
{
g_assert (string != NULL);
if (G_LIKELY (use_tap_format) && strchr (string, '\n') != NULL)
{
static gboolean last_had_final_newline = TRUE;
GString *output = g_string_new_len (NULL, strlen (string) + 2);
const char *line = string;
do
{
const char *next = strchr (line, '\n');
if (last_had_final_newline && (next || *line != '\0'))
{
for (unsigned l = 0; l < subtest_level; ++l)
g_string_append (output, TAP_SUBTEST_PREFIX);
if G_LIKELY (is_tap_comment)
g_string_append (output, "# ");
}
if (next)
{
next += 1; /* Include the newline */
g_string_append_len (output, line, next - line);
}
else
{
g_string_append (output, line);
last_had_final_newline = (*line == '\0');
}
line = next;
}
while (line != NULL);
g_default_print_func (output->str);
g_string_free (g_steal_pointer (&output), TRUE);
}
else
{
g_default_print_func (string);
}
}
static void
g_test_print_handler (const gchar *string)
{
g_test_print_handler_full (string, test_tap_log, TRUE, is_subtest () ? 1 : 0);
}
static void
g_test_tap_print (unsigned subtest_level,
gboolean commented,
const char *format,
...)
{
va_list args;
char *string;
va_start (args, format);
string = g_strdup_vprintf (format, args);
va_end (args);
g_test_print_handler_full (string, TRUE, commented, subtest_level);
g_free (string);
}
const char* const char*
g_test_log_type_name (GTestLogType log_type) g_test_log_type_name (GTestLogType log_type)
{ {
@ -949,6 +1038,7 @@ g_test_log_send (guint n_bytes,
{ {
GTestLogBuffer *lbuffer = g_test_log_buffer_new (); GTestLogBuffer *lbuffer = g_test_log_buffer_new ();
GTestLogMsg *msg; GTestLogMsg *msg;
GString *output;
guint ui; guint ui;
g_test_log_buffer_push (lbuffer, n_bytes, buffer); g_test_log_buffer_push (lbuffer, n_bytes, buffer);
msg = g_test_log_buffer_pop (lbuffer); msg = g_test_log_buffer_pop (lbuffer);
@ -956,22 +1046,25 @@ g_test_log_send (guint n_bytes,
g_warn_if_fail (lbuffer->data->len == 0); g_warn_if_fail (lbuffer->data->len == 0);
g_test_log_buffer_free (lbuffer); g_test_log_buffer_free (lbuffer);
/* print message */ /* print message */
g_printerr ("{*LOG(%s)", g_test_log_type_name (msg->log_type)); output = g_string_new (NULL);
g_string_printf (output, "{*LOG(%s)", g_test_log_type_name (msg->log_type));
for (ui = 0; ui < msg->n_strings; ui++) for (ui = 0; ui < msg->n_strings; ui++)
g_printerr (":{%s}", msg->strings[ui]); g_string_append_printf (output, ":{%s}", msg->strings[ui]);
if (msg->n_nums) if (msg->n_nums)
{ {
g_printerr (":("); g_string_append (output, ":(");
for (ui = 0; ui < msg->n_nums; ui++) for (ui = 0; ui < msg->n_nums; ui++)
{ {
if ((long double) (long) msg->nums[ui] == msg->nums[ui]) if ((long double) (long) msg->nums[ui] == msg->nums[ui])
g_printerr ("%s%ld", ui ? ";" : "", (long) msg->nums[ui]); g_string_append_printf (output, "%s%ld", ui ? ";" : "", (long) msg->nums[ui]);
else else
g_printerr ("%s%.16g", ui ? ";" : "", (double) msg->nums[ui]); g_string_append_printf (output, "%s%.16g", ui ? ";" : "", (double) msg->nums[ui]);
} }
g_printerr (")"); g_string_append_c (output, ')');
} }
g_printerr (":LOG*}\n"); g_string_append (output, ":LOG*}");
g_printerr ("%s\n", output->str);
g_string_free (output, TRUE);
g_test_log_msg_free (msg); g_test_log_msg_free (msg);
} }
} }
@ -989,14 +1082,38 @@ g_test_log (GTestLogType lbit,
gchar *astrings[3] = { NULL, NULL, NULL }; gchar *astrings[3] = { NULL, NULL, NULL };
guint8 *dbuffer; guint8 *dbuffer;
guint32 dbufferlen; guint32 dbufferlen;
unsigned subtest_level;
if (g_once_init_enter (&g_default_print_func))
{
g_once_init_leave (&g_default_print_func,
g_set_print_handler (g_test_print_handler));
g_assert_nonnull (g_default_print_func);
}
subtest_level = is_subtest () ? 1 : 0;
switch (lbit) switch (lbit)
{ {
case G_TEST_LOG_START_BINARY: case G_TEST_LOG_START_BINARY:
if (test_tap_log) if (test_tap_log)
g_print ("# random seed: %s\n", string2); {
if (!is_subtest ())
{
g_test_tap_print (0, FALSE, "TAP version 13\n");
}
else
{
g_test_tap_print (subtest_level > 0 ? subtest_level - 1 : 0, TRUE,
"Subtest: %s\n", test_argv0);
}
g_print ("random seed: %s\n", string2);
}
else if (g_test_verbose ()) else if (g_test_verbose ())
g_print ("GTest: random seed: %s\n", string2); {
g_print ("GTest: random seed: %s\n", string2);
}
break; break;
case G_TEST_LOG_START_SUITE: case G_TEST_LOG_START_SUITE:
if (test_tap_log) if (test_tap_log)
@ -1004,9 +1121,9 @@ g_test_log (GTestLogType lbit,
/* We only print the TAP "plan" (1..n) ahead of time if we did /* We only print the TAP "plan" (1..n) ahead of time if we did
* not use the -p option to select specific tests to be run. */ * not use the -p option to select specific tests to be run. */
if (string1[0] != 0) if (string1[0] != 0)
g_print ("# Start of %s tests\n", string1); g_print ("Start of %s tests\n", string1);
else if (test_paths == NULL) else if (test_paths == NULL)
g_print ("1..%d\n", test_count); g_test_tap_print (subtest_level, FALSE, "1..%d\n", test_count);
} }
break; break;
case G_TEST_LOG_STOP_SUITE: case G_TEST_LOG_STOP_SUITE:
@ -1016,9 +1133,9 @@ g_test_log (GTestLogType lbit,
* we were using -p, we need to print how many tests we ran at * we were using -p, we need to print how many tests we ran at
* the end instead. */ * the end instead. */
if (string1[0] != 0) if (string1[0] != 0)
g_print ("# End of %s tests\n", string1); g_print ("End of %s tests\n", string1);
else if (test_paths != NULL) else if (test_paths != NULL)
g_print ("1..%d\n", test_run_count); g_test_tap_print (subtest_level, FALSE, "1..%d\n", test_run_count);
} }
break; break;
case G_TEST_LOG_STOP_CASE: case G_TEST_LOG_STOP_CASE:
@ -1026,7 +1143,7 @@ g_test_log (GTestLogType lbit,
fail = result == G_TEST_RUN_FAILURE; fail = result == G_TEST_RUN_FAILURE;
if (test_tap_log) if (test_tap_log)
{ {
const gchar *ok; GString *tap_output;
/* The TAP representation for an expected failure starts with /* The TAP representation for an expected failure starts with
* "not ok", even though it does not actually count as failing * "not ok", even though it does not actually count as failing
@ -1035,28 +1152,33 @@ g_test_log (GTestLogType lbit,
* for which GTestResult does not currently have a * for which GTestResult does not currently have a
* representation. */ * representation. */
if (fail || result == G_TEST_RUN_INCOMPLETE) if (fail || result == G_TEST_RUN_INCOMPLETE)
ok = "not ok"; tap_output = g_string_new ("not ok");
else else
ok = "ok"; tap_output = g_string_new ("ok");
g_print ("%s %d %s", ok, test_run_count, string1); if (is_subtest ())
g_string_prepend (tap_output, TAP_SUBTEST_PREFIX);
g_string_append_printf (tap_output, " %d %s", test_run_count, string1);
if (result == G_TEST_RUN_INCOMPLETE) if (result == G_TEST_RUN_INCOMPLETE)
g_print (" # TODO %s\n", string2 ? string2 : ""); g_string_append_printf (tap_output, " # TODO %s", string2 ? string2 : "");
else if (result == G_TEST_RUN_SKIPPED) else if (result == G_TEST_RUN_SKIPPED)
g_print (" # SKIP %s\n", string2 ? string2 : ""); g_string_append_printf (tap_output, " # SKIP %s", string2 ? string2 : "");
else if (result == G_TEST_RUN_FAILURE && string2 != NULL) else if (result == G_TEST_RUN_FAILURE && string2 != NULL)
g_print (" - %s\n", string2); g_string_append_printf (tap_output, " - %s", string2);
else
g_print ("\n"); g_string_append_c (tap_output, '\n');
g_default_print_func (tap_output->str);
g_string_free (g_steal_pointer (&tap_output), TRUE);
} }
else if (g_test_verbose ()) else if (g_test_verbose ())
g_print ("GTest: result: %s\n", g_test_result_names[result]); g_print ("GTest: result: %s\n", g_test_result_names[result]);
else if (!g_test_quiet ()) else if (!g_test_quiet () && !test_in_subprocess)
g_print ("%s\n", g_test_result_names[result]); g_print ("%s\n", g_test_result_names[result]);
if (fail && test_mode_fatal) if (fail && test_mode_fatal)
{ {
if (test_tap_log) if (test_tap_log)
g_print ("Bail out!\n"); g_test_tap_print (0, FALSE, "Bail out!\n");
g_abort (); g_abort ();
} }
if (result == G_TEST_RUN_SKIPPED || result == G_TEST_RUN_INCOMPLETE) if (result == G_TEST_RUN_SKIPPED || result == G_TEST_RUN_INCOMPLETE)
@ -1064,44 +1186,54 @@ g_test_log (GTestLogType lbit,
break; break;
case G_TEST_LOG_SKIP_CASE: case G_TEST_LOG_SKIP_CASE:
if (test_tap_log) if (test_tap_log)
g_print ("ok %d %s # SKIP\n", test_run_count, string1); {
g_test_tap_print (subtest_level, FALSE, "ok %d %s # SKIP\n",
test_run_count, string1);
}
break; break;
case G_TEST_LOG_MIN_RESULT: case G_TEST_LOG_MIN_RESULT:
if (test_tap_log) if (test_tap_log)
g_print ("# min perf: %s\n", string1); g_print ("min perf: %s\n", string1);
else if (g_test_verbose ()) else if (g_test_verbose ())
g_print ("(MINPERF:%s)\n", string1); g_print ("(MINPERF:%s)\n", string1);
break; break;
case G_TEST_LOG_MAX_RESULT: case G_TEST_LOG_MAX_RESULT:
if (test_tap_log) if (test_tap_log)
g_print ("# max perf: %s\n", string1); g_print ("max perf: %s\n", string1);
else if (g_test_verbose ()) else if (g_test_verbose ())
g_print ("(MAXPERF:%s)\n", string1); g_print ("(MAXPERF:%s)\n", string1);
break; break;
case G_TEST_LOG_MESSAGE: case G_TEST_LOG_MESSAGE:
if (test_tap_log) if (test_tap_log)
{ g_print ("%s\n", string1);
if (strstr (string1, "\n") == NULL)
g_print ("# %s\n", string1);
else
{
char **lines = g_strsplit (string1, "\n", -1);
gsize i;
for (i = 0; lines[i] != NULL; i++)
g_print ("# %s\n", lines[i]);
g_strfreev (lines);
}
}
else if (g_test_verbose ()) else if (g_test_verbose ())
g_print ("(MSG: %s)\n", string1); g_print ("(MSG: %s)\n", string1);
break; break;
case G_TEST_LOG_ERROR: case G_TEST_LOG_ERROR:
if (test_tap_log) if (test_tap_log)
g_print ("Bail out! %s\n", string1); {
char *message = g_strdup (string1);
char *line = message;
while ((line = strchr (line, '\n')))
*(line++) = ' ';
if (is_subtest ())
{
g_test_tap_print (subtest_level, FALSE, "Bail out! %s\n", message);
g_test_tap_print (0, FALSE, "Bail out!\n");
}
else
{
g_test_tap_print (0, FALSE, "Bail out! %s\n", message);
}
g_free (message);
}
else if (g_test_verbose ()) else if (g_test_verbose ())
g_print ("(ERROR: %s)\n", string1); {
g_print ("(ERROR: %s)\n", string1);
}
break; break;
default: ; default: ;
} }
@ -1634,16 +1766,31 @@ void
} }
va_end (args); va_end (args);
/* setup random seed string */
g_snprintf (seedstr, sizeof (seedstr), "R02S%08x%08x%08x%08x", g_random_int(), g_random_int(), g_random_int(), g_random_int());
test_run_seedstr = seedstr;
/* parse args, sets up mode, changes seed, etc. */ /* parse args, sets up mode, changes seed, etc. */
parse_args (argc, argv); parse_args (argc, argv);
if (test_run_seedstr == NULL)
{
/* setup random seed string */
g_snprintf (seedstr, sizeof (seedstr), "R02S%08x%08x%08x%08x",
g_random_int(), g_random_int(), g_random_int(), g_random_int());
test_run_seedstr = seedstr;
}
if (!g_get_prgname() && !no_g_set_prgname) if (!g_get_prgname() && !no_g_set_prgname)
g_set_prgname ((*argv)[0]); g_set_prgname ((*argv)[0]);
if (g_getenv ("G_TEST_ROOT_PROCESS"))
{
test_is_subtest = TRUE;
}
else if (!g_setenv ("G_TEST_ROOT_PROCESS", test_argv0 ? test_argv0 : "root", TRUE))
{
g_printerr ("%s: Failed to set environment variable %s\n",
test_argv0, "G_TEST_ROOT_PROCESS");
exit (1);
}
/* Set up the temporary directory for isolating the test. We have to do this /* Set up the temporary directory for isolating the test. We have to do this
* early, as we want the return values from g_get_user_data_dir() (and * early, as we want the return values from g_get_user_data_dir() (and
* friends) to return subdirectories of the temporary directory throughout * friends) to return subdirectories of the temporary directory throughout
@ -3003,7 +3150,12 @@ test_should_run (const char *test_path,
return TRUE; return TRUE;
if (g_test_verbose ()) if (g_test_verbose ())
g_print ("GTest: skipping: %s\n", test_run_name); {
if (test_tap_log)
g_print ("skipping: %s\n", test_run_name);
else
g_print ("GTest: skipping: %s\n", test_run_name);
}
return FALSE; return FALSE;
} }
@ -3217,9 +3369,10 @@ gtest_default_log_handler (const gchar *log_domain,
msg = g_strjoinv ("", (gchar**) strv); msg = g_strjoinv ("", (gchar**) strv);
g_test_log (fatal ? G_TEST_LOG_ERROR : G_TEST_LOG_MESSAGE, msg, NULL, 0, NULL); g_test_log (fatal ? G_TEST_LOG_ERROR : G_TEST_LOG_MESSAGE, msg, NULL, 0, NULL);
g_log_default_handler (log_domain, log_level, message, unused_data);
g_free (msg); g_free (msg);
if (!test_tap_log)
g_log_default_handler (log_domain, log_level, message, unused_data);
} }
void void
@ -3543,7 +3696,10 @@ child_read (GIOChannel *io, GIOCondition cond, gpointer user_data)
{ {
g_string_append_len (data->stdout_str, buf, nread); g_string_append_len (data->stdout_str, buf, nread);
if (data->echo_stdout) if (data->echo_stdout)
echo_file = stdout; {
if G_UNLIKELY (!test_tap_log)
echo_file = stdout;
}
} }
else else
{ {
@ -3624,6 +3780,22 @@ wait_for_child (GPid pid,
g_main_loop_unref (data.loop); g_main_loop_unref (data.loop);
g_main_context_unref (context); g_main_context_unref (context);
if (echo_stdout && test_tap_log && data.stdout_str->len > 0)
{
gboolean added_newline = FALSE;
if (data.stdout_str->str[data.stdout_str->len - 1] != '\n')
{
g_string_append_c (data.stdout_str, '\n');
added_newline = TRUE;
}
g_test_print_handler_full (data.stdout_str->str, TRUE, TRUE, 1);
if (added_newline)
g_string_truncate (data.stdout_str, data.stdout_str->len - 1);
}
test_trap_last_pid = pid; test_trap_last_pid = pid;
test_trap_last_status = data.child_status; test_trap_last_status = data.child_status;
test_trap_last_stdout = g_string_free (data.stdout_str, FALSE); test_trap_last_stdout = g_string_free (data.stdout_str, FALSE);
@ -3847,7 +4019,12 @@ g_test_trap_subprocess (const char *test_path,
} }
if (g_test_verbose ()) if (g_test_verbose ())
g_print ("GTest: subprocess: %s\n", test_path); {
if (test_tap_log)
g_print ("subprocess: %s\n", test_path);
else
g_print ("GTest: subprocess: %s\n", test_path);
}
test_trap_clear (); test_trap_clear ();
test_trap_last_subprocess = g_strdup (test_path); test_trap_last_subprocess = g_strdup (test_path);
@ -4071,8 +4248,10 @@ g_test_trap_assertions (const char *domain,
logged_child_output = logged_child_output || log_child_output (process_id); logged_child_output = logged_child_output || log_child_output (process_id);
msg = g_strdup_printf ("stdout of child process (%s) %s: %s\nstdout was:\n%s", g_test_message ("stdout was:\n%s", test_trap_last_stdout);
process_id, match_error, stdout_pattern, test_trap_last_stdout);
msg = g_strdup_printf ("stdout of child process (%s) %s: %s",
process_id, match_error, stdout_pattern);
g_assertion_message (domain, file, line, func, msg); g_assertion_message (domain, file, line, func, msg);
g_free (msg); g_free (msg);
} }
@ -4082,8 +4261,10 @@ g_test_trap_assertions (const char *domain,
logged_child_output = logged_child_output || log_child_output (process_id); logged_child_output = logged_child_output || log_child_output (process_id);
msg = g_strdup_printf ("stderr of child process (%s) %s: %s\nstderr was:\n%s", g_test_message ("stderr was:\n%s", test_trap_last_stderr);
process_id, match_error, stderr_pattern, test_trap_last_stderr);
msg = g_strdup_printf ("stderr of child process (%s) %s: %s",
process_id, match_error, stderr_pattern);
g_assertion_message (domain, file, line, func, msg); g_assertion_message (domain, file, line, func, msg);
g_free (msg); g_free (msg);
} }

View File

@ -403,7 +403,7 @@ test_GDateTime_new_from_timeval (void)
dt = g_date_time_new_from_timeval_local (&tv); dt = g_date_time_new_from_timeval_local (&tv);
if (g_test_verbose ()) if (g_test_verbose ())
g_printerr ("\nDT%04d-%02d-%02dT%02d:%02d:%02d%s\n", g_test_message ("DT%04d-%02d-%02dT%02d:%02d:%02d%s",
g_date_time_get_year (dt), g_date_time_get_year (dt),
g_date_time_get_month (dt), g_date_time_get_month (dt),
g_date_time_get_day_of_month (dt), g_date_time_get_day_of_month (dt),
@ -501,7 +501,7 @@ test_GDateTime_new_from_timeval_utc (void)
dt = g_date_time_new_from_timeval_utc (&tv); dt = g_date_time_new_from_timeval_utc (&tv);
if (g_test_verbose ()) if (g_test_verbose ())
g_printerr ("\nDT%04d-%02d-%02dT%02d:%02d:%02d%s\n", g_test_message ("DT%04d-%02d-%02dT%02d:%02d:%02d%s",
g_date_time_get_year (dt), g_date_time_get_year (dt),
g_date_time_get_month (dt), g_date_time_get_month (dt),
g_date_time_get_day_of_month (dt), g_date_time_get_day_of_month (dt),
@ -2097,7 +2097,7 @@ test_all_dates (void)
dt = g_date_time_new (timezone, year, month, day, 0, 0, 0); dt = g_date_time_new (timezone, year, month, day, 0, 0, 0);
#if 0 #if 0
g_printerr ("%04d-%02d-%02d = %04d-W%02d-%d = %04d-%03d\n", g_test_message ("%04d-%02d-%02d = %04d-W%02d-%d = %04d-%03d",
year, month, day, year, month, day,
week_year, week_num, weekday, week_year, week_num, weekday,
year, day_of_year); year, day_of_year);
@ -2384,7 +2384,7 @@ check_and_set_locale (int category,
setlocale (category, name); setlocale (category, name);
if (strstr (setlocale (category, NULL), name) == NULL) if (strstr (setlocale (category, NULL), name) == NULL)
{ {
g_print ("Unavailable '%s' locale\n", name); g_test_message ("Unavailable '%s' locale", name);
g_test_skip ("required locale not available, skipping tests"); g_test_skip ("required locale not available, skipping tests");
return FALSE; return FALSE;
} }

View File

@ -204,11 +204,11 @@ print_buckets (gint buckets[],
for (i = 0; i < count; i++) for (i = 0; i < count; i++)
if (i < count - 1) if (i < count - 1)
g_print ("%-4lld-%4lld|", i == 0 ? 0 : bucket_limits[i - 1], bucket_limits[i] - 1); g_printerr ("%-4lld-%4lld|", i == 0 ? 0 : bucket_limits[i - 1], bucket_limits[i] - 1);
else else
g_print (" >= %-4lld|", bucket_limits[i - 1]); g_printerr (" >= %-4lld|", bucket_limits[i - 1]);
g_print ("\n"); g_printerr ("\n");
for (i = 0; i < count; i++) for (i = 0; i < count; i++)
{ {
@ -225,17 +225,17 @@ print_buckets (gint buckets[],
len = 4; len = 4;
padding = 9 - len; padding = 9 - len;
for (j = 0; j < padding / 2; j++) for (j = 0; j < padding / 2; j++)
g_print (" "); g_printerr (" ");
if (buckets[i] != 0) if (buckets[i] != 0)
g_print ("%*d", len, buckets[i]); g_printerr ("%*d", len, buckets[i]);
else else
g_print (" "); g_printerr (" ");
for (j = padding / 2; j < padding; j++) for (j = padding / 2; j < padding; j++)
g_print (" "); g_printerr (" ");
g_print (" "); g_printerr (" ");
} }
g_print ("\n\n"); g_printerr ("\n\n");
} }
static void static void
@ -281,7 +281,7 @@ test_gpoll (void)
} }
times_avg /= NUM_POLLEES; times_avg /= NUM_POLLEES;
g_print ("\nempty poll time:\n%4lldns - %4lldns, average %4lldns\n", times_min, times_max, times_avg); g_printerr ("\nempty poll time:\n%4lldns - %4lldns, average %4lldns\n", times_min, times_max, times_avg);
print_buckets (buckets, bucket_limits, BUCKET_COUNT); print_buckets (buckets, bucket_limits, BUCKET_COUNT);
times_avg = 0; times_avg = 0;
@ -336,7 +336,7 @@ test_gpoll (void)
} }
times_avg /= NUM_POLLEES; times_avg /= NUM_POLLEES;
g_print ("1-socket + msg poll time:\n%4lldns - %4lldns, average %4lldns\n", times_min, times_max, times_avg); g_printerr ("1-socket + msg poll time:\n%4lldns - %4lldns, average %4lldns\n", times_min, times_max, times_avg);
print_buckets (buckets, bucket_limits, BUCKET_COUNT); print_buckets (buckets, bucket_limits, BUCKET_COUNT);
times_avg = 0; times_avg = 0;
@ -384,7 +384,7 @@ test_gpoll (void)
} }
times_avg /= NUM_POLLEES; times_avg /= NUM_POLLEES;
g_print ("1-socket poll time:\n%4lldns - %4lldns, average %4lldns\n", times_min, times_max, times_avg); g_printerr ("1-socket poll time:\n%4lldns - %4lldns, average %4lldns\n", times_min, times_max, times_avg);
print_buckets (buckets, bucket_limits, BUCKET_COUNT); print_buckets (buckets, bucket_limits, BUCKET_COUNT);
times_avg = 0; times_avg = 0;
@ -433,7 +433,7 @@ test_gpoll (void)
} }
times_avg /= NUM_POLLEES; times_avg /= NUM_POLLEES;
g_print ("half-socket poll time:\n%4lldns - %4lldns, average %4lldns\n", times_min, times_max, times_avg); g_printerr ("half-socket poll time:\n%4lldns - %4lldns, average %4lldns\n", times_min, times_max, times_avg);
print_buckets (buckets, bucket_limits, BUCKET_COUNT); print_buckets (buckets, bucket_limits, BUCKET_COUNT);
times_avg = 0; times_avg = 0;
@ -491,7 +491,7 @@ test_gpoll (void)
} }
times_avg /= NUM_POLLEES; times_avg /= NUM_POLLEES;
g_print ("half-socket + msg poll time:\n%4lldns - %4lldns, average %4lldns\n", times_min, times_max, times_avg); g_printerr ("half-socket + msg poll time:\n%4lldns - %4lldns, average %4lldns\n", times_min, times_max, times_avg);
print_buckets (buckets, bucket_limits, BUCKET_COUNT); print_buckets (buckets, bucket_limits, BUCKET_COUNT);
times_avg = 0; times_avg = 0;
@ -540,7 +540,7 @@ test_gpoll (void)
} }
times_avg /= NUM_POLLEES; times_avg /= NUM_POLLEES;
g_print ("%d-socket poll time: \n%4lldns - %4lldns, average %4lldns\n", NUM_POLLEES, times_min, times_max, times_avg); g_printerr ("%d-socket poll time: \n%4lldns - %4lldns, average %4lldns\n", NUM_POLLEES, times_min, times_max, times_avg);
print_buckets (buckets, bucket_limits, BUCKET_COUNT); print_buckets (buckets, bucket_limits, BUCKET_COUNT);
activatable = 0; activatable = 0;
@ -599,7 +599,7 @@ test_gpoll (void)
} }
times_avg /= NUM_POLLEES; times_avg /= NUM_POLLEES;
g_print ("variable socket number + msg poll time: \n%4lldns - %4lldns, average %4lldns\n", times_min, times_max, times_avg); g_printerr ("variable socket number + msg poll time: \n%4lldns - %4lldns, average %4lldns\n", times_min, times_max, times_avg);
print_buckets (buckets, bucket_limits, BUCKET_COUNT); print_buckets (buckets, bucket_limits, BUCKET_COUNT);
cleanup_sockets (sockets, opp_sockets, NUM_POLLEES); cleanup_sockets (sockets, opp_sockets, NUM_POLLEES);

View File

@ -3,6 +3,12 @@
#define G_LOG_USE_STRUCTURED 1 #define G_LOG_USE_STRUCTURED 1
#include <glib.h> #include <glib.h>
#ifdef G_OS_WIN32
#define LINE_END "\r\n"
#else
#define LINE_END "\n"
#endif
/* Test g_warn macros */ /* Test g_warn macros */
static void static void
test_warnings (void) test_warnings (void)
@ -61,16 +67,45 @@ test_default_handler_error (void)
} }
static void static void
test_default_handler_critical (void) test_default_handler_error_stderr (void)
{ {
g_log_writer_default_set_use_stderr (FALSE);
g_log_set_default_handler (g_log_default_handler, NULL);
g_error ("message1");
exit (0);
}
static void
test_default_handler_critical_stderr (void)
{
g_log_writer_default_set_use_stderr (TRUE);
g_log_set_default_handler (g_log_default_handler, NULL); g_log_set_default_handler (g_log_default_handler, NULL);
g_critical ("message2"); g_critical ("message2");
exit (0); exit (0);
} }
static void
test_default_handler_critical (void)
{
g_log_writer_default_set_use_stderr (FALSE);
g_log_set_default_handler (g_log_default_handler, NULL);
g_critical ("message2");
exit (0);
}
static void
test_default_handler_warning_stderr (void)
{
g_log_writer_default_set_use_stderr (TRUE);
g_log_set_default_handler (g_log_default_handler, NULL);
g_warning ("message3");
exit (0);
}
static void static void
test_default_handler_warning (void) test_default_handler_warning (void)
{ {
g_log_writer_default_set_use_stderr (FALSE);
g_log_set_default_handler (g_log_default_handler, NULL); g_log_set_default_handler (g_log_default_handler, NULL);
g_warning ("message3"); g_warning ("message3");
exit (0); exit (0);
@ -79,6 +114,16 @@ test_default_handler_warning (void)
static void static void
test_default_handler_message (void) test_default_handler_message (void)
{ {
g_log_writer_default_set_use_stderr (FALSE);
g_log_set_default_handler (g_log_default_handler, NULL);
g_message ("message4");
exit (0);
}
static void
test_default_handler_message_stderr (void)
{
g_log_writer_default_set_use_stderr (TRUE);
g_log_set_default_handler (g_log_default_handler, NULL); g_log_set_default_handler (g_log_default_handler, NULL);
g_message ("message4"); g_message ("message4");
exit (0); exit (0);
@ -87,6 +132,16 @@ test_default_handler_message (void)
static void static void
test_default_handler_info (void) test_default_handler_info (void)
{ {
g_log_writer_default_set_use_stderr (FALSE);
g_log_set_default_handler (g_log_default_handler, NULL);
g_log (G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "message5");
exit (0);
}
static void
test_default_handler_info_stderr (void)
{
g_log_writer_default_set_use_stderr (TRUE);
g_log_set_default_handler (g_log_default_handler, NULL); g_log_set_default_handler (g_log_default_handler, NULL);
g_log (G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "message5"); g_log (G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "message5");
exit (0); exit (0);
@ -95,6 +150,7 @@ test_default_handler_info (void)
static void static void
test_default_handler_bar_info (void) test_default_handler_bar_info (void)
{ {
g_log_writer_default_set_use_stderr (FALSE);
g_log_set_default_handler (g_log_default_handler, NULL); g_log_set_default_handler (g_log_default_handler, NULL);
g_setenv ("G_MESSAGES_DEBUG", "foo bar baz", TRUE); g_setenv ("G_MESSAGES_DEBUG", "foo bar baz", TRUE);
@ -106,6 +162,7 @@ test_default_handler_bar_info (void)
static void static void
test_default_handler_baz_debug (void) test_default_handler_baz_debug (void)
{ {
g_log_writer_default_set_use_stderr (FALSE);
g_log_set_default_handler (g_log_default_handler, NULL); g_log_set_default_handler (g_log_default_handler, NULL);
g_setenv ("G_MESSAGES_DEBUG", "foo bar baz", TRUE); g_setenv ("G_MESSAGES_DEBUG", "foo bar baz", TRUE);
@ -117,6 +174,7 @@ test_default_handler_baz_debug (void)
static void static void
test_default_handler_debug (void) test_default_handler_debug (void)
{ {
g_log_writer_default_set_use_stderr (FALSE);
g_log_set_default_handler (g_log_default_handler, NULL); g_log_set_default_handler (g_log_default_handler, NULL);
g_setenv ("G_MESSAGES_DEBUG", "all", TRUE); g_setenv ("G_MESSAGES_DEBUG", "all", TRUE);
@ -192,6 +250,7 @@ test_default_handler_would_drop (void)
static void static void
test_default_handler_0x400 (void) test_default_handler_0x400 (void)
{ {
g_log_writer_default_set_use_stderr (FALSE);
g_log_set_default_handler (g_log_default_handler, NULL); g_log_set_default_handler (g_log_default_handler, NULL);
g_log (G_LOG_DOMAIN, 1<<10, "message7"); g_log (G_LOG_DOMAIN, 1<<10, "message7");
exit (0); exit (0);
@ -205,26 +264,51 @@ test_default_handler (void)
g_test_trap_assert_failed (); g_test_trap_assert_failed ();
g_test_trap_assert_stderr ("*ERROR*message1*"); g_test_trap_assert_stderr ("*ERROR*message1*");
g_test_trap_subprocess ("/logging/default-handler/subprocess/error-stderr", 0,
G_TEST_SUBPROCESS_DEFAULT);
g_test_trap_assert_failed ();
g_test_trap_assert_stderr ("*ERROR*message1*");
g_test_trap_subprocess ("/logging/default-handler/subprocess/critical", 0, g_test_trap_subprocess ("/logging/default-handler/subprocess/critical", 0,
G_TEST_SUBPROCESS_DEFAULT); G_TEST_SUBPROCESS_DEFAULT);
g_test_trap_assert_failed (); g_test_trap_assert_failed ();
g_test_trap_assert_stderr ("*CRITICAL*message2*"); g_test_trap_assert_stderr ("*CRITICAL*message2*");
g_test_trap_subprocess ("/logging/default-handler/subprocess/critical-stderr", 0,
G_TEST_SUBPROCESS_DEFAULT);
g_test_trap_assert_failed ();
g_test_trap_assert_stderr ("*CRITICAL*message2*");
g_test_trap_subprocess ("/logging/default-handler/subprocess/warning", 0, g_test_trap_subprocess ("/logging/default-handler/subprocess/warning", 0,
G_TEST_SUBPROCESS_DEFAULT); G_TEST_SUBPROCESS_DEFAULT);
g_test_trap_assert_failed (); g_test_trap_assert_failed ();
g_test_trap_assert_stderr ("*WARNING*message3*"); g_test_trap_assert_stderr ("*WARNING*message3*");
g_test_trap_subprocess ("/logging/default-handler/subprocess/warning-stderr", 0,
G_TEST_SUBPROCESS_DEFAULT);
g_test_trap_assert_failed ();
g_test_trap_assert_stderr ("*WARNING*message3*");
g_test_trap_subprocess ("/logging/default-handler/subprocess/message", 0, g_test_trap_subprocess ("/logging/default-handler/subprocess/message", 0,
G_TEST_SUBPROCESS_DEFAULT); G_TEST_SUBPROCESS_DEFAULT);
g_test_trap_assert_passed (); g_test_trap_assert_passed ();
g_test_trap_assert_stderr ("*Message*message4*"); g_test_trap_assert_stderr ("*Message*message4*");
g_test_trap_subprocess ("/logging/default-handler/subprocess/message-stderr", 0,
G_TEST_SUBPROCESS_DEFAULT);
g_test_trap_assert_passed ();
g_test_trap_assert_stderr ("*Message*message4*");
g_test_trap_subprocess ("/logging/default-handler/subprocess/info", 0, g_test_trap_subprocess ("/logging/default-handler/subprocess/info", 0,
G_TEST_SUBPROCESS_DEFAULT); G_TEST_SUBPROCESS_DEFAULT);
g_test_trap_assert_passed (); g_test_trap_assert_passed ();
g_test_trap_assert_stdout_unmatched ("*INFO*message5*"); g_test_trap_assert_stdout_unmatched ("*INFO*message5*");
g_test_trap_subprocess ("/logging/default-handler/subprocess/info-stderr", 0,
G_TEST_SUBPROCESS_DEFAULT);
g_test_trap_assert_passed ();
g_test_trap_assert_stderr_unmatched ("*INFO*message5*");
g_test_trap_subprocess ("/logging/default-handler/subprocess/bar-info", 0, g_test_trap_subprocess ("/logging/default-handler/subprocess/bar-info", 0,
G_TEST_SUBPROCESS_DEFAULT); G_TEST_SUBPROCESS_DEFAULT);
g_test_trap_assert_passed (); g_test_trap_assert_passed ();
@ -284,13 +368,27 @@ test_print_handler (void)
GPrintFunc old_print_handler; GPrintFunc old_print_handler;
old_print_handler = g_set_print_handler (my_print_handler); old_print_handler = g_set_print_handler (my_print_handler);
g_assert (old_print_handler == NULL); g_assert_nonnull (old_print_handler);
my_print_count = 0; my_print_count = 0;
g_print ("bu ba"); g_print ("bu ba");
g_assert_cmpint (my_print_count, ==, 1); g_assert_cmpint (my_print_count, ==, 1);
g_set_print_handler (NULL); if (g_test_subprocess ())
{
g_set_print_handler (NULL);
old_print_handler ("default handler\n");
g_print ("bu ba\n");
return;
}
g_set_print_handler (old_print_handler);
g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT);
g_test_trap_assert_stdout ("*default handler" LINE_END "*");
g_test_trap_assert_stdout ("*bu ba" LINE_END "*");
g_test_trap_assert_stdout_unmatched ("*# default handler" LINE_END "*");
g_test_trap_assert_stdout_unmatched ("*# bu ba" LINE_END "*");
g_test_trap_has_passed ();
} }
static void static void
@ -299,13 +397,25 @@ test_printerr_handler (void)
GPrintFunc old_printerr_handler; GPrintFunc old_printerr_handler;
old_printerr_handler = g_set_printerr_handler (my_print_handler); old_printerr_handler = g_set_printerr_handler (my_print_handler);
g_assert (old_printerr_handler == NULL); g_assert_nonnull (old_printerr_handler);
my_print_count = 0; my_print_count = 0;
g_printerr ("bu ba"); g_printerr ("bu ba");
g_assert_cmpint (my_print_count, ==, 1); g_assert_cmpint (my_print_count, ==, 1);
g_set_printerr_handler (NULL); if (g_test_subprocess ())
{
g_set_printerr_handler (NULL);
old_printerr_handler ("default handler\n");
g_printerr ("bu ba\n");
return;
}
g_set_printerr_handler (old_printerr_handler);
g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT);
g_test_trap_assert_stderr ("*default handler" LINE_END "*");
g_test_trap_assert_stderr ("*bu ba" LINE_END "*");
g_test_trap_has_passed ();
} }
static char *fail_str = "foo"; static char *fail_str = "foo";
@ -746,10 +856,15 @@ main (int argc, char *argv[])
g_test_add_func ("/logging/default-handler", test_default_handler); g_test_add_func ("/logging/default-handler", test_default_handler);
g_test_add_func ("/logging/default-handler/subprocess/error", test_default_handler_error); g_test_add_func ("/logging/default-handler/subprocess/error", test_default_handler_error);
g_test_add_func ("/logging/default-handler/subprocess/error-stderr", test_default_handler_error_stderr);
g_test_add_func ("/logging/default-handler/subprocess/critical", test_default_handler_critical); g_test_add_func ("/logging/default-handler/subprocess/critical", test_default_handler_critical);
g_test_add_func ("/logging/default-handler/subprocess/critical-stderr", test_default_handler_critical_stderr);
g_test_add_func ("/logging/default-handler/subprocess/warning", test_default_handler_warning); g_test_add_func ("/logging/default-handler/subprocess/warning", test_default_handler_warning);
g_test_add_func ("/logging/default-handler/subprocess/warning-stderr", test_default_handler_warning_stderr);
g_test_add_func ("/logging/default-handler/subprocess/message", test_default_handler_message); g_test_add_func ("/logging/default-handler/subprocess/message", test_default_handler_message);
g_test_add_func ("/logging/default-handler/subprocess/message-stderr", test_default_handler_message_stderr);
g_test_add_func ("/logging/default-handler/subprocess/info", test_default_handler_info); g_test_add_func ("/logging/default-handler/subprocess/info", test_default_handler_info);
g_test_add_func ("/logging/default-handler/subprocess/info-stderr", test_default_handler_info_stderr);
g_test_add_func ("/logging/default-handler/subprocess/bar-info", test_default_handler_bar_info); g_test_add_func ("/logging/default-handler/subprocess/bar-info", test_default_handler_bar_info);
g_test_add_func ("/logging/default-handler/subprocess/baz-debug", test_default_handler_baz_debug); g_test_add_func ("/logging/default-handler/subprocess/baz-debug", test_default_handler_baz_debug);
g_test_add_func ("/logging/default-handler/subprocess/debug", test_default_handler_debug); g_test_add_func ("/logging/default-handler/subprocess/debug", test_default_handler_debug);

View File

@ -140,6 +140,7 @@ glib_tests = {
'string' : {}, 'string' : {},
'strvbuilder' : {}, 'strvbuilder' : {},
'testing' : { 'testing' : {
'args': [ '--verbose' ],
'extra_programs' : ['testing-helper'], 'extra_programs' : ['testing-helper'],
}, },
'test-printf' : {}, 'test-printf' : {},
@ -386,7 +387,7 @@ foreach test_name, extra_args : glib_tests
) )
depends = [extra_args.get('depends', [])] depends = [extra_args.get('depends', [])]
suite = ['glib'] + extra_args.get('suite', []) suite = ['glib', 'core'] + extra_args.get('suite', [])
timeout = suite.contains('slow') ? test_timeout_slow : test_timeout timeout = suite.contains('slow') ? test_timeout_slow : test_timeout
if extra_args.get('can_fail', false) if extra_args.get('can_fail', false)
@ -398,6 +399,8 @@ foreach test_name, extra_args : glib_tests
endforeach endforeach
test(test_name, exe, test(test_name, exe,
args: extra_args.get('args', []),
protocol : extra_args.get('protocol', test_protocol),
depends : depends, depends : depends,
env : test_env, env : test_env,
timeout : timeout, timeout : timeout,
@ -431,7 +434,7 @@ endif
foreach test_name, extra_args : python_tests foreach test_name, extra_args : python_tests
depends = [extra_args.get('depends', [])] depends = [extra_args.get('depends', [])]
suite = ['glib', 'no-valgrind'] suite = ['glib', 'core', 'no-valgrind']
if extra_args.get('can_fail', false) if extra_args.get('can_fail', false)
suite += 'failing' suite += 'failing'
@ -444,6 +447,7 @@ foreach test_name, extra_args : python_tests
test( test(
test_name, test_name,
python, python,
protocol : extra_args.get('protocol', test_protocol),
depends: depends, depends: depends,
args: ['-B', files(test_name)], args: ['-B', files(test_name)],
env: test_env, env: test_env,
@ -486,7 +490,7 @@ if not meson.is_cross_build() and host_system != 'windows'
test('gtester-xmllint-check', xmllint, test('gtester-xmllint-check', xmllint,
args : ['--noout', tmpsample_xml], args : ['--noout', tmpsample_xml],
env : test_env, env : test_env,
suite : ['glib'], suite : ['glib', 'core'],
) )
endif endif
endif endif

View File

@ -26,7 +26,7 @@ WinMain (struct HINSTANCE__ *hInstance,
} }
else if (__argc <= 2) else if (__argc <= 2)
{ {
printf ("This is stdout\n"); printf ("# This is stdout\n");
fflush (stdout); fflush (stdout);
fprintf (stderr, "This is stderr\n"); fprintf (stderr, "This is stderr\n");
@ -41,36 +41,36 @@ WinMain (struct HINSTANCE__ *hInstance,
if (infd < 0 || outfd < 0) if (infd < 0 || outfd < 0)
{ {
printf ("spawn-test-win32-gui: illegal fds on command line %s", fprintf (stderr, "spawn-test-win32-gui: illegal fds on command line %s\n",
lpszCmdLine); lpszCmdLine);
exit (1); exit (1);
} }
n = strlen ("Hello there"); n = strlen ("Hello there");
if (write (outfd, &n, sizeof (n)) == -1 || if (write (outfd, &n, sizeof (n)) == -1 ||
write (outfd, "Hello there", n) == -1) write (outfd, "Hello there\n", n) == -1)
{ {
int errsv = errno; int errsv = errno;
printf ("spawn-test-win32-gui: Write error: %s", strerror (errsv)); fprintf (stderr, "spawn-test-win32-gui: Write error: %s\n", strerror (errsv));
exit (1); exit (1);
} }
if ((k = read (infd, &n, sizeof (n))) != sizeof (n)) if ((k = read (infd, &n, sizeof (n))) != sizeof (n))
{ {
printf ("spawn-test-win32-gui: Got only %d bytes, wanted %d", fprintf (stderr, "spawn-test-win32-gui: Got only %d bytes, wanted %d\n",
k, (int)sizeof (n)); k, (int)sizeof (n));
exit (1); exit (1);
} }
printf ("spawn-test-win32-gui: Parent says %d bytes to read", n); fprintf (stderr, "spawn-test-win32-gui: Parent says %d bytes to read\n", n);
if ((k = read (infd, buf, n)) != n) if ((k = read (infd, buf, n)) != n)
{ {
int errsv = errno; int errsv = errno;
if (k == -1) if (k == -1)
printf ("spawn-test-win32-gui: Read error: %s", strerror (errsv)); fprintf (stderr, "spawn-test-win32-gui: Read error: %s\n", strerror (errsv));
else else
printf ("spawn-test-win32-gui: Got only %d bytes", k); fprintf (stderr, "spawn-test-win32-gui: Got only %d bytes\n", k);
exit (1); exit (1);
} }
@ -79,7 +79,7 @@ WinMain (struct HINSTANCE__ *hInstance,
write (outfd, "See ya", n) == -1) write (outfd, "See ya", n) == -1)
{ {
int errsv = errno; int errsv = errno;
printf ("spawn-test-win32-gui: Write error: %s", strerror (errsv)); fprintf (stderr, "spawn-test-win32-gui: Write error: %s\n", strerror (errsv));
exit (1); exit (1);
} }
} }

View File

@ -149,7 +149,7 @@ test_spawn_basics (void)
g_assert_no_error (err); g_assert_no_error (err);
g_assert_true (result); g_assert_true (result);
g_assert_cmpstr (output, ==, "This is stdout\r\n"); g_assert_cmpstr (output, ==, "# This is stdout\r\n");
g_assert_cmpstr (erroutput, ==, "This is stderr\r\n"); g_assert_cmpstr (erroutput, ==, "This is stderr\r\n");
g_free (output); g_free (output);

View File

@ -20,6 +20,7 @@
#include <glib.h> #include <glib.h>
#include <locale.h> #include <locale.h>
#include <stdio.h>
#ifdef G_OS_WIN32 #ifdef G_OS_WIN32
#include <fcntl.h> #include <fcntl.h>
#include <io.h> #include <io.h>
@ -51,6 +52,12 @@ test_fail (void)
g_test_fail (); g_test_fail ();
} }
static void
test_error (void)
{
g_error ("This should error out\nBecause it's just\nwrong!");
}
static void static void
test_fail_printf (void) test_fail_printf (void)
{ {
@ -79,6 +86,63 @@ test_summary (void)
"it in the TAP output later."); "it in the TAP output later.");
} }
static void
test_message (void)
{
g_test_message ("Tests that single line message works");
g_test_message ("Tests that multi\n\nline\nmessage\nworks");
g_test_message ("\nTests that multi\nline\nmessage\nworks with leading and trailing too\n");
}
static void
test_print (void)
{
g_print ("Tests that single line message works\n");
g_print ("test that multiple\nlines ");
g_print ("can be ");
g_print ("written ");
g_print ("separately\n");
}
static void
test_subprocess_stdout (void)
{
if (g_test_subprocess ())
{
printf ("Tests that single line message works\n");
printf ("test that multiple\nlines ");
printf ("can be ");
printf ("written ");
printf ("separately\n");
puts ("And another line has been put");
return;
}
g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_INHERIT_STDOUT);
g_test_trap_has_passed ();
g_test_trap_assert_stdout ("/sub-stdout: Tests that single line message works\n*");
g_test_trap_assert_stdout ("*\ntest that multiple\nlines can be written separately\n*");
g_test_trap_assert_stdout ("*\nAnd another line has been put\n*");
}
static void
test_subprocess_stdout_no_nl (void)
{
if (g_test_subprocess ())
{
printf ("A message without trailing new line");
return;
}
g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_INHERIT_STDOUT);
g_test_trap_has_passed ();
g_test_trap_assert_stdout ("/sub-stdout-no-nl: A message without trailing new line");
}
int int
main (int argc, main (int argc,
char *argv[]) char *argv[])
@ -149,6 +213,15 @@ main (int argc,
{ {
g_test_add_func ("/fail", test_fail); g_test_add_func ("/fail", test_fail);
} }
else if (g_strcmp0 (argv1, "error") == 0)
{
g_test_add_func ("/error", test_error);
}
else if (g_strcmp0 (argv1, "error-and-pass") == 0)
{
g_test_add_func ("/error", test_error);
g_test_add_func ("/pass", test_pass);
}
else if (g_strcmp0 (argv1, "fail-printf") == 0) else if (g_strcmp0 (argv1, "fail-printf") == 0)
{ {
g_test_add_func ("/fail-printf", test_fail_printf); g_test_add_func ("/fail-printf", test_fail_printf);
@ -185,9 +258,33 @@ main (int argc,
{ {
g_test_add_func ("/summary", test_summary); g_test_add_func ("/summary", test_summary);
} }
else if (g_strcmp0 (argv1, "message") == 0)
{
g_test_add_func ("/message", test_message);
}
else if (g_strcmp0 (argv1, "print") == 0)
{
g_test_add_func ("/print", test_print);
}
else if (g_strcmp0 (argv1, "subprocess-stdout") == 0)
{
g_test_add_func ("/sub-stdout", test_subprocess_stdout);
}
else if (g_strcmp0 (argv1, "subprocess-stdout-no-nl") == 0)
{
g_test_add_func ("/sub-stdout-no-nl", test_subprocess_stdout_no_nl);
}
else else
{ {
g_assert_not_reached (); if (g_test_subprocess ())
{
g_test_add_func ("/sub-stdout", test_subprocess_stdout);
g_test_add_func ("/sub-stdout-no-nl", test_subprocess_stdout_no_nl);
}
else
{
g_assert_not_reached ();
}
} }
return g_test_run (); return g_test_run ();

File diff suppressed because it is too large Load Diff

View File

@ -5,6 +5,7 @@ gmodule_tests = {
if have_cxx if have_cxx
gmodule_tests += { gmodule_tests += {
'cxx' : { 'cxx' : {
'protocol': 'exitcode',
'source' : ['cxx.cpp'], 'source' : ['cxx.cpp'],
'suite' : ['cpp'], 'suite' : ['cpp'],
} }
@ -13,6 +14,7 @@ if have_cxx
foreach std, arg: cxx_standards foreach std, arg: cxx_standards
gmodule_tests += { gmodule_tests += {
'cxx-@0@'.format(std) : { 'cxx-@0@'.format(std) : {
'protocol': 'exitcode',
'source' : ['cxx.cpp'], 'source' : ['cxx.cpp'],
'suite' : ['cpp'], 'suite' : ['cpp'],
'cpp_args' : [arg], 'cpp_args' : [arg],
@ -115,6 +117,7 @@ foreach test_name, extra_args : gmodule_tests
test(test_name, test(test_name,
exe, exe,
protocol : extra_args.get('protocol', test_protocol),
depends : depends, depends : depends,
env : test_env, env : test_env,
timeout : timeout, timeout : timeout,

View File

@ -41,7 +41,7 @@ gobject_tests = {
'defaultiface' : { 'defaultiface' : {
'source' : ['defaultiface.c', 'testmodule.c'], 'source' : ['defaultiface.c', 'testmodule.c'],
}, },
'deftype' : {}, 'deftype' : { 'protocol': 'exitcode' },
'deprecated-properties' : {}, 'deprecated-properties' : {},
'dynamictype' : { 'dynamictype' : {
'source' : ['dynamictype.c', 'testmodule.c'], 'source' : ['dynamictype.c', 'testmodule.c'],
@ -109,6 +109,7 @@ gobject_tests = {
if have_cxx if have_cxx
gobject_tests += { gobject_tests += {
'cxx' : { 'cxx' : {
'protocol': 'exitcode',
'source' : ['cxx.cpp'], 'source' : ['cxx.cpp'],
'suite' : ['cpp'], 'suite' : ['cpp'],
}, },
@ -117,6 +118,7 @@ if have_cxx
foreach std, arg: cxx_standards foreach std, arg: cxx_standards
gobject_tests += { gobject_tests += {
'cxx-@0@'.format(std) : { 'cxx-@0@'.format(std) : {
'protocol': 'exitcode',
'source' : ['cxx.cpp'], 'source' : ['cxx.cpp'],
'suite' : ['cpp'], 'suite' : ['cpp'],
'cpp_args' : [arg], 'cpp_args' : [arg],
@ -186,7 +188,13 @@ foreach test_name, extra_args : gobject_tests
timeout = timeout * 10 timeout = timeout * 10
endif endif
test(test_name, exe, env : test_env, timeout : timeout, suite : suite) test(test_name,
exe,
protocol : extra_args.get('protocol', test_protocol),
env : test_env,
timeout : timeout,
suite : suite,
)
endforeach endforeach
foreach test_name, extra_args : python_tests foreach test_name, extra_args : python_tests
@ -200,6 +208,7 @@ foreach test_name, extra_args : python_tests
test( test(
test_name, test_name,
python, python,
protocol : extra_args.get('protocol', test_protocol),
depends: depends, depends: depends,
args: ['-B', files(test_name)], args: ['-B', files(test_name)],
env: test_env, env: test_env,

View File

@ -44,5 +44,11 @@ foreach test_name, extra_args : gthread_tests
suite += 'failing' suite += 'failing'
endif endif
test(test_name, exe, env : test_env, timeout : timeout, suite : suite) test(test_name,
exe,
protocol : extra_args.get('protocol', test_protocol),
env : test_env,
timeout : timeout,
suite : suite,
)
endforeach endforeach

View File

@ -151,6 +151,10 @@ common_test_env = [
'MALLOC_CHECK_=2', 'MALLOC_CHECK_=2',
] ]
# Note: this may cause the tests output not to be printed when running in
# verbose mode, see https://github.com/mesonbuild/meson/issues/11185
# Can be changed it to 'exitcode' if required during development.
test_protocol = 'tap'
test_timeout = 30 test_timeout = 30
test_timeout_slow = 90 test_timeout_slow = 90