1 /* -*- mode: C; c-file-style: "gnu" -*- */
2 /* dispatch.c Message dispatcher
4 * Copyright (C) 2003 CodeFactory AB
5 * Copyright (C) 2003, 2004, 2005 Red Hat, Inc.
6 * Copyright (C) 2004 Imendio HB
8 * Licensed under the Academic Free License version 2.1
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 #include "connection.h"
30 #include "activation.h"
35 #include <dbus/dbus-internals.h>
39 send_one_message (DBusConnection *connection,
41 DBusConnection *sender,
42 DBusConnection *addressed_recipient,
44 BusTransaction *transaction,
47 if (!bus_context_check_security_policy (context, transaction,
53 return TRUE; /* silently don't send it */
55 if (!bus_transaction_send (transaction,
67 bus_dispatch_matches (BusTransaction *transaction,
68 DBusConnection *sender,
69 DBusConnection *addressed_recipient,
74 BusConnections *connections;
76 BusMatchmaker *matchmaker;
80 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
82 /* sender and recipient can both be NULL for the bus driver,
83 * or for signals with no particular recipient
86 _dbus_assert (sender == NULL || bus_connection_is_active (sender));
87 _dbus_assert (dbus_message_get_sender (message) != NULL);
89 connections = bus_transaction_get_connections (transaction);
91 dbus_error_init (&tmp_error);
92 context = bus_transaction_get_context (transaction);
93 matchmaker = bus_context_get_matchmaker (context);
96 if (!bus_matchmaker_get_recipients (matchmaker, connections,
97 sender, addressed_recipient, message,
104 link = _dbus_list_get_first_link (&recipients);
107 DBusConnection *dest;
111 if (!send_one_message (dest, context, sender, addressed_recipient,
112 message, transaction, &tmp_error))
115 link = _dbus_list_get_next_link (&recipients, link);
118 _dbus_list_clear (&recipients);
120 if (dbus_error_is_set (&tmp_error))
122 dbus_move_error (&tmp_error, error);
129 static DBusHandlerResult
130 bus_dispatch (DBusConnection *connection,
131 DBusMessage *message)
133 const char *sender, *service_name;
135 BusTransaction *transaction;
137 DBusHandlerResult result;
138 DBusConnection *addressed_recipient;
140 result = DBUS_HANDLER_RESULT_HANDLED;
143 addressed_recipient = NULL;
144 dbus_error_init (&error);
146 context = bus_connection_get_context (connection);
147 _dbus_assert (context != NULL);
149 /* If we can't even allocate an OOM error, we just go to sleep
152 while (!bus_connection_preallocate_oom_error (connection))
153 _dbus_wait_for_memory ();
155 /* Ref connection in case we disconnect it at some point in here */
156 dbus_connection_ref (connection);
158 service_name = dbus_message_get_destination (message);
160 #ifdef DBUS_ENABLE_VERBOSE_MODE
162 const char *interface_name, *member_name, *error_name;
164 interface_name = dbus_message_get_interface (message);
165 member_name = dbus_message_get_member (message);
166 error_name = dbus_message_get_error_name (message);
168 _dbus_verbose ("DISPATCH: %s %s %s to %s\n",
169 interface_name ? interface_name : "(no interface)",
170 member_name ? member_name : "(no member)",
171 error_name ? error_name : "(no error name)",
172 service_name ? service_name : "peer");
174 #endif /* DBUS_ENABLE_VERBOSE_MODE */
176 /* If service_name is NULL, if it's a signal we send it to all
177 * connections with a match rule. If it's not a signal, there
178 * are some special cases here but mostly we just bail out.
180 if (service_name == NULL)
182 if (dbus_message_is_signal (message,
183 DBUS_INTERFACE_LOCAL,
186 bus_connection_disconnected (connection);
190 if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_SIGNAL)
192 /* DBusConnection also handles some of these automatically, we leave
195 result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
200 /* Create our transaction */
201 transaction = bus_transaction_new (context);
202 if (transaction == NULL)
204 BUS_SET_OOM (&error);
208 /* Assign a sender to the message */
209 if (bus_connection_is_active (connection))
211 sender = bus_connection_get_name (connection);
212 _dbus_assert (sender != NULL);
214 if (!dbus_message_set_sender (message, sender))
216 BUS_SET_OOM (&error);
220 /* We need to refetch the service name here, because
221 * dbus_message_set_sender can cause the header to be
222 * reallocated, and thus the service_name pointer will become
225 service_name = dbus_message_get_destination (message);
229 strcmp (service_name, DBUS_SERVICE_DBUS) == 0) /* to bus driver */
231 if (!bus_context_check_security_policy (context, transaction,
232 connection, NULL, NULL, message, &error))
234 _dbus_verbose ("Security policy rejected message\n");
238 _dbus_verbose ("Giving message to %s\n", DBUS_SERVICE_DBUS);
239 if (!bus_driver_handle_message (connection, transaction, message, &error))
242 else if (!bus_connection_is_active (connection)) /* clients must talk to bus driver first */
244 _dbus_verbose ("Received message from non-registered client. Disconnecting.\n");
245 dbus_connection_close (connection);
248 else if (service_name != NULL) /* route to named service */
250 DBusString service_string;
252 BusRegistry *registry;
254 _dbus_assert (service_name != NULL);
256 registry = bus_connection_get_registry (connection);
258 _dbus_string_init_const (&service_string, service_name);
259 service = bus_registry_lookup (registry, &service_string);
261 if (service == NULL && dbus_message_get_auto_start (message))
263 BusActivation *activation;
264 /* We can't do the security policy check here, since the addressed
265 * recipient service doesn't exist yet. We do it before sending the
266 * message after the service has been created.
268 activation = bus_connection_get_activation (connection);
270 if (!bus_activation_activate_service (activation, connection, transaction, TRUE,
271 message, service_name, &error))
273 _DBUS_ASSERT_ERROR_IS_SET (&error);
274 _dbus_verbose ("bus_activation_activate_service() failed: %s\n", error.name);
280 else if (service == NULL)
282 dbus_set_error (&error,
283 DBUS_ERROR_NAME_HAS_NO_OWNER,
284 "Name \"%s\" does not exist",
290 addressed_recipient = bus_service_get_primary_owners_connection (service);
291 _dbus_assert (addressed_recipient != NULL);
293 if (!bus_context_check_security_policy (context, transaction,
294 connection, addressed_recipient,
299 /* Dispatch the message */
300 if (!bus_transaction_send (transaction, addressed_recipient, message))
302 BUS_SET_OOM (&error);
308 /* Now match the messages against any match rules, which will send
309 * out signals and such. addressed_recipient may == NULL.
311 if (!bus_dispatch_matches (transaction, connection, addressed_recipient, message, &error))
315 if (dbus_error_is_set (&error))
317 if (!dbus_connection_get_is_connected (connection))
319 /* If we disconnected it, we won't bother to send it any error
322 _dbus_verbose ("Not sending error to connection we disconnected\n");
324 else if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
326 bus_connection_send_oom_error (connection, message);
328 /* cancel transaction due to OOM */
329 if (transaction != NULL)
331 bus_transaction_cancel_and_free (transaction);
337 /* Try to send the real error, if no mem to do that, send
340 _dbus_assert (transaction != NULL);
341 if (!bus_transaction_send_error_reply (transaction, connection,
344 bus_connection_send_oom_error (connection, message);
346 /* cancel transaction due to OOM */
347 if (transaction != NULL)
349 bus_transaction_cancel_and_free (transaction);
356 dbus_error_free (&error);
359 if (transaction != NULL)
361 bus_transaction_execute_and_free (transaction);
364 dbus_connection_unref (connection);
369 static DBusHandlerResult
370 bus_dispatch_message_filter (DBusConnection *connection,
371 DBusMessage *message,
374 return bus_dispatch (connection, message);
378 bus_dispatch_add_connection (DBusConnection *connection)
380 if (!dbus_connection_add_filter (connection,
381 bus_dispatch_message_filter,
389 bus_dispatch_remove_connection (DBusConnection *connection)
391 /* Here we tell the bus driver that we want to get off. */
392 bus_driver_remove_connection (connection);
394 dbus_connection_remove_filter (connection,
395 bus_dispatch_message_filter,
399 #ifdef DBUS_BUILD_TESTS
403 #include <sys/types.h>
407 /* This is used to know whether we need to block in order to finish
408 * sending a message, or whether the initial dbus_connection_send()
409 * already flushed the queue.
411 #define SEND_PENDING(connection) (dbus_connection_has_messages_to_send (connection))
413 typedef dbus_bool_t (* Check1Func) (BusContext *context);
414 typedef dbus_bool_t (* Check2Func) (BusContext *context,
415 DBusConnection *connection);
417 static dbus_bool_t check_no_leftovers (BusContext *context);
420 block_connection_until_message_from_bus (BusContext *context,
421 DBusConnection *connection,
422 const char *what_is_expected)
424 _dbus_verbose ("expecting: %s\n", what_is_expected);
426 while (dbus_connection_get_dispatch_status (connection) ==
427 DBUS_DISPATCH_COMPLETE &&
428 dbus_connection_get_is_connected (connection))
430 bus_test_run_bus_loop (context, TRUE);
431 bus_test_run_clients_loop (FALSE);
436 spin_connection_until_authenticated (BusContext *context,
437 DBusConnection *connection)
439 _dbus_verbose ("Spinning to auth connection %p\n", connection);
440 while (!dbus_connection_get_is_authenticated (connection) &&
441 dbus_connection_get_is_connected (connection))
443 bus_test_run_bus_loop (context, FALSE);
444 bus_test_run_clients_loop (FALSE);
446 _dbus_verbose (" ... done spinning to auth connection %p\n", connection);
449 /* compensate for fact that pop_message() can return #NULL due to OOM */
451 pop_message_waiting_for_memory (DBusConnection *connection)
453 while (dbus_connection_get_dispatch_status (connection) ==
454 DBUS_DISPATCH_NEED_MEMORY)
455 _dbus_wait_for_memory ();
457 return dbus_connection_pop_message (connection);
461 borrow_message_waiting_for_memory (DBusConnection *connection)
463 while (dbus_connection_get_dispatch_status (connection) ==
464 DBUS_DISPATCH_NEED_MEMORY)
465 _dbus_wait_for_memory ();
467 return dbus_connection_borrow_message (connection);
471 warn_unexpected_real (DBusConnection *connection,
472 DBusMessage *message,
473 const char *expected,
474 const char *function,
478 _dbus_warn ("%s:%d received message interface \"%s\" member \"%s\" error name \"%s\" on %p, expecting %s\n",
480 dbus_message_get_interface (message) ?
481 dbus_message_get_interface (message) : "(unset)",
482 dbus_message_get_member (message) ?
483 dbus_message_get_member (message) : "(unset)",
484 dbus_message_get_error_name (message) ?
485 dbus_message_get_error_name (message) : "(unset)",
489 _dbus_warn ("%s:%d received no message on %p, expecting %s\n",
490 function, line, connection, expected);
493 #define warn_unexpected(connection, message, expected) \
494 warn_unexpected_real (connection, message, expected, _DBUS_FUNCTION_NAME, __LINE__)
497 verbose_message_received (DBusConnection *connection,
498 DBusMessage *message)
500 _dbus_verbose ("Received message interface \"%s\" member \"%s\" error name \"%s\" on %p\n",
501 dbus_message_get_interface (message) ?
502 dbus_message_get_interface (message) : "(unset)",
503 dbus_message_get_member (message) ?
504 dbus_message_get_member (message) : "(unset)",
505 dbus_message_get_error_name (message) ?
506 dbus_message_get_error_name (message) : "(unset)",
519 ServiceInfoKind expected_kind;
520 const char *expected_service_name;
522 DBusConnection *skip_connection;
523 } CheckServiceOwnerChangedData;
526 check_service_owner_changed_foreach (DBusConnection *connection,
529 CheckServiceOwnerChangedData *d = data;
530 DBusMessage *message;
532 const char *service_name, *old_owner, *new_owner;
534 if (d->expected_kind == SERVICE_CREATED
535 && connection == d->skip_connection)
538 dbus_error_init (&error);
541 message = pop_message_waiting_for_memory (connection);
544 _dbus_warn ("Did not receive a message on %p, expecting %s\n",
545 connection, "NameOwnerChanged");
548 else if (!dbus_message_is_signal (message,
552 warn_unexpected (connection, message, "NameOwnerChanged");
558 reget_service_info_data:
563 dbus_message_get_args (message, &error,
564 DBUS_TYPE_STRING, &service_name,
565 DBUS_TYPE_STRING, &old_owner,
566 DBUS_TYPE_STRING, &new_owner,
569 if (dbus_error_is_set (&error))
571 if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
573 dbus_error_free (&error);
574 _dbus_wait_for_memory ();
575 goto reget_service_info_data;
579 _dbus_warn ("Did not get the expected arguments\n");
584 if ((d->expected_kind == SERVICE_CREATED && ( old_owner[0] || !new_owner[0]))
585 || (d->expected_kind == OWNER_CHANGED && (!old_owner[0] || !new_owner[0]))
586 || (d->expected_kind == SERVICE_DELETED && (!old_owner[0] || new_owner[0])))
588 _dbus_warn ("inconsistent NameOwnerChanged arguments\n");
592 if (strcmp (service_name, d->expected_service_name) != 0)
594 _dbus_warn ("expected info on service %s, got info on %s\n",
595 d->expected_service_name,
600 if (*service_name == ':' && new_owner[0]
601 && strcmp (service_name, new_owner) != 0)
603 _dbus_warn ("inconsistent ServiceOwnedChanged message (\"%s\" [ %s -> %s ])\n",
604 service_name, old_owner, new_owner);
612 dbus_error_free (&error);
615 dbus_message_unref (message);
622 kill_client_connection (BusContext *context,
623 DBusConnection *connection)
627 CheckServiceOwnerChangedData socd;
629 _dbus_verbose ("killing connection %p\n", connection);
631 s = dbus_bus_get_unique_name (connection);
632 _dbus_assert (s != NULL);
634 while ((base_service = _dbus_strdup (s)) == NULL)
635 _dbus_wait_for_memory ();
637 dbus_connection_ref (connection);
639 /* kick in the disconnect handler that unrefs the connection */
640 dbus_connection_close (connection);
642 bus_test_run_everything (context);
644 _dbus_assert (bus_test_client_listed (connection));
646 /* Run disconnect handler in test.c */
647 if (bus_connection_dispatch_one_message (connection))
648 _dbus_assert_not_reached ("something received on connection being killed other than the disconnect");
650 _dbus_assert (!dbus_connection_get_is_connected (connection));
651 dbus_connection_unref (connection);
653 _dbus_assert (!bus_test_client_listed (connection));
655 socd.expected_kind = SERVICE_DELETED;
656 socd.expected_service_name = base_service;
658 socd.skip_connection = NULL;
660 bus_test_clients_foreach (check_service_owner_changed_foreach,
663 dbus_free (base_service);
666 _dbus_assert_not_reached ("didn't get the expected NameOwnerChanged (deletion) messages");
668 if (!check_no_leftovers (context))
669 _dbus_assert_not_reached ("stuff left in message queues after disconnecting a client");
673 kill_client_connection_unchecked (DBusConnection *connection)
675 /* This kills the connection without expecting it to affect
676 * the rest of the bus.
678 _dbus_verbose ("Unchecked kill of connection %p\n", connection);
680 dbus_connection_ref (connection);
681 dbus_connection_close (connection);
682 /* dispatching disconnect handler will unref once */
683 if (bus_connection_dispatch_one_message (connection))
684 _dbus_assert_not_reached ("message other than disconnect dispatched after failure to register");
686 _dbus_assert (!bus_test_client_listed (connection));
687 dbus_connection_unref (connection);
693 } CheckNoMessagesData;
696 check_no_messages_foreach (DBusConnection *connection,
699 CheckNoMessagesData *d = data;
700 DBusMessage *message;
702 message = pop_message_waiting_for_memory (connection);
705 warn_unexpected (connection, message, "no messages");
711 dbus_message_unref (message);
716 check_no_leftovers (BusContext *context)
718 CheckNoMessagesData nmd;
721 bus_test_clients_foreach (check_no_messages_foreach,
726 _dbus_verbose ("%s: leftover message found\n",
727 _DBUS_FUNCTION_NAME);
734 /* returns TRUE if the correct thing happens,
735 * but the correct thing may include OOM errors.
738 check_hello_message (BusContext *context,
739 DBusConnection *connection)
741 DBusMessage *message;
742 DBusMessage *name_message;
743 dbus_uint32_t serial;
747 const char *acquired;
750 dbus_error_init (&error);
756 _dbus_verbose ("check_hello_message for %p\n", connection);
758 message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
766 dbus_connection_ref (connection); /* because we may get disconnected */
768 if (!dbus_connection_send (connection, message, &serial))
770 dbus_message_unref (message);
771 dbus_connection_unref (connection);
775 _dbus_assert (dbus_message_has_signature (message, ""));
777 dbus_message_unref (message);
780 if (!dbus_connection_get_is_connected (connection))
782 _dbus_verbose ("connection was disconnected (presumably auth failed)\n");
784 dbus_connection_unref (connection);
789 /* send our message */
790 bus_test_run_clients_loop (SEND_PENDING (connection));
792 if (!dbus_connection_get_is_connected (connection))
794 _dbus_verbose ("connection was disconnected (presumably auth failed)\n");
796 dbus_connection_unref (connection);
801 block_connection_until_message_from_bus (context, connection, "reply to Hello");
803 if (!dbus_connection_get_is_connected (connection))
805 _dbus_verbose ("connection was disconnected (presumably auth failed)\n");
807 dbus_connection_unref (connection);
812 dbus_connection_unref (connection);
814 message = pop_message_waiting_for_memory (connection);
817 _dbus_warn ("Did not receive a reply to %s %d on %p\n",
818 "Hello", serial, connection);
822 verbose_message_received (connection, message);
824 if (!dbus_message_has_sender (message, DBUS_SERVICE_DBUS))
826 _dbus_warn ("Message has wrong sender %s\n",
827 dbus_message_get_sender (message) ?
828 dbus_message_get_sender (message) : "(none)");
832 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
834 if (dbus_message_is_error (message,
835 DBUS_ERROR_NO_MEMORY))
837 ; /* good, this is a valid response */
841 warn_unexpected (connection, message, "not this error");
848 CheckServiceOwnerChangedData socd;
850 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_RETURN)
852 ; /* good, expected */
856 warn_unexpected (connection, message, "method return for Hello");
861 retry_get_hello_name:
862 if (!dbus_message_get_args (message, &error,
863 DBUS_TYPE_STRING, &name,
866 if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
868 _dbus_verbose ("no memory to get service name arg from hello\n");
869 dbus_error_free (&error);
870 _dbus_wait_for_memory ();
871 goto retry_get_hello_name;
875 _dbus_assert (dbus_error_is_set (&error));
876 _dbus_warn ("Did not get the expected single string argument to hello\n");
881 _dbus_verbose ("Got hello name: %s\n", name);
883 while (!dbus_bus_set_unique_name (connection, name))
884 _dbus_wait_for_memory ();
886 socd.expected_kind = SERVICE_CREATED;
887 socd.expected_service_name = name;
889 socd.skip_connection = connection; /* we haven't done AddMatch so won't get it ourselves */
890 bus_test_clients_foreach (check_service_owner_changed_foreach,
896 name_message = message;
897 /* Client should also have gotten ServiceAcquired */
899 message = pop_message_waiting_for_memory (connection);
902 _dbus_warn ("Expecting %s, got nothing\n",
906 if (! dbus_message_is_signal (message, DBUS_INTERFACE_DBUS,
909 _dbus_warn ("Expecting %s, got smthg else\n",
914 retry_get_acquired_name:
915 if (!dbus_message_get_args (message, &error,
916 DBUS_TYPE_STRING, &acquired,
919 if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
921 _dbus_verbose ("no memory to get service name arg from acquired\n");
922 dbus_error_free (&error);
923 _dbus_wait_for_memory ();
924 goto retry_get_acquired_name;
928 _dbus_assert (dbus_error_is_set (&error));
929 _dbus_warn ("Did not get the expected single string argument to ServiceAcquired\n");
934 _dbus_verbose ("Got acquired name: %s\n", acquired);
936 if (strcmp (acquired, name) != 0)
938 _dbus_warn ("Acquired name is %s but expected %s\n",
945 if (!check_no_leftovers (context))
951 _dbus_verbose ("ending %s retval = %d\n", _DBUS_FUNCTION_NAME, retval);
953 dbus_error_free (&error);
956 dbus_message_unref (message);
959 dbus_message_unref (name_message);
964 /* returns TRUE if the correct thing happens,
965 * but the correct thing may include OOM errors.
968 check_double_hello_message (BusContext *context,
969 DBusConnection *connection)
971 DBusMessage *message;
972 dbus_uint32_t serial;
977 dbus_error_init (&error);
980 _dbus_verbose ("check_double_hello_message for %p\n", connection);
982 message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
990 if (!dbus_connection_send (connection, message, &serial))
992 dbus_message_unref (message);
996 dbus_message_unref (message);
999 /* send our message */
1000 bus_test_run_clients_loop (SEND_PENDING (connection));
1002 dbus_connection_ref (connection); /* because we may get disconnected */
1003 block_connection_until_message_from_bus (context, connection, "reply to Hello");
1005 if (!dbus_connection_get_is_connected (connection))
1007 _dbus_verbose ("connection was disconnected: %s %d\n", _DBUS_FUNCTION_NAME, __LINE__);
1009 dbus_connection_unref (connection);
1014 dbus_connection_unref (connection);
1016 message = pop_message_waiting_for_memory (connection);
1017 if (message == NULL)
1019 _dbus_warn ("Did not receive a reply to %s %d on %p\n",
1020 "Hello", serial, connection);
1024 verbose_message_received (connection, message);
1026 if (!dbus_message_has_sender (message, DBUS_SERVICE_DBUS))
1028 _dbus_warn ("Message has wrong sender %s\n",
1029 dbus_message_get_sender (message) ?
1030 dbus_message_get_sender (message) : "(none)");
1034 if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_ERROR)
1036 warn_unexpected (connection, message, "method return for Hello");
1040 if (!check_no_leftovers (context))
1046 dbus_error_free (&error);
1049 dbus_message_unref (message);
1054 /* returns TRUE if the correct thing happens,
1055 * but the correct thing may include OOM errors.
1058 check_get_connection_unix_user (BusContext *context,
1059 DBusConnection *connection)
1061 DBusMessage *message;
1062 dbus_uint32_t serial;
1065 const char *base_service_name;
1069 dbus_error_init (&error);
1072 _dbus_verbose ("check_get_connection_unix_user for %p\n", connection);
1074 message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
1076 DBUS_INTERFACE_DBUS,
1077 "GetConnectionUnixUser");
1079 if (message == NULL)
1082 base_service_name = dbus_bus_get_unique_name (connection);
1084 if (!dbus_message_append_args (message,
1085 DBUS_TYPE_STRING, &base_service_name,
1088 dbus_message_unref (message);
1092 if (!dbus_connection_send (connection, message, &serial))
1094 dbus_message_unref (message);
1098 /* send our message */
1099 bus_test_run_clients_loop (SEND_PENDING (connection));
1101 dbus_message_unref (message);
1104 dbus_connection_ref (connection); /* because we may get disconnected */
1105 block_connection_until_message_from_bus (context, connection, "reply to GetConnectionUnixUser");
1107 if (!dbus_connection_get_is_connected (connection))
1109 _dbus_verbose ("connection was disconnected: %s %d\n", _DBUS_FUNCTION_NAME, __LINE__);
1111 dbus_connection_unref (connection);
1116 dbus_connection_unref (connection);
1118 message = pop_message_waiting_for_memory (connection);
1119 if (message == NULL)
1121 _dbus_warn ("Did not receive a reply to %s %d on %p\n",
1122 "GetConnectionUnixUser", serial, connection);
1126 verbose_message_received (connection, message);
1128 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
1130 if (dbus_message_is_error (message, DBUS_ERROR_NO_MEMORY))
1132 ; /* good, this is a valid response */
1136 warn_unexpected (connection, message, "not this error");
1143 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_RETURN)
1145 ; /* good, expected */
1149 warn_unexpected (connection, message,
1150 "method_return for GetConnectionUnixUser");
1157 if (!dbus_message_get_args (message, &error,
1158 DBUS_TYPE_UINT32, &uid,
1161 if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
1163 _dbus_verbose ("no memory to get uid by GetConnectionUnixUser\n");
1164 dbus_error_free (&error);
1165 _dbus_wait_for_memory ();
1166 goto retry_get_property;
1170 _dbus_assert (dbus_error_is_set (&error));
1171 _dbus_warn ("Did not get the expected DBUS_TYPE_UINT32 from GetConnectionUnixUser\n");
1177 if (!check_no_leftovers (context))
1183 dbus_error_free (&error);
1186 dbus_message_unref (message);
1191 /* returns TRUE if the correct thing happens,
1192 * but the correct thing may include OOM errors.
1195 check_get_connection_unix_process_id (BusContext *context,
1196 DBusConnection *connection)
1198 DBusMessage *message;
1199 dbus_uint32_t serial;
1202 const char *base_service_name;
1206 dbus_error_init (&error);
1209 _dbus_verbose ("check_get_connection_unix_process_id for %p\n", connection);
1211 message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
1213 DBUS_INTERFACE_DBUS,
1214 "GetConnectionUnixProcessID");
1216 if (message == NULL)
1219 base_service_name = dbus_bus_get_unique_name (connection);
1221 if (!dbus_message_append_args (message,
1222 DBUS_TYPE_STRING, &base_service_name,
1225 dbus_message_unref (message);
1229 if (!dbus_connection_send (connection, message, &serial))
1231 dbus_message_unref (message);
1235 /* send our message */
1236 bus_test_run_clients_loop (SEND_PENDING (connection));
1238 dbus_message_unref (message);
1241 dbus_connection_ref (connection); /* because we may get disconnected */
1242 block_connection_until_message_from_bus (context, connection, "reply to GetConnectionUnixProcessID");
1244 if (!dbus_connection_get_is_connected (connection))
1246 _dbus_verbose ("connection was disconnected: %s %d\n", _DBUS_FUNCTION_NAME, __LINE__);
1248 dbus_connection_unref (connection);
1253 dbus_connection_unref (connection);
1255 message = pop_message_waiting_for_memory (connection);
1256 if (message == NULL)
1258 _dbus_warn ("Did not receive a reply to %s %d on %p\n",
1259 "GetConnectionUnixProcessID", serial, connection);
1263 verbose_message_received (connection, message);
1265 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
1267 if (dbus_message_is_error (message, DBUS_ERROR_NO_MEMORY))
1269 ; /* good, this is a valid response */
1273 warn_unexpected (connection, message, "not this error");
1280 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_RETURN)
1282 ; /* good, expected */
1286 warn_unexpected (connection, message,
1287 "method_return for GetConnectionUnixProcessID");
1294 if (!dbus_message_get_args (message, &error,
1295 DBUS_TYPE_UINT32, &pid,
1298 if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
1300 _dbus_verbose ("no memory to get pid by GetConnectionUnixProcessID\n");
1301 dbus_error_free (&error);
1302 _dbus_wait_for_memory ();
1303 goto retry_get_property;
1307 _dbus_assert (dbus_error_is_set (&error));
1308 _dbus_warn ("Did not get the expected DBUS_TYPE_UINT32 from GetConnectionUnixProcessID\n");
1313 /* test if returned pid is the same as our own pid
1315 * @todo It would probably be good to restructure the tests
1316 * in a way so our parent is the bus that we're testing
1317 * cause then we can test that the pid returned matches
1320 if (pid != (dbus_uint32_t) getpid ())
1322 _dbus_assert (dbus_error_is_set (&error));
1323 _dbus_warn ("Result from GetConnectionUnixProcessID is not our own pid\n");
1329 if (!check_no_leftovers (context))
1335 dbus_error_free (&error);
1338 dbus_message_unref (message);
1343 /* returns TRUE if the correct thing happens,
1344 * but the correct thing may include OOM errors.
1347 check_add_match_all (BusContext *context,
1348 DBusConnection *connection)
1350 DBusMessage *message;
1352 dbus_uint32_t serial;
1354 const char *empty = "";
1357 dbus_error_init (&error);
1360 _dbus_verbose ("check_add_match_all for %p\n", connection);
1362 message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
1364 DBUS_INTERFACE_DBUS,
1367 if (message == NULL)
1370 /* empty string match rule matches everything */
1371 if (!dbus_message_append_args (message, DBUS_TYPE_STRING, &empty,
1374 dbus_message_unref (message);
1378 if (!dbus_connection_send (connection, message, &serial))
1380 dbus_message_unref (message);
1384 dbus_message_unref (message);
1387 dbus_connection_ref (connection); /* because we may get disconnected */
1389 /* send our message */
1390 bus_test_run_clients_loop (SEND_PENDING (connection));
1392 if (!dbus_connection_get_is_connected (connection))
1394 _dbus_verbose ("connection was disconnected: %s %d\n", _DBUS_FUNCTION_NAME, __LINE__);
1396 dbus_connection_unref (connection);
1401 block_connection_until_message_from_bus (context, connection, "reply to AddMatch");
1403 if (!dbus_connection_get_is_connected (connection))
1405 _dbus_verbose ("connection was disconnected: %s %d\n", _DBUS_FUNCTION_NAME, __LINE__);
1407 dbus_connection_unref (connection);
1412 dbus_connection_unref (connection);
1414 message = pop_message_waiting_for_memory (connection);
1415 if (message == NULL)
1417 _dbus_warn ("Did not receive a reply to %s %d on %p\n",
1418 "AddMatch", serial, connection);
1422 verbose_message_received (connection, message);
1424 if (!dbus_message_has_sender (message, DBUS_SERVICE_DBUS))
1426 _dbus_warn ("Message has wrong sender %s\n",
1427 dbus_message_get_sender (message) ?
1428 dbus_message_get_sender (message) : "(none)");
1432 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
1434 if (dbus_message_is_error (message,
1435 DBUS_ERROR_NO_MEMORY))
1437 ; /* good, this is a valid response */
1441 warn_unexpected (connection, message, "not this error");
1448 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_RETURN)
1450 ; /* good, expected */
1451 _dbus_assert (dbus_message_get_reply_serial (message) == serial);
1455 warn_unexpected (connection, message, "method return for AddMatch");
1461 if (!check_no_leftovers (context))
1467 dbus_error_free (&error);
1470 dbus_message_unref (message);
1475 /* returns TRUE if the correct thing happens,
1476 * but the correct thing may include OOM errors.
1479 check_hello_connection (BusContext *context)
1481 DBusConnection *connection;
1484 dbus_error_init (&error);
1486 connection = dbus_connection_open_private ("debug-pipe:name=test-server", &error);
1487 if (connection == NULL)
1489 _DBUS_ASSERT_ERROR_IS_SET (&error);
1490 dbus_error_free (&error);
1494 if (!bus_setup_debug_client (connection))
1496 dbus_connection_close (connection);
1497 dbus_connection_unref (connection);
1501 spin_connection_until_authenticated (context, connection);
1503 if (!check_hello_message (context, connection))
1506 if (dbus_bus_get_unique_name (connection) == NULL)
1508 /* We didn't successfully register, so we can't
1509 * do the usual kill_client_connection() checks
1511 kill_client_connection_unchecked (connection);
1515 if (!check_add_match_all (context, connection))
1518 kill_client_connection (context, connection);
1524 #define NONEXISTENT_SERVICE_NAME "test.this.service.does.not.exist.ewuoiurjdfxcvn"
1526 /* returns TRUE if the correct thing happens,
1527 * but the correct thing may include OOM errors.
1530 check_nonexistent_service_no_auto_start (BusContext *context,
1531 DBusConnection *connection)
1533 DBusMessage *message;
1534 dbus_uint32_t serial;
1536 const char *nonexistent = NONEXISTENT_SERVICE_NAME;
1537 dbus_uint32_t flags;
1539 message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
1541 DBUS_INTERFACE_DBUS,
1542 "StartServiceByName");
1544 if (message == NULL)
1547 dbus_message_set_auto_start (message, FALSE);
1550 if (!dbus_message_append_args (message,
1551 DBUS_TYPE_STRING, &nonexistent,
1552 DBUS_TYPE_UINT32, &flags,
1555 dbus_message_unref (message);
1559 if (!dbus_connection_send (connection, message, &serial))
1561 dbus_message_unref (message);
1565 dbus_message_unref (message);
1568 bus_test_run_everything (context);
1569 block_connection_until_message_from_bus (context, connection, "reply to ActivateService on nonexistent");
1570 bus_test_run_everything (context);
1572 if (!dbus_connection_get_is_connected (connection))
1574 _dbus_verbose ("connection was disconnected: %s %d\n", _DBUS_FUNCTION_NAME, __LINE__);
1580 message = pop_message_waiting_for_memory (connection);
1581 if (message == NULL)
1583 _dbus_warn ("Did not receive a reply to %s %d on %p\n",
1584 "StartServiceByName", serial, connection);
1588 verbose_message_received (connection, message);
1590 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
1592 if (!dbus_message_has_sender (message, DBUS_SERVICE_DBUS))
1594 _dbus_warn ("Message has wrong sender %s\n",
1595 dbus_message_get_sender (message) ?
1596 dbus_message_get_sender (message) : "(none)");
1600 if (dbus_message_is_error (message,
1601 DBUS_ERROR_NO_MEMORY))
1603 ; /* good, this is a valid response */
1605 else if (dbus_message_is_error (message,
1606 DBUS_ERROR_SERVICE_UNKNOWN))
1608 ; /* good, this is expected also */
1612 warn_unexpected (connection, message, "not this error");
1618 _dbus_warn ("Did not expect to successfully activate %s\n",
1619 NONEXISTENT_SERVICE_NAME);
1627 dbus_message_unref (message);
1632 /* returns TRUE if the correct thing happens,
1633 * but the correct thing may include OOM errors.
1636 check_nonexistent_service_auto_start (BusContext *context,
1637 DBusConnection *connection)
1639 DBusMessage *message;
1640 dbus_uint32_t serial;
1643 message = dbus_message_new_method_call (NONEXISTENT_SERVICE_NAME,
1644 "/org/freedesktop/TestSuite",
1645 "org.freedesktop.TestSuite",
1648 if (message == NULL)
1651 if (!dbus_connection_send (connection, message, &serial))
1653 dbus_message_unref (message);
1657 dbus_message_unref (message);
1660 bus_test_run_everything (context);
1661 block_connection_until_message_from_bus (context, connection, "reply to Echo");
1662 bus_test_run_everything (context);
1664 if (!dbus_connection_get_is_connected (connection))
1666 _dbus_verbose ("connection was disconnected: %s %d\n", _DBUS_FUNCTION_NAME, __LINE__);
1672 message = pop_message_waiting_for_memory (connection);
1674 if (message == NULL)
1676 _dbus_warn ("Did not receive a reply to %s %d on %p\n",
1677 "Echo message (auto activation)", serial, connection);
1681 verbose_message_received (connection, message);
1683 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
1685 if (!dbus_message_has_sender (message, DBUS_SERVICE_DBUS))
1687 _dbus_warn ("Message has wrong sender %s\n",
1688 dbus_message_get_sender (message) ?
1689 dbus_message_get_sender (message) : "(none)");
1693 if (dbus_message_is_error (message,
1694 DBUS_ERROR_NO_MEMORY))
1696 ; /* good, this is a valid response */
1698 else if (dbus_message_is_error (message,
1699 DBUS_ERROR_SERVICE_UNKNOWN))
1701 ; /* good, this is expected also */
1705 warn_unexpected (connection, message, "not this error");
1711 _dbus_warn ("Did not expect to successfully activate %s\n",
1712 NONEXISTENT_SERVICE_NAME);
1720 dbus_message_unref (message);
1726 check_base_service_activated (BusContext *context,
1727 DBusConnection *connection,
1728 DBusMessage *initial_message,
1729 const char **base_service_p)
1731 DBusMessage *message;
1734 const char *base_service, *base_service_from_bus, *old_owner;
1738 dbus_error_init (&error);
1739 base_service = NULL;
1741 base_service_from_bus = NULL;
1743 message = initial_message;
1744 dbus_message_ref (message);
1746 if (dbus_message_is_signal (message,
1747 DBUS_INTERFACE_DBUS,
1748 "NameOwnerChanged"))
1750 CheckServiceOwnerChangedData socd;
1752 reget_service_name_arg:
1753 base_service = NULL;
1755 base_service_from_bus = NULL;
1757 if (!dbus_message_get_args (message, &error,
1758 DBUS_TYPE_STRING, &base_service,
1759 DBUS_TYPE_STRING, &old_owner,
1760 DBUS_TYPE_STRING, &base_service_from_bus,
1763 if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
1765 dbus_error_free (&error);
1766 _dbus_wait_for_memory ();
1767 goto reget_service_name_arg;
1771 _dbus_warn ("Message %s doesn't have a service name: %s\n",
1772 "NameOwnerChanged (creation)",
1778 if (*base_service != ':')
1780 _dbus_warn ("Expected base service activation, got \"%s\" instead\n",
1785 if (strcmp (base_service, base_service_from_bus) != 0)
1787 _dbus_warn ("Expected base service activation, got \"%s\" instead with owner \"%s\"\n",
1788 base_service, base_service_from_bus);
1794 _dbus_warn ("Received an old_owner argument during base service activation, \"%s\"\n",
1799 socd.expected_kind = SERVICE_CREATED;
1800 socd.expected_service_name = base_service;
1801 socd.failed = FALSE;
1802 socd.skip_connection = connection;
1803 bus_test_clients_foreach (check_service_owner_changed_foreach,
1811 warn_unexpected (connection, message, "NameOwnerChanged (creation) for base service");
1817 *base_service_p = base_service;
1823 dbus_message_unref (message);
1824 dbus_error_free (&error);
1830 check_service_activated (BusContext *context,
1831 DBusConnection *connection,
1832 const char *activated_name,
1833 const char *base_service_name,
1834 DBusMessage *initial_message)
1836 DBusMessage *message;
1839 dbus_uint32_t activation_result;
1843 dbus_error_init (&error);
1845 message = initial_message;
1846 dbus_message_ref (message);
1848 if (dbus_message_is_signal (message,
1849 DBUS_INTERFACE_DBUS,
1850 "NameOwnerChanged"))
1852 CheckServiceOwnerChangedData socd;
1853 const char *service_name, *base_service_from_bus, *old_owner;
1855 reget_service_name_arg:
1856 service_name = NULL;
1858 base_service_from_bus = NULL;
1860 if (!dbus_message_get_args (message, &error,
1861 DBUS_TYPE_STRING, &service_name,
1862 DBUS_TYPE_STRING, &old_owner,
1863 DBUS_TYPE_STRING, &base_service_from_bus,
1866 if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
1868 dbus_error_free (&error);
1869 _dbus_wait_for_memory ();
1870 goto reget_service_name_arg;
1874 _dbus_warn ("Message %s doesn't have a service name: %s\n",
1875 "NameOwnerChanged (creation)",
1881 if (strcmp (service_name, activated_name) != 0)
1883 _dbus_warn ("Expected to see service %s created, saw %s instead\n",
1884 activated_name, service_name);
1888 if (strcmp (base_service_name, base_service_from_bus) != 0)
1890 _dbus_warn ("NameOwnerChanged reports wrong base service: %s owner, expected %s instead\n",
1891 base_service_from_bus, base_service_name);
1897 _dbus_warn ("expected a %s, got a %s\n",
1898 "NameOwnerChanged (creation)",
1899 "NameOwnerChanged (change)");
1903 socd.expected_kind = SERVICE_CREATED;
1904 socd.skip_connection = connection;
1905 socd.failed = FALSE;
1906 socd.expected_service_name = service_name;
1907 bus_test_clients_foreach (check_service_owner_changed_foreach,
1913 dbus_message_unref (message);
1914 service_name = NULL;
1916 base_service_from_bus = NULL;
1918 message = pop_message_waiting_for_memory (connection);
1919 if (message == NULL)
1921 _dbus_warn ("Expected a reply to %s, got nothing\n",
1922 "StartServiceByName");
1928 warn_unexpected (connection, message, "NameOwnerChanged for the activated name");
1933 if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_METHOD_RETURN)
1935 warn_unexpected (connection, message, "reply to StartServiceByName");
1940 activation_result = 0;
1941 if (!dbus_message_get_args (message, &error,
1942 DBUS_TYPE_UINT32, &activation_result,
1945 if (!dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
1947 _dbus_warn ("Did not have activation result first argument to %s: %s\n",
1948 "StartServiceByName", error.message);
1952 dbus_error_free (&error);
1956 if (activation_result == DBUS_START_REPLY_SUCCESS)
1958 else if (activation_result == DBUS_START_REPLY_ALREADY_RUNNING)
1962 _dbus_warn ("Activation result was %u, no good.\n",
1968 dbus_message_unref (message);
1971 if (!check_no_leftovers (context))
1973 _dbus_warn ("Messages were left over after verifying existent activation results\n");
1981 dbus_message_unref (message);
1982 dbus_error_free (&error);
1988 check_service_auto_activated (BusContext *context,
1989 DBusConnection *connection,
1990 const char *activated_name,
1991 const char *base_service_name,
1992 DBusMessage *initial_message)
1994 DBusMessage *message;
2000 dbus_error_init (&error);
2002 message = initial_message;
2003 dbus_message_ref (message);
2005 if (dbus_message_is_signal (message,
2006 DBUS_INTERFACE_DBUS,
2007 "NameOwnerChanged"))
2009 const char *service_name;
2010 CheckServiceOwnerChangedData socd;
2012 reget_service_name_arg:
2013 if (!dbus_message_get_args (message, &error,
2014 DBUS_TYPE_STRING, &service_name,
2017 if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
2019 dbus_error_free (&error);
2020 _dbus_wait_for_memory ();
2021 goto reget_service_name_arg;
2025 _dbus_warn ("Message %s doesn't have a service name: %s\n",
2028 dbus_error_free (&error);
2033 if (strcmp (service_name, activated_name) != 0)
2035 _dbus_warn ("Expected to see service %s created, saw %s instead\n",
2036 activated_name, service_name);
2040 socd.expected_kind = SERVICE_CREATED;
2041 socd.expected_service_name = service_name;
2042 socd.failed = FALSE;
2043 socd.skip_connection = connection;
2044 bus_test_clients_foreach (check_service_owner_changed_foreach,
2050 /* Note that this differs from regular activation in that we don't get a
2051 * reply to ActivateService here.
2054 dbus_message_unref (message);
2056 service_name = NULL;
2060 warn_unexpected (connection, message, "NameOwnerChanged for the activated name");
2069 dbus_message_unref (message);
2075 check_service_deactivated (BusContext *context,
2076 DBusConnection *connection,
2077 const char *activated_name,
2078 const char *base_service)
2081 CheckServiceOwnerChangedData socd;
2085 /* Now we are expecting ServiceOwnerChanged (deletion) messages for the base
2086 * service and the activated_name. The base service
2087 * notification is required to come last.
2089 socd.expected_kind = SERVICE_DELETED;
2090 socd.expected_service_name = activated_name;
2091 socd.failed = FALSE;
2092 socd.skip_connection = NULL;
2093 bus_test_clients_foreach (check_service_owner_changed_foreach,
2099 socd.expected_kind = SERVICE_DELETED;
2100 socd.expected_service_name = base_service;
2101 socd.failed = FALSE;
2102 socd.skip_connection = NULL;
2103 bus_test_clients_foreach (check_service_owner_changed_foreach,
2116 check_send_exit_to_service (BusContext *context,
2117 DBusConnection *connection,
2118 const char *service_name,
2119 const char *base_service)
2121 dbus_bool_t got_error;
2122 DBusMessage *message;
2123 dbus_uint32_t serial;
2126 _dbus_verbose ("Sending exit message to the test service\n");
2130 /* Kill off the test service by sending it a quit message */
2131 message = dbus_message_new_method_call (service_name,
2132 "/org/freedesktop/TestSuite",
2133 "org.freedesktop.TestSuite",
2136 if (message == NULL)
2138 /* Do this again; we still need the service to exit... */
2139 if (!check_send_exit_to_service (context, connection,
2140 service_name, base_service))
2146 if (!dbus_connection_send (connection, message, &serial))
2148 dbus_message_unref (message);
2150 /* Do this again; we still need the service to exit... */
2151 if (!check_send_exit_to_service (context, connection,
2152 service_name, base_service))
2158 dbus_message_unref (message);
2162 bus_test_run_clients_loop (SEND_PENDING (connection));
2164 /* read it in and write it out to test service */
2165 bus_test_run_bus_loop (context, FALSE);
2167 /* see if we got an error during message bus dispatching */
2168 bus_test_run_clients_loop (FALSE);
2169 message = borrow_message_waiting_for_memory (connection);
2170 got_error = message != NULL && dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR;
2173 dbus_connection_return_message (connection, message);
2179 /* If no error, wait for the test service to exit */
2180 block_connection_until_message_from_bus (context, connection, "test service to exit");
2182 bus_test_run_everything (context);
2187 message = pop_message_waiting_for_memory (connection);
2188 _dbus_assert (message != NULL);
2190 if (dbus_message_get_reply_serial (message) != serial)
2192 warn_unexpected (connection, message,
2193 "error with the correct reply serial");
2197 if (!dbus_message_is_error (message,
2198 DBUS_ERROR_NO_MEMORY))
2200 warn_unexpected (connection, message,
2201 "a no memory error from asking test service to exit");
2205 _dbus_verbose ("Got error %s when asking test service to exit\n",
2206 dbus_message_get_error_name (message));
2208 /* Do this again; we still need the service to exit... */
2209 if (!check_send_exit_to_service (context, connection,
2210 service_name, base_service))
2215 if (!check_service_deactivated (context, connection,
2216 service_name, base_service))
2219 /* Should now have a NoReply error from the Exit() method
2220 * call; it should have come after all the deactivation
2223 message = pop_message_waiting_for_memory (connection);
2225 if (message == NULL)
2227 warn_unexpected (connection, NULL,
2228 "reply to Exit() method call");
2231 if (!dbus_message_is_error (message,
2232 DBUS_ERROR_NO_REPLY))
2234 warn_unexpected (connection, message,
2235 "NoReply error from Exit() method call");
2239 if (dbus_message_get_reply_serial (message) != serial)
2241 warn_unexpected (connection, message,
2242 "error with the correct reply serial");
2246 _dbus_verbose ("Got error %s after test service exited\n",
2247 dbus_message_get_error_name (message));
2249 if (!check_no_leftovers (context))
2251 _dbus_warn ("Messages were left over after %s\n",
2252 _DBUS_FUNCTION_NAME);
2261 dbus_message_unref (message);
2267 check_got_error (BusContext *context,
2268 DBusConnection *connection,
2269 const char *first_error_name,
2272 DBusMessage *message;
2275 dbus_bool_t error_found;
2276 const char *error_name;
2280 message = pop_message_waiting_for_memory (connection);
2281 if (message == NULL)
2283 _dbus_warn ("Did not get an expected error\n");
2287 if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_ERROR)
2289 warn_unexpected (connection, message, "an error");
2294 error_found = FALSE;
2296 va_start (ap, first_error_name);
2297 error_name = first_error_name;
2298 while (error_name != NULL)
2300 if (dbus_message_is_error (message, error_name))
2305 error_name = va_arg (ap, char*);
2311 _dbus_warn ("Expected error %s or other, got %s instead\n",
2313 dbus_message_get_error_name (message));
2321 dbus_message_unref (message);
2328 GOT_SERVICE_CREATED,
2329 GOT_SERVICE_DELETED,
2334 static GotServiceInfo
2335 check_got_service_info (DBusMessage *message)
2337 GotServiceInfo message_kind;
2339 if (dbus_message_is_signal (message,
2340 DBUS_INTERFACE_DBUS,
2341 "NameOwnerChanged"))
2344 const char *service_name, *old_owner, *new_owner;
2345 dbus_error_init (&error);
2347 reget_service_info_data:
2348 service_name = NULL;
2352 dbus_message_get_args (message, &error,
2353 DBUS_TYPE_STRING, &service_name,
2354 DBUS_TYPE_STRING, &old_owner,
2355 DBUS_TYPE_STRING, &new_owner,
2357 if (dbus_error_is_set (&error))
2359 if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
2361 dbus_error_free (&error);
2362 goto reget_service_info_data;
2366 _dbus_warn ("unexpected arguments for NameOwnerChanged message\n");
2367 message_kind = GOT_SOMETHING_ELSE;
2370 else if (!old_owner[0])
2371 message_kind = GOT_SERVICE_CREATED;
2372 else if (!new_owner[0])
2373 message_kind = GOT_SERVICE_DELETED;
2375 message_kind = GOT_SOMETHING_ELSE;
2377 dbus_error_free (&error);
2379 else if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
2380 message_kind = GOT_ERROR;
2382 message_kind = GOT_SOMETHING_ELSE;
2384 return message_kind;
2387 #define EXISTENT_SERVICE_NAME "org.freedesktop.DBus.TestSuiteEchoService"
2389 /* returns TRUE if the correct thing happens,
2390 * but the correct thing may include OOM errors.
2393 check_existent_service_no_auto_start (BusContext *context,
2394 DBusConnection *connection)
2396 DBusMessage *message;
2397 DBusMessage *base_service_message;
2398 const char *base_service;
2399 dbus_uint32_t serial;
2401 const char *existent = EXISTENT_SERVICE_NAME;
2402 dbus_uint32_t flags;
2404 base_service_message = NULL;
2406 message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
2408 DBUS_INTERFACE_DBUS,
2409 "StartServiceByName");
2411 if (message == NULL)
2414 dbus_message_set_auto_start (message, FALSE);
2417 if (!dbus_message_append_args (message,
2418 DBUS_TYPE_STRING, &existent,
2419 DBUS_TYPE_UINT32, &flags,
2422 dbus_message_unref (message);
2426 if (!dbus_connection_send (connection, message, &serial))
2428 dbus_message_unref (message);
2432 dbus_message_unref (message);
2435 bus_test_run_everything (context);
2437 /* now wait for the message bus to hear back from the activated
2440 block_connection_until_message_from_bus (context, connection, "activated service to connect");
2442 bus_test_run_everything (context);
2444 if (!dbus_connection_get_is_connected (connection))
2446 _dbus_verbose ("connection was disconnected: %s %d\n", _DBUS_FUNCTION_NAME, __LINE__);
2452 message = pop_message_waiting_for_memory (connection);
2453 if (message == NULL)
2455 _dbus_warn ("Did not receive any messages after %s %d on %p\n",
2456 "StartServiceByName", serial, connection);
2460 verbose_message_received (connection, message);
2461 _dbus_verbose (" (after sending %s)\n", "StartServiceByName");
2463 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
2465 if (!dbus_message_has_sender (message, DBUS_SERVICE_DBUS))
2467 _dbus_warn ("Message has wrong sender %s\n",
2468 dbus_message_get_sender (message) ?
2469 dbus_message_get_sender (message) : "(none)");
2473 if (dbus_message_is_error (message,
2474 DBUS_ERROR_NO_MEMORY))
2476 ; /* good, this is a valid response */
2478 else if (dbus_message_is_error (message,
2479 DBUS_ERROR_SPAWN_CHILD_EXITED) ||
2480 dbus_message_is_error (message,
2481 DBUS_ERROR_SPAWN_CHILD_SIGNALED) ||
2482 dbus_message_is_error (message,
2483 DBUS_ERROR_SPAWN_EXEC_FAILED))
2485 ; /* good, this is expected also */
2489 _dbus_warn ("Did not expect error %s\n",
2490 dbus_message_get_error_name (message));
2496 GotServiceInfo message_kind;
2498 if (!check_base_service_activated (context, connection,
2499 message, &base_service))
2502 base_service_message = message;
2505 /* We may need to block here for the test service to exit or finish up */
2506 block_connection_until_message_from_bus (context, connection, "test service to exit or finish up");
2508 message = dbus_connection_borrow_message (connection);
2509 if (message == NULL)
2511 _dbus_warn ("Did not receive any messages after base service creation notification\n");
2515 message_kind = check_got_service_info (message);
2517 dbus_connection_return_message (connection, message);
2520 switch (message_kind)
2522 case GOT_SOMETHING_ELSE:
2523 _dbus_warn ("Unexpected message after ActivateService "
2524 "(should be an error or a service announcement");
2528 if (!check_got_error (context, connection,
2529 DBUS_ERROR_SPAWN_CHILD_EXITED,
2530 DBUS_ERROR_NO_MEMORY,
2533 /* A service deleted should be coming along now after this error.
2534 * We can also get the error *after* the service deleted.
2539 case GOT_SERVICE_DELETED:
2541 /* The service started up and got a base address, but then
2542 * failed to register under EXISTENT_SERVICE_NAME
2544 CheckServiceOwnerChangedData socd;
2546 socd.expected_kind = SERVICE_DELETED;
2547 socd.expected_service_name = base_service;
2548 socd.failed = FALSE;
2549 socd.skip_connection = NULL;
2551 bus_test_clients_foreach (check_service_owner_changed_foreach,
2557 /* Now we should get an error about the service exiting
2558 * if we didn't get it before.
2560 if (message_kind != GOT_ERROR)
2562 block_connection_until_message_from_bus (context, connection, "error about service exiting");
2564 /* and process everything again */
2565 bus_test_run_everything (context);
2567 if (!check_got_error (context, connection,
2568 DBUS_ERROR_SPAWN_CHILD_EXITED,
2569 DBUS_ERROR_NO_MEMORY,
2576 case GOT_SERVICE_CREATED:
2577 message = pop_message_waiting_for_memory (connection);
2578 if (message == NULL)
2580 _dbus_warn ("Failed to pop message we just put back! "
2581 "should have been a NameOwnerChanged (creation)\n");
2585 if (!check_service_activated (context, connection, EXISTENT_SERVICE_NAME,
2586 base_service, message))
2589 dbus_message_unref (message);
2592 if (!check_no_leftovers (context))
2594 _dbus_warn ("Messages were left over after successful activation\n");
2598 if (!check_send_exit_to_service (context, connection,
2599 EXISTENT_SERVICE_NAME, base_service))
2610 dbus_message_unref (message);
2612 if (base_service_message)
2613 dbus_message_unref (base_service_message);
2618 #ifndef DBUS_WIN_FIXME
2619 /* returns TRUE if the correct thing happens,
2620 * but the correct thing may include OOM errors.
2623 check_segfault_service_no_auto_start (BusContext *context,
2624 DBusConnection *connection)
2626 DBusMessage *message;
2627 dbus_uint32_t serial;
2629 const char *segv_service;
2630 dbus_uint32_t flags;
2632 message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
2634 DBUS_INTERFACE_DBUS,
2635 "StartServiceByName");
2637 if (message == NULL)
2640 dbus_message_set_auto_start (message, FALSE);
2642 segv_service = "org.freedesktop.DBus.TestSuiteSegfaultService";
2644 if (!dbus_message_append_args (message,
2645 DBUS_TYPE_STRING, &segv_service,
2646 DBUS_TYPE_UINT32, &flags,
2649 dbus_message_unref (message);
2653 if (!dbus_connection_send (connection, message, &serial))
2655 dbus_message_unref (message);
2659 dbus_message_unref (message);
2662 bus_test_run_everything (context);
2663 block_connection_until_message_from_bus (context, connection, "reply to activating segfault service");
2664 bus_test_run_everything (context);
2666 if (!dbus_connection_get_is_connected (connection))
2668 _dbus_verbose ("connection was disconnected: %s %d\n", _DBUS_FUNCTION_NAME, __LINE__);
2674 message = pop_message_waiting_for_memory (connection);
2675 if (message == NULL)
2677 _dbus_warn ("Did not receive a reply to %s %d on %p\n",
2678 "StartServiceByName", serial, connection);
2682 verbose_message_received (connection, message);
2684 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
2686 if (!dbus_message_has_sender (message, DBUS_SERVICE_DBUS))
2688 _dbus_warn ("Message has wrong sender %s\n",
2689 dbus_message_get_sender (message) ?
2690 dbus_message_get_sender (message) : "(none)");
2694 if (dbus_message_is_error (message,
2695 DBUS_ERROR_NO_MEMORY))
2697 ; /* good, this is a valid response */
2699 else if (dbus_message_is_error (message,
2700 DBUS_ERROR_SPAWN_CHILD_SIGNALED))
2702 ; /* good, this is expected also */
2706 warn_unexpected (connection, message, "not this error");
2713 _dbus_warn ("Did not expect to successfully activate segfault service\n");
2721 dbus_message_unref (message);
2727 /* returns TRUE if the correct thing happens,
2728 * but the correct thing may include OOM errors.
2731 check_segfault_service_auto_start (BusContext *context,
2732 DBusConnection *connection)
2734 DBusMessage *message;
2735 dbus_uint32_t serial;
2738 message = dbus_message_new_method_call ("org.freedesktop.DBus.TestSuiteSegfaultService",
2739 "/org/freedesktop/TestSuite",
2740 "org.freedesktop.TestSuite",
2743 if (message == NULL)
2746 if (!dbus_connection_send (connection, message, &serial))
2748 dbus_message_unref (message);
2752 dbus_message_unref (message);
2755 bus_test_run_everything (context);
2756 block_connection_until_message_from_bus (context, connection, "reply to Echo on segfault service");
2757 bus_test_run_everything (context);
2759 if (!dbus_connection_get_is_connected (connection))
2761 _dbus_verbose ("connection was disconnected: %s %d\n", _DBUS_FUNCTION_NAME, __LINE__);
2767 message = pop_message_waiting_for_memory (connection);
2768 if (message == NULL)
2770 _dbus_warn ("Did not receive a reply to %s %d on %p\n",
2771 "Echo message (auto activation)", serial, connection);
2775 verbose_message_received (connection, message);
2777 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
2779 if (!dbus_message_has_sender (message, DBUS_SERVICE_DBUS))
2781 _dbus_warn ("Message has wrong sender %s\n",
2782 dbus_message_get_sender (message) ?
2783 dbus_message_get_sender (message) : "(none)");
2787 if (dbus_message_is_error (message,
2788 DBUS_ERROR_NO_MEMORY))
2790 ; /* good, this is a valid response */
2792 else if (dbus_message_is_error (message,
2793 DBUS_ERROR_SPAWN_CHILD_SIGNALED))
2795 ; /* good, this is expected also */
2799 warn_unexpected (connection, message, "not this error");
2806 _dbus_warn ("Did not expect to successfully activate segfault service\n");
2814 dbus_message_unref (message);
2820 #define TEST_ECHO_MESSAGE "Test echo message"
2821 #define TEST_RUN_HELLO_FROM_SELF_MESSAGE "Test sending message to self"
2823 /* returns TRUE if the correct thing happens,
2824 * but the correct thing may include OOM errors.
2827 check_existent_hello_from_self (BusContext *context,
2828 DBusConnection *connection)
2830 DBusMessage *message;
2831 dbus_uint32_t serial;
2834 message = dbus_message_new_method_call (EXISTENT_SERVICE_NAME,
2835 "/org/freedesktop/TestSuite",
2836 "org.freedesktop.TestSuite",
2837 "RunHelloFromSelf");
2839 if (message == NULL)
2842 text = TEST_RUN_HELLO_FROM_SELF_MESSAGE;
2843 if (!dbus_message_append_args (message,
2844 DBUS_TYPE_STRING, &text,
2847 dbus_message_unref (message);
2851 if (!dbus_connection_send (connection, message, &serial))
2853 dbus_message_unref (message);
2857 dbus_message_unref (message);
2860 bus_test_run_everything (context);
2862 /* Note: if this test is run in OOM mode, it will block when the bus
2863 * doesn't send a reply due to OOM.
2865 block_connection_until_message_from_bus (context, connection, "reply from running hello from self");
2867 message = pop_message_waiting_for_memory (connection);
2868 if (message == NULL)
2870 _dbus_warn ("Failed to pop message! Should have been reply from RunHelloFromSelf message\n");
2874 if (dbus_message_get_reply_serial (message) != serial)
2876 _dbus_warn ("Wrong reply serial\n");
2877 dbus_message_unref (message);
2881 dbus_message_unref (message);
2887 /* returns TRUE if the correct thing happens,
2888 * but the correct thing may include OOM errors.
2891 check_existent_ping (BusContext *context,
2892 DBusConnection *connection)
2894 DBusMessage *message;
2895 dbus_uint32_t serial;
2896 message = dbus_message_new_method_call (EXISTENT_SERVICE_NAME,
2897 "/org/freedesktop/TestSuite",
2898 "org.freedesktop.DBus.Peer",
2901 if (message == NULL)
2904 if (!dbus_connection_send (connection, message, &serial))
2906 dbus_message_unref (message);
2910 dbus_message_unref (message);
2913 bus_test_run_everything (context);
2915 /* Note: if this test is run in OOM mode, it will block when the bus
2916 * doesn't send a reply due to OOM.
2918 block_connection_until_message_from_bus (context, connection, "reply from running Ping");
2920 message = pop_message_waiting_for_memory (connection);
2921 if (message == NULL)
2923 _dbus_warn ("Failed to pop message! Should have been reply from Ping message\n");
2927 if (dbus_message_get_reply_serial (message) != serial)
2929 _dbus_warn ("Wrong reply serial\n");
2930 dbus_message_unref (message);
2934 if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_METHOD_RETURN)
2936 _dbus_warn ("Unexpected message return during Ping\n");
2937 dbus_message_unref (message);
2941 dbus_message_unref (message);
2947 /* returns TRUE if the correct thing happens,
2948 * but the correct thing may include OOM errors.
2951 check_existent_get_machine_id (BusContext *context,
2952 DBusConnection *connection)
2954 DBusMessage *message;
2955 dbus_uint32_t serial;
2956 const char *machine_id;
2958 message = dbus_message_new_method_call (EXISTENT_SERVICE_NAME,
2959 "/org/freedesktop/TestSuite",
2960 "org.freedesktop.DBus.Peer",
2963 if (message == NULL)
2966 if (!dbus_connection_send (connection, message, &serial))
2968 dbus_message_unref (message);
2972 dbus_message_unref (message);
2975 bus_test_run_everything (context);
2977 /* Note: if this test is run in OOM mode, it will block when the bus
2978 * doesn't send a reply due to OOM.
2980 block_connection_until_message_from_bus (context, connection, "reply from running GetMachineId");
2982 message = pop_message_waiting_for_memory (connection);
2983 if (message == NULL)
2985 _dbus_warn ("Failed to pop message! Should have been reply from GetMachineId message\n");
2989 if (dbus_message_get_reply_serial (message) != serial)
2991 _dbus_warn ("Wrong reply serial\n");
2992 dbus_message_unref (message);
2996 if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_METHOD_RETURN)
2998 _dbus_warn ("Unexpected message return during GetMachineId\n");
2999 dbus_message_unref (message);
3004 if (!dbus_message_get_args (message, NULL, DBUS_TYPE_STRING, &machine_id, DBUS_TYPE_INVALID))
3006 _dbus_warn ("Did not get a machine ID in reply to GetMachineId\n");
3007 dbus_message_unref (message);
3011 if (machine_id == NULL || strlen (machine_id) != 32)
3013 _dbus_warn ("Machine id looks bogus: '%s'\n", machine_id ? machine_id : "null");
3014 dbus_message_unref (message);
3018 /* We can't check that the machine id is correct because during make check it is
3019 * just made up for each process separately
3022 dbus_message_unref (message);
3028 /* returns TRUE if the correct thing happens,
3029 * but the correct thing may include OOM errors.
3032 check_existent_service_auto_start (BusContext *context,
3033 DBusConnection *connection)
3035 DBusMessage *message;
3036 DBusMessage *base_service_message;
3037 dbus_uint32_t serial;
3039 const char *base_service;
3042 base_service_message = NULL;
3044 message = dbus_message_new_method_call (EXISTENT_SERVICE_NAME,
3045 "/org/freedesktop/TestSuite",
3046 "org.freedesktop.TestSuite",
3049 if (message == NULL)
3052 text = TEST_ECHO_MESSAGE;
3053 if (!dbus_message_append_args (message,
3054 DBUS_TYPE_STRING, &text,
3057 dbus_message_unref (message);
3061 if (!dbus_connection_send (connection, message, &serial))
3063 dbus_message_unref (message);
3067 dbus_message_unref (message);
3070 bus_test_run_everything (context);
3072 /* now wait for the message bus to hear back from the activated
3075 block_connection_until_message_from_bus (context, connection, "reply to Echo on existent service");
3076 bus_test_run_everything (context);
3078 if (!dbus_connection_get_is_connected (connection))
3080 _dbus_verbose ("connection was disconnected: %s %d\n", _DBUS_FUNCTION_NAME, __LINE__);
3086 message = pop_message_waiting_for_memory (connection);
3087 if (message == NULL)
3089 _dbus_warn ("Did not receive any messages after auto start %d on %p\n",
3090 serial, connection);
3094 verbose_message_received (connection, message);
3095 _dbus_verbose (" (after sending %s)\n", "auto start");
3097 /* we should get zero or two ServiceOwnerChanged signals */
3098 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_SIGNAL)
3100 GotServiceInfo message_kind;
3102 if (!check_base_service_activated (context, connection,
3103 message, &base_service))
3106 base_service_message = message;
3109 /* We may need to block here for the test service to exit or finish up */
3110 block_connection_until_message_from_bus (context, connection, "service to exit");
3112 /* Should get a service creation notification for the activated
3113 * service name, or a service deletion on the base service name
3115 message = dbus_connection_borrow_message (connection);
3116 if (message == NULL)
3118 _dbus_warn ("No message after auto activation "
3119 "(should be a service announcement)\n");
3120 dbus_connection_return_message (connection, message);
3125 message_kind = check_got_service_info (message);
3127 dbus_connection_return_message (connection, message);
3130 switch (message_kind)
3132 case GOT_SERVICE_CREATED:
3133 message = pop_message_waiting_for_memory (connection);
3134 if (message == NULL)
3136 _dbus_warn ("Failed to pop message we just put back! "
3137 "should have been a NameOwnerChanged (creation)\n");
3141 /* Check that ServiceOwnerChanged (creation) was correctly received */
3142 if (!check_service_auto_activated (context, connection, EXISTENT_SERVICE_NAME,
3143 base_service, message))
3146 dbus_message_unref (message);
3151 case GOT_SERVICE_DELETED:
3153 /* The service started up and got a base address, but then
3154 * failed to register under EXISTENT_SERVICE_NAME
3156 CheckServiceOwnerChangedData socd;
3158 socd.expected_kind = SERVICE_DELETED;
3159 socd.expected_service_name = base_service;
3160 socd.failed = FALSE;
3161 socd.skip_connection = NULL;
3162 bus_test_clients_foreach (check_service_owner_changed_foreach,
3172 case GOT_SOMETHING_ELSE:
3173 _dbus_warn ("Unexpected message after auto activation\n");
3178 /* OK, now we've dealt with ServiceOwnerChanged signals, now should
3179 * come the method reply (or error) from the initial method call
3182 /* Note: if this test is run in OOM mode, it will block when the bus
3183 * doesn't send a reply due to OOM.
3185 block_connection_until_message_from_bus (context, connection, "reply from echo message after auto-activation");
3187 message = pop_message_waiting_for_memory (connection);
3188 if (message == NULL)
3190 _dbus_warn ("Failed to pop message! Should have been reply from echo message\n");
3194 if (dbus_message_get_reply_serial (message) != serial)
3196 _dbus_warn ("Wrong reply serial\n");
3200 dbus_message_unref (message);
3203 if (!check_existent_ping (context, connection))
3206 if (!check_existent_get_machine_id (context, connection))
3209 if (!check_existent_hello_from_self (context, connection))
3212 if (!check_send_exit_to_service (context, connection,
3213 EXISTENT_SERVICE_NAME,
3221 dbus_message_unref (message);
3223 if (base_service_message)
3224 dbus_message_unref (base_service_message);
3229 #define SHELL_FAIL_SERVICE_NAME "org.freedesktop.DBus.TestSuiteShellEchoServiceFail"
3231 /* returns TRUE if the correct thing happens,
3232 * but the correct thing may include OOM errors.
3235 check_shell_fail_service_auto_start (BusContext *context,
3236 DBusConnection *connection)
3238 DBusMessage *message;
3239 dbus_uint32_t serial;
3242 message = dbus_message_new_method_call (SHELL_FAIL_SERVICE_NAME,
3243 "/org/freedesktop/TestSuite",
3244 "org.freedesktop.TestSuite",
3247 if (message == NULL)
3250 if (!dbus_connection_send (connection, message, &serial))
3252 dbus_message_unref (message);
3256 dbus_message_unref (message);
3259 bus_test_run_everything (context);
3260 block_connection_until_message_from_bus (context, connection, "reply to shell Echo on service which should fail to auto-start");
3261 bus_test_run_everything (context);
3263 if (!dbus_connection_get_is_connected (connection))
3265 _dbus_verbose ("connection was disconnected: %s %d\n", _DBUS_FUNCTION_NAME, __LINE__);
3271 message = pop_message_waiting_for_memory (connection);
3272 if (message == NULL)
3274 _dbus_warn ("Did not receive a reply to %s %d on %p\n",
3275 "Echo message (auto activation)", serial, connection);
3279 verbose_message_received (connection, message);
3281 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
3283 if (!dbus_message_has_sender (message, DBUS_SERVICE_DBUS))
3285 _dbus_warn ("Message has wrong sender %s\n",
3286 dbus_message_get_sender (message) ?
3287 dbus_message_get_sender (message) : "(none)");
3291 if (dbus_message_is_error (message,
3292 DBUS_ERROR_NO_MEMORY))
3294 ; /* good, this is a valid response */
3296 else if (dbus_message_is_error (message,
3297 DBUS_ERROR_INVALID_ARGS))
3299 _dbus_verbose("got invalid args\n");
3300 ; /* good, this is expected also */
3304 warn_unexpected (connection, message, "not this error");
3311 _dbus_warn ("Did not expect to successfully auto-start shell fail service\n");
3319 dbus_message_unref (message);
3324 #define SHELL_SUCCESS_SERVICE_NAME "org.freedesktop.DBus.TestSuiteShellEchoServiceSuccess"
3326 /* returns TRUE if the correct thing happens,
3327 * but the correct thing may include OOM errors.
3330 check_shell_service_success_auto_start (BusContext *context,
3331 DBusConnection *connection)
3333 DBusMessage *message;
3334 DBusMessage *base_service_message;
3335 dbus_uint32_t serial;
3337 const char *base_service;
3338 const char *argv[7] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL};
3340 base_service_message = NULL;
3342 message = dbus_message_new_method_call (SHELL_SUCCESS_SERVICE_NAME,
3343 "/org/freedesktop/TestSuite",
3344 "org.freedesktop.TestSuite",
3347 if (message == NULL)
3350 if (!dbus_connection_send (connection, message, &serial))
3352 dbus_message_unref (message);
3356 dbus_message_unref (message);
3359 bus_test_run_everything (context);
3361 /* now wait for the message bus to hear back from the activated
3364 block_connection_until_message_from_bus (context, connection, "reply to Echo on shell success service");
3365 bus_test_run_everything (context);
3367 if (!dbus_connection_get_is_connected (connection))
3369 _dbus_verbose ("connection was disconnected: %s %d\n", _DBUS_FUNCTION_NAME, __LINE__);
3375 message = pop_message_waiting_for_memory (connection);
3376 if (message == NULL)
3378 _dbus_warn ("Did not receive any messages after auto start %d on %p\n",
3379 serial, connection);
3383 verbose_message_received (connection, message);
3384 _dbus_verbose (" (after sending %s)\n", "auto start");
3386 /* we should get zero or two ServiceOwnerChanged signals */
3387 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_SIGNAL)
3389 GotServiceInfo message_kind;
3391 if (!check_base_service_activated (context, connection,
3392 message, &base_service))
3395 base_service_message = message;
3398 /* We may need to block here for the test service to exit or finish up */
3399 block_connection_until_message_from_bus (context, connection, "service to exit");
3401 /* Should get a service creation notification for the activated
3402 * service name, or a service deletion on the base service name
3404 message = dbus_connection_borrow_message (connection);
3405 if (message == NULL)
3407 _dbus_warn ("No message after auto activation "
3408 "(should be a service announcement)\n");
3409 dbus_connection_return_message (connection, message);
3414 message_kind = check_got_service_info (message);
3416 dbus_connection_return_message (connection, message);
3419 switch (message_kind)
3421 case GOT_SERVICE_CREATED:
3422 message = pop_message_waiting_for_memory (connection);
3423 if (message == NULL)
3425 _dbus_warn ("Failed to pop message we just put back! "
3426 "should have been a NameOwnerChanged (creation)\n");
3430 /* Check that ServiceOwnerChanged (creation) was correctly received */
3431 if (!check_service_auto_activated (context, connection, SHELL_SUCCESS_SERVICE_NAME,
3432 base_service, message))
3435 dbus_message_unref (message);
3440 case GOT_SERVICE_DELETED:
3442 /* The service started up and got a base address, but then
3443 * failed to register under SHELL_SUCCESS_SERVICE_NAME
3445 CheckServiceOwnerChangedData socd;
3447 socd.expected_kind = SERVICE_DELETED;
3448 socd.expected_service_name = base_service;
3449 socd.failed = FALSE;
3450 socd.skip_connection = NULL;
3451 bus_test_clients_foreach (check_service_owner_changed_foreach,
3461 case GOT_SOMETHING_ELSE:
3462 _dbus_warn ("Unexpected message after auto activation\n");
3467 /* OK, now we've dealt with ServiceOwnerChanged signals, now should
3468 * come the method reply (or error) from the initial method call
3471 /* Note: if this test is run in OOM mode, it will block when the bus
3472 * doesn't send a reply due to OOM.
3474 block_connection_until_message_from_bus (context, connection, "reply from echo message after auto-activation");
3476 message = pop_message_waiting_for_memory (connection);
3477 if (message == NULL)
3479 _dbus_warn ("Failed to pop message! Should have been reply from echo message\n");
3483 if (dbus_message_get_reply_serial (message) != serial)
3485 _dbus_warn ("Wrong reply serial\n");
3489 if (!dbus_message_get_args (message, NULL,
3490 DBUS_TYPE_STRING, &argv[0],
3491 DBUS_TYPE_STRING, &argv[1],
3492 DBUS_TYPE_STRING, &argv[2],
3493 DBUS_TYPE_STRING, &argv[3],
3494 DBUS_TYPE_STRING, &argv[4],
3495 DBUS_TYPE_STRING, &argv[5],
3496 DBUS_TYPE_STRING, &argv[6],
3499 _dbus_warn ("Error getting arguments from return\n");
3503 /* don't worry about arg[0] as it may be different
3504 depending on the path to the tests
3506 if (strcmp("-test", argv[1]) != 0)
3508 _dbus_warn ("Unexpected argv[1] in shell success service test (expected: %s, got: %s)\n",
3513 if (strcmp("that", argv[2]) != 0)
3515 _dbus_warn ("Unexpected argv[2] in shell success service test (expected: %s, got: %s)\n",
3520 if (strcmp("we get", argv[3]) != 0)
3522 _dbus_warn ("Unexpected argv[3] in shell success service test (expected: %s, got: %s)\n",
3527 if (strcmp("back", argv[4]) != 0)
3529 _dbus_warn ("Unexpected argv[4] in shell success service test (expected: %s, got: %s)\n",
3534 if (strcmp("--what", argv[5]) != 0)
3536 _dbus_warn ("Unexpected argv[5] in shell success service test (expected: %s, got: %s)\n",
3541 if (strcmp("we put in", argv[6]) != 0)
3543 _dbus_warn ("Unexpected argv[6] in shell success service test (expected: %s, got: %s)\n",
3544 "we put in", argv[6]);
3548 dbus_message_unref (message);
3551 if (!check_send_exit_to_service (context, connection,
3552 SHELL_SUCCESS_SERVICE_NAME,
3560 dbus_message_unref (message);
3562 if (base_service_message)
3563 dbus_message_unref (base_service_message);
3571 BusContext *context;
3575 check_oom_check1_func (void *data)
3577 Check1Data *d = data;
3579 if (! (* d->func) (d->context))
3582 if (!check_no_leftovers (d->context))
3584 _dbus_warn ("Messages were left over, should be covered by test suite\n");
3592 check1_try_iterations (BusContext *context,
3593 const char *description,
3599 d.context = context;
3601 if (!_dbus_test_oom_handling (description, check_oom_check1_func,
3603 _dbus_assert_not_reached ("test failed");
3607 check_get_services (BusContext *context,
3608 DBusConnection *connection,
3613 DBusMessage *message;
3614 dbus_uint32_t serial;
3621 dbus_error_init (&error);
3624 message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
3626 DBUS_INTERFACE_DBUS,
3629 if (message == NULL)
3632 if (!dbus_connection_send (connection, message, &serial))
3634 dbus_message_unref (message);
3638 /* send our message */
3639 bus_test_run_clients_loop (SEND_PENDING (connection));
3641 dbus_message_unref (message);
3644 dbus_connection_ref (connection); /* because we may get disconnected */
3645 block_connection_until_message_from_bus (context, connection, "reply to ListActivatableNames/ListNames");
3647 if (!dbus_connection_get_is_connected (connection))
3649 _dbus_verbose ("connection was disconnected: %s %d\n", _DBUS_FUNCTION_NAME, __LINE__);
3651 dbus_connection_unref (connection);
3656 dbus_connection_unref (connection);
3658 message = pop_message_waiting_for_memory (connection);
3659 if (message == NULL)
3661 _dbus_warn ("Did not receive a reply to %s %d on %p\n",
3662 method, serial, connection);
3666 verbose_message_received (connection, message);
3668 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
3670 if (dbus_message_is_error (message, DBUS_ERROR_NO_MEMORY))
3672 ; /* good, this is a valid response */
3676 warn_unexpected (connection, message, "not this error");
3683 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_RETURN)
3685 ; /* good, expected */
3689 warn_unexpected (connection, message,
3690 "method_return for ListActivatableNames/ListNames");
3697 if (!dbus_message_get_args (message, &error,
3703 if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
3705 _dbus_verbose ("no memory to list services by %s\n", method);
3706 dbus_error_free (&error);
3707 _dbus_wait_for_memory ();
3708 goto retry_get_property;
3712 _dbus_assert (dbus_error_is_set (&error));
3713 _dbus_warn ("Did not get the expected DBUS_TYPE_ARRAY from %s\n", method);
3722 if (!check_no_leftovers (context))
3728 dbus_error_free (&error);
3731 dbus_message_unref (message);
3736 /* returns TRUE if the correct thing happens,
3737 * but the correct thing may include OOM errors.
3740 check_list_services (BusContext *context,
3741 DBusConnection *connection)
3743 DBusMessage *message;
3744 DBusMessage *base_service_message;
3745 const char *base_service;
3746 dbus_uint32_t serial;
3748 const char *existent = EXISTENT_SERVICE_NAME;
3749 dbus_uint32_t flags;
3753 _dbus_verbose ("check_list_services for %p\n", connection);
3755 if (!check_get_services (context, connection, "ListActivatableNames", &services, &len))
3760 if (!_dbus_string_array_contains ((const char **)services, existent))
3762 _dbus_warn ("Did not get the expected %s from ListActivatableNames\n", existent);
3766 dbus_free_string_array (services);
3768 base_service_message = NULL;
3770 message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
3772 DBUS_INTERFACE_DBUS,
3773 "StartServiceByName");
3775 if (message == NULL)
3778 dbus_message_set_auto_start (message, FALSE);
3781 if (!dbus_message_append_args (message,
3782 DBUS_TYPE_STRING, &existent,
3783 DBUS_TYPE_UINT32, &flags,
3786 dbus_message_unref (message);
3790 if (!dbus_connection_send (connection, message, &serial))
3792 dbus_message_unref (message);
3796 dbus_message_unref (message);
3799 bus_test_run_everything (context);
3801 /* now wait for the message bus to hear back from the activated
3804 block_connection_until_message_from_bus (context, connection, "activated service to connect");
3806 bus_test_run_everything (context);
3808 if (!dbus_connection_get_is_connected (connection))
3810 _dbus_verbose ("connection was disconnected: %s %d\n", _DBUS_FUNCTION_NAME, __LINE__);
3816 message = pop_message_waiting_for_memory (connection);
3817 if (message == NULL)
3819 _dbus_warn ("Did not receive any messages after %s %d on %p\n",
3820 "StartServiceByName", serial, connection);
3824 verbose_message_received (connection, message);
3825 _dbus_verbose (" (after sending %s)\n", "StartServiceByName");
3827 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR)
3829 if (!dbus_message_has_sender (message, DBUS_SERVICE_DBUS))
3831 _dbus_warn ("Message has wrong sender %s\n",
3832 dbus_message_get_sender (message) ?
3833 dbus_message_get_sender (message) : "(none)");
3837 if (dbus_message_is_error (message,
3838 DBUS_ERROR_NO_MEMORY))
3840 ; /* good, this is a valid response */
3842 else if (dbus_message_is_error (message,
3843 DBUS_ERROR_SPAWN_CHILD_EXITED) ||
3844 dbus_message_is_error (message,
3845 DBUS_ERROR_SPAWN_CHILD_SIGNALED) ||
3846 dbus_message_is_error (message,
3847 DBUS_ERROR_SPAWN_EXEC_FAILED))
3849 ; /* good, this is expected also */
3853 _dbus_warn ("Did not expect error %s\n",
3854 dbus_message_get_error_name (message));
3860 GotServiceInfo message_kind;
3862 if (!check_base_service_activated (context, connection,
3863 message, &base_service))
3866 base_service_message = message;
3869 /* We may need to block here for the test service to exit or finish up */
3870 block_connection_until_message_from_bus (context, connection, "test service to exit or finish up");
3872 message = dbus_connection_borrow_message (connection);
3873 if (message == NULL)
3875 _dbus_warn ("Did not receive any messages after base service creation notification\n");
3879 message_kind = check_got_service_info (message);
3881 dbus_connection_return_message (connection, message);
3884 switch (message_kind)
3886 case GOT_SOMETHING_ELSE:
3888 case GOT_SERVICE_DELETED:
3889 _dbus_warn ("Unexpected message after ActivateService "
3890 "(should be an error or a service announcement)\n");
3893 case GOT_SERVICE_CREATED:
3894 message = pop_message_waiting_for_memory (connection);
3895 if (message == NULL)
3897 _dbus_warn ("Failed to pop message we just put back! "
3898 "should have been a NameOwnerChanged (creation)\n");
3902 if (!check_service_activated (context, connection, EXISTENT_SERVICE_NAME,
3903 base_service, message))
3906 dbus_message_unref (message);
3909 if (!check_no_leftovers (context))
3911 _dbus_warn ("Messages were left over after successful activation\n");
3919 if (!check_get_services (context, connection, "ListNames", &services, &len))
3924 if (!_dbus_string_array_contains ((const char **)services, existent))
3926 _dbus_warn ("Did not get the expected %s from ListNames\n", existent);
3930 dbus_free_string_array (services);
3932 if (!check_send_exit_to_service (context, connection,
3933 EXISTENT_SERVICE_NAME, base_service))
3940 dbus_message_unref (message);
3942 if (base_service_message)
3943 dbus_message_unref (base_service_message);
3951 BusContext *context;
3952 DBusConnection *connection;
3956 check_oom_check2_func (void *data)
3958 Check2Data *d = data;
3960 if (! (* d->func) (d->context, d->connection))
3963 if (!check_no_leftovers (d->context))
3965 _dbus_warn ("Messages were left over, should be covered by test suite\n");
3973 check2_try_iterations (BusContext *context,
3974 DBusConnection *connection,
3975 const char *description,
3981 d.context = context;
3982 d.connection = connection;
3984 if (!_dbus_test_oom_handling (description, check_oom_check2_func,
3987 _dbus_warn ("%s failed during oom\n", description);
3988 _dbus_assert_not_reached ("test failed");
3993 bus_dispatch_test (const DBusString *test_data_dir)
3995 BusContext *context;
3996 DBusConnection *foo;
3997 DBusConnection *bar;
3998 DBusConnection *baz;
4001 dbus_error_init (&error);
4003 context = bus_context_new_test (test_data_dir,
4004 "valid-config-files/debug-allow-all.conf");
4005 if (context == NULL)
4008 foo = dbus_connection_open_private ("debug-pipe:name=test-server", &error);
4010 _dbus_assert_not_reached ("could not alloc connection");
4012 if (!bus_setup_debug_client (foo))
4013 _dbus_assert_not_reached ("could not set up connection");
4015 spin_connection_until_authenticated (context, foo);
4017 if (!check_hello_message (context, foo))
4018 _dbus_assert_not_reached ("hello message failed");
4020 if (!check_double_hello_message (context, foo))
4021 _dbus_assert_not_reached ("double hello message failed");
4023 if (!check_add_match_all (context, foo))
4024 _dbus_assert_not_reached ("AddMatch message failed");
4026 bar = dbus_connection_open_private ("debug-pipe:name=test-server", &error);
4028 _dbus_assert_not_reached ("could not alloc connection");
4030 if (!bus_setup_debug_client (bar))
4031 _dbus_assert_not_reached ("could not set up connection");
4033 spin_connection_until_authenticated (context, bar);
4035 if (!check_hello_message (context, bar))
4036 _dbus_assert_not_reached ("hello message failed");
4038 if (!check_add_match_all (context, bar))
4039 _dbus_assert_not_reached ("AddMatch message failed");
4041 baz = dbus_connection_open_private ("debug-pipe:name=test-server", &error);
4043 _dbus_assert_not_reached ("could not alloc connection");
4045 if (!bus_setup_debug_client (baz))
4046 _dbus_assert_not_reached ("could not set up connection");
4048 spin_connection_until_authenticated (context, baz);
4050 if (!check_hello_message (context, baz))
4051 _dbus_assert_not_reached ("hello message failed");
4053 if (!check_add_match_all (context, baz))
4054 _dbus_assert_not_reached ("AddMatch message failed");
4056 if (!check_get_connection_unix_user (context, baz))
4057 _dbus_assert_not_reached ("GetConnectionUnixUser message failed");
4059 if (!check_get_connection_unix_process_id (context, baz))
4060 _dbus_assert_not_reached ("GetConnectionUnixProcessID message failed");
4062 if (!check_list_services (context, baz))
4063 _dbus_assert_not_reached ("ListActivatableNames message failed");
4065 if (!check_no_leftovers (context))
4067 _dbus_warn ("Messages were left over after setting up initial connections\n");
4068 _dbus_assert_not_reached ("initial connection setup failed");
4071 check1_try_iterations (context, "create_and_hello",
4072 check_hello_connection);
4074 check2_try_iterations (context, foo, "nonexistent_service_no_auto_start",
4075 check_nonexistent_service_no_auto_start);
4077 #ifdef DBUS_WIN_FIXME
4078 _dbus_warn("TODO: dispatch.c segfault_service_no_auto_start test\n");
4080 check2_try_iterations (context, foo, "segfault_service_no_auto_start",
4081 check_segfault_service_no_auto_start);
4084 check2_try_iterations (context, foo, "existent_service_no_auto_start",
4085 check_existent_service_no_auto_start);
4087 check2_try_iterations (context, foo, "nonexistent_service_auto_start",
4088 check_nonexistent_service_auto_start);
4091 #ifdef DBUS_WIN_FIXME
4092 _dbus_warn("TODO: dispatch.c segfault_service_auto_start test\n");
4094 check2_try_iterations (context, foo, "segfault_service_auto_start",
4095 check_segfault_service_auto_start);
4098 check2_try_iterations (context, foo, "shell_fail_service_auto_start",
4099 check_shell_fail_service_auto_start);
4102 /* Note: need to resolve some issues with the testing code in order to run
4103 * this in oom (handle that we sometimes don't get replies back from the bus
4104 * when oom happens, without blocking the test).
4106 check2_try_iterations (context, foo, "existent_service_auto_auto_start",
4107 check_existent_service_auto_start);
4110 if (!check_existent_service_auto_start (context, foo))
4111 _dbus_assert_not_reached ("existent service auto start failed");
4113 if (!check_shell_service_success_auto_start (context, foo))
4114 _dbus_assert_not_reached ("shell success service auto start failed");
4116 _dbus_verbose ("Disconnecting foo, bar, and baz\n");
4118 kill_client_connection_unchecked (foo);
4119 kill_client_connection_unchecked (bar);
4120 kill_client_connection_unchecked (baz);
4122 bus_context_unref (context);
4128 bus_dispatch_sha1_test (const DBusString *test_data_dir)
4130 BusContext *context;
4131 DBusConnection *foo;
4134 dbus_error_init (&error);
4136 /* Test SHA1 authentication */
4137 _dbus_verbose ("Testing SHA1 context\n");
4139 context = bus_context_new_test (test_data_dir,
4140 "valid-config-files/debug-allow-all-sha1.conf");
4141 if (context == NULL)
4144 foo = dbus_connection_open_private ("debug-pipe:name=test-server", &error);
4146 _dbus_assert_not_reached ("could not alloc connection");
4148 if (!bus_setup_debug_client (foo))
4149 _dbus_assert_not_reached ("could not set up connection");
4151 spin_connection_until_authenticated (context, foo);
4153 if (!check_hello_message (context, foo))
4154 _dbus_assert_not_reached ("hello message failed");
4156 if (!check_add_match_all (context, foo))
4157 _dbus_assert_not_reached ("addmatch message failed");
4159 if (!check_no_leftovers (context))
4161 _dbus_warn ("Messages were left over after setting up initial SHA-1 connection\n");
4162 _dbus_assert_not_reached ("initial connection setup failed");
4165 check1_try_iterations (context, "create_and_hello_sha1",
4166 check_hello_connection);
4168 kill_client_connection_unchecked (foo);
4170 bus_context_unref (context);
4175 #endif /* DBUS_BUILD_TESTS */