[gnome-chess/chess-telepathy-networking-support-664946-rebase: 62/64] Add telepathy-dbus-tube offerer and accepter tests



commit 2a08ed2cc1e7b8f20f7061353b6b070d08fcb544
Author: Chandni Verma <chandniverma2112 gmail com>
Date:   Wed Dec 12 04:06:29 2012 +0530

    Add telepathy-dbus-tube offerer and accepter tests

 tests/Makefile.am |   13 ++-
 tests/accepter.c  |  265 ++++++++++++++++++++++++++++++++++++++++++
 tests/constants.h |    9 ++
 tests/offerer.c   |  332 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 616 insertions(+), 3 deletions(-)
---
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 0f3f4ff..1ff26a0 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -28,7 +28,9 @@ test_demo_gdbus_client_VALAFLAGS = \
 	--pkg gio-2.0
 
 networking_tests = \
-	test-fetch-contacts
+	test-fetch-contacts \
+	offerer \
+	accepter
 
 vala_tests = \
 	test-demo-gdbus-client \
@@ -43,10 +45,12 @@ noinst_PROGRAMS += \
 
 AM_CFLAGS += \
 	$(GEE_CFLAGS) \
-	$(TELEPATHY_CFLAGS)
+	$(TELEPATHY_CFLAGS) \
+	$(GIO_CFLAGS)
 LDADD += \
 	$(GEE_LIBS) \
-	$(TELEPATHY_LIBS)
+	$(TELEPATHY_LIBS) \
+	$(GIO_LIBS)
 endif #ENABLE_NETWORKING
 
 test_fetch_contacts_SOURCES = test-fetch-contacts.c
@@ -54,3 +58,6 @@ test_fetch_contacts_SOURCES = test-fetch-contacts.c
 test_demo_gdbus_server_SOURCES = test-demo-gdbus-server.vala
 test_demo_gdbus_client_SOURCES = test-demo-gdbus-client.vala
 
