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 test_remote_actions (void)
242 g_assert (outstanding_watches == 0);
245 c = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
247 main_loop = g_main_loop_new (NULL, 0);
249 /* spawn the master */
250 spawn ("got ./cmd 0\n"
253 "exit status: 0\n", NULL,
256 spawn ("actions quit new action1 action2\n"
257 "exit status: 0\n", NULL,
258 "./actions", "list", NULL);
260 spawn ("exit status: 0\n", NULL,
261 "./actions", "activate", NULL);
263 spawn ("exit status: 0\n", NULL,
264 "./actions", "set-state", NULL);
266 g_main_loop_run (main_loop);
271 g_main_loop_unref (main_loop);
275 /* Now that we register non-unique apps on the bus we need to fix the
276 * following test not to assume that it's safe to create multiple instances
277 * of the same app in one process.
279 * See https://bugzilla.gnome.org/show_bug.cgi?id=647986 for the patch that
280 * introduced this problem.
283 static GApplication *recently_activated;
284 static GMainLoop *loop;
287 nonunique_activate (GApplication *application)
289 recently_activated = application;
292 g_main_loop_quit (loop);
295 static GApplication *
296 make_app (gboolean non_unique)
301 app = g_application_new ("org.gtk.Test-Application",
302 non_unique ? G_APPLICATION_NON_UNIQUE : 0);
303 g_signal_connect (app, "activate", G_CALLBACK (nonunique_activate), NULL);
304 ok = g_application_register (app, NULL, NULL);
307 g_object_unref (app);
311 g_application_activate (app);
317 test_nonunique (void)
319 GApplication *first, *second, *third, *fourth;
323 first = make_app (TRUE);
324 /* non-remote because it is non-unique */
325 g_assert (!g_application_get_is_remote (first));
326 g_assert (recently_activated == first);
327 recently_activated = NULL;
329 second = make_app (FALSE);
330 /* non-remote because it is first */
331 g_assert (!g_application_get_is_remote (second));
332 g_assert (recently_activated == second);
333 recently_activated = NULL;
335 third = make_app (TRUE);
336 /* non-remote because it is non-unique */
337 g_assert (!g_application_get_is_remote (third));
338 g_assert (recently_activated == third);
339 recently_activated = NULL;
341 fourth = make_app (FALSE);
342 /* should have failed to register due to being
343 * unable to register the object paths
345 g_assert (fourth == NULL);
346 g_assert (recently_activated == NULL);
348 g_object_unref (first);
349 g_object_unref (second);
350 g_object_unref (third);
362 GApplicationFlags flags;
367 GError *error = NULL;
370 c = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
372 app = g_object_new (G_TYPE_APPLICATION,
373 "application-id", "org.gtk.TestApplication",
377 "application-id", &id,
379 "is-registered", ®istered,
380 "inactivity-timeout", &timeout,
383 g_assert_cmpstr (id, ==, "org.gtk.TestApplication");
384 g_assert_cmpint (flags, ==, G_APPLICATION_FLAGS_NONE);
385 g_assert (!registered);
386 g_assert_cmpint (timeout, ==, 0);
388 ret = g_application_register (G_APPLICATION (app), NULL, &error);
390 g_assert_no_error (error);
393 "is-registered", ®istered,
394 "is-remote", &remote,
397 g_assert (registered);
401 "inactivity-timeout", 1000,
404 g_application_quit (G_APPLICATION (app));
407 g_object_unref (app);
418 g_assert (!g_application_id_is_valid (""));
419 g_assert (!g_application_id_is_valid ("."));
420 g_assert (!g_application_id_is_valid ("a"));
421 g_assert (!g_application_id_is_valid ("abc"));
422 g_assert (!g_application_id_is_valid (".abc"));
423 g_assert (!g_application_id_is_valid ("abc."));
424 g_assert (!g_application_id_is_valid ("a..b"));
425 g_assert (!g_application_id_is_valid ("a/b"));
426 g_assert (!g_application_id_is_valid ("a\nb"));
427 g_assert (!g_application_id_is_valid ("a\nb"));
428 g_assert (!g_application_id_is_valid ("_a.b"));
429 g_assert (!g_application_id_is_valid ("-a.b"));
430 id = g_new0 (gchar, 261);
431 memset (id, 'a', 260);
434 g_assert (!g_application_id_is_valid (id));
437 g_assert (g_application_id_is_valid ("a.b"));
438 g_assert (g_application_id_is_valid ("A.B"));
439 g_assert (g_application_id_is_valid ("A-.B"));
440 g_assert (g_application_id_is_valid ("a_b.c-d"));
441 g_assert (g_application_id_is_valid ("org.gnome.SessionManager"));
444 static gboolean nodbus_activated;
447 release_app (gpointer user_data)
449 g_application_release (user_data);
450 return G_SOURCE_REMOVE;
454 nodbus_activate (GApplication *app)
456 nodbus_activated = TRUE;
457 g_application_hold (app);
459 g_assert (g_application_get_dbus_connection (app) == NULL);
460 g_assert (g_application_get_dbus_object_path (app) == NULL);
462 g_idle_add (release_app, app);
468 char *binpath = g_test_build_filename (G_TEST_BUILT, "unimportant", NULL);
469 gchar *argv[] = { binpath, NULL };
472 app = g_application_new ("org.gtk.Unimportant", G_APPLICATION_FLAGS_NONE);
473 g_signal_connect (app, "activate", G_CALLBACK (nodbus_activate), NULL);
474 g_application_run (app, 1, argv);
475 g_object_unref (app);
477 g_assert (nodbus_activated);
481 static gboolean noappid_activated;
484 noappid_activate (GApplication *app)
486 noappid_activated = TRUE;
487 g_application_hold (app);
489 g_assert (g_application_get_flags (app) & G_APPLICATION_NON_UNIQUE);
491 g_idle_add (release_app, app);
494 /* test that no appid -> non-unique */
498 char *binpath = g_test_build_filename (G_TEST_BUILT, "unimportant", NULL);
499 gchar *argv[] = { binpath, NULL };
502 app = g_application_new (NULL, G_APPLICATION_FLAGS_NONE);
503 g_signal_connect (app, "activate", G_CALLBACK (noappid_activate), NULL);
504 g_application_run (app, 1, argv);
505 g_object_unref (app);
507 g_assert (noappid_activated);
511 static gboolean activated;
512 static gboolean quitted;
515 quit_app (gpointer user_data)
518 g_application_quit (user_data);
519 return G_SOURCE_REMOVE;
523 quit_activate (GApplication *app)
526 g_application_hold (app);
528 g_assert (g_application_get_dbus_connection (app) != NULL);
529 g_assert (g_application_get_dbus_object_path (app) != NULL);
531 g_idle_add (quit_app, app);
538 char *binpath = g_test_build_filename (G_TEST_BUILT, "unimportant", NULL);
539 gchar *argv[] = { binpath, NULL };
543 c = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
545 app = g_application_new ("org.gtk.Unimportant",
546 G_APPLICATION_FLAGS_NONE);
549 g_signal_connect (app, "activate", G_CALLBACK (quit_activate), NULL);
550 g_application_run (app, 1, argv);
551 g_object_unref (app);
554 g_assert (activated);
562 on_activate (GApplication *app)
568 g_assert (!g_application_get_is_remote (app));
570 actions = g_action_group_list_actions (G_ACTION_GROUP (app));
571 g_assert (g_strv_length (actions) == 0);
572 g_strfreev (actions);
574 action = (GAction*)g_simple_action_new_stateful ("test", G_VARIANT_TYPE_BOOLEAN, g_variant_new_boolean (FALSE));
575 g_action_map_add_action (G_ACTION_MAP (app), action);
577 actions = g_action_group_list_actions (G_ACTION_GROUP (app));
578 g_assert (g_strv_length (actions) == 1);
579 g_strfreev (actions);
581 g_action_group_change_action_state (G_ACTION_GROUP (app), "test", g_variant_new_boolean (TRUE));
582 state = g_action_group_get_action_state (G_ACTION_GROUP (app), "test");
583 g_assert (g_variant_get_boolean (state) == TRUE);
585 action = g_action_map_lookup_action (G_ACTION_MAP (app), "test");
586 g_assert (action != NULL);
588 g_action_map_remove_action (G_ACTION_MAP (app), "test");
590 actions = g_action_group_list_actions (G_ACTION_GROUP (app));
591 g_assert (g_strv_length (actions) == 0);
592 g_strfreev (actions);
596 test_local_actions (void)
598 char *binpath = g_test_build_filename (G_TEST_BUILT, "unimportant", NULL);
599 gchar *argv[] = { binpath, NULL };
602 app = g_application_new ("org.gtk.Unimportant",
603 G_APPLICATION_FLAGS_NONE);
604 g_signal_connect (app, "activate", G_CALLBACK (on_activate), NULL);
605 g_application_run (app, 1, argv);
606 g_object_unref (app);
610 typedef GApplication TestLocCmdApp;
611 typedef GApplicationClass TestLocCmdAppClass;
613 static GType test_loc_cmd_app_get_type (void);
614 G_DEFINE_TYPE (TestLocCmdApp, test_loc_cmd_app, G_TYPE_APPLICATION)
617 test_loc_cmd_app_init (TestLocCmdApp *app)
622 test_loc_cmd_app_startup (GApplication *app)
624 g_assert_not_reached ();
628 test_loc_cmd_app_shutdown (GApplication *app)
630 g_assert_not_reached ();
634 test_loc_cmd_app_local_command_line (GApplication *application,
642 test_loc_cmd_app_class_init (TestLocCmdAppClass *klass)
644 G_APPLICATION_CLASS (klass)->startup = test_loc_cmd_app_startup;
645 G_APPLICATION_CLASS (klass)->shutdown = test_loc_cmd_app_shutdown;
646 G_APPLICATION_CLASS (klass)->local_command_line = test_loc_cmd_app_local_command_line;
650 test_local_command_line (void)
652 char *binpath = g_test_build_filename (G_TEST_BUILT, "unimportant", NULL);
653 gchar *argv[] = { binpath, "-invalid", NULL };
656 app = g_object_new (test_loc_cmd_app_get_type (),
657 "application-id", "org.gtk.Unimportant",
658 "flags", G_APPLICATION_FLAGS_NONE,
660 g_application_run (app, 1, argv);
661 g_object_unref (app);
666 main (int argc, char **argv)
668 g_test_init (&argc, &argv, NULL);
670 g_test_dbus_unset ();
672 g_test_add_func ("/gapplication/no-dbus", test_nodbus);
673 g_test_add_func ("/gapplication/basic", basic);
674 g_test_add_func ("/gapplication/no-appid", test_noappid);
675 /* g_test_add_func ("/gapplication/non-unique", test_nonunique); */
676 g_test_add_func ("/gapplication/properties", properties);
677 g_test_add_func ("/gapplication/app-id", appid);
678 g_test_add_func ("/gapplication/quit", test_quit);
679 g_test_add_func ("/gapplication/local-actions", test_local_actions);
680 g_test_add_func ("/gapplication/remote-actions", test_remote_actions);
681 g_test_add_func ("/gapplication/local-command-line", test_local_command_line);
682 g_test_add_func ("/gapplication/remote-command-line", test_remote_command_line);
684 return g_test_run ();