*/
#include <gio/gio.h>
+#include <stdlib.h>
#include <unistd.h>
#include <string.h>
/* ---------------------------------------------------------------------------------------------------- */
+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
-test_exit_on_close (void)
+closed_cb (GDBusConnection *c G_GNUC_UNUSED,
+ gboolean remote_peer_vanished,
+ GError *error,
+ gpointer test_data)
{
+ const TestData *td = test_data;
+
+ 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
+close_async_cb (GObject *source G_GNUC_UNUSED,
+ GAsyncResult *res G_GNUC_UNUSED,
+ gpointer nil G_GNUC_UNUSED)
+{
+}
+
+static void
+test_exit_on_close (gconstpointer test_data)
+{
+ const TestData *td = test_data;
+
+ /* all the tests rely on a shared main loop */
+ loop = g_main_loop_new (NULL, FALSE);
+
+ /* 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);
+
if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDOUT | G_TEST_TRAP_SILENCE_STDERR))
{
GDBusConnection *c;
+
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,
- nuke_session_bus_cb,
- NULL);
+
+ g_timeout_add (50, quit_later_cb, NULL);
g_main_loop_run (loop);
- session_bus_down ();
+
+ 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_dbus_connection_close (c, NULL, close_async_cb, NULL);
+ }
+ else
+ {
+ session_bus_down ();
+ }
+
g_main_loop_run (loop);
+ /* this is only reached when we turn off exit-on-close */
+ g_main_loop_unref (loop);
+ exit (0);
+ }
+
+ 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 with error: Underlying GIOStream returned 0 bytes on an async read (g-io-error-quark, 0). Exiting.*");
- g_test_trap_assert_failed();
}
/* ---------------------------------------------------------------------------------------------------- */
main (int argc,
char *argv[])
{
+ gint i;
+
g_type_init ();
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 = g_strdup_printf ("/gdbus/exit-on-close/%s", cases[i].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);
+ g_test_add_data_func (name, &cases[i], test_exit_on_close);
+ g_free (name);
+ }
- g_test_add_func ("/gdbus/exit-on-close", test_exit_on_close);
return g_test_run();
}