--suppressions-list=tests/data/cppcheck.supp \
--enable=warning,performance,portability,style
-# Used by maintainers to run the main test suite under valgrind. Suppress
-# the xmalloc and pod-spelling tests because the former won't work properly
-# under valgrind (due to increased memory usage) and the latter is pointless
-# to run under valgrind. Don't try to trace several of the tests that are
-# written in Perl or shell and test Perl programs.
+# The full path to valgrind and its options, used when doing valgrind
+# testing.
+VALGRIND_COMMAND = $(PATH_VALGRIND) --leak-check=full \
+ --trace-children=yes --trace-children-skip=/bin/sh \
+ --suppressions=$(abs_top_srcdir)/tests/data/valgrind.supp \
+ --log-file=$(abs_top_builddir)/tests/tmp/valgrind/log.%p
+
+# Used by maintainers to run the main test suite under valgrind.
check-valgrind: $(check_PROGRAMS) tests/data/dictionary.pwd
- rm -rf $(abs_top_builddir)/tmp-valgrind
- mkdir $(abs_top_builddir)/tmp-valgrind
- env valgrind --leak-check=full \
- --show-reachable=yes --trace-children=yes \
- --log-file=$(abs_top_builddir)/tmp-valgrind/log.%p \
- --suppressions=$(abs_top_srcdir)/tests/data/valgrind.supp \
- --trace-children-skip="/bin/sh,*/cat,*/diff,*/expr,*/grep,*/mkdir,*/rm,*/rmdir,*/sed,*/sleep,*/true,*/wc,*/docs/*-t,*/perl/*-t,*/data/make-krb5-conf,*/tools/heimdal-history-t,*/tools/wordlist*-t" \
- tests/runtests -l '$(abs_top_srcdir)/tests/TESTS'
-
+ rm -rf $(abs_top_builddir)/tests/tmp
+ mkdir $(abs_top_builddir)/tests/tmp
+ mkdir $(abs_top_builddir)/tests/tmp/valgrind
+ C_TAP_VALGRIND="$(VALGRIND_COMMAND)" tests/runtests \
+ -l '$(abs_top_srcdir)/tests/TESTS'
# Used by maintainers to reformat all source code using clang-format and
# excluding some files.
--- /dev/null
+#!/usr/bin/perl
+#
+# Check for errors in valgrind logs.
+#
+# The canonical version of this file is maintained in the rra-c-util package,
+# which can be found at <https://www.eyrie.org/~eagle/software/rra-c-util/>.
+#
+# Copyright 2018-2019 Russ Allbery <eagle@eyrie.org>
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+# DEALINGS IN THE SOFTWARE.
+#
+# SPDX-License-Identifier: MIT
+
+use 5.008;
+use strict;
+use warnings;
+
+use lib "$ENV{C_TAP_SOURCE}/tap/perl";
+
+use Test::RRA;
+use Test::RRA::Automake qw(automake_setup);
+
+use File::Spec;
+use Test::More;
+
+# Skip this test if C_TAP_VALGRIND was not set.
+if (!exists $ENV{C_TAP_VALGRIND}) {
+ plan skip_all => 'Not testing under valgrind';
+}
+
+# Set up Automake testing.
+automake_setup({ chdir_build => 1 });
+
+# Gather the list of valgrind logs (and skip this test if there are none).
+opendir(my $logdir, File::Spec->catfile('tests', 'tmp', 'valgrind'))
+ or plan skip_all => 'No valgrind logs in tests/tmp/valgrind';
+my @logs = grep { m{ \A log [.] }xms } readdir $logdir;
+closedir($logdir) or BAIL_OUT("cannot close directory: $!");
+
+# Check each log file.
+plan tests => scalar(@logs);
+for my $file (@logs) {
+ my $path = File::Spec->catfile('tests', 'tmp', 'valgrind', $file);
+ open(my $log, '<', $path) or BAIL_OUT("cannot open $path: $!");
+ my $okay = 1;
+ my @log;
+ while (defined(my $line = <$log>)) {
+ push(@log, $line);
+ if ($line =~ m{ ERROR [ ] SUMMARY: [ ] (\d+) [ ] errors }xms) {
+ $okay = ($1 == 0);
+ }
+ }
+ close($log) or BAIL_OUT("cannot close $path: $!");
+ if ($okay) {
+ unlink($path);
+ } else {
+ for my $line (@log) {
+ print '# ', $line
+ or BAIL_OUT("cannot print to standard output: $!");
+ }
+ }
+ ok($okay, $path);
+}
+
+# Remove tests/tmp/valgrind if it's now empty.
+rmdir(File::Spec->catfile('tests', 'tmp', 'valgrind'));
+rmdir(File::Spec->catfile('tests', 'tmp'));