Branch data Line data Source code
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 : 2 : print_address (void)
38 : : {
39 : 2 : GError *error = NULL;
40 : : gchar *addr;
41 : :
42 : 2 : addr = g_dbus_address_get_for_bus_sync (G_BUS_TYPE_SESSION, NULL,
43 : : &error);
44 : :
45 : 2 : g_assert_no_error (error);
46 : 2 : g_assert_nonnull (addr);
47 : 2 : g_print ("%s\n", addr);
48 : 2 : g_free (addr);
49 : 2 : }
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 : 1 : set_up_mock_xdg_runtime_dir (void)
60 : : {
61 : 1 : GError *error = NULL;
62 : : GSocketAddress *addr;
63 : :
64 : 1 : mock_bus = g_socket_new (G_SOCKET_FAMILY_UNIX, G_SOCKET_TYPE_STREAM, 0,
65 : : &error);
66 : 1 : g_assert_no_error (error);
67 : 1 : g_assert_true (G_IS_SOCKET (mock_bus));
68 : :
69 : : /* alters tmpdir in-place */
70 : 1 : if (g_mkdtemp_full (tmpdir, 0700) == NULL)
71 : : {
72 : 0 : int errsv = errno;
73 : 0 : g_error ("g_mkdtemp_full: %s", g_strerror (errsv));
74 : : }
75 : :
76 : 1 : mock_bus_path = g_strconcat (tmpdir, "/bus", NULL);
77 : 1 : addr = g_unix_socket_address_new (mock_bus_path);
78 : 1 : g_socket_bind (mock_bus, addr, FALSE, &error);
79 : 1 : g_assert_no_error (error);
80 : 1 : g_object_unref (addr);
81 : :
82 : 1 : g_setenv ("XDG_RUNTIME_DIR", tmpdir, TRUE);
83 : 1 : }
84 : :
85 : : static void
86 : 1 : tear_down_mock_xdg_runtime_dir (void)
87 : : {
88 : 1 : GError *error = NULL;
89 : :
90 : 1 : g_socket_close (mock_bus, &error);
91 : 1 : g_assert_no_error (error);
92 : :
93 : 1 : if (g_unlink (mock_bus_path) < 0)
94 : : {
95 : 0 : int errsv = errno;
96 : 0 : g_error ("g_unlink(\"%s\"): %s", mock_bus_path, g_strerror (errsv));
97 : : }
98 : :
99 : 1 : if (g_rmdir (tmpdir) < 0)
100 : : {
101 : 0 : int errsv = errno;
102 : 0 : g_error ("g_rmdir(\"%s\"): %s", tmpdir, g_strerror (errsv));
103 : : }
104 : :
105 : 1 : g_clear_object (&mock_bus);
106 : 1 : g_clear_pointer (&mock_bus_path, g_free);
107 : 1 : }
108 : :
109 : : static gchar *path = NULL;
110 : :
111 : : static void
112 : 2 : set_up_mock_dbus_launch (void)
113 : : {
114 : 2 : path = g_strconcat (g_test_get_dir (G_TEST_BUILT), ":",
115 : : g_getenv ("PATH"), NULL);
116 : 2 : 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 : 2 : g_setenv ("DISPLAY", "an unrealistic mock X11 display", TRUE);
122 : 2 : }
123 : :
124 : : static void
125 : 2 : tear_down_mock_dbus_launch (void)
126 : : {
127 : 2 : g_clear_pointer (&path, g_free);
128 : 2 : }
129 : :
130 : : static void
131 : 2 : test_x11_autolaunch (void)
132 : : {
133 : 2 : if (g_test_subprocess ())
134 : : {
135 : 1 : g_unsetenv ("DISPLAY");
136 : 1 : g_unsetenv ("DBUS_SESSION_BUS_ADDRESS");
137 : 1 : g_unsetenv ("XDG_RUNTIME_DIR");
138 : 1 : g_unsetenv ("G_MESSAGES_DEBUG");
139 : 1 : set_up_mock_dbus_launch ();
140 : :
141 : 1 : print_address ();
142 : :
143 : 1 : tear_down_mock_dbus_launch ();
144 : 1 : return;
145 : : }
146 : :
147 : 1 : g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT);
148 : 1 : g_test_trap_assert_stderr_unmatched ("?*");
149 : 1 : g_test_trap_assert_stdout ("hello:this=address-is-from-the,mock=dbus-launch\n");
150 : 1 : g_test_trap_assert_passed ();
151 : : }
152 : :
153 : : static void
154 : 2 : test_xdg_runtime (void)
155 : : {
156 : 2 : if (g_test_subprocess ())
157 : : {
158 : 1 : g_unsetenv ("DISPLAY");
159 : 1 : g_unsetenv ("DBUS_SESSION_BUS_ADDRESS");
160 : 1 : set_up_mock_xdg_runtime_dir ();
161 : 1 : set_up_mock_dbus_launch ();
162 : :
163 : 1 : print_address ();
164 : :
165 : 1 : tear_down_mock_dbus_launch ();
166 : 1 : tear_down_mock_xdg_runtime_dir ();
167 : 1 : return;
168 : : }
169 : :
170 : 1 : g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT);
171 : 1 : g_test_trap_assert_stderr_unmatched ("?*");
172 : 1 : g_test_trap_assert_stdout ("unix:path=/tmp/gdbus%2Cunix%2Ctest.*/bus\n");
173 : 1 : 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 : 3 : main (int argc,
215 : : char *argv[])
216 : : {
217 : 3 : g_test_init (&argc, &argv, NULL);
218 : :
219 : : #ifdef G_OS_UNIX
220 : 3 : g_test_add_func ("/gdbus/x11-autolaunch", test_x11_autolaunch);
221 : 3 : 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 : 3 : return g_test_run ();
229 : : }
|