/* Feature test for https://bugs.freedesktop.org/show_bug.cgi?id=18291 * * Copyright (C) 2009 Collabora Ltd. * Copyright (C) 2009 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 #include "tests/lib/echo-cm.h" #include "tests/lib/util.h" typedef enum { ACTIVATE_CM = (1 << 0), USE_CWR = (1 << 1), USE_OLD_LIST = (1 << 2), DROP_NAME_ON_GET = (1 << 3), DROP_NAME_ON_GET_TWICE = (1 << 4), NO_PROPERTIES = (1 << 5) } TestFlags; typedef struct { TpTestsEchoConnectionManager parent; guint drop_name_on_get; gboolean implement_properties; } MyConnectionManager; typedef TpTestsEchoConnectionManagerClass MyConnectionManagerClass; typedef struct { GMainLoop *mainloop; TpDBusDaemon *dbus; MyConnectionManager *service_cm; TpConnectionManager *cm; TpConnectionManager *echo; TpConnectionManager *spurious; GError *error /* initialized where needed */; } Test; static void my_properties_iface_init (gpointer iface); static GType my_connection_manager_get_type (void); G_DEFINE_TYPE_WITH_CODE (MyConnectionManager, my_connection_manager, TP_TESTS_TYPE_ECHO_CONNECTION_MANAGER, G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_DBUS_PROPERTIES, my_properties_iface_init)) static void my_connection_manager_class_init (MyConnectionManagerClass *cls) { } static void my_connection_manager_init (MyConnectionManager *self) { self->implement_properties = TRUE; } static void my_get (TpSvcDBusProperties *iface G_GNUC_UNUSED, const gchar *i G_GNUC_UNUSED, const gchar *p G_GNUC_UNUSED, DBusGMethodInvocation *context) { /* The telepathy-glib client side should never call this: * GetAll() is better. */ g_assert_not_reached (); } static void my_get_all (TpSvcDBusProperties *iface, const gchar *i, DBusGMethodInvocation *context) { MyConnectionManager *cm = (MyConnectionManager *) iface; /* If necessary, emulate the CM exiting and coming back. */ if (cm->drop_name_on_get) { TpDBusDaemon *dbus = tp_base_connection_manager_get_dbus_daemon ( TP_BASE_CONNECTION_MANAGER (cm)); GString *string = g_string_new (TP_CM_BUS_NAME_BASE); GError *error = NULL; g_string_append (string, "example_echo"); cm->drop_name_on_get--; tp_dbus_daemon_release_name (dbus, string->str, &error); g_assert_no_error (error); tp_dbus_daemon_request_name (dbus, string->str, FALSE, &error); g_assert_no_error (error); } /* Do we implement properties? */ if (cm->implement_properties) { GHashTable *ht = tp_dbus_properties_mixin_dup_all ((GObject *) cm, i); tp_svc_dbus_properties_return_from_get_all (context, ht); g_hash_table_unref (ht); } else { tp_dbus_g_method_return_not_implemented (context); } } static void my_properties_iface_init (gpointer iface) { TpSvcDBusPropertiesClass *cls = iface; #define IMPLEMENT(x) \ tp_svc_dbus_properties_implement_##x (cls, my_##x) IMPLEMENT (get); IMPLEMENT (get_all); #undef IMPLEMENT } static void setup (Test *test, gconstpointer data) { TpBaseConnectionManager *service_cm_as_base; gboolean ok; tp_debug_set_flags ("all"); test->mainloop = g_main_loop_new (NULL, FALSE); test->dbus = tp_tests_dbus_daemon_dup_or_die (); test->service_cm = tp_tests_object_new_static_class ( my_connection_manager_get_type (), NULL); g_assert (test->service_cm != NULL); service_cm_as_base = TP_BASE_CONNECTION_MANAGER (test->service_cm); g_assert (service_cm_as_base != NULL); ok = tp_base_connection_manager_register (service_cm_as_base); g_assert (ok); test->cm = NULL; } static void teardown (Test *test, gconstpointer data) { g_clear_object (&test->service_cm); g_clear_object (&test->dbus); g_clear_object (&test->cm); g_clear_object (&test->echo); g_clear_object (&test->spurious); g_main_loop_unref (test->mainloop); test->mainloop = NULL; } static void test_valid_name (void) { GError *error = NULL; g_assert (tp_connection_manager_check_valid_name ("gabble", NULL)); g_assert (tp_connection_manager_check_valid_name ("l33t_cm", NULL)); g_assert (!tp_connection_manager_check_valid_name ("wtf tbh", &error)); g_assert (error != NULL); g_clear_error (&error); g_assert (!tp_connection_manager_check_valid_name ("0pointer", &error)); g_assert (error != NULL); g_clear_error (&error); } static void on_got_info_expect_none (TpConnectionManager *self, guint info_source, gpointer p) { Test *test = p; g_assert (self == test->cm); g_assert_cmpuint (info_source, ==, TP_CM_INFO_SOURCE_NONE); g_assert_cmpuint (info_source, ==, test->cm->info_source); g_main_loop_quit (test->mainloop); } static void test_nothing_got_info (Test *test, gconstpointer data) { GError *error = NULL; gulong id; test->cm = tp_connection_manager_new (test->dbus, "not_actually_there", NULL, &error); g_assert (TP_IS_CONNECTION_MANAGER (test->cm)); g_assert_no_error (error); /* Spin the mainloop until we get the got-info signal. This API is rubbish, * but it's better than it used to be... */ g_test_bug ("18207"); id = g_signal_connect (test->cm, "got-info", G_CALLBACK (on_got_info_expect_none), test); g_main_loop_run (test->mainloop); g_signal_handler_disconnect (test->cm, id); g_assert_cmpstr (test->cm->name, ==, "not_actually_there"); g_assert_cmpuint (test->cm->running, ==, FALSE); g_assert_cmpuint (test->cm->info_source, ==, TP_CM_INFO_SOURCE_NONE); g_assert (test->cm->protocols == NULL); g_assert (tp_connection_manager_dup_protocols (test->cm) == NULL); } static void on_got_info_expect_file (TpConnectionManager *self, guint info_source, gpointer p) { Test *test = p; g_assert (self == test->cm); g_assert_cmpuint (info_source, ==, TP_CM_INFO_SOURCE_FILE); g_assert_cmpuint (info_source, ==, test->cm->info_source); g_main_loop_quit (test->mainloop); } static void test_file_got_info (Test *test, gconstpointer data) { GError *error = NULL; gulong id; const TpConnectionManagerParam *param; const TpConnectionManagerProtocol *protocol; gchar **strv; GValue value = { 0 }; gboolean ok; GVariant *variant; test->cm = tp_connection_manager_new (test->dbus, "spurious", NULL, &error); g_assert (TP_IS_CONNECTION_MANAGER (test->cm)); g_assert_no_error (error); g_test_bug ("18207"); id = g_signal_connect (test->cm, "got-info", G_CALLBACK (on_got_info_expect_file), test); g_main_loop_run (test->mainloop); g_signal_handler_disconnect (test->cm, id); g_assert_cmpstr (test->cm->name, ==, "spurious"); g_assert_cmpuint (test->cm->running, ==, FALSE); g_assert_cmpuint (test->cm->info_source, ==, TP_CM_INFO_SOURCE_FILE); g_assert (test->cm->protocols != NULL); g_assert (test->cm->protocols[0] != NULL); g_assert (test->cm->protocols[1] != NULL); g_assert (test->cm->protocols[2] == NULL); strv = tp_connection_manager_dup_protocol_names (test->cm); if (tp_strdiff (strv[0], "normal")) { g_assert_cmpstr (strv[0], ==, "weird"); g_assert_cmpstr (strv[1], ==, "normal"); } else { g_assert_cmpstr (strv[0], ==, "normal"); g_assert_cmpstr (strv[1], ==, "weird"); } g_assert (strv[2] == NULL); g_strfreev (strv); g_assert (tp_connection_manager_has_protocol (test->cm, "normal")); g_assert (!tp_connection_manager_has_protocol (test->cm, "not-there")); protocol = tp_connection_manager_get_protocol (test->cm, "normal"); g_assert_cmpstr (protocol->name, ==, "normal"); g_assert (tp_connection_manager_protocol_can_register (protocol)); g_assert (tp_connection_manager_protocol_has_param (protocol, "account")); g_assert (!tp_connection_manager_protocol_has_param (protocol, "not-there")); /* FIXME: it's not technically an API guarantee that params * come out in this order... */ param = &protocol->params[0]; g_assert_cmpstr (param->name, ==, "account"); g_assert_cmpstr (param->dbus_signature, ==, "s"); g_assert_cmpuint (param->flags, ==, TP_CONN_MGR_PARAM_FLAG_REQUIRED | TP_CONN_MGR_PARAM_FLAG_REGISTER); g_assert (param == tp_connection_manager_protocol_get_param (protocol, "account")); g_assert_cmpstr (tp_connection_manager_param_get_name (param), ==, "account"); g_assert_cmpstr (tp_connection_manager_param_get_dbus_signature (param), ==, "s"); g_assert (tp_connection_manager_param_is_required (param)); g_assert (tp_connection_manager_param_is_required_for_registration (param)); g_assert (!tp_connection_manager_param_is_secret (param)); g_assert (!tp_connection_manager_param_is_dbus_property (param)); g_assert (!tp_connection_manager_param_is_dbus_property (param)); ok = tp_connection_manager_param_get_default (param, &value); g_assert (!ok); g_assert (!G_IS_VALUE (&value)); g_assert (tp_connection_manager_param_dup_default_variant (param) == NULL); param = &protocol->params[1]; g_assert_cmpstr (param->name, ==, "password"); g_assert_cmpstr (param->dbus_signature, ==, "s"); g_assert_cmpuint (param->flags, ==, TP_CONN_MGR_PARAM_FLAG_REQUIRED | TP_CONN_MGR_PARAM_FLAG_REGISTER | TP_CONN_MGR_PARAM_FLAG_SECRET); g_assert (param == tp_connection_manager_protocol_get_param (protocol, "password")); param = &protocol->params[2]; g_assert_cmpstr (param->name, ==, "register"); g_assert_cmpstr (param->dbus_signature, ==, "b"); g_assert_cmpuint (param->flags, ==, TP_CONN_MGR_PARAM_FLAG_HAS_DEFAULT); g_assert (param == tp_connection_manager_protocol_get_param (protocol, "register")); ok = tp_connection_manager_param_get_default (param, &value); g_assert (ok); g_assert (G_IS_VALUE (&value)); g_assert (G_VALUE_HOLDS_BOOLEAN (&value)); g_value_unset (&value); variant = tp_connection_manager_param_dup_default_variant (param); g_assert_cmpstr (g_variant_get_type_string (variant), ==, "b"); g_assert_cmpint (g_variant_get_boolean (variant), ==, TRUE); param = &protocol->params[3]; g_assert (param->name == NULL); strv = tp_connection_manager_protocol_dup_param_names (protocol); g_assert_cmpstr (strv[0], ==, "account"); g_assert_cmpstr (strv[1], ==, "password"); g_assert_cmpstr (strv[2], ==, "register"); g_assert (strv[3] == NULL); g_strfreev (strv); /* switch to the other protocol, whichever one that actually is */ if (protocol == test->cm->protocols[0]) { protocol = test->cm->protocols[1]; } else { g_assert (protocol == test->cm->protocols[1]); protocol = test->cm->protocols[0]; } g_assert_cmpstr (protocol->name, ==, "weird"); g_assert (protocol == tp_connection_manager_get_protocol (test->cm, "weird")); g_assert (!tp_connection_manager_protocol_can_register (protocol)); param = &protocol->params[0]; g_assert_cmpstr (param->name, ==, "com.example.Bork.Bork.Bork"); g_assert_cmpuint (param->flags, ==, TP_CONN_MGR_PARAM_FLAG_DBUS_PROPERTY | TP_CONN_MGR_PARAM_FLAG_HAS_DEFAULT); g_assert_cmpstr (param->dbus_signature, ==, "u"); param = &protocol->params[1]; g_assert (param->name == NULL); g_assert (test->cm->protocols[2] == NULL); } static void test_complex_file_got_info (Test *test, gconstpointer data) { GError *error = NULL; gulong id; const TpConnectionManagerParam *param; const TpConnectionManagerProtocol *protocol; gchar **strv; GPtrArray *arr; test->cm = tp_connection_manager_new (test->dbus, "test_manager_file", NULL, &error); g_assert (TP_IS_CONNECTION_MANAGER (test->cm)); g_assert_no_error (error); g_test_bug ("18207"); id = g_signal_connect (test->cm, "got-info", G_CALLBACK (on_got_info_expect_file), test); g_main_loop_run (test->mainloop); g_signal_handler_disconnect (test->cm, id); g_assert_cmpstr (test->cm->name, ==, "test_manager_file"); g_assert_cmpuint (test->cm->running, ==, FALSE); g_assert_cmpuint (test->cm->info_source, ==, TP_CM_INFO_SOURCE_FILE); g_assert (test->cm->protocols != NULL); g_assert (test->cm->protocols[0] != NULL); g_assert (test->cm->protocols[1] != NULL); g_assert (test->cm->protocols[2] != NULL); g_assert (test->cm->protocols[3] == NULL); /* FIXME: it's not technically an API guarantee that params * come out in this order... */ protocol = tp_connection_manager_get_protocol (test->cm, "foo"); g_assert_cmpstr (protocol->name, ==, "foo"); param = &protocol->params[0]; g_assert_cmpstr (param->name, ==, "account"); g_assert_cmpstr (param->dbus_signature, ==, "s"); g_assert_cmpuint (param->flags, ==, TP_CONN_MGR_PARAM_FLAG_REQUIRED | TP_CONN_MGR_PARAM_FLAG_HAS_DEFAULT); g_assert (G_VALUE_HOLDS_STRING (¶m->default_value)); g_assert_cmpstr (g_value_get_string (¶m->default_value), ==, "foo@default"); param = &protocol->params[1]; g_assert_cmpstr (param->name, ==, "password"); g_assert_cmpstr (param->dbus_signature, ==, "s"); g_assert_cmpuint (param->flags, ==, TP_CONN_MGR_PARAM_FLAG_REQUIRED | TP_CONN_MGR_PARAM_FLAG_SECRET); g_assert (G_VALUE_HOLDS_STRING (¶m->default_value)); param = &protocol->params[2]; g_assert_cmpstr (param->name, ==, "encryption-key"); g_assert_cmpstr (param->dbus_signature, ==, "s"); g_assert_cmpuint (param->flags, ==, TP_CONN_MGR_PARAM_FLAG_SECRET); g_assert (G_VALUE_HOLDS_STRING (¶m->default_value)); param = &protocol->params[3]; g_assert_cmpstr (param->name, ==, "port"); g_assert_cmpstr (param->dbus_signature, ==, "q"); g_assert_cmpuint (param->flags, ==, TP_CONN_MGR_PARAM_FLAG_HAS_DEFAULT); g_assert (G_VALUE_HOLDS_UINT (¶m->default_value)); g_assert_cmpuint (g_value_get_uint (¶m->default_value), ==, 1234); param = &protocol->params[4]; g_assert_cmpstr (param->name, ==, "register"); g_assert_cmpstr (param->dbus_signature, ==, "b"); g_assert_cmpuint (param->flags, ==, 0); g_assert (G_VALUE_HOLDS_BOOLEAN (¶m->default_value)); param = &protocol->params[5]; g_assert_cmpstr (param->name, ==, "server-list"); g_assert_cmpstr (param->dbus_signature, ==, "as"); g_assert_cmpuint (param->flags, ==, TP_CONN_MGR_PARAM_FLAG_HAS_DEFAULT); g_assert (G_VALUE_HOLDS (¶m->default_value, G_TYPE_STRV)); strv = g_value_get_boxed (¶m->default_value); g_assert_cmpstr (strv[0], ==, "foo"); g_assert_cmpstr (strv[1], ==, "bar"); g_assert (strv[2] == NULL); param = &protocol->params[6]; g_assert (param->name == NULL); protocol = tp_connection_manager_get_protocol (test->cm, "bar"); g_assert_cmpstr (protocol->name, ==, "bar"); param = &protocol->params[0]; g_assert_cmpstr (param->name, ==, "account"); g_assert_cmpuint (param->flags, ==, TP_CONN_MGR_PARAM_FLAG_REQUIRED | TP_CONN_MGR_PARAM_FLAG_HAS_DEFAULT); g_assert_cmpstr (param->dbus_signature, ==, "s"); g_assert (G_VALUE_HOLDS_STRING (¶m->default_value)); g_assert_cmpstr (g_value_get_string (¶m->default_value), ==, "bar@default"); param = &protocol->params[1]; g_assert_cmpstr (param->name, ==, "encryption-key"); g_assert_cmpuint (param->flags, ==, TP_CONN_MGR_PARAM_FLAG_REQUIRED | TP_CONN_MGR_PARAM_FLAG_SECRET); g_assert_cmpstr (param->dbus_signature, ==, "s"); g_assert (G_VALUE_HOLDS_STRING (¶m->default_value)); param = &protocol->params[2]; g_assert_cmpstr (param->name, ==, "password"); g_assert_cmpuint (param->flags, ==, TP_CONN_MGR_PARAM_FLAG_REQUIRED | TP_CONN_MGR_PARAM_FLAG_SECRET); g_assert_cmpstr (param->dbus_signature, ==, "s"); g_assert (G_VALUE_HOLDS_STRING (¶m->default_value)); param = &protocol->params[3]; g_assert_cmpstr (param->name, ==, "port"); g_assert_cmpstr (param->dbus_signature, ==, "q"); g_assert_cmpuint (param->flags, ==, TP_CONN_MGR_PARAM_FLAG_HAS_DEFAULT); g_assert (G_VALUE_HOLDS_UINT (¶m->default_value)); g_assert_cmpuint (g_value_get_uint (¶m->default_value), ==, 4321); param = &protocol->params[4]; g_assert_cmpstr (param->name, ==, "register"); g_assert_cmpstr (param->dbus_signature, ==, "b"); g_assert_cmpuint (param->flags, ==, 0); g_assert (G_VALUE_HOLDS_BOOLEAN (¶m->default_value)); param = &protocol->params[5]; g_assert_cmpstr (param->name, ==, "server-list"); g_assert_cmpstr (param->dbus_signature, ==, "as"); g_assert_cmpuint (param->flags, ==, TP_CONN_MGR_PARAM_FLAG_HAS_DEFAULT); g_assert (G_VALUE_HOLDS (¶m->default_value, G_TYPE_STRV)); strv = g_value_get_boxed (¶m->default_value); g_assert_cmpstr (strv[0], ==, "bar"); g_assert_cmpstr (strv[1], ==, "foo"); g_assert (strv[2] == NULL); param = &protocol->params[6]; g_assert (param->name == NULL); protocol = tp_connection_manager_get_protocol (test->cm, "somewhat-pathological"); g_assert_cmpstr (protocol->name, ==, "somewhat-pathological"); param = &protocol->params[0]; g_assert_cmpstr (param->name, ==, "foo"); g_assert_cmpuint (param->flags, ==, TP_CONN_MGR_PARAM_FLAG_REQUIRED | TP_CONN_MGR_PARAM_FLAG_HAS_DEFAULT); g_assert_cmpstr (param->dbus_signature, ==, "s"); g_assert (G_VALUE_HOLDS_STRING (¶m->default_value)); g_assert_cmpstr (g_value_get_string (¶m->default_value), ==, "hello world"); param = &protocol->params[1]; g_assert_cmpstr (param->name, ==, "semicolons"); g_assert_cmpuint (param->flags, ==, TP_CONN_MGR_PARAM_FLAG_HAS_DEFAULT | TP_CONN_MGR_PARAM_FLAG_SECRET); g_assert_cmpstr (param->dbus_signature, ==, "s"); g_assert (G_VALUE_HOLDS_STRING (¶m->default_value)); g_assert_cmpstr (g_value_get_string (¶m->default_value), ==, "list;of;misc;"); param = &protocol->params[2]; g_assert_cmpstr (param->name, ==, "list"); g_assert_cmpuint (param->flags, ==, TP_CONN_MGR_PARAM_FLAG_HAS_DEFAULT); g_assert_cmpstr (param->dbus_signature, ==, "as"); g_assert (G_VALUE_HOLDS (¶m->default_value, G_TYPE_STRV)); strv = g_value_get_boxed (¶m->default_value); g_assert_cmpstr (strv[0], ==, "list"); g_assert_cmpstr (strv[1], ==, "of"); g_assert_cmpstr (strv[2], ==, "misc"); g_assert (strv[3] == NULL); param = &protocol->params[3]; g_assert_cmpstr (param->name, ==, "unterminated-list"); g_assert_cmpuint (param->flags, ==, TP_CONN_MGR_PARAM_FLAG_HAS_DEFAULT); g_assert_cmpstr (param->dbus_signature, ==, "as"); g_assert (G_VALUE_HOLDS (¶m->default_value, G_TYPE_STRV)); strv = g_value_get_boxed (¶m->default_value); g_assert_cmpstr (strv[0], ==, "list"); g_assert_cmpstr (strv[1], ==, "of"); g_assert_cmpstr (strv[2], ==, "misc"); g_assert (strv[3] == NULL); param = &protocol->params[4]; g_assert_cmpstr (param->name, ==, "spaces-in-list"); g_assert_cmpuint (param->flags, ==, TP_CONN_MGR_PARAM_FLAG_HAS_DEFAULT); g_assert_cmpstr (param->dbus_signature, ==, "as"); g_assert (G_VALUE_HOLDS (¶m->default_value, G_TYPE_STRV)); strv = g_value_get_boxed (¶m->default_value); g_assert_cmpstr (strv[0], ==, "list"); g_assert_cmpstr (strv[1], ==, " of"); g_assert_cmpstr (strv[2], ==, " misc "); g_assert (strv[3] == NULL); param = &protocol->params[5]; g_assert_cmpstr (param->name, ==, "escaped-semicolon-in-list"); g_assert_cmpuint (param->flags, ==, TP_CONN_MGR_PARAM_FLAG_HAS_DEFAULT); g_assert_cmpstr (param->dbus_signature, ==, "as"); g_assert (G_VALUE_HOLDS (¶m->default_value, G_TYPE_STRV)); strv = g_value_get_boxed (¶m->default_value); g_assert_cmpstr (strv[0], ==, "list;of"); g_assert_cmpstr (strv[1], ==, "misc"); g_assert (strv[2] == NULL); param = &protocol->params[6]; g_assert_cmpstr (param->name, ==, "doubly-escaped-semicolon-in-list"); g_assert_cmpuint (param->flags, ==, TP_CONN_MGR_PARAM_FLAG_HAS_DEFAULT); g_assert_cmpstr (param->dbus_signature, ==, "as"); g_assert (G_VALUE_HOLDS (¶m->default_value, G_TYPE_STRV)); strv = g_value_get_boxed (¶m->default_value); g_assert_cmpstr (strv[0], ==, "list\\"); g_assert_cmpstr (strv[1], ==, "of"); g_assert_cmpstr (strv[2], ==, "misc"); g_assert (strv[3] == NULL); param = &protocol->params[7]; g_assert_cmpstr (param->name, ==, "triply-escaped-semicolon-in-list"); g_assert_cmpuint (param->flags, ==, TP_CONN_MGR_PARAM_FLAG_HAS_DEFAULT); g_assert_cmpstr (param->dbus_signature, ==, "as"); g_assert (G_VALUE_HOLDS (¶m->default_value, G_TYPE_STRV)); strv = g_value_get_boxed (¶m->default_value); g_assert_cmpstr (strv[0], ==, "list\\;of"); g_assert_cmpstr (strv[1], ==, "misc"); g_assert (strv[2] == NULL); param = &protocol->params[8]; g_assert_cmpstr (param->name, ==, "empty-list"); g_assert_cmpuint (param->flags, ==, TP_CONN_MGR_PARAM_FLAG_HAS_DEFAULT); g_assert_cmpstr (param->dbus_signature, ==, "as"); g_assert (G_VALUE_HOLDS (¶m->default_value, G_TYPE_STRV)); strv = g_value_get_boxed (¶m->default_value); g_assert (strv == NULL || strv[0] == NULL); param = &protocol->params[9]; g_assert_cmpstr (param->name, ==, "escaped-semicolon"); g_assert_cmpuint (param->flags, ==, TP_CONN_MGR_PARAM_FLAG_HAS_DEFAULT); g_assert_cmpstr (param->dbus_signature, ==, "s"); g_assert (G_VALUE_HOLDS_STRING (¶m->default_value)); g_assert_cmpstr (g_value_get_string (¶m->default_value), ==, "foo\\;bar"); param = &protocol->params[10]; g_assert_cmpstr (param->name, ==, "object"); g_assert_cmpuint (param->flags, ==, TP_CONN_MGR_PARAM_FLAG_HAS_DEFAULT); g_assert_cmpstr (param->dbus_signature, ==, "o"); g_assert (G_VALUE_HOLDS (¶m->default_value, DBUS_TYPE_G_OBJECT_PATH)); g_assert_cmpstr (g_value_get_boxed (¶m->default_value), ==, "/misc"); param = &protocol->params[11]; g_assert_cmpstr (param->name, ==, "q"); g_assert_cmpuint (param->flags, ==, TP_CONN_MGR_PARAM_FLAG_HAS_DEFAULT); g_assert_cmpstr (param->dbus_signature, ==, "q"); g_assert (G_VALUE_HOLDS_UINT (¶m->default_value)); g_assert_cmpint (g_value_get_uint (¶m->default_value), ==, 42); param = &protocol->params[12]; g_assert_cmpstr (param->name, ==, "u"); g_assert_cmpuint (param->flags, ==, TP_CONN_MGR_PARAM_FLAG_HAS_DEFAULT); g_assert_cmpstr (param->dbus_signature, ==, "u"); g_assert (G_VALUE_HOLDS_UINT (¶m->default_value)); g_assert_cmpint (g_value_get_uint (¶m->default_value), ==, 42); param = &protocol->params[13]; g_assert_cmpstr (param->name, ==, "t"); g_assert_cmpuint (param->flags, ==, TP_CONN_MGR_PARAM_FLAG_HAS_DEFAULT); g_assert_cmpstr (param->dbus_signature, ==, "t"); g_assert (G_VALUE_HOLDS_UINT64 (¶m->default_value)); g_assert_cmpuint ((guint) g_value_get_uint64 (¶m->default_value), ==, 42); param = &protocol->params[14]; g_assert_cmpstr (param->name, ==, "n"); g_assert_cmpuint (param->flags, ==, TP_CONN_MGR_PARAM_FLAG_HAS_DEFAULT); g_assert_cmpstr (param->dbus_signature, ==, "n"); g_assert (G_VALUE_HOLDS_INT (¶m->default_value)); g_assert_cmpint (g_value_get_int (¶m->default_value), ==, -42); param = &protocol->params[15]; g_assert_cmpstr (param->name, ==, "i"); g_assert_cmpuint (param->flags, ==, TP_CONN_MGR_PARAM_FLAG_HAS_DEFAULT); g_assert_cmpstr (param->dbus_signature, ==, "i"); g_assert (G_VALUE_HOLDS_INT (¶m->default_value)); g_assert_cmpint (g_value_get_int (¶m->default_value), ==, -42); param = &protocol->params[16]; g_assert_cmpstr (param->name, ==, "x"); g_assert_cmpuint (param->flags, ==, TP_CONN_MGR_PARAM_FLAG_HAS_DEFAULT); g_assert_cmpstr (param->dbus_signature, ==, "x"); g_assert (G_VALUE_HOLDS_INT64 (¶m->default_value)); g_assert_cmpint ((int) g_value_get_int64 (¶m->default_value), ==, -42); param = &protocol->params[17]; g_assert_cmpstr (param->name, ==, "d"); g_assert_cmpuint (param->flags, ==, TP_CONN_MGR_PARAM_FLAG_HAS_DEFAULT); g_assert_cmpstr (param->dbus_signature, ==, "d"); g_assert (G_VALUE_HOLDS_DOUBLE (¶m->default_value)); param = &protocol->params[18]; g_assert_cmpstr (param->name, ==, "empty-string-in-list"); g_assert_cmpuint (param->flags, ==, TP_CONN_MGR_PARAM_FLAG_HAS_DEFAULT); g_assert_cmpstr (param->dbus_signature, ==, "as"); g_assert (G_VALUE_HOLDS (¶m->default_value, G_TYPE_STRV)); strv = g_value_get_boxed (¶m->default_value); g_assert_cmpstr (strv[0], ==, ""); g_assert (strv[1] == NULL); param = &protocol->params[19]; g_assert_cmpstr (param->name, ==, "true"); g_assert_cmpuint (param->flags, ==, TP_CONN_MGR_PARAM_FLAG_HAS_DEFAULT); g_assert_cmpstr (param->dbus_signature, ==, "b"); g_assert (G_VALUE_HOLDS_BOOLEAN (¶m->default_value)); g_assert_cmpint (g_value_get_boolean (¶m->default_value), ==, TRUE); param = &protocol->params[20]; g_assert_cmpstr (param->name, ==, "false"); g_assert_cmpuint (param->flags, ==, TP_CONN_MGR_PARAM_FLAG_HAS_DEFAULT); g_assert_cmpstr (param->dbus_signature, ==, "b"); g_assert (G_VALUE_HOLDS_BOOLEAN (¶m->default_value)); g_assert_cmpint (g_value_get_boolean (¶m->default_value), ==, FALSE); param = &protocol->params[21]; g_assert_cmpstr (param->name, ==, "y"); g_assert_cmpuint (param->flags, ==, TP_CONN_MGR_PARAM_FLAG_HAS_DEFAULT); g_assert_cmpstr (param->dbus_signature, ==, "y"); g_assert (G_VALUE_HOLDS_UCHAR (¶m->default_value)); g_assert_cmpint (g_value_get_uchar (¶m->default_value), ==, 42); param = &protocol->params[22]; g_assert_cmpstr (param->name, ==, "ao"); g_assert_cmpuint (param->flags, ==, TP_CONN_MGR_PARAM_FLAG_HAS_DEFAULT); g_assert_cmpstr (param->dbus_signature, ==, "ao"); g_assert (G_VALUE_HOLDS (¶m->default_value, TP_ARRAY_TYPE_OBJECT_PATH_LIST)); arr = g_value_get_boxed (¶m->default_value); g_assert_cmpuint (arr->len, ==, 2); g_assert_cmpstr ((gchar *) g_ptr_array_index (arr, 0), ==, "/misc"); g_assert_cmpstr ((gchar *) g_ptr_array_index (arr, 1), ==, "/other"); param = &protocol->params[23]; g_assert (param->name == NULL); } static void on_got_info_expect_live (TpConnectionManager *self, guint info_source, gpointer p) { Test *test = p; g_assert (self == test->cm); g_assert_cmpuint (info_source, ==, TP_CM_INFO_SOURCE_LIVE); g_assert_cmpuint (info_source, ==, test->cm->info_source); g_main_loop_quit (test->mainloop); } static void test_dbus_got_info (Test *test, gconstpointer data) { GError *error = NULL; gulong id; test->cm = tp_connection_manager_new (test->dbus, TP_BASE_CONNECTION_MANAGER_GET_CLASS (test->service_cm)->cm_dbus_name, NULL, &error); g_assert (TP_IS_CONNECTION_MANAGER (test->cm)); g_assert_no_error (error); g_test_bug ("18207"); id = g_signal_connect (test->cm, "got-info", G_CALLBACK (on_got_info_expect_live), test); g_main_loop_run (test->mainloop); g_signal_handler_disconnect (test->cm, id); } static void ready_or_not (TpConnectionManager *self, const GError *error, gpointer user_data, GObject *weak_object G_GNUC_UNUSED) { Test *test = user_data; if (error != NULL) test->error = g_error_copy (error); g_main_loop_quit (test->mainloop); } static void test_nothing_ready (Test *test, gconstpointer data) { gchar *name; guint info_source; TestFlags flags = GPOINTER_TO_INT (data); test->error = NULL; test->cm = tp_connection_manager_new (test->dbus, "nonexistent_cm", NULL, &test->error); g_assert (TP_IS_CONNECTION_MANAGER (test->cm)); g_assert_no_error (test->error); g_test_bug ("18291"); if (flags & USE_CWR) { tp_connection_manager_call_when_ready (test->cm, ready_or_not, test, NULL, NULL); g_main_loop_run (test->mainloop); g_assert (test->error != NULL); g_clear_error (&test->error); } else { tp_tests_proxy_run_until_prepared_or_failed (test->cm, NULL, &test->error); g_assert_error (test->error, DBUS_GERROR, DBUS_GERROR_SERVICE_UNKNOWN); } g_assert_cmpstr (tp_connection_manager_get_name (test->cm), ==, "nonexistent_cm"); g_assert_cmpuint (tp_connection_manager_is_ready (test->cm), ==, FALSE); g_assert_cmpuint (tp_proxy_is_prepared (test->cm, TP_CONNECTION_MANAGER_FEATURE_CORE), ==, FALSE); g_assert (tp_proxy_get_invalidated (test->cm) == NULL); g_assert_cmpuint (tp_connection_manager_is_running (test->cm), ==, FALSE); g_assert_cmpuint (tp_connection_manager_get_info_source (test->cm), ==, TP_CM_INFO_SOURCE_NONE); g_object_get (test->cm, "info-source", &info_source, "cm-name", &name, NULL); g_assert_cmpstr (name, ==, "nonexistent_cm"); g_assert_cmpuint (info_source, ==, TP_CM_INFO_SOURCE_NONE); g_free (name); } static void test_file_ready (Test *test, gconstpointer data) { gchar *name; guint info_source; TestFlags flags = GPOINTER_TO_INT (data); GList *l; test->error = NULL; test->cm = tp_connection_manager_new (test->dbus, "spurious", NULL, &test->error); g_assert (TP_IS_CONNECTION_MANAGER (test->cm)); g_assert_no_error (test->error); g_test_bug ("18291"); if (flags & USE_CWR) { tp_connection_manager_call_when_ready (test->cm, ready_or_not, test, NULL, NULL); g_main_loop_run (test->mainloop); g_assert_no_error (test->error); } else { tp_tests_proxy_run_until_prepared (test->cm, NULL); } g_assert_cmpstr (tp_connection_manager_get_name (test->cm), ==, "spurious"); g_assert_cmpuint (tp_connection_manager_is_ready (test->cm), ==, TRUE); g_assert_cmpuint (tp_connection_manager_is_running (test->cm), ==, FALSE); g_assert_cmpuint (tp_proxy_is_prepared (test->cm, TP_CONNECTION_MANAGER_FEATURE_CORE), ==, TRUE); g_assert (tp_proxy_get_invalidated (test->cm) == NULL); g_assert_cmpuint (tp_connection_manager_get_info_source (test->cm), ==, TP_CM_INFO_SOURCE_FILE); g_object_get (test->cm, "info-source", &info_source, "cm-name", &name, NULL); g_assert_cmpstr (name, ==, "spurious"); g_assert_cmpuint (info_source, ==, TP_CM_INFO_SOURCE_FILE); g_free (name); l = tp_connection_manager_dup_protocols (test->cm); g_assert_cmpuint (g_list_length (l), ==, 2); g_assert (TP_IS_PROTOCOL (l->data)); g_assert (TP_IS_PROTOCOL (l->next->data)); g_list_free_full (l, g_object_unref); } static void test_complex_file_ready (Test *test, gconstpointer data) { gchar *name; guint info_source; TestFlags flags = GPOINTER_TO_INT (data); test->error = NULL; test->cm = tp_connection_manager_new (test->dbus, "test_manager_file", NULL, &test->error); g_assert (TP_IS_CONNECTION_MANAGER (test->cm)); g_assert_no_error (test->error); g_test_bug ("18291"); if (flags & USE_CWR) { tp_connection_manager_call_when_ready (test->cm, ready_or_not, test, NULL, NULL); g_main_loop_run (test->mainloop); g_assert_no_error (test->error); } else { tp_tests_proxy_run_until_prepared (test->cm, NULL); } g_assert_cmpstr (tp_connection_manager_get_name (test->cm), ==, "test_manager_file"); g_assert_cmpuint (tp_proxy_is_prepared (test->cm, TP_CONNECTION_MANAGER_FEATURE_CORE), ==, TRUE); g_assert (tp_proxy_get_invalidated (test->cm) == NULL); g_assert_cmpuint (tp_connection_manager_is_ready (test->cm), ==, TRUE); g_assert_cmpuint (tp_connection_manager_is_running (test->cm), ==, FALSE); g_assert_cmpuint (tp_connection_manager_get_info_source (test->cm), ==, TP_CM_INFO_SOURCE_FILE); g_object_get (test->cm, "info-source", &info_source, "cm-name", &name, NULL); g_assert_cmpstr (name, ==, "test_manager_file"); g_assert_cmpuint (info_source, ==, TP_CM_INFO_SOURCE_FILE); g_free (name); } static gboolean idle_activate (gpointer cm) { tp_connection_manager_activate (cm); return FALSE; } static void test_dbus_ready (Test *test, gconstpointer data) { gchar *name; guint info_source; const TestFlags flags = GPOINTER_TO_INT (data); GList *l; test->error = NULL; test->cm = tp_connection_manager_new (test->dbus, TP_BASE_CONNECTION_MANAGER_GET_CLASS (test->service_cm)->cm_dbus_name, NULL, &test->error); g_assert (TP_IS_CONNECTION_MANAGER (test->cm)); g_assert_no_error (test->error); if (flags & NO_PROPERTIES) test->service_cm->implement_properties = FALSE; if (flags & DROP_NAME_ON_GET_TWICE) { test->service_cm->drop_name_on_get = 2; } else if (flags & DROP_NAME_ON_GET) { test->service_cm->drop_name_on_get = 1; } if (flags & ACTIVATE_CM) { g_test_bug ("23524"); /* The bug being tested here was caused by ListProtocols being called * twice on the same CM; this can be triggered by _activate()ing at * exactly the wrong moment. But the wrong moment involves racing an * idle. This triggered the assertion about 1/3 of the time on my laptop. * --wjt */ g_idle_add (idle_activate, test->cm); } else { g_test_bug ("18291"); } if (flags & USE_CWR) { tp_connection_manager_call_when_ready (test->cm, ready_or_not, test, NULL, NULL); g_main_loop_run (test->mainloop); g_assert_no_error (test->error); } else { tp_tests_proxy_run_until_prepared_or_failed (test->cm, NULL, &test->error); } g_assert_cmpstr (tp_connection_manager_get_name (test->cm), ==, "example_echo"); if (flags & DROP_NAME_ON_GET_TWICE) { /* If it dies during introspection *twice*, we assume it has crashed * or something. */ g_assert_error (test->error, TP_DBUS_ERRORS, TP_DBUS_ERROR_NAME_OWNER_LOST); g_clear_error (&test->error); g_assert_cmpuint (tp_proxy_is_prepared (test->cm, TP_CONNECTION_MANAGER_FEATURE_CORE), ==, FALSE); g_assert_cmpuint (tp_connection_manager_is_ready (test->cm), ==, FALSE); g_assert_cmpuint (tp_connection_manager_get_info_source (test->cm), ==, TP_CM_INFO_SOURCE_NONE); return; } g_assert_no_error (test->error); g_assert_cmpuint (tp_proxy_is_prepared (test->cm, TP_CONNECTION_MANAGER_FEATURE_CORE), ==, TRUE); g_assert (tp_proxy_get_invalidated (test->cm) == NULL); g_assert_cmpuint (tp_connection_manager_is_ready (test->cm), ==, TRUE); g_assert_cmpuint (tp_connection_manager_is_running (test->cm), ==, TRUE); g_assert_cmpuint (tp_connection_manager_get_info_source (test->cm), ==, TP_CM_INFO_SOURCE_LIVE); g_object_get (test->cm, "info-source", &info_source, "cm-name", &name, NULL); g_assert_cmpstr (name, ==, "example_echo"); g_assert_cmpuint (info_source, ==, TP_CM_INFO_SOURCE_LIVE); g_free (name); l = tp_connection_manager_dup_protocols (test->cm); g_assert_cmpuint (g_list_length (l), ==, 1); g_assert_cmpstr (tp_protocol_get_name (l->data), ==, "example"); g_list_free_full (l, g_object_unref); } static void on_listed_connection_managers (TpConnectionManager * const * cms, gsize n_cms, const GError *error, gpointer user_data, GObject *weak_object G_GNUC_UNUSED) { Test *test = user_data; g_assert_cmpuint ((guint) n_cms, ==, 2); g_assert (cms[2] == NULL); if (tp_connection_manager_is_running (cms[0])) { test->echo = g_object_ref (cms[0]); test->spurious = g_object_ref (cms[1]); } else { test->spurious = g_object_ref (cms[0]); test->echo = g_object_ref (cms[1]); } g_main_loop_quit (test->mainloop); } static void test_list (Test *test, gconstpointer data) { TestFlags flags = GPOINTER_TO_INT (data); if (flags & USE_OLD_LIST) { tp_list_connection_managers (test->dbus, on_listed_connection_managers, test, NULL, NULL); g_main_loop_run (test->mainloop); } else { GAsyncResult *res = NULL; GList *cms; tp_list_connection_managers_async (test->dbus, tp_tests_result_ready_cb, &res); tp_tests_run_until_result (&res); cms = tp_list_connection_managers_finish (res, &test->error); g_assert_no_error (test->error); g_assert_cmpuint (g_list_length (cms), ==, 2); /* transfer ownership */ if (tp_connection_manager_is_running (cms->data)) { test->echo = cms->data; test->spurious = cms->next->data; } else { test->spurious = cms->data; test->echo = cms->next->data; } g_object_unref (res); g_list_free (cms); } g_assert (tp_connection_manager_is_running (test->echo)); g_assert (!tp_connection_manager_is_running (test->spurious)); g_assert (tp_proxy_is_prepared (test->echo, TP_CONNECTION_MANAGER_FEATURE_CORE)); g_assert (tp_proxy_is_prepared (test->spurious, TP_CONNECTION_MANAGER_FEATURE_CORE)); g_assert (tp_proxy_get_invalidated (test->echo) == NULL); g_assert (tp_proxy_get_invalidated (test->spurious) == NULL); g_assert (tp_connection_manager_is_ready (test->echo)); g_assert (tp_connection_manager_is_ready (test->spurious)); g_assert_cmpuint (tp_connection_manager_get_info_source (test->echo), ==, TP_CM_INFO_SOURCE_LIVE); g_assert_cmpuint (tp_connection_manager_get_info_source (test->spurious), ==, TP_CM_INFO_SOURCE_FILE); g_assert (tp_connection_manager_has_protocol (test->echo, "example")); g_assert (tp_connection_manager_has_protocol (test->spurious, "normal")); } int main (int argc, char **argv) { tp_tests_init (&argc, &argv); g_test_bug_base ("http://bugs.freedesktop.org/show_bug.cgi?id="); g_test_add_func ("/cm/valid-name", test_valid_name); g_test_add ("/cm/nothing (old)", Test, NULL, setup, test_nothing_got_info, teardown); g_test_add ("/cm/file (old)", Test, NULL, setup, test_file_got_info, teardown); g_test_add ("/cm/file (old, complex)", Test, NULL, setup, test_complex_file_got_info, teardown); g_test_add ("/cm/dbus (old)", Test, NULL, setup, test_dbus_got_info, teardown); g_test_add ("/cm/nothing", Test, GINT_TO_POINTER (0), setup, test_nothing_ready, teardown); g_test_add ("/cm/nothing/cwr", Test, GINT_TO_POINTER (USE_CWR), setup, test_nothing_ready, teardown); g_test_add ("/cm/file", Test, GINT_TO_POINTER (0), setup, test_file_ready, teardown); g_test_add ("/cm/file/cwr", Test, GINT_TO_POINTER (USE_CWR), setup, test_file_ready, teardown); g_test_add ("/cm/file/complex", Test, GINT_TO_POINTER (0), setup, test_complex_file_ready, teardown); g_test_add ("/cm/file/complex/cwr", Test, GINT_TO_POINTER (USE_CWR), setup, test_complex_file_ready, teardown); g_test_add ("/cm/dbus", Test, GINT_TO_POINTER (0), setup, test_dbus_ready, teardown); g_test_add ("/cm/dbus/cwr", Test, GINT_TO_POINTER (USE_CWR), setup, test_dbus_ready, teardown); g_test_add ("/cm/dbus/activate", Test, GINT_TO_POINTER (ACTIVATE_CM), setup, test_dbus_ready, teardown); g_test_add ("/cm/dbus/activate/cwr", Test, GINT_TO_POINTER (USE_CWR|ACTIVATE_CM), setup, test_dbus_ready, teardown); g_test_add ("/cm/dbus-fallback", Test, GINT_TO_POINTER (NO_PROPERTIES), setup, test_dbus_ready, teardown); g_test_add ("/cm/dbus-fallback/cwr", Test, GINT_TO_POINTER (NO_PROPERTIES | USE_CWR), setup, test_dbus_ready, teardown); g_test_add ("/cm/dbus-fallback/activate", Test, GINT_TO_POINTER (NO_PROPERTIES | ACTIVATE_CM), setup, test_dbus_ready, teardown); g_test_add ("/cm/dbus-fallback/activate/cwr", Test, GINT_TO_POINTER (NO_PROPERTIES | ACTIVATE_CM | USE_CWR), setup, test_dbus_ready, teardown); g_test_add ("/cm/dbus/dies", Test, GINT_TO_POINTER (DROP_NAME_ON_GET), setup, test_dbus_ready, teardown); g_test_add ("/cm/dbus-fallback/dies", Test, GINT_TO_POINTER (NO_PROPERTIES | DROP_NAME_ON_GET), setup, test_dbus_ready, teardown); g_test_add ("/cm/dbus/dies-twice", Test, GINT_TO_POINTER (DROP_NAME_ON_GET_TWICE), setup, test_dbus_ready, teardown); g_test_add ("/cm/dbus-fallback/dies-twice", Test, GINT_TO_POINTER (NO_PROPERTIES | DROP_NAME_ON_GET_TWICE), setup, test_dbus_ready, teardown); g_test_add ("/cm/list", Test, GINT_TO_POINTER (0), setup, test_list, teardown); g_test_add ("/cm/list", Test, GINT_TO_POINTER (USE_OLD_LIST), setup, test_list, teardown); return tp_tests_run_with_bus (); }