diff options
author | Simon McVittie <simon.mcvittie@collabora.co.uk> | 2014-03-12 08:49:41 +0000 |
---|---|---|
committer | Simon McVittie <simon.mcvittie@collabora.co.uk> | 2014-03-13 14:25:14 +0000 |
commit | 0a8b1c9170c03f35562606acf32f11fabb23b96f (patch) | |
tree | 209ca637367ce97671615135efa588625fe1521b | |
parent | b6bf79f143f1b7ec98f03c3fd20d8eb269dc71d8 (diff) |
call-cancellation, disconnection tests: don't use TpDBusDaemon as proxy
TpDBusDaemon is rather special: in particular, it can't be invalidated
implicitly by the peer disconnecting, because there is no peer.
At the moment we fake it by forcing the DBusGProxy to be disposed,
but that's an implementation detail; it would be better for the peer
to actually disconnect.
While we're changing all these lines anyway, make a step towards
using GTest, by grouping some of the miscellaneous state in a
fixture.
-rw-r--r-- | tests/dbus/call-cancellation.c | 264 | ||||
-rw-r--r-- | tests/dbus/disconnection.c | 239 |
2 files changed, 273 insertions, 230 deletions
diff --git a/tests/dbus/call-cancellation.c b/tests/dbus/call-cancellation.c index b54223d21..fca97d58a 100644 --- a/tests/dbus/call-cancellation.c +++ b/tests/dbus/call-cancellation.c @@ -10,6 +10,7 @@ #include <telepathy-glib/util.h> #include "tests/lib/myassert.h" +#include "tests/lib/simple-channel-dispatcher.h" #include "tests/lib/stub-object.h" #include "tests/lib/util.h" @@ -18,18 +19,6 @@ /* state tracking */ static GMainLoop *mainloop; -static TpDBusDaemon *a; -static TpDBusDaemon *b; -static TpDBusDaemon *c; -static TpDBusDaemon *d; -static TpDBusDaemon *e; -static TpDBusDaemon *f; -static TpDBusDaemon *g; -static TpDBusDaemon *h; -static TpDBusDaemon *i; -static TpDBusDaemon *j; -static TpDBusDaemon *k; -static TpDBusDaemon *z; static TpIntset *method_ok; static TpIntset *method_error; static TpIntset *freed_user_data; @@ -51,9 +40,17 @@ enum { TEST_J, TEST_K, TEST_Z = 25, - N_DAEMONS + N_PROXIES }; +typedef struct { + TpDBusDaemon *dbus_daemon; + TpProxy *proxies[N_PROXIES]; + GObject *cd_service; +} Fixture; + +static Fixture *f; + static void destroy_user_data (gpointer user_data) { @@ -79,30 +76,30 @@ k_stub_destroyed (gpointer data, } static void -listed_names (TpDBusDaemon *proxy, - const gchar **names, - const GError *error, - gpointer user_data, - GObject *weak_object) +method_cb (TpProxy *proxy, + GHashTable *props, + const GError *error, + gpointer user_data, + GObject *weak_object) { guint which = GPOINTER_TO_UINT (user_data); - TpDBusDaemon *want_proxy = NULL; + TpProxy *want_proxy = NULL; GObject *want_object = NULL; if (error == NULL) { - g_message ("ListNames() succeeded (first name: %s), according to " - "user_data this was on proxy #%d '%c'", *names, which, 'a' + which); + g_message ("GetAll() succeeded, according to " + "user_data this was on proxy #%d '%c'", which, 'a' + which); tp_intset_add (method_ok, which); + want_proxy = f->proxies[which]; + switch (which) { case TEST_A: - want_proxy = a; - want_object = (GObject *) z; + want_object = (GObject *) f->proxies[TEST_Z]; break; case TEST_C: - want_proxy = c; want_object = NULL; break; case TEST_D: @@ -114,8 +111,7 @@ listed_names (TpDBusDaemon *proxy, want_object = (GObject *) copy_of_g; break; case TEST_Z: - want_proxy = z; - want_object = (GObject *) a; + want_object = (GObject *) f->proxies[TEST_A]; break; default: MYASSERT (FALSE, ": %c (%p) method call succeeded, which shouldn't " @@ -125,20 +121,19 @@ listed_names (TpDBusDaemon *proxy, } else { - g_message ("ListNames() failed (%s), according to " - "user_data this was on proxy #%d '%c'", error->message, + g_message ("GetAll() failed, according to " + "user_data this was on proxy #%d '%c'", which, 'a' + which); tp_intset_add (method_error, which); + want_proxy = f->proxies[which]; + want_object = NULL; + switch (which) { case TEST_C: - want_proxy = c; - want_object = NULL; break; case TEST_F: - want_proxy = f; - want_object = NULL; break; default: MYASSERT (FALSE, ": %c (%p) method call failed, which shouldn't " @@ -156,66 +151,90 @@ listed_names (TpDBusDaemon *proxy, } static void -noc (TpDBusDaemon *proxy, - const gchar *name, - const gchar *old, - const gchar *new, +signal_cb (TpProxy *proxy, + const gchar *iface, + GHashTable *changed, + const gchar **invalidated, gpointer user_data, GObject *weak_object) { /* do nothing */ } +static void +setup (void) +{ + f->dbus_daemon = tp_tests_dbus_daemon_dup_or_die (); + + /* Any random object with an interface: what matters is that it can + * accept a method call and emit a signal. We use the Properties + * interface here. */ + f->cd_service = tp_tests_object_new_static_class ( + TP_TESTS_TYPE_SIMPLE_CHANNEL_DISPATCHER, + NULL); + tp_dbus_daemon_register_object (f->dbus_daemon, "/", f->cd_service); +} + +static void +teardown (void) +{ + tp_tests_assert_last_unref (&f->cd_service); + tp_tests_assert_last_unref (&f->dbus_daemon); +} + +static TpProxy * +new_proxy (void) +{ + return tp_tests_object_new_static_class (TP_TYPE_PROXY, + "dbus-daemon", f->dbus_daemon, + "bus-name", tp_dbus_daemon_get_unique_name (f->dbus_daemon), + "object-path", "/", + NULL); +} + int main (int argc, char **argv) { + Fixture fixture = { NULL }; GObject *b_stub, *i_stub, *j_stub, *k_stub; GError err = { TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "Because I said so" }; TpProxyPendingCall *pc; gpointer tmp_obj; + guint i; tp_tests_abort_after (10); tp_debug_set_flags ("all"); - freed_user_data = tp_intset_sized_new (N_DAEMONS); - method_ok = tp_intset_sized_new (N_DAEMONS); - method_error = tp_intset_sized_new (N_DAEMONS); + freed_user_data = tp_intset_sized_new (N_PROXIES); + method_ok = tp_intset_sized_new (N_PROXIES); + method_error = tp_intset_sized_new (N_PROXIES); mainloop = g_main_loop_new (NULL, FALSE); - /* We use TpDBusDaemon because it's a convenient concrete subclass of - * TpProxy. */ + /* it's on the stack, but it's valid until we leave main(), which will + * do for now... one day this test should use GTest, but this might + * not be that day */ + f = &fixture; + + setup (); + g_message ("Creating proxies"); - a = tp_tests_dbus_daemon_dup_or_die (); - g_message ("a=%p", a); - b = tp_dbus_daemon_new (tp_proxy_get_dbus_connection (a)); - g_message ("b=%p", b); - c = tp_dbus_daemon_new (tp_proxy_get_dbus_connection (a)); - g_message ("c=%p", c); - d = tp_dbus_daemon_new (tp_proxy_get_dbus_connection (a)); - g_message ("d=%p", d); - e = tp_dbus_daemon_new (tp_proxy_get_dbus_connection (a)); - g_message ("e=%p", e); - f = tp_dbus_daemon_new (tp_proxy_get_dbus_connection (a)); - g_message ("f=%p", f); - g = tp_dbus_daemon_new (tp_proxy_get_dbus_connection (a)); - g_message ("g=%p", g); - h = tp_dbus_daemon_new (tp_proxy_get_dbus_connection (a)); - g_message ("h=%p", h); - i = tp_dbus_daemon_new (tp_proxy_get_dbus_connection (a)); - g_message ("i=%p", i); - j = tp_dbus_daemon_new (tp_proxy_get_dbus_connection (a)); - g_message ("j=%p", j); - k = tp_dbus_daemon_new (tp_proxy_get_dbus_connection (a)); - g_message ("k=%p", k); - z = tp_dbus_daemon_new (tp_proxy_get_dbus_connection (a)); - g_message ("z=%p", z); + + for (i = TEST_A; i <= TEST_K; i++) + { + f->proxies[i] = new_proxy (); + g_message ("%c=%p", 'a' + i, f->proxies[i]); + } + + f->proxies[TEST_Z] = new_proxy (); + g_message ("z=%p", f->proxies[TEST_Z]); /* a survives */ g_message ("Starting call on a"); - tp_cli_dbus_daemon_call_list_names (a, -1, listed_names, PTR (TEST_A), - destroy_user_data, (GObject *) z); + tp_cli_dbus_properties_call_get_all (f->proxies[TEST_A], -1, + TP_IFACE_CHANNEL_DISPATCHER, method_cb, PTR (TEST_A), + destroy_user_data, (GObject *) f->proxies[TEST_Z]); MYASSERT (!tp_intset_is_member (freed_user_data, TEST_A), ""); MYASSERT (!tp_intset_is_member (method_ok, TEST_A), ""); MYASSERT (!tp_intset_is_member (method_error, TEST_A), ""); @@ -225,21 +244,23 @@ main (int argc, b_stub = tp_tests_object_new_static_class (tp_tests_stub_object_get_type (), NULL); g_message ("Starting call on b"); - tp_cli_dbus_daemon_call_list_names (b, -1, listed_names, PTR (TEST_B), + tp_cli_dbus_properties_call_get_all (f->proxies[TEST_B], -1, + TP_IFACE_CHANNEL_DISPATCHER, method_cb, PTR (TEST_B), destroy_user_data, b_stub); MYASSERT (!tp_intset_is_member (freed_user_data, TEST_B), ""); - g_object_unref (b_stub); + tp_tests_assert_last_unref (&b_stub); MYASSERT (!tp_intset_is_member (method_ok, TEST_B), ""); MYASSERT (!tp_intset_is_member (method_error, TEST_B), ""); /* c is explicitly invalidated for an application-specific reason, * but its call still proceeds */ g_message ("Starting call on c"); - tp_cli_dbus_daemon_call_list_names (c, -1, listed_names, PTR (TEST_C), + tp_cli_dbus_properties_call_get_all (f->proxies[TEST_C], -1, + TP_IFACE_CHANNEL_DISPATCHER, method_cb, PTR (TEST_C), destroy_user_data, NULL); MYASSERT (!tp_intset_is_member (freed_user_data, TEST_C), ""); g_message ("Forcibly invalidating c"); - tp_proxy_invalidate ((TpProxy *) c, &err); + tp_proxy_invalidate (f->proxies[TEST_C], &err); MYASSERT (!tp_intset_is_member (freed_user_data, TEST_C), ""); MYASSERT (!tp_intset_is_member (method_ok, TEST_C), ""); MYASSERT (!tp_intset_is_member (method_error, TEST_C), ""); @@ -247,14 +268,14 @@ main (int argc, /* d gets unreferenced, but survives long enough for the call to complete * successfully later, because the pending call holds a reference */ g_message ("Starting call on d"); - tp_cli_dbus_daemon_call_list_names (d, -1, listed_names, PTR (TEST_D), + tp_cli_dbus_properties_call_get_all (f->proxies[TEST_D], -1, + TP_IFACE_CHANNEL_DISPATCHER, method_cb, PTR (TEST_D), destroy_user_data, NULL); MYASSERT (!tp_intset_is_member (freed_user_data, TEST_D), ""); g_message ("Unreferencing d"); - copy_of_d = d; + copy_of_d = f->proxies[TEST_D]; g_object_add_weak_pointer (copy_of_d, ©_of_d); - g_object_unref (d); - d = NULL; + g_clear_object (&f->proxies[TEST_D]); MYASSERT (copy_of_d != NULL, ""); MYASSERT (!tp_intset_is_member (freed_user_data, TEST_D), ""); MYASSERT (!tp_intset_is_member (method_ok, TEST_D), ""); @@ -262,7 +283,8 @@ main (int argc, /* e gets its method call cancelled explicitly */ g_message ("Starting call on e"); - pc = tp_cli_dbus_daemon_call_list_names (e, -1, listed_names, PTR (TEST_E), + pc = tp_cli_dbus_properties_call_get_all (f->proxies[TEST_E], -1, + TP_IFACE_CHANNEL_DISPATCHER, method_cb, PTR (TEST_E), destroy_user_data, NULL); MYASSERT (!tp_intset_is_member (freed_user_data, TEST_E), ""); g_message ("Cancelling call on e"); @@ -276,12 +298,13 @@ main (int argc, * Note that this test case exploits implementation details of dbus-glib. * If it stops working after a dbus-glib upgrade, that's probably why. */ g_message ("Starting call on f"); - tp_cli_dbus_daemon_call_list_names (f, -1, listed_names, PTR (TEST_F), + tp_cli_dbus_properties_call_get_all (f->proxies[TEST_F], -1, + TP_IFACE_CHANNEL_DISPATCHER, method_cb, PTR (TEST_F), destroy_user_data, NULL); MYASSERT (!tp_intset_is_member (freed_user_data, TEST_F), ""); g_message ("Forcibly disposing f's DBusGProxy to simulate name owner loss"); - tmp_obj = tp_proxy_get_interface_by_id ((TpProxy *) f, - TP_IFACE_QUARK_DBUS_DAEMON, NULL); + tmp_obj = tp_proxy_get_interface_by_id (f->proxies[TEST_F], + TP_IFACE_QUARK_DBUS_PROPERTIES, NULL); MYASSERT (tmp_obj != NULL, ""); g_object_run_dispose (tmp_obj); /* the callback will be queued (to avoid reentrancy), so we don't get it @@ -296,14 +319,14 @@ main (int argc, * proxy. This is never necessary, but is an interesting corner case that * should be tested. */ g_message ("Starting call on g"); - tp_cli_dbus_daemon_call_list_names (g, -1, listed_names, PTR (TEST_G), - destroy_user_data, (GObject *) g); + tp_cli_dbus_properties_call_get_all (f->proxies[TEST_G], -1, + TP_IFACE_CHANNEL_DISPATCHER, method_cb, PTR (TEST_G), + destroy_user_data, (GObject *) f->proxies[TEST_G]); MYASSERT (!tp_intset_is_member (freed_user_data, TEST_G), ""); g_message ("Unreferencing g"); - copy_of_g = g; + copy_of_g = f->proxies[TEST_G]; g_object_add_weak_pointer (copy_of_g, ©_of_g); - g_object_unref (g); - g = NULL; + g_clear_object (&f->proxies[TEST_G]); MYASSERT (copy_of_g != NULL, ""); MYASSERT (!tp_intset_is_member (freed_user_data, TEST_G), ""); MYASSERT (!tp_intset_is_member (method_ok, TEST_G), ""); @@ -312,14 +335,14 @@ main (int argc, /* h gets unreferenced, *and* the call is cancelled (regression test for * fd.o #14576) */ g_message ("Starting call on h"); - pc = tp_cli_dbus_daemon_call_list_names (h, -1, listed_names, PTR (TEST_H), + pc = tp_cli_dbus_properties_call_get_all (f->proxies[TEST_H], -1, + TP_IFACE_CHANNEL_DISPATCHER, method_cb, PTR (TEST_H), destroy_user_data, NULL); MYASSERT (!tp_intset_is_member (freed_user_data, TEST_H), ""); g_message ("Unreferencing h"); - copy_of_h = h; + copy_of_h = f->proxies[TEST_H]; g_object_add_weak_pointer (copy_of_h, ©_of_h); - g_object_unref (h); - h = NULL; + g_clear_object (&f->proxies[TEST_H]); MYASSERT (copy_of_h != NULL, ""); MYASSERT (!tp_intset_is_member (freed_user_data, TEST_H), ""); MYASSERT (!tp_intset_is_member (method_ok, TEST_H), ""); @@ -336,24 +359,24 @@ main (int argc, * for the minimal regression test) */ i_stub = tp_tests_object_new_static_class (tp_tests_stub_object_get_type (), NULL); - tp_cli_dbus_daemon_connect_to_name_owner_changed (i, noc, PTR (TEST_I), - NULL, i_stub, NULL); + tp_cli_dbus_properties_connect_to_properties_changed (f->proxies[TEST_I], + signal_cb, PTR (TEST_I), NULL, i_stub, NULL); g_message ("Starting call on i"); - tp_cli_dbus_daemon_call_list_names (i, -1, listed_names, PTR (TEST_I), + tp_cli_dbus_properties_call_get_all (f->proxies[TEST_I], -1, + TP_IFACE_CHANNEL_DISPATCHER, method_cb, PTR (TEST_I), destroy_user_data, i_stub); MYASSERT (!tp_intset_is_member (freed_user_data, TEST_I), ""); - tp_cli_dbus_daemon_connect_to_name_owner_changed (i, noc, PTR (TEST_I), - NULL, i_stub, NULL); + tp_cli_dbus_properties_connect_to_properties_changed (f->proxies[TEST_I], + signal_cb, PTR (TEST_I), NULL, i_stub, NULL); g_message ("Unreferencing i"); - copy_of_i = i; + copy_of_i = f->proxies[TEST_I]; g_object_add_weak_pointer (copy_of_i, ©_of_i); - g_object_unref (i); - i = NULL; + g_clear_object (&f->proxies[TEST_I]); MYASSERT (copy_of_i != NULL, ""); MYASSERT (!tp_intset_is_member (freed_user_data, TEST_I), ""); MYASSERT (!tp_intset_is_member (method_ok, TEST_I), ""); MYASSERT (!tp_intset_is_member (method_error, TEST_I), ""); - g_object_unref (i_stub); + tp_tests_assert_last_unref (&i_stub); MYASSERT (!tp_intset_is_member (method_ok, TEST_I), ""); MYASSERT (!tp_intset_is_member (method_error, TEST_I), ""); @@ -363,7 +386,8 @@ main (int argc, NULL); g_object_weak_ref (j_stub, j_stub_destroyed, PTR (TEST_J)); g_message ("Starting call on j"); - pc = tp_cli_dbus_daemon_call_list_names (j, -1, listed_names, j_stub, + pc = tp_cli_dbus_properties_call_get_all (f->proxies[TEST_J], -1, + TP_IFACE_CHANNEL_DISPATCHER, method_cb, j_stub, g_object_unref, j_stub); MYASSERT (!tp_intset_is_member (freed_user_data, TEST_J), ""); g_message ("Cancelling call on j"); @@ -379,20 +403,22 @@ main (int argc, NULL); g_message ("Starting call on k"); g_object_weak_ref (k_stub, k_stub_destroyed, &pc); - tp_cli_dbus_daemon_call_list_names (k, -1, listed_names, PTR (TEST_K), + tp_cli_dbus_properties_call_get_all (f->proxies[TEST_K], -1, + TP_IFACE_CHANNEL_DISPATCHER, method_cb, PTR (TEST_K), destroy_user_data, k_stub); MYASSERT (!tp_intset_is_member (freed_user_data, TEST_K), ""); MYASSERT (!tp_intset_is_member (method_ok, TEST_K), ""); MYASSERT (!tp_intset_is_member (method_error, TEST_K), ""); - g_object_unref (k_stub); + tp_tests_assert_last_unref (&k_stub); MYASSERT (!tp_intset_is_member (method_ok, TEST_K), ""); MYASSERT (!tp_intset_is_member (method_error, TEST_K), ""); /* z survives too; we assume that method calls succeed in order, * so when z has had its reply, we can stop the main loop */ g_message ("Starting call on z"); - tp_cli_dbus_daemon_call_list_names (z, -1, listed_names, PTR (TEST_Z), - destroy_user_data, (GObject *) a); + tp_cli_dbus_properties_call_get_all (f->proxies[TEST_Z], -1, + TP_IFACE_CHANNEL_DISPATCHER, method_cb, PTR (TEST_Z), + destroy_user_data, (GObject *) f->proxies[TEST_A]); MYASSERT (!tp_intset_is_member (freed_user_data, TEST_Z), ""); MYASSERT (!tp_intset_is_member (method_ok, TEST_Z), ""); MYASSERT (!tp_intset_is_member (method_error, TEST_Z), ""); @@ -445,26 +471,18 @@ main (int argc, MYASSERT (!tp_intset_is_member (method_error, TEST_Z), ""); g_message ("Dereferencing remaining proxies"); - g_object_unref (a); - a = NULL; - g_object_unref (b); - b = NULL; - g_object_unref (c); - c = NULL; - MYASSERT (d == NULL, ""); - g_object_unref (e); - e = NULL; - g_object_unref (f); - f = NULL; - MYASSERT (g == NULL, ""); - MYASSERT (h == NULL, ""); - MYASSERT (i == NULL, ""); - g_object_unref (j); - j = NULL; - g_object_unref (k); - k = NULL; - g_object_unref (z); - z = NULL; + tp_tests_assert_last_unref (&f->proxies[TEST_A]); + tp_tests_assert_last_unref (&f->proxies[TEST_B]); + tp_tests_assert_last_unref (&f->proxies[TEST_C]); + g_assert (f->proxies[TEST_D] == NULL); + tp_tests_assert_last_unref (&f->proxies[TEST_E]); + tp_tests_assert_last_unref (&f->proxies[TEST_F]); + g_assert (f->proxies[TEST_G] == NULL); + g_assert (f->proxies[TEST_H] == NULL); + g_assert (f->proxies[TEST_I] == NULL); + tp_tests_assert_last_unref (&f->proxies[TEST_J]); + tp_tests_assert_last_unref (&f->proxies[TEST_K]); + tp_tests_assert_last_unref (&f->proxies[TEST_Z]); /* we should already have checked each of these at least once, but just to * make sure we have a systematic test that all user data is freed... */ @@ -485,5 +503,7 @@ main (int argc, tp_intset_destroy (method_ok); tp_intset_destroy (method_error); + teardown (); + return 0; } diff --git a/tests/dbus/disconnection.c b/tests/dbus/disconnection.c index d2efcfa76..243db0702 100644 --- a/tests/dbus/disconnection.c +++ b/tests/dbus/disconnection.c @@ -7,9 +7,11 @@ #include <telepathy-glib/interfaces.h> #include <telepathy-glib/intset.h> #include <telepathy-glib/proxy-subclass.h> /* for _invalidated etc. */ +#include <telepathy-glib/svc-generic.h> #include <telepathy-glib/util.h> #include "tests/lib/myassert.h" +#include "tests/lib/simple-channel-dispatcher.h" #include "tests/lib/stub-object.h" #include "tests/lib/util.h" @@ -18,15 +20,6 @@ /* state tracking */ static GMainLoop *mainloop; -static TpDBusDaemon *a; -static TpDBusDaemon *b; -static TpDBusDaemon *c; -static TpDBusDaemon *d; -static TpDBusDaemon *e; -static TpDBusDaemon *f; -static TpDBusDaemon *g; -static TpDBusDaemon *h; -static TpDBusDaemon *z; static TpIntset *caught_signal; static TpIntset *freed_user_data; @@ -40,9 +33,17 @@ enum { TEST_G, TEST_H, TEST_Z = 25, - N_DAEMONS + N_PROXIES }; +typedef struct { + TpDBusDaemon *dbus_daemon; + TpProxy *proxies[N_PROXIES]; + GObject *cd_service; +} Fixture; + +static Fixture *f; + static void h_stub_destroyed (gpointer data, GObject *stub) @@ -62,58 +63,44 @@ destroy_user_data (gpointer user_data) } static void -requested_name (TpDBusDaemon *proxy, - guint result, - const GError *error, - gpointer user_data, - GObject *weak_object) -{ - g_message ("RequestName raised %s", - (error == NULL ? "no error" : error->message)); - /* we're on a private bus, so certainly nobody else should own this name */ - g_assert_no_error ((GError *) error); - MYASSERT (result == DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER, ": %u", result); -} - -static void -dummy_noc (TpDBusDaemon *proxy, - const gchar *name, - const gchar *old, - const gchar *new, - gpointer user_data, - GObject *weak_object) +unwanted_signal_cb (TpProxy *proxy, + const gchar *iface, + GHashTable *changed, + const gchar **invalidated, + gpointer user_data, + GObject *weak_object) { - g_error ("dummy_noc called - a signal connection which should have " + g_error ("unwanted_signal_cb called - a signal connection which should have " "failed has succeeded. Args: proxy=%p user_data=%p", proxy, user_data); } static void -noc (TpDBusDaemon *proxy, - const gchar *name, - const gchar *old, - const gchar *new, - gpointer user_data, - GObject *weak_object) +signal_cb (TpProxy *proxy, + const gchar *iface, + GHashTable *changed, + const gchar **invalidated, + gpointer user_data, + GObject *weak_object) { guint which = GPOINTER_TO_UINT (user_data); - TpDBusDaemon *want_proxy = NULL; + TpProxy *want_proxy = NULL; GObject *want_object = NULL; - g_message ("Caught signal (%s: %s -> %s) with proxy #%d '%c' according to " - "user_data", name, old, new, which, 'a' + which); + g_message ("Caught signal with proxy #%d '%c' according to " + "user_data", which, 'a' + which); g_message ("Proxy is %p, weak object is %p", proxy, weak_object); tp_intset_add (caught_signal, which); + want_proxy = f->proxies[which]; + switch (which) { case TEST_A: - want_proxy = a; - want_object = (GObject *) z; + want_object = (GObject *) f->proxies[TEST_Z]; break; case TEST_Z: - want_proxy = z; - want_object = (GObject *) a; + want_object = (GObject *) f->proxies[TEST_A]; break; default: g_error ("%c (%p) got the signal, which shouldn't have happened", @@ -143,51 +130,82 @@ set_freed (gpointer user_data) *boolptr = TRUE; } +static void +setup (void) +{ + f->dbus_daemon = tp_tests_dbus_daemon_dup_or_die (); + + /* Any random object with an interface: what matters is that it can + * accept a method call and emit a signal. We use the Properties + * interface here. */ + f->cd_service = tp_tests_object_new_static_class ( + TP_TESTS_TYPE_SIMPLE_CHANNEL_DISPATCHER, + NULL); + tp_dbus_daemon_register_object (f->dbus_daemon, "/", f->cd_service); +} + +static void +teardown (void) +{ + tp_tests_assert_last_unref (&f->cd_service); + tp_tests_assert_last_unref (&f->dbus_daemon); +} + +static TpProxy * +new_proxy (void) +{ + return tp_tests_object_new_static_class (TP_TYPE_PROXY, + "dbus-daemon", f->dbus_daemon, + "bus-name", tp_dbus_daemon_get_unique_name (f->dbus_daemon), + "object-path", "/", + NULL); +} + int main (int argc, char **argv) { + Fixture fixture = { NULL }; GObject *stub; GError *error_out = NULL; GError err = { TP_ERROR, TP_ERROR_INVALID_ARGUMENT, "Because I said so" }; TpProxySignalConnection *sc; gpointer tmp_obj; gboolean freed = FALSE; + GHashTable *empty_asv; + int i; tp_tests_abort_after (10); tp_debug_set_flags ("all"); - freed_user_data = tp_intset_sized_new (N_DAEMONS); - caught_signal = tp_intset_sized_new (N_DAEMONS); + freed_user_data = tp_intset_sized_new (N_PROXIES); + caught_signal = tp_intset_sized_new (N_PROXIES); + + /* it's on the stack, but it's valid until we leave main(), which will + * do for now... one day this test should use GTest, but this might + * not be that day */ + f = &fixture; + + setup (); mainloop = g_main_loop_new (NULL, FALSE); - /* We use TpDBusDaemon because it's a convenient concrete subclass of - * TpProxy. */ g_message ("Creating proxies"); - a = tp_tests_dbus_daemon_dup_or_die (); - g_message ("a=%p", a); - b = tp_dbus_daemon_new (tp_proxy_get_dbus_connection (a)); - g_message ("b=%p", b); - c = tp_dbus_daemon_new (tp_proxy_get_dbus_connection (a)); - g_message ("c=%p", c); - d = tp_dbus_daemon_new (tp_proxy_get_dbus_connection (a)); - g_message ("d=%p", d); - e = tp_dbus_daemon_new (tp_proxy_get_dbus_connection (a)); - g_message ("e=%p", e); - f = tp_dbus_daemon_new (tp_proxy_get_dbus_connection (a)); - g_message ("f=%p", f); - g = tp_dbus_daemon_new (tp_proxy_get_dbus_connection (a)); - g_message ("g=%p", g); - h = tp_dbus_daemon_new (tp_proxy_get_dbus_connection (a)); - g_message ("h=%p", h); - z = tp_dbus_daemon_new (tp_proxy_get_dbus_connection (a)); - g_message ("z=%p", z); + + for (i = TEST_A; i <= TEST_H; i++) + { + f->proxies[i] = new_proxy (); + g_message ("%c=%p", 'a' + i, f->proxies[i]); + } + + f->proxies[TEST_Z] = new_proxy (); + g_message ("z=%p", f->proxies[TEST_Z]); /* a survives */ g_message ("Connecting signal to a"); - tp_cli_dbus_daemon_connect_to_name_owner_changed (a, noc, PTR (TEST_A), - destroy_user_data, (GObject *) z, &error_out); + tp_cli_dbus_properties_connect_to_properties_changed (f->proxies[TEST_A], + signal_cb, PTR (TEST_A), + destroy_user_data, (GObject *) f->proxies[TEST_Z], &error_out); g_assert_no_error (error_out); /* b gets its signal connection cancelled because stub is @@ -195,24 +213,27 @@ main (int argc, stub = tp_tests_object_new_static_class (tp_tests_stub_object_get_type (), NULL); g_message ("Connecting signal to b"); - tp_cli_dbus_daemon_connect_to_name_owner_changed (b, noc, PTR (TEST_B), + tp_cli_dbus_properties_connect_to_properties_changed (f->proxies[TEST_B], + signal_cb, PTR (TEST_B), destroy_user_data, stub, &error_out); g_assert_no_error (error_out); MYASSERT (!tp_intset_is_member (freed_user_data, TEST_B), ""); - g_object_unref (stub); + tp_tests_assert_last_unref (&stub); /* c gets its signal connection cancelled because it's explicitly * invalidated */ g_message ("Connecting signal to c"); - tp_cli_dbus_daemon_connect_to_name_owner_changed (c, noc, PTR (TEST_C), + tp_cli_dbus_properties_connect_to_properties_changed (f->proxies[TEST_C], + signal_cb, PTR (TEST_C), destroy_user_data, NULL, &error_out); g_assert_no_error (error_out); MYASSERT (!tp_intset_is_member (freed_user_data, TEST_C), ""); g_message ("Forcibly invalidating c"); - tp_proxy_invalidate ((TpProxy *) c, &err); + tp_proxy_invalidate ((TpProxy *) f->proxies[TEST_C], &err); /* assert that connecting to a signal on an invalid proxy fails */ freed = FALSE; - tp_cli_dbus_daemon_connect_to_name_owner_changed (c, dummy_noc, &freed, + tp_cli_dbus_properties_connect_to_properties_changed (f->proxies[TEST_C], + unwanted_signal_cb, &freed, set_freed, NULL, &error_out); MYASSERT (freed, ""); MYASSERT (error_out != NULL, ""); @@ -226,20 +247,18 @@ main (int argc, /* d gets its signal connection cancelled because it's * implicitly invalidated by being destroyed */ g_message ("Connecting signal to d"); - tp_cli_dbus_daemon_connect_to_name_owner_changed (d, noc, PTR (TEST_D), + tp_cli_dbus_properties_connect_to_properties_changed (f->proxies[TEST_D], + signal_cb, PTR (TEST_D), destroy_user_data, NULL, &error_out); g_assert_no_error (error_out); MYASSERT (!tp_intset_is_member (freed_user_data, TEST_D), ""); g_message ("Destroying d"); - tmp_obj = d; - g_object_add_weak_pointer (tmp_obj, &tmp_obj); - g_object_unref (d); - MYASSERT (tmp_obj == NULL, ""); - d = NULL; + tp_tests_assert_last_unref (&f->proxies[TEST_D]); /* e gets its signal connection cancelled explicitly */ g_message ("Connecting signal to e"); - sc = tp_cli_dbus_daemon_connect_to_name_owner_changed (e, noc, PTR (TEST_E), + sc = tp_cli_dbus_properties_connect_to_properties_changed ( + f->proxies[TEST_E], signal_cb, PTR (TEST_E), destroy_user_data, NULL, &error_out); g_assert_no_error (error_out); MYASSERT (!tp_intset_is_member (freed_user_data, TEST_E), ""); @@ -252,19 +271,20 @@ main (int argc, * Note that this test case exploits implementation details of dbus-glib. * If it stops working after a dbus-glib upgrade, that's probably why. */ g_message ("Connecting signal to f"); - tp_cli_dbus_daemon_connect_to_name_owner_changed (f, noc, PTR (TEST_F), + tp_cli_dbus_properties_connect_to_properties_changed (f->proxies[TEST_F], + signal_cb, PTR (TEST_F), destroy_user_data, NULL, &error_out); g_assert_no_error (error_out); MYASSERT (!tp_intset_is_member (freed_user_data, TEST_F), ""); g_message ("Forcibly disposing f's DBusGProxy to simulate name owner loss"); - tmp_obj = tp_proxy_get_interface_by_id ((TpProxy *) f, - TP_IFACE_QUARK_DBUS_DAEMON, NULL); + tmp_obj = tp_proxy_get_interface_by_id (f->proxies[TEST_F], + TP_IFACE_QUARK_DBUS_PROPERTIES, NULL); MYASSERT (tmp_obj != NULL, ""); g_object_run_dispose (tmp_obj); /* assert that connecting to a signal on an invalid proxy fails */ freed = FALSE; - tp_cli_dbus_daemon_connect_to_name_owner_changed (f, dummy_noc, &freed, - set_freed, NULL, &error_out); + tp_cli_dbus_properties_connect_to_properties_changed (f->proxies[TEST_F], + unwanted_signal_cb, &freed, set_freed, NULL, &error_out); MYASSERT (freed, ""); MYASSERT (error_out != NULL, ""); MYASSERT (error_out->code == DBUS_GERROR_NAME_HAS_NO_OWNER, ""); @@ -276,16 +296,13 @@ main (int argc, * connection weakly references the proxy. This is never necessary, but is * an interesting corner case that should be tested. */ g_message ("Connecting signal to g"); - tp_cli_dbus_daemon_connect_to_name_owner_changed (g, noc, PTR (TEST_G), - destroy_user_data, (GObject *) g, &error_out); + tp_cli_dbus_properties_connect_to_properties_changed (f->proxies[TEST_G], + signal_cb, PTR (TEST_G), + destroy_user_data, (GObject *) f->proxies[TEST_G], &error_out); g_assert_no_error (error_out); MYASSERT (!tp_intset_is_member (freed_user_data, TEST_G), ""); g_message ("Destroying g"); - tmp_obj = g; - g_object_add_weak_pointer (tmp_obj, &tmp_obj); - g_object_unref (g); - MYASSERT (tmp_obj == NULL, ""); - g = NULL; + tp_tests_assert_last_unref (&f->proxies[TEST_G]); /* h gets its signal connection cancelled because its weak object is * destroyed, meaning there are simultaneously two reasons for it to become @@ -294,24 +311,27 @@ main (int argc, NULL); g_object_weak_ref (stub, h_stub_destroyed, &sc); g_message ("Connecting signal to h"); - tp_cli_dbus_daemon_connect_to_name_owner_changed (h, noc, PTR (TEST_H), + tp_cli_dbus_properties_connect_to_properties_changed (f->proxies[TEST_H], + signal_cb, PTR (TEST_H), destroy_user_data, stub, &error_out); g_assert_no_error (error_out); MYASSERT (!tp_intset_is_member (freed_user_data, TEST_H), ""); - g_object_unref (stub); + tp_tests_assert_last_unref (&stub); /* z survives; we assume that the signals are delivered in either * forward or reverse order, so if both a and z have had their signal, we * can stop the main loop */ g_message ("Connecting signal to z"); - tp_cli_dbus_daemon_connect_to_name_owner_changed (z, noc, PTR (TEST_Z), - destroy_user_data, (GObject *) a, &error_out); + tp_cli_dbus_properties_connect_to_properties_changed (f->proxies[TEST_Z], + signal_cb, PTR (TEST_Z), + destroy_user_data, (GObject *) f->proxies[TEST_A], &error_out); g_assert_no_error (error_out); - /* make sure a NameOwnerChanged signal occurs */ - g_message ("Requesting name"); - tp_cli_dbus_daemon_call_request_name (a, -1, "com.example.NameTest", - 0, requested_name, NULL, NULL, NULL); + g_message ("Emitting signal"); + empty_asv = tp_asv_new (NULL, NULL); + tp_svc_dbus_properties_emit_properties_changed (f->cd_service, + TP_IFACE_CHANNEL_DISPATCHER, empty_asv, NULL); + g_hash_table_unref (empty_asv); g_message ("Running main loop"); g_main_loop_run (mainloop); @@ -333,14 +353,15 @@ main (int argc, MYASSERT (!tp_intset_is_member (freed_user_data, TEST_Z), ""); g_message ("Dereferencing remaining proxies"); - g_object_unref (a); - g_object_unref (b); - g_object_unref (c); - MYASSERT (d == NULL, ""); - g_object_unref (e); - g_object_unref (f); - MYASSERT (g == NULL, ""); - g_object_unref (z); + tp_tests_assert_last_unref (&f->proxies[TEST_A]); + tp_tests_assert_last_unref (&f->proxies[TEST_B]); + tp_tests_assert_last_unref (&f->proxies[TEST_C]); + g_assert (f->proxies[TEST_D] == NULL); + tp_tests_assert_last_unref (&f->proxies[TEST_E]); + tp_tests_assert_last_unref (&f->proxies[TEST_F]); + g_assert (f->proxies[TEST_G] == NULL); + tp_tests_assert_last_unref (&f->proxies[TEST_H]); + tp_tests_assert_last_unref (&f->proxies[TEST_Z]); /* we should already have checked each of these at least once, but just to * make sure we have a systematic test that all user data is freed... */ @@ -357,5 +378,7 @@ main (int argc, tp_intset_destroy (freed_user_data); tp_intset_destroy (caught_signal); + teardown (); + return 0; } |