@matheusbsbs / matheus-bagliano / commits / 4e1be63c3b
Fork 0

Add valgrind support in test scripts

This patch adds the ability to use valgrind's memcheck tool to diagnose memory problems in Git while running the test scripts. It requires valgrind 3.4.0 or newer. It works by creating symlinks to a valgrind script, which have the same name as our Git binaries, and then putting that directory in front of the test script's PATH as well as set GIT_EXEC_PATH to that directory. Git scripts are symlinked from that directory directly. That way, Git binaries called by Git scripts are valgrinded, too. Valgrind can be used by specifying "GIT_TEST_OPTS=--valgrind" in the make invocation. Any invocation of git that finds any errors under valgrind will exit with failure code 126. Any valgrind output will go to the usual stderr channel for tests (i.e., /dev/null, unless -v has been specified). If you need to pass options to valgrind -- you might want to run another tool than memcheck, for example -- you can set the environment variable GIT_VALGRIND_OPTIONS. A few default suppressions are included, since libz seems to trigger quite a few false positives. We'll assume that libz works and that we can ignore any errors which are reported there. Note: it is safe to run the valgrind tests in parallel, as the links in t/valgrind/bin/ are created using proper locking. Initial patch and all the hard work by Jeff King. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Johannes Schindelin committed Feb 4, 2009 at 00:25 UTC 4e1be63c3b05fd379b51b611b7e869ff6977d8ab
5 files changed +99 -3
t/README
+7 -1
@@ -39,7 +39,8 @@ this:
39 * passed all 3 test(s)
40
41 You can pass --verbose (or -v), --debug (or -d), and --immediate
42 -(or -i) command line argument to the test.
42 +(or -i) command line argument to the test, or by setting GIT_TEST_OPTS
43 +appropriately before running "make".
44
45 --verbose::
46 This makes the test more verbose. Specifically, the
@@ -58,6 +59,11 @@ You can pass --verbose (or -v), --debug (or -d), and --immediate
59 This causes additional long-running tests to be run (where
60 available), for more exhaustive testing.
61
62 +--valgrind::
63 + Execute all Git binaries with valgrind and exit with status
64 + 126 on errors (just like regular tests, this will only stop
65 + the test script when running under -i). Valgrind errors
66 + go to stderr, so you might want to pass the -v option, too.
67
68 Skipping Tests
69 --------------
t/test-lib.sh
+56 -2
@@ -94,6 +94,8 @@ do
94 --no-python)
95 # noop now...
96 shift ;;
97 + --va|--val|--valg|--valgr|--valgri|--valgrin|--valgrind)
98 + valgrind=t; shift ;;
99 *)
100 break ;;
101 esac
@@ -492,8 +494,60 @@ test_done () {
494 # Test the binaries we have just built. The tests are kept in
495 # t/ subdirectory and are run in 'trash directory' subdirectory.
496 TEST_DIRECTORY=$(pwd)
495 -PATH=$TEST_DIRECTORY/..:$PATH
496 -GIT_EXEC_PATH=$(pwd)/..
497 +if test -z "$valgrind"
498 +then
499 + PATH=$TEST_DIRECTORY/..:$PATH
500 + GIT_EXEC_PATH=$TEST_DIRECTORY/..
501 +else
502 + make_symlink () {
503 + test -h "$2" &&
504 + test "$1" = "$(readlink "$2")" || {
505 + # be super paranoid
506 + if mkdir "$2".lock
507 + then
508 + rm -f "$2" &&
509 + ln -s "$1" "$2" &&
510 + rm -r "$2".lock
511 + else
512 + while test -d "$2".lock
513 + do
514 + say "Waiting for lock on $2."
515 + sleep 1
516 + done
517 + fi
518 + }
519 + }
520 +
521 + make_valgrind_symlink () {
522 + # handle only executables
523 + test -x "$1" || return
524 +
525 + base=$(basename "$1")
526 + symlink_target=$TEST_DIRECTORY/../$base
527 + # do not override scripts
528 + if test -x "$symlink_target" &&
529 + test ! -d "$symlink_target" &&
530 + test "#!" != "$(head -c 2 < "$symlink_target")"
531 + then
532 + symlink_target=../valgrind.sh
533 + fi
534 + # create the link, or replace it if it is out of date
535 + make_symlink "$symlink_target" "$GIT_VALGRIND/bin/$base" || exit
536 + }
537 +
538 + # override all git executables in TEST_DIRECTORY/..
539 + GIT_VALGRIND=$TEST_DIRECTORY/valgrind
540 + mkdir -p "$GIT_VALGRIND"/bin
541 + for file in $TEST_DIRECTORY/../git* $TEST_DIRECTORY/../test-*
542 + do
543 + make_valgrind_symlink $file
544 + done
545 + PATH=$GIT_VALGRIND/bin:$PATH
546 + GIT_EXEC_PATH=$GIT_VALGRIND/bin
547 + export GIT_VALGRIND
548 +
549 + make_symlink ../../../templates "$GIT_VALGRIND"/bin/templates || exit
550 +fi
551 GIT_TEMPLATE_DIR=$(pwd)/../templates/blt
552 unset GIT_CONFIG
553 GIT_CONFIG_NOSYSTEM=1
t/valgrind/.gitignore new
+2
@@ -0,0 +1,2 @@
1 +/bin/
2 +/templates
t/valgrind/default.supp new
+21
@@ -0,0 +1,21 @@
1 +{
2 + ignore-zlib-errors-cond
3 + Memcheck:Cond
4 + obj:*libz.so*
5 +}
6 +
7 +{
8 + ignore-zlib-errors-value4
9 + Memcheck:Value4
10 + obj:*libz.so*
11 +}
12 +
13 +{
14 + writing-data-from-zlib-triggers-errors
15 + Memcheck:Param
16 + write(buf)
17 + obj:/lib/ld-*.so
18 + fun:write_in_full
19 + fun:write_buffer
20 + fun:write_loose_object
21 +}
t/valgrind/valgrind.sh new
+13
@@ -0,0 +1,13 @@
1 +#!/bin/sh
2 +
3 +base=$(basename "$0")
4 +
5 +exec valgrind -q --error-exitcode=126 \
6 + --leak-check=no \
7 + --suppressions="$GIT_VALGRIND/default.supp" \
8 + --gen-suppressions=all \
9 + --track-origins=yes \
10 + --log-fd=4 \
11 + --input-fd=4 \
12 + $GIT_VALGRIND_OPTIONS \
13 + "$GIT_VALGRIND"/../../"$base" "$@"