+offerer_SOURCES = offerer.c constants.h
+accepter_SOURCES = accepter.c constants.h
+
diff --git a/tests/accepter.c b/tests/accepter.c
new file mode 100644
index 0000000..54af9c4
--- /dev/null
+++ b/tests/accepter.c
@@ -0,0 +1,265 @@
+/* This is an improvised test on the accepter example available in TelepathyGLib
+ * demonstrating usage of multiple objects exported by offerer on DBusConnection 
+ * obtained from Tube. */
+
+#include <telepathy-glib/telepathy-glib.h>
+#include "constants.h"
+
+static GMainLoop *loop = NULL;
+
+static void
+dbus_connection_closed_cb (
+    GDBusConnection *connection,
+    gboolean remote_peer_vanished,
+    GError *error,
+    gpointer user_data)
+{
+  if (remote_peer_vanished)
+    g_debug ("remote peer disconnected: %s", error->message);
+  else if (error != NULL)
+    g_debug ("remote peer sent broken data: %s", error->message);
+  else
+    g_debug ("supposedly we closed the connection locally?!");
+
+  g_object_unref (connection);
+}
+
+static void
+lucky_number_cb (
+    GDBusConnection *connection,
+    const gchar *sender_name,
+    const gchar *object_path,
+    const gchar *interface_name,
+    const gchar *signal_name,
+    GVariant *parameters,
+    gpointer user_data)
+{
+  if (g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(u)")))
+    {
+      guint32 x;
+
+      g_variant_get (parameters, "(u)", &x);
+      g_debug ("My lucky number is: %u", x);
+    }
+  else
+    {
+      g_warning ("LuckyNumber's arguments were %s, not (u)",
+          g_variant_get_type_string (parameters));
+    }
+}
+
+static void
+add_cb (
+    GObject *source,
+    GAsyncResult *result,
+    gpointer user_data)
+{
+  GDBusConnection *conn = G_DBUS_CONNECTION (source);
+  GVariant *ret;
+  GError *error = NULL;
+
+  ret = g_dbus_connection_call_finish (conn, result, &error);
+
+  if (ret != NULL)
+    {
+      gint32 value;
+
+      g_variant_get (ret, "(i)", &value);
+      g_debug ("Adding my numbers together gave: %i", value);
+      g_variant_unref (ret);
+    }
+  else
+    {
+      g_warning ("Add() failed: %s", error->message);
+      g_clear_error (&error);
+    }
+}
+
+static void
+get_id_cb (
+    GObject *source,
+    GAsyncResult *result,
+    gpointer user_data)
+{
+  GDBusConnection *conn = G_DBUS_CONNECTION (source);
+  GVariant *ret;
+  GError *error = NULL;
+
+  ret = g_dbus_connection_call_finish (conn, result, &error);
+
+  if (ret != NULL)
+    {
+      const gchar* value;
+
+      g_variant_get (ret, "(s)", &value);
+      g_debug ("get_id () gave channel initiator's id as: %s", value);
+      g_variant_unref (ret);
+    }
+  else
+    {
+      g_warning ("get_id() failed: %s", error->message);
+      g_clear_error (&error);
+    }
+}
+
+static void
+tube_accepted (GObject *tube,
+    GAsyncResult *res,
+    gpointer user_data)
+{
+  GDBusConnection *conn;
+  GError *error = NULL;
+
+  conn = tp_dbus_tube_channel_accept_finish (
+      TP_DBUS_TUBE_CHANNEL (tube), res, &error);
+  if (conn == NULL)
+    {
+      g_debug ("Failed to accept tube: %s", error->message);
+      g_error_free (error);
+      tp_channel_close_async (TP_CHANNEL (tube), NULL, NULL);
+      return;
+    }
+
+  g_debug ("tube accepted");
+  g_signal_connect (conn, "closed",
+      G_CALLBACK (dbus_connection_closed_cb), NULL);
+
+  g_dbus_connection_signal_subscribe (conn,
+      /* since we only deal with 1-1 connections, no need to match sender */
+      NULL,
+      EXAMPLE_INTERFACE,
+      "LuckyNumber",
+      EXAMPLE_PATH,
+      NULL,
+      G_DBUS_SIGNAL_FLAGS_NONE,
+      lucky_number_cb,
+      NULL, NULL);
+
+  g_dbus_connection_call (conn,
+      NULL,
+      "/org/gnome/games/glchess/initiator",
+      "org.gnome.games.chess.game",
+      "get_id",
+      NULL,
+      G_VARIANT_TYPE ("(s)"),
+      G_DBUS_CALL_FLAGS_NONE,
+      -1,
+      NULL,
+      get_id_cb,
+      NULL);
+
+  g_dbus_connection_call (conn,
+      NULL,
+      EXAMPLE_PATH,
+      EXAMPLE_INTERFACE,
+      "Add",
+      g_variant_new ("(ii)", 45, 54),
+      G_VARIANT_TYPE ("(i)"),
+      G_DBUS_CALL_FLAGS_NONE,
+      -1,
+      NULL,
+      add_cb,
+      NULL);
+}
+
+static void
+tube_invalidated_cb (TpStreamTubeChannel *tube,
+    guint domain,
+    gint code,
+    gchar *message,
+    gpointer user_data)
+{
+  g_debug ("Tube has been invalidated: %s", message);
+  g_main_loop_quit (loop);
+  g_object_unref (tube);
+}
+
+static void
+handle_channels (TpSimpleHandler *handler,
+    TpAccount *account,
+    TpConnection *conn,
+    GList *channels,
+    GList *requests,
+    gint64 action_time,
+    TpHandleChannelsContext *context,
+    gpointer user_data)
+{
+  TpDBusTubeChannel *tube;
+  GList *l;
+  GError error = { TP_ERROR, TP_ERROR_NOT_AVAILABLE,
+      "No channel to be handled" };
+
+  g_debug ("Handling channels");
+
+  for (l = channels; l != NULL; l = l->next)
+    {
+      TpDBusTubeChannel *channel = l->data;
+
+      if (!TP_IS_DBUS_TUBE_CHANNEL (channel))
+        continue;
+
+      if (tp_strdiff (tp_dbus_tube_channel_get_service_name (channel),
+            EXAMPLE_SERVICE_NAME))
+        continue;
+
+      g_debug ("Accepting tube");
+
+      tube = g_object_ref (channel);
+
+      g_signal_connect (tube, "invalidated",
+          G_CALLBACK (tube_invalidated_cb), NULL);
+
+      tp_dbus_tube_channel_accept_async (tube, tube_accepted, context);
+
+      tp_handle_channels_context_accept (context);
+      return;
+    }
+
+  g_debug ("Rejecting channels");
+  tp_handle_channels_context_fail (context, &error);
+}
+
+
+int
+main (int argc,
+    const char **argv)
+{
+  TpAccountManager *manager;
+  TpBaseClient *handler;
+  GError *error = NULL;
+
+  g_type_init ();
+
+  manager = tp_account_manager_dup ();
+  handler = tp_simple_handler_new_with_am (manager, FALSE, FALSE,
+      "ExampleServiceHandler", FALSE, handle_channels, NULL, NULL);
+
+  tp_base_client_take_handler_filter (handler, tp_asv_new (
+      TP_PROP_CHANNEL_CHANNEL_TYPE,
+      G_TYPE_STRING,
+      TP_IFACE_CHANNEL_TYPE_DBUS_TUBE,
+
+      TP_PROP_CHANNEL_TARGET_HANDLE_TYPE,
+      G_TYPE_UINT,
+      TP_HANDLE_TYPE_CONTACT,
+
+      TP_PROP_CHANNEL_TYPE_DBUS_TUBE_SERVICE_NAME,
+      G_TYPE_STRING,
+      EXAMPLE_SERVICE_NAME,
+
+      NULL));
+
+  tp_base_client_register (handler, &error);
+  g_assert_no_error (error);
+
+  g_debug ("Waiting for tube offer");
+
+  loop = g_main_loop_new (NULL, FALSE);
+  g_main_loop_run (loop);
+
+  g_main_loop_unref (loop);
+  g_object_unref (handler);
+  g_object_unref (manager);
+
+  return 0;
+}
diff --git a/tests/constants.h b/tests/constants.h
new file mode 100644
index 0000000..77d9b1c
--- /dev/null
+++ b/tests/constants.h
@@ -0,0 +1,9 @@
+#ifndef DBUS_TUBE_EXAMPLE_CONSTANTS_H
+#define DBUS_TUBE_EXAMPLE_CONSTANTS_H
+
+#define EXAMPLE_SERVICE_NAME "uk.co.example.calculator"
+
+#define EXAMPLE_INTERFACE "org.example.terriblecalculator"
+#define EXAMPLE_PATH "/org/example/calculator"
+
+#endif
diff --git a/tests/offerer.c b/tests/offerer.c
new file mode 100644
index 0000000..e31e91b
--- /dev/null
+++ b/tests/offerer.c
@@ -0,0 +1,332 @@
+/* This is an improvised test on the accepter example available in TelepathyGLib
+ * demonstrating multiple objects exported on DBusConnection obtained from Tube. */
+
+#include <telepathy-glib/telepathy-glib.h>
+#include "constants.h"
+
+static GMainLoop *loop = NULL;
+
+static void
+connection_closed_cb (
+    GObject *source,
+    GAsyncResult *result,
+    gpointer user_data)
+{
+  GDBusConnection *connection = G_DBUS_CONNECTION (source);
+  GError *error = NULL;
+
+  if (!g_dbus_connection_close_finish (connection, result, &error))
+    {
+      g_warning ("Couldn't close connection: %s", error->message);
+      g_clear_error (&error);
+    }
+  else
+    {
+      g_debug ("Connection closed.");
+    }
+
+  tp_channel_close_async (TP_CHANNEL (user_data), NULL, NULL);
+  g_object_unref (connection);
+}
+
+static void
+method_call_func_for_game_iface (
+    GDBusConnection *connection,
+    const gchar *sender,
+    const gchar *object_path,
+    const gchar *interface_name,
+    const gchar *method_name,
+    GVariant *parameters,
+    GDBusMethodInvocation *invocation,
+    gpointer user_data)
+{
+  if (tp_strdiff (method_name, "get_id"))
+    {
+      g_dbus_method_invocation_return_error (invocation,
+          G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD,
+          "Unknown method '%s' on interface " EXAMPLE_INTERFACE,
+          method_name);
+    }
+  else
+    {
+      g_dbus_method_invocation_return_value (invocation,
+          g_variant_new ("(s)",
+          tp_contact_get_identifier (TP_CONTACT (user_data))));
+
+      g_dbus_connection_flush_sync (connection, NULL, NULL);
+//      g_dbus_connection_close (connection, NULL, connection_closed_cb, user_data);
+
+    }
+}
+static void
+handle_method_call (
+    GDBusConnection *connection,
+    const gchar *sender,
+    const gchar *object_path,
+    const gchar *interface_name,
+    const gchar *method_name,
+    GVariant *parameters,
+    GDBusMethodInvocation *invocation,
+    gpointer user_data)
+{
+  if (tp_strdiff (method_name, "Add"))
+    {
+      g_dbus_method_invocation_return_error (invocation,
+          G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD,
+          "Unknown method '%s' on interface " EXAMPLE_INTERFACE,
+          method_name);
+    }
+  else if (!g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(ii)")))
+    {
+      g_dbus_method_invocation_return_error (invocation,
+          G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
+          "Add takes two int32 parameters, not %s",
+          g_variant_get_type_string (parameters));
+    }
+  else /* hooray! */
+    {
+      guint x, y;
+      gboolean ret;
+
+      g_variant_get (parameters, "(ii)", &x, &y);
+
+      g_dbus_method_invocation_return_value (invocation,
+                                             g_variant_new ("(i)", x + y));
+
+      ret = g_dbus_connection_emit_signal (connection,
+          NULL, object_path, interface_name, "LuckyNumber",
+          g_variant_new ("(u)", g_random_int ()),
+          NULL);
+      /* "This can only fail if 'parameters' is not compatible with the D-Bus
+       * protocol."
+       */
+      g_return_if_fail (ret);
+
+      g_dbus_connection_flush_sync (connection, NULL, NULL);
+      g_dbus_connection_close (connection, NULL, connection_closed_cb, user_data);
+    }
+}
+
+static void
+register_object (GDBusConnection *connection,
+    TpDBusTubeChannel *channel)
+{
+  GDBusNodeInfo *introspection_data;
+  guint registration_id;
+  static const GDBusInterfaceVTable interface_vtable =
+  {
+    handle_method_call,
+    NULL,
+    NULL,
+  };
+
+  static const GDBusInterfaceVTable interface_vtable2 =
+  {
+    method_call_func_for_game_iface,
+    NULL,
+    NULL
+  };
+
+  static const gchar introspection_xml[] =
+    "<node>"
+    "  <interface name='" EXAMPLE_INTERFACE "'>"
+    "    <method name='Add'>"
+    "      <arg type='i' name='x' direction='in'/>"
+    "      <arg type='i' name='y' direction='in'/>"
+    "      <arg type='i' name='result' direction='out'/>"
+    "    </method>"
+    "    <signal name='LuckyNumber'>"
+    "      <arg type='u' name='number'/>"
+    "    </signal>"
+    "  </interface>"
+    "</node>";
+
+  static const gchar introspection_xml2[] =
+    "<node>"
+    "  <interface name='org.gnome.games.chess.game'>"
+    "    <method name='get_id'>"
+    "      <arg type='s' name='res' direction='out'/>"
+    "    </method>"
+    "  </interface>"
+    "</node>";
+
+  introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, NULL);
+  g_assert (introspection_data != NULL);
+
+  registration_id = g_dbus_connection_register_object (connection,
+      EXAMPLE_PATH, introspection_data->interfaces[0],
+      &interface_vtable, g_object_ref (channel), g_object_unref, NULL);
+  g_assert (registration_id > 0);
+
+  g_dbus_node_info_unref (introspection_data);
+
+  introspection_data = g_dbus_node_info_new_for_xml (introspection_xml2,
+      NULL);
+  g_assert (introspection_data != NULL);
+
+  registration_id = g_dbus_connection_register_object (connection,
+      "/org/gnome/games/glchess/initiator", introspection_data->interfaces[0],
+      &interface_vtable2,
+      g_object_ref (tp_channel_get_initiator_contact (TP_CHANNEL (channel))),
+      g_object_unref, NULL);
+  g_assert (registration_id > 0);
+
+  g_dbus_node_info_unref (introspection_data);
+}
+
+static void
+tube_offered (GObject *tube,
+    GAsyncResult *res,
+    gpointer user_data)
+{
+  GError *error = NULL;
+  GDBusConnection *conn;
+
+  conn = tp_dbus_tube_channel_offer_finish (TP_DBUS_TUBE_CHANNEL (tube), res,
+      &error);
+  if (conn == NULL)
+    {
+      g_debug ("Failed to offer tube: %s", error->message);
+      g_error_free (error);
+      tp_channel_close_async (TP_CHANNEL (tube), NULL, NULL);
+      return;
+    }
+
+  g_debug ("Tube opened");
+  register_object (conn, TP_DBUS_TUBE_CHANNEL (tube));
+}
+
+static void
+tube_invalidated_cb (TpStreamTubeChannel *tube,
+    guint domain,
+    gint code,
+    gchar *message,
+    gpointer user_data)
+{
+  g_debug ("Tube has been invalidated: %s", message);
+  g_main_loop_quit (loop);
+  g_object_unref (tube);
+}
+
+static void
+channel_created (GObject *source,
+    GAsyncResult *result,
+    gpointer user_data)
+{
+  TpChannel *channel;
+  GError *error = NULL;
+  TpDBusTubeChannel *tube;
+
+  channel = tp_account_channel_request_create_and_handle_channel_finish (
+      TP_ACCOUNT_CHANNEL_REQUEST (source), result, NULL, &error);
+  if (channel == NULL)
+    {
+      g_debug ("Failed to create channel: %s", error->message);
+      g_error_free (error);
+      g_main_loop_quit (loop);
+      return;
+    }
+
+  g_debug ("Channel created: %s", tp_proxy_get_object_path (channel));
+
+  tube = TP_DBUS_TUBE_CHANNEL (channel);
+
+  g_signal_connect (tube, "invalidated",
+      G_CALLBACK (tube_invalidated_cb), NULL);
+
+  tp_dbus_tube_channel_offer_async (tube, NULL, tube_offered, NULL);
+}
+
+static void ensure_legacy_channel_async (TpAccount *account,
+    const gchar* contact)
+{
+  GHashTable *request = tp_asv_new (
+      TP_PROP_CHANNEL_CHANNEL_TYPE,
+      G_TYPE_STRING,
+      TP_IFACE_CHANNEL_TYPE_TUBES,
+
+      TP_PROP_CHANNEL_TARGET_HANDLE_TYPE,
+      TP_TYPE_HANDLE,
+      TP_HANDLE_TYPE_CONTACT,
+
+      TP_PROP_CHANNEL_TARGET_ID,
+      G_TYPE_STRING,
+      contact,
+
+      NULL);
+
+  TpAccountChannelRequest *req =
+      tp_account_channel_request_new (account, request,
+          TP_USER_ACTION_TIME_CURRENT_TIME);
+
+  tp_account_channel_request_ensure_channel_async (req, NULL, NULL, NULL, NULL);
+
+  g_hash_table_unref (request);
+  g_object_unref (req);
+}
+
+int
+main (int argc,
+    const char **argv)
+{
+  TpAutomaticClientFactory *factory;
+  TpAccount *account;
+  char *account_path;
+  GError *error = NULL;
+  TpAccountChannelRequest *req;
+  GHashTable *request;
+
+  g_type_init ();
+
+  if (argc != 3)
+    g_error ("Usage: offerer gabble/jabber/ladygaga t-pain example com");
+
+  factory = tp_automatic_client_factory_new (NULL);
+
+  account_path = g_strconcat (TP_ACCOUNT_OBJECT_PATH_BASE, argv[1], NULL);
+  account = tp_simple_client_factory_ensure_account (
+      TP_SIMPLE_CLIENT_FACTORY (factory), account_path, NULL, &error);
+  g_assert_no_error (error);
+  g_free (account_path);
+
+  /* Workaround for https://bugs.freedesktop.org/show_bug.cgi?id=47760 */
+  ensure_legacy_channel_async (account, argv[2]);
+
+  request = tp_asv_new (
+      TP_PROP_CHANNEL_CHANNEL_TYPE,
+      G_TYPE_STRING,
+      TP_IFACE_CHANNEL_TYPE_DBUS_TUBE,
+
+      TP_PROP_CHANNEL_TARGET_HANDLE_TYPE,
+      G_TYPE_UINT,
+      TP_HANDLE_TYPE_CONTACT,
+
+      TP_PROP_CHANNEL_TARGET_ID,
+      G_TYPE_STRING,
+      argv[2],
+
+      TP_PROP_CHANNEL_TYPE_DBUS_TUBE_SERVICE_NAME,
+      G_TYPE_STRING,
+      EXAMPLE_SERVICE_NAME,
+
+      NULL);
+
+  g_debug ("Offer channel to %s", argv[2]);
+
+  req = tp_account_channel_request_new (account, request,
+      TP_USER_ACTION_TIME_CURRENT_TIME);
+
+  tp_account_channel_request_create_and_handle_channel_async (req, NULL,
+      channel_created, NULL);
+
+  loop = g_main_loop_new (NULL, FALSE);
+  g_main_loop_run (loop);
+
+  g_object_unref (account);
+  g_object_unref (req);
+  g_hash_table_unref (request);
+  g_main_loop_unref (loop);
+  g_object_unref (factory);
+
+  return 0;
+}



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]