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

Generated by: LCOV version 2.0-1