6 #include "gdbus-tests.h"
7 #include "gdbus-sessionbus.h"
9 static gint outstanding_watches;
10 static GMainLoop *main_loop;
14 gchar *expected_stdout;
16 gchar *expected_stderr;
21 check_data (gint fd, const gchar *expected)
26 len = strlen (expected);
27 buffer = g_alloca (len + 100);
28 actual = read (fd, buffer, len + 100);
30 g_assert_cmpint (actual, >=, 0);
33 memcmp (buffer, expected, len) != 0)
35 buffer[MIN(len + 100, actual)] = '\0';
37 g_error ("\nExpected\n-----\n%s-----\nGot (%s)\n-----\n%s-----\n",
39 (actual > len) ? "truncated" : "full", buffer);
48 ChildData *child = data;
50 g_assert_cmpint (status, ==, 0);
52 if (--outstanding_watches == 0)
53 g_main_loop_quit (main_loop);
55 check_data (child->stdout_pipe, child->expected_stdout);
56 close (child->stdout_pipe);
57 g_free (child->expected_stdout);
59 if (child->expected_stderr)
61 check_data (child->stderr_pipe, child->expected_stderr);
62 close (child->stderr_pipe);
63 g_free (child->expected_stderr);
66 g_slice_free (ChildData, child);
70 spawn (const gchar *expected_stdout,
71 const gchar *expected_stderr,
72 const gchar *first_arg,
85 va_start (ap, first_arg);
86 array = g_ptr_array_new ();
87 g_ptr_array_add (array, g_test_build_filename (G_TEST_BUILT, "basic-application", NULL));
88 for (arg = first_arg; arg; arg = va_arg (ap, const gchar *))
89 g_ptr_array_add (array, g_strdup (arg));
90 g_ptr_array_add (array, NULL);
91 args = (gchar **) g_ptr_array_free (array, FALSE);
94 env = g_environ_setenv (g_get_environ (), "TEST", "1", TRUE);
96 data = g_slice_new (ChildData);
97 data->expected_stdout = g_strdup (expected_stdout);
98 data->expected_stderr = g_strdup (expected_stderr);
100 g_spawn_async_with_pipes (NULL, args, env,
101 G_SPAWN_DO_NOT_REAP_CHILD,
102 NULL, NULL, &pid, NULL,
104 expected_stderr ? &data->stderr_pipe : NULL,
106 g_assert_no_error (error);
110 g_child_watch_add (pid, child_quit, data);
111 outstanding_watches++;
113 /* we block until the children write to stdout to make sure
114 * they have started, as they need to be executed in order;
115 * see https://bugzilla.gnome.org/show_bug.cgi?id=664627
117 fd.fd = data->stdout_pipe;
118 fd.events = G_IO_IN | G_IO_HUP | G_IO_ERR;
127 g_assert (outstanding_watches == 0);
130 c = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
132 main_loop = g_main_loop_new (NULL, 0);
134 /* spawn the master */
136 "open file:///a file:///b\n"
137 "exit status: 0\n", NULL,
140 /* send it some files */
141 spawn ("exit status: 0\n", NULL,
142 "./app", "/a", "/b", NULL);
144 g_main_loop_run (main_loop);
149 g_main_loop_unref (main_loop);
153 test_remote_command_line (void)
160 g_assert (outstanding_watches == 0);
163 c = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
165 main_loop = g_main_loop_new (NULL, 0);
167 file = g_file_new_for_commandline_arg ("foo");
168 cwd = g_get_current_dir ();
170 replies = g_strconcat ("got ./cmd 0\n",
172 "cmdline ./cmd echo --abc -d\n",
173 "environment TEST=1\n",
175 "file ", g_file_get_path (file), "\n",
183 g_object_unref (file);
185 /* spawn the master */
186 spawn (replies, NULL,
191 /* send it a few commandlines */
192 spawn ("exit status: 0\n", NULL,
195 spawn ("exit status: 0\n", NULL,
196 "./cmd", "echo", "--abc", "-d", NULL);
198 spawn ("exit status: 0\n", NULL,
199 "./cmd", "env", NULL);
201 spawn ("exit status: 0\n", NULL,
202 "./cmd", "getenv", NULL);
204 spawn ("print test\n"
205 "exit status: 0\n", NULL,
206 "./cmd", "print", "test", NULL);
208 spawn ("exit status: 0\n", "printerr test\n",
209 "./cmd", "printerr", "test", NULL);
211 spawn ("exit status: 0\n", NULL,
212 "./cmd", "file", "foo", NULL);
214 spawn ("exit status: 0\n", NULL,
215 "./cmd", "properties", NULL);
217 spawn ("exit status: 0\n", NULL,
218 "./cmd", "cwd", NULL);
220 spawn ("exit status: 0\n", NULL,
221 "./cmd", "busy", NULL);
223 spawn ("exit status: 0\n", NULL,
224 "./cmd", "idle", NULL);
226 spawn ("exit status: 0\n", NULL,
227 "./cmd", "stdin", NULL);
229 g_main_loop_run (main_loop);
234 g_main_loop_unref (main_loop);
238 /* Now that we register non-unique apps on the bus we need to fix the
239 * following test not to assume that it's safe to create multiple instances
240 * of the same app in one process.
242 * See https://bugzilla.gnome.org/show_bug.cgi?id=647986 for the patch that
243 * introduced this problem.
246 static GApplication *recently_activated;
247 static GMainLoop *loop;
250 nonunique_activate (GApplication *application)
252 recently_activated = application;
255 g_main_loop_quit (loop);
258 static GApplication *
259 make_app (gboolean non_unique)
264 app = g_application_new ("org.gtk.Test-Application",
265 non_unique ? G_APPLICATION_NON_UNIQUE : 0);
266 g_signal_connect (app, "activate", G_CALLBACK (nonunique_activate), NULL);
267 ok = g_application_register (app, NULL, NULL);
270 g_object_unref (app);
274 g_application_activate (app);
280 test_nonunique (void)
282 GApplication *first, *second, *third, *fourth;
286 first = make_app (TRUE);
287 /* non-remote because it is non-unique */
288 g_assert (!g_application_get_is_remote (first));
289 g_assert (recently_activated == first);
290 recently_activated = NULL;
292 second = make_app (FALSE);
293 /* non-remote because it is first */
294 g_assert (!g_application_get_is_remote (second));
295 g_assert (recently_activated == second);
296 recently_activated = NULL;
298 third = make_app (TRUE);
299 /* non-remote because it is non-unique */
300 g_assert (!g_application_get_is_remote (third));
301 g_assert (recently_activated == third);
302 recently_activated = NULL;
304 fourth = make_app (FALSE);
305 /* should have failed to register due to being
306 * unable to register the object paths
308 g_assert (fourth == NULL);
309 g_assert (recently_activated == NULL);
311 g_object_unref (first);
312 g_object_unref (second);
313 g_object_unref (third);
325 GApplicationFlags flags;
330 GError *error = NULL;
333 c = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
335 app = g_object_new (G_TYPE_APPLICATION,
336 "application-id", "org.gtk.TestApplication",
340 "application-id", &id,
342 "is-registered", ®istered,
343 "inactivity-timeout", &timeout,
346 g_assert_cmpstr (id, ==, "org.gtk.TestApplication");
347 g_assert_cmpint (flags, ==, G_APPLICATION_FLAGS_NONE);
348 g_assert (!registered);
349 g_assert_cmpint (timeout, ==, 0);
351 ret = g_application_register (G_APPLICATION (app), NULL, &error);
353 g_assert_no_error (error);
356 "is-registered", ®istered,
357 "is-remote", &remote,
360 g_assert (registered);
364 "inactivity-timeout", 1000,
367 g_application_quit (G_APPLICATION (app));
370 g_object_unref (app);
381 g_assert (!g_application_id_is_valid (""));
382 g_assert (!g_application_id_is_valid ("."));
383 g_assert (!g_application_id_is_valid ("a"));
384 g_assert (!g_application_id_is_valid ("abc"));
385 g_assert (!g_application_id_is_valid (".abc"));
386 g_assert (!g_application_id_is_valid ("abc."));
387 g_assert (!g_application_id_is_valid ("a..b"));
388 g_assert (!g_application_id_is_valid ("a/b"));
389 g_assert (!g_application_id_is_valid ("a\nb"));
390 g_assert (!g_application_id_is_valid ("a\nb"));
391 g_assert (!g_application_id_is_valid ("_a.b"));
392 g_assert (!g_application_id_is_valid ("-a.b"));
393 id = g_new0 (gchar, 261);
394 memset (id, 'a', 260);
397 g_assert (!g_application_id_is_valid (id));
400 g_assert (g_application_id_is_valid ("a.b"));
401 g_assert (g_application_id_is_valid ("A.B"));
402 g_assert (g_application_id_is_valid ("A-.B"));
403 g_assert (g_application_id_is_valid ("a_b.c-d"));
404 g_assert (g_application_id_is_valid ("org.gnome.SessionManager"));
407 static gboolean nodbus_activated;
410 release_app (gpointer user_data)
412 g_application_release (user_data);
413 return G_SOURCE_REMOVE;
417 nodbus_activate (GApplication *app)
419 nodbus_activated = TRUE;
420 g_application_hold (app);
422 g_assert (g_application_get_dbus_connection (app) == NULL);
423 g_assert (g_application_get_dbus_object_path (app) == NULL);
425 g_idle_add (release_app, app);
431 char *binpath = g_test_build_filename (G_TEST_BUILT, "unimportant", NULL);
432 gchar *argv[] = { binpath, NULL };
435 app = g_application_new ("org.gtk.Unimportant", G_APPLICATION_FLAGS_NONE);
436 g_signal_connect (app, "activate", G_CALLBACK (nodbus_activate), NULL);
437 g_application_run (app, 1, argv);
438 g_object_unref (app);
440 g_assert (nodbus_activated);
444 static gboolean noappid_activated;
447 noappid_activate (GApplication *app)
449 noappid_activated = TRUE;
450 g_application_hold (app);
452 g_assert (g_application_get_flags (app) & G_APPLICATION_NON_UNIQUE);
454 g_idle_add (release_app, app);
457 /* test that no appid -> non-unique */
461 char *binpath = g_test_build_filename (G_TEST_BUILT, "unimportant", NULL);
462 gchar *argv[] = { binpath, NULL };
465 app = g_application_new (NULL, G_APPLICATION_FLAGS_NONE);
466 g_signal_connect (app, "activate", G_CALLBACK (noappid_activate), NULL);
467 g_application_run (app, 1, argv);
468 g_object_unref (app);
470 g_assert (noappid_activated);
474 static gboolean activated;
475 static gboolean quitted;
478 quit_app (gpointer user_data)
481 g_application_quit (user_data);
482 return G_SOURCE_REMOVE;
486 quit_activate (GApplication *app)
489 g_application_hold (app);
491 g_assert (g_application_get_dbus_connection (app) != NULL);
492 g_assert (g_application_get_dbus_object_path (app) != NULL);
494 g_idle_add (quit_app, app);
501 char *binpath = g_test_build_filename (G_TEST_BUILT, "unimportant", NULL);
502 gchar *argv[] = { binpath, NULL };
506 c = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
508 app = g_application_new ("org.gtk.Unimportant",
509 G_APPLICATION_FLAGS_NONE);
512 g_signal_connect (app, "activate", G_CALLBACK (quit_activate), NULL);
513 g_application_run (app, 1, argv);
514 g_object_unref (app);
517 g_assert (activated);
525 on_activate (GApplication *app)
531 g_assert (!g_application_get_is_remote (app));
533 actions = g_action_group_list_actions (G_ACTION_GROUP (app));
534 g_assert (g_strv_length (actions) == 0);
535 g_strfreev (actions);
537 action = (GAction*)g_simple_action_new_stateful ("test", G_VARIANT_TYPE_BOOLEAN, g_variant_new_boolean (FALSE));
538 g_action_map_add_action (G_ACTION_MAP (app), action);
540 actions = g_action_group_list_actions (G_ACTION_GROUP (app));
541 g_assert (g_strv_length (actions) == 1);
542 g_strfreev (actions);
544 g_action_group_change_action_state (G_ACTION_GROUP (app), "test", g_variant_new_boolean (TRUE));
545 state = g_action_group_get_action_state (G_ACTION_GROUP (app), "test");
546 g_assert (g_variant_get_boolean (state) == TRUE);
548 action = g_action_map_lookup_action (G_ACTION_MAP (app), "test");
549 g_assert (action != NULL);
551 g_action_map_remove_action (G_ACTION_MAP (app), "test");
553 actions = g_action_group_list_actions (G_ACTION_GROUP (app));
554 g_assert (g_strv_length (actions) == 0);
555 g_strfreev (actions);
561 char *binpath = g_test_build_filename (G_TEST_BUILT, "unimportant", NULL);
562 gchar *argv[] = { binpath, NULL };
565 app = g_application_new ("org.gtk.Unimportant",
566 G_APPLICATION_FLAGS_NONE);
567 g_signal_connect (app, "activate", G_CALLBACK (on_activate), NULL);
568 g_application_run (app, 1, argv);
569 g_object_unref (app);
573 typedef GApplication TestLocCmdApp;
574 typedef GApplicationClass TestLocCmdAppClass;
576 static GType test_loc_cmd_app_get_type (void);
577 G_DEFINE_TYPE (TestLocCmdApp, test_loc_cmd_app, G_TYPE_APPLICATION)
580 test_loc_cmd_app_init (TestLocCmdApp *app)
585 test_loc_cmd_app_startup (GApplication *app)
587 g_assert_not_reached ();
591 test_loc_cmd_app_shutdown (GApplication *app)
593 g_assert_not_reached ();
597 test_loc_cmd_app_local_command_line (GApplication *application,
605 test_loc_cmd_app_class_init (TestLocCmdAppClass *klass)
607 G_APPLICATION_CLASS (klass)->startup = test_loc_cmd_app_startup;
608 G_APPLICATION_CLASS (klass)->shutdown = test_loc_cmd_app_shutdown;
609 G_APPLICATION_CLASS (klass)->local_command_line = test_loc_cmd_app_local_command_line;
613 test_local_command_line (void)
615 char *binpath = g_test_build_filename (G_TEST_BUILT, "unimportant", NULL);
616 gchar *argv[] = { binpath, "-invalid", NULL };
619 app = g_object_new (test_loc_cmd_app_get_type (),
620 "application-id", "org.gtk.Unimportant",
621 "flags", G_APPLICATION_FLAGS_NONE,
623 g_application_run (app, 1, argv);
624 g_object_unref (app);
629 main (int argc, char **argv)
631 g_test_init (&argc, &argv, NULL);
633 g_test_dbus_unset ();
635 g_test_add_func ("/gapplication/no-dbus", test_nodbus);
636 g_test_add_func ("/gapplication/basic", basic);
637 g_test_add_func ("/gapplication/no-appid", test_noappid);
638 /* g_test_add_func ("/gapplication/non-unique", test_nonunique); */
639 g_test_add_func ("/gapplication/properties", properties);
640 g_test_add_func ("/gapplication/app-id", appid);
641 g_test_add_func ("/gapplication/quit", test_quit);
642 g_test_add_func ("/gapplication/actions", test_actions);
643 g_test_add_func ("/gapplication/local-command-line", test_local_command_line);
644 g_test_add_func ("/gapplication/remote-command-line", test_remote_command_line);
646 return g_test_run ();