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_filter (DBusConnection     *connection,
00106                           DBusMessage        *message,
00107                           void               *user_data)
00108 {
00109   if (!dbus_message_is_signal (message,
00110                                DBUS_INTERFACE_ORG_FREEDESKTOP_LOCAL,
00111                                "Disconnected"))
00112     return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
00113     
00114   _dbus_verbose ("Removing client %p in disconnect handler\n",
00115                  connection);
00116   
00117   _dbus_list_remove (&clients, connection);
00118 
00119   dbus_connection_unref (connection);
00120   
00121   if (clients == NULL)
00122     {
00123       _dbus_loop_unref (client_loop);
00124       client_loop = NULL;
00125     }
00126   
00127   return DBUS_HANDLER_RESULT_HANDLED;
00128 }
00129 
00130 dbus_bool_t
00131 bus_setup_debug_client (DBusConnection *connection)
00132 {
00133   dbus_bool_t retval;  
00134 
00135   if (!dbus_connection_add_filter (connection,
00136                                    client_disconnect_filter,
00137                                    NULL, NULL))
00138     return FALSE;
00139 
00140   retval = FALSE;
00141 
00142   if (client_loop == NULL)
00143     {
00144       client_loop = _dbus_loop_new ();
00145       if (client_loop == NULL)
00146         goto out;
00147     }
00148   
00149   if (!dbus_connection_set_watch_functions (connection,
00150                                             add_client_watch,
00151                                             remove_client_watch,
00152                                             NULL,
00153                                             connection,
00154                                             NULL))
00155     goto out;
00156       
00157   if (!dbus_connection_set_timeout_functions (connection,
00158                                               add_client_timeout,
00159                                               remove_client_timeout,
00160                                               NULL,
00161                                               connection, NULL))
00162     goto out;
00163 
00164   if (!_dbus_list_append (&clients, connection))
00165     goto out;
00166   
00167   retval = TRUE;
00168   
00169  out:
00170   if (!retval)
00171     {
00172       dbus_connection_remove_filter (connection,
00173                                      client_disconnect_filter,
00174                                      NULL);
00175       
00176       dbus_connection_set_watch_functions (connection,
00177                                            NULL, NULL, NULL, NULL, NULL);
00178       dbus_connection_set_timeout_functions (connection,
00179                                              NULL, NULL, NULL, NULL, NULL);
00180 
00181       _dbus_list_remove_last (&clients, connection);
00182 
00183       if (clients == NULL)
00184         {
00185           _dbus_loop_unref (client_loop);
00186           client_loop = NULL;
00187         }
00188     }
00189       
00190   return retval;
00191 }
00192 
00193 void
00194 bus_test_clients_foreach (BusConnectionForeachFunction  function,
00195                           void                         *data)
00196 {
00197   DBusList *link;
00198   
00199   link = _dbus_list_get_first_link (&clients);
00200   while (link != NULL)
00201     {
00202       DBusConnection *connection = link->data;
00203       DBusList *next = _dbus_list_get_next_link (&clients, link);
00204 
00205       if (!(* function) (connection, data))
00206         break;
00207       
00208       link = next;
00209     }
00210 }
00211 
00212 dbus_bool_t
00213 bus_test_client_listed (DBusConnection *connection)
00214 {
00215   DBusList *link;
00216   
00217   link = _dbus_list_get_first_link (&clients);
00218   while (link != NULL)
00219     {
00220       DBusConnection *c = link->data;
00221       DBusList *next = _dbus_list_get_next_link (&clients, link);
00222 
00223       if (c == connection)
00224         return TRUE;
00225       
00226       link = next;
00227     }
00228 
00229   return FALSE;
00230 }
00231 
00232 void
00233 bus_test_run_clients_loop (dbus_bool_t block_once)
00234 {
00235   if (client_loop == NULL)
00236     return;
00237 
00238   /* dispatch before we block so pending dispatches
00239    * won't make our block return early
00240    */
00241   _dbus_loop_dispatch (client_loop);
00242   
00243   /* Do one blocking wait, since we're expecting data */
00244   if (block_once)
00245     {
00246       _dbus_verbose ("---> blocking on \"client side\"\n");
00247       _dbus_loop_iterate (client_loop, TRUE);
00248     }
00249 
00250   /* Then mop everything up */
00251   while (_dbus_loop_iterate (client_loop, FALSE))
00252     ;
00253 }
00254 
00255 void
00256 bus_test_run_bus_loop (BusContext *context,
00257                        dbus_bool_t block_once)
00258 {
00259   /* dispatch before we block so pending dispatches
00260    * won't make our block return early
00261    */
00262   _dbus_loop_dispatch (bus_context_get_loop (context));
00263   
00264   /* Do one blocking wait, since we're expecting data */
00265   if (block_once)
00266     {
00267       _dbus_verbose ("---> blocking on \"server side\"\n");
00268       _dbus_loop_iterate (bus_context_get_loop (context), TRUE);
00269     }
00270 
00271   /* Then mop everything up */
00272   while (_dbus_loop_iterate (bus_context_get_loop (context), FALSE))
00273     ;
00274 }
00275 
00276 void
00277 bus_test_run_everything (BusContext *context)
00278 {
00279   while (_dbus_loop_iterate (bus_context_get_loop (context), FALSE) ||
00280          (client_loop == NULL || _dbus_loop_iterate (client_loop, FALSE)))
00281     ;
00282 }
00283 
00284 BusContext*
00285 bus_context_new_test (const DBusString *test_data_dir,
00286                       const char       *filename)
00287 {
00288   DBusError error;
00289   DBusString config_file;
00290   DBusString relative;
00291   BusContext *context;
00292   
00293   if (!_dbus_string_init (&config_file))
00294     {
00295       _dbus_warn ("No memory\n");
00296       return NULL;
00297     }
00298 
00299   if (!_dbus_string_copy (test_data_dir, 0,
00300                           &config_file, 0))
00301     {
00302       _dbus_warn ("No memory\n");
00303       _dbus_string_free (&config_file);
00304       return NULL;
00305     }
00306 
00307   _dbus_string_init_const (&relative, filename);
00308 
00309   if (!_dbus_concat_dir_and_file (&config_file, &relative))
00310     {
00311       _dbus_warn ("No memory\n");
00312       _dbus_string_free (&config_file);
00313       return NULL;
00314     }
00315   
00316   dbus_error_init (&error);
00317   context = bus_context_new (&config_file, FALSE, -1, -1, &error);
00318   if (context == NULL)
00319     {
00320       _DBUS_ASSERT_ERROR_IS_SET (&error);
00321       
00322       _dbus_warn ("Failed to create debug bus context from configuration file %s: %s\n",
00323                   filename, error.message);
00324 
00325       dbus_error_free (&error);
00326       
00327       _dbus_string_free (&config_file);
00328       
00329       return NULL;
00330     }
00331 
00332   _dbus_string_free (&config_file);
00333   
00334   return context;
00335 }
00336 
00337 #endif

Generated on Mon Sep 29 21:31:02 2003 for D-BUS by doxygen1.2.15