/* Feature test for https://bugs.freedesktop.org/show_bug.cgi?id=27835
*
* Copyright © 2007-2010 Collabora Ltd.
* Copyright © 2007-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
#include
#include
#include
#include
#include
#include
#include "tests/lib/simple-conn.h"
#include "tests/lib/util.h"
/* an almost-no-op subclass... */
typedef TpTestsSimpleConnection InterestedConnection;
typedef TpTestsSimpleConnectionClass InterestedConnectionClass;
static GType interested_connection_get_type (void);
G_DEFINE_TYPE_WITH_CODE (InterestedConnection,
interested_connection,
TP_TESTS_TYPE_SIMPLE_CONNECTION,
G_STMT_START { } G_STMT_END)
/* Lord Pearson of Rannoch: My Lords, I beg leave to ask the Question
* standing in my name on the Order Paper. In doing so, I declare an
* interest as patron of the British Register of Chinese Herbal Medicine.
* -- Hansard, 2010-02-01 */
#define SUPPORTED_TOKEN "com.example.rannoch/ChineseHerbalMedicine"
/* Lord Hoyle: My Lords, in thanking my noble friend for his Answer, I declare
* an interest as the chairman and now president of Warrington Wolves Rugby
* League Club. -- Hansard, 2010-01-11
*/
#define UNSUPPORTED_TOKEN "org.example.Warrington/Wolves"
static void
interested_connection_init (InterestedConnection *self G_GNUC_UNUSED)
{
}
static void
interested_connection_constructed (GObject *object)
{
TpBaseConnection *base = (TpBaseConnection *) object;
void (*chain_up) (GObject *) =
((GObjectClass *) interested_connection_parent_class)->constructed;
if (chain_up != NULL)
chain_up (object);
tp_base_connection_add_possible_client_interest (base,
TP_IFACE_QUARK_CONNECTION_INTERFACE_LOCATION);
tp_base_connection_add_possible_client_interest (base,
g_quark_from_static_string (SUPPORTED_TOKEN));
}
static void
interested_connection_class_init (InterestedConnectionClass *cls)
{
GObjectClass *object_class = (GObjectClass *) cls;
object_class->constructed = interested_connection_constructed;
}
typedef struct {
TpDBusDaemon *dbus;
DBusConnection *client_libdbus;
DBusGConnection *client_dbusglib;
TpDBusDaemon *client_bus;
TpTestsSimpleConnection *service_conn;
TpBaseConnection *service_conn_as_base;
gchar *conn_name;
gchar *conn_path;
TpConnection *conn;
gboolean cwr_ready;
GError *cwr_error /* initialized in setup */;
GAsyncResult *prepare_result;
GPtrArray *log;
} Test;
static void
connection_prepared_cb (GObject *object,
GAsyncResult *res,
gpointer user_data)
{
Test *test = user_data;
g_message ("%p prepared", object);
g_assert (test->prepare_result == NULL);
test->prepare_result = g_object_ref (res);
}
static void
interested_cb (TpBaseConnection *unused G_GNUC_UNUSED,
const gchar *iface,
Test *test)
{
g_ptr_array_add (test->log, g_strdup_printf ("interested in %s", iface));
}
static void
location_interested_cb (TpBaseConnection *unused G_GNUC_UNUSED,
const gchar *iface,
Test *test)
{
g_assert_cmpstr (iface, ==, TP_IFACE_CONNECTION_INTERFACE_LOCATION);
g_ptr_array_add (test->log, g_strdup ("Location interested"));
}
static void
uninterested_cb (TpBaseConnection *unused G_GNUC_UNUSED,
const gchar *iface,
Test *test)
{
g_ptr_array_add (test->log, g_strdup_printf ("uninterested in %s", iface));
}
static void
location_uninterested_cb (TpBaseConnection *unused G_GNUC_UNUSED,
const gchar *iface,
Test *test)
{
g_assert_cmpstr (iface, ==, TP_IFACE_CONNECTION_INTERFACE_LOCATION);
g_ptr_array_add (test->log, g_strdup ("Location uninterested"));
}
static void
setup (Test *test,
gconstpointer data)
{
GError *error = NULL;
GQuark features[] = { TP_CONNECTION_FEATURE_CONNECTED, 0 };
g_type_init ();
tp_debug_set_flags ("all");
test->dbus = tp_tests_dbus_daemon_dup_or_die ();
test->client_libdbus = dbus_bus_get_private (DBUS_BUS_STARTER, NULL);
g_assert (test->client_libdbus != NULL);
dbus_connection_setup_with_g_main (test->client_libdbus, NULL);
dbus_connection_set_exit_on_disconnect (test->client_libdbus, FALSE);
test->client_dbusglib = dbus_connection_get_g_connection (
test->client_libdbus);
dbus_g_connection_ref (test->client_dbusglib);
test->client_bus = tp_dbus_daemon_new (test->client_dbusglib);
g_assert (test->client_bus != NULL);
test->service_conn = tp_tests_object_new_static_class (
interested_connection_get_type (),
"account", "me@example.com",
"protocol", "simple-protocol",
NULL);
test->service_conn_as_base = TP_BASE_CONNECTION (test->service_conn);
g_assert (test->service_conn != NULL);
g_assert (test->service_conn_as_base != NULL);
g_assert (tp_base_connection_register (test->service_conn_as_base, "simple",
&test->conn_name, &test->conn_path, &error));
g_assert_no_error (error);
test->cwr_ready = FALSE;
test->cwr_error = NULL;
test->conn = tp_connection_new (test->client_bus, test->conn_name,
test->conn_path, &error);
g_assert (test->conn != NULL);
g_assert_no_error (error);
tp_cli_connection_call_connect (test->conn, -1, NULL, NULL, NULL, NULL);
g_assert (!tp_proxy_is_prepared (test->conn, TP_CONNECTION_FEATURE_CORE));
g_assert (!tp_proxy_is_prepared (test->conn,
TP_CONNECTION_FEATURE_CONNECTED));
tp_proxy_prepare_async (test->conn, features, connection_prepared_cb, test);
g_assert (test->prepare_result == NULL);
while (test->prepare_result == NULL)
g_main_context_iteration (NULL, TRUE);
g_assert (tp_proxy_prepare_finish (test->conn, test->prepare_result,
&error));
g_assert_no_error (error);
g_object_unref (test->prepare_result);
test->prepare_result = NULL;
test->log = g_ptr_array_new_with_free_func (g_free);
g_signal_connect (test->service_conn,
"clients-interested", G_CALLBACK (interested_cb), test);
g_signal_connect (test->service_conn,
"clients-interested::" TP_IFACE_CONNECTION_INTERFACE_LOCATION,
G_CALLBACK (location_interested_cb), test);
g_signal_connect (test->service_conn,
"clients-uninterested", G_CALLBACK (uninterested_cb), test);
g_signal_connect (test->service_conn,
"clients-uninterested::" TP_IFACE_CONNECTION_INTERFACE_LOCATION,
G_CALLBACK (location_uninterested_cb), test);
}
static void
teardown (Test *test,
gconstpointer data)
{
TpConnection *conn;
gboolean ok;
GError *error = NULL;
if (test->conn != NULL)
{
g_object_unref (test->conn);
test->conn = NULL;
}
/* disconnect the connection so we don't leak it */
conn = tp_connection_new (test->dbus, test->conn_name, test->conn_path,
&error);
g_assert (conn != NULL);
g_assert_no_error (error);
ok = tp_cli_connection_run_disconnect (conn, -1, &error, NULL);
g_assert (ok);
g_assert_no_error (error);
g_assert (!tp_connection_run_until_ready (conn, FALSE, &error, NULL));
g_assert_error (error, TP_ERRORS, TP_ERROR_CANCELLED);
g_clear_error (&error);
test->service_conn_as_base = NULL;
g_object_unref (test->service_conn);
g_free (test->conn_name);
g_free (test->conn_path);
g_object_unref (test->dbus);
test->dbus = NULL;
g_object_unref (test->client_bus);
test->client_bus = NULL;
dbus_g_connection_unref (test->client_dbusglib);
dbus_connection_close (test->client_libdbus);
dbus_connection_unref (test->client_libdbus);
g_ptr_array_free (test->log, TRUE);
}
static void
test_interested_client (Test *test,
gconstpointer nil G_GNUC_UNUSED)
{
guint i;
tp_connection_add_client_interest_by_id (test->conn,
TP_IFACE_QUARK_CONNECTION_INTERFACE_LOCATION);
tp_connection_add_client_interest_by_id (test->conn,
TP_IFACE_QUARK_CONNECTION_INTERFACE_AVATARS);
/* run until (after) the AddClientInterest calls have gone out */
tp_tests_proxy_run_until_dbus_queue_processed (test->client_bus);
/* we auto-release the Location client interest by disposing the client
* connection */
g_object_run_dispose ((GObject *) test->conn);
g_object_unref (test->conn);
test->conn = NULL;
/* run until (after) the RemoveClientInterest call has gone out */
tp_tests_proxy_run_until_dbus_queue_processed (test->client_bus);
/* then, run until (after) the CM should have processed both ACI and RCI */
tp_tests_proxy_run_until_dbus_queue_processed (test->dbus);
i = 0;
g_assert_cmpuint (test->log->len, >, i);
g_assert_cmpstr (g_ptr_array_index (test->log, i), ==,
"interested in " TP_IFACE_CONNECTION_INTERFACE_LOCATION);
i++;
g_assert_cmpuint (test->log->len, >, i);
g_assert_cmpstr (g_ptr_array_index (test->log, i), ==,
"Location interested");
i++;
g_assert_cmpuint (test->log->len, >, i);
g_assert_cmpstr (g_ptr_array_index (test->log, i), ==,
"uninterested in " TP_IFACE_CONNECTION_INTERFACE_LOCATION);
i++;
g_assert_cmpuint (test->log->len, >, i);
g_assert_cmpstr (g_ptr_array_index (test->log, i), ==,
"Location uninterested");
i++;
g_assert_cmpuint (test->log->len, ==, i);
}
static void
test_interest (Test *test,
gconstpointer nil G_GNUC_UNUSED)
{
static const gchar * telepathy[] = {
TP_IFACE_CONNECTION_INTERFACE_LOCATION,
TP_IFACE_CONNECTION_INTERFACE_AVATARS,
NULL
};
static const gchar * hansard[] = {
SUPPORTED_TOKEN,
UNSUPPORTED_TOKEN,
NULL
};
GError *error = NULL;
guint i;
tp_cli_connection_run_add_client_interest (test->conn, -1, telepathy, &error,
NULL);
g_assert_no_error (error);
tp_cli_connection_run_add_client_interest (test->conn, -1, hansard, &error,
NULL);
g_assert_no_error (error);
tp_cli_connection_run_add_client_interest (test->conn, -1, telepathy, &error,
NULL);
g_assert_no_error (error);
tp_cli_connection_run_remove_client_interest (test->conn, -1, telepathy,
&error, NULL);
g_assert_no_error (error);
tp_cli_connection_run_remove_client_interest (test->conn, -1, hansard,
&error, NULL);
g_assert_no_error (error);
/* we auto-release the Location client interest by dropping the client
* connection */
dbus_connection_flush (test->client_libdbus);
dbus_connection_close (test->client_libdbus);
while (test->log->len < 6)
g_main_context_iteration (NULL, TRUE);
i = 0;
g_assert_cmpuint (test->log->len, >, i);
g_assert_cmpstr (g_ptr_array_index (test->log, i), ==,
"interested in " TP_IFACE_CONNECTION_INTERFACE_LOCATION);
i++;
g_assert_cmpuint (test->log->len, >, i);
g_assert_cmpstr (g_ptr_array_index (test->log, i), ==,
"Location interested");
i++;
g_assert_cmpuint (test->log->len, >, i);
g_assert_cmpstr (g_ptr_array_index (test->log, i), ==,
"interested in " SUPPORTED_TOKEN);
i++;
g_assert_cmpuint (test->log->len, >, i);
g_assert_cmpstr (g_ptr_array_index (test->log, i), ==,
"uninterested in " SUPPORTED_TOKEN);
i++;
g_assert_cmpuint (test->log->len, >, i);
g_assert_cmpstr (g_ptr_array_index (test->log, i), ==,
"uninterested in " TP_IFACE_CONNECTION_INTERFACE_LOCATION);
i++;
g_assert_cmpuint (test->log->len, >, i);
g_assert_cmpstr (g_ptr_array_index (test->log, i), ==,
"Location uninterested");
i++;
g_assert_cmpuint (test->log->len, ==, i);
}
int
main (int argc,
char **argv)
{
tp_tests_init (&argc, &argv);
g_test_add ("/conn/interest", Test, NULL, setup, test_interest, teardown);
g_test_add ("/conn/interested-client", Test, NULL, setup,
test_interested_client, teardown);
return g_test_run ();
}