Blame egg/egg-testing.c

Packit b00eeb
/*
Packit b00eeb
 * gnome-keyring
Packit b00eeb
 *
Packit b00eeb
 * Copyright (C) 2011 Collabora Ltd.
Packit b00eeb
 *
Packit b00eeb
 * This program is free software; you can redistribute it and/or modify
Packit b00eeb
 * it under the terms of the GNU Lesser General Public License as
Packit b00eeb
 * published by the Free Software Foundation; either version 2.1 of
Packit b00eeb
 * the License, or (at your option) any later version.
Packit b00eeb
 *
Packit b00eeb
 * This program is distributed in the hope that it will be useful, but
Packit b00eeb
 * WITHOUT ANY WARRANTY; without even the implied warranty of
Packit b00eeb
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit b00eeb
 * Lesser General Public License for more details.
Packit b00eeb
 *
Packit b00eeb
 * You should have received a copy of the GNU Lesser General Public
Packit b00eeb
 * License along with this program; if not, see <http://www.gnu.org/licenses/>.
Packit b00eeb
 *
Packit b00eeb
 * Stef Walter <stefw@collabora.co.uk>
Packit b00eeb
 */
Packit b00eeb
Packit b00eeb
#include "config.h"
Packit b00eeb
Packit b00eeb
#include "egg-testing.h"
Packit b00eeb
Packit b00eeb
#include <glib-object.h>
Packit b00eeb
Packit b00eeb
#include <errno.h>
Packit b00eeb
#include <string.h>
Packit b00eeb
#include <unistd.h>
Packit b00eeb
Packit b00eeb
#ifdef WITH_VALGRIND
Packit b00eeb
#include <valgrind/valgrind.h>
Packit b00eeb
#endif
Packit b00eeb
Packit b00eeb
#if 0
Packit b00eeb
static GCond *wait_condition = NULL;
Packit b00eeb
static GCond *wait_start = NULL;
Packit b00eeb
static GMutex *wait_mutex = NULL;
Packit b00eeb
static gboolean wait_waiting = FALSE;
Packit b00eeb
#endif
Packit b00eeb
Packit b00eeb
gboolean
Packit b00eeb
egg_testing_on_valgrind (void)
Packit b00eeb
{
Packit b00eeb
#ifdef WITH_VALGRIND
Packit b00eeb
	return RUNNING_ON_VALGRIND;
Packit b00eeb
#else
Packit b00eeb
	return FALSE;
Packit b00eeb
#endif
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
Packit b00eeb
static const char HEXC[] = "0123456789ABCDEF";
Packit b00eeb
Packit b00eeb
gchar *
Packit b00eeb
egg_test_escape_data (const guchar *data,
Packit b00eeb
                      gsize n_data)
Packit b00eeb
{
Packit b00eeb
	GString *result;
Packit b00eeb
	gchar c;
Packit b00eeb
	gsize i;
Packit b00eeb
	guchar j;
Packit b00eeb
Packit b00eeb
	g_assert (data != NULL);
Packit b00eeb
Packit b00eeb
	result = g_string_sized_new (n_data * 2 + 1);
Packit b00eeb
	for (i = 0; i < n_data; ++i) {
Packit b00eeb
		c = data[i];
Packit b00eeb
		if (g_ascii_isprint (c) && !strchr ("\n\r\v", c)) {
Packit b00eeb
			g_string_append_c (result, c);
Packit b00eeb
		} else {
Packit b00eeb
			g_string_append (result, "\\x");
Packit b00eeb
			j = c >> 4 & 0xf;
Packit b00eeb
			g_string_append_c (result, HEXC[j]);
Packit b00eeb
			j = c & 0xf;
Packit b00eeb
			g_string_append_c (result, HEXC[j]);
Packit b00eeb
		}
Packit b00eeb
	}
Packit b00eeb
Packit b00eeb
	return g_string_free (result, FALSE);
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
void
Packit b00eeb
egg_assertion_message_cmpmem (const char     *domain,
Packit b00eeb
                              const char     *file,
Packit b00eeb
                              int             line,
Packit b00eeb
                              const char     *func,
Packit b00eeb
                              const char     *expr,
Packit b00eeb
                              gconstpointer   arg1,
Packit b00eeb
                              gsize           n_arg1,
Packit b00eeb
                              const char     *cmp,
Packit b00eeb
                              gconstpointer   arg2,
Packit b00eeb
                              gsize           n_arg2)
Packit b00eeb
{
Packit b00eeb
  char *a1, *a2, *s;
Packit b00eeb
  a1 = arg1 ? egg_test_escape_data (arg1, n_arg1) : g_strdup ("NULL");
Packit b00eeb
  a2 = arg2 ? egg_test_escape_data (arg2, n_arg2) : g_strdup ("NULL");
Packit b00eeb
  s = g_strdup_printf ("assertion failed (%s): (%s %s %s)", expr, a1, cmp, a2);
Packit b00eeb
  g_free (a1);
Packit b00eeb
  g_free (a2);
Packit b00eeb
  g_assertion_message (domain, file, line, func, s);
Packit b00eeb
  g_free (s);
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
static void (*wait_stop_impl) (void);
Packit b00eeb
static gboolean (*wait_until_impl) (int timeout);
Packit b00eeb
Packit b00eeb
#if 0
Packit b00eeb
void
Packit b00eeb
egg_test_wait_stop (void)
Packit b00eeb
{
Packit b00eeb
	g_assert (wait_stop_impl != NULL);
Packit b00eeb
	(wait_stop_impl) ();
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
gboolean
Packit b00eeb
egg_test_wait_until (int timeout)
Packit b00eeb
{
Packit b00eeb
	g_assert (wait_until_impl != NULL);
Packit b00eeb
	return (wait_until_impl) (timeout);
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
static void
Packit b00eeb
thread_wait_stop (void)
Packit b00eeb
{
Packit b00eeb
	GTimeVal tv;
Packit b00eeb
Packit b00eeb
	g_get_current_time (&tv;;
Packit b00eeb
	g_time_val_add (&tv, 1000);
Packit b00eeb
Packit b00eeb
	g_assert (wait_mutex);
Packit b00eeb
	g_assert (wait_condition);
Packit b00eeb
	g_mutex_lock (wait_mutex);
Packit b00eeb
		if (!wait_waiting)
Packit b00eeb
			g_cond_timed_wait (wait_start, wait_mutex, &tv;;
Packit b00eeb
		g_assert (wait_waiting);
Packit b00eeb
		g_cond_broadcast (wait_condition);
Packit b00eeb
	g_mutex_unlock (wait_mutex);
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
static gboolean
Packit b00eeb
thread_wait_until (int timeout)
Packit b00eeb
{
Packit b00eeb
	GTimeVal tv;
Packit b00eeb
	gboolean ret;
Packit b00eeb
Packit b00eeb
	g_get_current_time (&tv;;
Packit b00eeb
	g_time_val_add (&tv, timeout * 1000);
Packit b00eeb
Packit b00eeb
	g_assert (wait_mutex);
Packit b00eeb
	g_assert (wait_condition);
Packit b00eeb
	g_mutex_lock (wait_mutex);
Packit b00eeb
		g_assert (!wait_waiting);
Packit b00eeb
		wait_waiting = TRUE;
Packit b00eeb
		g_cond_broadcast (wait_start);
Packit b00eeb
		ret = g_cond_timed_wait (wait_condition, wait_mutex, &tv;;
Packit b00eeb
		g_assert (wait_waiting);
Packit b00eeb
		wait_waiting = FALSE;
Packit b00eeb
	g_mutex_unlock (wait_mutex);
Packit b00eeb
Packit b00eeb
	return ret;
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
static GMainLoop *wait_loop = NULL;
Packit b00eeb
Packit b00eeb
static void
Packit b00eeb
loop_wait_stop (void)
Packit b00eeb
{
Packit b00eeb
	g_assert (wait_loop != NULL);
Packit b00eeb
	g_main_loop_quit (wait_loop);
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
static gboolean
Packit b00eeb
on_loop_wait_timeout (gpointer data)
Packit b00eeb
{
Packit b00eeb
	gboolean *timed_out = data;
Packit b00eeb
	*timed_out = TRUE;
Packit b00eeb
Packit b00eeb
	g_assert (wait_loop != NULL);
Packit b00eeb
	g_main_loop_quit (wait_loop);
Packit b00eeb
Packit b00eeb
	return TRUE; /* we remove this source later */
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
static gboolean
Packit b00eeb
loop_wait_until (int timeout)
Packit b00eeb
{
Packit b00eeb
	gboolean ret = FALSE;
Packit b00eeb
	gboolean timed_out = FALSE;
Packit b00eeb
	guint source;
Packit b00eeb
Packit b00eeb
	g_assert (wait_loop == NULL);
Packit b00eeb
	wait_loop = g_main_loop_new (g_main_context_get_thread_default (), FALSE);
Packit b00eeb
Packit b00eeb
	source = g_timeout_add (timeout, on_loop_wait_timeout, &timed_out);
Packit b00eeb
Packit b00eeb
	g_main_loop_run (wait_loop);
Packit b00eeb
Packit b00eeb
	if (timed_out) {
Packit b00eeb
		g_source_remove (source);
Packit b00eeb
		ret = FALSE;
Packit b00eeb
	} else {
Packit b00eeb
		ret = TRUE;
Packit b00eeb
	}
Packit b00eeb
Packit b00eeb
	g_main_loop_unref (wait_loop);
Packit b00eeb
	wait_loop = NULL;
Packit b00eeb
	return ret;
Packit b00eeb
Packit b00eeb
	g_assert (wait_loop != NULL);
Packit b00eeb
	g_main_loop_quit (wait_loop);
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
static gpointer
Packit b00eeb
testing_thread (gpointer loop)
Packit b00eeb
{
Packit b00eeb
	gint ret;
Packit b00eeb
Packit b00eeb
	wait_stop_impl = thread_wait_stop;
Packit b00eeb
	wait_until_impl = thread_wait_until;
Packit b00eeb
Packit b00eeb
	ret = g_test_run ();
Packit b00eeb
Packit b00eeb
	wait_stop_impl = NULL;
Packit b00eeb
	wait_until_impl = NULL;
Packit b00eeb
Packit b00eeb
	/* Quit the main loop now that tests are done */
Packit b00eeb
	g_main_loop_quit (loop);
Packit b00eeb
	return GINT_TO_POINTER (ret);
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
gint
Packit b00eeb
egg_tests_run_with_loop (void)
Packit b00eeb
{
Packit b00eeb
	GThread *thread;
Packit b00eeb
	GMainLoop *loop;
Packit b00eeb
	gpointer ret;
Packit b00eeb
Packit b00eeb
	loop = g_main_loop_new (NULL, FALSE);
Packit b00eeb
	wait_condition = g_cond_new ();
Packit b00eeb
	wait_start = g_cond_new ();
Packit b00eeb
	wait_mutex = g_mutex_new ();
Packit b00eeb
Packit b00eeb
	thread = g_thread_create (testing_thread, loop, TRUE, NULL);
Packit b00eeb
	g_assert (thread);
Packit b00eeb
Packit b00eeb
	g_main_loop_run (loop);
Packit b00eeb
	ret = g_thread_join (thread);
Packit b00eeb
	g_main_loop_unref (loop);
Packit b00eeb
Packit b00eeb
	g_cond_free (wait_condition);
Packit b00eeb
	g_cond_free (wait_start);
Packit b00eeb
	g_mutex_free (wait_mutex);
Packit b00eeb
Packit b00eeb
	return GPOINTER_TO_INT (ret);
Packit b00eeb
}
Packit b00eeb
#endif
Packit b00eeb
Packit b00eeb
Packit b00eeb
static void (*wait_stop_impl) (void);
Packit b00eeb
static gboolean (*wait_until_impl) (int timeout);
Packit b00eeb
Packit b00eeb
void
Packit b00eeb
egg_test_wait_stop (void)
Packit b00eeb
{
Packit b00eeb
	g_assert (wait_stop_impl != NULL);
Packit b00eeb
	(wait_stop_impl) ();
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
gboolean
Packit b00eeb
egg_test_wait_until (int timeout)
Packit b00eeb
{
Packit b00eeb
	g_assert (wait_until_impl != NULL);
Packit b00eeb
	return (wait_until_impl) (timeout);
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
static GMainLoop *wait_loop = NULL;
Packit b00eeb
Packit b00eeb
static void
Packit b00eeb
loop_wait_stop (void)
Packit b00eeb
{
Packit b00eeb
	g_assert (wait_loop != NULL);
Packit b00eeb
	g_main_loop_quit (wait_loop);
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
static gboolean
Packit b00eeb
on_loop_wait_timeout (gpointer data)
Packit b00eeb
{
Packit b00eeb
	gboolean *timed_out = data;
Packit b00eeb
	*timed_out = TRUE;
Packit b00eeb
Packit b00eeb
	g_assert (wait_loop != NULL);
Packit b00eeb
	g_main_loop_quit (wait_loop);
Packit b00eeb
Packit b00eeb
	return TRUE; /* we remove this source later */
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
static gboolean
Packit b00eeb
loop_wait_until (int timeout)
Packit b00eeb
{
Packit b00eeb
	gboolean timed_out = FALSE;
Packit b00eeb
	guint source;
Packit b00eeb
Packit b00eeb
	g_assert (wait_loop == NULL);
Packit b00eeb
	wait_loop = g_main_loop_new (g_main_context_get_thread_default (), FALSE);
Packit b00eeb
Packit b00eeb
	source = g_timeout_add (timeout, on_loop_wait_timeout, &timed_out);
Packit b00eeb
Packit b00eeb
	g_main_loop_run (wait_loop);
Packit b00eeb
Packit b00eeb
	g_source_remove (source);
Packit b00eeb
	g_main_loop_unref (wait_loop);
Packit b00eeb
	wait_loop = NULL;
Packit b00eeb
	return !timed_out;
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
gint
Packit b00eeb
egg_tests_run_with_loop (void)
Packit b00eeb
{
Packit b00eeb
	gint ret;
Packit b00eeb
Packit b00eeb
	wait_stop_impl = loop_wait_stop;
Packit b00eeb
	wait_until_impl = loop_wait_until;
Packit b00eeb
Packit b00eeb
	ret = g_test_run ();
Packit b00eeb
Packit b00eeb
	wait_stop_impl = NULL;
Packit b00eeb
	wait_until_impl = NULL;
Packit b00eeb
Packit b00eeb
	while (g_main_context_iteration (NULL, FALSE));
Packit b00eeb
Packit b00eeb
	return ret;
Packit b00eeb
}