diff options
-rw-r--r-- | test/dbus-daemon.c | 165 |
1 files changed, 144 insertions, 21 deletions
diff --git a/test/dbus-daemon.c b/test/dbus-daemon.c index e8bdace3..e57fcfa9 100644 --- a/test/dbus-daemon.c +++ b/test/dbus-daemon.c @@ -100,6 +100,7 @@ typedef struct { gchar *address; DBusConnection *left_conn; + gboolean left_conn_shouted_signal_filter; DBusConnection *right_conn; GQueue held_messages; @@ -107,6 +108,7 @@ typedef struct { gboolean right_conn_hold; gboolean wait_forever_called; guint activation_forking_counter; + guint signal_counter; gchar *tmp_runtime_dir; gchar *saved_runtime_dir; @@ -158,6 +160,19 @@ hold_filter (DBusConnection *connection, return DBUS_HANDLER_RESULT_HANDLED; } +static DBusHandlerResult +shouted_signal_filter (DBusConnection *connection, + DBusMessage *message, + void *user_data) +{ + Fixture *f = user_data; + + if (dbus_message_is_signal (message, "com.example", "Shouted")) + f->signal_counter++; + + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + typedef struct { const char *bug_ref; guint min_messages; @@ -237,6 +252,31 @@ add_hold_filter (Fixture *f) } static void +add_shouted_signal_filter (Fixture *f) +{ + if (!dbus_connection_add_filter (f->left_conn, shouted_signal_filter, f, NULL)) + g_error ("OOM"); + + f->left_conn_shouted_signal_filter = TRUE; +} + +static void +right_conn_emit_shouted (Fixture *f) +{ + DBusMessage *m; + + m = dbus_message_new_signal ("/", "com.example", "Shouted"); + + if (m == NULL) + g_error ("OOM"); + + if (!dbus_connection_send (f->right_conn, m, NULL)) + g_error ("OOM"); + + dbus_clear_message (&m); +} + +static void pc_count (DBusPendingCall *pc, void *data) { @@ -257,30 +297,11 @@ pc_enqueue (DBusPendingCall *pc, } static void -test_echo (Fixture *f, - gconstpointer context) +echo_left_to_right (Fixture *f, + guint count) { - const Config *config = context; - guint count = 2000; guint sent; guint received = 0; - double elapsed; - - if (f->skip) - return; - - if (config != NULL && config->bug_ref != NULL) - g_test_bug (config->bug_ref); - - if (g_test_perf ()) - count = 100000; - - if (config != NULL) - count = MAX (config->min_messages, count); - - add_echo_filter (f); - - g_test_timer_start (); for (sent = 0; sent < count; sent++) { @@ -309,6 +330,33 @@ test_echo (Fixture *f, while (received < count) test_main_context_iterate (f->ctx, TRUE); +} + +static void +test_echo (Fixture *f, + gconstpointer context) +{ + const Config *config = context; + guint count = 2000; + double elapsed; + + if (f->skip) + return; + + if (config != NULL && config->bug_ref != NULL) + g_test_bug (config->bug_ref); + + if (g_test_perf ()) + count = 100000; + + if (config != NULL) + count = MAX (config->min_messages, count); + + add_echo_filter (f); + + g_test_timer_start (); + + echo_left_to_right (f, count); elapsed = g_test_timer_elapsed (); @@ -2535,6 +2583,12 @@ teardown (Fixture *f, if (f->left_conn != NULL) { + if (f->left_conn_shouted_signal_filter) + { + dbus_connection_remove_filter (f->left_conn, shouted_signal_filter, f); + f->left_conn_shouted_signal_filter = FALSE; + } + test_connection_shutdown (f->ctx, f->left_conn); dbus_connection_close (f->left_conn); } @@ -2674,6 +2728,71 @@ static Config send_destination_prefix_config = { TEST_USER_ME, SPECIFY_ADDRESS }; +static void +test_match_remove_fails (Fixture *f, + gconstpointer context G_GNUC_UNUSED) +{ + const char *match_rule = "type='signal'"; + + if (f->skip) + return; + + /* Unlike in test_match_remove_succeeds(), we never added this */ + dbus_bus_remove_match (f->left_conn, match_rule, &f->e); + g_assert_cmpstr (f->e.name, ==, DBUS_ERROR_MATCH_RULE_NOT_FOUND); +} + +static void +test_match_remove_succeeds (Fixture *f, + gconstpointer context G_GNUC_UNUSED) +{ + const char *match_rule = "type='signal'"; + + if (f->skip) + return; + + add_shouted_signal_filter (f); + + /* We use this to make sure that a method call from the "left" connection + * will get a reply from the "right", to sync up */ + add_echo_filter (f); + + /* Emit a signal from the "right" connection, and assert that the "left" + * does not receive it yet */ + f->signal_counter = 0; + right_conn_emit_shouted (f); + /* Because messages are totally-ordered, if the "left" connection was + * going to receive the signal, it would receive it before it got + * the reply from this async call to the "right" connection */ + echo_left_to_right (f, 1); + g_assert_cmpuint (f->signal_counter, ==, 0); + + dbus_bus_add_match (f->left_conn, match_rule, &f->e); + test_assert_no_error (&f->e); + + f->signal_counter = 0; + + /* Emit a signal from the "right" connection, and assert that the "left" + * receives it */ + right_conn_emit_shouted (f); + + while (f->signal_counter < 1) + test_main_context_iterate (f->ctx, TRUE); + + dbus_bus_remove_match (f->left_conn, match_rule, &f->e); + test_assert_no_error (&f->e); + + /* Emit a signal from the "right" connection, and assert that the "left" + * does not receive it this time */ + f->signal_counter = 0; + right_conn_emit_shouted (f); + /* Because messages are totally-ordered, if the "left" connection was + * going to receive the signal, it would receive it before it got + * the reply from this async call to the "right" connection */ + echo_left_to_right (f, 1); + g_assert_cmpuint (f->signal_counter, ==, 0); +} + int main (int argc, char **argv) @@ -2708,6 +2827,10 @@ main (int argc, g_test_add ("/limits/max-names-per-connection", Fixture, &max_names_per_connection_config, setup, test_max_names_per_connection, teardown); + g_test_add ("/match/remove/fails", Fixture, NULL, + setup, test_match_remove_fails, teardown); + g_test_add ("/match/remove/succeeds", Fixture, NULL, + setup, test_match_remove_succeeds, teardown); g_test_add ("/peer/ping", Fixture, NULL, setup, test_peer_ping, teardown); g_test_add ("/peer/get-machine-id", Fixture, NULL, setup, test_peer_get_machine_id, teardown); |