test.c 8.06 KB
Newer Older
1
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
2 3 4 5
/* test.c  unit test routines
 *
 * Copyright (C) 2003 Red Hat, Inc.
 *
6
 * Licensed under the Academic Free License version 2.1
7
 *
8 9 10 11 12 13 14 15 16
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
17
 *
18 19
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
20
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
21 22 23
 *
 */

24 25
#include <config.h>

26
#ifdef DBUS_ENABLE_EMBEDDED_TESTS
27
#include "test.h"
28
#include <dbus/dbus-internals.h>
29
#include <dbus/dbus-list.h>
30
#include <dbus/dbus-sysdeps.h>
31 32 33 34 35

/* The "debug client" watch/timeout handlers don't dispatch messages,
 * as we manually pull them in order to verify them. This is why they
 * are different from the real handlers in connection.c
 */
36
static DBusList *clients = NULL;
37
static DBusLoop *client_loop = NULL;
38 39

static dbus_bool_t
40
add_client_watch (DBusWatch      *watch,
41
                  void           *data)
42
{
43
  return _dbus_loop_add_watch (client_loop, watch);
44 45 46
}

static void
47
remove_client_watch (DBusWatch      *watch,
48
                     void           *data)
49
{
50
  _dbus_loop_remove_watch (client_loop, watch);
51 52
}

53 54 55 56 57 58 59
static void
toggle_client_watch (DBusWatch      *watch,
                     void           *data)
{
  _dbus_loop_toggle_watch (client_loop, watch);
}

60
static dbus_bool_t
61
add_client_timeout (DBusTimeout    *timeout,
62
                    void           *data)
63
{
64
  return _dbus_loop_add_timeout (client_loop, timeout);
65 66 67
}

static void
68
remove_client_timeout (DBusTimeout    *timeout,
69
                       void           *data)
70
{
71
  _dbus_loop_remove_timeout (client_loop, timeout);
72 73
}

74
static DBusHandlerResult
75 76 77
client_disconnect_filter (DBusConnection     *connection,
                          DBusMessage        *message,
                          void               *user_data)
78
{
79
  if (!dbus_message_is_signal (message,
80
                               DBUS_INTERFACE_LOCAL,
81
                               "Disconnected"))
82
    return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
83

84 85
  _dbus_verbose ("Removing client %p in disconnect handler\n",
                 connection);
86

87
  _dbus_list_remove (&clients, connection);
88

89
  dbus_connection_unref (connection);
90

91 92
  if (clients == NULL)
    {
93
      _dbus_loop_unref (client_loop);
94 95
      client_loop = NULL;
    }
96

97
  return DBUS_HANDLER_RESULT_HANDLED;
98
}
99 100 101 102

dbus_bool_t
bus_setup_debug_client (DBusConnection *connection)
{
103
  dbus_bool_t retval;
104

105
  if (!dbus_connection_add_filter (connection,
106 107 108
                                   client_disconnect_filter,
                                   NULL, NULL))
    return FALSE;
109 110

  retval = FALSE;
111 112 113

  if (client_loop == NULL)
    {
114
      client_loop = _dbus_loop_new ();
115 116 117
      if (client_loop == NULL)
        goto out;
    }
118

119
  if (!dbus_connection_set_watch_functions (connection,
120 121
                                            add_client_watch,
                                            remove_client_watch,
122
                                            toggle_client_watch,
123 124 125
                                            connection,
                                            NULL))
    goto out;
126

127
  if (!dbus_connection_set_timeout_functions (connection,
128 129
                                              add_client_timeout,
                                              remove_client_timeout,
130
                                              NULL,
131
                                              connection, NULL))
132 133
    goto out;

134 135
  if (!_dbus_list_append (&clients, connection))
    goto out;
136

137
  retval = TRUE;
138

139 140
 out:
  if (!retval)
141
    {
142 143 144
      dbus_connection_remove_filter (connection,
                                     client_disconnect_filter,
                                     NULL);
145

146
      dbus_connection_set_watch_functions (connection,
147
                                           NULL, NULL, NULL, NULL, NULL);
148
      dbus_connection_set_timeout_functions (connection,
149
                                             NULL, NULL, NULL, NULL, NULL);
150 151

      _dbus_list_remove_last (&clients, connection);
152 153 154

      if (clients == NULL)
        {
155
          _dbus_loop_unref (client_loop);
156 157
          client_loop = NULL;
        }
158
    }
159

160 161 162 163 164 165 166 167
  return retval;
}

