DBusConnection *monitor;
DBusConnection *sender;
DBusConnection *recipient;
+ gboolean recipient_enqueue_filter_added;
GQueue monitored;
+ GQueue received;
const char *monitor_name;
const char *sender_name;
FALSE
};
+static const char * const well_known_destination_match_rules[] = {
+ "destination='com.example.Recipient'",
+ NULL
+};
+
static Config forbidding_config = {
"valid-config-files/forbidding.conf",
NULL,
FALSE
};
+static Config well_known_destination_config = {
+ NULL,
+ well_known_destination_match_rules,
+ FALSE
+};
+
static Config no_rules_config = {
NULL,
no_match_rules,
FALSE
};
+#ifdef DBUS_UNIX
static Config fake_systemd_config = {
"valid-config-files/systemd-activation.conf",
NULL,
FALSE
};
+#endif
static Config side_effects_config = {
NULL,
}
static DBusHandlerResult
-recipient_filter (DBusConnection *connection,
+recipient_check_filter (DBusConnection *connection,
DBusMessage *message,
void *user_data)
{
}
static DBusHandlerResult
+recipient_enqueue_filter (DBusConnection *connection,
+ DBusMessage *message,
+ void *user_data)
+{
+ Fixture *f = user_data;
+
+ if (dbus_message_is_signal (message, DBUS_INTERFACE_DBUS,
+ "NameAcquired") ||
+ dbus_message_is_signal (message, DBUS_INTERFACE_DBUS,
+ "NameLost") ||
+ dbus_message_is_signal (message, DBUS_INTERFACE_DBUS,
+ "NameOwnerChanged"))
+ {
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ }
+
+ g_queue_push_tail (&f->received, dbus_message_ref (message));
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+}
+
+static DBusHandlerResult
systemd_filter (DBusConnection *connection,
DBusMessage *message,
void *user_data)
}
static void
+take_well_known_name (Fixture *f,
+ DBusConnection *connection,
+ const char *name)
+{
+ int ret;
+
+ ret = dbus_bus_request_name (connection, name,
+ DBUS_NAME_FLAG_DO_NOT_QUEUE, &f->e);
+ test_assert_no_error (&f->e);
+ g_assert_cmpint (ret, ==, DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER);
+}
+
+static void
setup (Fixture *f,
gconstpointer context)
{
dbus_error_init (&f->e);
f->address = test_get_dbus_daemon (f->config ? f->config->config_file : NULL,
- TEST_USER_ME, &f->daemon_pid);
+ TEST_USER_ME, NULL, &f->daemon_pid);
if (f->address == NULL)
return;
if (!dbus_connection_add_filter (f->monitor, monitor_filter, f, NULL))
g_error ("OOM");
- if (!dbus_connection_add_filter (f->recipient, recipient_filter, f, NULL))
+ if (!dbus_connection_add_filter (f->recipient, recipient_check_filter,
+ f, NULL))
g_error ("OOM");
}
static void
-become_monitor (Fixture *f)
+become_monitor (Fixture *f,
+ const Config *config)
{
DBusMessage *m;
DBusPendingCall *pc;
int i;
dbus_uint32_t zero = 0;
- if (f->config != NULL && f->config->match_rules != NULL)
- match_rules = f->config->match_rules;
+ dbus_connection_set_route_peer_messages (f->monitor, TRUE);
+
+ if (config == NULL)
+ config = f->config;
+
+ if (config != NULL && config->match_rules != NULL)
+ match_rules = config->match_rules;
else
match_rules = wildcard_match_rules;
}
/*
+ * Test what happens if the method call arguments are invalid.
+ */
+static void
+test_invalid (Fixture *f,
+ gconstpointer context)
+{
+ DBusMessage *m;
+ DBusPendingCall *pc;
+ dbus_bool_t ok;
+ DBusMessageIter appender, array_appender;
+ dbus_uint32_t zero = 0;
+ dbus_uint32_t invalid_flags = G_MAXUINT32;
+ const char *s;
+
+ if (f->address == NULL)
+ return;
+
+ dbus_connection_set_route_peer_messages (f->monitor, TRUE);
+
+ /* Try to become a monitor but specify nonzero flags - not allowed */
+
+ m = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
+ DBUS_PATH_DBUS, DBUS_INTERFACE_MONITORING, "BecomeMonitor");
+
+ if (m == NULL)
+ g_error ("OOM");
+
+ dbus_message_iter_init_append (m, &appender);
+
+ if (!dbus_message_iter_open_container (&appender, DBUS_TYPE_ARRAY, "s",
+ &array_appender))
+ g_error ("OOM");
+
+ if (!dbus_message_iter_close_container (&appender, &array_appender) ||
+ !dbus_message_iter_append_basic (&appender, DBUS_TYPE_UINT32,
+ &invalid_flags))
+ g_error ("OOM");
+
+ if (!dbus_connection_send_with_reply (f->monitor, m, &pc,
+ DBUS_TIMEOUT_USE_DEFAULT) ||
+ pc == NULL)
+ g_error ("OOM");
+
+ dbus_message_unref (m);
+ m = NULL;
+
+ if (dbus_pending_call_get_completed (pc))
+ test_pending_call_store_reply (pc, &m);
+ else if (!dbus_pending_call_set_notify (pc, test_pending_call_store_reply,
+ &m, NULL))
+ g_error ("OOM");
+
+ while (m == NULL)
+ test_main_context_iterate (f->ctx, TRUE);
+
+ g_assert_cmpint (dbus_message_get_type (m), ==, DBUS_MESSAGE_TYPE_ERROR);
+ g_assert_cmpstr (dbus_message_get_error_name (m), ==,
+ DBUS_ERROR_INVALID_ARGS);
+
+ /* Try to become a monitor but use the wrong object path - not allowed
+ * (security hardening against inappropriate XML policy rules) */
+
+ dbus_pending_call_unref (pc);
+ dbus_message_unref (m);
+
+ m = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
+ "/", DBUS_INTERFACE_MONITORING, "BecomeMonitor");
+
+ if (m == NULL)
+ g_error ("OOM");
+
+ dbus_message_iter_init_append (m, &appender);
+
+ if (!dbus_message_iter_open_container (&appender, DBUS_TYPE_ARRAY, "s",
+ &array_appender))
+ g_error ("OOM");
+
+ if (!dbus_message_iter_close_container (&appender, &array_appender) ||
+ !dbus_message_iter_append_basic (&appender, DBUS_TYPE_UINT32, &zero))
+ g_error ("OOM");
+
+ if (!dbus_connection_send_with_reply (f->monitor, m, &pc,
+ DBUS_TIMEOUT_USE_DEFAULT) ||
+ pc == NULL)
+ g_error ("OOM");
+
+ dbus_message_unref (m);
+ m = NULL;
+
+ if (dbus_pending_call_get_completed (pc))
+ test_pending_call_store_reply (pc, &m);
+ else if (!dbus_pending_call_set_notify (pc, test_pending_call_store_reply,
+ &m, NULL))
+ g_error ("OOM");
+
+ while (m == NULL)
+ test_main_context_iterate (f->ctx, TRUE);
+
+ g_assert_cmpint (dbus_message_get_type (m), ==, DBUS_MESSAGE_TYPE_ERROR);
+ g_assert_cmpstr (dbus_message_get_error_name (m), ==,
+ DBUS_ERROR_UNKNOWN_INTERFACE);
+
+ /* Try to become a monitor but specify a bad match rule -
+ * also not allowed */
+
+ dbus_pending_call_unref (pc);
+ dbus_message_unref (m);
+
+ m = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
+ DBUS_PATH_DBUS, DBUS_INTERFACE_MONITORING, "BecomeMonitor");
+
+ if (m == NULL)
+ g_error ("OOM");
+
+ dbus_message_iter_init_append (m, &appender);
+
+ if (!dbus_message_iter_open_container (&appender, DBUS_TYPE_ARRAY, "s",
+ &array_appender))
+ g_error ("OOM");
+
+ /* Syntactically incorrect match rule taken from #92298 - was probably
+ * intended to be path='/modules/...'
+ */
+ s = "interface='org.kde.walletd',member='/modules/kwalletd/org.kde.KWallet/walletOpened'";
+
+ if (!dbus_message_iter_append_basic (&array_appender, DBUS_TYPE_STRING,
+ &s) ||
+ !dbus_message_iter_close_container (&appender, &array_appender) ||
+ !dbus_message_iter_append_basic (&appender, DBUS_TYPE_UINT32, &zero) ||
+ !dbus_connection_send_with_reply (f->monitor, m, &pc,
+ DBUS_TIMEOUT_USE_DEFAULT) ||
+ pc == NULL)
+ g_error ("OOM");
+
+ dbus_message_unref (m);
+ m = NULL;
+
+ if (dbus_pending_call_get_completed (pc))
+ test_pending_call_store_reply (pc, &m);
+ else if (!dbus_pending_call_set_notify (pc, test_pending_call_store_reply,
+ &m, NULL))
+ g_error ("OOM");
+
+ while (m == NULL)
+ test_main_context_iterate (f->ctx, TRUE);
+
+ g_assert_cmpint (dbus_message_get_type (m), ==, DBUS_MESSAGE_TYPE_ERROR);
+ g_assert_cmpstr (dbus_message_get_error_name (m), ==,
+ DBUS_ERROR_MATCH_RULE_INVALID);
+
+ dbus_pending_call_unref (pc);
+ dbus_message_unref (m);
+
+ /* We did not become a monitor, so we can still call methods. */
+
+ pc = NULL;
+ m = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
+ DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS, "GetId");
+
+ if (m == NULL)
+ g_error ("OOM");
+
+ if (!dbus_connection_send_with_reply (f->monitor, m, &pc,
+ DBUS_TIMEOUT_USE_DEFAULT) ||
+ pc == NULL)
+ g_error ("OOM");
+
+ dbus_message_unref (m);
+ m = NULL;
+
+ if (dbus_pending_call_get_completed (pc))
+ test_pending_call_store_reply (pc, &m);
+ else if (!dbus_pending_call_set_notify (pc, test_pending_call_store_reply,
+ &m, NULL))
+ g_error ("OOM");
+
+ while (m == NULL)
+ test_main_context_iterate (f->ctx, TRUE);
+
+ if (dbus_set_error_from_message (&f->e, m))
+ g_error ("%s: %s", f->e.name, f->e.message);
+
+ ok = dbus_message_get_args (m, &f->e,
+ DBUS_TYPE_STRING, &s,
+ DBUS_TYPE_INVALID);
+ test_assert_no_error (&f->e);
+ g_assert (ok);
+ g_assert_cmpstr (s, !=, NULL);
+ g_assert_cmpstr (s, !=, "");
+
+ dbus_pending_call_unref (pc);
+ dbus_message_unref (m);
+}
+
+/*
* Test the side-effects of becoming a monitor.
*/
static void
}
}
- become_monitor (f);
+ become_monitor (f, NULL);
while (!lost_unique || !lost_a || !lost_b || !lost_c)
{
dbus_bus_add_match (f->recipient, "type='signal'", &f->e);
test_assert_no_error (&f->e);
- become_monitor (f);
+ become_monitor (f, NULL);
m = dbus_message_new_signal ("/foo", "com.example.bar", "BroadcastSignal1");
dbus_connection_send (f->sender, m, NULL);
dbus_bus_add_match (f->recipient, "type='signal'", &f->e);
test_assert_no_error (&f->e);
- become_monitor (f);
+ if (!dbus_connection_add_filter (f->recipient, recipient_enqueue_filter,
+ f, NULL))
+ g_error ("OOM");
+ f->recipient_enqueue_filter_added = TRUE;
+
+ become_monitor (f, NULL);
m = dbus_message_new_signal ("/foo", "com.example.CannotSend",
"BroadcastSignal1");
dbus_connection_send (f->sender, m, NULL);
dbus_message_unref (m);
- while (g_queue_get_length (&f->monitored) < 6)
+ m = dbus_message_new_signal ("/foo", "com.example.CannotBroadcast",
+ "CannotBroadcast");
+ dbus_connection_send (f->sender, m, NULL);
+ dbus_message_unref (m);
+
+ m = dbus_message_new_signal ("/foo", "com.example.CannotBroadcast2",
+ "CannotBroadcast2");
+ dbus_connection_send (f->sender, m, NULL);
+ dbus_message_unref (m);
+
+ /* these two will go through: we use them as an indirect way to assert that
+ * the recipient has not received anything earlier */
+ m = dbus_message_new_signal ("/foo", "com.example.CannotUnicast",
+ "CannotUnicast");
+ dbus_connection_send (f->sender, m, NULL);
+ dbus_message_unref (m);
+ m = dbus_message_new_signal ("/foo", "com.example.CannotUnicast2",
+ "CannotUnicast2");
+ dbus_connection_send (f->sender, m, NULL);
+ dbus_message_unref (m);
+
+ while (g_queue_get_length (&f->monitored) < 12)
test_main_context_iterate (f->ctx, TRUE);
m = g_queue_pop_head (&f->monitored);
dbus_message_unref (m);
m = g_queue_pop_head (&f->monitored);
+ assert_signal (m, f->sender_name, "/foo", "com.example.CannotBroadcast",
+ "CannotBroadcast", "", NULL);
+ dbus_message_unref (m);
+
+ m = g_queue_pop_head (&f->monitored);
+ assert_error_reply (m, DBUS_SERVICE_DBUS, f->sender_name,
+ DBUS_ERROR_ACCESS_DENIED);
+ dbus_message_unref (m);
+
+ m = g_queue_pop_head (&f->monitored);
+ assert_signal (m, f->sender_name, "/foo", "com.example.CannotBroadcast2",
+ "CannotBroadcast2", "", NULL);
+ dbus_message_unref (m);
+
+ m = g_queue_pop_head (&f->monitored);
+ assert_error_reply (m, DBUS_SERVICE_DBUS, f->sender_name,
+ DBUS_ERROR_ACCESS_DENIED);
+ dbus_message_unref (m);
+
+ m = g_queue_pop_head (&f->monitored);
+ assert_signal (m, f->sender_name, "/foo", "com.example.CannotUnicast",
+ "CannotUnicast", "", NULL);
+ dbus_message_unref (m);
+
+ m = g_queue_pop_head (&f->monitored);
+ assert_signal (m, f->sender_name, "/foo", "com.example.CannotUnicast2",
+ "CannotUnicast2", "", NULL);
+ dbus_message_unref (m);
+
+ m = g_queue_pop_head (&f->monitored);
+ g_assert (m == NULL);
+
+ /* the intended recipient only received the ones that were on the interface
+ * where broadcasts are allowed */
+
+ while (g_queue_get_length (&f->received) < 2)
+ test_main_context_iterate (f->ctx, TRUE);
+
+ m = g_queue_pop_head (&f->received);
+ assert_signal (m, f->sender_name, "/foo", "com.example.CannotUnicast",
+ "CannotUnicast", "", NULL);
+ dbus_message_unref (m);
+
+ m = g_queue_pop_head (&f->received);
+ assert_signal (m, f->sender_name, "/foo", "com.example.CannotUnicast2",
+ "CannotUnicast2", "", NULL);
+ dbus_message_unref (m);
+
+ m = g_queue_pop_head (&f->received);
g_assert (m == NULL);
}
if (f->address == NULL)
return;
- become_monitor (f);
+ become_monitor (f, NULL);
m = dbus_message_new_signal ("/foo", "com.example.bar", "UnicastSignal1");
if (!dbus_message_set_destination (m, f->recipient_name))
if (f->address == NULL)
return;
- become_monitor (f);
+ if (!dbus_connection_add_filter (f->recipient, recipient_enqueue_filter,
+ f, NULL))
+ g_error ("OOM");
+ f->recipient_enqueue_filter_added = TRUE;
+
+ become_monitor (f, NULL);
m = dbus_message_new_signal ("/foo", "com.example.CannotSend",
"UnicastSignal1");
dbus_connection_send (f->sender, m, NULL);
dbus_message_unref (m);
- while (g_queue_get_length (&f->monitored) < 6)
+ m = dbus_message_new_signal ("/foo", "com.example.CannotUnicast",
+ "CannotUnicast");
+ if (!dbus_message_set_destination (m, f->recipient_name))
+ g_error ("OOM");
+ dbus_connection_send (f->sender, m, NULL);
+ dbus_message_unref (m);
+
+ m = dbus_message_new_signal ("/foo", "com.example.CannotUnicast2",
+ "CannotUnicast2");
+ if (!dbus_message_set_destination (m, f->recipient_name))
+ g_error ("OOM");
+ dbus_connection_send (f->sender, m, NULL);
+ dbus_message_unref (m);
+
+ /* these two will go through: we use them as an indirect way to assert that
+ * the recipient has not received anything earlier */
+ m = dbus_message_new_signal ("/foo", "com.example.CannotBroadcast",
+ "CannotBroadcast");
+ if (!dbus_message_set_destination (m, f->recipient_name))
+ g_error ("OOM");
+ dbus_connection_send (f->sender, m, NULL);
+ dbus_message_unref (m);
+ m = dbus_message_new_signal ("/foo", "com.example.CannotBroadcast2",
+ "CannotBroadcast2");
+ if (!dbus_message_set_destination (m, f->recipient_name))
+ g_error ("OOM");
+ dbus_connection_send (f->sender, m, NULL);
+ dbus_message_unref (m);
+
+ while (g_queue_get_length (&f->monitored) < 12)
test_main_context_iterate (f->ctx, TRUE);
m = g_queue_pop_head (&f->monitored);
dbus_message_unref (m);
m = g_queue_pop_head (&f->monitored);
+ assert_signal (m, f->sender_name, "/foo", "com.example.CannotUnicast",
+ "CannotUnicast", "", f->recipient_name);
+ dbus_message_unref (m);
+
+ m = g_queue_pop_head (&f->monitored);
+ assert_error_reply (m, DBUS_SERVICE_DBUS, f->sender_name,
+ DBUS_ERROR_ACCESS_DENIED);
+ dbus_message_unref (m);
+
+ m = g_queue_pop_head (&f->monitored);
+ assert_signal (m, f->sender_name, "/foo", "com.example.CannotUnicast2",
+ "CannotUnicast2", "", f->recipient_name);
+ dbus_message_unref (m);
+
+ m = g_queue_pop_head (&f->monitored);
+ assert_error_reply (m, DBUS_SERVICE_DBUS, f->sender_name,
+ DBUS_ERROR_ACCESS_DENIED);
+ dbus_message_unref (m);
+
+ m = g_queue_pop_head (&f->monitored);
+ assert_signal (m, f->sender_name, "/foo", "com.example.CannotBroadcast",
+ "CannotBroadcast", "", f->recipient_name);
+ dbus_message_unref (m);
+
+ m = g_queue_pop_head (&f->monitored);
+ assert_signal (m, f->sender_name, "/foo", "com.example.CannotBroadcast2",
+ "CannotBroadcast2", "", f->recipient_name);
+ dbus_message_unref (m);
+
+ m = g_queue_pop_head (&f->monitored);
+ g_assert (m == NULL);
+
+ /* the intended recipient only received the ones that were on the interface
+ * where unicasts are allowed */
+
+ while (g_queue_get_length (&f->received) < 2)
+ test_main_context_iterate (f->ctx, TRUE);
+
+ m = g_queue_pop_head (&f->received);
+ assert_signal (m, f->sender_name, "/foo", "com.example.CannotBroadcast",
+ "CannotBroadcast", "", f->recipient_name);
+ dbus_message_unref (m);
+
+ m = g_queue_pop_head (&f->received);
+ assert_signal (m, f->sender_name, "/foo", "com.example.CannotBroadcast2",
+ "CannotBroadcast2", "", f->recipient_name);
+ dbus_message_unref (m);
+
+ m = g_queue_pop_head (&f->received);
g_assert (m == NULL);
}
if (f->address == NULL)
return;
- become_monitor (f);
+ become_monitor (f, NULL);
+
+ /* regression test for
+ * https://bugs.freedesktop.org/show_bug.cgi?id=90952 */
+ m = dbus_message_new_method_call (f->recipient_name, "/foo",
+ DBUS_INTERFACE_PEER, "Ping");
+ dbus_connection_send (f->sender, m, NULL);
+ dbus_message_unref (m);
+
+ while (g_queue_get_length (&f->monitored) < 2)
+ test_main_context_iterate (f->ctx, TRUE);
+
+ m = g_queue_pop_head (&f->monitored);
+ assert_method_call (m, f->sender_name, f->recipient_name, "/foo",
+ DBUS_INTERFACE_PEER, "Ping", "");
+ dbus_message_unref (m);
+
+ m = g_queue_pop_head (&f->monitored);
+ assert_method_reply (m, f->recipient_name, f->sender_name, "");
+ dbus_message_unref (m);
+
+ m = g_queue_pop_head (&f->monitored);
+ g_assert (m == NULL);
m = dbus_message_new_method_call (f->recipient_name, "/foo", "com.example.bar",
"Call1");
if (f->address == NULL)
return;
- become_monitor (f);
+ become_monitor (f, NULL);
m = dbus_message_new_method_call (f->recipient_name, "/foo",
"com.example.CannotSend", "Call1");
if (f->address == NULL)
return;
- become_monitor (f);
+ become_monitor (f, NULL);
res = dbus_bus_request_name (f->sender, "com.example.Sender",
DBUS_NAME_FLAG_DO_NOT_QUEUE, &f->e);
"eavesdrop='true',interface='com.example.Tedious'", &f->e);
test_assert_no_error (&f->e);
- become_monitor (f);
+ become_monitor (f, NULL);
m = dbus_message_new_signal ("/foo", "com.example.Interesting",
"UnicastSignal1");
}
static void
+test_well_known_destination (Fixture *f,
+ gconstpointer context)
+{
+ DBusMessage *m;
+
+ if (f->address == NULL)
+ return;
+
+ take_well_known_name (f, f->recipient, "com.example.Recipient");
+ /* we don't expect_take_well_known_name here because the
+ * monitor isn't up yet */
+
+ become_monitor (f, NULL);
+
+ /* The sender sends a message to itself. It will not be observed. */
+ m = dbus_message_new_signal ("/foo", "com.example.bar", "Unobserved");
+ if (!dbus_message_set_destination (m, f->sender_name))
+ g_error ("OOM");
+ dbus_connection_send (f->sender, m, NULL);
+ dbus_message_unref (m);
+
+ /* The sender sends a message to the recipient by well-known name.
+ * It will be observed. */
+ m = dbus_message_new_signal ("/foo", "com.example.bar", "Observed1");
+ if (!dbus_message_set_destination (m, "com.example.Recipient"))
+ g_error ("OOM");
+ dbus_connection_send (f->sender, m, NULL);
+ dbus_message_unref (m);
+
+ /* The sender sends a message to the recipient by unique name.
+ * It will still be observed. */
+ m = dbus_message_new_signal ("/foo", "com.example.bar", "Observed2");
+ if (!dbus_message_set_destination (m, f->recipient_name))
+ g_error ("OOM");
+ dbus_connection_send (f->sender, m, NULL);
+ dbus_message_unref (m);
+
+ while (g_queue_get_length (&f->monitored) < 2)
+ test_main_context_iterate (f->ctx, TRUE);
+
+ m = g_queue_pop_head (&f->monitored);
+ assert_signal (m, f->sender_name, "/foo", "com.example.bar",
+ "Observed1", "", "com.example.Recipient");
+ dbus_message_unref (m);
+
+ m = g_queue_pop_head (&f->monitored);
+ assert_signal (m, f->sender_name, "/foo", "com.example.bar",
+ "Observed2", "", f->recipient_name);
+ dbus_message_unref (m);
+
+ m = g_queue_pop_head (&f->monitored);
+ g_assert (m == NULL);
+}
+
+static void
+test_unique_destination (Fixture *f,
+ gconstpointer context)
+{
+ DBusMessage *m;
+ Config config = {
+ NULL,
+ NULL, /* match rules */
+ FALSE
+ };
+ const gchar *match_rules[2] = { NULL, NULL };
+ gchar *rule;
+
+ if (f->address == NULL)
+ return;
+
+ take_well_known_name (f, f->recipient, "com.example.Recipient");
+ /* we don't expect_take_well_known_name here because the
+ * monitor isn't up yet */
+
+ rule = g_strdup_printf ("destination='%s'", f->recipient_name);
+ /* free it later */
+ g_test_queue_free (rule);
+ match_rules[0] = rule;
+ config.match_rules = match_rules;
+
+ become_monitor (f, &config);
+
+ /* The sender sends a message to itself. It will not be observed. */
+ m = dbus_message_new_signal ("/foo", "com.example.bar", "Unobserved");
+ if (!dbus_message_set_destination (m, f->sender_name))
+ g_error ("OOM");
+ dbus_connection_send (f->sender, m, NULL);
+ dbus_message_unref (m);
+
+ /* The sender sends a message to the recipient by well-known name.
+ * It will be observed. */
+ m = dbus_message_new_signal ("/foo", "com.example.bar", "Observed1");
+ if (!dbus_message_set_destination (m, "com.example.Recipient"))
+ g_error ("OOM");
+ dbus_connection_send (f->sender, m, NULL);
+ dbus_message_unref (m);
+
+ /* The sender sends a message to the recipient by unique name.
+ * It will still be observed. */
+ m = dbus_message_new_signal ("/foo", "com.example.bar", "Observed2");
+ if (!dbus_message_set_destination (m, f->recipient_name))
+ g_error ("OOM");
+ dbus_connection_send (f->sender, m, NULL);
+ dbus_message_unref (m);
+
+ while (g_queue_get_length (&f->monitored) < 2)
+ test_main_context_iterate (f->ctx, TRUE);
+
+ m = g_queue_pop_head (&f->monitored);
+ assert_signal (m, f->sender_name, "/foo", "com.example.bar",
+ "Observed1", "", "com.example.Recipient");
+ dbus_message_unref (m);
+
+ m = g_queue_pop_head (&f->monitored);
+ assert_signal (m, f->sender_name, "/foo", "com.example.bar",
+ "Observed2", "", f->recipient_name);
+ dbus_message_unref (m);
+
+ m = g_queue_pop_head (&f->monitored);
+ g_assert (m == NULL);
+}
+
+#ifdef DBUS_UNIX
+/* currently only used for the systemd activation test */
+static void
expect_new_connection (Fixture *f)
{
DBusMessage *m;
dbus_message_unref (m);
}
-static void
-take_well_known_name (Fixture *f,
- DBusConnection *connection,
- const char *name)
-{
- int ret;
-
- ret = dbus_bus_request_name (connection, name,
- DBUS_NAME_FLAG_DO_NOT_QUEUE, &f->e);
- test_assert_no_error (&f->e);
- g_assert_cmpint (ret, ==, DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER);
-}
-
+/* currently only used for the systemd activation test */
static void
expect_take_well_known_name (Fixture *f,
DBusConnection *connection,
if (f->address == NULL)
return;
- become_monitor (f);
+ become_monitor (f, NULL);
/* The sender sends a message to an activatable service. */
m = dbus_message_new_signal ("/foo", "com.example.bar", "UnicastSignal1");
"com.example.Nope");
dbus_message_unref (m);
}
+#endif /* DBUS_UNIX */
static void
teardown (Fixture *f,
if (f->recipient != NULL)
{
- dbus_connection_remove_filter (f->recipient, recipient_filter, f);
+ dbus_connection_remove_filter (f->recipient, recipient_check_filter, f);
+ if (f->recipient_enqueue_filter_added)
+ dbus_connection_remove_filter (f->recipient, recipient_enqueue_filter,
+ f);
dbus_connection_close (f->recipient);
dbus_connection_unref (f->recipient);
f->recipient = NULL;
f->activated = NULL;
}
- test_kill_pid (f->daemon_pid);
- g_spawn_close_pid (f->daemon_pid);
+ if (f->daemon_pid != 0)
+ {
+ test_kill_pid (f->daemon_pid);
+ g_spawn_close_pid (f->daemon_pid);
+ f->daemon_pid = 0;
+ }
test_main_context_unref (f->ctx);
g_queue_foreach (&f->monitored, (GFunc) dbus_message_unref, NULL);
g_queue_clear (&f->monitored);
+ g_queue_foreach (&f->received, (GFunc) dbus_message_unref, NULL);
+ g_queue_clear (&f->received);
+
g_free (f->address);
}
{
test_init (&argc, &argv);
+ g_test_add ("/monitor/invalid", Fixture, NULL,
+ setup, test_invalid, teardown);
g_test_add ("/monitor/become", Fixture, &side_effects_config,
setup, test_become_monitor, teardown);
g_test_add ("/monitor/broadcast", Fixture, NULL,
setup, test_dbus_daemon, teardown);
g_test_add ("/monitor/selective", Fixture, &selective_config,
setup, test_selective, teardown);
+ g_test_add ("/monitor/well-known-destination",
+ Fixture, &well_known_destination_config,
+ setup, test_well_known_destination, teardown);
+ g_test_add ("/monitor/unique-destination",
+ Fixture, NULL,
+ setup, test_unique_destination, teardown);
g_test_add ("/monitor/wildcard", Fixture, &wildcard_config,
setup, test_unicast_signal, teardown);
g_test_add ("/monitor/no-rule", Fixture, &no_rules_config,
setup, test_unicast_signal, teardown);
g_test_add ("/monitor/no-eavesdrop", Fixture, &no_eavesdrop_config,
setup, test_unicast_signal, teardown);
+
+#ifdef DBUS_UNIX
+ /* this relies on the systemd activation code path */
g_test_add ("/monitor/activation", Fixture, &fake_systemd_config,
setup, test_activation, teardown);
+#endif
return g_test_run ();
}