[Pkg-telepathy-commits] [telepathy-glib-1] 112/212: contacts/subscription-states test: redesign to fix a race condition
Simon McVittie
smcv at debian.org
Wed May 14 12:09:02 UTC 2014
This is an automated email from the git hooks/post-receive script.
smcv pushed a commit to branch debian
in repository telepathy-glib-1.
commit 7f8573b7864b8fb60d0838e10621aff3ae0dcd5e
Author: Simon McVittie <simon.mcvittie at collabora.co.uk>
Date: Fri Apr 4 14:00:15 2014 +0100
contacts/subscription-states test: redesign to fix a race condition
Under GDBus, we can receive more than one signal in the same iteration
of the main loop. I missed this instance in my initial GDBus port
because it's inconsistent and hard to reproduce, but it's the same
anti-pattern: we're waiting for two signals that both happen as a
result of the same action:
signal_cb (...)
{
g_main_loop_quit (loop);
}
...
test (...)
{
...
g_main_loop_run (loop);
... things without side-effects ...
g_main_loop_run (loop);
...
}
I think it's better style for test code to be more explicit and have
less spooky-action-at-a-distance, anyway.
Bug: https://bugs.freedesktop.org/show_bug.cgi?id=77139
Reviewed-by: Xavier Claessens
---
tests/dbus/contacts.c | 91 +++++++++++++++++++++++++++++++++++----------------
1 file changed, 63 insertions(+), 28 deletions(-)
diff --git a/tests/dbus/contacts.c b/tests/dbus/contacts.c
index 2de2f73..716e43e 100644
--- a/tests/dbus/contacts.c
+++ b/tests/dbus/contacts.c
@@ -1554,31 +1554,29 @@ test_dup_if_possible (Fixture *f,
typedef struct
{
+ gboolean signal_received;
TpSubscriptionState subscribe;
TpSubscriptionState publish;
- const gchar *publish_request;
-
- GMainLoop *loop;
+ gchar *publish_request;
} SubscriptionStates;
static void
-assert_subscription_states (TpContact *contact,
- SubscriptionStates *states)
-{
- g_assert_cmpint (tp_contact_get_subscribe_state (contact), ==, states->subscribe);
- g_assert_cmpint (tp_contact_get_publish_state (contact), ==, states->publish);
- g_assert_cmpstr (tp_contact_get_publish_request (contact), ==, states->publish_request);
-}
-
-static void
subscription_states_changed_cb (TpContact *contact,
TpSubscriptionState subscribe,
TpSubscriptionState publish,
const gchar *publish_request,
SubscriptionStates *states)
{
- assert_subscription_states (contact, states);
- g_main_loop_quit (states->loop);
+ g_assert_cmpint (tp_contact_get_subscribe_state (contact), ==, subscribe);
+ g_assert_cmpint (tp_contact_get_publish_state (contact), ==, publish);
+ g_assert_cmpstr (tp_contact_get_publish_request (contact), ==,
+ publish_request);
+
+ states->signal_received = TRUE;
+ states->subscribe = subscribe;
+ states->publish = publish;
+ g_clear_pointer (&states->publish_request, g_free);
+ states->publish_request = g_strdup (publish_request);
}
static void
@@ -1589,8 +1587,8 @@ test_subscription_states (Fixture *f,
TpContact *alice;
TpTestsContactListManager *manager;
GQuark features[] = { TP_CONTACT_FEATURE_SUBSCRIPTION_STATES, 0 };
- SubscriptionStates states = { TP_SUBSCRIPTION_STATE_NO,
- TP_SUBSCRIPTION_STATE_NO, "", f->result.loop };
+ SubscriptionStates states = { FALSE, TP_SUBSCRIPTION_STATE_NO,
+ TP_SUBSCRIPTION_STATE_NO, NULL };
manager = tp_tests_contacts_connection_get_contact_list_manager (
f->service_conn);
@@ -1604,7 +1602,12 @@ test_subscription_states (Fixture *f,
g_main_loop_run (f->result.loop);
g_assert_no_error (f->result.error);
- assert_subscription_states (alice, &states);
+ g_assert_cmpint (tp_contact_get_subscribe_state (alice), ==,
+ TP_SUBSCRIPTION_STATE_NO);
+ g_assert_cmpint (tp_contact_get_publish_state (alice), ==,
+ TP_SUBSCRIPTION_STATE_NO);
+ g_assert_cmpstr (tp_contact_get_publish_request (alice), ==,
+ "");
reset_result (&f->result);
@@ -1613,24 +1616,56 @@ test_subscription_states (Fixture *f,
/* Request subscription */
tp_tests_contact_list_manager_request_subscription (manager, 1, &alice_handle, "");
- states.subscribe = TP_SUBSCRIPTION_STATE_ASK;
- g_main_loop_run (states.loop);
+
+ while (!states.signal_received)
+ g_main_context_iteration (NULL, TRUE);
+
+ g_assert_cmpint (states.subscribe, ==, TP_SUBSCRIPTION_STATE_ASK);
+ g_assert_cmpint (states.publish, ==, TP_SUBSCRIPTION_STATE_NO);
+ g_assert_cmpstr (states.publish_request, ==, "");
+ g_clear_pointer (&states.publish_request, g_free);
+ states.signal_received = FALSE;
/* Request again must re-emit the signal. Saying please this time will make
* the request accepted and will ask for publish. */
tp_tests_contact_list_manager_request_subscription (manager, 1, &alice_handle, "please");
- g_main_loop_run (states.loop);
- states.subscribe = TP_SUBSCRIPTION_STATE_YES;
- states.publish = TP_SUBSCRIPTION_STATE_ASK;
- states.publish_request = "automatic publish request";
- g_main_loop_run (states.loop);
+
+ while (!states.signal_received)
+ g_main_context_iteration (NULL, TRUE);
+
+ if (states.subscribe != TP_SUBSCRIPTION_STATE_YES)
+ {
+ /* we might receive this repeated signal in the same main loop
+ * iteration as the YES/ASK/"automatic publish request" one below,
+ * in which case it isn't visible to this regression test,
+ * or we might receive it in its own main loop iteration */
+ g_assert_cmpint (states.subscribe, ==, TP_SUBSCRIPTION_STATE_ASK);
+ g_assert_cmpint (states.publish, ==, TP_SUBSCRIPTION_STATE_NO);
+ g_assert_cmpstr (states.publish_request, ==, "");
+ g_clear_pointer (&states.publish_request, g_free);
+ states.signal_received = FALSE;
+
+ while (!states.signal_received)
+ g_main_context_iteration (NULL, TRUE);
+ }
+
+ g_assert_cmpint (states.subscribe, ==, TP_SUBSCRIPTION_STATE_YES);
+ g_assert_cmpint (states.publish, ==, TP_SUBSCRIPTION_STATE_ASK);
+ g_assert_cmpstr (states.publish_request, ==, "automatic publish request");
+ g_clear_pointer (&states.publish_request, g_free);
+ states.signal_received = FALSE;
/* Remove the contact */
tp_tests_contact_list_manager_remove (manager, 1, &alice_handle);
- states.subscribe = TP_SUBSCRIPTION_STATE_NO;
- states.publish = TP_SUBSCRIPTION_STATE_NO;
- states.publish_request = "";
- g_main_loop_run (states.loop);
+
+ while (!states.signal_received)
+ g_main_context_iteration (NULL, TRUE);
+
+ g_assert_cmpint (states.subscribe, ==, TP_SUBSCRIPTION_STATE_NO);
+ g_assert_cmpint (states.publish, ==, TP_SUBSCRIPTION_STATE_NO);
+ g_assert_cmpstr (states.publish_request, ==, "");
+ g_clear_pointer (&states.publish_request, g_free);
+ states.signal_received = FALSE;
g_object_unref (alice);
}
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-telepathy/telepathy-glib-1.git
More information about the Pkg-telepathy-commits
mailing list