Browse Source

Merge branch 'work/valgrind'

Michal 'vorner' Vaner 14 years ago
parent
commit
8053d85447
3 changed files with 142 additions and 2 deletions
  1. 3 2
      tools/README
  2. 75 0
      tools/tests_in_valgrind.sh
  3. 64 0
      tools/valgrind_test_cleaner.pl

+ 3 - 2
tools/README

@@ -1,3 +1,4 @@
 The "tools" directory contains scripts for helping the BIND 10
-developers maintain the source tree. These are not intended
-to be built nor installed by the build system.
+developers with various tasks, eg. maintaining the source tree,
+running some tests. These are not intended to be built nor
+installed by the build system.

+ 75 - 0
tools/tests_in_valgrind.sh

@@ -0,0 +1,75 @@
+#!/bin/sh
+
+###########################################
+# This script runs all tests in valgrind. Configure and compile bind the way
+# you want it to be tested (you should use --with-gtest, however, or you get
+# no tests). Then run this script from the top build directory.
+#
+# Note that the test isn't what you would call "production quality" (it is
+# expected to be used by the bind10 developers, not end user) and might break,
+# some ways of breaking it are known.
+#
+# There are two variables that modify it's behaviour.
+# * VALGRIND_FLAGS are the flag passed to valgrind. There are some, hopefully
+#      reasonable defaults which you can overwrite. Note that the variable is
+#      used unmodified inside a sed pattern with # as a modifier, which can
+#      easily break it. There was no motivation to fix this.
+# * VALGRIND_FILE is the file to store the output into. Default is valgrind.log
+###########################################
+
+# First, make sure the tests are up to date
+make
+
+if [ $? = 2 ] ; then
+    echo "Did you run configure? Or maybe you're running the script from the tools directory? (you need to run it from the top bind10 build directory)"
+    exit 1
+fi
+
+set -e
+
+# Some configuration
+# TODO Escape for sed, this might break
+LOGFILE="${VALGRIND_FILE:-`pwd`/valgrind.log}"
+FLAGS="${VALGRIND_FLAGS:---leak-check=full --track-fds=yes}"
+FLAGS="$FLAGS --log-file=$LOGFILE.%p"
+
+FOUND_ANY=false
+FAILED=
+
+# Find all the tests (yes, doing it by a name is a nasty hack)
+# Since the while runs in a subprocess, we need to get the assignments out, done by the eval
+eval $(find . -type f -name run_unittests -print | grep -v '\.libs/run_unittests$' | while read testname ; do
+    sed -e 's#exec "#exec valgrind '"$FLAGS"' "#' "$testname" > "$testname.valgrind"
+    chmod +x "$testname.valgrind"
+    echo "$testname" >>"$LOGFILE"
+    echo "===============" >>"$LOGFILE"
+    OLDDIR="`pwd`"
+    cd $(dirname "$testname")
+    ./run_unittests.valgrind >&2 &
+    PID="$!"
+    set +e
+    wait "$PID"
+    CODE="$?"
+    set -e
+    cd "$OLDDIR"
+    if [ "$CODE" != 0 ] ; then
+        echo 'FAILED="$FAILED
+'"$testname"'"'
+    fi
+    NAME="$LOGFILE.$PID"
+    rm "$testname.valgrind"
+    # Remove the ones from death tests
+    grep "==$PID==" "$NAME" >>"$LOGFILE"
+    rm "$NAME"
+    echo 'FOUND_ANY=true'
+done)
+
+if test -n "$FAILED"; then
+    echo "These tests failed:" >&2
+    echo "$FAILED" >&2
+fi
+
+if ! $FOUND_ANY ; then
+    echo "No test was found. It is possible you configured without --with-gtest or you run it from wrong directory" >&2
+    exit 1
+fi

+ 64 - 0
tools/valgrind_test_cleaner.pl

@@ -0,0 +1,64 @@
+#!/usr/bin/perl
+use strict;
+use warnings;
+
+# This script can be used on a valgrind output of the tests (from
+# tests_in_valgrind.sh) to remove some uninteresting error reports.
+# Since we care about the tested application not leaking/crashing, not
+# the tests itself, memory leaks that are caused only by the tests
+# (eg. unreleased test data), we don't want to have logs full of them.
+#
+# This script does some heuristics to eliminate some of such error
+# reports. Currently, the memory lost reports whose stack contains
+# no call from the real application are suppressed.
+#
+# Of course, the rest still can contain many uninteresting entries.
+
+# Yes, it's perl even when we use python. I wrote it for myself when
+# I needed to clean the outputs and after it proved useful to me, I
+# thought it might be for others too, so I just included it. It's not
+# that we would be switching to perl. If it should grow in future to
+# include more heuristics and do something more fancy, we should probably
+# rewrite it in python instead.
+
+my ($block, $blockOK);
+
+sub endBlock(_) {
+	return unless $block;
+	if ($blockOK) {
+		print @$block;
+	}
+	undef $block;
+	undef $blockOK;
+}
+
+sub startBlock(_) {
+	$block = [@_];
+}
+
+sub addToBlock(_) {
+	my ($line) = @_;
+	push @$block, $line;
+	return unless $line =~ /^==\d+==\s+(at|by) 0x[0-9A-F]+: (.*) \(.+:\d+\)$/;
+	$_ = $2;
+	return $blockOK = 1 if /^isc::/;
+	return $blockOK = 1 if /^asiolink:/;
+	return if /^main \(/;
+	return if /^testing::/;
+	return if /^\(anonymous namespace\)::/;
+	$blockOK = 1;
+}
+
+while(<>) {
+	if (/^==\d+==\s*$/) {
+		print;
+		endBlock;
+	} elsif (/^==\d+==\s+\d+bytes.*lost in loss record/) {
+		startBlock;
+	} elsif ($block) {
+		addToBlock;
+	} else {
+		print;
+	}
+}
+endBlock;