(root)/
glib-2.79.0/
gio/
tests/
gdbus-address-get-session.c
       1  /* GLib testing framework examples and tests
       2   *
       3   * Copyright © 2015 Collabora Ltd.
       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  
      21  #include <glib.h>
      22  
      23  /* This test does NOT depend on any dbus binaries preinstalled on test host.
      24   * On Unix it uses mock environment (test_xdg_runtime)
      25   * or mock dbus-launch binary (test_x11_autolaunch).
      26   * On Windows it relies on the fact that libgio provides
      27   * internal session dbus-server on win32.
      28   */
      29  
      30  #include <errno.h>
      31  
      32  #include <glib/gstdio.h>
      33  #include <gio/gio.h>
      34  #include <gio/gunixsocketaddress.h>
      35  
      36  static void
      37  print_address (void)
      38  {
      39    GError *error = NULL;
      40    gchar *addr;
      41  
      42    addr = g_dbus_address_get_for_bus_sync (G_BUS_TYPE_SESSION, NULL,
      43        &error);
      44  
      45    g_assert_no_error (error);
      46    g_assert_nonnull (addr);
      47    g_print ("%s\n", addr);
      48    g_free (addr);
      49  }
      50  
      51  #ifdef G_OS_UNIX
      52  
      53  static GSocket *mock_bus = NULL;
      54  static gchar *mock_bus_path = NULL;
      55  /* this is deliberately something that needs escaping */
      56  static gchar tmpdir[] = "/tmp/gdbus,unix,test.XXXXXX";
      57  
      58  static void
      59  set_up_mock_xdg_runtime_dir (void)
      60  {
      61    GError *error = NULL;
      62    GSocketAddress *addr;
      63  
      64    mock_bus = g_socket_new (G_SOCKET_FAMILY_UNIX, G_SOCKET_TYPE_STREAM, 0,
      65        &error);
      66    g_assert_no_error (error);
      67    g_assert_true (G_IS_SOCKET (mock_bus));
      68  
      69    /* alters tmpdir in-place */
      70    if (g_mkdtemp_full (tmpdir, 0700) == NULL)
      71      {
      72        int errsv = errno;
      73        g_error ("g_mkdtemp_full: %s", g_strerror (errsv));
      74      }
      75  
      76    mock_bus_path = g_strconcat (tmpdir, "/bus", NULL);
      77    addr = g_unix_socket_address_new (mock_bus_path);
      78    g_socket_bind (mock_bus, addr, FALSE, &error);
      79    g_assert_no_error (error);
      80    g_object_unref (addr);
      81  
      82    g_setenv ("XDG_RUNTIME_DIR", tmpdir, TRUE);
      83  }
      84  
      85  static void
      86  tear_down_mock_xdg_runtime_dir (void)
      87  {
      88    GError *error = NULL;
      89  
      90    g_socket_close (mock_bus, &error);
      91    g_assert_no_error (error);
      92  
      93    if (g_unlink (mock_bus_path) < 0)
      94      {
      95        int errsv = errno;
      96        g_error ("g_unlink(\"%s\"): %s", mock_bus_path, g_strerror (errsv));
      97      }
      98  
      99    if (g_rmdir (tmpdir) < 0)
     100      {
     101        int errsv = errno;
     102        g_error ("g_rmdir(\"%s\"): %s", tmpdir, g_strerror (errsv));
     103      }
     104  
     105    g_clear_object (&mock_bus);
     106    g_clear_pointer (&mock_bus_path, g_free);
     107  }
     108  
     109  static gchar *path = NULL;
     110  
     111  static void
     112  set_up_mock_dbus_launch (void)
     113  {
     114    path = g_strconcat (g_test_get_dir (G_TEST_BUILT), ":",
     115        g_getenv ("PATH"), NULL);
     116    g_setenv ("PATH", path, TRUE);
     117  
     118    /* libdbus won't even try X11 autolaunch if DISPLAY is unset; GDBus
     119     * does the same in Debian derivatives (proposed upstream in
     120     * GNOME#723506) */
     121    g_setenv ("DISPLAY", "an unrealistic mock X11 display", TRUE);
     122  }
     123  
     124  static void
     125  tear_down_mock_dbus_launch (void)
     126  {
     127    g_clear_pointer (&path, g_free);
     128  }
     129  
     130  static void
     131  test_x11_autolaunch (void)
     132  {
     133    if (g_test_subprocess ())
     134      {
     135        g_unsetenv ("DISPLAY");
     136        g_unsetenv ("DBUS_SESSION_BUS_ADDRESS");
     137        g_unsetenv ("XDG_RUNTIME_DIR");
     138        g_unsetenv ("G_MESSAGES_DEBUG");
     139        set_up_mock_dbus_launch ();
     140  
     141        print_address ();
     142  
     143        tear_down_mock_dbus_launch ();
     144        return;
     145      }
     146  
     147    g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT);
     148    g_test_trap_assert_stderr_unmatched ("?*");
     149    g_test_trap_assert_stdout ("hello:this=address-is-from-the,mock=dbus-launch\n");
     150    g_test_trap_assert_passed ();
     151  }
     152  
     153  static void
     154  test_xdg_runtime (void)
     155  {
     156    if (g_test_subprocess ())
     157      {
     158        g_unsetenv ("DISPLAY");
     159        g_unsetenv ("DBUS_SESSION_BUS_ADDRESS");
     160        set_up_mock_xdg_runtime_dir ();
     161        set_up_mock_dbus_launch ();
     162  
     163        print_address ();
     164  
     165        tear_down_mock_dbus_launch ();
     166        tear_down_mock_xdg_runtime_dir ();
     167        return;
     168      }
     169  
     170    g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT);
     171    g_test_trap_assert_stderr_unmatched ("?*");
     172    g_test_trap_assert_stdout ("unix:path=/tmp/gdbus%2Cunix%2Ctest.*/bus\n");
     173    g_test_trap_assert_passed ();
     174  }
     175  
     176  #endif
     177  
     178  #ifdef G_OS_WIN32
     179  static void
     180  check_and_cleanup_autolaunched_win32_bus (void)
     181  {
     182    /* win32 autostarted bus runs infinitely if no client ever connected.
     183     * However it exits in several seconds if the last client disconnects.
     184     * _This_ test only checks successful launching and connectivity,
     185     * and don't bother on bus termination behavior (being it a bug or not).
     186     * So connect+disconnect here is not only connectivity test,
     187     * but also the workaround the bus process infinite run.
     188     */
     189    GError *err = NULL;
     190    GDBusConnection *bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &err);
     191    g_assert_no_error (err);
     192    g_object_unref (bus);
     193  }
     194  
     195  static void
     196  test_win32_autolaunch (void)
     197  {
     198    if (g_test_subprocess ())
     199      {
     200        print_address ();
     201  
     202        check_and_cleanup_autolaunched_win32_bus ();
     203        return;
     204      }
     205  
     206    g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT);
     207    /* stderr is not checked: coverage prints warnings there */
     208    g_test_trap_assert_stdout ("nonce-tcp:host=localhost,port=*,noncefile=*\\gdbus-nonce-file-*\n");
     209    g_test_trap_assert_passed ();
     210  }
     211  #endif
     212  
     213  int
     214  main (int   argc,
     215        char *argv[])
     216  {
     217    g_test_init (&argc, &argv, NULL);
     218  
     219  #ifdef G_OS_UNIX
     220    g_test_add_func ("/gdbus/x11-autolaunch", test_x11_autolaunch);
     221    g_test_add_func ("/gdbus/xdg-runtime", test_xdg_runtime);
     222  #endif
     223  
     224  #ifdef G_OS_WIN32
     225    g_test_add_func ("/gdbus/win32-autolaunch", test_win32_autolaunch);
     226  #endif
     227  
     228    return g_test_run ();
     229  }