From 618a56f2d0a95aeafa84d0f4223fe2de67979616 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 3 Feb 2009 13:57:11 -0500 Subject: [PATCH] Bug 19796: Add test-async which exercises async call path --- test/name-test/Makefile.am | 8 ++- test/name-test/run-test.sh | 3 + test/name-test/test-async.c | 148 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 157 insertions(+), 2 deletions(-) create mode 100644 test/name-test/test-async.c diff --git a/test/name-test/Makefile.am b/test/name-test/Makefile.am index 10a2536..f0f4331 100644 --- a/test/name-test/Makefile.am +++ b/test/name-test/Makefile.am @@ -16,7 +16,7 @@ if DBUS_BUILD_TESTS ## we use noinst_PROGRAMS not check_PROGRAMS for TESTS so that we ## build even when not doing "make check" -noinst_PROGRAMS=test-names test-pending-call-dispatch test-threads-init test-ids test-shutdown test-privserver test-privserver-client +noinst_PROGRAMS=test-names test-pending-call-dispatch test-async test-threads-init test-ids test-shutdown test-privserver test-privserver-client test_names_SOURCES= \ test-names.c @@ -26,10 +26,14 @@ test_names_LDFLAGS=@R_DYNAMIC_LDFLAG@ test_pending_call_dispatch_SOURCES = \ test-pending-call-dispatch.c - test_pending_call_dispatch_LDADD=$(top_builddir)/dbus/libdbus-convenience.la $(DBUS_TEST_LIBS) test_pending_call_dispatch_LDFLAGS=@R_DYNAMIC_LDFLAG@ +test_async_SOURCES = \ + test-async.c +test_async_LDADD=$(top_builddir)/dbus/libdbus-convenience.la ../libdbus-testutils.la $(DBUS_TEST_LIBS) +test_async_LDFLAGS=@R_DYNAMIC_LDFLAG@ + test_threads_init_SOURCES = \ test-threads-init.c diff --git a/test/name-test/run-test.sh b/test/name-test/run-test.sh index 3699bc9..cae41a9 100755 --- a/test/name-test/run-test.sh +++ b/test/name-test/run-test.sh @@ -39,6 +39,9 @@ ${DBUS_TOP_BUILDDIR}/libtool --mode=execute $DEBUG $DBUS_TOP_BUILDDIR/test/name- echo "running test-pending-call-dispatch" ${DBUS_TOP_BUILDDIR}/libtool --mode=execute $DEBUG $DBUS_TOP_BUILDDIR/test/name-test/test-pending-call-dispatch || die "test-pending-call-dispatch failed" +echo "running test-async" +${DBUS_TOP_BUILDDIR}/libtool --mode=execute $DEBUG $DBUS_TOP_BUILDDIR/test/name-test/test-async || die "test-async failed" + echo "running test-threads-init" ${DBUS_TOP_BUILDDIR}/libtool --mode=execute $DEBUG $DBUS_TOP_BUILDDIR/test/name-test/test-threads-init || die "test-threads-init failed" diff --git a/test/name-test/test-async.c b/test/name-test/test-async.c new file mode 100644 index 0000000..32741f1 --- /dev/null +++ b/test/name-test/test-async.c @@ -0,0 +1,148 @@ +#include +#include +#include +#include "../test-utils.h" +#define DBUS_COMPILATION +#include +#include + +#define TOTAL_REQUESTS 50000 +#define MAX_INFLIGHT_REQUESTS 200 + +typedef struct { + DBusLoop *loop; + DBusConnection *session; + unsigned int remaining_to_send; + unsigned int pending_replies_count; + DBusList *pending_replies; + + unsigned int lastchecked_remaining_to_send; + unsigned int lastchecked_pending_replies_count; +} TestData; + +static void iteration (TestData *data); + +static void +pending_notify (DBusPendingCall *pending, void *user_data) +{ + TestData *data = user_data; + + data->pending_replies_count--; + + _dbus_list_remove (&data->pending_replies, pending); + + iteration (data); +} + +static void +iteration (TestData *data) +{ + DBusMessage *reply; + char *echo = "echo"; + + if (data->remaining_to_send == 0 && data->pending_replies_count == 0) + { + _dbus_loop_quit (data->loop); + return; + } + + while (data->remaining_to_send > 0 && data->pending_replies_count < MAX_INFLIGHT_REQUESTS) { + DBusPendingCall *pending; + DBusMessage *method; + + method = dbus_message_new_method_call ("org.freedesktop.DBus.TestSuiteEchoService", + "/org/freedesktop/TestSuite", + "org.freedesktop.TestSuite", + "Echo"); + + dbus_message_append_args (method, DBUS_TYPE_STRING, &echo, NULL); + dbus_connection_send_with_reply (data->session, method, &pending, -1); + dbus_message_unref (method); + + dbus_pending_call_set_notify (pending, pending_notify, + data, NULL); + + _dbus_list_prepend (&data->pending_replies, pending); + data->remaining_to_send--; + data->pending_replies_count++; + } +} + +static void +handle_timeout_callback (DBusTimeout *timeout, + void *data) +{ + dbus_timeout_handle (timeout); +} + +static dbus_bool_t +idle_check_timed_out (void *user_data) +{ + TestData *data = user_data; + + if (data->lastchecked_remaining_to_send == data->remaining_to_send + && data->lastchecked_pending_replies_count == data->pending_replies_count) + { + fprintf (stderr, "test-async: FATAL: stuck at %d remaining, %d pending\n", + data->remaining_to_send, data->pending_replies_count); + exit (1); + } + data->lastchecked_remaining_to_send = data->remaining_to_send; + data->lastchecked_pending_replies_count = data->pending_replies_count; + return TRUE; +} + +int +main (int argc, char *argv[]) +{ + DBusConnection *conn; + DBusError error; + TestData data; + DBusLoop *loop; + DBusTimeout *idle_check; + DBusMessage *method; + + loop = _dbus_loop_new (); + + dbus_error_init (&error); + + conn = dbus_bus_get (DBUS_BUS_SESSION, &error); + test_connection_setup (loop, conn); + + data.loop = loop; + data.session = conn; + data.remaining_to_send = TOTAL_REQUESTS; + data.pending_replies_count = 0; + data.pending_replies = NULL; + data.lastchecked_remaining_to_send = 0; + data.lastchecked_pending_replies_count = 0; + + printf ("test-async: Starting\n"); + + /* Set up an idle to periodically check we're making progress; + * i.e. that we haven't lost a reply. */ + idle_check = _dbus_timeout_new (3000, + idle_check_timed_out, + &data, + NULL); + _dbus_loop_add_timeout (loop, + idle_check, + handle_timeout_callback, + &data, + NULL); + + iteration (&data); + + _dbus_loop_run (loop); + + method = dbus_message_new_method_call ("org.freedesktop.TestSuiteEchoService", + "/org/freedesktop/TestSuite", + "org.freedesktop.TestSuite", + "Exit"); + dbus_connection_send (conn, method, NULL); + dbus_message_unref (method); + + printf ("test-async: Success\n"); + fflush (stdout); + exit (0); +} -- 1.6.0.6