Commit 533044c5 authored by Stef Walter's avatar Stef Walter

Makefile.am: Use parallel tests for 'make check'

Also build in a 'make check-memory' and related functionality
which drives valgrind.
parent 4f0b8a25
......@@ -57,7 +57,7 @@ config.status
config.status.lineno
config.sub
/configure
/install-sh
install-sh
/intltool-extract
/intltool-extract.in
/intltool-merge
......@@ -81,8 +81,15 @@ depcomp
/junk
/TODO.tasks
/build/
/test-*
/frob-*
/dump-*
/*-standalone
/gnome-keyring-3
/valgrind-suppressions
/build/coverage
/build/test-driver
/docs/*/html/
/docs/gnome-keyring-daemon/prompter.xml
......
......@@ -4,14 +4,7 @@ SUBDIRS = \
. \
po
ACLOCAL_AMFLAGS = ${ACLOCAL_FLAGS}
EXTRA_DIST = \
intltool-extract.in \
intltool-merge.in \
intltool-update.in \
ChangeLog.old \
HACKING
ACLOCAL_AMFLAGS = -I build/m4 ${ACLOCAL_FLAGS}
DISTCHECK_CONFIGURE_FLAGS = \
--enable-doc \
......@@ -70,27 +63,32 @@ asn1-reparse:
sed -i 's|#include.*|/* \0 */|' $$a.h \
done
test: $(TEST_PROGS)
gtester --verbose -m $(TEST_MODE) --g-fatal-warnings $(TEST_PROGS)
check-local: test
all-local: $(check_PROGRAMS)
TEST_ARGS =
TEST_SUPPRESSIONS = $(top_builddir)/build/valgrind-suppressions
perform-memcheck: $(TEST_PROGS)
make -C $(top_builddir)/build all
@for test in $(TEST_PROGS); do \
G_SLICE=always-malloc libtool --mode=execute \
valgrind --trace-children=no --gen-suppressions=all \
--suppressions=$(TEST_SUPPRESSIONS) \
--leak-check=full --show-reachable=yes --num-callers=16 \
--quiet --error-exitcode=3 \
$(builddir)/$$test $(TEST_ARGS) || exit 3; \
done
# Default executable tests
LOG_DRIVER = $(srcdir)/build/tap-driver
LOG_DRIVER_FLAGS = --format=tap
LOG_COMPILER = $(srcdir)/build/tap-gtester
VALGRIND_ARGS = --trace-children=no --quiet --error-exitcode=33 \
--suppressions=valgrind-suppressions --gen-suppressions=all \
--num-callers=16
VALGRIND_SUPPRESSIONS = \
build/gcr.supp \
build/gcrypt.supp \
build/glib.supp \
build/glibc.supp \
build/p11-kit.supp \
build/pthread.supp \
build/unknown.supp
valgrind-suppressions: $(VALGRIND_SUPPRESSIONS)
$(AM_V_GEN) cat $^ > $@
check-memory: valgrind-suppressions
$(MAKE) LOG_FLAGS="-- libtool --mode=execute valgrind $(VALGRIND_ARGS)" \
$(AM_MAKEFLAGS) check
recheck-memory: valgrind-suppressions
$(MAKE) LOG_FLAGS="-- libtool --mode=execute valgrind $(VALGRIND_ARGS)" \
$(AM_MAKEFLAGS) recheck
coverage:
mkdir -p $(top_builddir)/build/coverage
......@@ -162,22 +160,31 @@ AM_CPPFLAGS = \
$(GLIB_CFLAGS)
bin_PROGRAMS =
check_PROGRAMS = $(TEST_PROGS)
check_PROGRAMS =
noinst_DATA =
noinst_LIBRARIES =
noinst_LTLIBRARIES =
noinst_PROGRAMS =
noinst_PROGRAMS = $(check_PROGRAMS)
TESTS =
ASN1_FILES =
BUILT_SOURCES = prep-builddir
CLEANFILES = $(BUILT_SOURCES)
TEST_PROGS =
moduledir = $(pkcs11standalonedir)
module_LTLIBRARIES =
EXTRA_DIST += \
$(ASN1_FILES)
EXTRA_DIST = \
intltool-extract.in \
intltool-merge.in \
intltool-update.in \
ChangeLog.old \
HACKING \
$(ASN1_FILES) \
build/tap-driver \
build/tap-gtester \
$(VALGRIND_SUPPRESSIONS) \
$(NULL)
include egg/Makefile.am
include daemon/Makefile.am
......
{
gcr_pkcs11_set_trust_store_uri
Memcheck:Leak
...
fun:g_strdup
fun:gcr_pkcs11_set_trust_store_uri
}
{
gcr_pkcs11_set_trust_lookup_uris
Memcheck:Leak
...
fun:g_strdupv
fun:gcr_pkcs11_set_trust_lookup_uris
}
{
gpg_err_init
Memcheck:Leak
...
fun:gpg_err_init
}
{
_gcry_module_add
Memcheck:Leak
...
fun:_gcry_module_add
}
{
_gcry_rngcsprng_create_nonce
Memcheck:Leak
...
fun:_gcry_malloc
...
fun:initialize
fun:_gcry_rngcsprng_create_nonce
}
{
_gcry_rngcsprng_create_nonce
Memcheck:Leak
...
fun:_gcry_malloc
...
fun:initialize
fun:_gcry_rngcsprng_randomize
}
{
gcry_control__init
Memcheck:Leak
...
fun:glib_thread_mutex_init
...
fun:_gcry_vcontrol
fun:gcry_control
}
{
g_type_register_static_1
Memcheck:Leak
...
fun:g_type_register_static
}
{
g_type_register_fundamental
Memcheck:Leak
...
fun:g_type_register_fundamental
}
{
g_type_init_with_debug_flags
Memcheck:Leak
...
fun:g_type_init_with_debug_flags
}
{
g_type_class_ref
Memcheck:Leak
...
fun:g_type_class_ref
}
{
g_type_add_interface_static
Memcheck:Leak
...
fun:g_type_add_interface_static
}
{
g_param_spec_internal
Memcheck:Leak
...
fun:g_type_class_ref
fun:g_type_create_instance
fun:g_param_spec_internal
}
{
g_param_spec_enum
Memcheck:Leak
...
fun:g_type_class_ref
fun:g_param_spec_enum
}
{
g_param_spec_flags
Memcheck:Leak
...
fun:g_type_class_ref
fun:g_param_spec_flags
}
{
g_quark_from_static_string
Memcheck:Leak
...
fun:g_quark_from_static_string
}
{
g_quark_from_string
Memcheck:Leak
...
fun:g_quark_from_string
}
{
g_value_register_transform_func
Memcheck:Leak
...
fun:g_value_register_transform_func
}
{
test_run_seed
Memcheck:Leak
...
fun:g_rand_new_with_seed_array
fun:test_run_seed
...
fun:g_test_run_suite
}
{
g_test_init
Memcheck:Leak
...
fun:g_test_init
}
{
g_intern_static_string
Memcheck:Leak
...
fun:g_intern_static_string
}
{
g_main_context_push_thread_default
Memcheck:Leak
...
fun:g_queue_new
fun:g_main_context_push_thread_default
}
{
g_dbus_error_register_error
Memcheck:Leak
...
fun:g_dbus_error_register_error
}
{
g_param_spec_pool_insert
Memcheck:Leak
...
fun:g_param_spec_pool_insert
}
{
g_main_context_default
Memcheck:Leak
...
fun:g_main_context_default
}
{
g_main_context_check
Memcheck:Leak
...
fun:g_ptr_array_add
fun:g_main_context_check
}
{
g_test_run_suite
Memcheck:Leak
...
fun:g_slist_copy
fun:g_test_run_suite_internal
fun:g_test_run_suite
}
{
g_dbus_interface_info_cache_build
Memcheck:Leak
...
fun:g_dbus_interface_info_cache_build
}
{
g_cancellable_push_current
Memcheck:Leak
...
fun:thread_memory_from_self
...
fun:g_cancellable_push_current
}
{
g_io_scheduler_push_job
Memcheck:Leak
...
fun:init_scheduler
fun:g_once_impl
fun:g_io_scheduler_push_job
}
{
g_io_scheduler_push_job_2
Memcheck:Leak
...
fun:g_system_thread_new
...
fun:g_io_scheduler_push_job
}
{
g_bus_get_sync__available_connections
Memcheck:Leak
...
fun:g_hash_table_new
fun:initable_init
fun:g_initable_init
fun:g_bus_get_sync
}
{
g_socket_connection_factory_register_type
Memcheck:Leak
...
fun:g_socket_connection_factory_register_type
}
{
g_test_add_vtable
Memcheck:Leak
...
fun:g_test_add_vtable
}
{
g_mutex_lock
Memcheck:Leak
...
fun:g_mutex_impl_new
fun:g_mutex_get_impl
fun:g_mutex_lock
}
{
g_thread_self
Memcheck:Leak
...
fun:g_thread_self
}
{
g_rec_mutex_lock
Memcheck:Leak
...
fun:g_rec_mutex_impl_new
fun:g_rec_mutex_get_impl
fun:g_rec_mutex_lock
}
{
test_case_run
Memcheck:Leak
...
fun:g_malloc0
fun:test_case_run
...
fun:g_test_run_suite
}
{
g_get_charset
Memcheck:Leak
...
fun:g_get_charset
}
{
g_test_run_suite__timer_new
Memcheck:Leak
...
fun:g_timer_new
fun:test_case_run
...
fun:g_test_run_suite
}
{
g_test_run_suite__timer_new2
Memcheck:Leak
...
fun:g_timer_new
fun:test_case_run*
...
fun:g_test_run_suite
}
{
g_test_run_suite__strconcat
Memcheck:Leak
...
fun:g_strconcat
fun:test_case_run
...
fun:g_test_run_suite
fun:g_test_run
}
{
g_type_interface_add_prerequisite
Memcheck:Leak
...
fun:g_type_interface_add_prerequisite
}
{
g_test_run_suite_2
Memcheck:Leak
...
fun:g_slist_copy
fun:g_test_run_suite_internal
...
fun:g_test_run_suite
}
{
g_test_run_suite_3
Memcheck:Leak
...
fun:g_malloc0
fun:g_test_run_suite_internal
...
fun:g_test_run_suite
}
{
g_set_prgname
Memcheck:Leak
...
fun:g_set_prgname
}
{
g_test_run_suite__strconcat_2
Memcheck:Leak
...
fun:g_strconcat
fun:g_test_run_suite_internal
}
{
g_test_run_suite__strdup
Memcheck:Leak
...
fun:g_strdup
fun:g_test_run_suite_internal
}
{
g_private_get
Memcheck:Leak
...
fun:g_private_get
}
{
g_private_set
Memcheck:Leak
...
fun:g_private_set
}
{
g_static_private_set_1
Memcheck:Leak
...
fun:g_array_set_size
fun:g_static_private_set
}
{
g_static_private_set_2
Memcheck:Leak
...
fun:g_array_sized_new
fun:g_static_private_set
}
{
g_static_mutex_get_mutex_impl
Memcheck:Leak
...
fun:g_static_mutex_get_mutex_impl
}
{
g_variant_type_info_unref
Memcheck:Leak
...
fun:g_hash_table_remove
fun:g_variant_type_info_unref
}
{
g_get_filename_charsets
Memcheck:Leak
...
fun:g_get_filename_charsets
}
{
g_intern_string
Memcheck:Leak
...
fun:g_intern_string
}
{
g_main_context_iterate
Memcheck:Leak
...
fun:g_malloc
fun:g_main_context_iterate
}
{
g_main_context_dispatch
Memcheck:Leak
...
fun:get_dispatch
fun:g_main_context_dispatch
}
{
g_log_set_handler
Memcheck:Leak
...
fun:g_log_set_handler
}
{
g_simple_async_result_complete
Memcheck:Leak
...
fun:g_main_context_push_thread_default
fun:g_simple_async_result_complete
}
{
<insert_a_suppression_name_here>
Memcheck:Leak
...
fun:g_static_private_set
fun:g_module_open
}
{
g_child_watch_source_new
Memcheck:Leak
...
fun:ensure_unix_signal_handler_installed_unlocked
fun:g_child_watch_source_new
}
{
g_thread_pool_thread_proxy
Memcheck:Leak
...
fun:g_malloc
fun:g_cond_new_posix_impl
...
fun:g_async_queue_timed_pop
fun:g_thread_pool_thread_proxy
}
{
g_module_open
Memcheck:Leak
...
fun:g_private_impl_new
...
fun:g_module_open
}
{
g_system_thread_new
Memcheck:Leak
...
fun:g_system_thread_new
}
{
thread_memory_from_self
Memcheck:Leak
...
fun:thread_memory_from_self
}
{
g_get_language_names
Memcheck:Leak
...
fun:g_get_language_names
}
{
dlclose
Memcheck:Leak
...
fun:dlclose
}
{
dlopen
Memcheck:Leak
...
fun:_dlerror_run
fun:dlopen@@GLIBC_2.2.5
}
{
_p11_library_get_thread_local
Memcheck:Leak
...
fun:_p11_library_get_thread_local
}
{
pixman
Memcheck:Leak
fun:malloc
obj:/usr/lib64/libpixman-1.so.0.22.2
}
{
_dl_allocate_tls
Memcheck:Leak
...
fun:_dl_allocate_tls
fun:pthread_create*
}
#!/usr/bin/python
# Copyright (C) 2013 Red Hat, Inc.
#
# Cockpit 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.
#
# Cockpit 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 Cockpit; If not, see <http://www.gnu.org/licenses/>.
#
# This is a TAP driver for automake
#
# In particular it leaves stderr untouched, and is cleaner than the
# one implemented in shell that is making the rounds.
#
# This implements the automake "Custom Test Driver" protocol:
# https://www.gnu.org/software/automake/manual/html_node/Custom-Test-Drivers.html
#
# This consumes the Test Anything Protocol (ie: TAP)
# https://metacpan.org/pod/release/PETDANCE/Test-Harness-2.64/lib/Test/Harness/TAP.pod
#
import argparse
import os
import select
import subprocess
import sys
class Driver:
def __init__(self, args):
self.argv = args.command
self.test_name = args.test_name
self.log = open(args.log_file, "w")
self.log.write("# %s\n" % " ".join(sys.argv))
self.trs = open(args.trs_file, "w")
self.color_tests = args.color_tests
self.expect_failure = args.expect_failure
def report(self, code, *args):
CODES = {
"XPASS": '\x1b[0;31m', # red
"FAIL": '\x1b[0;31m', # red
"PASS": '\x1b[0;32m', # grn
"XFAIL": '\x1b[1;32m', # lgn
"SKIP": '\x1b[1;34m', # blu
"ERROR": '\x1b[0;35m', # mgn
}
# Print out to console
if self.color_tests:
if code in CODES:
sys.stdout.write(CODES[code])
sys.stdout.write(code)
if self.color_tests:
sys.stdout.write('\x1b[m')
sys.stdout.write(": ")
sys.stdout.write(self.test_name)
sys.stdout.write(" ")
for arg in args:
sys.stdout.write(str(arg))
sys.stdout.write("\n")
sys.stdout.flush()
# Book keeping
if code in CODES:
self.trs.write(":test-result: %s\n" % code)
def result_pass(self, *args):
if self.expect_failure:
self.report("XPASS", *args)
else:
self.report("PASS", *args)
def result_fail(self, *args):
if self.expect_failure:
self.report("XFAIL", *args)
else:
self.report("FAIL", *args)
def result_skip(self, *args):
if self.expect_failure:
self.report("XFAIL", *args)
else:
self.report("SKIP", *args)
def report_error(self, description=""):
self.report("ERROR", "", description)
def process(self, output):
pass
def execute(self):
try:
proc = subprocess.Popen(self.argv, close_fds=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
except OSError, ex:
self.report_error("Couldn't run %s: %s" % (self.argv[0], str(ex)))
return
outf = proc.stdout.fileno()
errf = proc.stderr.fileno()
rset = [outf, errf]
while len(rset) > 0:
ret = select.select(rset, [], [], 10)
if outf in ret[0]:
data = os.read(outf, 1024)
if data == "":
rset.remove(outf)
self.log.write(data)
self.process(data)
if errf in ret[0]:
data = os.read(errf, 1024)
if data == "":
rset.remove(errf)
self.log.write(data)
sys.stderr.write(data)
proc.wait()
return proc.returncode
class TapDriver(Driver):
def __init__(self, args):
Driver.__init__(self, args)
self.output = ""
self.reported = { }
self.test_plan = None
self.late_plan = False
self.errored = False
self.bail_out = False