Merge branch 'ab/leak-check'

Extend SANITIZE=leak checking and declare more tests "currently leak-free".

* ab/leak-check:
  CI: use "GIT_TEST_SANITIZE_LEAK_LOG=true" in linux-leaks
  upload-pack: fix a memory leak in create_pack_file()
  leak tests: mark passing SANITIZE=leak tests as leak-free
  leak tests: don't skip some tests under SANITIZE=leak
  test-lib: have the "check" mode for SANITIZE=leak consider leak logs
  test-lib: add a GIT_TEST_PASSING_SANITIZE_LEAK=check mode
  test-lib: simplify by removing test_external
  tests: move copy/pasted PERL + Test::More checks to a lib-perl.sh
  t/Makefile: don't remove test-results in "clean-except-prove-cache"
  test-lib: add a SANITIZE=leak logging mode
  t/README: reword the "GIT_TEST_PASSING_SANITIZE_LEAK" description
  test-lib: add a --invert-exit-code switch
  test-lib: fix GIT_EXIT_OK logic errors, use BAIL_OUT
  test-lib: don't set GIT_EXIT_OK before calling test_atexit_handler
  test-lib: use $1, not $@ in test_known_broken_{ok,failure}_
This commit is contained in:
Junio C Hamano 2022-08-12 13:19:08 -07:00
commit 657c7403a3
57 changed files with 408 additions and 230 deletions

View File

@ -276,6 +276,7 @@ linux-musl)
linux-leaks) linux-leaks)
export SANITIZE=leak export SANITIZE=leak
export GIT_TEST_PASSING_SANITIZE_LEAK=true export GIT_TEST_PASSING_SANITIZE_LEAK=true
export GIT_TEST_SANITIZE_LEAK_LOG=true
;; ;;
esac esac

View File

@ -3,16 +3,9 @@
cd ../../../t cd ../../../t
test_description='git-credential-netrc' test_description='git-credential-netrc'
. ./test-lib.sh . ./test-lib.sh
. "$TEST_DIRECTORY"/lib-perl.sh
if ! test_have_prereq PERL; then skip_all_if_no_Test_More
skip_all='skipping perl interface tests, perl not available'
test_done
fi
perl -MTest::More -e 0 2>/dev/null || {
skip_all="Perl Test::More unavailable, skipping test"
test_done
}
# set up test repository # set up test repository
@ -20,13 +13,10 @@
'set up test repository' \ 'set up test repository' \
'git config --add gpg.program test.git-config-gpg' 'git config --add gpg.program test.git-config-gpg'
# The external test will outputs its own plan
test_external_has_tap=1
export PERL5LIB="$GITPERLLIB" export PERL5LIB="$GITPERLLIB"
test_external \ test_expect_success 'git-credential-netrc' '
'git-credential-netrc' \
perl "$GIT_BUILD_DIR"/contrib/credential/netrc/test.pl perl "$GIT_BUILD_DIR"/contrib/credential/netrc/test.pl
'
test_done test_done
) )

View File

@ -42,7 +42,7 @@ $(T):
@echo "*** $@ ***"; GIT_CONFIG=.git/config '$(SHELL_PATH_SQ)' $@ $(GIT_TEST_OPTS) @echo "*** $@ ***"; GIT_CONFIG=.git/config '$(SHELL_PATH_SQ)' $@ $(GIT_TEST_OPTS)
clean-except-prove-cache: clean-except-prove-cache:
$(RM) -r 'trash directory'.* '$(TEST_RESULTS_DIRECTORY_SQ)' $(RM) -r 'trash directory'.*
$(RM) -r valgrind/bin $(RM) -r valgrind/bin
clean: clean-except-prove-cache clean: clean-except-prove-cache

View File

@ -47,7 +47,7 @@ pre-clean:
$(RM) -r '$(TEST_RESULTS_DIRECTORY_SQ)' $(RM) -r '$(TEST_RESULTS_DIRECTORY_SQ)'
clean-except-prove-cache: clean-except-prove-cache:
$(RM) -r 'trash directory'.* '$(TEST_RESULTS_DIRECTORY_SQ)' $(RM) -r 'trash directory'.*
$(RM) -r valgrind/bin $(RM) -r valgrind/bin
clean: clean-except-prove-cache clean: clean-except-prove-cache

View File

@ -62,7 +62,7 @@ pre-clean:
$(RM) -r '$(TEST_RESULTS_DIRECTORY_SQ)' $(RM) -r '$(TEST_RESULTS_DIRECTORY_SQ)'
clean-except-prove-cache: clean-chainlint clean-except-prove-cache: clean-chainlint
$(RM) -r 'trash directory'.* '$(TEST_RESULTS_DIRECTORY_SQ)' $(RM) -r 'trash directory'.*
$(RM) -r valgrind/bin $(RM) -r valgrind/bin
clean: clean-except-prove-cache clean: clean-except-prove-cache

View File

