summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.ac1
-rw-r--r--telepathy-logger/log-store-pidgin.c2
-rw-r--r--tests/Makefile.am42
-rw-r--r--tests/dbus/Makefile.am73
-rw-r--r--tests/dbus/dbus-1/session.conf.in30
-rw-r--r--tests/dbus/test-searches.c316
-rw-r--r--tests/dbus/test-tpl-log-store-pidgin.c571
-rw-r--r--tests/lib/Makefile.am14
-rw-r--r--tests/lib/simple-account-manager.c180
-rw-r--r--tests/lib/simple-account-manager.h58
-rw-r--r--tests/lib/simple-account.c416
-rw-r--r--tests/lib/simple-account.h56
-rwxr-xr-xtools/test-wrapper.sh30
-rw-r--r--tools/valgrind.mk13
-rw-r--r--tools/with-session-bus.sh94
15 files changed, 1872 insertions, 24 deletions
diff --git a/configure.ac b/configure.ac
index f1efa76..f82ebb6 100644
--- a/configure.ac
+++ b/configure.ac
@@ -222,6 +222,7 @@ AC_CONFIG_FILES([
telepathy-logger/telepathy-logger-0.1-uninstalled.pc
tools/Makefile
tests/Makefile
+ tests/dbus/Makefile
tests/lib/Makefile
tests/suppressions/Makefile
tests/twisted/Makefile
diff --git a/telepathy-logger/log-store-pidgin.c b/telepathy-logger/log-store-pidgin.c
index fc6dd79..f406095 100644
--- a/telepathy-logger/log-store-pidgin.c
+++ b/telepathy-logger/log-store-pidgin.c
@@ -608,7 +608,7 @@ log_store_pidgin_search_hit_new (TplLogStore *self,
hit = g_slice_new0 (TplLogSearchHit);
hit->date = log_store_pidgin_get_time (strv[len-1]);
- hit->type = g_str_has_suffix (strv[len-2], ".chat")
+ hit->type = g_str_has_suffix (strv[len-2], ".chat")
? TPL_EVENT_SEARCH_TEXT : TPL_EVENT_SEARCH_TEXT_ROOM;
/* Remove ".chat" suffix. */
diff --git a/tests/Makefile.am b/tests/Makefile.am
index b09613a..d5c4cb4 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -2,50 +2,60 @@ if WANT_TWISTED_TESTS
CHECKTWISTED = twisted
endif
-SUBDIRS = $(CHECKTWISTED) suppressions lib
+SUBDIRS = $(CHECKTWISTED) suppressions lib dbus
LDADD = \
$(top_builddir)/telepathy-logger/libtelepathy-logger.la \
$(TPL_LIBS)
+TEST_EXECUTABLES = \
+ test-entity \
+ test-tpl-channel \
+ test-tpl-conf \
+ test-tpl-log-store-sqlite \
+ test-tpl-log-manager \
+ test-tpl-observer \
+ $(NULL)
+
noinst_PROGRAMS = \
- test-entity \
- test-tpl-channel \
- test-tpl-conf \
- test-tpl-log-store-sqlite \
- test-tpl-log-manager \
- test-tpl-observer \
- test-searches \
+ ${TEST_EXECUTABLES} \
$(NULL)
test_tpl_channel_SOURCES = \
test-tpl-channel.c \
tpl-channel-test.c \
- tpl-channel-test.h
+ tpl-channel-test.h \
+ $(NULL)
test_tpl_observer_SOURCES = \
test-tpl-observer.c \
- tpl-channel-test.c
+ tpl-channel-test.c \
+ $(NULL)
test_searches_SOURCES = \
test-searches.c \
- constants.h
+ constants.h \
+ $(NULL)
test_entity_LDADD = \
$(top_builddir)/tests/lib/libtp-logger-tests.la \
- $(LDADD)
+ $(LDADD) \
+ $(NULL)
AM_CFLAGS = \
$(ERROR_CFLAGS) \
$(TPL_CFLAGS) \
-I$(top_srcdir) \
- -I$(top_builddir)
+ -I$(top_builddir) \
+ $(NULL)
-TESTS = $(noinst_PROGRAMS)
+TESTS = $(TEST_EXECUTABLES)
TESTS_ENVIRONMENT = \
- G_DEBUG=fatal-warnings,fatal-criticals \
- TPL_TEST_MODE=true \
+ G_DEBUG=fatal-warnings,fatal-criticals \
+ TPL_TEST_MODE=true \
+ TEST_LOG_DIR=@abs_top_srcdir@/tests/logs \
+ $(top_srcdir)/tools/test-wrapper.sh \
$(NULL)
check-valgrind: $(TESTS)
diff --git a/tests/dbus/Makefile.am b/tests/dbus/Makefile.am
new file mode 100644
index 0000000..57ddb21
--- /dev/null
+++ b/tests/dbus/Makefile.am
@@ -0,0 +1,73 @@
+noinst_PROGRAMS = \
+ test-searches \
+ test-tpl-log-store-pidgin \
+ $(NULL)
+
+TESTS = $(noinst_PROGRAMS)
+
+LDADD = \
+ $(top_builddir)/tests/lib/libtp-logger-tests.la \
+ $(top_builddir)/telepathy-logger/libtelepathy-logger.la \
+ $(TPL_LIBS) \
+ $(NULL)
+
+
+check_c_sources = *.c
+include $(top_srcdir)/tools/check-coding-style.mk
+check-local: check-coding-style
+
+AM_CPPFLAGS = \
+ -I${top_srcdir} -I${top_builddir} \
+ -D_TP_IGNORE_DEPRECATIONS \
+ $(TPL_CFLAGS) \
+ $(NULL)
+
+AM_CFLAGS = $(ERROR_CFLAGS)
+
+TESTS_ENVIRONMENT = \
+ abs_top_builddir=@abs_top_builddir@ \
+ TPL_TEST_MODE=true \
+ TPL_TEST_LOG_DIR=@abs_top_srcdir@/tests/logs \
+ GSETTINGS_SCHEMA_DIR=@abs_srcdir@/data \
+ XDG_DATA_HOME=@abs_top_builddir@/tests/logs \
+ XDG_DATA_DIRS=@abs_srcdir@ \
+ G_SLICE=debug-blocks \
+ TPL_DEBUG=all \
+ G_DEBUG=fatal_warnings,fatal_criticals$(maybe_gc_friendly) \
+ $(top_srcdir)/tools/test-wrapper.sh \
+ sh $(top_srcdir)/tools/with-session-bus.sh \
+ --config-file=dbus-1/session.conf -- \
+ $(EXTRA_TESTS_ENVIRONMENT)
+
+EXTRA_TESTS_ENVIRONMENT =
+
+check-valgrind:
+ $(MAKE) check-TESTS \
+ maybe_gc_friendly=,gc-friendly \
+ TESTS_ENVIRONMENT="$(VALGRIND_TESTS_ENVIRONMENT)"
+
+include $(top_srcdir)/tools/valgrind.mk
+
+VALGRIND_TESTS_ENVIRONMENT = \
+ $(TESTS_ENVIRONMENT) \
+ env G_SLICE=always-malloc CHECK_VERBOSE=1 \
+ $(top_builddir)/libtool --mode=execute \
+ $(VALGRIND) --suppressions=$(top_srcdir)/tests/tests.supp $(VALGRIND_FLAGS)
+
+BUILT_SOURCES = \
+ dbus-1/session.conf \
+ $(NULL)
+
+CLEANFILES = $(BUILT_SOURCES)
+
+distclean-local:
+ rm -f capture-*.log
+ rm -rf _gen
+
+EXTRA_DIST = \
+ dbus-1/session.conf.in \
+ $(NULL)
+
+dbus-1/%.conf: $(srcdir)/dbus-1/%.conf.in
+ $(AM_V_at)$(mkdir_p) dbus-1
+ $(AM_V_GEN)sed -e "s|[@]abs_top_builddir[@]|@abs_top_builddir@|g" $< > $@
diff --git a/tests/dbus/dbus-1/session.conf.in b/tests/dbus/dbus-1/session.conf.in
new file mode 100644
index 0000000..52fe180
--- /dev/null
+++ b/tests/dbus/dbus-1/session.conf.in
@@ -0,0 +1,30 @@
+<!-- Copied from telepathy-gabble (which doubtless copied it from somewhere
+ else) and modified.
+ This configuration file controls the per-user-login-session message bus.
+ Add a session-local.conf and edit that rather than changing this
+ file directly. -->
+
+<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-Bus Bus Configuration 1.0//EN"
+ "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
+<busconfig>
+ <!-- Our well-known bus type, don't change this -->
+ <type>session</type>
+
+ <listen>unix:tmpdir=/tmp</listen>
+
+ <servicedir>@abs_top_builddir@/tests/dbus/dbus-1/services/</servicedir>
+
+ <policy context="default">
+ <!-- Allow everything to be sent -->
+ <allow send_destination="*" eavesdrop="true"/>
+ <!-- Allow everything to be received -->
+ <allow eavesdrop="true"/>
+ <!-- Allow anyone to own anything -->
+ <allow own="*"/>
+ </policy>
+
+ <!-- This is included last so local configuration can override what's
+ in this standard file -->
+
+
+</busconfig>
diff --git a/tests/dbus/test-searches.c b/tests/dbus/test-searches.c
new file mode 100644
index 0000000..eac2c94
--- /dev/null
+++ b/tests/dbus/test-searches.c
@@ -0,0 +1,316 @@
+#include "../../telepathy-logger/log-manager.c"
+
+#include "../lib/util.h"
+#include "../lib/simple-account.h"
+#include "../lib/simple-account-manager.h"
+
+#include <telepathy-logger/debug-internal.h>
+#include <telepathy-logger/log-manager-internal.h>
+#include <telepathy-logger/log-store-internal.h>
+
+#include <telepathy-glib/debug-sender.h>
+
+/* it was defined in telepathy-logger/log-store-pidgin.c */
+#undef DEBUG_FLAG
+#define DEBUG_FLAG TPL_DEBUG_TESTSUITE
+#include <telepathy-logger/debug-internal.h>
+
+#define ACCOUNT_PATH_JABBER TP_ACCOUNT_OBJECT_PATH_BASE "gabble/jabber/user_40collabora_2eco_2euk"
+#define MY_ID "user@collabora.co.uk"
+#define ID "user2@collabora.co.uk"
+
+typedef struct
+{
+ GMainLoop *main_loop;
+
+ TpDBusDaemon *dbus;
+ TpAccount *account;
+ TpTestsSimpleAccount *account_service;
+
+ TplLogManager *manager;
+} TestCaseFixture;
+
+
+
+#ifdef ENABLE_DEBUG
+static TpDebugSender *debug_sender = NULL;
+static gboolean stamp_logs = FALSE;
+
+
+static void
+log_to_debug_sender (const gchar *log_domain,
+ GLogLevelFlags log_level,
+ const gchar *string)
+{
+ GTimeVal now;
+
+ g_return_if_fail (TP_IS_DEBUG_SENDER (debug_sender));
+
+ g_get_current_time (&now);
+
+ tp_debug_sender_add_message (debug_sender, &now, log_domain, log_level,
+ string);
+}
+
+
+static void
+log_handler (const gchar *log_domain,
+ GLogLevelFlags log_level,
+ const gchar *message,
+ gpointer user_data)
+{
+ if (stamp_logs)
+ {
+ GTimeVal now;
+ gchar now_str[32];
+ gchar *tmp;
+ struct tm tm;
+
+ g_get_current_time (&now);
+ localtime_r (&(now.tv_sec), &tm);
+ strftime (now_str, 32, "%Y-%m-%d %H:%M:%S", &tm);
+ tmp = g_strdup_printf ("%s.%06ld: %s",
+ now_str, now.tv_usec, message);
+
+ g_log_default_handler (log_domain, log_level, tmp, NULL);
+
+ g_free (tmp);
+ }
+ else
+ {
+ g_log_default_handler (log_domain, log_level, message, NULL);
+ }
+
+ log_to_debug_sender (log_domain, log_level, message);
+}
+#endif /* ENABLE_DEBUG */
+
+
+
+static void
+test_get_dates (TestCaseFixture *fixture,
+ gconstpointer user_data)
+{
+ GList *ret, *loc;
+
+ ret = _tpl_log_manager_get_dates (fixture->manager, fixture->account, ID,
+ TPL_EVENT_SEARCH_TEXT);
+ /* it includes 1 date from libpurple logs, 5 from TpLogger. Empathy
+ * log-store date are the same of the TpLogger store, and wont' be present,
+ * being duplicates */
+ g_assert_cmpint (g_list_length (ret), ==, 6);
+
+ /* we do not want duplicates */
+ ret = g_list_sort (ret, (GCompareFunc) g_strcmp0);
+ for (loc = ret; loc != NULL; loc = g_list_next (loc))
+ if (loc->next)
+ g_assert (g_date_compare (loc->data, loc->next->data) != 0);
+
+ g_list_foreach (ret, (GFunc) g_free, NULL);
+ g_list_free (ret);
+}
+
+static void
+test_get_entities (TestCaseFixture *fixture,
+ gconstpointer user_data)
+{
+ GList *ret, *loc;
+
+ ret = _tpl_log_manager_get_entities (fixture->manager, fixture->account);
+ /* only ID=user2@collabora.co.uk is currently present, among PidginStore,
+ * EmpathyStore and XmlStore */
+ g_assert_cmpint (g_list_length (ret), ==, 1);
+
+ /* we do not want duplicates */
+ ret = g_list_sort (ret, (GCompareFunc) _tpl_entity_compare);
+ for (loc = ret; loc != NULL; loc = g_list_next (loc))
+ if (loc->next)
+ g_assert (_tpl_entity_compare (loc->data, loc->next->data) != 0);
+
+ g_list_foreach (ret, (GFunc) g_object_unref, NULL);
+ g_list_free (ret);
+}
+
+static void
+teardown_service (TestCaseFixture* fixture,
+ gconstpointer user_data)
+{
+ GError *error = NULL;
+
+ g_assert (user_data != NULL);
+
+ if (fixture->account != NULL)
+ {
+ /* FIXME is it useful in this suite */
+ tp_tests_proxy_run_until_dbus_queue_processed (fixture->account);
+
+ g_object_unref (fixture->account);
+ fixture->account = NULL;
+ }
+
+ tp_dbus_daemon_unregister_object (fixture->dbus, fixture->account_service);
+ g_object_unref (fixture->account_service);
+ fixture->account_service = NULL;
+
+ tp_dbus_daemon_release_name (fixture->dbus, TP_ACCOUNT_MANAGER_BUS_NAME,
+ &error);
+ g_assert_no_error (error);
+
+ g_object_unref (fixture->dbus);
+ fixture->dbus = NULL;
+}
+
+static void
+teardown (TestCaseFixture* fixture,
+ gconstpointer user_data)
+{
+ g_object_unref (fixture->manager);
+ fixture->manager = NULL;
+
+ if (user_data != NULL)
+ teardown_service (fixture, user_data);
+
+ g_main_loop_unref (fixture->main_loop);
+ fixture->main_loop = NULL;
+}
+
+
+static void
+account_prepare_cb (GObject *source,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ TestCaseFixture *fixture = user_data;
+ GError *error = NULL;
+
+ tp_proxy_prepare_finish (source, result, &error);
+ g_assert_no_error (error);
+
+ g_main_loop_quit (fixture->main_loop);
+}
+
+
+static void
+setup_service (TestCaseFixture* fixture,
+ gconstpointer user_data)
+{
+ GQuark account_features[] = { TP_ACCOUNT_FEATURE_CORE, 0 };
+ const gchar *account_path;
+ GValue *boxed_params;
+ GHashTable *params = (GHashTable *) user_data;
+ GError *error = NULL;
+
+ g_assert (params != NULL);
+
+ fixture->dbus = tp_tests_dbus_daemon_dup_or_die ();
+ g_assert (fixture->dbus != NULL);
+
+ tp_dbus_daemon_request_name (fixture->dbus,
+ TP_ACCOUNT_MANAGER_BUS_NAME, FALSE, &error);
+ g_assert_no_error (error);
+
+ /* Create service-side Account object with the passed parameters */
+ fixture->account_service = g_object_new (TP_TESTS_TYPE_SIMPLE_ACCOUNT,
+ NULL);
+ g_assert (fixture->account_service != NULL);
+
+ /* account-path will be set-up as parameter as well, this is not an issue */
+ account_path = g_value_get_string (
+ (const GValue *) g_hash_table_lookup (params, "account-path"));
+ g_assert (account_path != NULL);
+
+ boxed_params = tp_g_value_slice_new_boxed (TP_HASH_TYPE_STRING_VARIANT_MAP,
+ params);
+ g_object_set_property (G_OBJECT (fixture->account_service),
+ "parameters", boxed_params);
+
+ tp_dbus_daemon_register_object (fixture->dbus, account_path,
+ fixture->account_service);
+
+ fixture->account = tp_account_new (fixture->dbus, account_path, NULL);
+ g_assert (fixture->account != NULL);
+ tp_proxy_prepare_async (fixture->account, account_features,
+ account_prepare_cb, fixture);
+ g_main_loop_run (fixture->main_loop);
+
+ g_assert (tp_account_is_prepared (fixture->account,
+ TP_ACCOUNT_FEATURE_CORE));
+
+ tp_g_value_slice_free (boxed_params);
+}
+
+static void
+setup (TestCaseFixture* fixture,
+ gconstpointer user_data)
+{
+ DEBUG ("setting up");
+
+ fixture->main_loop = g_main_loop_new (NULL, FALSE);
+ g_assert (fixture->main_loop != NULL);
+
+ fixture->manager = tpl_log_manager_dup_singleton ();
+
+ if (user_data != NULL)
+ setup_service (fixture, user_data);
+
+ DEBUG ("set up finished");
+}
+
+static void
+setup_debug (void)
+{
+ tp_debug_divert_messages (g_getenv ("TPL_LOGFILE"));
+
+#ifdef ENABLE_DEBUG
+ _tpl_debug_set_flags_from_env ();
+
+ stamp_logs = (g_getenv ("TPL_TIMING") != NULL);
+ debug_sender = tp_debug_sender_dup ();
+
+ g_log_set_default_handler (log_handler, NULL);
+#endif /* ENABLE_DEBUG */
+}
+
+
+int
+main (int argc, char **argv)
+{
+ GHashTable *params = NULL;
+ GList *l = NULL;
+ int retval;
+
+ g_type_init ();
+
+ setup_debug ();
+
+ /* no account tests */
+ g_test_init (&argc, &argv, NULL);
+ g_test_bug_base ("http://bugs.freedesktop.org/show_bug.cgi?id=");
+
+ /* account related tests */
+ params = g_hash_table_new_full (g_str_hash, g_str_equal, NULL,
+ (GDestroyNotify) tp_g_value_slice_free);
+ g_assert (params != NULL);
+
+ l = g_list_prepend (l, params);
+
+ g_hash_table_insert (params, "account",
+ tp_g_value_slice_new_static_string (MY_ID));
+ g_hash_table_insert (params, "account-path",
+ tp_g_value_slice_new_static_string (ACCOUNT_PATH_JABBER));
+
+ g_test_add ("/log-manager/get-dates",
+ TestCaseFixture, params,
+ setup, test_get_dates, teardown);
+
+ g_test_add ("/log-manager/get-entities",
+ TestCaseFixture, params,
+ setup, test_get_entities, teardown);
+
+
+ retval = g_test_run ();
+
+ g_list_foreach (l, (GFunc) g_hash_table_unref, NULL);
+
+ return retval;
+}
diff --git a/tests/dbus/test-tpl-log-store-pidgin.c b/tests/dbus/test-tpl-log-store-pidgin.c
new file mode 100644
index 0000000..bcaaeb3
--- /dev/null
+++ b/tests/dbus/test-tpl-log-store-pidgin.c
@@ -0,0 +1,571 @@
+/* FIXME: hugly kludge: we need to include all the declarations which are used
+ * by the GInterface and thus not in the -internal.h */
+#include "../../telepathy-logger/log-store-pidgin.c"
+
+
+#include "../lib/util.h"
+#include "../lib/simple-account.h"
+#include "../lib/simple-account-manager.h"
+
+#include <telepathy-logger/log-store-pidgin-internal.h>
+#include <telepathy-logger/event-text-internal.h>
+
+#include <telepathy-glib/debug-sender.h>
+
+/* it was defined in telepathy-logger/log-store-pidgin.c */
+#undef DEBUG_FLAG
+#define DEBUG_FLAG TPL_DEBUG_TESTSUITE
+#include <telepathy-logger/debug-internal.h>
+
+#include <glib.h>
+
+#define ACCOUNT_PATH_JABBER TP_ACCOUNT_OBJECT_PATH_BASE "foo/jabber/baz"
+#define ACCOUNT_PATH_IRC TP_ACCOUNT_OBJECT_PATH_BASE "foo/irc/baz"
+
+typedef struct
+{
+ gchar *basedir;
+
+ GMainLoop *main_loop;
+
+ TpDBusDaemon *dbus;
+ TpAccount *account;
+ TpTestsSimpleAccount *account_service;
+
+ TplLogStorePidgin *store;
+} PidginTestCaseFixture;
+
+#ifdef ENABLE_DEBUG
+static TpDebugSender *debug_sender = NULL;
+static gboolean stamp_logs = FALSE;
+
+
+static void
+log_to_debug_sender (const gchar *log_domain,
+ GLogLevelFlags log_level,
+ const gchar *string)
+{
+ GTimeVal now;
+
+ g_return_if_fail (TP_IS_DEBUG_SENDER (debug_sender));
+
+ g_get_current_time (&now);
+
+ tp_debug_sender_add_message (debug_sender, &now, log_domain, log_level,
+ string);
+}
+
+
+static void
+log_handler (const gchar *log_domain,
+ GLogLevelFlags log_level,
+ const gchar *message,
+ gpointer user_data)
+{
+ if (stamp_logs)
+ {
+ GTimeVal now;
+ gchar now_str[32];
+ gchar *tmp;
+ struct tm tm;
+
+ g_get_current_time (&now);
+ localtime_r (&(now.tv_sec), &tm);
+ strftime (now_str, 32, "%Y-%m-%d %H:%M:%S", &tm);
+ tmp = g_strdup_printf ("%s.%06ld: %s",
+ now_str, now.tv_usec, message);
+
+ g_log_default_handler (log_domain, log_level, tmp, NULL);
+
+ g_free (tmp);
+ }
+ else
+ {
+ g_log_default_handler (log_domain, log_level, message, NULL);
+ }
+
+ log_to_debug_sender (log_domain, log_level, message);
+}
+#endif /* ENABLE_DEBUG */
+
+
+static void
+account_prepare_cb (GObject *source,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ PidginTestCaseFixture *fixture = user_data;
+ GError *error = NULL;
+
+ tp_proxy_prepare_finish (source, result, &error);
+ g_assert_no_error (error);
+
+ g_main_loop_quit (fixture->main_loop);
+}
+
+
+static void
+setup_service (PidginTestCaseFixture* fixture,
+ gconstpointer user_data)
+{
+ GQuark account_features[] = { TP_ACCOUNT_FEATURE_CORE, 0 };
+ const gchar *account_path;
+ GValue *boxed_params;
+ GHashTable *params = (GHashTable *) user_data;
+ GError *error = NULL;
+
+ g_assert (params != NULL);
+
+ fixture->dbus = tp_tests_dbus_daemon_dup_or_die ();
+ g_assert (fixture->dbus != NULL);
+
+ tp_dbus_daemon_request_name (fixture->dbus,
+ TP_ACCOUNT_MANAGER_BUS_NAME, FALSE, &error);
+ g_assert_no_error (error);
+
+ /* Create service-side Account object with the passed parameters */
+ fixture->account_service = g_object_new (TP_TESTS_TYPE_SIMPLE_ACCOUNT,
+ NULL);
+ g_assert (fixture->account_service != NULL);
+
+ /* account-path will be set-up as parameter as well, this is not an issue */
+ account_path = g_value_get_string (
+ (const GValue *) g_hash_table_lookup (params, "account-path"));
+ g_assert (account_path != NULL);
+
+ boxed_params = tp_g_value_slice_new_boxed (TP_HASH_TYPE_STRING_VARIANT_MAP,
+ params);
+ g_object_set_property (G_OBJECT (fixture->account_service),
+ "parameters", boxed_params);
+
+ tp_dbus_daemon_register_object (fixture->dbus, account_path,
+ fixture->account_service);
+
+ fixture->account = tp_account_new (fixture->dbus, account_path, NULL);
+ g_assert (fixture->account != NULL);
+ tp_proxy_prepare_async (fixture->account, account_features,
+ account_prepare_cb, fixture);
+ g_main_loop_run (fixture->main_loop);
+
+ g_assert (tp_account_is_prepared (fixture->account,
+ TP_ACCOUNT_FEATURE_CORE));
+
+ tp_g_value_slice_free (boxed_params);
+}
+
+static void
+setup (PidginTestCaseFixture* fixture,
+ gconstpointer user_data)
+{
+ DEBUG ("setting up");
+
+ fixture->main_loop = g_main_loop_new (NULL, FALSE);
+ g_assert (fixture->main_loop != NULL);
+
+ fixture->basedir = g_build_path (G_DIR_SEPARATOR_S,
+ g_getenv ("TPL_TEST_LOG_DIR"), "purple", NULL);
+ DEBUG ("basedir is %s", fixture->basedir);
+
+ fixture->store = g_object_new (TPL_TYPE_LOG_STORE_PIDGIN,
+ "name", "testcase",
+ "testmode", TRUE,
+ NULL);
+
+ if (user_data != NULL)
+ setup_service (fixture, user_data);
+
+ DEBUG ("set up finished");
+}
+
+static void
+teardown_service (PidginTestCaseFixture* fixture,
+ gconstpointer user_data)
+{
+ GError *error = NULL;
+
+ g_assert (user_data != NULL);
+
+ if (fixture->account != NULL)
+ {
+ /* FIXME is it useful in this suite */
+ tp_tests_proxy_run_until_dbus_queue_processed (fixture->account);
+
+ g_object_unref (fixture->account);
+ fixture->account = NULL;
+ }
+
+ tp_dbus_daemon_unregister_object (fixture->dbus, fixture->account_service);
+ g_object_unref (fixture->account_service);
+ fixture->account_service = NULL;
+
+ tp_dbus_daemon_release_name (fixture->dbus, TP_ACCOUNT_MANAGER_BUS_NAME,
+ &error);
+ g_assert_no_error (error);
+
+ g_object_unref (fixture->dbus);
+ fixture->dbus = NULL;
+}
+
+static void
+teardown (PidginTestCaseFixture* fixture,
+ gconstpointer user_data)
+{
+ g_free (fixture->basedir);
+ fixture->basedir = NULL;
+
+ g_object_unref (fixture->store);
+ fixture->store = NULL;
+
+ if (user_data != NULL)
+ teardown_service (fixture, user_data);
+
+ g_main_loop_unref (fixture->main_loop);
+ fixture->main_loop = NULL;
+}
+
+static void
+test_basedir (PidginTestCaseFixture *fixture,
+ gconstpointer user_data)
+{
+ TplLogStorePidgin *store;
+ gchar *dir;
+
+ g_assert_cmpstr (log_store_pidgin_get_basedir (fixture->store), ==,
+ fixture->basedir);
+
+ /* try to instantiate the default store, without passing basedir, it has to
+ * match the real libpurple basedir */
+ store = g_object_new (TPL_TYPE_LOG_STORE_PIDGIN,
+ "name", "testcase",
+ "readable", FALSE,
+ "writable", FALSE,
+ NULL);
+ dir = g_build_path (G_DIR_SEPARATOR_S, g_get_home_dir (), ".purple",
+ "logs", NULL);
+ g_assert_cmpstr (log_store_pidgin_get_basedir (store), ==, dir);
+
+ g_object_unref (store);
+ g_free (dir);
+}
+
+static void
+test_get_dates_jabber (PidginTestCaseFixture *fixture,
+ gconstpointer user_data)
+{
+ GList *dates = NULL;
+ GDate *date = NULL;
+
+ /* Chatroom messages */
+ dates = log_store_pidgin_get_dates (TPL_LOG_STORE (fixture->store), fixture->account,
+ "test@conference.collabora.co.uk", TPL_EVENT_SEARCH_TEXT_ROOM);
+
+ g_assert_cmpint (g_list_length (dates), ==, 2);
+
+ date = g_list_nth_data (dates, 0);
+ g_assert_cmpint (0, ==,
+ g_date_compare (date, g_date_new_dmy (12, G_DATE_APRIL, 2010)));
+
+ g_date_free (date);
+
+ date = g_list_nth_data (dates, 1);
+ g_assert_cmpint (0, ==,
+ g_date_compare (date, g_date_new_dmy (29, G_DATE_APRIL, 2010)));
+
+ g_date_free (date);
+ g_list_free (dates);
+
+ /* 1-1 messages */
+ dates = log_store_pidgin_get_dates (TPL_LOG_STORE (fixture->store), fixture->account,
+ "user2@collabora.co.uk", TPL_EVENT_SEARCH_TEXT);
+
+ g_assert_cmpint (g_list_length (dates), ==, 1);
+
+ date = g_list_nth_data (dates, 0);
+ g_assert_cmpint (0, ==,
+ g_date_compare (date, g_date_new_dmy (10, G_DATE_DECEMBER, 2010)));
+
+ g_date_free (date);
+ g_list_free (dates);
+}
+
+static void
+test_get_dates_irc (PidginTestCaseFixture *fixture,
+ gconstpointer user_data)
+{
+ GList *dates = NULL;
+ GDate *date = NULL;
+
+ dates = log_store_pidgin_get_dates (TPL_LOG_STORE (fixture->store), fixture->account,
+ "#telepathy", TPL_EVENT_SEARCH_TEXT_ROOM);
+
+ g_assert_cmpint (g_list_length (dates), ==, 1);
+
+ date = g_list_nth_data (dates, 0);
+ g_assert_cmpint (0, ==,
+ g_date_compare (date, g_date_new_dmy (30, G_DATE_NOVEMBER, 2010)));
+
+ g_list_foreach (dates, (GFunc) g_date_free, NULL);
+ g_list_free (dates);
+}
+
+static void
+test_get_time (PidginTestCaseFixture *fixture,
+ gconstpointer user_data)
+{
+ GDate *date;
+
+ date = log_store_pidgin_get_time ("2010-04-29.140346+0100BST.html");
+
+ g_assert_cmpint (g_date_get_day (date), ==, 29);
+ g_assert_cmpint (g_date_get_month (date), ==, G_DATE_APRIL);
+ g_assert_cmpint (g_date_get_year (date), ==, 2010);
+
+ g_date_free (date);
+}
+
+static void
+test_get_name (PidginTestCaseFixture *fixture,
+ gconstpointer user_data)
+{
+ const gchar *name;
+
+ name = log_store_pidgin_get_name (TPL_LOG_STORE (fixture->store));
+
+ g_assert_cmpstr (name, ==, "testcase");
+}
+
+static void
+test_get_events_for_date_jabber (PidginTestCaseFixture *fixture,
+ gconstpointer user_data)
+{
+ GList *l;
+ TplEventText *msg = NULL;
+ GDate *date = g_date_new_dmy (12, G_DATE_APRIL, 2010);
+
+ /* chatroom messages */
+ l = log_store_pidgin_get_events_for_date (TPL_LOG_STORE (fixture->store),
+ fixture->account,
+ "test@conference.collabora.co.uk", TPL_EVENT_SEARCH_TEXT_ROOM,
+ date);
+
+ g_assert_cmpint (g_list_length (l), ==, 6);
+
+ msg = g_list_nth_data (l, 0);
+ g_assert (_tpl_event_text_is_chatroom (msg) == TRUE);
+ g_assert_cmpstr (tpl_event_text_get_message (msg), ==, NULL);
+
+ g_list_foreach (l, (GFunc) g_object_unref, NULL);
+ g_list_free (l);
+
+ /* 1-1 messages */
+ g_date_set_dmy (date, 10, G_DATE_DECEMBER, 2010);
+ l = log_store_pidgin_get_events_for_date (TPL_LOG_STORE (fixture->store),
+ fixture->account,
+ "user2@collabora.co.uk", FALSE,
+ date);
+
+ g_assert_cmpint (g_list_length (l), ==, 2);
+
+ msg = g_list_nth_data (l, 0);
+ g_assert (_tpl_event_text_is_chatroom (msg) == FALSE);
+ g_assert_cmpstr (tpl_event_text_get_message (msg), ==, NULL);
+
+ g_list_foreach (l, (GFunc) g_object_unref, NULL);
+ g_list_free (l);
+
+ g_date_free (date);
+}
+
+static void
+test_get_entities_jabber (PidginTestCaseFixture *fixture,
+ gconstpointer user_data)
+{
+ GList *l = NULL;
+ TplEntity *entity;
+
+ l = log_store_pidgin_get_entities (TPL_LOG_STORE (fixture->store),
+ fixture->account);
+
+ /* FIXME: currently the docstring says it should return both 1-1 and chatrooms
+ * chats, but code for the existing stores only return the 1-1 chats */
+ g_assert_cmpint (g_list_length (l), ==, 1);
+
+ entity = g_list_nth_data (l, 0);
+ g_assert_cmpstr (tpl_entity_get_identifier (entity), ==,
+ "user2@collabora.co.uk");
+ g_assert (tpl_entity_get_entity_type (entity) == TPL_ENTITY_CONTACT);
+
+ g_list_foreach (l, (GFunc) g_object_unref, NULL);
+ g_list_free (l);
+}
+
+static void
+test_search_in_identifier (PidginTestCaseFixture *fixture,
+ gconstpointer user_data)
+{
+ GList *l = NULL;
+ TplLogSearchHit *hit;
+
+ l = log_store_pidgin_search_in_identifier (
+ TPL_LOG_STORE (fixture->store), fixture->account,
+ "user2@collabora.co.uk", TPL_EVENT_SEARCH_TEXT, "bla bla");
+
+ g_assert_cmpint (g_list_length (l), ==, 0);
+
+ tpl_log_manager_search_free (l);
+
+ l = log_store_pidgin_search_in_identifier (
+ TPL_LOG_STORE (fixture->store), fixture->account,
+ "user2@collabora.co.uk", TPL_EVENT_SEARCH_TEXT, "hey you");
+
+ g_assert_cmpint (g_list_length (l), ==, 1);
+ hit = g_list_nth_data (l, 0);
+ g_assert (hit->type == TPL_EVENT_SEARCH_TEXT);
+ g_assert_cmpstr (hit->id, ==, "user2@collabora.co.uk");
+
+ g_assert_cmpint (g_date_get_day (hit->date), ==, 10);
+ g_assert_cmpint (g_date_get_month (hit->date), ==, G_DATE_DECEMBER);
+ g_assert_cmpint (g_date_get_year (hit->date), ==, 2010);
+
+ tpl_log_manager_search_free (l);
+
+ return;
+}
+
+static void
+test_search_new (PidginTestCaseFixture *fixture,
+ gconstpointer user_data)
+{
+ GList *l = NULL;
+ TplLogSearchHit *hit;
+
+ /* empty search */
+ l = log_store_pidgin_search_new (TPL_LOG_STORE (fixture->store),
+ "I do not exist in this log store data base!");
+
+ g_assert_cmpint (g_list_length (l), ==, 0);
+
+ tpl_log_manager_search_free (l);
+
+ /* non empty search matching 1-1 */
+ l = log_store_pidgin_search_new (TPL_LOG_STORE (fixture->store),
+ "hey you");
+
+ g_assert_cmpint (g_list_length (l), ==, 1);
+
+ hit = g_list_nth_data (l, 0);
+
+ tpl_log_manager_search_free (l);
+
+ /* non empty search, checking chatrooms are also searched */
+ l = log_store_pidgin_search_new (TPL_LOG_STORE (fixture->store),
+ "disco remote servers");
+
+ g_assert_cmpint (g_list_length (l), ==, 1);
+
+ hit = g_list_nth_data (l, 0);
+
+ tpl_log_manager_search_free (l);
+}
+
+
+static void
+setup_debug (void)
+{
+ tp_debug_divert_messages (g_getenv ("TPL_LOGFILE"));
+
+#ifdef ENABLE_DEBUG
+ _tpl_debug_set_flags_from_env ();
+
+ stamp_logs = (g_getenv ("TPL_TIMING") != NULL);
+ debug_sender = tp_debug_sender_dup ();
+
+ g_log_set_default_handler (log_handler, NULL);
+#endif /* ENABLE_DEBUG */
+}
+
+
+int
+main (int argc, char **argv)
+{
+ GHashTable *params = NULL;
+ GList *l = NULL;
+ int retval;
+
+ g_type_init ();
+
+ setup_debug ();
+
+ /* no account tests */
+ g_test_init (&argc, &argv, NULL);
+ g_test_bug_base ("http://bugs.freedesktop.org/show_bug.cgi?id=");
+
+ g_test_add ("/log-store-pidgin/get-name",
+ PidginTestCaseFixture, NULL,
+ setup, test_get_name, teardown);
+
+ g_test_add ("/log-store-pidgin/get-time",
+ PidginTestCaseFixture, NULL,
+ setup, test_get_time, teardown);
+
+ /* this searches all over the account in the log stores */
+ g_test_add ("/log-store-pidgin/search-new",
+ PidginTestCaseFixture, NULL,
+ setup, test_search_new, teardown);
+
+ /* jabber account tests */
+ params = g_hash_table_new_full (g_str_hash, g_str_equal, NULL,
+ (GDestroyNotify) tp_g_value_slice_free);
+ g_assert (params != NULL);
+
+ l = g_list_prepend (l, params);
+
+ g_hash_table_insert (params, "account",
+ tp_g_value_slice_new_static_string ("user@collabora.co.uk"));
+ g_hash_table_insert (params, "account-path",
+ tp_g_value_slice_new_static_string (ACCOUNT_PATH_JABBER));
+
+ g_test_add ("/log-store-pidgin/basedir",
+ PidginTestCaseFixture, params,
+ setup, test_basedir, teardown);
+
+ g_test_add ("/log-store-pidgin/get-dates-jabber",
+ PidginTestCaseFixture, params,
+ setup, test_get_dates_jabber, teardown);
+
+ g_test_add ("/log-store-pidgin/get-events-for-date-jabber",
+ PidginTestCaseFixture, params,
+ setup, test_get_events_for_date_jabber, teardown);
+
+ g_test_add ("/log-store-pidgin/get-entities-jabber",
+ PidginTestCaseFixture, params,
+ setup, test_get_entities_jabber, teardown);
+
+ g_test_add ("/log-store-pidgin/search-in-identifier",
+ PidginTestCaseFixture, params, setup,
+ test_search_in_identifier, teardown);
+
+ /* IRC account tests */
+ params = g_hash_table_new_full (g_str_hash, g_str_equal, NULL,
+ (GDestroyNotify) tp_g_value_slice_free);
+ g_assert (params != NULL);
+
+ l = g_list_prepend (l, params);
+
+ g_hash_table_insert (params, "account",
+ tp_g_value_slice_new_static_string ("user"));
+ g_hash_table_insert (params, "server",
+ tp_g_value_slice_new_static_string ("irc.freenode.net"));
+ g_hash_table_insert (params, "account-path",
+ tp_g_value_slice_new_static_string (ACCOUNT_PATH_IRC));
+
+ g_test_add ("/log-store-pidgin/get-dates-irc",
+ PidginTestCaseFixture, params,
+ setup, test_get_dates_irc, teardown);
+
+ retval = g_test_run ();
+
+ g_list_foreach (l, (GFunc) g_hash_table_unref, NULL);
+
+ return retval;
+}
diff --git a/tests/lib/Makefile.am b/tests/lib/Makefile.am
index 97bcf88..e0b7940 100644
--- a/tests/lib/Makefile.am
+++ b/tests/lib/Makefile.am
@@ -3,6 +3,10 @@ noinst_LTLIBRARIES = libtp-logger-tests.la
libtp_logger_tests_la_SOURCES = \
contacts-conn.c \
contacts-conn.h \
+ simple-account.c \
+ simple-account.h \
+ simple-account-manager.c \
+ simple-account-manager.h \
simple-conn.c \
simple-conn.h \
textchan-null.c \
@@ -16,11 +20,7 @@ check-local: check-coding-style
AM_CFLAGS = \
$(ERROR_CFLAGS) \
- $(DBUS_CFLAGS) \
- $(GLIB_CFLAGS) \
- $(TPL_CFLAGS)
+ $(TPL_CFLAGS)\
+ $(NULL)
-libtp_logger_tests_la_LIBADD = \
- $(DBUS_LIBS) \
- $(GLIB_LIBS) \
- $(top_builddir)/telepathy-logger/libtelepathy-logger.la
+libtp_logger_tests_la_LIBADD = $(TPL_LIBS) \ No newline at end of file
diff --git a/tests/lib/simple-account-manager.c b/tests/lib/simple-account-manager.c
new file mode 100644
index 0000000..e1d1611
--- /dev/null
+++ b/tests/lib/simple-account-manager.c
@@ -0,0 +1,180 @@
+/*
+ * simple-account-manager.c - a simple account manager service.
+ *
+ * Copyright (C) 2007-2009 Collabora Ltd. <http://www.collabora.co.uk/>
+ * Copyright (C) 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 "simple-account-manager.h"
+
+#include <telepathy-glib/gtypes.h>
+#include <telepathy-glib/interfaces.h>
+#include <telepathy-glib/svc-generic.h>
+#include <telepathy-glib/svc-account-manager.h>
+
+static void account_manager_iface_init (gpointer, gpointer);
+
+G_DEFINE_TYPE_WITH_CODE (TpTestsSimpleAccountManager,
+ tp_tests_simple_account_manager,
+ G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_ACCOUNT_MANAGER,
+ account_manager_iface_init);
+ G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_DBUS_PROPERTIES,
+ tp_dbus_properties_mixin_iface_init)
+ )
+
+
+/* TP_IFACE_ACCOUNT_MANAGER is implied */
+static const char *ACCOUNT_MANAGER_INTERFACES[] = { NULL };
+
+static gchar *VALID_ACCOUNTS[] = {
+ "/org/freedesktop/Telepathy/Account/fakecm/fakeproto/validaccount",
+ NULL };
+
+static gchar *INVALID_ACCOUNTS[] = {
+ "/org/freedesktop/Telepathy/Account/fakecm/fakeproto/invalidaccount",
+ NULL };
+
+enum
+{
+ PROP_0,
+ PROP_INTERFACES,
+ PROP_VALID_ACCOUNTS,
+ PROP_INVALID_ACCOUNTS,
+};
+
+struct _TpTestsSimpleAccountManagerPrivate
+{
+ int dummy;
+};
+
+static void
+tp_tests_simple_account_manager_create_account (TpSvcAccountManager *self,
+ const gchar *in_Connection_Manager,
+ const gchar *in_Protocol,
+ const gchar *in_Display_Name,
+ GHashTable *in_Parameters,
+ GHashTable *in_Properties,
+ DBusGMethodInvocation *context)
+{
+ const gchar *out_Account = "/some/fake/account/i/think";
+
+ tp_svc_account_manager_return_from_create_account (context, out_Account);
+}
+
+static void
+account_manager_iface_init (gpointer klass,
+ gpointer unused G_GNUC_UNUSED)
+{
+#define IMPLEMENT(x) tp_svc_account_manager_implement_##x (\
+ klass, tp_tests_simple_account_manager_##x)
+ IMPLEMENT (create_account);
+#undef IMPLEMENT
+}
+
+
+static void
+tp_tests_simple_account_manager_init (TpTestsSimpleAccountManager *self)
+{
+ self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
+ TP_TESTS_TYPE_SIMPLE_ACCOUNT_MANAGER, TpTestsSimpleAccountManagerPrivate);
+}
+
+static void
+tp_tests_simple_account_manager_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *spec)
+{
+ GPtrArray *accounts;
+ guint i = 0;
+
+ switch (property_id) {
+ case PROP_INTERFACES:
+ g_value_set_boxed (value, ACCOUNT_MANAGER_INTERFACES);
+ break;
+
+ case PROP_VALID_ACCOUNTS:
+ accounts = g_ptr_array_new ();
+
+ for (i=0; VALID_ACCOUNTS[i] != NULL; i++)
+ g_ptr_array_add (accounts, g_strdup (VALID_ACCOUNTS[i]));
+
+ g_value_take_boxed (value, accounts);
+ break;
+
+ case PROP_INVALID_ACCOUNTS:
+ accounts = g_ptr_array_new ();
+
+ for (i=0; INVALID_ACCOUNTS[i] != NULL; i++)
+ g_ptr_array_add (accounts, g_strdup (VALID_ACCOUNTS[i]));
+
+ g_value_take_boxed (value, accounts);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, spec);
+ break;
+ }
+}
+
+/**
+ * This class currently only provides the minimum for
+ * tp_account_manager_prepare to succeed. This turns out to be only a working
+ * Properties.GetAll(). If we wanted later to check the case where
+ * tp_account_prepare succeeds, we would need to implement an account object
+ * too.
+ */
+static void
+tp_tests_simple_account_manager_class_init (
+ TpTestsSimpleAccountManagerClass *klass)
+{
+ GObjectClass *object_class = (GObjectClass *) klass;
+ GParamSpec *param_spec;
+
+ static TpDBusPropertiesMixinPropImpl am_props[] = {
+ { "Interfaces", "interfaces", NULL },
+ { "ValidAccounts", "valid-accounts", NULL },
+ { "InvalidAccounts", "invalid-accounts", NULL },
+ /*
+ { "SupportedAccountProperties", "supported-account-properties", NULL },
+ */
+ { NULL }
+ };
+
+ static TpDBusPropertiesMixinIfaceImpl prop_interfaces[] = {
+ { TP_IFACE_ACCOUNT_MANAGER,
+ tp_dbus_properties_mixin_getter_gobject_properties,
+ NULL,
+ am_props
+ },
+ { NULL },
+ };
+
+ g_type_class_add_private (klass, sizeof (TpTestsSimpleAccountManagerPrivate));
+ object_class->get_property = tp_tests_simple_account_manager_get_property;
+
+ param_spec = g_param_spec_boxed ("interfaces", "Extra D-Bus interfaces",
+ "In this case we only implement AccountManager, so none.",
+ G_TYPE_STRV,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (object_class, PROP_INTERFACES, param_spec);
+ param_spec = g_param_spec_boxed ("valid-accounts", "Valid accounts",
+ "The accounts which are valid on this account. This may be a lie.",
+ TP_ARRAY_TYPE_OBJECT_PATH_LIST,
+ G_PARAM_READABLE);
+ g_object_class_install_property (object_class, PROP_VALID_ACCOUNTS, param_spec);
+ param_spec = g_param_spec_boxed ("invalid-accounts", "Invalid accounts",
+ "The accounts which are invalid on this account. This may be a lie.",
+ TP_ARRAY_TYPE_OBJECT_PATH_LIST,
+ G_PARAM_READABLE);
+ g_object_class_install_property (object_class, PROP_INVALID_ACCOUNTS, param_spec);
+
+ klass->dbus_props_class.interfaces = prop_interfaces;
+ tp_dbus_properties_mixin_class_init (object_class,
+ G_STRUCT_OFFSET (TpTestsSimpleAccountManagerClass, dbus_props_class));
+}
diff --git a/tests/lib/simple-account-manager.h b/tests/lib/simple-account-manager.h
new file mode 100644
index 0000000..b4f787c
--- /dev/null
+++ b/tests/lib/simple-account-manager.h
@@ -0,0 +1,58 @@
+/*
+ * simple-account-manager.h - header for a simple account manager service.
+ *
+ * Copyright (C) 2007-2009 Collabora Ltd. <http://www.collabora.co.uk/>
+ * Copyright (C) 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.
+ */
+
+#ifndef __TP_TESTS_SIMPLE_ACCOUNT_MANAGER_H__
+#define __TP_TESTS_SIMPLE_ACCOUNT_MANAGER_H__
+
+#include <glib-object.h>
+#include <telepathy-glib/dbus-properties-mixin.h>
+
+
+G_BEGIN_DECLS
+
+typedef struct _TpTestsSimpleAccountManager TpTestsSimpleAccountManager;
+typedef struct _TpTestsSimpleAccountManagerClass TpTestsSimpleAccountManagerClass;
+typedef struct _TpTestsSimpleAccountManagerPrivate TpTestsSimpleAccountManagerPrivate;
+
+struct _TpTestsSimpleAccountManagerClass {
+ GObjectClass parent_class;
+ TpDBusPropertiesMixinClass dbus_props_class;
+};
+
+struct _TpTestsSimpleAccountManager {
+ GObject parent;
+
+ TpTestsSimpleAccountManagerPrivate *priv;
+};
+
+GType tp_tests_simple_account_manager_get_type (void);
+
+/* TYPE MACROS */
+#define TP_TESTS_TYPE_SIMPLE_ACCOUNT_MANAGER \
+ (tp_tests_simple_account_manager_get_type ())
+#define SIMPLE_ACCOUNT_MANAGER(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST((obj), TP_TESTS_TYPE_SIMPLE_ACCOUNT_MANAGER, \
+ TpTestsSimpleAccountManager))
+#define SIMPLE_ACCOUNT_MANAGER_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST((klass), TP_TESTS_TYPE_SIMPLE_ACCOUNT_MANAGER, \
+ TpTestsSimpleAccountManagerClass))
+#define SIMPLE_IS_ACCOUNT_MANAGER(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE((obj), TP_TESTS_TYPE_SIMPLE_ACCOUNT_MANAGER))
+#define SIMPLE_IS_ACCOUNT_MANAGER_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE((klass), TP_TESTS_TYPE_SIMPLE_ACCOUNT_MANAGER))
+#define SIMPLE_ACCOUNT_MANAGER_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), TP_TESTS_TYPE_SIMPLE_ACCOUNT_MANAGER, \
+ TpTestsSimpleAccountManagerClass))
+
+
+G_END_DECLS
+
+#endif /* #ifndef __TP_TESTS_SIMPLE_ACCOUNT_MANAGER_H__ */
diff --git a/tests/lib/simple-account.c b/tests/lib/simple-account.c
new file mode 100644
index 0000000..8b25af2
--- /dev/null
+++ b/tests/lib/simple-account.c
@@ -0,0 +1,416 @@
+/*
+ * simple-account.c - a simple account service.
+ *
+ * Copyright (C) 2010 Collabora Ltd. <http://www.collabora.co.uk/>
+ *
+ * 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 "simple-account.h"
+
+#include <telepathy-glib/dbus.h>
+#include <telepathy-glib/defs.h>
+#include <telepathy-glib/enums.h>
+#include <telepathy-glib/gtypes.h>
+#include <telepathy-glib/interfaces.h>
+#include <telepathy-glib/util.h>
+#include <telepathy-glib/svc-generic.h>
+#include <telepathy-glib/svc-account.h>
+
+static void account_iface_init (gpointer, gpointer);
+
+G_DEFINE_TYPE_WITH_CODE (TpTestsSimpleAccount,
+ tp_tests_simple_account,
+ G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_ACCOUNT,
+ account_iface_init);
+ G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_ACCOUNT_INTERFACE_STORAGE,
+ NULL);
+ G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_DBUS_PROPERTIES,
+ tp_dbus_properties_mixin_iface_init)
+ )
+
+/* TP_IFACE_ACCOUNT is implied */
+static const char *ACCOUNT_INTERFACES[] = {
+ TP_IFACE_ACCOUNT_INTERFACE_STORAGE,
+ NULL };
+
+enum
+{
+ PROP_0,
+ PROP_INTERFACES,
+ PROP_DISPLAY_NAME,
+ PROP_ICON,
+ PROP_VALID,
+ PROP_ENABLED,
+ PROP_NICKNAME,
+ PROP_PARAMETERS,
+ PROP_AUTOMATIC_PRESENCE,
+ PROP_CONNECT_AUTO,
+ PROP_CONNECTION,
+ PROP_CONNECTION_STATUS,
+ PROP_CONNECTION_STATUS_REASON,
+ PROP_CURRENT_PRESENCE,
+ PROP_REQUESTED_PRESENCE,
+ PROP_NORMALIZED_NAME,
+ PROP_HAS_BEEN_ONLINE,
+ PROP_STORAGE_PROVIDER,
+ PROP_STORAGE_IDENTIFIER,
+ PROP_STORAGE_SPECIFIC_INFORMATION,
+ PROP_STORAGE_RESTRICTIONS
+};
+
+struct _TpTestsSimpleAccountPrivate
+{
+ gpointer unused;
+ GHashTable *parameters;
+};
+
+static void
+account_iface_init (gpointer klass,
+ gpointer unused G_GNUC_UNUSED)
+{
+#define IMPLEMENT(x) tp_svc_account_implement_##x (\
+ klass, tp_tests_simple_account_##x)
+ /* TODO */
+#undef IMPLEMENT
+}
+
+
+static void
+tp_tests_simple_account_init (TpTestsSimpleAccount *self)
+{
+ self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, TP_TESTS_TYPE_SIMPLE_ACCOUNT,
+ TpTestsSimpleAccountPrivate);
+ self->priv->parameters = g_hash_table_new_full (g_str_hash, g_str_equal,
+ (GDestroyNotify) g_free, (GDestroyNotify) tp_g_value_slice_free);
+}
+
+static gpointer
+_parameters_hash_copy_key (gpointer boxed)
+{
+ return g_strdup (boxed);
+}
+
+static gpointer
+_parameters_hash_copy_value (gpointer boxed)
+{
+ GValue *ret = tp_g_value_slice_new (G_TYPE_STRING);
+
+ g_value_copy (boxed, ret);
+ return ret;
+}
+
+
+static void
+tp_tests_simple_account_set_property (GObject *object,
+ guint param_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ TpTestsSimpleAccount *self = TP_TESTS_SIMPLE_ACCOUNT (object);
+
+ switch (param_id) {
+ case PROP_PARAMETERS:
+ tp_g_hash_table_update (self->priv->parameters,
+ g_value_get_boxed (value), _parameters_hash_copy_key,
+ _parameters_hash_copy_value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+ break;
+ }
+}
+
+
+static void
+tp_tests_simple_account_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *spec)
+{
+ TpTestsSimpleAccount *self = TP_TESTS_SIMPLE_ACCOUNT (object);
+ GValueArray *presence;
+ GValue identifier = { 0, };
+
+ presence = tp_value_array_build (3,
+ G_TYPE_UINT, TP_CONNECTION_PRESENCE_TYPE_AVAILABLE,
+ G_TYPE_STRING, "available",
+ G_TYPE_STRING, "",
+ G_TYPE_INVALID);
+
+ g_value_init (&identifier, G_TYPE_STRING);
+ g_value_set_string (&identifier, "unique-identifier");
+
+ switch (property_id) {
+ case PROP_INTERFACES:
+ g_value_set_boxed (value, ACCOUNT_INTERFACES);
+ break;
+ case PROP_DISPLAY_NAME:
+ g_value_set_string (value, "Fake Account");
+ break;
+ case PROP_ICON:
+ g_value_set_string (value, "");
+ break;
+ case PROP_VALID:
+ g_value_set_boolean (value, TRUE);
+ break;
+ case PROP_ENABLED:
+ g_value_set_boolean (value, TRUE);
+ break;
+ case PROP_NICKNAME:
+ g_value_set_string (value, "badger");
+ break;
+ case PROP_PARAMETERS:
+ g_value_set_boxed (value, self->priv->parameters);
+ break;
+ case PROP_AUTOMATIC_PRESENCE:
+ g_value_set_boxed (value, presence);
+ break;
+ case PROP_CONNECT_AUTO:
+ g_value_set_boolean (value, FALSE);
+ break;
+ case PROP_CONNECTION:
+ g_value_set_boxed (value, "/");
+ break;
+ case PROP_CONNECTION_STATUS:
+ g_value_set_uint (value, TP_CONNECTION_STATUS_CONNECTED);
+ break;
+ case PROP_CONNECTION_STATUS_REASON:
+ g_value_set_uint (value, TP_CONNECTION_STATUS_REASON_REQUESTED);
+ break;
+ case PROP_CURRENT_PRESENCE:
+ g_value_set_boxed (value, presence);
+ break;
+ case PROP_REQUESTED_PRESENCE:
+ g_value_set_boxed (value, presence);
+ break;
+ case PROP_NORMALIZED_NAME:
+ g_value_set_string (value, "");
+ break;
+ case PROP_HAS_BEEN_ONLINE:
+ g_value_set_boolean (value, TRUE);
+ break;
+ case PROP_STORAGE_PROVIDER:
+ g_value_set_string (value, "org.freedesktop.Telepathy.glib.test");
+ break;
+ case PROP_STORAGE_IDENTIFIER:
+ g_value_set_boxed (value, &identifier);
+ break;
+ case PROP_STORAGE_SPECIFIC_INFORMATION:
+ g_value_take_boxed (value, tp_asv_new (
+ "one", G_TYPE_INT, 1,
+ "two", G_TYPE_UINT, 2,
+ "marco", G_TYPE_STRING, "polo",
+ NULL));
+ break;
+ case PROP_STORAGE_RESTRICTIONS:
+ g_value_set_uint (value,
+ TP_STORAGE_RESTRICTION_FLAG_CANNOT_SET_ENABLED |
+ TP_STORAGE_RESTRICTION_FLAG_CANNOT_SET_PARAMETERS);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, spec);
+ break;
+ }
+
+ g_boxed_free (TP_STRUCT_TYPE_SIMPLE_PRESENCE, presence);
+ g_value_unset (&identifier);
+}
+
+/**
+ * This class currently only provides the minimum for
+ * tp_account_prepare to succeed. This turns out to be only a working
+ * Properties.GetAll().
+ */
+static void
+tp_tests_simple_account_class_init (TpTestsSimpleAccountClass *klass)
+{
+ GObjectClass *object_class = (GObjectClass *) klass;
+ GParamSpec *param_spec;
+
+ static TpDBusPropertiesMixinPropImpl a_props[] = {
+ { "Interfaces", "interfaces", NULL },
+ { "DisplayName", "display-name", NULL },
+ { "Icon", "icon", NULL },
+ { "Valid", "valid", NULL },
+ { "Enabled", "enabled", NULL },
+ { "Nickname", "nickname", NULL },
+ { "Parameters", "parameters", NULL },
+ { "AutomaticPresence", "automatic-presence", NULL },
+ { "ConnectAutomatically", "connect-automatically", NULL },
+ { "Connection", "connection", NULL },
+ { "ConnectionStatus", "connection-status", NULL },
+ { "ConnectionStatusReason", "connection-status-reason", NULL },
+ { "CurrentPresence", "current-presence", NULL },
+ { "RequestedPresence", "requested-presence", NULL },
+ { "NormalizedName", "normalized-name", NULL },
+ { "HasBeenOnline", "has-been-online", NULL },
+ { NULL }
+ };
+
+ static TpDBusPropertiesMixinPropImpl ais_props[] = {
+ { "StorageProvider", "storage-provider", NULL },
+ { "StorageIdentifier", "storage-identifier", NULL },
+ { "StorageSpecificInformation", "storage-specific-information", NULL },
+ { "StorageRestrictions", "storage-restrictions", NULL },
+ { NULL },
+ };
+
+ static TpDBusPropertiesMixinIfaceImpl prop_interfaces[] = {
+ { TP_IFACE_ACCOUNT,
+ tp_dbus_properties_mixin_getter_gobject_properties,
+ NULL,
+ a_props
+ },
+ {
+ TP_IFACE_ACCOUNT_INTERFACE_STORAGE,
+ tp_dbus_properties_mixin_getter_gobject_properties,
+ NULL,
+ ais_props
+ },
+ { NULL },
+ };
+
+ g_type_class_add_private (klass, sizeof (TpTestsSimpleAccountPrivate));
+ object_class->get_property = tp_tests_simple_account_get_property;
+ object_class->set_property = tp_tests_simple_account_set_property;
+
+ param_spec = g_param_spec_boxed ("interfaces", "Extra D-Bus interfaces",
+ "In this case we only implement Account, so none.",
+ G_TYPE_STRV,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (object_class, PROP_INTERFACES, param_spec);
+
+ param_spec = g_param_spec_string ("display-name", "display name",
+ "DisplayName property",
+ NULL,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (object_class, PROP_DISPLAY_NAME, param_spec);
+
+ param_spec = g_param_spec_string ("icon", "icon",
+ "Icon property",
+ NULL,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (object_class, PROP_ICON, param_spec);
+
+ param_spec = g_param_spec_boolean ("valid", "valid",
+ "Valid property",
+ FALSE,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (object_class, PROP_VALID, param_spec);
+
+ param_spec = g_param_spec_boolean ("enabled", "enabled",
+ "Enabled property",
+ FALSE,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (object_class, PROP_ENABLED, param_spec);
+
+ param_spec = g_param_spec_string ("nickname", "nickname",
+ "Nickname property",
+ NULL,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (object_class, PROP_NICKNAME, param_spec);
+
+ param_spec = g_param_spec_boxed ("parameters", "parameters",
+ "Parameters property",
+ TP_HASH_TYPE_STRING_VARIANT_MAP,
+ G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (object_class, PROP_PARAMETERS, param_spec);
+
+ param_spec = g_param_spec_boxed ("automatic-presence", "automatic presence",
+ "AutomaticPresence property",
+ TP_STRUCT_TYPE_SIMPLE_PRESENCE,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (object_class, PROP_AUTOMATIC_PRESENCE,
+ param_spec);
+
+ param_spec = g_param_spec_boolean ("connect-automatically",
+ "connect automatically", "ConnectAutomatically property",
+ FALSE,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (object_class, PROP_CONNECT_AUTO, param_spec);
+
+ param_spec = g_param_spec_boxed ("connection", "connection",
+ "Connection property",
+ DBUS_TYPE_G_OBJECT_PATH,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (object_class, PROP_CONNECTION, param_spec);
+
+ param_spec = g_param_spec_uint ("connection-status", "connection status",
+ "ConnectionStatus property",
+ 0, NUM_TP_CONNECTION_STATUSES, TP_CONNECTION_STATUS_DISCONNECTED,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (object_class, PROP_CONNECTION_STATUS,
+ param_spec);
+
+ param_spec = g_param_spec_uint ("connection-status-reason",
+ "connection status reason", "ConnectionStatusReason property",
+ 0, NUM_TP_CONNECTION_STATUS_REASONS,
+ TP_CONNECTION_STATUS_REASON_NONE_SPECIFIED,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (object_class, PROP_CONNECTION_STATUS_REASON,
+ param_spec);
+
+ param_spec = g_param_spec_boxed ("current-presence", "current presence",
+ "CurrentPresence property",
+ TP_STRUCT_TYPE_SIMPLE_PRESENCE,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (object_class, PROP_CURRENT_PRESENCE,
+ param_spec);
+
+ param_spec = g_param_spec_boxed ("requested-presence", "requested presence",
+ "RequestedPresence property",
+ TP_STRUCT_TYPE_SIMPLE_PRESENCE,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (object_class, PROP_REQUESTED_PRESENCE,
+ param_spec);
+
+ param_spec = g_param_spec_string ("normalized-name", "normalized name",
+ "NormalizedName property",
+ NULL,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (object_class, PROP_NORMALIZED_NAME,
+ param_spec);
+
+ param_spec = g_param_spec_boolean ("has-been-online", "has been online",
+ "HasBeenOnline property",
+ FALSE,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (object_class, PROP_HAS_BEEN_ONLINE,
+ param_spec);
+
+ param_spec = g_param_spec_string ("storage-provider", "storage provider",
+ "StorageProvider property",
+ NULL,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (object_class, PROP_STORAGE_PROVIDER,
+ param_spec);
+
+ param_spec = g_param_spec_boxed ("storage-identifier", "storage identifier",
+ "StorageIdentifier property",
+ G_TYPE_VALUE,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (object_class, PROP_STORAGE_IDENTIFIER,
+ param_spec);
+
+ param_spec = g_param_spec_boxed ("storage-specific-information",
+ "storage specific information", "StorageSpecificInformation property",
+ TP_HASH_TYPE_STRING_VARIANT_MAP,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (object_class,
+ PROP_STORAGE_SPECIFIC_INFORMATION, param_spec);
+
+ param_spec = g_param_spec_uint ("storage-restrictions",
+ "storage restrictions", "StorageRestrictions property",
+ 0, G_MAXUINT, 0,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+ g_object_class_install_property (object_class, PROP_STORAGE_RESTRICTIONS,
+ param_spec);
+
+ klass->dbus_props_class.interfaces = prop_interfaces;
+ tp_dbus_properties_mixin_class_init (object_class,
+ G_STRUCT_OFFSET (TpTestsSimpleAccountClass, dbus_props_class));
+}
diff --git a/tests/lib/simple-account.h b/tests/lib/simple-account.h
new file mode 100644
index 0000000..7af263d
--- /dev/null
+++ b/tests/lib/simple-account.h
@@ -0,0 +1,56 @@
+/*
+ * simple-account.h - header for a simple account service.
+ *
+ * Copyright (C) 2010 Collabora Ltd. <http://www.collabora.co.uk/>
+ *
+ * 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.
+ */
+
+#ifndef __TP_TESTS_SIMPLE_ACCOUNT_H__
+#define __TP_TESTS_SIMPLE_ACCOUNT_H__
+
+#include <glib-object.h>
+#include <telepathy-glib/dbus-properties-mixin.h>
+
+
+G_BEGIN_DECLS
+
+typedef struct _TpTestsSimpleAccount TpTestsSimpleAccount;
+typedef struct _TpTestsSimpleAccountClass TpTestsSimpleAccountClass;
+typedef struct _TpTestsSimpleAccountPrivate TpTestsSimpleAccountPrivate;
+
+struct _TpTestsSimpleAccountClass {
+ GObjectClass parent_class;
+ TpDBusPropertiesMixinClass dbus_props_class;
+};
+
+struct _TpTestsSimpleAccount {
+ GObject parent;
+
+ TpTestsSimpleAccountPrivate *priv;
+};
+
+GType tp_tests_simple_account_get_type (void);
+
+/* TYPE MACROS */
+#define TP_TESTS_TYPE_SIMPLE_ACCOUNT \
+ (tp_tests_simple_account_get_type ())
+#define TP_TESTS_SIMPLE_ACCOUNT(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST((obj), TP_TESTS_TYPE_SIMPLE_ACCOUNT, \
+ TpTestsSimpleAccount))
+#define TP_TESTS_SIMPLE_ACCOUNT_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST((klass), TP_TESTS_TYPE_SIMPLE_ACCOUNT, \
+ TpTestsSimpleAccountClass))
+#define TP_TESTS_SIMPLE_IS_ACCOUNT(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE((obj), TP_TESTS_TYPE_SIMPLE_ACCOUNT))
+#define TP_TESTS_SIMPLE_IS_ACCOUNT_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE((klass), TP_TESTS_TYPE_SIMPLE_ACCOUNT))
+#define TP_TESTS_SIMPLE_ACCOUNT_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), TP_TESTS_TYPE_SIMPLE_ACCOUNT, \
+ TpTestsSimpleAccountClass))
+
+G_END_DECLS
+
+#endif /* #ifndef __TP_TESTS_SIMPLE_ACCOUNT_H__ */
diff --git a/tools/test-wrapper.sh b/tools/test-wrapper.sh
new file mode 100755
index 0000000..9490067
--- /dev/null
+++ b/tools/test-wrapper.sh
@@ -0,0 +1,30 @@
+#!/bin/sh
+# Make tests shut up. On success, if stdout is a tty, we only output messages
+# about skipped tests; on failure, or if stdout is a file or pipe, we output
+# the lot.
+#
+# Usage: test-wrapper.sh PROGRAM [ARGS...]
+
+set -e
+
+if test -t 1 && test "z$CHECK_VERBOSE" = z; then
+ : # continue with the output-suppressed code path, below
+else
+ "$@" || e=$?
+ exit $e
+fi
+
+e=0
+"$@" > capture-$$.log 2>&1 || e=$?
+if test z$e = z0; then
+ grep -i skipped capture-$$.log || true
+ rm -f capture-$$.log
+else
+ cat capture-$$.log
+ exit $e
+fi
+
+# Copyright © 2010 Collabora Ltd. <http://www.collabora.co.uk/>
+# 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. There is no warranty.
diff --git a/tools/valgrind.mk b/tools/valgrind.mk
new file mode 100644
index 0000000..25a3488
--- /dev/null
+++ b/tools/valgrind.mk
@@ -0,0 +1,13 @@
+VALGRIND = valgrind --tool=memcheck \
+ --verbose \
+ --leak-check=full \
+ --leak-resolution=high \
+ --suppressions=$(top_srcdir)/tools/telepathy-glib.supp \
+ --child-silent-after-fork=yes \
+ --num-callers=20 \
+ --gen-suppressions=all
+
+# other potentially interesting options:
+# --show-reachable=yes reachable objects (many!)
+# --read-var-info=yes better diagnostics from DWARF3 info
+# --track-origins=yes better diagnostics for uninit values (slow)
diff --git a/tools/with-session-bus.sh b/tools/with-session-bus.sh
new file mode 100644
index 0000000..063bd7e
--- /dev/null
+++ b/tools/with-session-bus.sh
@@ -0,0 +1,94 @@
+#!/bin/sh
+# with-session-bus.sh - run a program with a temporary D-Bus session daemon
+#
+# The canonical location of this program is the telepathy-glib tools/
+# directory, please synchronize any changes with that copy.
+#
+# Copyright (C) 2007-2008 Collabora Ltd. <http://www.collabora.co.uk/>
+#
+# 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.
+
+set -e
+
+me=with-session-bus
+
+dbus_daemon_args="--print-address=5 --print-pid=6 --fork"
+sleep=0
+
+usage ()
+{
+ echo "usage: $me [options] -- program [program_options]" >&2
+ echo "Requires write access to the current directory." >&2
+ echo "" >&2
+ echo "If \$WITH_SESSION_BUS_FORK_DBUS_MONITOR is set, fork dbus-monitor" >&2
+ echo "with the arguments in \$WITH_SESSION_BUS_FORK_DBUS_MONITOR_OPT." >&2
+ echo "The output of dbus-monitor is saved in $me-<pid>.dbus-monitor-logs" >&2
+ exit 2
+}
+
+while test "z$1" != "z--"; do
+ case "$1" in
+ --sleep=*)
+ sleep="$1"
+ sleep="${sleep#--sleep=}"
+ shift
+ ;;
+ --session)
+ dbus_daemon_args="$dbus_daemon_args --session"
+ shift
+ ;;
+ --config-file=*)
+ # FIXME: assumes config file doesn't contain any special characters
+ dbus_daemon_args="$dbus_daemon_args $1"
+ shift
+ ;;
+ *)
+ usage
+ ;;
+ esac
+done
+shift
+if test "z$1" = "z"; then usage; fi
+
+exec 5> $me-$$.address
+exec 6> $me-$$.pid
+
+cleanup ()
+{
+ pid=`head -n1 $me-$$.pid`
+ if test -n "$pid" ; then
+ echo "Killing temporary bus daemon: $pid" >&2
+ kill -INT "$pid"
+ fi
+ rm -f $me-$$.address
+ rm -f $me-$$.pid
+}
+
+trap cleanup INT HUP TERM
+dbus-daemon $dbus_daemon_args
+
+{ echo -n "Temporary bus daemon is "; cat $me-$$.address; } >&2
+{ echo -n "Temporary bus daemon PID is "; head -n1 $me-$$.pid; } >&2
+
+e=0
+DBUS_SESSION_BUS_ADDRESS="`cat $me-$$.address`"
+export DBUS_SESSION_BUS_ADDRESS
+
+if [ -n "$WITH_SESSION_BUS_FORK_DBUS_MONITOR" ] ; then
+ echo -n "Forking dbus-monitor $WITH_SESSION_BUS_FORK_DBUS_MONITOR_OPT" >&2
+ dbus-monitor $WITH_SESSION_BUS_FORK_DBUS_MONITOR_OPT \
+ > $me-$$.dbus-monitor-logs 2>&1 &
+fi
+
+"$@" || e=$?
+
+if test $sleep != 0; then
+ sleep $sleep
+fi
+
+trap - INT HUP TERM
+cleanup
+
+exit $e