GApplication: disable a broken test
[platform/upstream/glib.git] / gio / tests / gapplication.c
1 #include <gio/gio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <unistd.h>
5 #include "gdbus-sessionbus.h"
6
7 static gint outstanding_watches;
8 static GMainLoop *main_loop;
9
10 typedef struct
11 {
12   const gchar *expected_stdout;
13   gint stdout_pipe;
14 } ChildData;
15
16 static void
17 child_quit (GPid     pid,
18             gint     status,
19             gpointer data)
20 {
21   ChildData *child = data;
22   gssize expected, actual;
23   gchar *buffer;
24
25   g_assert_cmpint (status, ==, 0);
26
27   if (--outstanding_watches == 0)
28     g_main_loop_quit (main_loop);
29
30   expected = strlen (child->expected_stdout);
31   buffer = g_alloca (expected + 100);
32   actual = read (child->stdout_pipe, buffer, expected + 100);
33   close (child->stdout_pipe);
34
35   g_assert_cmpint (actual, >=, 0);
36
37   if (actual != expected ||
38       memcmp (buffer, child->expected_stdout, expected) != 0)
39     {
40       buffer[MIN(expected + 100, actual)] = '\0';
41
42       g_error ("\nExpected\n-----\n%s-----\nGot (%s)\n-----\n%s-----\n",
43                child->expected_stdout,
44                (actual > expected) ? "truncated" : "full", buffer);
45     }
46
47   g_slice_free (ChildData, child);
48 }
49
50 static void
51 spawn (const gchar *expected_stdout,
52        const gchar *first_arg,
53        ...)
54 {
55   GError *error = NULL;
56   const gchar *arg;
57   GPtrArray *array;
58   ChildData *data;
59   gchar **args;
60   va_list ap;
61   GPid pid;
62
63   va_start (ap, first_arg);
64   array = g_ptr_array_new ();
65   g_ptr_array_add (array, g_strdup ("./basic-application"));
66   for (arg = first_arg; arg; arg = va_arg (ap, const gchar *))
67     g_ptr_array_add (array, g_strdup (arg));
68   g_ptr_array_add (array, NULL);
69   args = (gchar **) g_ptr_array_free (array, FALSE);
70
71   data = g_slice_new (ChildData);
72   data->expected_stdout = expected_stdout;
73
74   g_spawn_async_with_pipes (NULL, args, NULL,
75                             G_SPAWN_DO_NOT_REAP_CHILD,
76                             NULL, NULL, &pid, NULL,
77                             &data->stdout_pipe, NULL, &error);
78   g_assert_no_error (error);
79
80   g_child_watch_add (pid, child_quit, data);
81   outstanding_watches++;
82 }
83
84 static void
85 basic (void)
86 {
87   session_bus_up ();
88
89   main_loop = g_main_loop_new (NULL, 0);
90
91   /* spawn the master */
92   spawn ("activated\n"
93          "open file:///a file:///b\n"
94          "cmdline '40 +' '2'\n"
95          "exit status: 0\n",
96          "./app", NULL);
97
98   /* make sure it becomes the master */
99   g_usleep (100000);
100
101   /* send it some files */
102   spawn ("exit status: 0\n",
103          "./app", "/a", "/b", NULL);
104
105   /* make sure the commandline arrives after the files */
106   g_usleep (100000);
107
108   spawn ("40 + 2 = 42\n"
109          "exit status: 42\n",
110          "./cmd", "40 +", "2", NULL);
111
112   g_main_loop_run (main_loop);
113
114   session_bus_down ();
115 }
116
117
118 static GApplication *recently_activated;
119 static GMainLoop *loop;
120
121 static void
122 nonunique_activate (GApplication *application)
123 {
124   recently_activated = application;
125
126   if (loop != NULL)
127     g_main_loop_quit (loop);
128 }
129
130 static GApplication *
131 make_app (gboolean non_unique)
132 {
133   GApplication *app;
134   gboolean ok;
135
136   app = g_application_new ("org.gtk.Test-Application",
137                            non_unique ? G_APPLICATION_NON_UNIQUE : 0);
138   g_signal_connect (app, "activate", G_CALLBACK (nonunique_activate), NULL);
139   ok = g_application_register (app, NULL, NULL);
140   if (!ok)
141     {
142       g_object_unref (app);
143       return NULL;
144     }
145
146   g_application_activate (app);
147
148   return app;
149 }
150
151 #if 0
152 Now that we register non-unique apps on the bus we need to fix the
153 following test not to assume that it's safe to create multiple instances
154 of the same app in one process.
155
156 See https://bugzilla.gnome.org/show_bug.cgi?id=647986 for the patch that
157 introduced this problem.
158
159 static void
160 test_nonunique (void)
161 {
162   GApplication *first, *second, *third, *fourth;
163
164   session_bus_up ();
165
166   first = make_app (TRUE);
167   /* non-remote because it is non-unique */
168   g_assert (!g_application_get_is_remote (first));
169   g_assert (recently_activated == first);
170   recently_activated = NULL;
171
172   second = make_app (FALSE);
173   /* non-remote because it is first */
174   g_assert (!g_application_get_is_remote (second));
175   g_assert (recently_activated == second);
176   recently_activated = NULL;
177
178   third = make_app (TRUE);
179   /* non-remote because it is non-unique */
180   g_assert (!g_application_get_is_remote (third));
181   g_assert (recently_activated == third);
182   recently_activated = NULL;
183
184   fourth = make_app (FALSE);
185   /* should have failed to register due to being
186    * unable to register the object paths
187    */
188   g_assert (fourth == NULL);
189   g_assert (recently_activated == NULL);
190
191   g_object_unref (first);
192   g_object_unref (second);
193   g_object_unref (third);
194
195   session_bus_down ();
196 }
197 #endif
198
199 static void
200 properties (void)
201 {
202   GObject *app;
203   gchar *id;
204   GApplicationFlags flags;
205   gboolean registered;
206   guint timeout;
207
208   app = g_object_new (G_TYPE_APPLICATION,
209                       "application-id", "org.gtk.TestApplication",
210                       NULL);
211
212   g_object_get (app,
213                 "application-id", &id,
214                 "flags", &flags,
215                 "is-registered", &registered,
216                 "inactivity-timeout", &timeout,
217                 NULL);
218
219   g_assert_cmpstr (id, ==, "org.gtk.TestApplication");
220   g_assert_cmpint (flags, ==, G_APPLICATION_FLAGS_NONE);
221   g_assert (!registered);
222   g_assert_cmpint (timeout, ==, 0);
223
224   g_object_unref (app);
225   g_free (id);
226 }
227
228 static void
229 appid (void)
230 {
231   gchar *id;
232
233   g_assert (!g_application_id_is_valid (""));
234   g_assert (!g_application_id_is_valid ("."));
235   g_assert (!g_application_id_is_valid ("a"));
236   g_assert (!g_application_id_is_valid ("abc"));
237   g_assert (!g_application_id_is_valid (".abc"));
238   g_assert (!g_application_id_is_valid ("abc."));
239   g_assert (!g_application_id_is_valid ("a..b"));
240   g_assert (!g_application_id_is_valid ("a/b"));
241   g_assert (!g_application_id_is_valid ("a\nb"));
242   g_assert (!g_application_id_is_valid ("a\nb"));
243   g_assert (!g_application_id_is_valid ("_a.b"));
244   g_assert (!g_application_id_is_valid ("-a.b"));
245   id = g_new0 (gchar, 261);
246   memset (id, 'a', 260);
247   id[1] = '.';
248   id[260] = 0;
249   g_assert (!g_application_id_is_valid (id));
250   g_free (id);
251
252   g_assert (g_application_id_is_valid ("a.b"));
253   g_assert (g_application_id_is_valid ("A.B"));
254   g_assert (g_application_id_is_valid ("A-.B"));
255   g_assert (g_application_id_is_valid ("a_b.c-d"));
256   g_assert (g_application_id_is_valid ("org.gnome.SessionManager"));
257 }
258
259 static gboolean nodbus_activated;
260
261 static gboolean
262 release_app (gpointer user_data)
263 {
264   g_application_release (user_data);
265   return G_SOURCE_REMOVE;
266 }
267
268 static void
269 nodbus_activate (GApplication *app)
270 {
271   nodbus_activated = TRUE;
272   g_application_hold (app);
273   g_idle_add (release_app, app);
274 }
275
276 static void
277 test_nodbus (void)
278 {
279   gchar *argv[] = { "./unimportant", NULL };
280   GDBusConnection *session;
281   GApplication *app;
282
283   session = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
284   g_assert (session == NULL);
285
286   app = g_application_new ("org.gtk.Unimportant",
287                            G_APPLICATION_FLAGS_NONE);
288   g_signal_connect (app, "activate", G_CALLBACK (nodbus_activate), NULL);
289   g_application_run (app, 1, argv);
290   g_object_unref (app);
291
292   g_assert (nodbus_activated);
293 }
294
295 int
296 main (int argc, char **argv)
297 {
298   g_type_init ();
299
300   g_test_init (&argc, &argv, NULL);
301
302   /* all the tests use a session bus with a well-known address
303    * that we can bring up and down using session_bus_up() and
304    * session_bus_down().
305    */
306   g_unsetenv ("DISPLAY");
307   g_setenv ("DBUS_SESSION_BUS_ADDRESS", session_bus_get_temporary_address (), TRUE);
308
309   g_test_add_func ("/gapplication/no-dbus", test_nodbus);
310   g_test_add_func ("/gapplication/basic", basic);
311 /*  g_test_add_func ("/gapplication/non-unique", test_nonunique); */
312   g_test_add_func ("/gapplication/properties", properties);
313   g_test_add_func ("/gapplication/app-id", appid);
314
315   return g_test_run ();
316 }