(linenum→info "unix/slp.c:2238")

dbus/1.0.2/bus/test.c

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