Commit 2c4f7c6b authored by Xavier Claessens's avatar Xavier Claessens

Add "check" framework support. Fixes bug #505622 (Guillaume Desmottes).

svn path=/trunk/; revision=509
parent 876e427b
......@@ -36,3 +36,4 @@ ltmain.sh
missing
mkinstalldirs
omf.make
compile
......@@ -39,6 +39,7 @@ MISSION_CONTROL_REQUIRED=4.37
# AC_DEFINE(G_DISABLE_DEPRECATED, 1, [Disable deprecated GLib symbols])
# AC_DEFINE(LIBTELEPATHY_DISABLE_DEPRECATED, 1, [Disable deprecated libtelepathy symbols])
AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_AUX_DIR(.)
AM_CONFIG_HEADER(config.h)
AM_INIT_AUTOMAKE(1.9 dist-bzip2 no-define)
......@@ -210,11 +211,24 @@ AM_CONDITIONAL(HAVE_NOTHERE, test "x$have_nothere" = "xyes")
# Tests
# -----------------------------------------------------------
AC_ARG_ENABLE(tests,
AS_HELP_STRING([--enable-tests=@<:@no/yes@:>@],
AS_HELP_STRING([--enable-tests=@<:@no/yes/auto@:>@],
[build tests]), ,
enable_tests=no)
AM_CONDITIONAL(HAVE_TESTS, test "x$enable_tests" = "xyes")
if test "x$enable_tests" != "xno"; then
PKG_CHECK_MODULES(CHECK,
[
check >= 0.9.4
], have_check="yes", have_check="no")
else
have_check=no
fi
if test "x$enable_tests" = "xyes" -a "x$have_check" != "xyes"; then
AC_MSG_ERROR([Couldn't find check dependencies.])
fi
AM_CONDITIONAL(HAVE_TESTS, test "x$have_check" = "xyes")
# -----------------------------------------------------------
# Python Bindings
......@@ -267,6 +281,12 @@ fi
AM_CONDITIONAL(HAVE_VOIP, test "x$enable_voip" = "xyes")
# Checks for the 'check' unit testing library
PKG_CHECK_MODULES([CHECK], [check >= 0.9.4],
[ HAVE_CHECK=yes ],
[ HAVE_CHECK=no ] )
AM_CONDITIONAL(HAVE_CHECK, test "x$HAVE_CHECK" = "xyes")
# -----------------------------------------------------------
AC_OUTPUT([
......@@ -280,6 +300,7 @@ AC_OUTPUT([
libempathy-gtk/Makefile
libempathy-gtk/libempathy-gtk.pc
src/Makefile
m4/Makefile
megaphone/Makefile
megaphone/src/Makefile
megaphone/data/Makefile
......
gtk-doc.m4
intltool.m4
dnl configure-time options for Empathy
dnl EMPATHY_ARG_VALGRIND
AC_DEFUN([EMPATHY_ARG_VALGRIND],
[
dnl valgrind inclusion
AC_ARG_ENABLE(valgrind,
AC_HELP_STRING([--enable-valgrind],[enable valgrind checking and run-time detection]),
[
case "${enableval}" in
yes|no) enable="${enableval}" ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-valgrind) ;;
esac
],
[enable=no])
EMPATHY_VALGRIND($enable, [2.1])
])
dnl Detect Valgrind location and flags
AC_DEFUN([EMPATHY_VALGRIND],
[
enable=$1
if test -n "$2"; then
valgrind_req=$2
else
valgrind_req="2.1"
fi
PKG_CHECK_MODULES(VALGRIND, valgrind > "$valgrind_req",
have_valgrind_runtime="yes", have_valgrind_runtime="no")
AC_PATH_PROG(VALGRIND_PATH, valgrind)
# Compile the instrumentation for valgrind only if the valgrind
# libraries are installed and the valgrind executable is found
if test "x$enable" = xyes &&
test "$have_valgrind_runtime" = yes &&
test -n "$VALGRIND_PATH" ;
then
AC_DEFINE(HAVE_VALGRIND, 1, [Define if valgrind should be used])
AC_MSG_NOTICE(using compile-time instrumentation for valgrind)
fi
AC_SUBST(VALGRIND_CFLAGS)
AC_SUBST(VALGRIND_LIBS)
AM_CONDITIONAL(HAVE_VALGRIND, test -n "$VALGRIND_PATH")
])
LOOPS = 10
CLEANFILES += valgrind.*.log
# run any given test by running make test.check
# if the test fails, run it again at at least debug level 2
%.check: %
@$(TESTS_ENVIRONMENT) \
$* || \
$(TESTS_ENVIRONMENT) \
$*
# run any given test in a loop
%.torture: %
@for i in `seq 1 $(LOOPS)`; do \
$(TESTS_ENVIRONMENT) \
$*; done
# run any given test in an infinite loop
%.forever: %
@while true; do \
$(TESTS_ENVIRONMENT) \
$* || break; done
# valgrind any given test by running make test.valgrind
%.valgrind: %
$(TESTS_ENVIRONMENT) \
CK_DEFAULT_TIMEOUT=360 \
G_SLICE=always-malloc \
G_DEBUG=gc-friendly \
libtool --mode=execute \
$(VALGRIND_PATH) -q \
$(foreach s,$(SUPPRESSIONS),--suppressions=$(s)) \
--tool=memcheck --leak-check=full --trace-children=yes \
--leak-resolution=high --num-callers=20 \
./$* 2>&1 | tee "valgrind.$*.log"
@if grep "==" "valgrind.$*.log" > /dev/null 2>&1; then \
exit 1; \
fi
# valgrind any given test and generate suppressions for it
%.valgrind.gen-suppressions: %
$(TESTS_ENVIRONMENT) \
CK_DEFAULT_TIMEOUT=360 \
G_SLICE=always-malloc \
G_DEBUG=gc-friendly \
libtool --mode=execute \
$(VALGRIND_PATH) -q \
$(foreach s,$(SUPPRESSIONS),--suppressions=$(s)) \
--tool=memcheck --leak-check=full --trace-children=yes \
--leak-resolution=high --num-callers=20 \
--gen-suppressions=all \
./$* 2>&1 | tee suppressions.log
# valgrind any given test until failure by running make test.valgrind-forever
%.valgrind-forever: %
@while $(MAKE) $*.valgrind; do \
true; done
# gdb any given test by running make test.gdb
%.gdb: %
$(TESTS_ENVIRONMENT) \
CK_FORK=no \
libtool --mode=execute \
gdb $*
# torture tests
torture: $(TESTS)
@echo "Torturing tests ..."
for i in `seq 1 $(LOOPS)`; do \
$(MAKE) check || \
(echo "Failure after $$i runs"; exit 1) || \
exit 1; \
done
@banner="All $(LOOPS) loops passed"; \
dashes=`echo "$$banner" | sed s/./=/g`; \
echo $$dashes; echo $$banner; echo $$dashes
# forever tests
forever: $(TESTS)
@echo "Forever tests ..."
while true; do \
$(MAKE) check || \
(echo "Failure"; exit 1) || \
exit 1; \
done
# valgrind all tests
valgrind: $(TESTS)
@echo "Valgrinding tests ..."
@failed=0; \
for t in $(filter-out $(VALGRIND_TESTS_DISABLE),$(TESTS)); do \
$(MAKE) $$t.valgrind; \
if test "$$?" -ne 0; then \
echo "Valgrind error for test $$t"; \
failed=`expr $$failed + 1`; \
whicht="$$whicht $$t"; \
fi; \
done; \
if test "$$failed" -ne 0; then \
echo "$$failed tests had leaks or errors under valgrind:"; \
echo "$$whicht"; \
false; \
fi
help:
@echo "make check -- run all checks"
@echo "make torture -- run all checks $(LOOPS) times"
@echo "make (dir)/(test).check -- run the given check once"
@echo "make (dir)/(test).forever -- run the given check forever"
@echo "make (dir)/(test).torture -- run the given check $(LOOPS) times"
@echo
@echo "make (dir)/(test).gdb -- start up gdb for the given test"
@echo
@echo "make valgrind -- valgrind all tests"
@echo "make (dir)/(test).valgrind -- valgrind the given test"
@echo "make (dir)/(test).valgrind-forever -- valgrind the given test forever"
@echo "make (dir)/(test).valgrind.gen-suppressions -- generate suppressions"
@echo " and save to suppressions.log"
@echo "make inspect -- inspect all plugin features"
check-main
contact-manager
*.log
CLEANFILES=
include $(top_srcdir)/rules/check.mak
SUPPRESSIONS=valgrind.supp dlopen.supp
AM_CPPFLAGS = \
-I$(top_srcdir) \
$(EMPATHY_CFLAGS) \
......@@ -13,3 +19,24 @@ bin_PROGRAMS = \
contact_manager_SOURCES = contact-manager.c
if HAVE_CHECK
check_PROGRAMS = check-main
TESTS = check-main
check_main_SOURCES = \
check-main.c \
check-helpers.c \
check-helpers.h \
check-libempathy.h \
check-empathy-utils.c
check_main_LDADD = \
@CHECK_LIBS@ \
$(top_builddir)/libempathy-gtk/libempathy-gtk.la \
$(top_builddir)/libempathy/libempathy.la \
$(AM_LDFLAGS)
check_main_CFLAGS = \
@CHECK_CFLAGS@ \
$(AM_CFLAGS)
endif
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <check.h>
#include "check-helpers.h"
#include "check-libempathy.h"
#include <libempathy/empathy-utils.h>
START_TEST (test_empathy_substring)
{
gchar *tmp;
tmp = empathy_substring ("empathy", 2, 6);
fail_if (tmp == NULL);
fail_if (strcmp (tmp, "path") != 0);
g_free (tmp);
}
END_TEST
TCase *
make_empathy_utils_tcase (void)
{
TCase *tc = tcase_create ("empathy-utils");
tcase_add_test (tc, test_empathy_substring);
return tc;
}
/*
* check-helpers.c - Source for some check helpers
* Copyright (C) 2007 Collabora Ltd.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <stdio.h>
#include <stdlib.h>
#include "check-helpers.h"
static gboolean expecting_critical = FALSE;
static gboolean received_critical = FALSE;
static void
check_helper_log_critical_func (const gchar *log_damain,
GLogLevelFlags log_level,
const gchar *message,
gpointer user_data)
{
if (!expecting_critical)
{
fail("Unexpected critical message: %s\n", message);
}
g_assert (log_level & G_LOG_LEVEL_CRITICAL);
received_critical = TRUE;
}
gboolean
got_critical (void)
{
return received_critical;
}
void
expect_critical (gboolean expected)
{
expecting_critical = expected;
received_critical = FALSE;
}
void
check_helpers_init (void)
{
g_log_set_handler (NULL, G_LOG_LEVEL_CRITICAL,
check_helper_log_critical_func, NULL);
}
/*
* check-helpers.c - Source for some check helpers
* Copyright (C) 2007 Collabora Ltd.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __CHECK_HELPERS_H__
#define __CHECK_HELPERS_H__
#include <glib.h>
#include <check.h>
void
check_helpers_init (void);
void
expect_critical (gboolean expected);
gboolean
got_critical (void);
#define fail_unless_critical(expr, ...) \
G_STMT_START { \
expect_critical (TRUE); \
expr; \
_fail_unless (got_critical (), __FILE__, __LINE__, \
"Expected g_critical, got none", ## __VA_ARGS__, NULL); \
expect_critical (FALSE); \
} G_STMT_END;
#endif /* #ifndef __CHECK_HELPERS_H__ */
#ifndef __CHECK_LIBEMPATHY__
#define __CHECK_LIBEMPATHY__
TCase * make_empathy_utils_tcase (void);
#endif /* #ifndef __CHECK_LIBEMPATHY__ */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <glib-object.h>
#include <check.h>
#include "check-helpers.h"
#include "check-libempathy.h"
#include "config.h"
static Suite *
make_libempathy_suite (void)
{
Suite *s = suite_create ("libempathy");
suite_add_tcase (s, make_empathy_utils_tcase ());
return s;
}
int
main (void)
{
int number_failed = 0;
Suite *s;
SRunner *sr;
check_helpers_init ();
g_type_init ();
s = make_libempathy_suite ();
sr = srunner_create (s);
srunner_run_all (sr, CK_NORMAL);
number_failed += srunner_ntests_failed (sr);
srunner_free (sr);
return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
}
{
<dlopen>
Addrcheck,Memcheck:Cond
obj:/lib/ld-2.5.so
obj:/lib/ld-2.5.so
obj:/lib/ld-2.5.so
obj:/lib/i686/cmov/libdl-2.5.so
obj:/lib/ld-2.5.so
obj:/lib/i686/cmov/libdl-2.5.so
fun:dlopen
}
{
<dlopen>
Addrcheck,Memcheck:Addr4
obj:/lib/ld-2.5.so
obj:/lib/ld-2.5.so
obj:/lib/ld-2.5.so
obj:/lib/ld-2.5.so
obj:/lib/ld-2.5.so
obj:/lib/ld-2.5.so
obj:/lib/i686/cmov/libdl-2.5.so
obj:/lib/ld-2.5.so
obj:/lib/i686/cmov/libdl-2.5.so
fun:dlopen
}
{
<dlopen>
Addrcheck,Memcheck:Cond
obj:/lib/ld-2.5.so
obj:/lib/ld-2.5.so
obj:/lib/ld-2.5.so
obj:/lib/ld-2.5.so
obj:/lib/i686/cmov/libdl-2.5.so
obj:/lib/ld-2.5.so
obj:/lib/i686/cmov/libdl-2.5.so
fun:dlopen
}
{
<dlsym>
Addrcheck,Memcheck:Addr4
obj:/lib/ld-2.5.so
obj:/lib/ld-2.5.so
obj:/lib/ld-2.5.so
obj:/lib/i686/cmov/libc-2.5.so
fun:_dl_sym
obj:/lib/i686/cmov/libdl-2.5.so
obj:/lib/ld-2.5.so
obj:/lib/i686/cmov/libdl-2.5.so
fun:dlsym
}
{
<dlsym>
Addrcheck,Memcheck:Cond
obj:/lib/ld-2.5.so
obj:/lib/ld-2.5.so
obj:/lib/ld-2.5.so
obj:/lib/i686/cmov/libc-2.5.so
fun:_dl_sym
obj:/lib/i686/cmov/libdl-2.5.so
obj:/lib/ld-2.5.so
obj:/lib/i686/cmov/libdl-2.5.so
fun:dlsym
}
{
<dlopen>
Addrcheck,Memcheck:Addr1
fun:malloc
obj:/lib/ld-2.5.so
obj:/lib/ld-2.5.so
obj:/lib/ld-2.5.so
obj:/lib/ld-2.5.so
obj:/lib/ld-2.5.so
obj:/lib/ld-2.5.so
obj:/lib/ld-2.5.so
obj:/lib/i686/cmov/libdl-2.5.so
obj:/lib/ld-2.5.so
obj:/lib/i686/cmov/libdl-2.5.so
fun:dlopen
}
{
<dlopen>
Addrcheck,Memcheck:Addr1
fun:malloc
obj:/lib/ld-2.5.so
obj:/lib/ld-2.5.so
obj:/lib/ld-2.5.so
obj:/lib/ld-2.5.so
obj:/lib/ld-2.5.so
obj:/lib/ld-2.5.so
obj:/lib/ld-2.5.so
obj:/lib/i686/cmov/libdl-2.5.so
obj:/lib/ld-2.5.so
obj:/lib/i686/cmov/libdl-2.5.so
fun:dlopen
}
{
<dlopen>
Addrcheck,Memcheck:Addr1
fun:malloc
obj:/lib/ld-2.5.so
obj:/lib/ld-2.5.so
obj:/lib/ld-2.5.so
obj:/lib/ld-2.5.so
obj:/lib/ld-2.5.so
obj:/lib/ld-2.5.so
obj:/lib/ld-2.5.so
obj:/lib/i686/cmov/libdl-2.5.so
obj:/lib/ld-2.5.so
obj:/lib/i686/cmov/libdl-2.5.so
fun:dlopen
}
{
<libdl>
Addrcheck,Memcheck:Addr4
obj:/lib/ld-2.5.so
obj:/lib/ld-2.5.so
obj:/lib/ld-2.5.so
obj:/lib/ld-2.5.so
obj:/lib/ld-2.5.so
obj:/lib/ld-2.5.so
obj:/lib/ld-2.5.so
obj:/lib/ld-2.5.so
obj:/lib/ld-2.5.so
obj:/lib/i686/cmov/libdl-2.5.so
obj:/lib/ld-2.5.so
obj:/lib/i686/cmov/libdl-2.5.so
}
### this file contains suppressions for valgrind when running
### the gibber/telepathy-salut unit tests based on the gstreamer one
### syscall suppressions
{
<clone on Wim's Debian>
Memcheck:Param
clone(parent_tidptr)
fun:clone
fun:clone
}
{
<clone on Wim's Debian>
Memcheck:Param
clone(child_tidptr)
fun:clone
fun:clone
}
{
<clone on Wim's Debian>
Memcheck:Param
clone(tlsinfo)
fun:clone
fun:clone
}
### glibc suppressions
{
<conditional jump on wim's debian 2/2/06>
Memcheck:Cond
obj:/lib/ld-2.3.*.so
fun:dl_open_worker
obj:/lib/ld-2.3.*.so
fun:_dl_open
fun:dlopen_doit
obj:/lib/ld-2.3.*.so
fun:_dlerror_run
fun:dlopen@@GLIBC_2.1
fun:g_module_open
}
# glibc does not deallocate thread-local storage
{
<tls>
Memcheck:Leak
fun:calloc
fun:_dl_allocate_tls
fun:pthread_create@@*
}
# I get an extra stack entry on x86/dapper
{
<tls>
Memcheck:Leak
fun:calloc
obj:/lib/ld-2.3.*.so
fun:_dl_allocate_tls
fun:pthread_create@@*
}
{
<pthread strstr>
Memcheck:Cond
fun:strstr
fun:__pthread_initialize_minimal
obj:/lib/libpthread-*.so
obj:/lib/libpthread-*.so
fun:call_init
fun:_dl_init
obj:/lib/ld-*.so
}
# a thread-related free problem in glibc from Edgard
{
__libc_freeres_rw_acess
Memcheck:Addr4
obj:*
obj:*
obj:*
obj:*
obj:*
fun:__libc_freeres
}
{
<a conditional jump on wim's debian>
Memcheck:Cond
obj:/lib/ld-2.3.*.so
obj:/lib/ld-2.3.*.so
obj:/lib/ld-2.3.*.so
obj:/lib/ld-2.3.*.so
obj:/lib/ld-2.3.*.so
}
# g_module_open-related problems
{
<started showing up on fc4-quick>
Memcheck:Addr2
fun:memcpy
fun:_dl_map_object_deps
fun:dl_open_worker
fun:_dl_catch_error
fun:_dl_open
fun:dlopen_doit
fun:_dl_catch_error
fun:_dlerror_run
fun:dlopen@@GLIBC_2.1
fun:g_module_open
}
{
<started showing up on fc4-quick>
Memcheck:Addr4
fun:memcpy
fun:_dl_map_object_deps
fun:dl_open_worker
fun:_dl_catch_error
fun:_dl_open
fun:dlopen_doit
fun:_dl_catch_error
fun:_dlerror_run
fun:dlopen@@GLIBC_2.1
fun:g_module_open
}
{
<g_module_open on wim's debian>
Memcheck:Cond
obj:/lib/ld-2.3.*.so
obj:/lib/ld-2.3.*.so
obj:/lib/ld-2.3.*.so
fun:do_sym
fun:_dl_sym
fun:dlsym_doit
obj:/lib/ld-2.3.*.so
fun:_dlerror_run
fun:dlsym
fun:g_module_symbol
fun:g_module_open
}
{
<g_module_open on wim's debian>
Memcheck:Cond
obj:/lib/ld-2.3.*.so
obj:/lib/ld-2.3.*.so
obj:/lib/ld-2.3.*.so
fun:dl_open_worker
obj:/lib/ld-2.3.*.so
fun:_dl_open
fun:dlopen_doit
obj:/lib/ld-2.3.*.so
fun:_dlerror_run
fun:dlopen@@GLIBC_2.1
fun:g_module_open
}
{
<g_module_open on wim's debian>
Memcheck:Cond
obj:/lib/ld-2.3.*.so
fun:dl_open_worker
obj:/lib/ld-2.3.*.so
fun:_dl_open
fun:dlopen_doit
obj:/lib/ld-2.3.*.so
fun:_dlerror_run
fun:dlopen@@GLIBC_2.1
fun:g_module_open
}
{
<leak on wim's debian in g_module_open>
Memcheck:Leak
fun:malloc
obj:/lib/ld-2.3.*.so
fun:dl_open_worker
obj:/lib/ld-2.3.*.so
fun:_dl_open
fun:dlopen_doit
obj:/lib/ld-2.3.*.so