[folks] TpTestBackend: Make sure DBus trafic is done in tear_down
- From: Xavier Claessens <xclaesse src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [folks] TpTestBackend: Make sure DBus trafic is done in tear_down
- Date: Wed, 28 Mar 2012 12:17:10 +0000 (UTC)
commit ff5f319a5901e51567e9ec13db5455de7b7f53aa
Author: Xavier Claessens <xavier claessens collabora co uk>
Date: Tue Mar 27 12:49:32 2012 +0200
TpTestBackend: Make sure DBus trafic is done in tear_down
tests/lib/telepathy/contactlist/Makefile.am | 2 +
tests/lib/telepathy/contactlist/backend.c | 8 +
tests/lib/telepathy/contactlist/util.c | 473 +++++++++++++++++++++++++++
tests/lib/telepathy/contactlist/util.h | 76 +++++
4 files changed, 559 insertions(+), 0 deletions(-)
---
diff --git a/tests/lib/telepathy/contactlist/Makefile.am b/tests/lib/telepathy/contactlist/Makefile.am
index 9db3ea7..d3e1e2e 100644
--- a/tests/lib/telepathy/contactlist/Makefile.am
+++ b/tests/lib/telepathy/contactlist/Makefile.am
@@ -30,6 +30,8 @@ libtp_test_contactlist_la_SOURCES = \
contact-list.h \
contact-list-manager.c \
contact-list-manager.h \
+ util.c \
+ util.h \
$(NULL)
libtp_test_contactlist_la_CFLAGS = \
diff --git a/tests/lib/telepathy/contactlist/backend.c b/tests/lib/telepathy/contactlist/backend.c
index f7d6db1..ec257c3 100644
--- a/tests/lib/telepathy/contactlist/backend.c
+++ b/tests/lib/telepathy/contactlist/backend.c
@@ -28,11 +28,13 @@
#include "account-manager.h"
#include "conn.h"
#include "contact-list.h"
+#include "util.h"
#include "backend.h"
struct _TpTestBackendPrivate
{
+ TpAccountManager *am_proxy;
TpDBusDaemon *daemon;
TpTestAccountManager *account_manager;
GList *accounts;
@@ -201,6 +203,8 @@ tp_test_backend_set_up (TpTestBackend *self)
priv->account_manager = tp_test_account_manager_new ();
tp_dbus_daemon_register_object (priv->daemon, TP_ACCOUNT_MANAGER_OBJECT_PATH,
priv->account_manager);
+
+ priv->am_proxy = tp_account_manager_dup ();
}
/**
@@ -313,6 +317,10 @@ tp_test_backend_tear_down (TpTestBackend *self)
TpTestBackendPrivate *priv = self->priv;
GError *error = NULL;
+ /* Make sure all dbus trafic is done */
+ tp_tests_proxy_run_until_dbus_queue_processed (priv->am_proxy);
+ g_clear_object (&priv->am_proxy);
+
tp_dbus_daemon_unregister_object (priv->daemon, priv->account_manager);
tp_clear_object (&priv->account_manager);
diff --git a/tests/lib/telepathy/contactlist/util.c b/tests/lib/telepathy/contactlist/util.c
new file mode 100644
index 0000000..b14fa42
--- /dev/null
+++ b/tests/lib/telepathy/contactlist/util.c
@@ -0,0 +1,473 @@
+/* Simple utility code used by the regression tests.
+ *
+ * Copyright  2008-2010 Collabora Ltd. <http://www.collabora.co.uk/>
+ * Copyright  2008 Nokia Corporation
+ *
+ * Copying and distribution of this file, with or without modification,
+ * are permitted in any medium without royalty provided the copyright
+ * notice and this notice are preserved.
+ */
+
+#include "config.h"
+
+#include "util.h"
+
+#include <telepathy-glib/connection.h>
+
+#include <glib/gstdio.h>
+#include <string.h>
+
+#ifdef G_OS_UNIX
+# include <unistd.h> /* for alarm() */
+#endif
+
+#ifdef HAVE_GIO_UNIX
+#include <gio/gunixsocketaddress.h>
+#include <gio/gunixconnection.h>
+#endif
+
+void
+tp_tests_proxy_run_until_prepared (gpointer proxy,
+ const GQuark *features)
+{
+ GError *error = NULL;
+
+ tp_tests_proxy_run_until_prepared_or_failed (proxy, features, &error);
+ g_assert_no_error (error);
+}
+
+/* A GAsyncReadyCallback whose user_data is a GAsyncResult **. It writes a
+ * reference to the result into that pointer. */
+void
+tp_tests_result_ready_cb (GObject *object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ GAsyncResult **result = user_data;
+
+ *result = g_object_ref (res);
+}
+
+/* Run until *result contains a result. Intended to be used with a pending
+ * async call that uses tp_tests_result_ready_cb. */
+void
+tp_tests_run_until_result (GAsyncResult **result)
+{
+ /* not synchronous */
+ g_assert (*result == NULL);
+
+ while (*result == NULL)
+ g_main_context_iteration (NULL, TRUE);
+}
+
+gboolean
+tp_tests_proxy_run_until_prepared_or_failed (gpointer proxy,
+ const GQuark *features,
+ GError **error)
+{
+ GAsyncResult *result = NULL;
+ gboolean r;
+
+ tp_proxy_prepare_async (proxy, features, tp_tests_result_ready_cb, &result);
+
+ tp_tests_run_until_result (&result);
+
+ r = tp_proxy_prepare_finish (proxy, result, error);
+ g_object_unref (result);
+ return r;
+}
+
+TpDBusDaemon *
+tp_tests_dbus_daemon_dup_or_die (void)
+{
+ TpDBusDaemon *d = tp_dbus_daemon_dup (NULL);
+
+ /* In a shared library, this would be very bad (see fd.o #18832), but in a
+ * regression test that's going to be run under a temporary session bus,
+ * it's just what we want. */
+ if (d == NULL)
+ {
+ g_error ("Unable to connect to session bus");
+ }
+
+ return d;
+}
+
+static void
+introspect_cb (TpProxy *proxy G_GNUC_UNUSED,
+ const gchar *xml G_GNUC_UNUSED,
+ const GError *error G_GNUC_UNUSED,
+ gpointer user_data,
+ GObject *weak_object G_GNUC_UNUSED)
+{
+ g_main_loop_quit (user_data);
+}
+
+void
+tp_tests_proxy_run_until_dbus_queue_processed (gpointer proxy)
+{
+ GMainLoop *loop = g_main_loop_new (NULL, FALSE);
+
+ tp_cli_dbus_introspectable_call_introspect (proxy, -1, introspect_cb,
+ loop, NULL, NULL);
+ g_main_loop_run (loop);
+ g_main_loop_unref (loop);
+}
+
+typedef struct {
+ GMainLoop *loop;
+ TpHandle handle;
+} HandleRequestResult;
+
+static void
+handles_requested_cb (TpConnection *connection G_GNUC_UNUSED,
+ TpHandleType handle_type G_GNUC_UNUSED,
+ guint n_handles,
+ const TpHandle *handles,
+ const gchar * const *ids G_GNUC_UNUSED,
+ const GError *error,
+ gpointer user_data,
+ GObject *weak_object G_GNUC_UNUSED)
+{
+ HandleRequestResult *result = user_data;
+
+ g_assert_no_error ((GError *) error);
+ g_assert_cmpuint (n_handles, ==, 1);
+ result->handle = handles[0];
+}
+
+static void
+handle_request_result_finish (gpointer r)
+{
+ HandleRequestResult *result = r;
+
+ g_main_loop_quit (result->loop);
+}
+
+TpHandle
+tp_tests_connection_run_request_contact_handle (TpConnection *connection,
+ const gchar *id)
+{
+ HandleRequestResult result = { g_main_loop_new (NULL, FALSE), 0 };
+ const gchar * const ids[] = { id, NULL };
+
+ tp_connection_request_handles (connection, -1, TP_HANDLE_TYPE_CONTACT, ids,
+ handles_requested_cb, &result, handle_request_result_finish, NULL);
+ g_main_loop_run (result.loop);
+ g_main_loop_unref (result.loop);
+ return result.handle;
+}
+
+void
+_test_assert_empty_strv (const char *file,
+ int line,
+ gconstpointer strv)
+{
+ const gchar * const *strings = strv;
+
+ if (strv != NULL && strings[0] != NULL)
+ {
+ guint i;
+
+ g_message ("%s:%d: expected empty strv, but got:", file, line);
+
+ for (i = 0; strings[i] != NULL; i++)
+ {
+ g_message ("* \"%s\"", strings[i]);
+ }
+
+ g_error ("%s:%d: strv wasn't empty (see above for contents",
+ file, line);
+ }
+}
+
+void
+_tp_tests_assert_strv_equals (const char *file,
+ int line,
+ const char *expected_desc,
+ gconstpointer expected_strv,
+ const char *actual_desc,
+ gconstpointer actual_strv)
+{
+ const gchar * const *expected = expected_strv;
+ const gchar * const *actual = actual_strv;
+ guint i;
+
+ g_assert (expected != NULL);
+ g_assert (actual != NULL);
+
+ for (i = 0; expected[i] != NULL || actual[i] != NULL; i++)
+ {
+ if (expected[i] == NULL)
+ {
+ g_error ("%s:%d: assertion failed: (%s)[%u] == (%s)[%u]: "
+ "NULL == %s", file, line, expected_desc, i,
+ actual_desc, i, actual[i]);
+ }
+ else if (actual[i] == NULL)
+ {
+ g_error ("%s:%d: assertion failed: (%s)[%u] == (%s)[%u]: "
+ "%s == NULL", file, line, expected_desc, i,
+ actual_desc, i, expected[i]);
+ }
+ else if (tp_strdiff (expected[i], actual[i]))
+ {
+ g_error ("%s:%d: assertion failed: (%s)[%u] == (%s)[%u]: "
+ "%s == %s", file, line, expected_desc, i,
+ actual_desc, i, expected[i], actual[i]);
+ }
+ }
+}
+
+void
+tp_tests_create_conn (GType conn_type,
+ const gchar *account,
+ gboolean connect,
+ TpBaseConnection **service_conn,
+ TpConnection **client_conn)
+{
+ TpDBusDaemon *dbus;
+ gchar *name;
+ gchar *conn_path;
+ GError *error = NULL;
+
+ g_assert (service_conn != NULL);
+ g_assert (client_conn != NULL);
+
+ dbus = tp_tests_dbus_daemon_dup_or_die ();
+
+ *service_conn = tp_tests_object_new_static_class (
+ conn_type,
+ "account", account,
+ "protocol", "simple",
+ NULL);
+ g_assert (*service_conn != NULL);
+
+ g_assert (tp_base_connection_register (*service_conn, "simple",
+ &name, &conn_path, &error));
+ g_assert_no_error (error);
+
+ *client_conn = tp_connection_new (dbus, name, conn_path,
+ &error);
+ g_assert (*client_conn != NULL);
+ g_assert_no_error (error);
+
+ if (connect)
+ {
+ GQuark conn_features[] = { TP_CONNECTION_FEATURE_CONNECTED, 0 };
+
+ tp_cli_connection_call_connect (*client_conn, -1, NULL, NULL, NULL, NULL);
+ tp_tests_proxy_run_until_prepared (*client_conn, conn_features);
+ }
+
+ g_free (name);
+ g_free (conn_path);
+
+ g_object_unref (dbus);
+}
+
+void
+tp_tests_create_and_connect_conn (GType conn_type,
+ const gchar *account,
+ TpBaseConnection **service_conn,
+ TpConnection **client_conn)
+{
+ tp_tests_create_conn (conn_type, account, TRUE, service_conn, client_conn);
+}
+
+/* This object exists solely so that tests/tests.supp can ignore "leaked"
+ * classes. */
+gpointer
+tp_tests_object_new_static_class (GType type,
+ ...)
+{
+ va_list ap;
+ GObject *object;
+ const gchar *first_property;
+
+ va_start (ap, type);
+ first_property = va_arg (ap, const gchar *);
+ object = g_object_new_valist (type, first_property, ap);
+ va_end (ap);
+ return object;
+}
+
+static gboolean
+time_out (gpointer nil G_GNUC_UNUSED)
+{
+ g_error ("Timed out");
+ g_assert_not_reached ();
+ return FALSE;
+}
+
+void
+tp_tests_abort_after (guint sec)
+{
+ gboolean debugger = FALSE;
+ gchar *contents;
+
+ if (g_file_get_contents ("/proc/self/status", &contents, NULL, NULL))
+ {
+/* http://www.youtube.com/watch?v=SXmv8quf_xM */
+#define TRACER_T "\nTracerPid:\t"
+ gchar *line = strstr (contents, TRACER_T);
+
+ if (line != NULL)
+ {
+ gchar *value = line + strlen (TRACER_T);
+
+ if (value[0] != '0' || value[1] != '\n')
+ debugger = TRUE;
+ }
+
+ g_free (contents);
+ }
+
+ if (g_getenv ("TP_TESTS_NO_TIMEOUT") != NULL || debugger)
+ return;
+
+ g_timeout_add_seconds (sec, time_out, NULL);
+
+#ifdef G_OS_UNIX
+ /* On Unix, we can kill the process more reliably; this is a safety-catch
+ * in case it deadlocks or something, in which case the main loop won't be
+ * processed. The default handler for SIGALRM is process termination. */
+ alarm (sec + 2);
+#endif
+}
+
+void
+tp_tests_init (int *argc,
+ char ***argv)
+{
+ g_type_init ();
+ tp_tests_abort_after (10);
+ tp_debug_set_flags ("all");
+
+ g_test_init (argc, argv, NULL);
+}
+
+void
+_tp_destroy_socket_control_list (gpointer data)
+{
+ GArray *tab = data;
+ g_array_unref (tab);
+}
+
+GValue *
+_tp_create_local_socket (TpSocketAddressType address_type,
+ TpSocketAccessControl access_control,
+ GSocketService **service,
+ gchar **unix_address,
+ GError **error)
+{
+ gboolean success;
+ GSocketAddress *address, *effective_address;
+ GValue *address_gvalue;
+
+ g_assert (service != NULL);
+ g_assert (unix_address != NULL);
+
+ switch (access_control)
+ {
+ case TP_SOCKET_ACCESS_CONTROL_LOCALHOST:
+ case TP_SOCKET_ACCESS_CONTROL_CREDENTIALS:
+ case TP_SOCKET_ACCESS_CONTROL_PORT:
+ break;
+
+ default:
+ g_assert_not_reached ();
+ }
+
+ switch (address_type)
+ {
+#ifdef HAVE_GIO_UNIX
+ case TP_SOCKET_ADDRESS_TYPE_UNIX:
+ {
+ address = g_unix_socket_address_new (tmpnam (NULL));
+ break;
+ }
+#endif
+
+ case TP_SOCKET_ADDRESS_TYPE_IPV4:
+ case TP_SOCKET_ADDRESS_TYPE_IPV6:
+ {
+ GInetAddress *localhost;
+
+ localhost = g_inet_address_new_loopback (
+ address_type == TP_SOCKET_ADDRESS_TYPE_IPV4 ?
+ G_SOCKET_FAMILY_IPV4 : G_SOCKET_FAMILY_IPV6);
+ address = g_inet_socket_address_new (localhost, 0);
+
+ g_object_unref (localhost);
+ break;
+ }
+
+ default:
+ g_assert_not_reached ();
+ }
+
+ *service = g_socket_service_new ();
+
+ success = g_socket_listener_add_address (
+ G_SOCKET_LISTENER (*service),
+ address, G_SOCKET_TYPE_STREAM,
+ G_SOCKET_PROTOCOL_DEFAULT,
+ NULL, &effective_address, NULL);
+ g_assert (success);
+
+ switch (address_type)
+ {
+#ifdef HAVE_GIO_UNIX
+ case TP_SOCKET_ADDRESS_TYPE_UNIX:
+ *unix_address = g_strdup (g_unix_socket_address_get_path (
+ G_UNIX_SOCKET_ADDRESS (effective_address)));
+ address_gvalue = tp_g_value_slice_new_bytes (
+ g_unix_socket_address_get_path_len (
+ G_UNIX_SOCKET_ADDRESS (effective_address)),
+ g_unix_socket_address_get_path (
+ G_UNIX_SOCKET_ADDRESS (effective_address)));
+ break;
+#endif
+
+ case TP_SOCKET_ADDRESS_TYPE_IPV4:
+ case TP_SOCKET_ADDRESS_TYPE_IPV6:
+ *unix_address = NULL;
+
+ address_gvalue = tp_g_value_slice_new_take_boxed (
+ TP_STRUCT_TYPE_SOCKET_ADDRESS_IPV4,
+ dbus_g_type_specialized_construct (
+ TP_STRUCT_TYPE_SOCKET_ADDRESS_IPV4));
+
+ dbus_g_type_struct_set (address_gvalue,
+ 0, address_type == TP_SOCKET_ADDRESS_TYPE_IPV4 ?
+ "127.0.0.1" : "::1",
+ 1, g_inet_socket_address_get_port (
+ G_INET_SOCKET_ADDRESS (effective_address)),
+ G_MAXUINT);
+ break;
+
+ default:
+ g_assert_not_reached ();
+ }
+
+ g_object_unref (address);
+ g_object_unref (effective_address);
+ return address_gvalue;
+}
+
+void
+tp_tests_connection_assert_disconnect_succeeds (TpConnection *connection)
+{
+ GAsyncResult *result = NULL;
+ GError *error = NULL;
+ gboolean ok;
+
+ tp_connection_disconnect_async (connection, tp_tests_result_ready_cb,
+ &result);
+ tp_tests_run_until_result (&result);
+ ok = tp_connection_disconnect_finish (connection, result, &error);
+ g_assert_no_error (error);
+ g_assert (ok);
+ g_object_unref (result);
+}
diff --git a/tests/lib/telepathy/contactlist/util.h b/tests/lib/telepathy/contactlist/util.h
new file mode 100644
index 0000000..d0428ac
--- /dev/null
+++ b/tests/lib/telepathy/contactlist/util.h
@@ -0,0 +1,76 @@
+/* Simple utility code used by the regression tests.
+ *
+ * Copyright  2008-2010 Collabora Ltd. <http://www.collabora.co.uk/>
+ * Copyright  2008 Nokia Corporation
+ *
+ * Copying and distribution of this file, with or without modification,
+ * are permitted in any medium without royalty provided the copyright
+ * notice and this notice are preserved.
+ */
+
+#ifndef __TP_TESTS_LIB_UTIL_H__
+#define __TP_TESTS_LIB_UTIL_H__
+
+#include <telepathy-glib/telepathy-glib.h>
+#include <telepathy-glib/base-connection.h>
+
+TpDBusDaemon *tp_tests_dbus_daemon_dup_or_die (void);
+
+void tp_tests_proxy_run_until_dbus_queue_processed (gpointer proxy);
+
+TpHandle tp_tests_connection_run_request_contact_handle (
+ TpConnection *connection,
+ const gchar *id);
+
+void tp_tests_proxy_run_until_prepared (gpointer proxy,
+ const GQuark *features);
+gboolean tp_tests_proxy_run_until_prepared_or_failed (gpointer proxy,
+ const GQuark *features,
+ GError **error);
+
+#define test_assert_empty_strv(strv) \
+ _test_assert_empty_strv (__FILE__, __LINE__, strv)
+void _test_assert_empty_strv (const char *file, int line, gconstpointer strv);
+
+#define tp_tests_assert_strv_equals(actual, expected) \
+ _tp_tests_assert_strv_equals (__FILE__, __LINE__, \
+ #actual, actual, \
+ #expected, expected)
+void _tp_tests_assert_strv_equals (const char *file, int line,
+ const char *actual_desc, gconstpointer actual_strv,
+ const char *expected_desc, gconstpointer expected_strv);
+
+void tp_tests_create_conn (GType conn_type,
+ const gchar *account,
+ gboolean connect,
+ TpBaseConnection **service_conn,
+ TpConnection **client_conn);
+
+void tp_tests_create_and_connect_conn (GType conn_type,
+ const gchar *account,
+ TpBaseConnection **service_conn,
+ TpConnection **client_conn);
+
+gpointer tp_tests_object_new_static_class (GType type,
+ ...) G_GNUC_NULL_TERMINATED;
+
+void tp_tests_run_until_result (GAsyncResult **result);
+void tp_tests_result_ready_cb (GObject *object,
+ GAsyncResult *res, gpointer user_data);
+
+void tp_tests_abort_after (guint sec);
+
+void tp_tests_init (int *argc,
+ char ***argv);
+
+GValue *_tp_create_local_socket (TpSocketAddressType address_type,
+ TpSocketAccessControl access_control,
+ GSocketService **service,
+ gchar **unix_address,
+ GError **error);
+
+void _tp_destroy_socket_control_list (gpointer data);
+
+void tp_tests_connection_assert_disconnect_succeeds (TpConnection *connection);
+
+#endif /* #ifndef __TP_TESTS_LIB_UTIL_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]