Main Page   Modules   Data Structures   File List   Data Fields   Related Pages  

test.c

00001 /* -*- mode: C; c-file-style: "gnu" -*- */
00002 /* test.c  unit test routines
00003  *
00004  * Copyright (C) 2003 Red Hat, Inc.
00005  *
00006  * Licensed under the Academic Free License version 1.2
00007  * 
00008  * This program is free software; you can redistribute it and/or modify
00009  * it under the terms of the GNU General Public License as published by
00010  * the Free Software Foundation; either version 2 of the License, or
00011  * (at your option) any later version.
00012  *
00013  * This program is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016  * GNU General Public License for more details.
00017  * 
00018  * You should have received a copy of the GNU General Public License
00019  * along with this program; if not, write to the Free Software
00020  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00021  *
00022  */
00023 
00024 #include <config.h>
00025 
00026 #ifdef DBUS_BUILD_TESTS
00027 #include "test.h"
00028 #include <dbus/dbus-internals.h>
00029 #include <dbus/dbus-list.h>
00030 
00031 /* The "debug client" watch/timeout handlers don't dispatch messages,
00032  * as we manually pull them in order to verify them. This is why they
00033  * are different from the real handlers in connection.c
00034  */
00035 static DBusList *clients = NULL;
00036 static DBusLoop *client_loop = NULL;
00037 
00038 static dbus_bool_t
00039 client_watch_callback (DBusWatch     *watch,
00040                        unsigned int   condition,
00041                        void          *data)
00042 {
00043   /* FIXME this can be done in dbus-mainloop.c
00044    * if the code in activation.c for the babysitter
00045    * watch handler is fixed.
00046    */
00047  
00048   return dbus_watch_handle (watch, condition);
00049 }
00050 
00051 static dbus_bool_t
00052 add_client_watch (DBusWatch      *watch,
00053                   void           *data)
00054 {
00055   DBusConnection *connection = data;
00056   
00057   return _dbus_loop_add_watch (client_loop,
00058                                watch, client_watch_callback, connection,
00059                                NULL);
00060 }
00061 
00062 static void
00063 remove_client_watch (DBusWatch      *watch,
00064                      void           *data)
00065 {
00066   DBusConnection *connection = data;
00067   
00068   _dbus_loop_remove_watch (client_loop,
00069                            watch, client_watch_callback, connection);
00070 }
00071 
00072 static void
00073 client_timeout_callback (DBusTimeout   *timeout,
00074                          void          *data)
00075 {
00076   DBusConnection *connection = data;
00077 
00078   dbus_connection_ref (connection);
00079 
00080   /* can return FALSE on OOM but we just let it fire again later */
00081   dbus_timeout_handle (timeout);
00082 
00083   dbus_connection_unref (connection);
00084 }
00085 
00086 static dbus_bool_t
00087 add_client_timeout (DBusTimeout    *timeout,
00088                     void           *data)
00089 {
00090   DBusConnection *connection = data;
00091   
00092   return _dbus_loop_add_timeout (client_loop, timeout, client_timeout_callback, connection, NULL);
00093 }
00094 
00095 static void
00096 remove_client_timeout (DBusTimeout    *timeout,
00097                        void           *data)
00098 {
00099   DBusConnection *connection = data;
00100   
00101   _dbus_loop_remove_timeout (client_loop, timeout, client_timeout_callback, connection);
00102 }
00103 
00104 static DBusHandlerResult
00105 client_disconnect_handler (DBusMessageHandler *handler,
00106                            DBusConnection     *connection,
00107                            DBusMessage        *message,
00108                            void               *user_data)
00109 {
00110   _dbus_verbose ("Removing client %p in disconnect handler\n",
00111                  connection);
00112   
00113   _dbus_list_remove (&clients, connection);
00114 
00115   dbus_connection_unref (connection);
00116   
00117   if (clients == NULL)
00118     {
00119       _dbus_loop_unref (client_loop);
00120       client_loop = NULL;
00121     }
00122   
00123   return DBUS_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
00124 }
00125 
00126 static dbus_int32_t handler_slot = -1;
00127 
00128 static void
00129 free_handler (void *data)
00130 {
00131   DBusMessageHandler *handler = data;
00132 
00133   dbus_message_handler_unref (handler);
00134   dbus_connection_free_data_slot (&handler_slot);
00135 }
00136 
00137 dbus_bool_t
00138 bus_setup_debug_client (DBusConnection *connection)
00139 {
00140   DBusMessageHandler *disconnect_handler;
00141   const char *to_handle[] = { DBUS_MESSAGE_LOCAL_DISCONNECT };
00142   dbus_bool_t retval;
00143   
00144   disconnect_handler = dbus_message_handler_new (client_disconnect_handler,
00145                                                  NULL, NULL);
00146 
00147   if (disconnect_handler == NULL)
00148     return FALSE;
00149 
00150   if (!dbus_connection_register_handler (connection,
00151                                          disconnect_handler,
00152                                          to_handle,
00153                                          _DBUS_N_ELEMENTS (to_handle)))
00154     {
00155       dbus_message_handler_unref (disconnect_handler);
00156       return FALSE;
00157     }
00158 
00159   retval = FALSE;
00160 
00161   if (client_loop == NULL)
00162     {
00163       client_loop = _dbus_loop_new ();
00164       if (client_loop == NULL)
00165         goto out;
00166     }
00167   
00168   if (!dbus_connection_set_watch_functions (connection,
00169                                             add_client_watch,
00170                                             remove_client_watch,
00171                                             NULL,
00172                                             connection,
00173                                             NULL))
00174     goto out;
00175       
00176   if (!dbus_connection_set_timeout_functions (connection,
00177                                               add_client_timeout,
00178                                               remove_client_timeout,
00179                                               NULL,
00180                                               connection, NULL))
00181     goto out;
00182 
00183   if (!_dbus_list_append (&clients, connection))
00184     goto out;
00185 
00186   if (!dbus_connection_allocate_data_slot (&handler_slot))
00187     goto out;
00188 
00189   /* Set up handler to be destroyed */  
00190   if (!dbus_connection_set_data (connection, handler_slot,
00191                                  disconnect_handler,
00192                                  free_handler))
00193     {
00194       dbus_connection_free_data_slot (&handler_slot);
00195       goto out;
00196     }
00197   
00198   retval = TRUE;
00199   
00200  out:
00201   if (!retval)
00202     {
00203       dbus_message_handler_unref (disconnect_handler); /* unregisters it */
00204       
00205       dbus_connection_set_watch_functions (connection,
00206                                            NULL, NULL, NULL, NULL, NULL);
00207       dbus_connection_set_timeout_functions (connection,
00208                                              NULL, NULL, NULL, NULL, NULL);
00209 
00210       _dbus_list_remove_last (&clients, connection);
00211 
00212       if (clients == NULL)
00213         {
00214           _dbus_loop_unref (client_loop);
00215           client_loop = NULL;
00216         }
00217     }
00218       
00219   return retval;
00220 }
00221 
00222 void
00223 bus_test_clients_foreach (BusConnectionForeachFunction  function,
00224                           void                         *data)
00225 {
00226   DBusList *link;
00227   
00228   link = _dbus_list_get_first_link (&clients);
00229   while (link != NULL)
00230     {
00231       DBusConnection *connection = link->data;
00232       DBusList *next = _dbus_list_get_next_link (&clients, link);
00233 
00234       if (!(* function) (connection, data))
00235         break;
00236       
00237       link = next;
00238     }
00239 }
00240 
00241 dbus_bool_t
00242 bus_test_client_listed (DBusConnection *connection)
00243 {
00244   DBusList *link;
00245   
00246   link = _dbus_list_get_first_link (&clients);
00247   while (link != NULL)
00248     {
00249       DBusConnection *c = link->data;
00250       DBusList *next = _dbus_list_get_next_link (&clients, link);
00251 
00252       if (c == connection)
00253         return TRUE;
00254       
00255       link = next;
00256     }
00257 
00258   return FALSE;
00259 }
00260 
00261 void
00262 bus_test_run_clients_loop (dbus_bool_t block_once)
00263 {
00264   if (client_loop == NULL)
00265     return;
00266 
00267   /* dispatch before we block so pending dispatches
00268    * won't make our block return early
00269    */
00270   _dbus_loop_dispatch (client_loop);
00271   
00272   /* Do one blocking wait, since we're expecting data */
00273   if (block_once)
00274     {
00275       _dbus_verbose ("---> blocking on \"client side\"\n");
00276       _dbus_loop_iterate (client_loop, TRUE);
00277     }
00278 
00279   /* Then mop everything up */
00280   while (_dbus_loop_iterate (client_loop, FALSE))
00281     ;
00282 }
00283 
00284 void
00285 bus_test_run_bus_loop (BusContext *context,
00286                        dbus_bool_t block_once)
00287 {
00288   /* dispatch before we block so pending dispatches
00289    * won't make our block return early
00290    */
00291   _dbus_loop_dispatch (bus_context_get_loop (context));
00292   
00293   /* Do one blocking wait, since we're expecting data */
00294   if (block_once)
00295     {
00296       _dbus_verbose ("---> blocking on \"server side\"\n");
00297       _dbus_loop_iterate (bus_context_get_loop (context), TRUE);
00298     }
00299 
00300   /* Then mop everything up */
00301   while (_dbus_loop_iterate (bus_context_get_loop (context), FALSE))
00302     ;
00303 }
00304 
00305 void
00306 bus_test_run_everything (BusContext *context)
00307 {
00308   while (_dbus_loop_iterate (bus_context_get_loop (context), FALSE) ||
00309          (client_loop == NULL || _dbus_loop_iterate (client_loop, FALSE)))
00310     ;
00311 }
00312 
00313 BusContext*
00314 bus_context_new_test (const DBusString *test_data_dir,
00315                       const char       *filename)
00316 {
00317   DBusError error;
00318   DBusString config_file;
00319   DBusString relative;
00320   BusContext *context;
00321   
00322   if (!_dbus_string_init (&config_file))
00323     {
00324       _dbus_warn ("No memory\n");
00325       return NULL;
00326     }
00327 
00328   if (!_dbus_string_copy (test_data_dir, 0,
00329                           &config_file, 0))
00330     {
00331       _dbus_warn ("No memory\n");
00332       _dbus_string_free (&config_file);
00333       return NULL;
00334     }
00335 
00336   _dbus_string_init_const (&relative, filename);
00337 
00338   if (!_dbus_concat_dir_and_file (&config_file, &relative))
00339     {
00340       _dbus_warn ("No memory\n");
00341       _dbus_string_free (&config_file);
00342       return NULL;
00343     }
00344   
00345   dbus_error_init (&error);
00346   context = bus_context_new (&config_file, FALSE, -1, -1, &error);
00347   if (context == NULL)
00348     {
00349       _DBUS_ASSERT_ERROR_IS_SET (&error);
00350       
00351       _dbus_warn ("Failed to create debug bus context from configuration file %s: %s\n",
00352                   filename, error.message);
00353 
00354       dbus_error_free (&error);
00355       
00356       _dbus_string_free (&config_file);
00357       
00358       return NULL;
00359     }
00360 
00361   _dbus_string_free (&config_file);
00362   
00363   return context;
00364 }
00365 
00366 #endif

Generated on Wed Oct 22 14:05:06 2003 for D-BUS by doxygen1.3-rc3