diff options
Diffstat (limited to 'bus')
-rw-r--r-- | bus/connection.c | 2 | ||||
-rw-r--r-- | bus/dispatch.c | 153 | ||||
-rw-r--r-- | bus/test.c | 87 | ||||
-rw-r--r-- | bus/utils.c | 6 |
4 files changed, 222 insertions, 26 deletions
diff --git a/bus/connection.c b/bus/connection.c index 700ca46d..1c699c6f 100644 --- a/bus/connection.c +++ b/bus/connection.c @@ -56,8 +56,6 @@ bus_connection_disconnected (DBusConnection *connection) { BusConnectionData *d; BusService *service; - - _dbus_warn ("Disconnected\n"); d = BUS_CONNECTION_DATA (connection); _dbus_assert (d != NULL); diff --git a/bus/dispatch.c b/bus/dispatch.c index 35ea5549..ac2fb15b 100644 --- a/bus/dispatch.c +++ b/bus/dispatch.c @@ -377,6 +377,10 @@ bus_dispatch_remove_connection (DBusConnection *connection) #ifdef DBUS_BUILD_TESTS +typedef dbus_bool_t (* Check1Func) (BusContext *context); +typedef dbus_bool_t (* Check2Func) (BusContext *context, + DBusConnection *connection); + static void flush_bus (BusContext *context) { @@ -384,6 +388,15 @@ flush_bus (BusContext *context) ; } +static void +kill_client_connection (DBusConnection *connection) +{ + /* kick in the disconnect handler that unrefs the connection */ + dbus_connection_disconnect (connection); + while (dbus_connection_dispatch_message (connection)) + ; +} + /* returns TRUE if the correct thing happens, * but the correct thing may include OOM errors. */ @@ -393,6 +406,10 @@ check_hello_message (BusContext *context, { DBusMessage *message; dbus_int32_t serial; + dbus_bool_t retval; + DBusError error; + + dbus_error_init (&error); message = dbus_message_new (DBUS_SERVICE_DBUS, DBUS_MESSAGE_HELLO); @@ -404,25 +421,150 @@ check_hello_message (BusContext *context, return TRUE; dbus_message_unref (message); + message = NULL; flush_bus (context); + if (!dbus_connection_get_is_connected (connection)) + { + _dbus_verbose ("connection was disconnected\n"); + return TRUE; + } + + retval = FALSE; + message = dbus_connection_pop_message (connection); if (message == NULL) { _dbus_warn ("Did not receive a reply to %s %d on %p\n", DBUS_MESSAGE_HELLO, serial, connection); - return FALSE; + goto out; } _dbus_verbose ("Received %s on %p\n", dbus_message_get_name (message), connection); + + if (dbus_message_get_is_error (message)) + { + if (dbus_message_name_is (message, + DBUS_ERROR_NO_MEMORY)) + { + ; /* good, this is a valid response */ + } + else + { + _dbus_warn ("Did not expect error %s\n", + dbus_message_get_name (message)); + goto out; + } + } + else + { + char *str; + + if (dbus_message_name_is (message, + DBUS_MESSAGE_HELLO)) + { + ; /* good, expected */ + } + else + { + _dbus_warn ("Did not expect reply %s\n", + dbus_message_get_name (message)); + goto out; + } + + if (!dbus_message_get_args (message, &error, + DBUS_TYPE_STRING, &str, + DBUS_TYPE_INVALID)) + { + _dbus_warn ("Did not get the expected single string argument\n"); + goto out; + } + + _dbus_verbose ("Got hello name: %s\n", str); + dbus_free (str); + } + + retval = TRUE; - dbus_message_unref (message); + out: + if (message) + dbus_message_unref (message); + return retval; +} + +/* returns TRUE if the correct thing happens, + * but the correct thing may include OOM errors. + */ +static dbus_bool_t +check_hello_connection (BusContext *context) +{ + DBusConnection *connection; + DBusResultCode result; + + result = DBUS_RESULT_SUCCESS; + connection = dbus_connection_open ("debug-pipe:name=test-server", &result); + if (connection == NULL) + { + _dbus_assert (result != DBUS_RESULT_SUCCESS); + return TRUE; + } + + if (!bus_setup_debug_client (connection)) + { + dbus_connection_unref (connection); + return TRUE; + } + + if (!check_hello_message (context, connection)) + return FALSE; + + kill_client_connection (connection); + return TRUE; } +static void +check1_try_iterations (BusContext *context, + const char *description, + Check1Func func) +{ + int approx_mallocs; + + /* Run once to see about how many mallocs are involved */ + + _dbus_set_fail_alloc_counter (_DBUS_INT_MAX); + + if (! (*func) (context)) + _dbus_assert_not_reached ("test failed"); + + approx_mallocs = _DBUS_INT_MAX - _dbus_get_fail_alloc_counter (); + + _dbus_verbose ("=================\n%s: about %d mallocs total\n=================\n", + description, approx_mallocs); + + approx_mallocs += 10; /* fudge factor */ + + /* Now run failing each malloc */ + + while (approx_mallocs >= 0) + { + _dbus_set_fail_alloc_counter (approx_mallocs); + + _dbus_verbose ("\n===\n %s: (will fail malloc %d)\n===\n", + description, approx_mallocs); + + if (! (*func) (context)) + _dbus_assert_not_reached ("test failed"); + + approx_mallocs -= 1; + } + + _dbus_set_fail_alloc_counter (_DBUS_INT_MAX); +} + dbus_bool_t bus_dispatch_test (const DBusString *test_data_dir) { @@ -440,6 +582,9 @@ bus_dispatch_test (const DBusString *test_data_dir) &error); if (context == NULL) _dbus_assert_not_reached ("could not alloc context"); + + check1_try_iterations (context, "create_and_hello", + check_hello_connection); foo = dbus_connection_open ("debug-pipe:name=test-server", &result); if (foo == NULL) @@ -464,6 +609,10 @@ bus_dispatch_test (const DBusString *test_data_dir) _dbus_assert_not_reached ("hello message failed"); if (!check_hello_message (context, baz)) _dbus_assert_not_reached ("hello message failed"); + + dbus_connection_unref (foo); + dbus_connection_unref (bar); + dbus_connection_unref (baz); return TRUE; } @@ -26,6 +26,7 @@ #ifdef DBUS_BUILD_TESTS #include "test.h" #include "loop.h" +#include <dbus/dbus-internals.h> /* The "debug client" watch/timeout handlers don't dispatch messages, * as we manually pull them in order to verify them. This is why they @@ -33,7 +34,7 @@ */ static void -connection_watch_callback (DBusWatch *watch, +client_watch_callback (DBusWatch *watch, unsigned int condition, void *data) { @@ -47,22 +48,22 @@ connection_watch_callback (DBusWatch *watch, } static dbus_bool_t -add_connection_watch (DBusWatch *watch, +add_client_watch (DBusWatch *watch, DBusConnection *connection) { - return bus_loop_add_watch (watch, connection_watch_callback, connection, + return bus_loop_add_watch (watch, client_watch_callback, connection, NULL); } static void -remove_connection_watch (DBusWatch *watch, +remove_client_watch (DBusWatch *watch, DBusConnection *connection) { - bus_loop_remove_watch (watch, connection_watch_callback, connection); + bus_loop_remove_watch (watch, client_watch_callback, connection); } static void -connection_timeout_callback (DBusTimeout *timeout, +client_timeout_callback (DBusTimeout *timeout, void *data) { DBusConnection *connection = data; @@ -75,43 +76,85 @@ connection_timeout_callback (DBusTimeout *timeout, } static dbus_bool_t -add_connection_timeout (DBusTimeout *timeout, +add_client_timeout (DBusTimeout *timeout, DBusConnection *connection) { - return bus_loop_add_timeout (timeout, connection_timeout_callback, connection, NULL); + return bus_loop_add_timeout (timeout, client_timeout_callback, connection, NULL); } static void -remove_connection_timeout (DBusTimeout *timeout, +remove_client_timeout (DBusTimeout *timeout, DBusConnection *connection) { - bus_loop_remove_timeout (timeout, connection_timeout_callback, connection); + bus_loop_remove_timeout (timeout, client_timeout_callback, connection); } +static DBusHandlerResult +client_disconnect_handler (DBusMessageHandler *handler, + DBusConnection *connection, + DBusMessage *message, + void *user_data) +{ + dbus_connection_unref (connection); + + return DBUS_HANDLER_RESULT_ALLOW_MORE_HANDLERS; +} dbus_bool_t bus_setup_debug_client (DBusConnection *connection) { + DBusMessageHandler *disconnect_handler; + const char *to_handle[] = { DBUS_MESSAGE_LOCAL_DISCONNECT }; + dbus_bool_t retval; - if (!dbus_connection_set_watch_functions (connection, - (DBusAddWatchFunction) add_connection_watch, - (DBusRemoveWatchFunction) remove_connection_watch, - connection, - NULL)) + disconnect_handler = dbus_message_handler_new (client_disconnect_handler, + NULL, NULL); + + if (disconnect_handler == NULL) + return FALSE; + + if (!dbus_connection_register_handler (connection, + disconnect_handler, + to_handle, + _DBUS_N_ELEMENTS (to_handle))) { - dbus_connection_disconnect (connection); + dbus_message_handler_unref (disconnect_handler); return FALSE; } + + retval = FALSE; + if (!dbus_connection_set_watch_functions (connection, + (DBusAddWatchFunction) add_client_watch, + (DBusRemoveWatchFunction) remove_client_watch, + connection, + NULL)) + goto out; + if (!dbus_connection_set_timeout_functions (connection, - (DBusAddTimeoutFunction) add_connection_timeout, - (DBusRemoveTimeoutFunction) remove_connection_timeout, + (DBusAddTimeoutFunction) add_client_timeout, + (DBusRemoveTimeoutFunction) remove_client_timeout, connection, NULL)) + goto out; + + retval = TRUE; + + out: + if (!retval) { - dbus_connection_disconnect (connection); - return FALSE; + dbus_connection_unregister_handler (connection, + disconnect_handler, + to_handle, + _DBUS_N_ELEMENTS (to_handle)); + + dbus_connection_set_watch_functions (connection, + NULL, NULL, NULL, NULL); + dbus_connection_set_timeout_functions (connection, + NULL, NULL, NULL, NULL); } - - return TRUE; + + dbus_message_handler_unref (disconnect_handler); + + return retval; } #endif diff --git a/bus/utils.c b/bus/utils.c index 8b964cc4..fadfc140 100644 --- a/bus/utils.c +++ b/bus/utils.c @@ -22,6 +22,7 @@ * */ +#include <config.h> #include "utils.h" #include <dbus/dbus-sysdeps.h> @@ -30,6 +31,11 @@ const char bus_no_memory_message[] = "Memory allocation failure in message bus"; void bus_wait_for_memory (void) { +#ifdef DBUS_BUILD_TESTS + /* make tests go fast */ + _dbus_sleep_milliseconds (10); +#else _dbus_sleep_milliseconds (500); +#endif } |