/* Tests of TpBaseClient * * Copyright © 2010-2011 Collabora Ltd. * * 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/util.h" #include "tests/lib/simple-account.h" #include "tests/lib/simple-conn.h" #include "tests/lib/my-conn-proxy.h" typedef struct { GMainLoop *mainloop; TpDBusDaemon *dbus; /* Service side objects */ TpBaseConnection *base_connection; /* Client side objects */ TpConnection *connection; TpTestsMyConnProxy *my_conn; GError *error /* initialized where needed */; gint wait; } Test; static void setup (Test *test, gconstpointer data) { test->mainloop = g_main_loop_new (NULL, FALSE); test->dbus = tp_tests_dbus_daemon_dup_or_die (); test->error = NULL; /* Create (service and client sides) connection objects */ tp_tests_create_and_connect_conn (TP_TESTS_TYPE_SIMPLE_CONNECTION, "me@test.com", &test->base_connection, &test->connection); test->my_conn = g_object_new (TP_TESTS_TYPE_MY_CONN_PROXY, "dbus-daemon", test->dbus, "bus-name", tp_proxy_get_bus_name (test->connection), "object-path", tp_proxy_get_object_path (test->connection), NULL); } static void disconnect_and_destroy_conn (Test *test) { tp_tests_connection_assert_disconnect_succeeds ( TP_CONNECTION (test->my_conn)); tp_clear_object (&test->connection); tp_clear_object (&test->base_connection); tp_clear_object (&test->my_conn); } static void teardown (Test *test, gconstpointer data) { g_clear_error (&test->error); tp_clear_object (&test->dbus); g_main_loop_unref (test->mainloop); test->mainloop = NULL; disconnect_and_destroy_conn (test); } static void prepare_cb (GObject *source, GAsyncResult *result, gpointer user_data) { Test *test = user_data; tp_proxy_prepare_finish (TP_PROXY (source), result, &test->error); test->wait--; if (test->wait <= 0) g_main_loop_quit (test->mainloop); } static void test_prepare_capabilities (Test *test, gconstpointer data G_GNUC_UNUSED) { /* Prepare capabilities on a new proxy. CORE should be automatically prepared * *before* checking if Requests is implemented as * tp_proxy_has_interface_by_id() can't work without CORE. */ GQuark features[] = { TP_CONNECTION_FEATURE_CAPABILITIES, 0 }; tp_proxy_prepare_async (test->my_conn, features, prepare_cb, test); g_main_loop_run (test->mainloop); g_assert_no_error (test->error); g_assert (tp_proxy_is_prepared (test->my_conn, TP_CONNECTION_FEATURE_CORE)); g_assert (tp_proxy_is_prepared (test->my_conn, TP_CONNECTION_FEATURE_CAPABILITIES)); } static void test_prepare_core (Test *test, gconstpointer data G_GNUC_UNUSED) { /* Test than preparing the 'top' core feature prepare the other core * features as well */ GQuark features[] = { TP_TESTS_MY_CONN_PROXY_FEATURE_CORE, 0 }; tp_proxy_prepare_async (test->my_conn, features, prepare_cb, test); g_main_loop_run (test->mainloop); g_assert_no_error (test->error); g_assert (tp_proxy_is_prepared (test->my_conn, TP_TESTS_MY_CONN_PROXY_FEATURE_CORE)); g_assert (tp_proxy_is_prepared (test->my_conn, TP_CONNECTION_FEATURE_CORE)); g_assert (!tp_proxy_is_prepared (test->my_conn, TP_CONNECTION_FEATURE_CAPABILITIES)); } static void test_depends (Test *test, gconstpointer data G_GNUC_UNUSED) { /* Test if A is automatically prepared when preparing B */ GQuark features[] = { TP_TESTS_MY_CONN_PROXY_FEATURE_B, 0 }; tp_proxy_prepare_async (test->my_conn, features, prepare_cb, test); g_main_loop_run (test->mainloop); g_assert_no_error (test->error); g_assert (tp_proxy_is_prepared (test->my_conn, TP_TESTS_MY_CONN_PROXY_FEATURE_CORE)); g_assert (tp_proxy_is_prepared (test->my_conn, TP_TESTS_MY_CONN_PROXY_FEATURE_A)); g_assert (tp_proxy_is_prepared (test->my_conn, TP_TESTS_MY_CONN_PROXY_FEATURE_B)); } static void test_wrong_iface (Test *test, gconstpointer data G_GNUC_UNUSED) { /* Feature can't be prepared because proxy doesn't support the right * interface */ GQuark features[] = { TP_TESTS_MY_CONN_PROXY_FEATURE_WRONG_IFACE, 0 }; tp_proxy_prepare_async (test->my_conn, features, prepare_cb, test); g_main_loop_run (test->mainloop); g_assert_no_error (test->error); g_assert (tp_proxy_is_prepared (test->my_conn, TP_TESTS_MY_CONN_PROXY_FEATURE_CORE)); g_assert (!tp_proxy_is_prepared (test->my_conn, TP_TESTS_MY_CONN_PROXY_FEATURE_WRONG_IFACE)); } static void test_bad_dep (Test *test, gconstpointer data G_GNUC_UNUSED) { /* Feature can't be prepared because it depends on an unpreparable * feature */ GQuark features[] = { TP_TESTS_MY_CONN_PROXY_FEATURE_BAD_DEP, 0 }; tp_proxy_prepare_async (test->my_conn, features, prepare_cb, test); g_main_loop_run (test->mainloop); g_assert_no_error (test->error); g_assert (tp_proxy_is_prepared (test->my_conn, TP_TESTS_MY_CONN_PROXY_FEATURE_CORE)); g_assert (!tp_proxy_is_prepared (test->my_conn, TP_TESTS_MY_CONN_PROXY_FEATURE_WRONG_IFACE)); g_assert (!tp_proxy_is_prepared (test->my_conn, TP_TESTS_MY_CONN_PROXY_FEATURE_BAD_DEP)); } static void test_fail (Test *test, gconstpointer data G_GNUC_UNUSED) { /* Feature preparation fails */ GQuark features[] = { TP_TESTS_MY_CONN_PROXY_FEATURE_FAIL, 0 }; tp_proxy_prepare_async (test->my_conn, features, prepare_cb, test); g_main_loop_run (test->mainloop); g_assert_no_error (test->error); g_assert (tp_proxy_is_prepared (test->my_conn, TP_TESTS_MY_CONN_PROXY_FEATURE_CORE)); g_assert (!tp_proxy_is_prepared (test->my_conn, TP_TESTS_MY_CONN_PROXY_FEATURE_FAIL)); } static void test_fail_dep (Test *test, gconstpointer data G_GNUC_UNUSED) { /* Feature can't be prepared because its deps can't be prepared */ GQuark features[] = { TP_TESTS_MY_CONN_PROXY_FEATURE_FAIL_DEP, 0 }; tp_proxy_prepare_async (test->my_conn, features, prepare_cb, test); g_main_loop_run (test->mainloop); g_assert_no_error (test->error); g_assert (tp_proxy_is_prepared (test->my_conn, TP_TESTS_MY_CONN_PROXY_FEATURE_CORE)); g_assert (!tp_proxy_is_prepared (test->my_conn, TP_TESTS_MY_CONN_PROXY_FEATURE_FAIL)); g_assert (!tp_proxy_is_prepared (test->my_conn, TP_TESTS_MY_CONN_PROXY_FEATURE_FAIL_DEP)); } static void test_retry (Test *test, gconstpointer data G_GNUC_UNUSED) { /* We have the prepare the feature twice */ GQuark features[] = { TP_TESTS_MY_CONN_PROXY_FEATURE_RETRY, 0 }; tp_proxy_prepare_async (test->my_conn, features, prepare_cb, test); g_main_loop_run (test->mainloop); g_assert_no_error (test->error); g_assert (tp_proxy_is_prepared (test->my_conn, TP_TESTS_MY_CONN_PROXY_FEATURE_CORE)); g_assert (!tp_proxy_is_prepared (test->my_conn, TP_TESTS_MY_CONN_PROXY_FEATURE_RETRY)); /* second attempt */ test->my_conn->retry_feature_success = TRUE; tp_proxy_prepare_async (test->my_conn, features, prepare_cb, test); g_main_loop_run (test->mainloop); g_assert_no_error (test->error); g_assert (tp_proxy_is_prepared (test->my_conn, TP_TESTS_MY_CONN_PROXY_FEATURE_CORE)); g_assert (tp_proxy_is_prepared (test->my_conn, TP_TESTS_MY_CONN_PROXY_FEATURE_RETRY)); } static void test_retry_dep (Test *test, gconstpointer data G_GNUC_UNUSED) { /* RETRY_DEP depends on a feature having can_retry and which failed, so * preparing RETRY_DEP will re-prepare it successfully */ GQuark features_retry[] = { TP_TESTS_MY_CONN_PROXY_FEATURE_RETRY, 0 }; GQuark features_retry_dep[] = { TP_TESTS_MY_CONN_PROXY_FEATURE_RETRY_DEP, 0 }; /* Try preparing TP_TESTS_MY_CONN_PROXY_FEATURE_RETRY, will fail */ tp_proxy_prepare_async (test->my_conn, features_retry, prepare_cb, test); g_main_loop_run (test->mainloop); g_assert_no_error (test->error); g_assert (tp_proxy_is_prepared (test->my_conn, TP_TESTS_MY_CONN_PROXY_FEATURE_CORE)); g_assert (!tp_proxy_is_prepared (test->my_conn, TP_TESTS_MY_CONN_PROXY_FEATURE_RETRY)); g_assert (!tp_proxy_is_prepared (test->my_conn, TP_TESTS_MY_CONN_PROXY_FEATURE_RETRY_DEP)); /* Try prepare TP_TESTS_MY_CONN_PROXY_FEATURE_RETRY_DEP, will re-prepare * TP_TESTS_MY_CONN_PROXY_FEATURE_RETRY */ test->my_conn->retry_feature_success = TRUE; tp_proxy_prepare_async (test->my_conn, features_retry_dep, prepare_cb, test); g_main_loop_run (test->mainloop); g_assert_no_error (test->error); g_assert (tp_proxy_is_prepared (test->my_conn, TP_TESTS_MY_CONN_PROXY_FEATURE_CORE)); g_assert (tp_proxy_is_prepared (test->my_conn, TP_TESTS_MY_CONN_PROXY_FEATURE_RETRY)); g_assert (tp_proxy_is_prepared (test->my_conn, TP_TESTS_MY_CONN_PROXY_FEATURE_RETRY_DEP)); } static void recreate_connection (Test *test) { gchar *name; gchar *conn_path; disconnect_and_destroy_conn (test); test->base_connection = tp_tests_object_new_static_class ( TP_TESTS_TYPE_SIMPLE_CONNECTION, "account", "me@test.com", "protocol", "simple", NULL); g_assert (test->base_connection != NULL); g_assert (tp_base_connection_register (test->base_connection, "simple", &name, &conn_path, &test->error)); g_assert_no_error (test->error); test->connection = tp_connection_new (test->dbus, name, conn_path, &test->error); g_assert_no_error (test->error); test->my_conn = g_object_new (TP_TESTS_TYPE_MY_CONN_PROXY, "dbus-daemon", test->dbus, "bus-name", tp_proxy_get_bus_name (test->connection), "object-path", tp_proxy_get_object_path (test->connection), NULL); g_assert (test->my_conn != NULL); g_free (name); g_free (conn_path); } static void test_before_connected (Test *test, gconstpointer data G_GNUC_UNUSED) { GQuark features[] = { TP_TESTS_MY_CONN_PROXY_FEATURE_BEFORE_CONNECTED, 0 }; GQuark connected[] = { TP_CONNECTION_FEATURE_CONNECTED, 0 }; /* We need a not yet connected connection */ recreate_connection (test); g_assert_cmpuint (test->my_conn->before_connected_state, ==, BEFORE_CONNECTED_STATE_UNPREPARED); /* Connection is not yet connected, prepare the feature */ tp_proxy_prepare_async (test->my_conn, features, prepare_cb, test); g_main_loop_run (test->mainloop); g_assert_no_error (test->error); g_assert (tp_proxy_is_prepared (test->my_conn, TP_TESTS_MY_CONN_PROXY_FEATURE_BEFORE_CONNECTED)); g_assert_cmpuint (test->my_conn->before_connected_state, ==, BEFORE_CONNECTED_STATE_NOT_CONNECTED); tp_cli_connection_call_connect (test->connection, -1, NULL, NULL, NULL, NULL); /* Wait that CONNECTED is announced */ tp_proxy_prepare_async (test->my_conn, connected, prepare_cb, test); g_main_loop_run (test->mainloop); g_assert_no_error (test->error); /* state has been updated */ g_assert_cmpuint (test->my_conn->before_connected_state, ==, BEFORE_CONNECTED_STATE_CONNECTED); } static void test_interface_later (Test *test, gconstpointer data G_GNUC_UNUSED) { GQuark features[] = { TP_TESTS_MY_CONN_PROXY_FEATURE_INTERFACE_LATER, 0 }; GQuark connected[] = { TP_CONNECTION_FEATURE_CONNECTED, 0 }; const gchar *interfaces[] = { TP_TESTS_MY_CONN_PROXY_IFACE_LATER, NULL }; /* We need a not yet connected connection */ recreate_connection (test); /* Try preparing before the connection is connected */ tp_proxy_prepare_async (test->my_conn, features, prepare_cb, test); g_main_loop_run (test->mainloop); g_assert_no_error (test->error); /* Feature isn't prepared */ g_assert (!tp_proxy_is_prepared (test->my_conn, TP_TESTS_MY_CONN_PROXY_FEATURE_INTERFACE_LATER)); tp_cli_connection_call_connect (test->connection, -1, NULL, NULL, NULL, NULL); /* While connecting the interface is added */ tp_base_connection_add_interfaces (test->base_connection, interfaces); /* Wait that CONNECTED is announced */ tp_proxy_prepare_async (test->my_conn, connected, prepare_cb, test); g_main_loop_run (test->mainloop); g_assert_no_error (test->error); /* The feature has been prepared now */ g_assert (tp_proxy_is_prepared (test->my_conn, TP_TESTS_MY_CONN_PROXY_FEATURE_INTERFACE_LATER)); } 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 ("/proxy-preparation/prepare-capabilities", Test, NULL, setup, test_prepare_capabilities, teardown); g_test_add ("/proxy-preparation/prepare-core", Test, NULL, setup, test_prepare_core, teardown); g_test_add ("/proxy-preparation/depends", Test, NULL, setup, test_depends, teardown); g_test_add ("/proxy-preparation/wrong-iface", Test, NULL, setup, test_wrong_iface, teardown); g_test_add ("/proxy-preparation/bad-dep", Test, NULL, setup, test_bad_dep, teardown); g_test_add ("/proxy-preparation/fail", Test, NULL, setup, test_fail, teardown); g_test_add ("/proxy-preparation/fail-dep", Test, NULL, setup, test_fail_dep, teardown); g_test_add ("/proxy-preparation/retry", Test, NULL, setup, test_retry, teardown); g_test_add ("/proxy-preparation/retry-dep", Test, NULL, setup, test_retry_dep, teardown); g_test_add ("/proxy-preparation/before-connected", Test, NULL, setup, test_before_connected, teardown); g_test_add ("/proxy-preparation/interface-later", Test, NULL, setup, test_interface_later, teardown); return tp_tests_run_with_bus (); }