[telepathy-glib/master] Re-usable test functions.
David Laban
david.laban at collabora.co.uk
Tue Nov 10 18:04:16 PST 2009
I found that I was wanting to execute the same test functions one after
another. This can't be done asyncronously unless you pass a list of functions
around which can be called when events happen.
This framework allows me to test tp_account_prepare by first creating an
account manager, and then using it to create an account.
I also made some whitespace-only changes to conform to the style guide.
---
tests/dbus/account-manager.c | 263 +++++++++++++++++++++++++++++++++++-------
1 files changed, 219 insertions(+), 44 deletions(-)
diff --git a/tests/dbus/account-manager.c b/tests/dbus/account-manager.c
index 28291b3..539ee4f 100644
--- a/tests/dbus/account-manager.c
+++ b/tests/dbus/account-manager.c
@@ -15,18 +15,62 @@
#include "tests/lib/simple-account-manager.h"
typedef struct {
+ GFunc action;
+ gpointer user_data;
+} ScriptAction;
+
+typedef struct {
GMainLoop *mainloop;
TpDBusDaemon *dbus;
DBusGConnection *bus;
SimpleAccountManager *service /* initialized in prepare_service */;
TpAccountManager *am;
+ TpAccount *account;
gboolean prepared /* The result of prepare_finish */;
guint timeout_id;
+ GList *script /* A list of GAsyncReadyCallback */;
GError *error /* initialized where needed */;
} Test;
+/**
+ * Functions for manipulating scripts follow this comment.
+ * In order to be generally useful, the script should probably be stored in its
+ * own data structure, rather than passed around with the test, and the
+ * user_data argument would need to be the test or something. As it is, these
+ * library-like functions rely on being defined after the Test struct.
+ */
+static ScriptAction *
+script_action_new (GFunc action,
+ gpointer data)
+{
+ ScriptAction *script_action = g_new (ScriptAction, 1);
+ script_action->action = action;
+ script_action->user_data = data;
+ return script_action;
+}
+
+static void
+script_append_action (Test *test,
+ GFunc action,
+ gpointer data)
+{
+ test->script = g_list_append (test->script,
+ script_action_new (action, data));
+}
+
+static void
+script_continue (gpointer script_data)
+{
+ Test *test = (Test *) script_data;
+ ScriptAction *action;
+ /* pop the previous action */
+ test->script = g_list_remove (test->script, test->script->data);
+ action = (ScriptAction *) test->script->data;
+ action->action (script_data, action->user_data);
+}
+
static gboolean
test_timed_out (gpointer data)
{
@@ -44,8 +88,32 @@ test_timed_out (gpointer data)
}
static void
+quit_action (gpointer script_data,
+ gpointer user_data G_GNUC_UNUSED)
+{
+ Test *test = (Test *) script_data;
+ g_main_loop_quit (test->mainloop);
+}
+
+static void
+script_start_with_deadline (Test *test,
+ guint timeout)
+{
+ ScriptAction *current_action;
+ script_append_action (test, quit_action, NULL);
+ current_action = (ScriptAction *) test->script->data;
+ test->timeout_id = g_timeout_add (timeout, test_timed_out, test);
+ current_action->action (test, current_action->user_data);
+ g_main_loop_run (test->mainloop);
+}
+
+/**
+ * Setup and teardown functions follow this comment.
+ */
+
+static void
setup (Test *test,
- gconstpointer data)
+ gconstpointer data)
{
g_type_init ();
tp_debug_set_flags ("all");
@@ -58,11 +126,12 @@ setup (Test *test,
test->am = NULL;
test->timeout_id = 0;
+ test->script = NULL;
}
static void
setup_service (Test *test,
- gconstpointer data)
+ gconstpointer data)
{
setup (test, data);
@@ -79,7 +148,7 @@ setup_service (Test *test,
static void
teardown (Test *test,
- gconstpointer data)
+ gconstpointer data)
{
if (test->am != NULL)
{
@@ -99,8 +168,9 @@ teardown (Test *test,
static void
teardown_service (Test *test,
- gconstpointer data)
+ gconstpointer data)
{
+ script_start_with_deadline (test, 1000);
g_assert (
tp_dbus_daemon_release_name (test->dbus, TP_ACCOUNT_MANAGER_BUS_NAME,
&test->error));
@@ -109,16 +179,20 @@ teardown_service (Test *test,
teardown (test, data);
}
+/**
+ * Non-dbus tests follow this comment
+ */
+
static void
test_new (Test *test,
- gconstpointer data G_GNUC_UNUSED)
+ gconstpointer data G_GNUC_UNUSED)
{
test->am = tp_account_manager_new (test->dbus);
}
static void
test_dup (Test *test,
- gconstpointer data G_GNUC_UNUSED)
+ gconstpointer data G_GNUC_UNUSED)
{
TpAccountManager *one, *two;
TpDBusDaemon *dbus_one, *dbus_two;
@@ -138,38 +212,137 @@ test_dup (Test *test,
g_object_unref (one);
}
-/** Tests which use the bus follow this comment. */
-
/**
- * Used by test_prepare.
- */
-static void am_prepare_cb (GObject *source_object,
+ * Actions for use with script_append_action() follow this comment. They are
+ * used in tests which involve asyncronous actions.
+ */
+
+static void
+noop_action (gpointer script_data,
+ gpointer user_data G_GNUC_UNUSED)
+{
+ script_continue (script_data);
+}
+
+static void
+finish_prepare_action (GObject *source_object,
GAsyncResult *res,
gpointer user_data)
{
Test *test = (Test *) user_data;
+ gboolean is_prepared_reply;
TpAccountManager *am = TP_ACCOUNT_MANAGER (source_object);
g_assert (test->am == am);
test->prepared = tp_account_manager_prepare_finish (am, res, &test->error);
- g_main_loop_quit (test->mainloop);
+ is_prepared_reply = tp_account_manager_is_prepared (test->am,
+ TP_ACCOUNT_MANAGER_FEATURE_CORE));
+ g_assert_intcmp (is_prepared_reply, ==, test->prepared);
+ script_continue (test);
+}
+
+static void
+prepare_action (gpointer script_data,
+ gpointer user_data G_GNUC_UNUSED)
+{
+ Test *test = (Test *) script_data;
+
+ test->am = tp_account_manager_new (test->dbus);
+ tp_account_manager_prepare_async (test->am, NULL, finish_prepare_action, test);
+}
+
+
+static void
+assert_ok_action (gpointer script_data,
+ gpointer user_data G_GNUC_UNUSED)
+{
+ Test *test = (Test *) script_data;
+
+ g_assert_no_error (test->error);
+ g_assert (test->prepared);
+
+ script_continue (script_data);
+}
+
+static void
+assert_failed_action (gpointer script_data,
+ gpointer user_data G_GNUC_UNUSED)
+{
+ Test *test = (Test *) script_data;
+
+ g_assert (test->error != NULL);
+ g_error_free (test->error);
+ test->error = NULL;
+
+ script_continue (script_data);
}
/**
- * Helper function for testing the functionality of prepare. Calls prepare
- * and then starts the mainloop until it finishes or times out after a second.
- * Not actually run as a test on its own even though it looks like one.
- * Note that test_prepare doesn't assert that the prepare
- * succeeded. Only that it didn't time out. Use test_prepare_success or
- * test_prepare_fail for this.
- */
+ * account related functions below this comment
+ */
+
+static void
+ensure_action (gpointer script_data,
+ gpointer user_data)
+{
+ char *path = (char *) user_data;
+ Test *test = (Test *) script_data;
+ g_assert (test != NULL);
+ g_assert (test->am != NULL);
+ g_assert (tp_account_manager_is_prepared (test->am, TP_ACCOUNT_MANAGER_FEATURE_CORE));
+ test->account = tp_account_manager_ensure_account (test->am,
+ path);
+
+ script_continue (script_data);
+}
+
+static void
+assert_account_ok_action (gpointer script_data,
+ gpointer user_data G_GNUC_UNUSED)
+{
+ Test *test = (Test *) script_data;
+ g_assert (test->account != NULL);
+
+ script_continue (script_data);
+}
+
+static void
+finish_account_prepare_action (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ Test *test = (Test *) user_data;
+ TpAccount *account = TP_ACCOUNT (source_object);
+ g_assert (test->account == account);
+ test->prepared = tp_account_prepare_finish (account, res, &test->error);
+ g_assert (test->prepared == tp_account_is_prepared (account, TP_ACCOUNT_FEATURE_CORE));
+
+ script_continue (test);
+}
+
+static void
+account_prepare_action (gpointer script_data,
+ gpointer user_data G_GNUC_UNUSED)
+{
+ Test *test = (Test *) script_data;
+
+ tp_account_prepare_async (test->account, NULL, finish_account_prepare_action, test);
+}
+
+/**
+ * Asyncronous tests below this comment. Tests append action functions and
+ * arguments to a script. Once the test function has returned, the teardown
+ * function is responsible for running the script, and quitting the mainloop
+ * afterwards.
+ * Action functions are each responsible for ensuring that the next action is
+ * called.
+ */
+
static void
test_prepare (Test *test,
- gconstpointer data G_GNUC_UNUSED)
+ gconstpointer data G_GNUC_UNUSED)
{
- test->am = tp_account_manager_new (test->dbus);
- tp_account_manager_prepare_async (test->am, NULL, am_prepare_cb, test);
- test->timeout_id = g_timeout_add (1000, test_timed_out, test);
- g_main_loop_run (test->mainloop);
+ script_append_action (test, prepare_action, NULL);
+ script_append_action (test, noop_action, NULL);
}
/**
@@ -177,11 +350,10 @@ test_prepare (Test *test,
*/
static void
test_prepare_success (Test *test,
- gconstpointer data G_GNUC_UNUSED)
+ gconstpointer data G_GNUC_UNUSED)
{
test_prepare (test, data);
- g_assert_no_error (test->error);
- g_assert (test->prepared);
+ script_append_action (test, assert_ok_action, NULL);
}
/**
@@ -191,12 +363,14 @@ test_prepare_success (Test *test,
*/
static void
test_prepare_no_name (Test *test,
- gconstpointer data G_GNUC_UNUSED)
+ gconstpointer data G_GNUC_UNUSED)
{
test_prepare (test, data);
- g_assert (test->error != NULL);
- test->error = NULL;
- g_assert (!test->prepared);
+
+ script_append_action (test, assert_failed_action, NULL);
+ /* Since we are using teardown rather than teardown_service, we need to
+ * run the script ourselves */
+ script_start_with_deadline (test, 1000);
}
/**
@@ -205,29 +379,30 @@ test_prepare_no_name (Test *test,
*/
static void
test_prepare_destroyed (Test *test,
- gconstpointer data G_GNUC_UNUSED)
+ gconstpointer data G_GNUC_UNUSED)
{
dbus_g_connection_unregister_g_object (test->bus, G_OBJECT (test->service));
test_prepare (test, data);
- g_assert (test->error != NULL);
- test->error = NULL;
- g_assert (!test->prepared);
- dbus_g_connection_register_g_object (test->bus, TP_ACCOUNT_MANAGER_OBJECT_PATH,
- (GObject *) test->service);
+ script_append_action (test, assert_failed_action, NULL);
}
static void
-test_create_success (Test *test,
- gconstpointer data G_GNUC_UNUSED)
+test_ensure (Test *test,
+ gconstpointer data G_GNUC_UNUSED)
{
test_prepare (test, data);
- g_assert_no_error (test->error);
- g_assert (test->prepared);
+ script_append_action (test, assert_ok_action, NULL);
+
+ script_append_action (test, ensure_action,
+ TP_ACCOUNT_OBJECT_PATH_BASE "fakecm/fakeproto/account");
+ script_append_action (test, assert_account_ok_action, NULL);
+ script_append_action (test, account_prepare_action, NULL);
+ script_append_action (test, assert_failed_action, NULL);
}
int
main (int argc,
- char **argv)
+ char **argv)
{
g_test_init (&argc, &argv, NULL);
g_test_bug_base ("http://bugs.freedesktop.org/show_bug.cgi?id=");
@@ -242,7 +417,7 @@ main (int argc,
g_test_add ("/am/prepare/name-not-provided", Test, NULL, setup,
test_prepare_no_name, teardown);
- g_test_add ("/am/create/success", Test, NULL, setup_service,
- test_create_success, teardown_service);
+ g_test_add ("/am/ensure", Test, NULL, setup_service,
+ test_ensure, teardown_service);
return g_test_run ();
}
--
1.5.6.5
More information about the telepathy-commits
mailing list