ofdbus/dbus/bus/test.c
changeset 0 e4d67989cc36
equal deleted inserted replaced
-1:000000000000 0:e4d67989cc36
       
     1 /* -*- mode: C; c-file-style: "gnu" -*- */
       
     2 /* test.c  unit test routines
       
     3  *
       
     4  * Copyright (C) 2003 Red Hat, Inc.
       
     5  * Portion Copyright © 2008 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
       
     6  * Licensed under the Academic Free License version 2.1
       
     7  * 
       
     8  * This program is free software; you can redistribute it and/or modify
       
     9  * it under the terms of the GNU General Public License as published by
       
    10  * the Free Software Foundation; either version 2 of the License, or
       
    11  * (at your option) any later version.
       
    12  *
       
    13  * This program is distributed in the hope that it will be useful,
       
    14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
       
    16  * GNU General Public License for more details.
       
    17  * 
       
    18  * You should have received a copy of the GNU General Public License
       
    19  * along with this program; if not, write to the Free Software
       
    20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
       
    21  *
       
    22  */
       
    23 
       
    24 #ifndef __SYMBIAN32__
       
    25 #include <config.h>
       
    26 #else
       
    27 #include "config.h"
       
    28 #endif //__SYMBIAN32__
       
    29 
       
    30 #ifdef DBUS_BUILD_TESTS
       
    31 #include "test.h"
       
    32 #ifndef __SYMBIAN32__
       
    33 #include <dbus/dbus-internals.h>
       
    34 #include <dbus/dbus-list.h>
       
    35 #else
       
    36 #include "dbus-internals.h"
       
    37 #include "dbus-list.h"
       
    38 #endif //__SYMBIAN32__
       
    39 
       
    40 /* The "debug client" watch/timeout handlers don't dispatch messages,
       
    41  * as we manually pull them in order to verify them. This is why they
       
    42  * are different from the real handlers in connection.c
       
    43  */
       
    44 static DBusList *clients = NULL;
       
    45 static DBusLoop *client_loop = NULL;
       
    46 
       
    47 static dbus_bool_t
       
    48 client_watch_callback (DBusWatch     *watch,
       
    49                        unsigned int   condition,
       
    50                        void          *data)
       
    51 {
       
    52   /* FIXME this can be done in dbus-mainloop.c
       
    53    * if the code in activation.c for the babysitter
       
    54    * watch handler is fixed.
       
    55    */
       
    56  
       
    57   return dbus_watch_handle (watch, condition);
       
    58 }
       
    59 
       
    60 static dbus_bool_t
       
    61 add_client_watch (DBusWatch      *watch,
       
    62                   void           *data)
       
    63 {
       
    64   DBusConnection *connection = data;
       
    65   
       
    66   return _dbus_loop_add_watch (client_loop,
       
    67                                watch, client_watch_callback, connection,
       
    68                                NULL);
       
    69 }
       
    70 
       
    71 static void
       
    72 remove_client_watch (DBusWatch      *watch,
       
    73                      void           *data)
       
    74 {
       
    75   DBusConnection *connection = data;
       
    76   
       
    77   _dbus_loop_remove_watch (client_loop,
       
    78                            watch, client_watch_callback, connection);
       
    79 }
       
    80 
       
    81 static void
       
    82 client_timeout_callback (DBusTimeout   *timeout,
       
    83                          void          *data)
       
    84 {
       
    85   DBusConnection *connection = data;
       
    86 
       
    87   dbus_connection_ref (connection);
       
    88 
       
    89   /* can return FALSE on OOM but we just let it fire again later */
       
    90   dbus_timeout_handle (timeout);
       
    91 
       
    92   dbus_connection_unref (connection);
       
    93 }
       
    94 
       
    95 static dbus_bool_t
       
    96 add_client_timeout (DBusTimeout    *timeout,
       
    97                     void           *data)
       
    98 {
       
    99   DBusConnection *connection = data;
       
   100   
       
   101   return _dbus_loop_add_timeout (client_loop, timeout, client_timeout_callback, connection, NULL);
       
   102 }
       
   103 
       
   104 static void
       
   105 remove_client_timeout (DBusTimeout    *timeout,
       
   106                        void           *data)
       
   107 {
       
   108   DBusConnection *connection = data;
       
   109   
       
   110   _dbus_loop_remove_timeout (client_loop, timeout, client_timeout_callback, connection);
       
   111 }
       
   112 
       
   113 static DBusHandlerResult
       
   114 client_disconnect_filter (DBusConnection     *connection,
       
   115                           DBusMessage        *message,
       
   116                           void               *user_data)
       
   117 {
       
   118   if (!dbus_message_is_signal (message,
       
   119                                DBUS_INTERFACE_LOCAL,
       
   120                                "Disconnected"))
       
   121     return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
       
   122     
       
   123   _dbus_verbose ("Removing client %p in disconnect handler\n",
       
   124                  connection);
       
   125   
       
   126   _dbus_list_remove (&clients, connection);
       
   127 
       
   128   dbus_connection_unref (connection);
       
   129   
       
   130   if (clients == NULL)
       
   131     {
       
   132       _dbus_loop_unref (client_loop);
       
   133       client_loop = NULL;
       
   134     }
       
   135   
       
   136   return DBUS_HANDLER_RESULT_HANDLED;
       
   137 }
       
   138 
       
   139 dbus_bool_t
       
   140 bus_setup_debug_client (DBusConnection *connection)
       
   141 {
       
   142   dbus_bool_t retval;  
       
   143 
       
   144   if (!dbus_connection_add_filter (connection,
       
   145                                    client_disconnect_filter,
       
   146                                    NULL, NULL))
       
   147     return FALSE;
       
   148 
       
   149   retval = FALSE;
       
   150 
       
   151   if (client_loop == NULL)
       
   152     {
       
   153       client_loop = _dbus_loop_new ();
       
   154       if (client_loop == NULL)
       
   155         goto out;
       
   156     }
       
   157   
       
   158   if (!dbus_connection_set_watch_functions (connection,
       
   159                                             add_client_watch,
       
   160                                             remove_client_watch,
       
   161                                             NULL,
       
   162                                             connection,
       
   163                                             NULL))
       
   164     goto out;
       
   165       
       
   166   if (!dbus_connection_set_timeout_functions (connection,
       
   167                                               add_client_timeout,
       
   168                                               remove_client_timeout,
       
   169                                               NULL,
       
   170                                               connection, NULL))
       
   171     goto out;
       
   172 
       
   173   if (!_dbus_list_append (&clients, connection))
       
   174     goto out;
       
   175   
       
   176   retval = TRUE;
       
   177   
       
   178  out:
       
   179   if (!retval)
       
   180     {
       
   181       dbus_connection_remove_filter (connection,
       
   182                                      client_disconnect_filter,
       
   183                                      NULL);
       
   184       
       
   185       dbus_connection_set_watch_functions (connection,
       
   186                                            NULL, NULL, NULL, NULL, NULL);
       
   187       dbus_connection_set_timeout_functions (connection,
       
   188                                              NULL, NULL, NULL, NULL, NULL);
       
   189 
       
   190       _dbus_list_remove_last (&clients, connection);
       
   191 
       
   192       if (clients == NULL)
       
   193         {
       
   194           _dbus_loop_unref (client_loop);
       
   195           client_loop = NULL;
       
   196         }
       
   197     }
       
   198       
       
   199   return retval;
       
   200 }
       
   201 
       
   202 void
       
   203 bus_test_clients_foreach (BusConnectionForeachFunction  function,
       
   204                           void                         *data)
       
   205 {
       
   206   DBusList *link;
       
   207   
       
   208   link = _dbus_list_get_first_link (&clients);
       
   209   while (link != NULL)
       
   210     {
       
   211       DBusConnection *connection = link->data;
       
   212       DBusList *next = _dbus_list_get_next_link (&clients, link);
       
   213 
       
   214       if (!(* function) (connection, data))
       
   215         break;
       
   216       
       
   217       link = next;
       
   218     }
       
   219 }
       
   220 
       
   221 dbus_bool_t
       
   222 bus_test_client_listed (DBusConnection *connection)
       
   223 {
       
   224   DBusList *link;
       
   225   
       
   226   link = _dbus_list_get_first_link (&clients);
       
   227   while (link != NULL)
       
   228     {
       
   229       DBusConnection *c = link->data;
       
   230       DBusList *next = _dbus_list_get_next_link (&clients, link);
       
   231 
       
   232       if (c == connection)
       
   233         return TRUE;
       
   234       
       
   235       link = next;
       
   236     }
       
   237 
       
   238   return FALSE;
       
   239 }
       
   240 
       
   241 void
       
   242 bus_test_run_clients_loop (dbus_bool_t block_once)
       
   243 {  
       
   244   if (client_loop == NULL)
       
   245     return;
       
   246 
       
   247   _dbus_verbose ("---> Dispatching on \"client side\"\n");
       
   248   
       
   249   /* dispatch before we block so pending dispatches
       
   250    * won't make our block return early
       
   251    */
       
   252   _dbus_loop_dispatch (client_loop);
       
   253   
       
   254   /* Do one blocking wait, since we're expecting data */
       
   255   if (block_once)
       
   256     {
       
   257       _dbus_verbose ("---> blocking on \"client side\"\n");
       
   258       _dbus_loop_iterate (client_loop, TRUE);
       
   259     }
       
   260 
       
   261   /* Then mop everything up */
       
   262   while (_dbus_loop_iterate (client_loop, FALSE))
       
   263     ;
       
   264 
       
   265   _dbus_verbose ("---> Done dispatching on \"client side\"\n");
       
   266 }
       
   267 
       
   268 void
       
   269 bus_test_run_bus_loop (BusContext *context,
       
   270                        dbus_bool_t block_once)
       
   271 {
       
   272   _dbus_verbose ("---> Dispatching on \"server side\"\n");
       
   273   
       
   274   /* dispatch before we block so pending dispatches
       
   275    * won't make our block return early
       
   276    */
       
   277   _dbus_loop_dispatch (bus_context_get_loop (context));
       
   278   
       
   279   /* Do one blocking wait, since we're expecting data */
       
   280   if (block_once)
       
   281     {
       
   282       _dbus_verbose ("---> blocking on \"server side\"\n");
       
   283       _dbus_loop_iterate (bus_context_get_loop (context), TRUE);
       
   284     }
       
   285 
       
   286   /* Then mop everything up */
       
   287   while (_dbus_loop_iterate (bus_context_get_loop (context), FALSE))
       
   288     ;
       
   289 
       
   290   _dbus_verbose ("---> Done dispatching on \"server side\"\n");
       
   291 }
       
   292 
       
   293 void
       
   294 bus_test_run_everything (BusContext *context)
       
   295 {
       
   296   while (_dbus_loop_iterate (bus_context_get_loop (context), FALSE) ||
       
   297          (client_loop == NULL || _dbus_loop_iterate (client_loop, FALSE)))
       
   298     ;
       
   299 }
       
   300 
       
   301 BusContext*
       
   302 bus_context_new_test (const DBusString *test_data_dir,
       
   303                       const char       *filename)
       
   304 {
       
   305   DBusError error;
       
   306   DBusString config_file;
       
   307   DBusString relative;
       
   308   BusContext *context;
       
   309   
       
   310   if (!_dbus_string_init (&config_file))
       
   311     {
       
   312       _dbus_warn ("No memory\n");
       
   313       return NULL;
       
   314     }
       
   315 
       
   316   if (!_dbus_string_copy (test_data_dir, 0,
       
   317                           &config_file, 0))
       
   318     {
       
   319       _dbus_warn ("No memory\n");
       
   320       _dbus_string_free (&config_file);
       
   321       return NULL;
       
   322     }
       
   323 
       
   324   _dbus_string_init_const (&relative, filename);
       
   325 
       
   326   if (!_dbus_concat_dir_and_file (&config_file, &relative))
       
   327     {
       
   328       _dbus_warn ("No memory\n");
       
   329       _dbus_string_free (&config_file);
       
   330       return NULL;
       
   331     }
       
   332   
       
   333   dbus_error_init (&error);
       
   334   context = bus_context_new (&config_file, FALSE, -1, -1, &error);
       
   335   if (context == NULL)
       
   336     {
       
   337       _DBUS_ASSERT_ERROR_IS_SET (&error);
       
   338       
       
   339       _dbus_warn ("Failed to create debug bus context from configuration file %s: %s\n",
       
   340                   filename, error.message);
       
   341 
       
   342       dbus_error_free (&error);
       
   343       
       
   344       _dbus_string_free (&config_file);
       
   345       
       
   346       return NULL;
       
   347     }
       
   348 
       
   349   _dbus_string_free (&config_file);
       
   350   
       
   351   return context;
       
   352 }
       
   353 
       
   354 #endif