(root)/
glib-2.79.0/
gio/
tests/
gdbus-tests.c
       1  /* GLib testing framework examples and tests
       2   *
       3   * Copyright (C) 2008-2010 Red Hat, Inc.
       4   *
       5   * SPDX-License-Identifier: LGPL-2.1-or-later
       6   *
       7   * This library is free software; you can redistribute it and/or
       8   * modify it under the terms of the GNU Lesser General Public
       9   * License as published by the Free Software Foundation; either
      10   * version 2.1 of the License, or (at your option) any later version.
      11   *
      12   * This library is distributed in the hope that it will be useful,
      13   * but WITHOUT ANY WARRANTY; without even the implied warranty of
      14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      15   * Lesser General Public License for more details.
      16   *
      17   * You should have received a copy of the GNU Lesser General
      18   * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
      19   *
      20   * Author: David Zeuthen <davidz@redhat.com>
      21   */
      22  
      23  #include <gio/gio.h>
      24  #ifndef _MSC_VER
      25  #include <unistd.h>
      26  #endif
      27  
      28  #include "gdbus-tests.h"
      29  
      30  /* ---------------------------------------------------------------------------------------------------- */
      31  
      32  typedef struct
      33  {
      34    GMainLoop *loop;
      35    gboolean   timed_out;
      36  } PropertyNotifyData;
      37  
      38  static void
      39  on_property_notify (GObject    *object,
      40                      GParamSpec *pspec,
      41                      gpointer    user_data)
      42  {
      43    PropertyNotifyData *data = user_data;
      44    g_main_loop_quit (data->loop);
      45  }
      46  
      47  static gboolean
      48  on_property_notify_timeout (gpointer user_data)
      49  {
      50    PropertyNotifyData *data = user_data;
      51    data->timed_out = TRUE;
      52    g_main_loop_quit (data->loop);
      53    return G_SOURCE_CONTINUE;
      54  }
      55  
      56  gboolean
      57  _g_assert_property_notify_run (gpointer     object,
      58                                 const gchar *property_name)
      59  {
      60    gchar *s;
      61    gulong handler_id;
      62    guint timeout_id;
      63    PropertyNotifyData data;
      64  
      65    data.loop = g_main_loop_new (g_main_context_get_thread_default (), FALSE);
      66    data.timed_out = FALSE;
      67    s = g_strdup_printf ("notify::%s", property_name);
      68    handler_id = g_signal_connect (object,
      69                                   s,
      70                                   G_CALLBACK (on_property_notify),
      71                                   &data);
      72    g_free (s);
      73    timeout_id = g_timeout_add_seconds (30,
      74                                        on_property_notify_timeout,
      75                                        &data);
      76    g_main_loop_run (data.loop);
      77    g_signal_handler_disconnect (object, handler_id);
      78    g_source_remove (timeout_id);
      79    g_main_loop_unref (data.loop);
      80  
      81    return data.timed_out;
      82  }
      83  
      84  static gboolean
      85  _give_up (gpointer data)
      86  {
      87    g_error ("%s", (const gchar *) data);
      88    g_return_val_if_reached (G_SOURCE_CONTINUE);
      89  }
      90  
      91  typedef struct
      92  {
      93    GMainContext *context;
      94    gboolean name_appeared;
      95    gboolean unwatch_complete;
      96  } WatchData;
      97  
      98  static void
      99  name_appeared_cb (GDBusConnection *connection,
     100                    const gchar     *name,
     101                    const gchar     *name_owner,
     102                    gpointer         user_data)
     103  {
     104    WatchData *data = user_data;
     105  
     106    g_assert (name_owner != NULL);
     107    data->name_appeared = TRUE;
     108    g_main_context_wakeup (data->context);
     109  }
     110  
     111  static void
     112  watch_free_cb (gpointer user_data)
     113  {
     114    WatchData *data = user_data;
     115  
     116    data->unwatch_complete = TRUE;
     117    g_main_context_wakeup (data->context);
     118  }
     119  
     120  void
     121  ensure_gdbus_testserver_up (GDBusConnection *connection,
     122                              GMainContext    *context)
     123  {
     124    GSource *timeout_source = NULL;
     125    guint watch_id;
     126    WatchData data = { context, FALSE, FALSE };
     127  
     128    g_main_context_push_thread_default (context);
     129  
     130    watch_id = g_bus_watch_name_on_connection (connection,
     131                                               "com.example.TestService",
     132                                               G_BUS_NAME_WATCHER_FLAGS_NONE,
     133                                               name_appeared_cb,
     134                                               NULL,
     135                                               &data,
     136                                               watch_free_cb);
     137  
     138    timeout_source = g_timeout_source_new_seconds (60);
     139    g_source_set_callback (timeout_source, _give_up,
     140                           "waited more than ~ 60s for gdbus-testserver to take its bus name",
     141                           NULL);
     142    g_source_attach (timeout_source, context);
     143  
     144    while (!data.name_appeared)
     145      g_main_context_iteration (context, TRUE);
     146  
     147    g_bus_unwatch_name (watch_id);
     148  
     149    while (!data.unwatch_complete)
     150      g_main_context_iteration (context, TRUE);
     151  
     152    g_source_destroy (timeout_source);
     153    g_source_unref (timeout_source);
     154  
     155    g_main_context_pop_thread_default (context);
     156  }
     157  
     158  /* ---------------------------------------------------------------------------------------------------- */
     159  
     160  typedef struct
     161  {
     162    GMainLoop *loop;
     163    gboolean   timed_out;
     164  } SignalReceivedData;
     165  
     166  static void
     167  on_signal_received (gpointer user_data)
     168  {
     169    SignalReceivedData *data = user_data;
     170    g_main_loop_quit (data->loop);
     171  }
     172  
     173  static gboolean
     174  on_signal_received_timeout (gpointer user_data)
     175  {
     176    SignalReceivedData *data = user_data;
     177    data->timed_out = TRUE;
     178    g_main_loop_quit (data->loop);
     179    return G_SOURCE_CONTINUE;
     180  }
     181  
     182  gboolean
     183  _g_assert_signal_received_run (gpointer     object,
     184                                 const gchar *signal_name)
     185  {
     186    gulong handler_id;
     187    guint timeout_id;
     188    SignalReceivedData data;
     189  
     190    data.loop = g_main_loop_new (g_main_context_get_thread_default (), FALSE);
     191    data.timed_out = FALSE;
     192    handler_id = g_signal_connect_swapped (object,
     193                                           signal_name,
     194                                           G_CALLBACK (on_signal_received),
     195                                           &data);
     196    timeout_id = g_timeout_add_seconds (30,
     197                                        on_signal_received_timeout,
     198                                        &data);
     199    g_main_loop_run (data.loop);
     200    g_signal_handler_disconnect (object, handler_id);
     201    g_source_remove (timeout_id);
     202    g_main_loop_unref (data.loop);
     203  
     204    return data.timed_out;
     205  }
     206  
     207  /* ---------------------------------------------------------------------------------------------------- */
     208  
     209  GDBusConnection *
     210  _g_bus_get_priv (GBusType            bus_type,
     211                   GCancellable       *cancellable,
     212                   GError            **error)
     213  {
     214    gchar *address;
     215    GDBusConnection *ret;
     216  
     217    ret = NULL;
     218  
     219    address = g_dbus_address_get_for_bus_sync (bus_type, cancellable, error);
     220    if (address == NULL)
     221      goto out;
     222  
     223    ret = g_dbus_connection_new_for_address_sync (address,
     224                                                  G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT |
     225                                                  G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION,
     226                                                  NULL, /* GDBusAuthObserver */
     227                                                  cancellable,
     228                                                  error);
     229    g_free (address);
     230  
     231   out:
     232    return ret;
     233  }
     234  
     235  /* ---------------------------------------------------------------------------------------------------- */