X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=gio%2Ftests%2Fgdbus-exit-on-close.c;h=befad74be0a9a5fc0ea519167cef0cd373e865b8;hb=e6456bcfb682113b2b623e9ccd9bcec46626e4ed;hp=7f75519cece6844329210f159b1678a08d286941;hpb=d0a14469d09d5fe23de219ba293fd4a266b02ced;p=platform%2Fupstream%2Fglib.git diff --git a/gio/tests/gdbus-exit-on-close.c b/gio/tests/gdbus-exit-on-close.c index 7f75519..befad74 100644 --- a/gio/tests/gdbus-exit-on-close.c +++ b/gio/tests/gdbus-exit-on-close.c @@ -1,6 +1,6 @@ /* GLib testing framework examples and tests * - * Copyright (C) 2008-2009 Red Hat, Inc. + * Copyright (C) 2008-2010 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 @@ -21,6 +21,7 @@ */ #include +#include #include #include @@ -31,32 +32,173 @@ static GMainLoop *loop = NULL; /* ---------------------------------------------------------------------------------------------------- */ +typedef struct { + const gchar *name; + const gchar *bug; + enum { + EXPLICITLY_FALSE = FALSE, + EXPLICITLY_TRUE = TRUE, + IMPLICITLY_TRUE + } exit_on_close; + enum { + LOCAL, + REMOTE + } who_closes; +} TestData; + +static const TestData cases[] = { + { "default", NULL, IMPLICITLY_TRUE, REMOTE }, + { "true", NULL, EXPLICITLY_TRUE, REMOTE }, + { "false", NULL, EXPLICITLY_FALSE, REMOTE }, + { "we-close", "662100", EXPLICITLY_TRUE, LOCAL }, + { NULL } +}; + static gboolean -nuke_session_bus_cb (gpointer data) +quit_later_cb (gpointer data G_GNUC_UNUSED) { g_main_loop_quit (loop); + return FALSE; } +#define VANISHED_PATTERN "*Remote peer vanished with error: Underlying GIOStream returned 0 bytes on an async read (g-io-error-quark, 0). Exiting.*" + +static void +closed_cb (GDBusConnection *c G_GNUC_UNUSED, + gboolean remote_peer_vanished, + GError *error, + gpointer test_data) +{ + const TestData *td = test_data; + + if (error == NULL) + g_debug ("closed (%d, no error)", remote_peer_vanished); + else + g_debug ("closed (%d, %s %d \"%s\")", remote_peer_vanished, + g_quark_to_string (error->domain), error->code, error->message); + + g_assert_cmpint (remote_peer_vanished, ==, (td->who_closes == REMOTE)); + g_assert_cmpint ((error == NULL), ==, (td->who_closes == LOCAL)); + + /* we delay this so that if exit-on-close was going to happen, it will + * win the race + */ + g_timeout_add (50, quit_later_cb, NULL); +} + static void -test_exit_on_close (void) +close_async_cb (GObject *source G_GNUC_UNUSED, + GAsyncResult *res G_GNUC_UNUSED, + gpointer nil G_GNUC_UNUSED) { - if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDOUT | G_TEST_TRAP_SILENCE_STDERR)) + GError *error = NULL; + + if (g_dbus_connection_close_finish (G_DBUS_CONNECTION (source), + res, + &error)) + { + g_debug ("closed connection"); + } + else { - GDBusConnection *c; - session_bus_up (); - c = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL); - g_assert (c != NULL); - g_assert (!g_dbus_connection_is_closed (c)); - g_timeout_add (50, - nuke_session_bus_cb, - NULL); - g_main_loop_run (loop); - session_bus_down (); - g_main_loop_run (loop); + g_warning ("failed to close connection: %s (%s #%d)", + error->message, g_quark_to_string (error->domain), + error->code); + } +} + +static void +test_exit_on_close_subprocess (gconstpointer test_data) +{ + const TestData *td = test_data; + GDBusConnection *c; + + loop = g_main_loop_new (NULL, FALSE); + + session_bus_up (); + c = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL); + + g_assert (c != NULL); + + /* the default is meant to be TRUE */ + if (td->exit_on_close != IMPLICITLY_TRUE) + g_dbus_connection_set_exit_on_close (c, td->exit_on_close); + + g_assert_cmpint (g_dbus_connection_get_exit_on_close (c), ==, + (td->exit_on_close != EXPLICITLY_FALSE)); + g_assert (!g_dbus_connection_is_closed (c)); + + g_timeout_add (50, quit_later_cb, NULL); + g_main_loop_run (loop); + + g_signal_connect (c, "closed", G_CALLBACK (closed_cb), (gpointer) td); + + if (td->who_closes == LOCAL) + { + GVariant *v; + GError *error = NULL; + + v = g_dbus_connection_call_sync (c, "org.freedesktop.DBus", + "/org/freedesktop/DBus", + "org.freedesktop.DBus", + "ListNames", + NULL, + G_VARIANT_TYPE ("(as)"), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &error); + g_assert_no_error (error); + g_assert (v != NULL); + g_variant_unref (v); + + g_dbus_connection_close (c, NULL, close_async_cb, NULL); + } + else + { + session_bus_stop (); + } + + g_main_loop_run (loop); + /* this is only reached when we turn off exit-on-close */ + g_main_loop_unref (loop); + g_object_unref (c); + + session_bus_down (); + + exit (0); +} + +static void +test_exit_on_close (gconstpointer test_data) +{ + const TestData *td = test_data; + GTestSubprocessFlags flags; + char *child_name; + + g_test_dbus_unset (); + + if (g_test_verbose ()) + flags = G_TEST_SUBPROCESS_INHERIT_STDOUT | G_TEST_SUBPROCESS_INHERIT_STDERR; + else + flags = 0; + + child_name = g_strdup_printf ("/gdbus/exit-on-close/%s/subprocess", td->name); + g_test_trap_subprocess (child_name, 0, flags); + g_free (child_name); + + if (td->exit_on_close == EXPLICITLY_FALSE || + td->who_closes == LOCAL) + { + g_test_trap_assert_stdout_unmatched (VANISHED_PATTERN); + g_test_trap_assert_passed (); + } + else + { + g_test_trap_assert_stdout (VANISHED_PATTERN); + g_test_trap_assert_failed(); } - g_test_trap_assert_stdout ("*Remote peer vanished. Exiting.*"); - g_test_trap_assert_failed(); } /* ---------------------------------------------------------------------------------------------------- */ @@ -65,18 +207,22 @@ int main (int argc, char *argv[]) { - g_type_init (); + gint i; + g_test_init (&argc, &argv, NULL); - /* all the tests rely on a shared main loop */ - loop = g_main_loop_new (NULL, FALSE); + for (i = 0; cases[i].name != NULL; i++) + { + gchar *name; - /* all the tests use a session bus with a well-known address that we can bring up and down - * using session_bus_up() and session_bus_down(). - */ - g_unsetenv ("DISPLAY"); - g_setenv ("DBUS_SESSION_BUS_ADDRESS", session_bus_get_temporary_address (), TRUE); + name = g_strdup_printf ("/gdbus/exit-on-close/%s", cases[i].name); + g_test_add_data_func (name, &cases[i], test_exit_on_close); + g_free (name); + + name = g_strdup_printf ("/gdbus/exit-on-close/%s/subprocess", cases[i].name); + g_test_add_data_func (name, &cases[i], test_exit_on_close_subprocess); + g_free (name); + } - g_test_add_func ("/gdbus/exit-on-close", test_exit_on_close); return g_test_run(); }