@ -366,12 +366,47 @@ excluded as so much relies on it, but this might change in the future.
GIT_TEST_SPLIT_INDEX=<boolean> forces split-index mode on the whole GIT_TEST_SPLIT_INDEX=<boolean> forces split-index mode on the whole
test suite. Accept any boolean values that are accepted by git-config. test suite. Accept any boolean values that are accepted by git-config.
GIT_TEST_PASSING_SANITIZE_LEAK=<boolean> when compiled with GIT_TEST_PASSING_SANITIZE_LEAK=true skips those tests that haven't
SANITIZE=leak will run only those tests that have whitelisted declared themselves as leak-free by setting
themselves as passing with no memory leaks. Tests can be whitelisted "TEST_PASSES_SANITIZE_LEAK=true" before sourcing "test-lib.sh". This
by setting "TEST_PASSES_SANITIZE_LEAK=true" before sourcing test mode is used by the "linux-leaks" CI target.
"test-lib.sh" itself at the top of the test script. This test mode is
used by the "linux-leaks" CI target. GIT_TEST_PASSING_SANITIZE_LEAK=check checks that our
"TEST_PASSES_SANITIZE_LEAK=true" markings are current. Rather than
skipping those tests that haven't set "TEST_PASSES_SANITIZE_LEAK=true"
before sourcing "test-lib.sh" this mode runs them with
"--invert-exit-code". This is used to check that there's a one-to-one
mapping between "TEST_PASSES_SANITIZE_LEAK=true" and those tests that
pass under "SANITIZE=leak". This is especially useful when testing a
series that fixes various memory leaks with "git rebase -x".
GIT_TEST_SANITIZE_LEAK_LOG=true will log memory leaks to
"test-results/$TEST_NAME.leak/trace.*" files. The logs include a
"dedup_token" (see +"ASAN_OPTIONS=help=1 ./git") and other options to
make logs +machine-readable.
With GIT_TEST_SANITIZE_LEAK_LOG=true we'll look at the leak logs
before exiting and exit on failure if the logs showed that we had a
memory leak, even if the test itself would have otherwise passed. This
allows us to catch e.g. missing &&-chaining. This is especially useful
when combined with "GIT_TEST_PASSING_SANITIZE_LEAK", see below.
GIT_TEST_PASSING_SANITIZE_LEAK=check when combined with "--immediate"
will run to completion faster, and result in the same failing
tests. The only practical reason to run
GIT_TEST_PASSING_SANITIZE_LEAK=check without "--immediate" is to
combine it with "GIT_TEST_SANITIZE_LEAK_LOG=true". If we stop at the
first failing test case our leak logs won't show subsequent leaks we
might have run into.
GIT_TEST_PASSING_SANITIZE_LEAK=(true|check) will not catch all memory
leaks unless combined with GIT_TEST_SANITIZE_LEAK_LOG=true. Some tests
run "git" (or "test-tool" etc.) without properly checking the exit
code, or git will invoke itself and fail to ferry the abort() exit
code to the original caller. When the two modes are combined we'll
look at the "test-results/$TEST_NAME.leak/trace.*" files at the end of
the test run to see if had memory leaks which the test itself didn't
catch.
GIT_TEST_PROTOCOL_VERSION=<n>, when set, makes 'protocol.version' GIT_TEST_PROTOCOL_VERSION=<n>, when set, makes 'protocol.version'
default to n. default to n.
@ -935,32 +970,6 @@ see test-lib-functions.sh for the full list and their options.
test_done test_done
fi fi
- test_external [<prereq>] <message> <external> <script>
Execute a <script> with an <external> interpreter (like perl). This
was added for tests like t9700-perl-git.sh which do most of their
work in an external test script.
test_external \
'GitwebCache::*FileCache*' \
perl "$TEST_DIRECTORY"/t9503/test_cache_interface.pl
If the test is outputting its own TAP you should set the
test_external_has_tap variable somewhere before calling the first
test_external* function. See t9700-perl-git.sh for an example.
# The external test will outputs its own plan
test_external_has_tap=1
- test_external_without_stderr [<prereq>] <message> <external> <script>
Like test_external but fail if there's any output on stderr,
instead of checking the exit code.
test_external_without_stderr \
'Perl API' \
perl "$TEST_DIRECTORY"/t9700/test.pl
- test_expect_code <exit-code> <command> - test_expect_code <exit-code> <command>
Run a command and ensure that it exits with the given exit code. Run a command and ensure that it exits with the given exit code.

19
t/lib-perl.sh Normal file
View File

@ -0,0 +1,19 @@
# Copyright (c) 2022 Ævar Arnfjörð Bjarmason
test_lazy_prereq PERL_TEST_MORE '
perl -MTest::More -e 0
'
skip_all_if_no_Test_More () {
if ! test_have_prereq PERL
then
skip_all='skipping perl interface tests, perl not available'
test_done
fi
if ! test_have_prereq PERL_TEST_MORE
then
skip_all="Perl Test::More unavailable, skipping test"
test_done
fi
}

View File

@ -578,6 +578,78 @@ test_expect_success 'subtest: --run invalid range end' '
EOF_ERR EOF_ERR
' '
test_expect_success 'subtest: --invert-exit-code without --immediate' '
run_sub_test_lib_test_err full-pass \
--invert-exit-code &&
check_sub_test_lib_test_err full-pass \
<<-\EOF_OUT 3<<-EOF_ERR
ok 1 - passing test #1
ok 2 - passing test #2
ok 3 - passing test #3
# passed all 3 test(s)
1..3
# faking up non-zero exit with --invert-exit-code
EOF_OUT
EOF_ERR
'
test_expect_success 'subtest: --invert-exit-code with --immediate: all passed' '
run_sub_test_lib_test_err full-pass \
--invert-exit-code --immediate &&
check_sub_test_lib_test_err full-pass \
<<-\EOF_OUT 3<<-EOF_ERR
ok 1 - passing test #1
ok 2 - passing test #2
ok 3 - passing test #3
# passed all 3 test(s)
1..3
# faking up non-zero exit with --invert-exit-code
EOF_OUT
EOF_ERR
'
test_expect_success 'subtest: --invert-exit-code without --immediate: partial pass' '
run_sub_test_lib_test partial-pass \
--invert-exit-code &&
check_sub_test_lib_test partial-pass <<-\EOF
ok 1 - passing test #1
not ok 2 - # TODO induced breakage (--invert-exit-code): failing test #2
# false
ok 3 - passing test #3
# failed 1 among 3 test(s)
1..3
# faked up failures as TODO & now exiting with 0 due to --invert-exit-code
EOF
'
test_expect_success 'subtest: --invert-exit-code with --immediate: partial pass' '
run_sub_test_lib_test partial-pass \
--invert-exit-code --immediate &&
check_sub_test_lib_test partial-pass \
<<-\EOF_OUT 3<<-EOF_ERR
ok 1 - passing test #1
not ok 2 - # TODO induced breakage (--invert-exit-code): failing test #2
# false
1..2
# faked up failures as TODO & now exiting with 0 due to --invert-exit-code
EOF_OUT
EOF_ERR
'
test_expect_success 'subtest: --invert-exit-code --immediate: got a failure' '
run_sub_test_lib_test partial-pass \
--invert-exit-code --immediate &&
check_sub_test_lib_test_err partial-pass \
<<-\EOF_OUT 3<<-EOF_ERR
ok 1 - passing test #1
not ok 2 - # TODO induced breakage (--invert-exit-code): failing test #2
# false
1..2
# faked up failures as TODO & now exiting with 0 due to --invert-exit-code
EOF_OUT
EOF_ERR
'
test_expect_success 'subtest: tests respect prerequisites' ' test_expect_success 'subtest: tests respect prerequisites' '
write_and_run_sub_test_lib_test prereqs <<-\EOF && write_and_run_sub_test_lib_test prereqs <<-\EOF &&

