Commit e3a29184 authored by Dan Winship's avatar Dan Winship Committed by Matthias Clasen

gtestutils: add g_test_trap_subprocess(), deprecate g_test_trap_fork()

g_test_trap_fork() doesn't work on Windows and is potentially flaky on
unix anyway given the fork-but-don't-exec. Replace it with
g_test_trap_subprocess(), which re-spawns the same program with
arguments telling it to run a specific (otherwise-ignored) test case.

Make the existing g_test_trap_fork() unit tests be unix-only (they
never passed on Windows anyway), and add a parallel set of
g_test_trap_subprocess() tests.

https://bugzilla.gnome.org/show_bug.cgi?id=679683
parent 79fab3e6
......@@ -2888,6 +2888,7 @@ g_test_perf
g_test_verbose
g_test_undefined
g_test_quiet
g_test_subprocess
g_test_run
GTestFunc
g_test_add_func
......@@ -2895,6 +2896,7 @@ GTestDataFunc
g_test_add_data_func
g_test_add_data_func_full
g_test_add
g_test_case_exists
g_test_fail
g_test_message
......@@ -2915,7 +2917,7 @@ g_test_expect_message
g_test_assert_expected_messages
GTestTrapFlags
g_test_trap_fork
g_test_trap_subprocess
g_test_trap_has_passed
g_test_trap_reached_timeout
g_test_trap_assert_passed
......@@ -2924,6 +2926,7 @@ g_test_trap_assert_stdout
g_test_trap_assert_stdout_unmatched
g_test_trap_assert_stderr
g_test_trap_assert_stderr_unmatched
g_test_trap_fork
g_test_rand_bit
g_test_rand_int
......
......@@ -1193,6 +1193,7 @@ g_test_add_vtable
g_test_assert_expected_messages_internal
g_test_bug
g_test_bug_base
g_test_case_exists
g_test_config_vars
g_test_create_case
g_test_create_suite
......@@ -1217,6 +1218,7 @@ g_test_rand_int
g_test_rand_int_range
g_test_run
g_test_run_suite
g_test_subprocess
g_test_suite_add
g_test_suite_add_suite
g_test_timer_elapsed
......@@ -1226,6 +1228,7 @@ g_test_trap_assertions
g_test_trap_fork
g_test_trap_has_passed
g_test_trap_reached_timeout
g_test_trap_subprocess
g_timer_continue
g_timer_destroy
g_timer_elapsed
......
......@@ -1094,7 +1094,7 @@ g_assert_warning (const char *log_domain,
*
* Note that you cannot use this to test g_error() messages, since
* g_error() intentionally never returns even if the program doesn't
* abort; use g_test_trap_fork() in this case.
* abort; use g_test_trap_subprocess() in this case.
*
* Since: 2.34
*/
......
This diff is collapsed.
......@@ -92,14 +92,17 @@ void g_test_init (int *argc,
char ***argv,
...);
/* query testing framework config */
#define g_test_initialized() (g_test_config_vars->test_initialized)
#define g_test_quick() (g_test_config_vars->test_quick)
#define g_test_slow() (!g_test_config_vars->test_quick)
#define g_test_thorough() (!g_test_config_vars->test_quick)
#define g_test_perf() (g_test_config_vars->test_perf)
#define g_test_verbose() (g_test_config_vars->test_verbose)
#define g_test_quiet() (g_test_config_vars->test_quiet)
#define g_test_undefined() (g_test_config_vars->test_undefined)
#define g_test_initialized() (g_test_config_vars->test_initialized)
#define g_test_quick() (g_test_config_vars->test_quick)
#define g_test_slow() (!g_test_config_vars->test_quick)
#define g_test_thorough() (!g_test_config_vars->test_quick)
#define g_test_perf() (g_test_config_vars->test_perf)
#define g_test_verbose() (g_test_config_vars->test_verbose)
#define g_test_quiet() (g_test_config_vars->test_quiet)
#define g_test_undefined() (g_test_config_vars->test_undefined)
GLIB_AVAILABLE_IN_2_36
gboolean g_test_subprocess (void);
/* run all tests under toplevel suite (path: /) */
int g_test_run (void);
/* hook up a test functions under test path */
......@@ -132,6 +135,9 @@ void g_test_fail (void);
(testpath, sizeof (Fixture), tdata, fsetup, ftest, fteardown); \
} G_STMT_END
GLIB_AVAILABLE_IN_2_36
gboolean g_test_case_exists (const char *test_path);
/* add test messages to the test report */
void g_test_message (const char *format,
...) G_GNUC_PRINTF (1, 2);
......@@ -154,8 +160,20 @@ typedef enum {
G_TEST_TRAP_SILENCE_STDERR = 1 << 8,
G_TEST_TRAP_INHERIT_STDIN = 1 << 9
} GTestTrapFlags;
GLIB_DEPRECATED_IN_2_36_FOR (g_test_trap_subprocess)
gboolean g_test_trap_fork (guint64 usec_timeout,
GTestTrapFlags test_trap_flags);
GLIB_AVAILABLE_IN_2_36
void g_test_trap_subprocess (const char *test_path,
guint64 usec_timeout,
GTestTrapFlags test_trap_flags);
#define g_test_trap_subprocess(test_path, usec_timeout, test_trap_flags) \
g_assert (g_test_case_exists (test_path)); \
g_test_trap_subprocess (test_path, usec_timeout, test_trap_flags);
gboolean g_test_trap_has_passed (void);
gboolean g_test_trap_reached_timeout (void);
#define g_test_trap_assert_passed() g_test_trap_assertions (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, 0, 0)
......
......@@ -76,6 +76,9 @@ test_timer (void)
g_test_maximized_result (5, "bogus-quantity: %ddummies", 5); /* simple API test */
}
#ifdef G_OS_UNIX
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
/* fork out for a failing test */
static void
test_fork_fail (void)
......@@ -118,6 +121,78 @@ test_fork_timeout (void)
g_assert (g_test_trap_reached_timeout());
}
G_GNUC_END_IGNORE_DEPRECATIONS
#endif /* G_OS_UNIX */
static void
test_subprocess_fail_child (void)
{
g_assert_not_reached ();
}
static void
test_subprocess_fail (void)
{
g_test_trap_subprocess ("/subprocess/fail:child",
0, G_TEST_TRAP_SILENCE_STDERR);
g_test_trap_assert_failed ();
g_test_trap_assert_stderr ("*ERROR*test_subprocess_fail_child*should not be reached*");
}
static void
test_subprocess_no_such_test_child (void)
{
g_test_trap_subprocess ("/subprocess/this-test-does-not-exist",
0, G_TEST_TRAP_SILENCE_STDERR);
g_assert_not_reached ();
}
static void
test_subprocess_no_such_test (void)
{
g_test_trap_subprocess ("/subprocess/no-such-test:child",
0, G_TEST_TRAP_SILENCE_STDERR);
g_test_trap_assert_failed ();
g_test_trap_assert_stderr ("*assertion failed*g_test_case_exists*");
g_test_trap_assert_stderr_unmatched ("*should not be reached*");
}
static void
test_subprocess_patterns_child (void)
{
g_print ("some stdout text: somagic17\n");
g_printerr ("some stderr text: semagic43\n");
exit (0);
}
static void
test_subprocess_patterns (void)
{
g_test_trap_subprocess ("/subprocess/patterns:child",
0, G_TEST_TRAP_SILENCE_STDOUT | G_TEST_TRAP_SILENCE_STDERR);
g_test_trap_assert_passed ();
g_test_trap_assert_stdout ("*somagic17*");
g_test_trap_assert_stderr ("*semagic43*");
}
static void
test_subprocess_timeout_child (void)
{
/* loop and sleep forever */
while (TRUE)
g_usleep (1000 * 1000);
}
static void
test_subprocess_timeout (void)
{
/* allow child to run for only a fraction of a second */
g_test_trap_subprocess ("/subprocess/timeout:child",
0.11 * 1000000, 0);
g_test_trap_assert_failed ();
g_assert (g_test_trap_reached_timeout ());
}
/* run a test with fixture setup and teardown */
typedef struct {
guint seed;
......@@ -335,10 +410,26 @@ main (int argc,
g_test_add ("/misc/primetoul", Fixturetest, (void*) 0xc0cac01a, fixturetest_setup, fixturetest_test, fixturetest_teardown);
if (g_test_perf())
g_test_add_func ("/misc/timer", test_timer);
#ifdef G_OS_UNIX
g_test_add_func ("/forking/fail assertion", test_fork_fail);
g_test_add_func ("/forking/patterns", test_fork_patterns);
if (g_test_slow())
g_test_add_func ("/forking/timeout", test_fork_timeout);
#endif
g_test_add_func ("/subprocess/fail", test_subprocess_fail);
g_test_add_func ("/subprocess/fail:child", test_subprocess_fail_child);
g_test_add_func ("/subprocess/no-such-test", test_subprocess_no_such_test);
g_test_add_func ("/subprocess/no-such-test:child", test_subprocess_no_such_test_child);
if (g_test_slow ())
{
g_test_add_func ("/subprocess/timeout", test_subprocess_timeout);
g_test_add_func ("/subprocess/timeout:child", test_subprocess_timeout_child);
}
g_test_add_func ("/subprocess/patterns", test_subprocess_patterns);
g_test_add_func ("/subprocess/patterns:child", test_subprocess_patterns_child);
g_test_add_func ("/misc/fatal-log-handler", test_fatal_log_handler);
g_test_add_func ("/misc/expected-messages", test_expected_messages);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment