Commit f05f87a8 authored by Havoc Pennington's avatar Havoc Pennington

2003-03-15 Havoc Pennington <hp@pobox.com>

	* bus/dispatch.c (bus_dispatch_test): OK, now finally actually
	write useful test code, after all that futzing around ;-)

	Test does not yet pass because we can't handle OOM in
	_dbus_transport_messages_pending (basically,
	dbus_connection_preallocate_send() does not prealloc the write
	watch). To fix this, I think we need to add new stuff to
	set_watch_functions, namely a SetEnabled function so we can alloc
	the watch earlier, then enable it later.

	* dbus/Makefile.am (libdbus_convenience_la_SOURCES): move
	dbus-memory.c to the convenience lib

	* bus/test.c: rename some static functions to keep them clearly
	distinct from stuff in connection.c. Handle client disconnection.
parent 169238e9
2003-03-15 Havoc Pennington <hp@pobox.com>
* bus/dispatch.c (bus_dispatch_test): OK, now finally actually
write useful test code, after all that futzing around ;-)
Test does not yet pass because we can't handle OOM in
_dbus_transport_messages_pending (basically,
dbus_connection_preallocate_send() does not prealloc the write
watch). To fix this, I think we need to add new stuff to
set_watch_functions, namely a SetEnabled function so we can alloc
the watch earlier, then enable it later.
* dbus/Makefile.am (libdbus_convenience_la_SOURCES): move
dbus-memory.c to the convenience lib
* bus/test.c: rename some static functions to keep them clearly
distinct from stuff in connection.c. Handle client disconnection.
2003-03-14 Havoc Pennington <hp@pobox.com> 2003-03-14 Havoc Pennington <hp@pobox.com>
* bus/dispatch.c (bus_dispatch_test): do test using debug-pipe * bus/dispatch.c (bus_dispatch_test): do test using debug-pipe
......
...@@ -56,8 +56,6 @@ bus_connection_disconnected (DBusConnection *connection) ...@@ -56,8 +56,6 @@ bus_connection_disconnected (DBusConnection *connection)
{ {
BusConnectionData *d; BusConnectionData *d;
BusService *service; BusService *service;
_dbus_warn ("Disconnected\n");
d = BUS_CONNECTION_DATA (connection); d = BUS_CONNECTION_DATA (connection);
_dbus_assert (d != NULL); _dbus_assert (d != NULL);
......
...@@ -377,6 +377,10 @@ bus_dispatch_remove_connection (DBusConnection *connection) ...@@ -377,6 +377,10 @@ bus_dispatch_remove_connection (DBusConnection *connection)
#ifdef DBUS_BUILD_TESTS #ifdef DBUS_BUILD_TESTS
typedef dbus_bool_t (* Check1Func) (BusContext *context);
typedef dbus_bool_t (* Check2Func) (BusContext *context,
DBusConnection *connection);
static void static void
flush_bus (BusContext *context) flush_bus (BusContext *context)
{ {
...@@ -384,6 +388,15 @@ 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, /* returns TRUE if the correct thing happens,
* but the correct thing may include OOM errors. * but the correct thing may include OOM errors.
*/ */
...@@ -393,6 +406,10 @@ check_hello_message (BusContext *context, ...@@ -393,6 +406,10 @@ check_hello_message (BusContext *context,
{ {
DBusMessage *message; DBusMessage *message;
dbus_int32_t serial; dbus_int32_t serial;
dbus_bool_t retval;
DBusError error;
dbus_error_init (&error);
message = dbus_message_new (DBUS_SERVICE_DBUS, message = dbus_message_new (DBUS_SERVICE_DBUS,
DBUS_MESSAGE_HELLO); DBUS_MESSAGE_HELLO);
...@@ -404,25 +421,150 @@ check_hello_message (BusContext *context, ...@@ -404,25 +421,150 @@ check_hello_message (BusContext *context,
return TRUE; return TRUE;
dbus_message_unref (message); dbus_message_unref (message);
message = NULL;
flush_bus (context); 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); message = dbus_connection_pop_message (connection);
if (message == NULL) if (message == NULL)
{ {
_dbus_warn ("Did not receive a reply to %s %d on %p\n", _dbus_warn ("Did not receive a reply to %s %d on %p\n",
DBUS_MESSAGE_HELLO, serial, connection); DBUS_MESSAGE_HELLO, serial, connection);
return FALSE; goto out;
} }
_dbus_verbose ("Received %s on %p\n", _dbus_verbose ("Received %s on %p\n",
dbus_message_get_name (message), connection); 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; 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 dbus_bool_t
bus_dispatch_test (const DBusString *test_data_dir) bus_dispatch_test (const DBusString *test_data_dir)
{ {
...@@ -440,6 +582,9 @@ bus_dispatch_test (const DBusString *test_data_dir) ...@@ -440,6 +582,9 @@ bus_dispatch_test (const DBusString *test_data_dir)
&error); &error);
if (context == NULL) if (context == NULL)
_dbus_assert_not_reached ("could not alloc context"); _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); foo = dbus_connection_open ("debug-pipe:name=test-server", &result);
if (foo == NULL) if (foo == NULL)
...@@ -464,6 +609,10 @@ bus_dispatch_test (const DBusString *test_data_dir) ...@@ -464,6 +609,10 @@ bus_dispatch_test (const DBusString *test_data_dir)
_dbus_assert_not_reached ("hello message failed"); _dbus_assert_not_reached ("hello message failed");
if (!check_hello_message (context, baz)) if (!check_hello_message (context, baz))
_dbus_assert_not_reached ("hello message failed"); _dbus_assert_not_reached ("hello message failed");
dbus_connection_unref (foo);
dbus_connection_unref (bar);
dbus_connection_unref (baz);
return TRUE; return TRUE;
} }
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#ifdef DBUS_BUILD_TESTS #ifdef DBUS_BUILD_TESTS
#include "test.h" #include "test.h"
#include "loop.h" #include "loop.h"
#include <dbus/dbus-internals.h>
/* The "debug client" watch/timeout handlers don't dispatch messages, /* The "debug client" watch/timeout handlers don't dispatch messages,
* as we manually pull them in order to verify them. This is why they * as we manually pull them in order to verify them. This is why they
...@@ -33,7 +34,7 @@ ...@@ -33,7 +34,7 @@
*/ */
static void static void
connection_watch_callback (DBusWatch *watch, client_watch_callback (DBusWatch *watch,
unsigned int condition, unsigned int condition,
void *data) void *data)
{ {
...@@ -47,22 +48,22 @@ connection_watch_callback (DBusWatch *watch, ...@@ -47,22 +48,22 @@ connection_watch_callback (DBusWatch *watch,
} }
static dbus_bool_t static dbus_bool_t
add_connection_watch (DBusWatch *watch, add_client_watch (DBusWatch *watch,
DBusConnection *connection) DBusConnection *connection)
{ {
return bus_loop_add_watch (watch, connection_watch_callback, connection, return bus_loop_add_watch (watch, client_watch_callback, connection,
NULL); NULL);
} }
static void static void
remove_connection_watch (DBusWatch *watch, remove_client_watch (DBusWatch *watch,
DBusConnection *connection) DBusConnection *connection)
{ {
bus_loop_remove_watch (watch, connection_watch_callback, connection); bus_loop_remove_watch (watch, client_watch_callback, connection);
} }
static void static void
connection_timeout_callback (DBusTimeout *timeout, client_timeout_callback (DBusTimeout *timeout,
void *data) void *data)
{ {
DBusConnection *connection = data; DBusConnection *connection = data;
...@@ -75,43 +76,85 @@ connection_timeout_callback (DBusTimeout *timeout, ...@@ -75,43 +76,85 @@ connection_timeout_callback (DBusTimeout *timeout,
} }
static dbus_bool_t static dbus_bool_t
add_connection_timeout (DBusTimeout *timeout, add_client_timeout (DBusTimeout *timeout,
DBusConnection *connection) 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 static void
remove_connection_timeout (DBusTimeout *timeout, remove_client_timeout (DBusTimeout *timeout,
DBusConnection *connection) 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 dbus_bool_t
bus_setup_debug_client (DBusConnection *connection) 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, disconnect_handler = dbus_message_handler_new (client_disconnect_handler,
(DBusAddWatchFunction) add_connection_watch, NULL, NULL);
(DBusRemoveWatchFunction) remove_connection_watch,
connection, if (disconnect_handler == NULL)
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; 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, if (!dbus_connection_set_timeout_functions (connection,
(DBusAddTimeoutFunction) add_connection_timeout, (DBusAddTimeoutFunction) add_client_timeout,
(DBusRemoveTimeoutFunction) remove_connection_timeout, (DBusRemoveTimeoutFunction) remove_client_timeout,
connection, NULL)) connection, NULL))
goto out;
retval = TRUE;
out:
if (!retval)
{ {
dbus_connection_disconnect (connection); dbus_connection_unregister_handler (connection,
return FALSE; 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 #endif
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
* *
*/ */
#include <config.h>
#include "utils.h" #include "utils.h"
#include <dbus/dbus-sysdeps.h> #include <dbus/dbus-sysdeps.h>
...@@ -30,6 +31,11 @@ const char bus_no_memory_message[] = "Memory allocation failure in message bus"; ...@@ -30,6 +31,11 @@ const char bus_no_memory_message[] = "Memory allocation failure in message bus";
void void
bus_wait_for_memory (void) bus_wait_for_memory (void)
{ {
#ifdef DBUS_BUILD_TESTS
/* make tests go fast */
_dbus_sleep_milliseconds (10);
#else
_dbus_sleep_milliseconds (500); _dbus_sleep_milliseconds (500);
#endif
} }
...@@ -136,6 +136,8 @@ AC_CHECK_LIB(nsl,gethostbyname) ...@@ -136,6 +136,8 @@ AC_CHECK_LIB(nsl,gethostbyname)
AC_CHECK_FUNCS(vsnprintf vasprintf nanosleep usleep poll setenv socketpair) AC_CHECK_FUNCS(vsnprintf vasprintf nanosleep usleep poll setenv socketpair)
AC_CHECK_HEADERS(execinfo.h, [AC_CHECK_FUNCS(backtrace)])
AC_CACHE_CHECK([for posix getpwnam_r], AC_CACHE_CHECK([for posix getpwnam_r],
ac_cv_func_posix_getpwnam_r, ac_cv_func_posix_getpwnam_r,
[AC_TRY_RUN([ [AC_TRY_RUN([
......
...@@ -34,7 +34,6 @@ libdbus_1_la_SOURCES= \ ...@@ -34,7 +34,6 @@ libdbus_1_la_SOURCES= \
dbus-errors.c \ dbus-errors.c \
dbus-keyring.c \ dbus-keyring.c \
dbus-keyring.h \ dbus-keyring.h \
dbus-memory.c \
dbus-message.c \ dbus-message.c \
dbus-message-handler.c \ dbus-message-handler.c \
dbus-message-internal.h \ dbus-message-internal.h \
...@@ -88,6 +87,7 @@ libdbus_convenience_la_SOURCES= \ ...@@ -88,6 +87,7 @@ libdbus_convenience_la_SOURCES= \
dbus-list.h \ dbus-list.h \
dbus-marshal.c \ dbus-marshal.c \
dbus-marshal.h \ dbus-marshal.h \
dbus-memory.c \
dbus-mempool.c \ dbus-mempool.c \
dbus-mempool.h \ dbus-mempool.h \
dbus-message-builder.c \ dbus-message-builder.c \
......
...@@ -256,6 +256,8 @@ dbus_malloc (size_t bytes) ...@@ -256,6 +256,8 @@ dbus_malloc (size_t bytes)
{ {
if (fail_counts != -1) if (fail_counts != -1)
_dbus_set_fail_alloc_counter (fail_counts); _dbus_set_fail_alloc_counter (fail_counts);
_dbus_verbose (" FAILING malloc of %d bytes\n", bytes);
return NULL; return NULL;
} }
...@@ -297,6 +299,8 @@ dbus_malloc0 (size_t bytes) ...@@ -297,6 +299,8 @@ dbus_malloc0 (size_t bytes)
{ {
if (fail_counts != -1) if (fail_counts != -1)
_dbus_set_fail_alloc_counter (fail_counts); _dbus_set_fail_alloc_counter (fail_counts);
_dbus_verbose (" FAILING malloc0 of %d bytes\n", bytes);
return NULL; return NULL;
} }
...@@ -340,6 +344,8 @@ dbus_realloc (void *memory, ...@@ -340,6 +344,8 @@ dbus_realloc (void *memory,
{ {
if (fail_counts != -1) if (fail_counts != -1)
_dbus_set_fail_alloc_counter (fail_counts); _dbus_set_fail_alloc_counter (fail_counts);
_dbus_verbose (" FAILING realloc of %d bytes\n", bytes);
return NULL; return NULL;
} }
......
...@@ -203,7 +203,10 @@ void* ...@@ -203,7 +203,10 @@ void*
_dbus_mem_pool_alloc (DBusMemPool *pool) _dbus_mem_pool_alloc (DBusMemPool *pool)
{ {
if (_dbus_decrement_fail_alloc_counter ()) if (_dbus_decrement_fail_alloc_counter ())
return NULL; {
_dbus_verbose (" FAILING mempool alloc\n");
return NULL;
}
if (pool->free_elements) if (pool->free_elements)
{ {
......
...@@ -628,8 +628,10 @@ _dbus_message_add_size_counter (DBusMessage *message, ...@@ -628,8 +628,10 @@ _dbus_message_add_size_counter (DBusMessage *message,
_dbus_string_get_length (&message->header) + _dbus_string_get_length (&message->header) +
_dbus_string_get_length (&message->body); _dbus_string_get_length (&message->body);
#if 0
_dbus_verbose ("message has size %ld\n", _dbus_verbose ("message has size %ld\n",
message->size_counter_delta); message->size_counter_delta);
#endif
_dbus_counter_adjust (message->size_counter, message->size_counter_delta); _dbus_counter_adjust (message->size_counter, message->size_counter_delta);
} }
...@@ -2587,13 +2589,15 @@ decode_header_data (const DBusString *data, ...@@ -2587,13 +2589,15 @@ decode_header_data (const DBusString *data,
} }
fields[FIELD_SERVICE].offset = _DBUS_ALIGN_VALUE (pos + 1, 4); fields[FIELD_SERVICE].offset = _DBUS_ALIGN_VALUE (pos + 1, 4);
#if 0
_dbus_verbose ("Found service name at offset %d\n", _dbus_verbose ("Found service name at offset %d\n",
fields[FIELD_SERVICE].offset); fields[FIELD_SERVICE].offset);
#endif
break; break;
case DBUS_HEADER_FIELD_NAME_AS_UINT32: case DBUS_HEADER_FIELD_NAME_AS_UINT32:
if (fields[FIELD_NAME].offset >= 0) if (fields[FIELD_NAME].offset >= 0)
{ {