View File

@ -65,7 +65,7 @@ test_expect_success 'check commit-tree' '
test_path_is_file "$REAL/objects/$(objpath $SHA)" test_path_is_file "$REAL/objects/$(objpath $SHA)"
' '
test_expect_success !SANITIZE_LEAK 'check rev-list' ' test_expect_success 'check rev-list' '
git update-ref "HEAD" "$SHA" && git update-ref "HEAD" "$SHA" &&
git rev-list HEAD >actual && git rev-list HEAD >actual &&
echo $SHA >expected && echo $SHA >expected &&

View File

@ -31,7 +31,7 @@ test_expect_success WRITE_TREE_OUT 'write-tree output on unwritable repository'
test_cmp expect out.write-tree test_cmp expect out.write-tree
' '
test_expect_success POSIXPERM,SANITY,!SANITIZE_LEAK 'commit should notice unwritable repository' ' test_expect_success POSIXPERM,SANITY 'commit should notice unwritable repository' '
test_when_finished "chmod 775 .git/objects .git/objects/??" && test_when_finished "chmod 775 .git/objects .git/objects/??" &&
chmod a-w .git/objects .git/objects/?? && chmod a-w .git/objects .git/objects/?? &&
test_must_fail git commit -m second 2>out.commit test_must_fail git commit -m second 2>out.commit

View File