void
bus_test_clients_foreach (BusConnectionForeachFunction  function,
                          void                         *data)
{
  DBusList *link;
168

169 170 171 172 173 174 175 176
  link = _dbus_list_get_first_link (&clients);
  while (link != NULL)
    {
      DBusConnection *connection = link->data;
      DBusList *next = _dbus_list_get_next_link (&clients, link);

      if (!(* function) (connection, data))
        break;
177

178 179 180 181 182 183 184 185
      link = next;
    }
}

dbus_bool_t
bus_test_client_listed (DBusConnection *connection)
{
  DBusList *link;
186

187 188 189 190 191 192 193 194
  link = _dbus_list_get_first_link (&clients);
  while (link != NULL)
    {
      DBusConnection *c = link->data;
      DBusList *next = _dbus_list_get_next_link (&clients, link);

      if (c == connection)
        return TRUE;
195

196 197 198 199
      link = next;
    }

  return FALSE;
200
}
201

202
void
203
bus_test_run_clients_loop (dbus_bool_t block_once)
204
{
205 206
  if (client_loop == NULL)
    return;
207

208
  _dbus_verbose ("---> Dispatching on \"client side\"\n");
209

210 211 212 213
  /* dispatch before we block so pending dispatches
   * won't make our block return early
   */
  _dbus_loop_dispatch (client_loop);
214

215
  /* Do one blocking wait, since we're expecting data */
216 217 218 219 220
  if (block_once)
    {
      _dbus_verbose ("---> blocking on \"client side\"\n");
      _dbus_loop_iterate (client_loop, TRUE);
    }
221 222

  /* Then mop everything up */
223
  while (_dbus_loop_iterate (client_loop, FALSE))
224
    ;
225 226

  _dbus_verbose ("---> Done dispatching on \"client side\"\n");
227 228 229
}

void
230 231
bus_test_run_bus_loop (BusContext *context,
                       dbus_bool_t block_once)
232
{
233
  _dbus_verbose ("---> Dispatching on \"server side\"\n");
234

235 236 237 238
  /* dispatch before we block so pending dispatches
   * won't make our block return early
   */
  _dbus_loop_dispatch (bus_context_get_loop (context));
239

240
  /* Do one blocking wait, since we're expecting data */
241 242 243 244 245
  if (block_once)
    {
      _dbus_verbose ("---> blocking on \"server side\"\n");
      _dbus_loop_iterate (bus_context_get_loop (context), TRUE);
    }
246 247

  /* Then mop everything up */
248
  while (_dbus_loop_iterate (bus_context_get_loop (context), FALSE))
249
    ;
250 251

  _dbus_verbose ("---> Done dispatching on \"server side\"\n");
252 253
}

254 255 256
void
bus_test_run_everything (BusContext *context)
{
257 258 259
  while (_dbus_loop_iterate (bus_context_get_loop (context), FALSE) ||
         (client_loop == NULL || _dbus_loop_iterate (client_loop, FALSE)))
    ;
260 261
}

262 263 264 265 266 267 268 269
BusContext*
bus_context_new_test (const DBusString *test_data_dir,
                      const char       *filename)
{
  DBusError error;
  DBusString config_file;
  DBusString relative;
  BusContext *context;
270

271
  if (!_dbus_string_init (&config_file))
272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292
    {
      _dbus_warn ("No memory\n");
      return NULL;
    }

  if (!_dbus_string_copy (test_data_dir, 0,
                          &config_file, 0))
    {
      _dbus_warn ("No memory\n");
      _dbus_string_free (&config_file);
      return NULL;
    }

  _dbus_string_init_const (&relative, filename);

  if (!_dbus_concat_dir_and_file (&config_file, &relative))
    {
      _dbus_warn ("No memory\n");
      _dbus_string_free (&config_file);
      return NULL;
    }
293

294
  dbus_error_init (&error);
295
  context = bus_context_new (&config_file, BUS_CONTEXT_FLAG_NONE, NULL, NULL, NULL, &error);
296 297 298
  if (context == NULL)
    {
      _DBUS_ASSERT_ERROR_IS_SET (&error);
299

300 301 302 303
      _dbus_warn ("Failed to create debug bus context from configuration file %s: %s\n",
                  filename, error.message);

      dbus_error_free (&error);
304

305
      _dbus_string_free (&config_file);
306

307 308 309 310
      return NULL;
    }

  _dbus_string_free (&config_file);
311

312 313 314
  return context;
}

315
#endif