LCOV - code coverage report
Current view: top level - glib/gio/tests - gdbus-connection.c (source / functions) Hit Total Coverage
Test: unnamed Lines: 495 508 97.4 %
Date: 2024-04-23 05:16:05 Functions: 27 30 90.0 %
Branches: 36 48 75.0 %

           Branch data     Line data    Source code
       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                 :            : #include <unistd.h>
      25                 :            : #include <string.h>
      26                 :            : 
      27                 :            : #include <sys/types.h>
      28                 :            : 
      29                 :            : #include "gdbus-tests.h"
      30                 :            : 
      31                 :            : /* all tests rely on a shared mainloop */
      32                 :            : static GMainLoop *loop = NULL;
      33                 :            : 
      34                 :            : #if 0
      35                 :            : G_GNUC_UNUSED static void
      36                 :            : _log (const gchar *format, ...)
      37                 :            : {
      38                 :            :   GTimeVal now;
      39                 :            :   time_t now_time;
      40                 :            :   struct tm *now_tm;
      41                 :            :   gchar time_buf[128];
      42                 :            :   gchar *str;
      43                 :            :   va_list var_args;
      44                 :            : 
      45                 :            :   va_start (var_args, format);
      46                 :            :   str = g_strdup_vprintf (format, var_args);
      47                 :            :   va_end (var_args);
      48                 :            : 
      49                 :            :   g_get_current_time (&now);
      50                 :            :   now_time = (time_t) now.tv_sec;
      51                 :            :   now_tm = localtime (&now_time);
      52                 :            :   strftime (time_buf, sizeof time_buf, "%H:%M:%S", now_tm);
      53                 :            : 
      54                 :            :   g_printerr ("%s.%06d: %s\n",
      55                 :            :            time_buf, (gint) now.tv_usec / 1000,
      56                 :            :            str);
      57                 :            :   g_free (str);
      58                 :            : }
      59                 :            : #else
      60                 :            : #define _log(...)
      61                 :            : #endif
      62                 :            : 
      63                 :            : static gboolean
      64                 :          0 : test_connection_quit_mainloop (gpointer user_data)
      65                 :            : {
      66                 :          0 :   gboolean *quit_mainloop_fired = user_data;  /* (atomic) */
      67                 :            :   _log ("quit_mainloop_fired");
      68                 :          0 :   g_atomic_int_set (quit_mainloop_fired, TRUE);
      69                 :          0 :   g_main_loop_quit (loop);
      70                 :          0 :   return G_SOURCE_CONTINUE;
      71                 :            : }
      72                 :            : 
      73                 :            : /* ---------------------------------------------------------------------------------------------------- */
      74                 :            : /* Connection life-cycle testing */
      75                 :            : /* ---------------------------------------------------------------------------------------------------- */
      76                 :            : 
      77                 :            : static const GDBusInterfaceInfo boo_interface_info =
      78                 :            : {
      79                 :            :   -1,
      80                 :            :   "org.example.Boo",
      81                 :            :   (GDBusMethodInfo **) NULL,
      82                 :            :   (GDBusSignalInfo **) NULL,
      83                 :            :   (GDBusPropertyInfo **) NULL,
      84                 :            :   NULL,
      85                 :            : };
      86                 :            : 
      87                 :            : static const GDBusInterfaceVTable boo_vtable =
      88                 :            : {
      89                 :            :   NULL, /* _method_call */
      90                 :            :   NULL, /* _get_property */
      91                 :            :   NULL,  /* _set_property */
      92                 :            :   { 0 }
      93                 :            : };
      94                 :            : 
      95                 :            : /* Runs in a worker thread. */
      96                 :            : static GDBusMessage *
      97                 :          1 : some_filter_func (GDBusConnection *connection,
      98                 :            :                   GDBusMessage    *message,
      99                 :            :                   gboolean         incoming,
     100                 :            :                   gpointer         user_data)
     101                 :            : {
     102                 :          1 :   return message;
     103                 :            : }
     104                 :            : 
     105                 :            : static void
     106                 :          0 : on_name_owner_changed (GDBusConnection *connection,
     107                 :            :                        const gchar     *sender_name,
     108                 :            :                        const gchar     *object_path,
     109                 :            :                        const gchar     *interface_name,
     110                 :            :                        const gchar     *signal_name,
     111                 :            :                        GVariant        *parameters,
     112                 :            :                        gpointer         user_data)
     113                 :            : {
     114                 :          0 : }
     115                 :            : 
     116                 :            : static void
     117                 :          3 : a_gdestroynotify_that_sets_a_gboolean_to_true_and_quits_loop (gpointer user_data)
     118                 :            : {
     119                 :          3 :   gboolean *val = user_data;  /* (atomic) */
     120                 :          3 :   g_atomic_int_set (val, TRUE);
     121                 :            :   _log ("destroynotify fired for %p", val);
     122                 :          3 :   g_main_loop_quit (loop);
     123                 :          3 : }
     124                 :            : 
     125                 :            : static void
     126                 :          1 : test_connection_bus_failure (void)
     127                 :            : {
     128                 :            :   GDBusConnection *c;
     129                 :          1 :   GError *error = NULL;
     130                 :            : 
     131                 :            :   /*
     132                 :            :    * Check for correct behavior when no bus is present
     133                 :            :    *
     134                 :            :    */
     135                 :          1 :   c = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
     136                 :          1 :   g_assert_nonnull (error);
     137                 :          1 :   g_assert_false (g_dbus_error_is_remote_error (error));
     138                 :          1 :   g_assert_null (c);
     139                 :          1 :   g_error_free (error);
     140                 :          1 : }
     141                 :            : 
     142                 :            : static void
     143                 :          1 : test_connection_life_cycle (void)
     144                 :            : {
     145                 :            :   gboolean ret;
     146                 :            :   GDBusConnection *c;
     147                 :            :   GDBusConnection *c2;
     148                 :            :   GError *error;
     149                 :            :   gboolean on_signal_registration_freed_called;  /* (atomic) */
     150                 :            :   gboolean on_filter_freed_called;  /* (atomic) */
     151                 :            :   gboolean on_register_object_freed_called;  /* (atomic) */
     152                 :            :   gboolean quit_mainloop_fired;  /* (atomic) */
     153                 :            :   guint quit_mainloop_id;
     154                 :            :   guint registration_id;
     155                 :            : 
     156                 :          1 :   error = NULL;
     157                 :            : 
     158                 :            :   /*
     159                 :            :    *  Check for correct behavior when a bus is present
     160                 :            :    */
     161                 :          1 :   session_bus_up ();
     162                 :            :   /* case 1 */
     163                 :          1 :   error = NULL;
     164                 :          1 :   c = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
     165                 :          1 :   g_assert_no_error (error);
     166                 :          1 :   g_assert_nonnull (c);
     167                 :          1 :   g_assert_false (g_dbus_connection_is_closed (c));
     168                 :            : 
     169                 :            :   /*
     170                 :            :    * Check that singleton handling work
     171                 :            :    */
     172                 :          1 :   error = NULL;
     173                 :          1 :   c2 = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
     174                 :          1 :   g_assert_no_error (error);
     175                 :          1 :   g_assert_nonnull (c2);
     176                 :          1 :   g_assert_true (c == c2);
     177                 :          1 :   g_object_unref (c2);
     178                 :            : 
     179                 :            :   /*
     180                 :            :    * Check that private connections work
     181                 :            :    */
     182                 :          1 :   c2 = _g_bus_get_priv (G_BUS_TYPE_SESSION, NULL, &error);
     183                 :          1 :   g_assert_no_error (error);
     184                 :          1 :   g_assert_nonnull (c2);
     185                 :          1 :   g_assert_true (c != c2);
     186                 :          1 :   g_object_unref (c2);
     187                 :            : 
     188                 :          1 :   c2 = _g_bus_get_priv (G_BUS_TYPE_SESSION, NULL, &error);
     189                 :          1 :   g_assert_no_error (error);
     190                 :          1 :   g_assert_nonnull (c2);
     191                 :          1 :   g_assert_false (g_dbus_connection_is_closed (c2));
     192                 :          1 :   ret = g_dbus_connection_close_sync (c2, NULL, &error);
     193                 :          1 :   g_assert_no_error (error);
     194                 :          1 :   g_assert_true (ret);
     195                 :          1 :   _g_assert_signal_received (c2, "closed");
     196                 :          1 :   g_assert_true (g_dbus_connection_is_closed (c2));
     197                 :          1 :   ret = g_dbus_connection_close_sync (c2, NULL, &error);
     198                 :          1 :   g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CLOSED);
     199                 :          1 :   g_error_free (error);
     200                 :          1 :   g_assert_false (ret);
     201                 :          1 :   g_object_unref (c2);
     202                 :            : 
     203                 :            :   /*
     204                 :            :    * Check that the finalization code works
     205                 :            :    *
     206                 :            :    * (and that the GDestroyNotify for filters and objects and signal
     207                 :            :    * registrations are run as expected)
     208                 :            :    */
     209                 :          1 :   error = NULL;
     210                 :          1 :   c2 = _g_bus_get_priv (G_BUS_TYPE_SESSION, NULL, &error);
     211                 :          1 :   g_assert_no_error (error);
     212                 :          1 :   g_assert_nonnull (c2);
     213                 :            :   /* signal registration */
     214                 :          1 :   g_atomic_int_set (&on_signal_registration_freed_called, FALSE);
     215                 :          1 :   g_dbus_connection_signal_subscribe (c2,
     216                 :            :                                       "org.freedesktop.DBus", /* bus name */
     217                 :            :                                       "org.freedesktop.DBus", /* interface */
     218                 :            :                                       "NameOwnerChanged",     /* member */
     219                 :            :                                       "/org/freesktop/DBus",  /* path */
     220                 :            :                                       NULL,                   /* arg0 */
     221                 :            :                                       G_DBUS_SIGNAL_FLAGS_NONE,
     222                 :            :                                       on_name_owner_changed,
     223                 :            :                                       (gpointer) &on_signal_registration_freed_called,
     224                 :            :                                       a_gdestroynotify_that_sets_a_gboolean_to_true_and_quits_loop);
     225                 :            :   /* filter func */
     226                 :          1 :   g_atomic_int_set (&on_filter_freed_called, FALSE);
     227                 :          1 :   g_dbus_connection_add_filter (c2,
     228                 :            :                                 some_filter_func,
     229                 :            :                                 (gpointer) &on_filter_freed_called,
     230                 :            :                                 a_gdestroynotify_that_sets_a_gboolean_to_true_and_quits_loop);
     231                 :            :   /* object registration */
     232                 :          1 :   g_atomic_int_set (&on_register_object_freed_called, FALSE);
     233                 :          1 :   error = NULL;
     234                 :          1 :   registration_id = g_dbus_connection_register_object (c2,
     235                 :            :                                                        "/foo",
     236                 :            :                                                        (GDBusInterfaceInfo *) &boo_interface_info,
     237                 :            :                                                        &boo_vtable,
     238                 :            :                                                        (gpointer) &on_register_object_freed_called,
     239                 :            :                                                        a_gdestroynotify_that_sets_a_gboolean_to_true_and_quits_loop,
     240                 :            :                                                        &error);
     241                 :          1 :   g_assert_no_error (error);
     242                 :          1 :   g_assert_cmpuint (registration_id, >, 0);
     243                 :            :   /* ok, finalize the connection and check that all the GDestroyNotify functions are invoked as expected */
     244                 :          1 :   g_object_unref (c2);
     245                 :          1 :   g_atomic_int_set (&quit_mainloop_fired, FALSE);
     246                 :          1 :   quit_mainloop_id = g_timeout_add (30000, test_connection_quit_mainloop, (gpointer) &quit_mainloop_fired);
     247                 :            :   _log ("destroynotifies for\n"
     248                 :            :         " register_object %p\n"
     249                 :            :         " filter          %p\n"
     250                 :            :         " signal          %p",
     251                 :            :         &on_register_object_freed_called,
     252                 :            :         &on_filter_freed_called,
     253                 :            :         &on_signal_registration_freed_called);
     254                 :            :   while (TRUE)
     255                 :            :     {
     256         [ +  + ]:          3 :       if (g_atomic_int_get (&on_signal_registration_freed_called) &&
     257         [ +  + ]:          2 :           g_atomic_int_get (&on_filter_freed_called) &&
     258         [ +  - ]:          1 :           g_atomic_int_get (&on_register_object_freed_called))
     259                 :          1 :         break;
     260         [ -  + ]:          2 :       if (g_atomic_int_get (&quit_mainloop_fired))
     261                 :          0 :         break;
     262                 :            :       _log ("entering loop");
     263                 :          2 :       g_main_loop_run (loop);
     264                 :            :       _log ("exiting loop");
     265                 :            :     }
     266                 :          1 :   g_source_remove (quit_mainloop_id);
     267                 :          1 :   g_assert_true (g_atomic_int_get (&on_signal_registration_freed_called));
     268                 :          1 :   g_assert_true (g_atomic_int_get (&on_filter_freed_called));
     269                 :          1 :   g_assert_true (g_atomic_int_get (&on_register_object_freed_called));
     270                 :          1 :   g_assert_false (g_atomic_int_get (&quit_mainloop_fired));
     271                 :            : 
     272                 :            :   /*
     273                 :            :    *  Check for correct behavior when the bus goes away
     274                 :            :    *
     275                 :            :    */
     276                 :          1 :   g_assert_false (g_dbus_connection_is_closed (c));
     277                 :          1 :   g_dbus_connection_set_exit_on_close (c, FALSE);
     278                 :          1 :   session_bus_stop ();
     279                 :          1 :   _g_assert_signal_received (c, "closed");
     280                 :          1 :   g_assert_true (g_dbus_connection_is_closed (c));
     281                 :          1 :   g_object_unref (c);
     282                 :            : 
     283                 :          1 :   session_bus_down ();
     284                 :          1 : }
     285                 :            : 
     286                 :            : /* ---------------------------------------------------------------------------------------------------- */
     287                 :            : /* Test that sending and receiving messages work as expected */
     288                 :            : /* ---------------------------------------------------------------------------------------------------- */
     289                 :            : 
     290                 :            : static void
     291                 :          1 : msg_cb_expect_error_disconnected (GDBusConnection *connection,
     292                 :            :                                   GAsyncResult    *res,
     293                 :            :                                   gpointer         user_data)
     294                 :            : {
     295                 :            :   GError *error;
     296                 :            :   GVariant *result;
     297                 :            : 
     298                 :            :   /* Make sure gdbusconnection isn't holding @connection's lock. (#747349) */
     299                 :          1 :   g_dbus_connection_get_last_serial (connection);
     300                 :            : 
     301                 :          1 :   error = NULL;
     302                 :          1 :   result = g_dbus_connection_call_finish (connection,
     303                 :            :                                           res,
     304                 :            :                                           &error);
     305                 :          1 :   g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CLOSED);
     306                 :          1 :   g_assert_false (g_dbus_error_is_remote_error (error));
     307                 :          1 :   g_error_free (error);
     308                 :          1 :   g_assert_null (result);
     309                 :            : 
     310                 :          1 :   g_main_loop_quit (loop);
     311                 :          1 : }
     312                 :            : 
     313                 :            : static void
     314                 :          1 : msg_cb_expect_error_unknown_method (GDBusConnection *connection,
     315                 :            :                                     GAsyncResult    *res,
     316                 :            :                                     gpointer         user_data)
     317                 :            : {
     318                 :            :   GError *error;
     319                 :            :   GVariant *result;
     320                 :            : 
     321                 :            :   /* Make sure gdbusconnection isn't holding @connection's lock. (#747349) */
     322                 :          1 :   g_dbus_connection_get_last_serial (connection);
     323                 :            : 
     324                 :          1 :   error = NULL;
     325                 :          1 :   result = g_dbus_connection_call_finish (connection,
     326                 :            :                                           res,
     327                 :            :                                           &error);
     328                 :          1 :   g_assert_error (error, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD);
     329                 :          1 :   g_assert_true (g_dbus_error_is_remote_error (error));
     330                 :          1 :   g_error_free (error);
     331                 :          1 :   g_assert_null (result);
     332                 :            : 
     333                 :          1 :   g_main_loop_quit (loop);
     334                 :          1 : }
     335                 :            : 
     336                 :            : static void
     337                 :          1 : msg_cb_expect_success (GDBusConnection *connection,
     338                 :            :                        GAsyncResult    *res,
     339                 :            :                        gpointer         user_data)
     340                 :            : {
     341                 :            :   GError *error;
     342                 :            :   GVariant *result;
     343                 :            : 
     344                 :            :   /* Make sure gdbusconnection isn't holding @connection's lock. (#747349) */
     345                 :          1 :   g_dbus_connection_get_last_serial (connection);
     346                 :            : 
     347                 :          1 :   error = NULL;
     348                 :          1 :   result = g_dbus_connection_call_finish (connection,
     349                 :            :                                           res,
     350                 :            :                                           &error);
     351                 :          1 :   g_assert_no_error (error);
     352                 :          1 :   g_assert_nonnull (result);
     353                 :          1 :   g_variant_unref (result);
     354                 :            : 
     355                 :          1 :   g_main_loop_quit (loop);
     356                 :          1 : }
     357                 :            : 
     358                 :            : static void
     359                 :          1 : msg_cb_expect_error_cancelled (GDBusConnection *connection,
     360                 :            :                                GAsyncResult    *res,
     361                 :            :                                gpointer         user_data)
     362                 :            : {
     363                 :            :   GError *error;
     364                 :            :   GVariant *result;
     365                 :            : 
     366                 :            :   /* Make sure gdbusconnection isn't holding @connection's lock. (#747349) */
     367                 :          1 :   g_dbus_connection_get_last_serial (connection);
     368                 :            : 
     369                 :          1 :   error = NULL;
     370                 :          1 :   result = g_dbus_connection_call_finish (connection,
     371                 :            :                                           res,
     372                 :            :                                           &error);
     373                 :          1 :   g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
     374                 :          1 :   g_assert_false (g_dbus_error_is_remote_error (error));
     375                 :          1 :   g_error_free (error);
     376                 :          1 :   g_assert_null (result);
     377                 :            : 
     378                 :          1 :   g_main_loop_quit (loop);
     379                 :          1 : }
     380                 :            : 
     381                 :            : static void
     382                 :          1 : msg_cb_expect_error_cancelled_2 (GDBusConnection *connection,
     383                 :            :                                  GAsyncResult    *res,
     384                 :            :                                  gpointer         user_data)
     385                 :            : {
     386                 :            :   GError *error;
     387                 :            :   GVariant *result;
     388                 :            : 
     389                 :            :   /* Make sure gdbusconnection isn't holding @connection's lock. (#747349) */
     390                 :          1 :   g_dbus_connection_get_last_serial (connection);
     391                 :            : 
     392                 :          1 :   error = NULL;
     393                 :          1 :   result = g_dbus_connection_call_finish (connection,
     394                 :            :                                           res,
     395                 :            :                                           &error);
     396                 :          1 :   g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
     397                 :          1 :   g_assert_false (g_dbus_error_is_remote_error (error));
     398                 :          1 :   g_error_free (error);
     399                 :          1 :   g_assert_null (result);
     400                 :            : 
     401                 :          1 :   g_main_loop_quit (loop);
     402                 :          1 : }
     403                 :            : 
     404                 :            : /* ---------------------------------------------------------------------------------------------------- */
     405                 :            : 
     406                 :            : static void
     407                 :          1 : test_connection_send (void)
     408                 :            : {
     409                 :            :   GDBusConnection *c;
     410                 :            :   GCancellable *ca;
     411                 :            : 
     412                 :          1 :   session_bus_up ();
     413                 :            : 
     414                 :            :   /* First, get an unopened connection */
     415                 :          1 :   c = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
     416                 :          1 :   g_assert_nonnull (c);
     417                 :          1 :   g_assert_false (g_dbus_connection_is_closed (c));
     418                 :            : 
     419                 :            :   /*
     420                 :            :    * Check that we never actually send a message if the GCancellable
     421                 :            :    * is already cancelled - i.e.  we should get G_IO_ERROR_CANCELLED
     422                 :            :    * when the actual connection is not up.
     423                 :            :    */
     424                 :          1 :   ca = g_cancellable_new ();
     425                 :          1 :   g_cancellable_cancel (ca);
     426                 :          1 :   g_dbus_connection_call (c,
     427                 :            :                           "org.freedesktop.DBus",  /* bus_name */
     428                 :            :                           "/org/freedesktop/DBus", /* object path */
     429                 :            :                           "org.freedesktop.DBus",  /* interface name */
     430                 :            :                           "GetId",                 /* method name */
     431                 :            :                           NULL, NULL,
     432                 :            :                           G_DBUS_CALL_FLAGS_NONE,
     433                 :            :                           -1,
     434                 :            :                           ca,
     435                 :            :                           (GAsyncReadyCallback) msg_cb_expect_error_cancelled,
     436                 :            :                           NULL);
     437                 :          1 :   g_main_loop_run (loop);
     438                 :          1 :   g_object_unref (ca);
     439                 :            : 
     440                 :            :   /*
     441                 :            :    * Check that we get a reply to the GetId() method call.
     442                 :            :    */
     443                 :          1 :   g_dbus_connection_call (c,
     444                 :            :                           "org.freedesktop.DBus",  /* bus_name */
     445                 :            :                           "/org/freedesktop/DBus", /* object path */
     446                 :            :                           "org.freedesktop.DBus",  /* interface name */
     447                 :            :                           "GetId",                 /* method name */
     448                 :            :                           NULL, NULL,
     449                 :            :                           G_DBUS_CALL_FLAGS_NONE,
     450                 :            :                           -1,
     451                 :            :                           NULL,
     452                 :            :                           (GAsyncReadyCallback) msg_cb_expect_success,
     453                 :            :                           NULL);
     454                 :          1 :   g_main_loop_run (loop);
     455                 :            : 
     456                 :            :   /*
     457                 :            :    * Check that we get an error reply to the NonExistantMethod() method call.
     458                 :            :    */
     459                 :          1 :   g_dbus_connection_call (c,
     460                 :            :                           "org.freedesktop.DBus",  /* bus_name */
     461                 :            :                           "/org/freedesktop/DBus", /* object path */
     462                 :            :                           "org.freedesktop.DBus",  /* interface name */
     463                 :            :                           "NonExistantMethod",     /* method name */
     464                 :            :                           NULL, NULL,
     465                 :            :                           G_DBUS_CALL_FLAGS_NONE,
     466                 :            :                           -1,
     467                 :            :                           NULL,
     468                 :            :                           (GAsyncReadyCallback) msg_cb_expect_error_unknown_method,
     469                 :            :                           NULL);
     470                 :          1 :   g_main_loop_run (loop);
     471                 :            : 
     472                 :            :   /*
     473                 :            :    * Check that cancellation works when the message is already in flight.
     474                 :            :    */
     475                 :          1 :   ca = g_cancellable_new ();
     476                 :          1 :   g_dbus_connection_call (c,
     477                 :            :                           "org.freedesktop.DBus",  /* bus_name */
     478                 :            :                           "/org/freedesktop/DBus", /* object path */
     479                 :            :                           "org.freedesktop.DBus",  /* interface name */
     480                 :            :                           "GetId",                 /* method name */
     481                 :            :                           NULL, NULL,
     482                 :            :                           G_DBUS_CALL_FLAGS_NONE,
     483                 :            :                           -1,
     484                 :            :                           ca,
     485                 :            :                           (GAsyncReadyCallback) msg_cb_expect_error_cancelled_2,
     486                 :            :                           NULL);
     487                 :          1 :   g_cancellable_cancel (ca);
     488                 :          1 :   g_main_loop_run (loop);
     489                 :          1 :   g_object_unref (ca);
     490                 :            : 
     491                 :            :   /*
     492                 :            :    * Check that we get an error when sending to a connection that is disconnected.
     493                 :            :    */
     494                 :          1 :   g_dbus_connection_set_exit_on_close (c, FALSE);
     495                 :          1 :   session_bus_stop ();
     496                 :          1 :   _g_assert_signal_received (c, "closed");
     497                 :          1 :   g_assert_true (g_dbus_connection_is_closed (c));
     498                 :            : 
     499                 :          1 :   g_dbus_connection_call (c,
     500                 :            :                           "org.freedesktop.DBus",  /* bus_name */
     501                 :            :                           "/org/freedesktop/DBus", /* object path */
     502                 :            :                           "org.freedesktop.DBus",  /* interface name */
     503                 :            :                           "GetId",                 /* method name */
     504                 :            :                           NULL, NULL,
     505                 :            :                           G_DBUS_CALL_FLAGS_NONE,
     506                 :            :                           -1,
     507                 :            :                           NULL,
     508                 :            :                           (GAsyncReadyCallback) msg_cb_expect_error_disconnected,
     509                 :            :                           NULL);
     510                 :          1 :   g_main_loop_run (loop);
     511                 :            : 
     512                 :          1 :   g_object_unref (c);
     513                 :            : 
     514                 :          1 :   session_bus_down ();
     515                 :          1 : }
     516                 :            : 
     517                 :            : /* ---------------------------------------------------------------------------------------------------- */
     518                 :            : /* Connection signal tests */
     519                 :            : /* ---------------------------------------------------------------------------------------------------- */
     520                 :            : 
     521                 :            : static void
     522                 :         35 : test_connection_signal_handler (GDBusConnection  *connection,
     523                 :            :                                 const gchar      *sender_name,
     524                 :            :                                 const gchar      *object_path,
     525                 :            :                                 const gchar      *interface_name,
     526                 :            :                                 const gchar      *signal_name,
     527                 :            :                                 GVariant         *parameters,
     528                 :            :                                 gpointer         user_data)
     529                 :            : {
     530                 :         35 :   gint *counter = user_data;
     531                 :         35 :   *counter += 1;
     532                 :            : 
     533                 :            :   /*g_debug ("in test_connection_signal_handler (sender=%s path=%s interface=%s member=%s)",
     534                 :            :            sender_name,
     535                 :            :            object_path,
     536                 :            :            interface_name,
     537                 :            :            signal_name);*/
     538                 :            : 
     539                 :         35 :   g_main_loop_quit (loop);
     540                 :         35 : }
     541                 :            : 
     542                 :            : static void
     543                 :          1 : test_connection_signals (void)
     544                 :            : {
     545                 :            :   GDBusConnection *c1;
     546                 :            :   GDBusConnection *c2;
     547                 :            :   GDBusConnection *c3;
     548                 :            :   guint s1;
     549                 :            :   guint s1b;
     550                 :            :   guint s2;
     551                 :            :   guint s3;
     552                 :            :   gint count_s1;
     553                 :            :   gint count_s1b;
     554                 :            :   gint count_s2;
     555                 :            :   gint count_name_owner_changed;
     556                 :            :   GError *error;
     557                 :            :   gboolean ret;
     558                 :            :   GVariant *result;
     559                 :            :   gboolean quit_mainloop_fired;
     560                 :            :   guint quit_mainloop_id;
     561                 :            : 
     562                 :          1 :   error = NULL;
     563                 :            : 
     564                 :            :   /*
     565                 :            :    * Bring up first separate connections
     566                 :            :    */
     567                 :          1 :   session_bus_up ();
     568                 :            :   /* if running with dbus-monitor, it claims the name :1.0 - so if we don't run with the monitor
     569                 :            :    * emulate this
     570                 :            :    */
     571         [ +  - ]:          1 :   if (g_getenv ("G_DBUS_MONITOR") == NULL)
     572                 :            :     {
     573                 :          1 :       c1 = _g_bus_get_priv (G_BUS_TYPE_SESSION, NULL, NULL);
     574                 :          1 :       g_assert_nonnull (c1);
     575                 :          1 :       g_assert_false (g_dbus_connection_is_closed (c1));
     576                 :          1 :       g_object_unref (c1);
     577                 :            :     }
     578                 :          1 :   c1 = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
     579                 :          1 :   g_assert_nonnull (c1);
     580                 :          1 :   g_assert_false (g_dbus_connection_is_closed (c1));
     581                 :          1 :   g_assert_cmpstr (g_dbus_connection_get_unique_name (c1), ==, ":1.1");
     582                 :            : 
     583                 :            :   /*
     584                 :            :    * Install two signal handlers for the first connection
     585                 :            :    *
     586                 :            :    *  - Listen to the signal "Foo" from :1.2 (e.g. c2)
     587                 :            :    *  - Listen to the signal "Foo" from anyone (e.g. both c2 and c3)
     588                 :            :    *
     589                 :            :    * and then count how many times this signal handler was invoked.
     590                 :            :    */
     591                 :          1 :   s1 = g_dbus_connection_signal_subscribe (c1,
     592                 :            :                                            ":1.2",
     593                 :            :                                            "org.gtk.GDBus.ExampleInterface",
     594                 :            :                                            "Foo",
     595                 :            :                                            "/org/gtk/GDBus/ExampleInterface",
     596                 :            :                                            NULL,
     597                 :            :                                            G_DBUS_SIGNAL_FLAGS_NONE,
     598                 :            :                                            test_connection_signal_handler,
     599                 :            :                                            &count_s1,
     600                 :            :                                            NULL);
     601                 :          1 :   s2 = g_dbus_connection_signal_subscribe (c1,
     602                 :            :                                            NULL, /* match any sender */
     603                 :            :                                            "org.gtk.GDBus.ExampleInterface",
     604                 :            :                                            "Foo",
     605                 :            :                                            "/org/gtk/GDBus/ExampleInterface",
     606                 :            :                                            NULL,
     607                 :            :                                            G_DBUS_SIGNAL_FLAGS_NONE,
     608                 :            :                                            test_connection_signal_handler,
     609                 :            :                                            &count_s2,
     610                 :            :                                            NULL);
     611                 :          1 :   s3 = g_dbus_connection_signal_subscribe (c1,
     612                 :            :                                            "org.freedesktop.DBus",  /* sender */
     613                 :            :                                            "org.freedesktop.DBus",  /* interface */
     614                 :            :                                            "NameOwnerChanged",      /* member */
     615                 :            :                                            "/org/freedesktop/DBus", /* path */
     616                 :            :                                            NULL,
     617                 :            :                                            G_DBUS_SIGNAL_FLAGS_NONE,
     618                 :            :                                            test_connection_signal_handler,
     619                 :            :                                            &count_name_owner_changed,
     620                 :            :                                            NULL);
     621                 :            :   /* Note that s1b is *just like* s1 - this is to catch a bug where N
     622                 :            :    * subscriptions of the same rule causes N calls to each of the N
     623                 :            :    * subscriptions instead of just 1 call to each of the N subscriptions.
     624                 :            :    */
     625                 :          1 :   s1b = g_dbus_connection_signal_subscribe (c1,
     626                 :            :                                             ":1.2",
     627                 :            :                                             "org.gtk.GDBus.ExampleInterface",
     628                 :            :                                             "Foo",
     629                 :            :                                             "/org/gtk/GDBus/ExampleInterface",
     630                 :            :                                             NULL,
     631                 :            :                                             G_DBUS_SIGNAL_FLAGS_NONE,
     632                 :            :                                             test_connection_signal_handler,
     633                 :            :                                             &count_s1b,
     634                 :            :                                             NULL);
     635                 :          1 :   g_assert_cmpuint (s1, !=, 0);
     636                 :          1 :   g_assert_cmpuint (s1b, !=, 0);
     637                 :          1 :   g_assert_cmpuint (s2, !=, 0);
     638                 :          1 :   g_assert_cmpuint (s3, !=, 0);
     639                 :            : 
     640                 :          1 :   count_s1 = 0;
     641                 :          1 :   count_s1b = 0;
     642                 :          1 :   count_s2 = 0;
     643                 :          1 :   count_name_owner_changed = 0;
     644                 :            : 
     645                 :            :   /*
     646                 :            :    * Make c2 emit "Foo" - we should catch it twice
     647                 :            :    *
     648                 :            :    * Note that there is no way to be sure that the signal subscriptions
     649                 :            :    * on c1 are effective yet - for all we know, the AddMatch() messages
     650                 :            :    * could sit waiting in a buffer somewhere between this process and
     651                 :            :    * the message bus. And emitting signals on c2 (a completely other
     652                 :            :    * socket!) will not necessarily change this.
     653                 :            :    *
     654                 :            :    * To ensure this is not the case, do a synchronous call on c1.
     655                 :            :    */
     656                 :          1 :   result = g_dbus_connection_call_sync (c1,
     657                 :            :                                         "org.freedesktop.DBus",  /* bus name */
     658                 :            :                                         "/org/freedesktop/DBus", /* object path */
     659                 :            :                                         "org.freedesktop.DBus",  /* interface name */
     660                 :            :                                         "GetId",                 /* method name */
     661                 :            :                                         NULL,                    /* parameters */
     662                 :            :                                         NULL,                    /* return type */
     663                 :            :                                         G_DBUS_CALL_FLAGS_NONE,
     664                 :            :                                         -1,
     665                 :            :                                         NULL,
     666                 :            :                                         &error);
     667                 :          1 :   g_assert_no_error (error);
     668                 :          1 :   g_assert_nonnull (result);
     669                 :          1 :   g_variant_unref (result);
     670                 :            : 
     671                 :            :   /*
     672                 :            :    * Bring up two other connections
     673                 :            :    */
     674                 :          1 :   c2 = _g_bus_get_priv (G_BUS_TYPE_SESSION, NULL, NULL);
     675                 :          1 :   g_assert_nonnull (c2);
     676                 :          1 :   g_assert_false (g_dbus_connection_is_closed (c2));
     677                 :          1 :   g_assert_cmpstr (g_dbus_connection_get_unique_name (c2), ==, ":1.2");
     678                 :          1 :   c3 = _g_bus_get_priv (G_BUS_TYPE_SESSION, NULL, NULL);
     679                 :          1 :   g_assert_nonnull (c3);
     680                 :          1 :   g_assert_false (g_dbus_connection_is_closed (c3));
     681                 :          1 :   g_assert_cmpstr (g_dbus_connection_get_unique_name (c3), ==, ":1.3");
     682                 :            : 
     683                 :            :   /* now, emit the signal on c2 */
     684                 :          1 :   ret = g_dbus_connection_emit_signal (c2,
     685                 :            :                                        NULL, /* destination bus name */
     686                 :            :                                        "/org/gtk/GDBus/ExampleInterface",
     687                 :            :                                        "org.gtk.GDBus.ExampleInterface",
     688                 :            :                                        "Foo",
     689                 :            :                                        NULL,
     690                 :            :                                        &error);
     691                 :          1 :   g_assert_no_error (error);
     692                 :          1 :   g_assert_true (ret);
     693   [ +  +  +  + ]:          4 :   while (!(count_s1 >= 1 && count_s2 >= 1))
     694                 :          3 :     g_main_loop_run (loop);
     695                 :          1 :   g_assert_cmpint (count_s1, ==, 1);
     696                 :          1 :   g_assert_cmpint (count_s2, ==, 1);
     697                 :            : 
     698                 :            :   /*
     699                 :            :    * Make c3 emit "Foo" - we should catch it only once
     700                 :            :    */
     701                 :          1 :   ret = g_dbus_connection_emit_signal (c3,
     702                 :            :                                        NULL, /* destination bus name */
     703                 :            :                                        "/org/gtk/GDBus/ExampleInterface",
     704                 :            :                                        "org.gtk.GDBus.ExampleInterface",
     705                 :            :                                        "Foo",
     706                 :            :                                        NULL,
     707                 :            :                                        &error);
     708                 :          1 :   g_assert_no_error (error);
     709                 :          1 :   g_assert_true (ret);
     710   [ -  +  +  + ]:          2 :   while (!(count_s1 == 1 && count_s2 == 2))
     711                 :          1 :     g_main_loop_run (loop);
     712                 :          1 :   g_assert_cmpint (count_s1, ==, 1);
     713                 :          1 :   g_assert_cmpint (count_s2, ==, 2);
     714                 :            : 
     715                 :            :   /*
     716                 :            :    * Also to check the total amount of NameOwnerChanged signals - use a 5 second ceiling
     717                 :            :    * to avoid spinning forever
     718                 :            :    */
     719                 :          1 :   quit_mainloop_fired = FALSE;
     720                 :          1 :   quit_mainloop_id = g_timeout_add (30000, test_connection_quit_mainloop, &quit_mainloop_fired);
     721   [ -  +  -  - ]:          1 :   while (count_name_owner_changed < 2 && !quit_mainloop_fired)
     722                 :          0 :     g_main_loop_run (loop);
     723                 :          1 :   g_source_remove (quit_mainloop_id);
     724                 :          1 :   g_assert_cmpint (count_s1, ==, 1);
     725                 :          1 :   g_assert_cmpint (count_s2, ==, 2);
     726                 :          1 :   g_assert_cmpint (count_name_owner_changed, ==, 2);
     727                 :            : 
     728                 :          1 :   g_dbus_connection_signal_unsubscribe (c1, s1);
     729                 :          1 :   g_dbus_connection_signal_unsubscribe (c1, s2);
     730                 :          1 :   g_dbus_connection_signal_unsubscribe (c1, s3);
     731                 :          1 :   g_dbus_connection_signal_unsubscribe (c1, s1b);
     732                 :            : 
     733                 :          1 :   g_object_unref (c1);
     734                 :          1 :   g_object_unref (c2);
     735                 :          1 :   g_object_unref (c3);
     736                 :            : 
     737                 :          1 :   session_bus_down ();
     738                 :          1 : }
     739                 :            : 
     740                 :            : static void
     741                 :         19 : test_match_rule (GDBusConnection  *connection,
     742                 :            :                  GDBusSignalFlags  flags,
     743                 :            :                  gchar            *arg0_rule,
     744                 :            :                  gchar            *arg0,
     745                 :            :                  const gchar      *signal_type,
     746                 :            :                  gboolean          should_match)
     747                 :            : {
     748                 :            :   guint subscription_ids[2];
     749                 :         19 :   gint emissions = 0;
     750                 :         19 :   gint matches = 0;
     751                 :         19 :   GError *error = NULL;
     752                 :            : 
     753                 :         19 :   subscription_ids[0] = g_dbus_connection_signal_subscribe (connection,
     754                 :            :                                                             NULL, "org.gtk.ExampleInterface", "Foo", "/",
     755                 :            :                                                             NULL,
     756                 :            :                                                             G_DBUS_SIGNAL_FLAGS_NONE,
     757                 :            :                                                             test_connection_signal_handler,
     758                 :            :                                                             &emissions, NULL);
     759                 :         19 :   subscription_ids[1] = g_dbus_connection_signal_subscribe (connection,
     760                 :            :                                                             NULL, "org.gtk.ExampleInterface", "Foo", "/",
     761                 :            :                                                             arg0_rule,
     762                 :            :                                                             flags,
     763                 :            :                                                             test_connection_signal_handler,
     764                 :            :                                                             &matches, NULL);
     765                 :         19 :   g_assert_cmpint (subscription_ids[0], !=, 0);
     766                 :         19 :   g_assert_cmpint (subscription_ids[1], !=, 0);
     767                 :            : 
     768                 :         19 :   g_dbus_connection_emit_signal (connection,
     769                 :            :                                  NULL, "/", "org.gtk.ExampleInterface",
     770                 :            :                                  "Foo", g_variant_new (signal_type, arg0),
     771                 :            :                                  &error);
     772                 :         19 :   g_assert_no_error (error);
     773                 :            : 
     774                 :            :   /* synchronously ping a non-existent method to make sure the signals are dispatched */
     775                 :         19 :   g_dbus_connection_call_sync (connection, "org.gtk.ExampleInterface", "/", "org.gtk.ExampleInterface",
     776                 :            :                                "Bar", g_variant_new ("()"), G_VARIANT_TYPE_UNIT, G_DBUS_CALL_FLAGS_NONE,
     777                 :            :                                -1, NULL, NULL);
     778                 :            : 
     779         [ +  + ]:         38 :   while (g_main_context_iteration (NULL, FALSE))
     780                 :            :     ;
     781                 :            : 
     782                 :         19 :   g_assert_cmpint (emissions, ==, 1);
     783                 :         19 :   g_assert_cmpint (matches, ==, should_match ? 1 : 0);
     784                 :            : 
     785                 :         19 :   g_dbus_connection_signal_unsubscribe (connection, subscription_ids[0]);
     786                 :         19 :   g_dbus_connection_signal_unsubscribe (connection, subscription_ids[1]);
     787                 :         19 : }
     788                 :            : 
     789                 :            : static void
     790                 :          1 : test_connection_signal_match_rules (void)
     791                 :            : {
     792                 :            :   GDBusConnection *con;
     793                 :            : 
     794                 :          1 :   session_bus_up ();
     795                 :          1 :   con = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
     796                 :            : 
     797                 :          1 :   test_match_rule (con, G_DBUS_SIGNAL_FLAGS_NONE, "foo", "foo", "(s)", TRUE);
     798                 :          1 :   test_match_rule (con, G_DBUS_SIGNAL_FLAGS_NONE, "foo", "bar", "(s)", FALSE);
     799                 :            : 
     800                 :          1 :   test_match_rule (con, G_DBUS_SIGNAL_FLAGS_MATCH_ARG0_NAMESPACE, "org.gtk", "", "(s)", FALSE);
     801                 :          1 :   test_match_rule (con, G_DBUS_SIGNAL_FLAGS_MATCH_ARG0_NAMESPACE, "org.gtk", "org", "(s)", FALSE);
     802                 :          1 :   test_match_rule (con, G_DBUS_SIGNAL_FLAGS_MATCH_ARG0_NAMESPACE, "org.gtk", "org.gtk", "(s)", TRUE);
     803                 :          1 :   test_match_rule (con, G_DBUS_SIGNAL_FLAGS_MATCH_ARG0_NAMESPACE, "org.gtk", "org.gtk.Example", "(s)", TRUE);
     804                 :          1 :   test_match_rule (con, G_DBUS_SIGNAL_FLAGS_MATCH_ARG0_NAMESPACE, "org.gtk", "org.gtk+", "(s)", FALSE);
     805                 :            : 
     806                 :          1 :   test_match_rule (con, G_DBUS_SIGNAL_FLAGS_MATCH_ARG0_PATH, "/", "/", "(s)", TRUE);
     807                 :          1 :   test_match_rule (con, G_DBUS_SIGNAL_FLAGS_MATCH_ARG0_PATH, "/", "", "(s)", FALSE);
     808                 :          1 :   test_match_rule (con, G_DBUS_SIGNAL_FLAGS_MATCH_ARG0_PATH, "/org/gtk/Example", "/org/gtk/Example", "(s)", TRUE);
     809                 :          1 :   test_match_rule (con, G_DBUS_SIGNAL_FLAGS_MATCH_ARG0_PATH, "/org/gtk/", "/org/gtk/Example", "(s)", TRUE);
     810                 :          1 :   test_match_rule (con, G_DBUS_SIGNAL_FLAGS_MATCH_ARG0_PATH, "/org/gtk/Example", "/org/gtk/", "(s)", TRUE);
     811                 :          1 :   test_match_rule (con, G_DBUS_SIGNAL_FLAGS_MATCH_ARG0_PATH, "/org/gtk/Example", "/org/gtk", "(s)", FALSE);
     812                 :          1 :   test_match_rule (con, G_DBUS_SIGNAL_FLAGS_MATCH_ARG0_PATH, "/org/gtk+", "/org/gtk", "(s)", FALSE);
     813                 :            : 
     814                 :          1 :   test_match_rule (con, G_DBUS_SIGNAL_FLAGS_MATCH_ARG0_PATH, "/", "/", "(o)", TRUE);
     815                 :          1 :   test_match_rule (con, G_DBUS_SIGNAL_FLAGS_MATCH_ARG0_PATH, "/org/gtk/Example", "/org/gtk/Example", "(o)", TRUE);
     816                 :          1 :   test_match_rule (con, G_DBUS_SIGNAL_FLAGS_MATCH_ARG0_PATH, "/org/gtk/", "/org/gtk/Example", "(o)", TRUE);
     817                 :          1 :   test_match_rule (con, G_DBUS_SIGNAL_FLAGS_MATCH_ARG0_PATH, "/org/gtk/Example", "/org/gtk", "(o)", FALSE);
     818                 :          1 :   test_match_rule (con, G_DBUS_SIGNAL_FLAGS_MATCH_ARG0_PATH, "/org/gtk+", "/org/gtk", "(o)", FALSE);
     819                 :            : 
     820                 :          1 :   g_object_unref (con);
     821                 :          1 :   session_bus_down ();
     822                 :          1 : }
     823                 :            : 
     824                 :            : /* ---------------------------------------------------------------------------------------------------- */
     825                 :            : 
     826                 :            : /* Accessed both from the test code and the filter function (in a worker thread)
     827                 :            :  * so all accesses must be atomic. */
     828                 :            : typedef struct
     829                 :            : {
     830                 :            :   GAsyncQueue *incoming_queue;  /* (element-type GDBusMessage) */
     831                 :            :   guint num_outgoing;  /* (atomic) */
     832                 :            : } FilterData;
     833                 :            : 
     834                 :            : /* Runs in a worker thread. */
     835                 :            : static GDBusMessage *
     836                 :          9 : filter_func (GDBusConnection *connection,
     837                 :            :              GDBusMessage    *message,
     838                 :            :              gboolean         incoming,
     839                 :            :              gpointer         user_data)
     840                 :            : {
     841                 :          9 :   FilterData *data = user_data;
     842                 :            : 
     843         [ +  + ]:          9 :   if (incoming)
     844                 :          5 :     g_async_queue_push (data->incoming_queue, g_object_ref (message));
     845                 :            :   else
     846                 :          4 :     g_atomic_int_inc (&data->num_outgoing);
     847                 :            : 
     848                 :          9 :   return message;
     849                 :            : }
     850                 :            : 
     851                 :            : static void
     852                 :          4 : wait_for_filtered_reply (GAsyncQueue *incoming_queue,
     853                 :            :                          guint32      expected_serial)
     854                 :            : {
     855                 :          4 :   GDBusMessage *popped_message = NULL;
     856                 :            : 
     857         [ +  - ]:          5 :   while ((popped_message = g_async_queue_pop (incoming_queue)) != NULL)
     858                 :            :     {
     859                 :          5 :       guint32 reply_serial = g_dbus_message_get_reply_serial (popped_message);
     860                 :          5 :       g_object_unref (popped_message);
     861         [ +  + ]:          5 :       if (reply_serial == expected_serial)
     862                 :          4 :         return;
     863                 :            :     }
     864                 :            : 
     865                 :            :   g_assert_not_reached ();
     866                 :            : }
     867                 :            : 
     868                 :            : typedef struct
     869                 :            : {
     870                 :            :   gboolean alter_incoming;
     871                 :            :   gboolean alter_outgoing;
     872                 :            : } FilterEffects;
     873                 :            : 
     874                 :            : /* Runs in a worker thread. */
     875                 :            : static GDBusMessage *
     876                 :          6 : other_filter_func (GDBusConnection *connection,
     877                 :            :                    GDBusMessage    *message,
     878                 :            :                    gboolean         incoming,
     879                 :            :                    gpointer         user_data)
     880                 :            : {
     881                 :          6 :   const FilterEffects *effects = user_data;
     882                 :            :   GDBusMessage *ret;
     883                 :            :   gboolean alter;
     884                 :            : 
     885         [ +  + ]:          6 :   if (incoming)
     886                 :          3 :     alter = effects->alter_incoming;
     887                 :            :   else
     888                 :          3 :     alter = effects->alter_outgoing;
     889                 :            : 
     890         [ +  + ]:          6 :   if (alter)
     891                 :            :     {
     892                 :            :       GDBusMessage *copy;
     893                 :            :       GVariant *body;
     894                 :            :       gchar *s;
     895                 :            :       gchar *s2;
     896                 :            : 
     897                 :          2 :       copy = g_dbus_message_copy (message, NULL);
     898                 :          2 :       g_object_unref (message);
     899                 :            : 
     900                 :          2 :       body = g_dbus_message_get_body (copy);
     901                 :          2 :       g_variant_get (body, "(s)", &s);
     902                 :          2 :       s2 = g_strdup_printf ("MOD: %s", s);
     903                 :          2 :       g_dbus_message_set_body (copy, g_variant_new ("(s)", s2));
     904                 :          2 :       g_free (s2);
     905                 :          2 :       g_free (s);
     906                 :            : 
     907                 :          2 :       ret = copy;
     908                 :            :     }
     909                 :            :   else
     910                 :            :     {
     911                 :          4 :       ret = message;
     912                 :            :     }
     913                 :            : 
     914                 :          6 :   return ret;
     915                 :            : }
     916                 :            : 
     917                 :            : static void
     918                 :          2 : test_connection_filter_name_owner_changed_signal_handler (GDBusConnection  *connection,
     919                 :            :                                                           const gchar      *sender_name,
     920                 :            :                                                           const gchar      *object_path,
     921                 :            :                                                           const gchar      *interface_name,
     922                 :            :                                                           const gchar      *signal_name,
     923                 :            :                                                           GVariant         *parameters,
     924                 :            :                                                           gpointer         user_data)
     925                 :            : {
     926                 :            :   const gchar *name;
     927                 :            :   const gchar *old_owner;
     928                 :            :   const gchar *new_owner;
     929                 :            : 
     930                 :          2 :   g_variant_get (parameters,
     931                 :            :                  "(&s&s&s)",
     932                 :            :                  &name,
     933                 :            :                  &old_owner,
     934                 :            :                  &new_owner);
     935                 :            : 
     936   [ +  +  +  - ]:          2 :   if (g_strcmp0 (name, "com.example.TestService") == 0 && strlen (new_owner) > 0)
     937                 :            :     {
     938                 :          1 :       g_main_loop_quit (loop);
     939                 :            :     }
     940                 :          2 : }
     941                 :            : 
     942                 :            : static gboolean
     943                 :          0 : test_connection_filter_on_timeout (gpointer user_data)
     944                 :            : {
     945                 :          0 :   g_printerr ("Timeout waiting 30 sec on service\n");
     946                 :            :   g_assert_not_reached ();
     947                 :            :   return G_SOURCE_REMOVE;
     948                 :            : }
     949                 :            : 
     950                 :            : static void
     951                 :          1 : test_connection_filter (void)
     952                 :            : {
     953                 :            :   GDBusConnection *c;
     954                 :          1 :   FilterData data = { NULL, 0 };
     955                 :            :   GDBusMessage *m;
     956                 :            :   GDBusMessage *m2;
     957                 :            :   GDBusMessage *r;
     958                 :            :   GError *error;
     959                 :            :   guint filter_id;
     960                 :            :   guint timeout_mainloop_id;
     961                 :            :   guint signal_handler_id;
     962                 :            :   FilterEffects effects;
     963                 :            :   GVariant *result;
     964                 :            :   const gchar *s;
     965                 :            :   guint32 serial_temp;
     966                 :            : 
     967                 :          1 :   session_bus_up ();
     968                 :            : 
     969                 :          1 :   error = NULL;
     970                 :          1 :   c = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
     971                 :          1 :   g_assert_no_error (error);
     972                 :          1 :   g_assert_nonnull (c);
     973                 :            : 
     974                 :          1 :   data.incoming_queue = g_async_queue_new_full (g_object_unref);
     975                 :          1 :   data.num_outgoing = 0;
     976                 :          1 :   filter_id = g_dbus_connection_add_filter (c,
     977                 :            :                                             filter_func,
     978                 :            :                                             &data,
     979                 :            :                                             NULL);
     980                 :            : 
     981                 :          1 :   m = g_dbus_message_new_method_call ("org.freedesktop.DBus", /* name */
     982                 :            :                                       "/org/freedesktop/DBus", /* path */
     983                 :            :                                       "org.freedesktop.DBus", /* interface */
     984                 :            :                                       "GetNameOwner");
     985                 :          1 :   g_dbus_message_set_body (m, g_variant_new ("(s)", "org.freedesktop.DBus"));
     986                 :          1 :   error = NULL;
     987                 :          1 :   g_dbus_connection_send_message (c, m, G_DBUS_SEND_MESSAGE_FLAGS_NONE, &serial_temp, &error);
     988                 :          1 :   g_assert_no_error (error);
     989                 :            : 
     990                 :          1 :   wait_for_filtered_reply (data.incoming_queue, serial_temp);
     991                 :            : 
     992                 :          1 :   m2 = g_dbus_message_copy (m, &error);
     993                 :          1 :   g_assert_no_error (error);
     994                 :          1 :   g_dbus_connection_send_message (c, m2, G_DBUS_SEND_MESSAGE_FLAGS_NONE, &serial_temp, &error);
     995                 :          1 :   g_object_unref (m2);
     996                 :          1 :   g_assert_no_error (error);
     997                 :            : 
     998                 :          1 :   wait_for_filtered_reply (data.incoming_queue, serial_temp);
     999                 :            : 
    1000                 :          1 :   m2 = g_dbus_message_copy (m, &error);
    1001                 :          1 :   g_assert_no_error (error);
    1002                 :          1 :   g_dbus_message_set_serial (m2, serial_temp);
    1003                 :            :   /* lock the message to test PRESERVE_SERIAL flag. */
    1004                 :          1 :   g_dbus_message_lock (m2);
    1005                 :          1 :   g_dbus_connection_send_message (c, m2, G_DBUS_SEND_MESSAGE_FLAGS_PRESERVE_SERIAL, &serial_temp, &error);
    1006                 :          1 :   g_object_unref (m2);
    1007                 :          1 :   g_assert_no_error (error);
    1008                 :            : 
    1009                 :          1 :   wait_for_filtered_reply (data.incoming_queue, serial_temp);
    1010                 :            : 
    1011                 :          1 :   m2 = g_dbus_message_copy (m, &error);
    1012                 :          1 :   g_assert_no_error (error);
    1013                 :          1 :   r = g_dbus_connection_send_message_with_reply_sync (c,
    1014                 :            :                                                       m2,
    1015                 :            :                                                       G_DBUS_SEND_MESSAGE_FLAGS_NONE,
    1016                 :            :                                                       -1,
    1017                 :            :                                                       &serial_temp,
    1018                 :            :                                                       NULL, /* GCancellable */
    1019                 :            :                                                       &error);
    1020                 :          1 :   g_object_unref (m2);
    1021                 :          1 :   g_assert_no_error (error);
    1022                 :          1 :   g_assert_nonnull (r);
    1023                 :          1 :   g_object_unref (r);
    1024                 :            : 
    1025                 :          1 :   wait_for_filtered_reply (data.incoming_queue, serial_temp);
    1026                 :          1 :   g_assert_cmpint (g_async_queue_length (data.incoming_queue), ==, 0);
    1027                 :            : 
    1028                 :          1 :   g_dbus_connection_remove_filter (c, filter_id);
    1029                 :            : 
    1030                 :          1 :   m2 = g_dbus_message_copy (m, &error);
    1031                 :          1 :   g_assert_no_error (error);
    1032                 :          1 :   r = g_dbus_connection_send_message_with_reply_sync (c,
    1033                 :            :                                                       m2,
    1034                 :            :                                                       G_DBUS_SEND_MESSAGE_FLAGS_NONE,
    1035                 :            :                                                       -1,
    1036                 :            :                                                       &serial_temp,
    1037                 :            :                                                       NULL, /* GCancellable */
    1038                 :            :                                                       &error);
    1039                 :          1 :   g_object_unref (m2);
    1040                 :          1 :   g_assert_no_error (error);
    1041                 :          1 :   g_assert_nonnull (r);
    1042                 :          1 :   g_object_unref (r);
    1043                 :          1 :   g_assert_cmpint (g_async_queue_length (data.incoming_queue), ==, 0);
    1044                 :          1 :   g_assert_cmpint (g_atomic_int_get (&data.num_outgoing), ==, 4);
    1045                 :            : 
    1046                 :            :   /* wait for service to be available */
    1047                 :          1 :   signal_handler_id = g_dbus_connection_signal_subscribe (c,
    1048                 :            :                                                           "org.freedesktop.DBus", /* sender */
    1049                 :            :                                                           "org.freedesktop.DBus",
    1050                 :            :                                                           "NameOwnerChanged",
    1051                 :            :                                                           "/org/freedesktop/DBus",
    1052                 :            :                                                           NULL, /* arg0 */
    1053                 :            :                                                           G_DBUS_SIGNAL_FLAGS_NONE,
    1054                 :            :                                                           test_connection_filter_name_owner_changed_signal_handler,
    1055                 :            :                                                           NULL,
    1056                 :            :                                                           NULL);
    1057                 :          1 :   g_assert_cmpint (signal_handler_id, !=, 0);
    1058                 :            : 
    1059                 :            :   /* this is safe; testserver will exit once the bus goes away */
    1060                 :          1 :   g_assert_true (g_spawn_command_line_async (g_test_get_filename (G_TEST_BUILT, "gdbus-testserver", NULL), NULL));
    1061                 :            : 
    1062                 :          1 :   timeout_mainloop_id = g_timeout_add (30000, test_connection_filter_on_timeout, NULL);
    1063                 :          1 :   g_main_loop_run (loop);
    1064                 :          1 :   g_source_remove (timeout_mainloop_id);
    1065                 :          1 :   g_dbus_connection_signal_unsubscribe (c, signal_handler_id);
    1066                 :            : 
    1067                 :            :   /* now test some combinations... */
    1068                 :          1 :   filter_id = g_dbus_connection_add_filter (c,
    1069                 :            :                                             other_filter_func,
    1070                 :            :                                             &effects,
    1071                 :            :                                             NULL);
    1072                 :            :   /* -- */
    1073                 :          1 :   effects.alter_incoming = FALSE;
    1074                 :          1 :   effects.alter_outgoing = FALSE;
    1075                 :          1 :   error = NULL;
    1076                 :          1 :   result = g_dbus_connection_call_sync (c,
    1077                 :            :                                         "com.example.TestService",      /* bus name */
    1078                 :            :                                         "/com/example/TestObject",      /* object path */
    1079                 :            :                                         "com.example.Frob",             /* interface name */
    1080                 :            :                                         "HelloWorld",                   /* method name */
    1081                 :            :                                         g_variant_new ("(s)", "Cat"),   /* parameters */
    1082                 :            :                                         G_VARIANT_TYPE ("(s)"),         /* return type */
    1083                 :            :                                         G_DBUS_CALL_FLAGS_NONE,
    1084                 :            :                                         -1,
    1085                 :            :                                         NULL,
    1086                 :            :                                         &error);
    1087                 :          1 :   g_assert_no_error (error);
    1088                 :          1 :   g_variant_get (result, "(&s)", &s);
    1089                 :          1 :   g_assert_cmpstr (s, ==, "You greeted me with 'Cat'. Thanks!");
    1090                 :          1 :   g_variant_unref (result);
    1091                 :            :   /* -- */
    1092                 :          1 :   effects.alter_incoming = TRUE;
    1093                 :          1 :   effects.alter_outgoing = TRUE;
    1094                 :          1 :   error = NULL;
    1095                 :          1 :   result = g_dbus_connection_call_sync (c,
    1096                 :            :                                         "com.example.TestService",      /* bus name */
    1097                 :            :                                         "/com/example/TestObject",      /* object path */
    1098                 :            :                                         "com.example.Frob",             /* interface name */
    1099                 :            :                                         "HelloWorld",                   /* method name */
    1100                 :            :                                         g_variant_new ("(s)", "Cat"),   /* parameters */
    1101                 :            :                                         G_VARIANT_TYPE ("(s)"),         /* return type */
    1102                 :            :                                         G_DBUS_CALL_FLAGS_NONE,
    1103                 :            :                                         -1,
    1104                 :            :                                         NULL,
    1105                 :            :                                         &error);
    1106                 :          1 :   g_assert_no_error (error);
    1107                 :          1 :   g_variant_get (result, "(&s)", &s);
    1108                 :          1 :   g_assert_cmpstr (s, ==, "MOD: You greeted me with 'MOD: Cat'. Thanks!");
    1109                 :          1 :   g_variant_unref (result);
    1110                 :            : 
    1111                 :            : 
    1112                 :          1 :   g_dbus_connection_remove_filter (c, filter_id);
    1113                 :            : 
    1114                 :          1 :   g_object_unref (c);
    1115                 :          1 :   g_object_unref (m);
    1116                 :          1 :   g_async_queue_unref (data.incoming_queue);
    1117                 :            : 
    1118                 :          1 :   session_bus_down ();
    1119                 :          1 : }
    1120                 :            : 
    1121                 :            : /* ---------------------------------------------------------------------------------------------------- */
    1122                 :            : 
    1123                 :            : #define NUM_THREADS 50
    1124                 :            : 
    1125                 :            : static void
    1126                 :         52 : send_bogus_message (GDBusConnection *c, guint32 *out_serial)
    1127                 :            : {
    1128                 :            :   GDBusMessage *m;
    1129                 :            :   GError *error;
    1130                 :            : 
    1131                 :         52 :   m = g_dbus_message_new_method_call ("org.freedesktop.DBus", /* name */
    1132                 :            :                                       "/org/freedesktop/DBus", /* path */
    1133                 :            :                                       "org.freedesktop.DBus", /* interface */
    1134                 :            :                                       "GetNameOwner");
    1135                 :         52 :   g_dbus_message_set_body (m, g_variant_new ("(s)", "org.freedesktop.DBus"));
    1136                 :         52 :   error = NULL;
    1137                 :         52 :   g_dbus_connection_send_message (c, m, G_DBUS_SEND_MESSAGE_FLAGS_NONE, out_serial, &error);
    1138                 :         52 :   g_assert_no_error (error);
    1139                 :         52 :   g_object_unref (m);
    1140                 :         52 : }
    1141                 :            : 
    1142                 :            : #define SLEEP_USEC (100 * 1000)
    1143                 :            : 
    1144                 :            : static gpointer
    1145                 :         50 : serials_thread_func (GDBusConnection *c)
    1146                 :            : {
    1147                 :            :   guint32 message_serial;
    1148                 :            :   guint i;
    1149                 :            : 
    1150                 :            :   /* No calls on this thread yet */
    1151                 :         50 :   g_assert_cmpint (g_dbus_connection_get_last_serial(c), ==, 0);
    1152                 :            : 
    1153                 :            :   /* Send a bogus message and store its serial */
    1154                 :         50 :   message_serial = 0;
    1155                 :         50 :   send_bogus_message (c, &message_serial);
    1156                 :            : 
    1157                 :            :   /* Give it some time to actually send the message out. 10 seconds
    1158                 :            :    * should be plenty, even on slow machines. */
    1159         [ +  - ]:         50 :   for (i = 0; i < 10 * G_USEC_PER_SEC / SLEEP_USEC; i++)
    1160                 :            :     {
    1161         [ +  - ]:         50 :       if (g_dbus_connection_get_last_serial(c) != 0)
    1162                 :         50 :         break;
    1163                 :            : 
    1164                 :          0 :       g_usleep (SLEEP_USEC);
    1165                 :            :     }
    1166                 :            : 
    1167                 :         50 :   g_assert_cmpint (g_dbus_connection_get_last_serial(c), !=, 0);
    1168                 :         50 :   g_assert_cmpint (g_dbus_connection_get_last_serial(c), ==, message_serial);
    1169                 :            : 
    1170                 :         50 :   return NULL;
    1171                 :            : }
    1172                 :            : 
    1173                 :            : static void
    1174                 :          1 : test_connection_serials (void)
    1175                 :            : {
    1176                 :            :   GDBusConnection *c;
    1177                 :            :   GError *error;
    1178                 :            :   GThread *pool[NUM_THREADS];
    1179                 :            :   int i;
    1180                 :            : 
    1181                 :          1 :   session_bus_up ();
    1182                 :            : 
    1183                 :          1 :   error = NULL;
    1184                 :          1 :   c = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
    1185                 :          1 :   g_assert_no_error (error);
    1186                 :          1 :   g_assert_nonnull (c);
    1187                 :            : 
    1188                 :            :   /* Status after initialization */
    1189                 :          1 :   g_assert_cmpint (g_dbus_connection_get_last_serial (c), ==, 1);
    1190                 :            : 
    1191                 :            :   /* Send a bogus message */
    1192                 :          1 :   send_bogus_message (c, NULL);
    1193                 :          1 :   g_assert_cmpint (g_dbus_connection_get_last_serial (c), ==, 2);
    1194                 :            : 
    1195                 :            :   /* Start the threads */
    1196         [ +  + ]:         51 :   for (i = 0; i < NUM_THREADS; i++)
    1197                 :         50 :     pool[i] = g_thread_new (NULL, (GThreadFunc) serials_thread_func, c);
    1198                 :            : 
    1199                 :            :   /* Wait until threads are finished */
    1200         [ +  + ]:         51 :   for (i = 0; i < NUM_THREADS; i++)
    1201                 :         50 :       g_thread_join (pool[i]);
    1202                 :            : 
    1203                 :            :   /* No calls in between on this thread, should be the last value */
    1204                 :          1 :   g_assert_cmpint (g_dbus_connection_get_last_serial (c), ==, 2);
    1205                 :            : 
    1206                 :          1 :   send_bogus_message (c, NULL);
    1207                 :            : 
    1208                 :            :   /* All above calls + calls in threads */
    1209                 :          1 :   g_assert_cmpint (g_dbus_connection_get_last_serial (c), ==, 3 + NUM_THREADS);
    1210                 :            : 
    1211                 :          1 :   g_object_unref (c);
    1212                 :            : 
    1213                 :          1 :   session_bus_down ();
    1214                 :          1 : }
    1215                 :            : 
    1216                 :            : /* ---------------------------------------------------------------------------------------------------- */
    1217                 :            : 
    1218                 :            : static void
    1219                 :          1 : get_connection_cb_expect_cancel (GObject       *source_object,
    1220                 :            :                                  GAsyncResult  *res,
    1221                 :            :                                  gpointer       user_data)
    1222                 :            : {
    1223                 :            :   GDBusConnection *c;
    1224                 :            :   GError *error;
    1225                 :            : 
    1226                 :          1 :   error = NULL;
    1227                 :          1 :   c = g_bus_get_finish (res, &error);
    1228                 :            : 
    1229                 :            :   /* unref here to avoid timeouts when the test fails */
    1230         [ -  + ]:          1 :   if (c)
    1231                 :          0 :     g_object_unref (c);
    1232                 :            : 
    1233                 :          1 :   g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
    1234                 :          1 :   g_assert_null (c);
    1235                 :            : 
    1236                 :          1 :   g_error_free (error);
    1237                 :          1 : }
    1238                 :            : 
    1239                 :            : static void
    1240                 :          1 : get_connection_cb_expect_success (GObject       *source_object,
    1241                 :            :                                   GAsyncResult  *res,
    1242                 :            :                                   gpointer       user_data)
    1243                 :            : {
    1244                 :            :   GDBusConnection *c;
    1245                 :            :   GError *error;
    1246                 :            : 
    1247                 :          1 :   error = NULL;
    1248                 :          1 :   c = g_bus_get_finish (res, &error);
    1249                 :          1 :   g_assert_no_error (error);
    1250                 :          1 :   g_assert_nonnull (c);
    1251                 :            : 
    1252                 :          1 :   g_main_loop_quit (loop);
    1253                 :            : 
    1254                 :          1 :   g_object_unref (c);
    1255                 :          1 : }
    1256                 :            : 
    1257                 :            : static void
    1258                 :          1 : test_connection_cancel (void)
    1259                 :            : {
    1260                 :            :   GCancellable *cancellable, *cancellable2;
    1261                 :            : 
    1262                 :          1 :   g_test_summary ("Test that cancelling one of two racing g_bus_get() calls does not cancel the other one");
    1263                 :            : 
    1264                 :          1 :   session_bus_up ();
    1265                 :            : 
    1266                 :          1 :   cancellable = g_cancellable_new ();
    1267                 :          1 :   cancellable2 = g_cancellable_new ();
    1268                 :            : 
    1269                 :          1 :   g_bus_get (G_BUS_TYPE_SESSION, cancellable, get_connection_cb_expect_cancel, NULL);
    1270                 :          1 :   g_bus_get (G_BUS_TYPE_SESSION, cancellable2, get_connection_cb_expect_success, NULL);
    1271                 :          1 :   g_cancellable_cancel (cancellable);
    1272                 :          1 :   g_main_loop_run (loop);
    1273                 :            : 
    1274                 :          1 :   g_object_unref (cancellable);
    1275                 :          1 :   g_object_unref (cancellable2);
    1276                 :            : 
    1277                 :          1 :   session_bus_down ();
    1278                 :          1 : }
    1279                 :            : 
    1280                 :            : /* ---------------------------------------------------------------------------------------------------- */
    1281                 :            : 
    1282                 :            : static void
    1283                 :          1 : test_connection_basic (void)
    1284                 :            : {
    1285                 :            :   GDBusConnection *connection;
    1286                 :            :   GError *error;
    1287                 :            :   GDBusCapabilityFlags flags;
    1288                 :            :   GDBusConnectionFlags connection_flags;
    1289                 :            :   gchar *guid;
    1290                 :            :   gchar *name;
    1291                 :            :   gboolean closed;
    1292                 :            :   gboolean exit_on_close;
    1293                 :            :   GIOStream *stream;
    1294                 :            :   GCredentials *credentials;
    1295                 :            : 
    1296                 :          1 :   session_bus_up ();
    1297                 :            : 
    1298                 :          1 :   error = NULL;
    1299                 :          1 :   connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
    1300                 :          1 :   g_assert_no_error (error);
    1301                 :          1 :   g_assert_nonnull (connection);
    1302                 :            : 
    1303                 :          1 :   flags = g_dbus_connection_get_capabilities (connection);
    1304                 :          1 :   g_assert_true (flags == G_DBUS_CAPABILITY_FLAGS_NONE ||
    1305                 :            :                  flags == G_DBUS_CAPABILITY_FLAGS_UNIX_FD_PASSING);
    1306                 :            : 
    1307                 :          1 :   connection_flags = g_dbus_connection_get_flags (connection);
    1308                 :            :   /* Ignore G_DBUS_CONNECTION_FLAGS_CROSS_NAMESPACE, it's an
    1309                 :            :    * implementation detail whether we set it */
    1310                 :          1 :   connection_flags &= ~G_DBUS_CONNECTION_FLAGS_CROSS_NAMESPACE;
    1311                 :          1 :   g_assert_cmpint (connection_flags, ==,
    1312                 :            :                    G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT |
    1313                 :            :                    G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION);
    1314                 :            : 
    1315                 :          1 :   credentials = g_dbus_connection_get_peer_credentials (connection);
    1316                 :          1 :   g_assert_null (credentials);
    1317                 :            : 
    1318                 :          1 :   g_object_get (connection,
    1319                 :            :                 "stream", &stream,
    1320                 :            :                 "guid", &guid,
    1321                 :            :                 "unique-name", &name,
    1322                 :            :                 "closed", &closed,
    1323                 :            :                 "exit-on-close", &exit_on_close,
    1324                 :            :                 "capabilities", &flags,
    1325                 :            :                 NULL);
    1326                 :            : 
    1327                 :          1 :   g_assert_true (G_IS_IO_STREAM (stream));
    1328                 :          1 :   g_assert_true (g_dbus_is_guid (guid));
    1329                 :          1 :   g_assert_true (g_dbus_is_unique_name (name));
    1330                 :          1 :   g_assert_false (closed);
    1331                 :          1 :   g_assert_true (exit_on_close);
    1332                 :          1 :   g_assert_true (flags == G_DBUS_CAPABILITY_FLAGS_NONE ||
    1333                 :            :                  flags == G_DBUS_CAPABILITY_FLAGS_UNIX_FD_PASSING);
    1334                 :          1 :   g_object_unref (stream);
    1335                 :          1 :   g_free (name);
    1336                 :          1 :   g_free (guid);
    1337                 :            : 
    1338                 :          1 :   g_object_unref (connection);
    1339                 :            : 
    1340                 :          1 :   session_bus_down ();
    1341                 :          1 : }
    1342                 :            : 
    1343                 :            : /* ---------------------------------------------------------------------------------------------------- */
    1344                 :            : 
    1345                 :            : int
    1346                 :          1 : main (int   argc,
    1347                 :            :       char *argv[])
    1348                 :            : {
    1349                 :            :   int ret;
    1350                 :            : 
    1351                 :          1 :   g_test_init (&argc, &argv, G_TEST_OPTION_ISOLATE_DIRS, NULL);
    1352                 :            : 
    1353                 :            :   /* all the tests rely on a shared main loop */
    1354                 :          1 :   loop = g_main_loop_new (NULL, FALSE);
    1355                 :            : 
    1356                 :          1 :   g_test_dbus_unset ();
    1357                 :            : 
    1358                 :            :   /* gdbus cleanup is pretty racy due to worker threads, so always do this test first */
    1359                 :          1 :   g_test_add_func ("/gdbus/connection/bus-failure", test_connection_bus_failure);
    1360                 :            : 
    1361                 :          1 :   g_test_add_func ("/gdbus/connection/basic", test_connection_basic);
    1362                 :          1 :   g_test_add_func ("/gdbus/connection/life-cycle", test_connection_life_cycle);
    1363                 :          1 :   g_test_add_func ("/gdbus/connection/send", test_connection_send);
    1364                 :          1 :   g_test_add_func ("/gdbus/connection/signals", test_connection_signals);
    1365                 :          1 :   g_test_add_func ("/gdbus/connection/signal-match-rules", test_connection_signal_match_rules);
    1366                 :          1 :   g_test_add_func ("/gdbus/connection/filter", test_connection_filter);
    1367                 :          1 :   g_test_add_func ("/gdbus/connection/serials", test_connection_serials);
    1368                 :          1 :   g_test_add_func ("/gdbus/connection/cancel", test_connection_cancel);
    1369                 :          1 :   ret = g_test_run();
    1370                 :            : 
    1371                 :          1 :   g_main_loop_unref (loop);
    1372                 :          1 :   return ret;
    1373                 :            : }

Generated by: LCOV version 1.14