@ -2,6 +2,7 @@
test_description='CRLF conversion all combinations' test_description='CRLF conversion all combinations'
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh . ./test-lib.sh
compare_files () { compare_files () {

View File

@ -5,6 +5,7 @@
test_description='reftable unittests' test_description='reftable unittests'
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh . ./test-lib.sh
test_expect_success 'unittests' ' test_expect_success 'unittests' '

View File

@ -2,6 +2,7 @@
test_description='verify safe.directory checks' test_description='verify safe.directory checks'
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh . ./test-lib.sh
GIT_TEST_ASSUME_DIFFERENT_OWNER=1 GIT_TEST_ASSUME_DIFFERENT_OWNER=1

View File

@ -5,6 +5,7 @@ test_description='Various filesystem issues'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh . ./test-lib.sh
auml=$(printf '\303\244') auml=$(printf '\303\244')

View File

@ -1,6 +1,8 @@
#!/bin/sh #!/bin/sh
test_description='Testing the various Bloom filter computations in bloom.c' test_description='Testing the various Bloom filter computations in bloom.c'
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh . ./test-lib.sh
test_expect_success 'compute unseeded murmur3 hash for empty string' ' test_expect_success 'compute unseeded murmur3 hash for empty string' '

View File

@ -7,22 +7,12 @@ test_description='Perl gettext interface (Git::I18N)'
TEST_PASSES_SANITIZE_LEAK=true TEST_PASSES_SANITIZE_LEAK=true
. ./lib-gettext.sh . ./lib-gettext.sh
. "$TEST_DIRECTORY"/lib-perl.sh
skip_all_if_no_Test_More
if ! test_have_prereq PERL; then test_expect_success 'run t0202/test.pl to test Git::I18N.pm' '
skip_all='skipping perl interface tests, perl not available' "$PERL_PATH" "$TEST_DIRECTORY"/t0202/test.pl 2>stderr &&
test_done test_must_be_empty stderr
fi '
perl -MTest::More -e 0 2>/dev/null || {
skip_all="Perl Test::More unavailable, skipping test"
test_done
}
# The external test will outputs its own plan
test_external_has_tap=1
test_external_without_stderr \
'Perl Git::I18N API' \
perl "$TEST_DIRECTORY"/t0202/test.pl
test_done test_done

View File

@ -5,6 +5,7 @@ test_description='test main ref store api'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh . ./test-lib.sh
RUN="test-tool ref-store main" RUN="test-tool ref-store main"

View File

@ -5,6 +5,7 @@ test_description='test worktree ref store api'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh . ./test-lib.sh
RWT="test-tool ref-store worktree:wt" RWT="test-tool ref-store worktree:wt"

View File

@ -4,6 +4,7 @@ test_description='Test reflog display routines'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh . ./test-lib.sh
test_expect_success 'setup' ' test_expect_success 'setup' '

View File

@ -132,7 +132,7 @@ test_expect_success 'use --default' '
test_must_fail git rev-parse --verify --default bar test_must_fail git rev-parse --verify --default bar
' '
test_expect_success !SANITIZE_LEAK 'main@{n} for various n' ' test_expect_success 'main@{n} for various n' '
git reflog >out && git reflog >out &&
N=$(wc -l <out) && N=$(wc -l <out) &&
Nm1=$(($N-1)) && Nm1=$(($N-1)) &&

View File

@ -5,6 +5,7 @@
test_description='racy split index' test_description='racy split index'
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh . ./test-lib.sh
test_expect_success 'setup' ' test_expect_success 'setup' '

View File

@ -3,6 +3,7 @@
test_description='basic checkout-index tests test_description='basic checkout-index tests
' '
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh . ./test-lib.sh
test_expect_success 'checkout-index --gobbledegook' ' test_expect_success 'checkout-index --gobbledegook' '

View File

@ -7,6 +7,7 @@ Ensures that checkout -m on a resolved file restores the conflicted file'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh . ./test-lib.sh
test_expect_success setup ' test_expect_success setup '

View File

@ -17,6 +17,7 @@ outside the repository. Two instances for which this can occur are tested:
repository can be added to the index. repository can be added to the index.
' '
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh . ./test-lib.sh
test_expect_success '1a: setup--config worktree' ' test_expect_success '1a: setup--config worktree' '

View File

@ -103,7 +103,7 @@ test_expect_success 'git ls-files --others with various exclude options.' '
test_cmp expect output test_cmp expect output
' '
test_expect_success !SANITIZE_LEAK 'restore gitignore' ' test_expect_success 'restore gitignore' '
git checkout --ignore-skip-worktree-bits $allignores && git checkout --ignore-skip-worktree-bits $allignores &&
rm .git/index rm .git/index
' '
@ -126,7 +126,7 @@ cat > expect << EOF
# three/ # three/
EOF EOF
test_expect_success !SANITIZE_LEAK 'git status honors core.excludesfile' \ test_expect_success 'git status honors core.excludesfile' \
'test_cmp expect output' 'test_cmp expect output'
test_expect_success 'trailing slash in exclude allows directory match(1)' ' test_expect_success 'trailing slash in exclude allows directory match(1)' '

View File

@ -2,6 +2,7 @@
test_description='git ls-files --deduplicate test' test_description='git ls-files --deduplicate test'
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh . ./test-lib.sh
test_expect_success 'setup' ' test_expect_success 'setup' '

View File

@ -51,7 +51,7 @@ test_expect_success 'creating many notes with git-notes' '
done done
' '
test_expect_success !SANITIZE_LEAK 'many notes created correctly with git-notes' ' test_expect_success 'many notes created correctly with git-notes' '
git log >output.raw && git log >output.raw &&
grep "^ " output.raw >output && grep "^ " output.raw >output &&
i=$num_notes && i=$num_notes &&

View File

@ -5,6 +5,7 @@ test_description='Return value of diffs'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh . ./test-lib.sh
test_expect_success 'setup' ' test_expect_success 'setup' '

View File

@ -33,7 +33,7 @@ test_expect_success 'GIT_EXTERNAL_DIFF environment' '
' '
test_expect_success !SANITIZE_LEAK 'GIT_EXTERNAL_DIFF environment should apply only to diff' ' test_expect_success 'GIT_EXTERNAL_DIFF environment should apply only to diff' '
GIT_EXTERNAL_DIFF=echo git log -p -1 HEAD >out && GIT_EXTERNAL_DIFF=echo git log -p -1 HEAD >out &&
grep "^diff --git a/file b/file" out grep "^diff --git a/file b/file" out
@ -74,7 +74,7 @@ test_expect_success 'diff.external' '
test_cmp expect actual test_cmp expect actual
' '
test_expect_success !SANITIZE_LEAK 'diff.external should apply only to diff' ' test_expect_success 'diff.external should apply only to diff' '
test_config diff.external echo && test_config diff.external echo &&
git log -p -1 HEAD >out && git log -p -1 HEAD >out &&
grep "^diff --git a/file b/file" out grep "^diff --git a/file b/file" out

View File

@ -2,6 +2,7 @@
test_description='diff function context' test_description='diff function context'
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh . ./test-lib.sh
dir="$TEST_DIRECTORY/t4051" dir="$TEST_DIRECTORY/t4051"

View File

@ -5,6 +5,7 @@ test_description='combined diff show only paths that are different to all parent
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh . ./test-lib.sh
# verify that diffc.expect matches output of # verify that diffc.expect matches output of

View File

@ -7,6 +7,7 @@ test_description='git apply should not get confused with type changes.
' '
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh . ./test-lib.sh
test_expect_success 'setup repository and commits' ' test_expect_success 'setup repository and commits' '

View File

@ -2,6 +2,7 @@
test_description='git merge-tree --write-tree' test_description='git merge-tree --write-tree'
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh . ./test-lib.sh
# This test is ort-specific # This test is ort-specific

View File

@ -2,6 +2,7 @@
test_description='pack-object compression configuration' test_description='pack-object compression configuration'
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh . ./test-lib.sh
test_expect_success setup ' test_expect_success setup '

View File

@ -5,6 +5,7 @@
test_description='git unpack-objects with large objects' test_description='git unpack-objects with large objects'
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh . ./test-lib.sh
prepare_dest () { prepare_dest () {

View File

@ -7,6 +7,7 @@ test_description='Test the post-merge hook.'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh . ./test-lib.sh
test_expect_success setup ' test_expect_success setup '

View File

@ -5,6 +5,7 @@ test_description='test automatic tag following'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh . ./test-lib.sh
# End state of the repository: # End state of the repository:

View File

@ -17,7 +17,7 @@ test_expect_success 'setup unexpected non-blob entry' '
broken_tree="$(git hash-object -w --literally -t tree broken-tree)" broken_tree="$(git hash-object -w --literally -t tree broken-tree)"
' '
test_expect_success !SANITIZE_LEAK 'TODO (should fail!): traverse unexpected non-blob entry (lone)' ' test_expect_success 'TODO (should fail!): traverse unexpected non-blob entry (lone)' '
sed "s/Z$//" >expect <<-EOF && sed "s/Z$//" >expect <<-EOF &&
$broken_tree Z $broken_tree Z
$tree foo $tree foo
@ -121,7 +121,7 @@ test_expect_success 'setup unexpected non-blob tag' '
tag=$(git hash-object -w --literally -t tag broken-tag) tag=$(git hash-object -w --literally -t tag broken-tag)
' '
test_expect_success !SANITIZE_LEAK 'TODO (should fail!): traverse unexpected non-blob tag (lone)' ' test_expect_success 'TODO (should fail!): traverse unexpected non-blob tag (lone)' '
git rev-list --objects $tag git rev-list --objects $tag
' '

View File

@ -4,6 +4,7 @@ test_description='Test merge without common ancestors'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh . ./test-lib.sh
# This scenario is based on a real-world repository of Shawn Pearce. # This scenario is based on a real-world repository of Shawn Pearce.

View File

@ -11,6 +11,7 @@ if core.symlinks is false.'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh . ./test-lib.sh
test_expect_success 'setup' ' test_expect_success 'setup' '

View File

@ -5,7 +5,6 @@ test_description='ask merge-recursive to merge binary files'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh . ./test-lib.sh
test_expect_success setup ' test_expect_success setup '

View File

@ -2,6 +2,7 @@
test_description='merge fast-forward and up to date' test_description='merge fast-forward and up to date'
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh . ./test-lib.sh
test_expect_success setup ' test_expect_success setup '

View File

@ -4,6 +4,7 @@ test_description='merge: handle file mode'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh . ./test-lib.sh
test_expect_success 'set up mode change in one branch' ' test_expect_success 'set up mode change in one branch' '

View File

@ -11,6 +11,7 @@ test_description='merge conflict in crlf repo
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh . ./test-lib.sh
test_expect_success setup ' test_expect_success setup '

View File

@ -4,6 +4,7 @@ test_description='Merge-recursive rename/delete conflict message'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh . ./test-lib.sh
test_expect_success 'rename/delete' ' test_expect_success 'rename/delete' '

View File

@ -2,6 +2,7 @@
test_description='merge-recursive backend test' test_description='merge-recursive backend test'
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh . ./test-lib.sh
# A <- create some files # A <- create some files

View File

@ -5,6 +5,7 @@ test_description='basic work tree status reporting'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh . ./test-lib.sh
test_expect_success setup ' test_expect_success setup '

View File

@ -2,6 +2,7 @@
test_description='git-status with core.ignorecase=true' test_description='git-status with core.ignorecase=true'
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh . ./test-lib.sh
test_expect_success 'status with hash collisions' ' test_expect_success 'status with hash collisions' '

View File

@ -5,6 +5,7 @@
test_description='Tests for "git reset" with "--merge" and "--keep" options' test_description='Tests for "git reset" with "--merge" and "--keep" options'
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh . ./test-lib.sh
test_expect_success setup ' test_expect_success setup '

View File

@ -5,6 +5,7 @@
test_description='Tests to check that "reset" options follow a known table' test_description='Tests to check that "reset" options follow a known table'
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh . ./test-lib.sh

View File

@ -4,6 +4,7 @@ test_description='git mergetool
Testing basic merge tools options' Testing basic merge tools options'
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh . ./test-lib.sh
test_expect_success 'mergetool --tool=vimdiff creates the expected layout' ' test_expect_success 'mergetool --tool=vimdiff creates the expected layout' '

View File

@ -8,7 +8,6 @@ test_description='git svn basic tests'
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
TEST_FAILS_SANITIZE_LEAK=true
. ./lib-git-svn.sh . ./lib-git-svn.sh
prepare_utf8_locale prepare_utf8_locale

View File

@ -4,17 +4,12 @@
# #
test_description='perl interface (Git.pm)' test_description='perl interface (Git.pm)'
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh . ./test-lib.sh
. "$TEST_DIRECTORY"/lib-perl.sh
if ! test_have_prereq PERL; then skip_all_if_no_Test_More
skip_all='skipping perl interface tests, perl not available'
test_done
fi
perl -MTest::More -e 0 2>/dev/null || {
skip_all="Perl Test::More unavailable, skipping test"
test_done
}
# set up test repository # set up test repository
@ -50,11 +45,9 @@ test_expect_success \
git config --add test.pathmulti bar git config --add test.pathmulti bar
' '
# The external test will outputs its own plan test_expect_success 'use t9700/test.pl to test Git.pm' '
test_external_has_tap=1 "$PERL_PATH" "$TEST_DIRECTORY"/t9700/test.pl 2>stderr &&
test_must_be_empty stderr
test_external_without_stderr \ '
'Perl API' \
perl "$TEST_DIRECTORY"/t9700/test.pl
test_done test_done

View File

@ -5,6 +5,7 @@ test_description='git web--browse basic tests
This test checks that git web--browse can handle various valid URLs.' This test checks that git web--browse can handle various valid URLs.'
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh . ./test-lib.sh
test_web_browse () { test_web_browse () {

View File

@ -633,7 +633,7 @@ test_hook () {
# - Explicitly using test_have_prereq. # - Explicitly using test_have_prereq.
# #
# - Implicitly by specifying the prerequisite tag in the calls to # - Implicitly by specifying the prerequisite tag in the calls to
# test_expect_{success,failure} and test_external{,_without_stderr}. # test_expect_{success,failure}
# #
# The single parameter is the prerequisite tag (a simple word, in all # The single parameter is the prerequisite tag (a simple word, in all
# capital letters by convention). # capital letters by convention).
@ -835,93 +835,6 @@ test_expect_success () {
test_finish_ test_finish_
} }
# test_external runs external test scripts that provide continuous
# test output about their progress, and succeeds/fails on
# zero/non-zero exit code. It outputs the test output on stdout even
# in non-verbose mode, and announces the external script with "# run
# <n>: ..." before running it. When providing relative paths, keep in
# mind that all scripts run in "trash directory".
# Usage: test_external description command arguments...
# Example: test_external 'Perl API' perl ../path/to/test.pl
test_external () {
test "$#" = 4 && { test_prereq=$1; shift; } || test_prereq=
test "$#" = 3 ||
BUG "not 3 or 4 parameters to test_external"
descr="$1"
shift
test_verify_prereq
export test_prereq
if ! test_skip "$descr" "$@"
then
# Announce the script to reduce confusion about the
# test output that follows.
say_color "" "# run $test_count: $descr ($*)"
# Export TEST_DIRECTORY, TRASH_DIRECTORY and GIT_TEST_LONG
# to be able to use them in script
export TEST_DIRECTORY TRASH_DIRECTORY GIT_TEST_LONG
# Run command; redirect its stderr to &4 as in
# test_run_, but keep its stdout on our stdout even in
# non-verbose mode.
"$@" 2>&4
if test "$?" = 0
then
if test $test_external_has_tap -eq 0; then
test_ok_ "$descr"
else
say_color "" "# test_external test $descr was ok"
test_success=$(($test_success + 1))
fi
else
if test $test_external_has_tap -eq 0; then
test_failure_ "$descr" "$@"
else
say_color error "# test_external test $descr failed: $@"
test_failure=$(($test_failure + 1))
fi
fi
fi
}
# Like test_external, but in addition tests that the command generated
# no output on stderr.
test_external_without_stderr () {
# The temporary file has no (and must have no) security
# implications.
tmp=${TMPDIR:-/tmp}
stderr="$tmp/git-external-stderr.$$.tmp"
test_external "$@" 4> "$stderr"
test -f "$stderr" || error "Internal error: $stderr disappeared."
descr="no stderr: $1"
shift
say >&3 "# expecting no stderr from previous command"
if test ! -s "$stderr"
then
rm "$stderr"
if test $test_external_has_tap -eq 0; then
test_ok_ "$descr"
else
say_color "" "# test_external_without_stderr test $descr was ok"
test_success=$(($test_success + 1))
fi
else
if test "$verbose" = t
then
output=$(echo; echo "# Stderr is:"; cat "$stderr")
else
output=
fi
# rm first in case test_failure exits.
rm "$stderr"
if test $test_external_has_tap -eq 0; then
test_failure_ "$descr" "$@" "$output"
else
say_color error "# test_external_without_stderr test $descr failed: $@: $output"
test_failure=$(($test_failure + 1))
fi
fi
}
# debugging-friendly alternatives to "test [-f|-d|-e]" # debugging-friendly alternatives to "test [-f|-d|-e]"
# The commands test the existence or non-existence of $1 # The commands test the existence or non-existence of $1
test_path_is_file () { test_path_is_file () {

View File

@ -238,6 +238,9 @@ parse_option () {
;; ;;
esac esac
;; ;;
--invert-exit-code)
invert_exit_code=t
;;
*) *)
echo "error: unknown test option '$opt'" >&2; exit 1 ;; echo "error: unknown test option '$opt'" >&2; exit 1 ;;
esac esac
@ -302,6 +305,11 @@ TEST_NUMBER="${TEST_NAME%%-*}"
TEST_NUMBER="${TEST_NUMBER#t}" TEST_NUMBER="${TEST_NUMBER#t}"
TEST_RESULTS_DIR="$TEST_OUTPUT_DIRECTORY/test-results" TEST_RESULTS_DIR="$TEST_OUTPUT_DIRECTORY/test-results"
TEST_RESULTS_BASE="$TEST_RESULTS_DIR/$TEST_NAME$TEST_STRESS_JOB_SFX" TEST_RESULTS_BASE="$TEST_RESULTS_DIR/$TEST_NAME$TEST_STRESS_JOB_SFX"
TEST_RESULTS_SAN_FILE_PFX=trace
TEST_RESULTS_SAN_DIR_SFX=leak
TEST_RESULTS_SAN_FILE=
TEST_RESULTS_SAN_DIR="$TEST_RESULTS_DIR/$TEST_NAME.$TEST_RESULTS_SAN_DIR_SFX"
TEST_RESULTS_SAN_DIR_NR_LEAKS_STARTUP=
TRASH_DIRECTORY="trash directory.$TEST_NAME$TEST_STRESS_JOB_SFX" TRASH_DIRECTORY="trash directory.$TEST_NAME$TEST_STRESS_JOB_SFX"
test -n "$root" && TRASH_DIRECTORY="$root/$TRASH_DIRECTORY" test -n "$root" && TRASH_DIRECTORY="$root/$TRASH_DIRECTORY"
case "$TRASH_DIRECTORY" in case "$TRASH_DIRECTORY" in
@ -309,6 +317,16 @@ case "$TRASH_DIRECTORY" in
*) TRASH_DIRECTORY="$TEST_OUTPUT_DIRECTORY/$TRASH_DIRECTORY" ;; *) TRASH_DIRECTORY="$TEST_OUTPUT_DIRECTORY/$TRASH_DIRECTORY" ;;
esac esac
# Utility functions using $TEST_RESULTS_* variables
nr_san_dir_leaks_ () {
# stderr piped to /dev/null because the directory may have
# been "rmdir"'d already.
find "$TEST_RESULTS_SAN_DIR" \
-type f \
-name "$TEST_RESULTS_SAN_FILE_PFX.*" 2>/dev/null |
wc -l
}
# If --stress was passed, run this test repeatedly in several parallel loops. # If --stress was passed, run this test repeatedly in several parallel loops.
if test "$GIT_TEST_STRESS_STARTED" = "done" if test "$GIT_TEST_STRESS_STARTED" = "done"
then then
@ -788,15 +806,31 @@ test_ok_ () {
finalize_test_case_output ok "$@" finalize_test_case_output ok "$@"
} }
_invert_exit_code_failure_end_blurb () {
say_color warn "# faked up failures as TODO & now exiting with 0 due to --invert-exit-code"
}
test_failure_ () { test_failure_ () {
failure_label=$1 failure_label=$1
test_failure=$(($test_failure + 1)) test_failure=$(($test_failure + 1))
say_color error "not ok $test_count - $1" local pfx=""
if test -n "$invert_exit_code" # && test -n "$HARNESS_ACTIVE"
then
pfx="# TODO induced breakage (--invert-exit-code):"
fi
say_color error "not ok $test_count - ${pfx:+$pfx }$1"
shift shift
printf '%s\n' "$*" | sed -e 's/^/# /' printf '%s\n' "$*" | sed -e 's/^/# /'
if test -n "$immediate" if test -n "$immediate"
then then
say_color error "1..$test_count" say_color error "1..$test_count"
if test -n "$invert_exit_code"
then
finalize_test_output
_invert_exit_code_failure_end_blurb
GIT_EXIT_OK=t
exit 0
fi
_error_exit _error_exit
fi fi
finalize_test_case_output failure "$failure_label" "$@" finalize_test_case_output failure "$failure_label" "$@"
@ -804,14 +838,14 @@ test_failure_ () {
test_known_broken_ok_ () { test_known_broken_ok_ () {
test_fixed=$(($test_fixed+1)) test_fixed=$(($test_fixed+1))
say_color error "ok $test_count - $@ # TODO known breakage vanished" say_color error "ok $test_count - $1 # TODO known breakage vanished"
finalize_test_case_output fixed "$@" finalize_test_case_output fixed "$1"
} }
test_known_broken_failure_ () { test_known_broken_failure_ () {
test_broken=$(($test_broken+1)) test_broken=$(($test_broken+1))
say_color warn "not ok $test_count - $@ # TODO known breakage" say_color warn "not ok $test_count - $1 # TODO known breakage"
finalize_test_case_output broken "$@" finalize_test_case_output broken "$1"
} }
test_debug () { test_debug () {
@ -1168,9 +1202,67 @@ test_atexit_handler () {
teardown_malloc_check teardown_malloc_check
} }
test_done () { sanitize_leak_log_message_ () {
GIT_EXIT_OK=t local new="$1" &&
local old="$2" &&
local file="$3" &&
printf "With SANITIZE=leak at exit we have %d leak logs, but started with %d
This means that we have a blindspot where git is leaking but we're
losing the exit code somewhere, or not propagating it appropriately
upwards!
See the logs at \"%s.*\";
those logs are reproduced below." \
"$new" "$old" "$file"
}
check_test_results_san_file_ () {
if test -z "$TEST_RESULTS_SAN_FILE"
then
return
fi &&
local old="$TEST_RESULTS_SAN_DIR_NR_LEAKS_STARTUP" &&
local new="$(nr_san_dir_leaks_)" &&
if test $new -le $old
then
return
fi &&
local out="$(sanitize_leak_log_message_ "$new" "$old" "$TEST_RESULTS_SAN_FILE")" &&
say_color error "$out" &&
if test "$old" != 0
then
echo &&
say_color error "The logs include output from past runs to avoid" &&
say_color error "that remove 'test-results' between runs."
fi &&
say_color error "$(cat "$TEST_RESULTS_SAN_FILE".*)" &&
if test -n "$passes_sanitize_leak" && test "$test_failure" = 0
then
say "As TEST_PASSES_SANITIZE_LEAK=true and our logs show we're leaking, exit non-zero!" &&
invert_exit_code=t
elif test -n "$passes_sanitize_leak"
then
say "As TEST_PASSES_SANITIZE_LEAK=true and our logs show we're leaking, and we're failing for other reasons too..." &&
invert_exit_code=
elif test -n "$sanitize_leak_check" && test "$test_failure" = 0
then
say "As TEST_PASSES_SANITIZE_LEAK=true isn't set the above leak is 'ok' with GIT_TEST_PASSING_SANITIZE_LEAK=check" &&
invert_exit_code=
elif test -n "$sanitize_leak_check"
then
say "As TEST_PASSES_SANITIZE_LEAK=true isn't set the above leak is 'ok' with GIT_TEST_PASSING_SANITIZE_LEAK=check" &&
invert_exit_code=t
else
say "With GIT_TEST_SANITIZE_LEAK_LOG=true our logs revealed a memory leak, exit non-zero!" &&
invert_exit_code=t
fi
}
test_done () {
# Run the atexit commands _before_ the trash directory is # Run the atexit commands _before_ the trash directory is
# removed, so the commands can access pidfiles and socket files. # removed, so the commands can access pidfiles and socket files.
test_atexit_handler test_atexit_handler
@ -1210,28 +1302,32 @@ test_done () {
fi fi
case "$test_failure" in case "$test_failure" in
0) 0)
if test $test_external_has_tap -eq 0 if test $test_remaining -gt 0
then then
if test $test_remaining -gt 0 say_color pass "# passed all $msg"
then
say_color pass "# passed all $msg"
fi
# Maybe print SKIP message
test -z "$skip_all" || skip_all="# SKIP $skip_all"
case "$test_count" in
0)
say "1..$test_count${skip_all:+ $skip_all}"
;;
*)
test -z "$skip_all" ||
say_color warn "$skip_all"
say "1..$test_count"
;;
esac
fi fi
if test -z "$debug" && test -n "$remove_trash" # Maybe print SKIP message
test -z "$skip_all" || skip_all="# SKIP $skip_all"
case "$test_count" in
0)
say "1..$test_count${skip_all:+ $skip_all}"
;;
*)
test -z "$skip_all" ||
say_color warn "$skip_all"
say "1..$test_count"
;;
esac
if test -n "$stress" && test -n "$invert_exit_code"
then
# We're about to move our "$TRASH_DIRECTORY"
# to "$TRASH_DIRECTORY.stress-failed" if
# --stress is combined with
# --invert-exit-code.
say "with --stress and --invert-exit-code we're not removing '$TRASH_DIRECTORY'"
elif test -z "$debug" && test -n "$remove_trash"
then then
test -d "$TRASH_DIRECTORY" || test -d "$TRASH_DIRECTORY" ||
error "Tests passed but trash directory already removed before test cleanup; aborting" error "Tests passed but trash directory already removed before test cleanup; aborting"
@ -1244,17 +1340,35 @@ test_done () {
} || } ||
error "Tests passed but test cleanup failed; aborting" error "Tests passed but test cleanup failed; aborting"
fi fi
check_test_results_san_file_ "$test_failure"
if test -z "$skip_all" && test -n "$invert_exit_code"
then
say_color warn "# faking up non-zero exit with --invert-exit-code"
GIT_EXIT_OK=t
exit 1
fi
test_at_end_hook_ test_at_end_hook_
GIT_EXIT_OK=t
exit 0 ;; exit 0 ;;
*) *)
if test $test_external_has_tap -eq 0 say_color error "# failed $test_failure among $msg"
say "1..$test_count"
check_test_results_san_file_ "$test_failure"
if test -n "$invert_exit_code"
then then
say_color error "# failed $test_failure among $msg" _invert_exit_code_failure_end_blurb
say "1..$test_count" GIT_EXIT_OK=t
exit 0
fi fi
GIT_EXIT_OK=t
exit 1 ;; exit 1 ;;
esac esac
@ -1387,14 +1501,12 @@ fi
GITPERLLIB="$GIT_BUILD_DIR"/perl/build/lib GITPERLLIB="$GIT_BUILD_DIR"/perl/build/lib
export GITPERLLIB export GITPERLLIB
test -d "$GIT_BUILD_DIR"/templates/blt || { test -d "$GIT_BUILD_DIR"/templates/blt || {
error "You haven't built things yet, have you?" BAIL_OUT "You haven't built things yet, have you?"
} }
if ! test -x "$GIT_BUILD_DIR"/t/helper/test-tool$X if ! test -x "$GIT_BUILD_DIR"/t/helper/test-tool$X
then then
echo >&2 'You need to build test-tool:' BAIL_OUT 'You need to build test-tool; Run "make t/helper/test-tool" in the source (toplevel) directory'
echo >&2 'Run "make t/helper/test-tool" in the source (toplevel) directory'
exit 1
fi fi
# Are we running this test at all? # Are we running this test at all?
@ -1408,24 +1520,70 @@ then
test_done test_done
fi fi
# skip non-whitelisted tests when compiled with SANITIZE=leak BAIL_OUT_ENV_NEEDS_SANITIZE_LEAK () {
BAIL_OUT "$1 has no effect except when compiled with SANITIZE=leak"
}
if test -n "$SANITIZE_LEAK" if test -n "$SANITIZE_LEAK"
then then
if test_bool_env GIT_TEST_PASSING_SANITIZE_LEAK false # Normalize with test_bool_env
then passes_sanitize_leak=
# We need to see it in "git env--helper" (via
# test_bool_env)
export TEST_PASSES_SANITIZE_LEAK
if ! test_bool_env TEST_PASSES_SANITIZE_LEAK false # We need to see TEST_PASSES_SANITIZE_LEAK in "git
then # env--helper" (via test_bool_env)
skip_all="skipping $this_test under GIT_TEST_PASSING_SANITIZE_LEAK=true" export TEST_PASSES_SANITIZE_LEAK
test_done if test_bool_env TEST_PASSES_SANITIZE_LEAK false
fi then
passes_sanitize_leak=t
fi fi
elif test_bool_env GIT_TEST_PASSING_SANITIZE_LEAK false
if test "$GIT_TEST_PASSING_SANITIZE_LEAK" = "check"
then
sanitize_leak_check=t
if test -n "$invert_exit_code"
then
BAIL_OUT "cannot use --invert-exit-code under GIT_TEST_PASSING_SANITIZE_LEAK=check"
fi
if test -z "$passes_sanitize_leak"
then
say "in GIT_TEST_PASSING_SANITIZE_LEAK=check mode, setting --invert-exit-code for TEST_PASSES_SANITIZE_LEAK != true"
invert_exit_code=t
fi
elif test -z "$passes_sanitize_leak" &&
test_bool_env GIT_TEST_PASSING_SANITIZE_LEAK false
then
skip_all="skipping $this_test under GIT_TEST_PASSING_SANITIZE_LEAK=true"
test_done
fi
if test_bool_env GIT_TEST_SANITIZE_LEAK_LOG false
then
if ! mkdir -p "$TEST_RESULTS_SAN_DIR"
then
BAIL_OUT "cannot create $TEST_RESULTS_SAN_DIR"
fi &&
TEST_RESULTS_SAN_FILE="$TEST_RESULTS_SAN_DIR/$TEST_RESULTS_SAN_FILE_PFX"
# In case "test-results" is left over from a previous
# run: Only report if new leaks show up.
TEST_RESULTS_SAN_DIR_NR_LEAKS_STARTUP=$(nr_san_dir_leaks_)
# Don't litter *.leak dirs if there was nothing to report
test_atexit "rmdir \"$TEST_RESULTS_SAN_DIR\" 2>/dev/null || :"
prepend_var LSAN_OPTIONS : dedup_token_length=9999
prepend_var LSAN_OPTIONS : log_exe_name=1
prepend_var LSAN_OPTIONS : log_path=\"$TEST_RESULTS_SAN_FILE\"
export LSAN_OPTIONS
fi
elif test "$GIT_TEST_PASSING_SANITIZE_LEAK" = "check" ||
test_bool_env GIT_TEST_PASSING_SANITIZE_LEAK false
then then
BAIL_OUT "GIT_TEST_PASSING_SANITIZE_LEAK=true has no effect except when compiled with SANITIZE=leak" BAIL_OUT_ENV_NEEDS_SANITIZE_LEAK "GIT_TEST_PASSING_SANITIZE_LEAK=true"
elif test_bool_env GIT_TEST_SANITIZE_LEAK_LOG false
then
BAIL_OUT_ENV_NEEDS_SANITIZE_LEAK "GIT_TEST_SANITIZE_LEAK_LOG=true"
fi fi
# Last-minute variable setup # Last-minute variable setup
@ -1448,9 +1606,7 @@ remove_trash_directory () {
# Test repository # Test repository
remove_trash_directory "$TRASH_DIRECTORY" || { remove_trash_directory "$TRASH_DIRECTORY" || {
GIT_EXIT_OK=t BAIL_OUT 'cannot prepare test area'
echo >&5 "FATAL: Cannot prepare test area"
exit 1
} }
remove_trash=t remove_trash=t
@ -1466,7 +1622,7 @@ fi
# Use -P to resolve symlinks in our working directory so that the cwd # Use -P to resolve symlinks in our working directory so that the cwd
# in subprocesses like git equals our $PWD (for pathname comparisons). # in subprocesses like git equals our $PWD (for pathname comparisons).
cd -P "$TRASH_DIRECTORY" || exit 1 cd -P "$TRASH_DIRECTORY" || BAIL_OUT "cannot cd -P to \"$TRASH_DIRECTORY\""
start_test_output "$0" start_test_output "$0"

View File

@ -455,6 +455,7 @@ static void create_pack_file(struct upload_pack_data *pack_data,
return; return;
fail: fail:
free(output_state);
send_client_data(3, abort_msg, sizeof(abort_msg), send_client_data(3, abort_msg, sizeof(abort_msg),
pack_data->use_sideband); pack_data->use_sideband);
die("git upload-pack: %s", abort_msg); die("git upload-pack: %s", abort_msg);