From a114e98d09248f843c87b99c15534db4cf6367aa Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Fri, 31 May 2013 21:24:21 -0400 Subject: [PATCH] Split off the gdbus-overflow test It is unrealiable under load, and frequently fails in the ostree tests. See https://bugzilla.gnome.org/show_bug.cgi?id=701105 --- gio/tests/Makefile.am | 3 +- gio/tests/gdbus-overflow.c | 252 +++++++++++++++++++++++++++++++++++++++++++++ gio/tests/gdbus-peer.c | 126 +---------------------- 3 files changed, 255 insertions(+), 126 deletions(-) create mode 100644 gio/tests/gdbus-overflow.c diff --git a/gio/tests/Makefile.am b/gio/tests/Makefile.am index 948be46..f9d5d80 100644 --- a/gio/tests/Makefile.am +++ b/gio/tests/Makefile.am @@ -97,6 +97,7 @@ test_progs += \ gdbus-close-pending \ gdbus-connection-flush \ gdbus-peer \ + gdbus-overflow \ gdbus-exit-on-close \ gdbus-non-socket \ gdbus-peer-object-manager \ @@ -523,7 +524,7 @@ testdata_DATA = $(test_files) testmetadir = $(datadir)/installed-tests/$(PACKAGE) xfail_tests = desktop-app-info.test -developer_only_tests = gsettings.test +developer_only_tests = gsettings.test gdbus-overflow.test testmeta_DATA = $(filter-out $(xfail_tests) $(developer_only_tests),$(test_progs:=.test)) %.test: %$(EXEEXT) Makefile diff --git a/gio/tests/gdbus-overflow.c b/gio/tests/gdbus-overflow.c new file mode 100644 index 0000000..f78960b --- /dev/null +++ b/gio/tests/gdbus-overflow.c @@ -0,0 +1,252 @@ +/* GLib testing framework examples and tests + * + * 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 + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: David Zeuthen + */ + +#include "config.h" + +#include +#include +#include + +/* for open(2) */ +#include +#include +#include +#include + +/* for g_unlink() */ +#include + +#include +#include +#include + +/* used in test_overflow */ +#ifdef G_OS_UNIX +#include +#include +#endif + +#ifdef G_OS_UNIX +static gboolean is_unix = TRUE; +#else +static gboolean is_unix = FALSE; +#endif + +static gchar *tmp_address = NULL; +static gchar *test_guid = NULL; +static GMainLoop *loop = NULL; + +static const gchar *test_interface_introspection_xml = + "" + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + ""; +static GDBusInterfaceInfo *test_interface_introspection_data = NULL; + + +#ifdef G_OS_UNIX + +/* Chosen to be big enough to overflow the socket buffer */ +#define OVERFLOW_NUM_SIGNALS 5000 +#define OVERFLOW_TIMEOUT_SEC 10 + +static GDBusMessage * +overflow_filter_func (GDBusConnection *connection, + GDBusMessage *message, + gboolean incoming, + gpointer user_data) +{ + volatile gint *counter = user_data; + *counter += 1; + return message; +} + +static gboolean +overflow_on_500ms_later_func (gpointer user_data) +{ + g_main_loop_quit (loop); + return FALSE; /* don't keep the idle */ +} + +static void +test_overflow (void) +{ + gint sv[2]; + gint n; + GSocket *socket; + GSocketConnection *socket_connection; + GDBusConnection *producer, *consumer; + GError *error; + GTimer *timer; + volatile gint n_messages_received; + volatile gint n_messages_sent; + + g_assert_cmpint (socketpair (AF_UNIX, SOCK_STREAM, 0, sv), ==, 0); + + error = NULL; + socket = g_socket_new_from_fd (sv[0], &error); + g_assert_no_error (error); + socket_connection = g_socket_connection_factory_create_connection (socket); + g_assert (socket_connection != NULL); + g_object_unref (socket); + producer = g_dbus_connection_new_sync (G_IO_STREAM (socket_connection), + NULL, /* guid */ + G_DBUS_CONNECTION_FLAGS_NONE, + NULL, /* GDBusAuthObserver */ + NULL, /* GCancellable */ + + &error); + g_dbus_connection_set_exit_on_close (producer, TRUE); + g_assert_no_error (error); + g_object_unref (socket_connection); + n_messages_sent = 0; + g_dbus_connection_add_filter (producer, overflow_filter_func, (gpointer) &n_messages_sent, NULL); + + /* send enough data that we get an EAGAIN */ + for (n = 0; n < OVERFLOW_NUM_SIGNALS; n++) + { + error = NULL; + g_dbus_connection_emit_signal (producer, + NULL, /* destination */ + "/org/foo/Object", + "org.foo.Interface", + "Member", + g_variant_new ("(s)", "a string"), + &error); + g_assert_no_error (error); + } + + /* sleep for 0.5 sec (to allow the GDBus IO thread to fill up the + * kernel buffers) and verify that n_messages_sent < + * OVERFLOW_NUM_SIGNALS + * + * This is to verify that not all the submitted messages have been + * sent to the underlying transport. + */ + g_timeout_add (500, overflow_on_500ms_later_func, NULL); + g_main_loop_run (loop); + g_assert_cmpint (n_messages_sent, <, OVERFLOW_NUM_SIGNALS); + + /* now suck it all out as a client, and add it up */ + socket = g_socket_new_from_fd (sv[1], &error); + g_assert_no_error (error); + socket_connection = g_socket_connection_factory_create_connection (socket); + g_assert (socket_connection != NULL); + g_object_unref (socket); + consumer = g_dbus_connection_new_sync (G_IO_STREAM (socket_connection), + NULL, /* guid */ + G_DBUS_CONNECTION_FLAGS_DELAY_MESSAGE_PROCESSING, + NULL, /* GDBusAuthObserver */ + NULL, /* GCancellable */ + &error); + g_assert_no_error (error); + g_object_unref (socket_connection); + n_messages_received = 0; + g_dbus_connection_add_filter (consumer, overflow_filter_func, (gpointer) &n_messages_received, NULL); + g_dbus_connection_start_message_processing (consumer); + + timer = g_timer_new (); + g_timer_start (timer); + + while (n_messages_received < OVERFLOW_NUM_SIGNALS && g_timer_elapsed (timer, NULL) < OVERFLOW_TIMEOUT_SEC) + g_main_context_iteration (NULL, FALSE); + + g_assert_cmpint (n_messages_sent, ==, OVERFLOW_NUM_SIGNALS); + g_assert_cmpint (n_messages_received, ==, OVERFLOW_NUM_SIGNALS); + + g_timer_destroy (timer); + g_object_unref (consumer); + g_object_unref (producer); +} +#else +static void +test_overflow (void) +{ + /* TODO: test this with e.g. GWin32InputStream/GWin32OutputStream */ +} +#endif + +/* ---------------------------------------------------------------------------------------------------- */ + + +int +main (int argc, + char *argv[]) +{ + gint ret; + GDBusNodeInfo *introspection_data = NULL; + gchar *tmpdir = NULL; + + g_test_init (&argc, &argv, NULL); + + introspection_data = g_dbus_node_info_new_for_xml (test_interface_introspection_xml, NULL); + g_assert (introspection_data != NULL); + test_interface_introspection_data = introspection_data->interfaces[0]; + + test_guid = g_dbus_generate_guid (); + + if (is_unix) + { + if (g_unix_socket_address_abstract_names_supported ()) + tmp_address = g_strdup ("unix:tmpdir=/tmp/gdbus-test-"); + else + { + tmpdir = g_dir_make_tmp ("gdbus-test-XXXXXX", NULL); + tmp_address = g_strdup_printf ("unix:tmpdir=%s", tmpdir); + } + } + else + tmp_address = g_strdup ("nonce-tcp:"); + + /* all the tests rely on a shared main loop */ + loop = g_main_loop_new (NULL, FALSE); + + g_test_add_func ("/gdbus/overflow", test_overflow); + + ret = g_test_run(); + + g_main_loop_unref (loop); + g_free (test_guid); + g_dbus_node_info_unref (introspection_data); + if (is_unix) + g_free (tmp_address); + if (tmpdir) + { + g_rmdir (tmpdir); + g_free (tmpdir); + } + + return ret; +} diff --git a/gio/tests/gdbus-peer.c b/gio/tests/gdbus-peer.c index 152c588..d85e948 100644 --- a/gio/tests/gdbus-peer.c +++ b/gio/tests/gdbus-peer.c @@ -39,7 +39,6 @@ #include #include -/* used in test_overflow */ #ifdef G_OS_UNIX #include #include @@ -1394,129 +1393,6 @@ test_credentials (void) /* ---------------------------------------------------------------------------------------------------- */ -#ifdef G_OS_UNIX - -/* Chosen to be big enough to overflow the socket buffer */ -#define OVERFLOW_NUM_SIGNALS 5000 -#define OVERFLOW_TIMEOUT_SEC 10 - -static GDBusMessage * -overflow_filter_func (GDBusConnection *connection, - GDBusMessage *message, - gboolean incoming, - gpointer user_data) -{ - volatile gint *counter = user_data; - *counter += 1; - return message; -} - -static gboolean -overflow_on_500ms_later_func (gpointer user_data) -{ - g_main_loop_quit (loop); - return FALSE; /* don't keep the idle */ -} - -static void -test_overflow (void) -{ - gint sv[2]; - gint n; - GSocket *socket; - GSocketConnection *socket_connection; - GDBusConnection *producer, *consumer; - GError *error; - GTimer *timer; - volatile gint n_messages_received; - volatile gint n_messages_sent; - - g_assert_cmpint (socketpair (AF_UNIX, SOCK_STREAM, 0, sv), ==, 0); - - error = NULL; - socket = g_socket_new_from_fd (sv[0], &error); - g_assert_no_error (error); - socket_connection = g_socket_connection_factory_create_connection (socket); - g_assert (socket_connection != NULL); - g_object_unref (socket); - producer = g_dbus_connection_new_sync (G_IO_STREAM (socket_connection), - NULL, /* guid */ - G_DBUS_CONNECTION_FLAGS_NONE, - NULL, /* GDBusAuthObserver */ - NULL, /* GCancellable */ - &error); - g_dbus_connection_set_exit_on_close (producer, TRUE); - g_assert_no_error (error); - g_object_unref (socket_connection); - n_messages_sent = 0; - g_dbus_connection_add_filter (producer, overflow_filter_func, (gpointer) &n_messages_sent, NULL); - - /* send enough data that we get an EAGAIN */ - for (n = 0; n < OVERFLOW_NUM_SIGNALS; n++) - { - error = NULL; - g_dbus_connection_emit_signal (producer, - NULL, /* destination */ - "/org/foo/Object", - "org.foo.Interface", - "Member", - g_variant_new ("(s)", "a string"), - &error); - g_assert_no_error (error); - } - - /* sleep for 0.5 sec (to allow the GDBus IO thread to fill up the - * kernel buffers) and verify that n_messages_sent < - * OVERFLOW_NUM_SIGNALS - * - * This is to verify that not all the submitted messages have been - * sent to the underlying transport. - */ - g_timeout_add (500, overflow_on_500ms_later_func, NULL); - g_main_loop_run (loop); - g_assert_cmpint (n_messages_sent, <, OVERFLOW_NUM_SIGNALS); - - /* now suck it all out as a client, and add it up */ - socket = g_socket_new_from_fd (sv[1], &error); - g_assert_no_error (error); - socket_connection = g_socket_connection_factory_create_connection (socket); - g_assert (socket_connection != NULL); - g_object_unref (socket); - consumer = g_dbus_connection_new_sync (G_IO_STREAM (socket_connection), - NULL, /* guid */ - G_DBUS_CONNECTION_FLAGS_DELAY_MESSAGE_PROCESSING, - NULL, /* GDBusAuthObserver */ - NULL, /* GCancellable */ - &error); - g_assert_no_error (error); - g_object_unref (socket_connection); - n_messages_received = 0; - g_dbus_connection_add_filter (consumer, overflow_filter_func, (gpointer) &n_messages_received, NULL); - g_dbus_connection_start_message_processing (consumer); - - timer = g_timer_new (); - g_timer_start (timer); - - while (n_messages_received < OVERFLOW_NUM_SIGNALS && g_timer_elapsed (timer, NULL) < OVERFLOW_TIMEOUT_SEC) - g_main_context_iteration (NULL, FALSE); - - g_assert_cmpint (n_messages_sent, ==, OVERFLOW_NUM_SIGNALS); - g_assert_cmpint (n_messages_received, ==, OVERFLOW_NUM_SIGNALS); - - g_timer_destroy (timer); - g_object_unref (consumer); - g_object_unref (producer); -} -#else -static void -test_overflow (void) -{ - /* TODO: test this with e.g. GWin32InputStream/GWin32OutputStream */ -} -#endif - -/* ---------------------------------------------------------------------------------------------------- */ - static gboolean tcp_anonymous_on_new_connection (GDBusServer *server, GDBusConnection *connection, @@ -1871,9 +1747,9 @@ main (int argc, g_test_add_func ("/gdbus/peer-to-peer", test_peer); g_test_add_func ("/gdbus/delayed-message-processing", delayed_message_processing); g_test_add_func ("/gdbus/nonce-tcp", test_nonce_tcp); + g_test_add_func ("/gdbus/tcp-anonymous", test_tcp_anonymous); g_test_add_func ("/gdbus/credentials", test_credentials); - g_test_add_func ("/gdbus/overflow", test_overflow); g_test_add_func ("/gdbus/codegen-peer-to-peer", codegen_test_peer); ret = g_test_run(); -- 2.7.4