aboutsummaryrefslogtreecommitdiffstats
path: root/t/test-lib.sh (follow)
AgeCommit message (Collapse)AuthorFilesLines
2025-10-22Merge branch 'bc/sha1-256-interop-01'Junio C Hamano1-0/+13
The beginning of SHA1-SHA256 interoperability work. * bc/sha1-256-interop-01: t1010: use BROKEN_OBJECTS prerequisite t: allow specifying compatibility hash fsck: consider gpgsig headers expected in tags rev-parse: allow printing compatibility hash docs: add documentation for loose objects docs: improve ambiguous areas of pack format documentation docs: reflect actual double signature for tags docs: update offset order for pack index v3 docs: update pack index v3 format
2025-10-09t: allow specifying compatibility hashbrian m. carlson1-0/+13
We want to specify a compatibility hash for testing interactions for SHA-256 repositories where we have SHA-1 compatibility enabled. Allow the user to specify this scenario in the test suite by setting GIT_TEST_DEFAULT_HASH to "sha256:sha1". Note that this will get passed into GIT_DEFAULT_HASH, which Git itself does not presently support. However, we will support this in a future commit. Since we'll now want to know the value for a specific version, let's add the ability to specify either the storage hash (in this case, SHA-256) or the compatibility hash (SHA-1). We use a different value for the compatibility hash that will be enabled for all repositories (test_repo_compat_hash_algo) versus the one that is used individually in some tests (test_compat_hash_algo), since we want to still run those individual tests without requiring that the testsuite be run fully in a compatibility mode. In some cases, we'll need to adjust our test suite to work in a proper way with a compatibility hash. For example, in such a case, we'll only use pack index v3, since v1 and v2 lack support for multiple algorithms. Since we won't want to write those older formats, we'll need to skip tests that do so. Let's add a COMPAT_HASH prerequisite for this purpose. Finally, in this scenario, we can no longer rely on having broken objects work since we lack compatibility mappings to rewrite objects in the repository. Add a prerequisite, BROKEN_OBJECTS, that we define in terms of COMPAT_HASH and checks to see if creating deliberately broken objects is possible, so that we can disable these tests if not. Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-09-18initial branch: give hints after switching the default nameJunio C Hamano1-3/+7
It is likely that those who came to Git after 3.0 switched the default initial branch name to 'main' would still try to follow tutorials that were written before 3.0 happened and with the assumption that the tool would call the initial branch 'master'. To help these new users after 3.0 boundary, let's retain one part of the hint we will be giving before the default changes, namely, how to rename the branch an unconfigured Git has created just once. We do this without telling them how to permanently configure the default name of the initial branch, and that design choice is very much deliberate. The whole point of switching the default name was because we did not want to force individual users to configure their default branch name but while the hard wired default was 'master', they _had_ to configure it away from 'master' in order to conform to the recent norm, and a hint that tells them how to do so is useful. But once the default is renamed to 'main', that no longer is true. A narrower audience who are new users that follow an instruction that assumes the initial branch name is 'master' would only need to learn "here is how to change the branch name to match the tutorial you are following in the repository you created for practice", and "here is how you keep creating repositories with the first branch with a name everybody hates" is unnecessary. It also needs to be noted that the advise token to squelch the message is the same advice.defaultBranchName as before, which is also very much deliberate. The users who do have that configured are those who _have_ been using Git since before 3.0, and they are not the target audience for the new advice message. Reusing the same advise token ensures that they do not have to turn the message off. Helped-by: Phillip Wood <phillip.wood@dunelm.org.uk> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-09-10breaking-changes: switch default branch to mainPhillip Wood1-4/+7
Since 1296cbe4b46 (init: document `init.defaultBranch` better, 2020-12-11) "git-init.adoc" has advertised that the default name of the initial branch may change in the future. The name "main" is chosen to match the default used by the big Git forge web sites. The advice printed when init.defaultBranch is not set is updated to say that the default will change to "main" in Git 3.0. Building with WITH_BREAKING_CHANGES enabled removes the advice and changes the default branch name to "main". The code in guess_remote_head() that looks for "refs/heads/master" is left unchanged as that is only called when the remote server does not support the symref capability in the v0 protocol or the symref extension to the ls-refs list in the v2 protocol. Such an old server is more likely to be using "master" as the default branch name. With the exception of the "git-init.adoc" the documentation is left unchanged. I had hoped to parameterize the name of the default branch by using an asciidoc attribute. Unfortunately attribute expansion is inhibited by backticks and we use backticks to mark up ref names so that idea does not work. As the changes to git-init.adoc show inserting ifdef's around each instance of the branch name "master" is cumbersome and makes the documentation sources harder to read. Apart from "git-init.adoc" there are some other files where "master" is used as the name of the initial branch rather than as an example of a branch name such as "user-manual.adoc" and "gitcore-tutorial.adoc". The name appears a lot in those so updating it with ifdef's is not really practical. We can update that document in the 3.0 release cycle. The other documentation where master is used as an example branch name can be gradually converted over time. Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-07-24Merge branch 'kl/test-installed-fix'Junio C Hamano1-2/+3
GIT_TEST_INSTALLED was not honored in the recent topic related to SHA256 hashes, which has been corrected. * kl/test-installed-fix: test-lib: respect GIT_TEST_INSTALLED when querying default hash
2025-07-21Merge branch 'bc/use-sha256-by-default-in-3.0'Junio C Hamano1-1/+6
Prepare to flip the default hash function to SHA-256. * bc/use-sha256-by-default-in-3.0: Enable SHA-256 by default in breaking changes mode help: add a build option for default hash t5300: choose the built-in hash outside of a repo t4042: choose the built-in hash outside of a repo t1007: choose the built-in hash outside of a repo t: default to compile-time default hash if not set setup: use the default algorithm to initialize repo format Use legacy hash for legacy formats builtin: use default hash when outside a repository hash: add a constant for the legacy hash algorithm hash: add a constant for the default hash algorithm
2025-07-15test-lib: respect GIT_TEST_INSTALLED when querying default hashKyle Lippincott1-2/+3
$GIT_TEST_INSTALLED can be set to use an "installed" git instead of the one from $GIT_BUILD_DIR. This is used by my company's internal test infrastructure, and not using $GIT_TEST_INSTALLED when querying the default hash meant that the tests were failing because the hash was effectively set to the empty string (since git didn't execute). In the two places we attempt to detect/execute git itself prior to overriding everything and putting it in $PATH, use identical logic for identifying the git binary to execute. This also has the effect of including the $X suffix when querying the default hash, but that's not strictly necessary. You don't need to specify .exe when running a binary on Windows, just when testing whether it exists or not. Signed-off-by: Kyle Lippincott <spectral@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-07-01Enable SHA-256 by default in breaking changes modebrian m. carlson1-1/+1
Our document on breaking changes indicates that we intend to default to SHA-256 in Git 3.0. Since most people choose the default option, this is an important security upgrade to our defaults. To allow people to test this case, when WITH_BREAKING_CHANGES is set in the configuration, build Git with SHA-256 as the default hash. Update the testsuite to use the build options information to automatically choose the right value. Note that if the command substitution for GIT_TEST_BUILTIN_HASH fails, so does the testsuite—and quite spectacularly at that. Thus, the case where the Git binary is somehow subtly broken will not go undetected. Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-07-01t: default to compile-time default hash if not setbrian m. carlson1-1/+6
Right now, the default compile-time hash is SHA-1. However, in the future, this might change and it would be helpful to gracefully handle this case in our testsuite. To avoid making these assumptions, let's introduce a variable that contains the built-in default hash and use it in our setup code as the fallback value if no hash was explicitly set. For now, this is always SHA-1, but in a future commit, we'll allow adjusting this and the variable will be more useful. To allow us to make our tests more robust, allow test_oid to take the --hash=builtin option to specify this hash, whatever it is. Additionally, add a DEFAULT_HASH_ALGORITHM prerequisite to check for the compile-time hash. Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-06-18Merge branch 'rj/meson-tap-parse-fixup'Junio C Hamano1-0/+3
An earlier test update incorrectly lost three prerequisites on macOS, which has been corrected. * rj/meson-tap-parse-fixup: test-lib: add missing prerequisites for Darwin
2025-06-17Merge branch 'ps/meson-tap-parse'Junio C Hamano1-4/+14
Meson-based build/test framework now understands TAP output generated by our tests. * ps/meson-tap-parse: meson: parse TAP output generated by our tests meson: introduce kwargs variable for tests test-lib: fail on unexpectedly passing tests t7815: fix unexpectedly passing test on macOS t/test-lib: fix TAP format for BASH_XTRACEFD warning t/test-lib: don't print shell traces to stdout t983*: use prereq to check for Python-specific git-p4(1) support t9822: use prereq to check for ISO-8859-1 support t: silence output from `test_create_repo()` t: stop announcing prereqs
2025-06-09test-lib: add missing prerequisites for DarwinRamsay Jones1-0/+3
commit d3d8c601fd ("t7815: fix unexpectedly passing test on macOS", 2025-06-02) added a MACOS prerequisite by adding a 'Darwin' case label to the 'OS-specific' case statement. However, this commit forgot to set several prerequisites which appear in the 'default' case label, in addition to the new MACOS prerequisite. This causes several tests, which macOS should pass, being skipped. In order to run all applicable tests on macOS, add the missing prerequisites to the 'Darwin' case. Signed-off-by: Ramsay Jones <ramsay@ramsayjones.plus.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-06-09Merge branch 'mm/test-in-absolute-home'Junio C Hamano1-0/+2
Tests that compare $HOME and $(pwd), which should be the same directory unless the tests chdir's around, would fail when the user enters the test directory via symbolic links, which has been corrected. * mm/test-in-absolute-home: t: run tests from a normalized working directory
2025-06-02test-lib: fail on unexpectedly passing testsPatrick Steinhardt1-1/+8
When tests are executed via `test_expect_failure` we rather obviously expect the test itself to fail. If it unexpectedly does not fail then we count the test as a "fixed" test and announce that a known breakage has vanished: ok 1 - setup ok 2 - create refs/heads/main # TODO known breakage vanished ok 3 - create refs/heads/main with oldvalue verification ... ok 299 - update-ref should also create reflog for HEAD # 1 known breakage(s) vanished; please update test(s) # passed all remaining 298 test(s) 1..299 While we announce that tests should be updated, the overall test suite still passes. This makes it quite hard to detect when a test that has previously failed succeeds now as the developer needs to pay close attention to the exact output. Even more importantly, tests that only succeed on _some_ systems are even easier to miss now, as one would have to explicitly take a look at respective CI jobs to notice that those do pass now. Furthermore, we are about to introduce support for parsing TAP output in Meson. In contrast to prove(1), which treats unexpected passes as a successful test run, Meson treats those as failure. Neither of these tools is wrong in doing so. Quoting the TAP specification [1]: Should a todo test point begin succeeding, the harness may report it in some way that indicates that whatever was supposed to be done has been, and it should be promoted to a normal Test Point. So it is essentially implementation-defined how exactly the unexpected pass is reported, and whether it should cause the overall test suite to fail or not. It is unarguably a bad thing for us though if these tools interpret these differently, as it would mean that test results now depend on whether the developer uses prove(1) or Meson. Unify the behaviour by causing a test suite to fail when there are any unexpected passes. As prove(1) does not consider an unexpected pass to be an error this leads to somewhat funky output: t1400-update-ref.sh ................................ Dubious, test returned 1 (wstat 256, 0x100) All 299 subtests passed (1 TODO test unexpectedly succeeded) ... Test Summary Report ------------------- t1400-update-ref.sh (Wstat: 256 (exited 1) Tests: 299 Failed: 0) TODO passed: 2 Non-zero exit status: 1 But as we directly announce that the root cause is an unexpected TODO that has succeeded it's not all that bad. [1]: https://testanything.org/tap-version-14-specification.html Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-06-02t7815: fix unexpectedly passing test on macOSPatrick Steinhardt1-0/+3
In t7815, we have the following test: test_expect_failure !CYGWIN 'git grep .fi a' ' git grep .fi a ' The test passes if '.' matches a NUL byte, which we expect to only happen on Cygwin. The upcoming changes to support parsing TAP output in Meson surface that this test, surprisingly, passes on macOS as well. It is unclear how long the test has been passing on macOS already. 064eed36c7f (config.mak.uname: only set NO_REGEX on cygwin for v1.7, 2025-04-17) mentions that the test started to pass for Cygwin. This was attributed to a new implementation of regcomp(3p) and friends, which was inherited from FreeBSD. Given the BSD lineage of macOS it is feasible that it also inherited similar code eventually that made the test pass now. It is somewhat dubious what the test actually brings to the table given that it is quite platform specific. Ideally, we would fix this mess by having a configure-time check whether regcomp(3p) works as expected, including NUL bytes, and use our bundled version of the regex library in case it doesn't. Like this, we could ensure that all platforms work the same in this edge case and mark the new behaviour as expected. This change is outside of the scope of this patch series, which only introduces support for TAP. So instead of fixing the bigger issue, ignore the test on Darwin like we already do for Cygwin. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-06-02t/test-lib: fix TAP format for BASH_XTRACEFD warningPatrick Steinhardt1-1/+1
When the Bash version is too old to support BASH_XTRACEFD we print a warning to stderr. This warning is not prefixed with "#", which causes TAP parsers to (wrongly) interpret the warning as part of the protocol. Fix this issue by prefixing the warning with a "#" so that it is treated as comment. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-06-02t/test-lib: don't print shell traces to stdoutPatrick Steinhardt1-2/+2
We have several flags like "--verbose", "--verbose-only" or "-x" that cause us to generate shell traces. The generated tracing output is split up in these cases so that the test's stdout is printed to file descriptor 3 whereas its stderr is printed to file descriptor 4. Depending on which options have been given, we then end up either: - Redirecting both file descriptors to a file. - Redirecting them to stdout and stderr, respectively. - Closing them in case we're running in none-verbose mode. The second case causes problems though when passing output to a TAP parser. We print the test's stdout to the console's stdout, and that results in broken TAP output. Fix the issue by instead redirecting the test's stdout to the shell's stderr. This makes it impossible to discern stdout from stderr, but going by my own experience I never came across a usecase where I would have needed this distinction. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-05-30t: run tests from a normalized working directoryMark Mentovai1-0/+2
Some tests make git perform actions that produce observable pathnames, and have expectations on those paths. Tests run with $HOME set to a $TRASH_DIRECTORY, and with their working directory the same $TRASH_DIRECTORY, although these paths are logically identical, they do not observe the same pathname canonicalization rules and thus might not be represented by strings that compare equal. In particular, no pathname normalization is applied to $TRASH_DIRECTORY or $HOME, while tests change their working directory with `cd -P`, which normalizes the working directory's path by fully resolving symbolic links. t7900's macOS maintenance tests (which are not limited to running on macOS) have an expectation on a path that `git maintenance` forms by using abspath.c strbuf_realpath() to resolve a canonical absolute path based on $HOME. When t7900 runs from a working directory that contains symbolic links in its pathname, $HOME will also contain symbolic links, which `git maintenance` resolves but the test's expectation does not, causing a test failure. Align $TRASH_DIRECTORY and $HOME with the normalized path as used for the working directory by resetting them to match the working directory after it's established by `cd -P`. With all paths in agreement and symbolic links resolved, pathname expectations can be set and met based on string comparison without regard to external environmental factors such as the presence of symbolic links in a path. Suggested-by: Junio C Hamano <gitster@pobox.com> Signed-off-by: Mark Mentovai <mark@chromium.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-04-17Merge branch 'en/merge-recursive-debug'Junio C Hamano1-2/+0
Remove remnants of the recursive merge strategy backend, which was superseded by the ort merge strategy. * en/merge-recursive-debug: builtin/{merge,rebase,revert}: remove GIT_TEST_MERGE_ALGORITHM tests: remove GIT_TEST_MERGE_ALGORITHM and test_expect_merge_algorithm merge-recursive.[ch]: thoroughly debug these merge, sequencer: switch recursive merges over to ort sequencer: switch non-recursive merges over to ort merge-ort: enable diff-algorithms other than histogram builtin/merge-recursive: switch to using merge_ort_generic() checkout: replace merge_trees() with merge_ort_nonrecursive()
2025-04-16Merge branch 'ps/test-wo-perl-prereq'Junio C Hamano1-18/+31
"make test" used to have a hard dependency on (basic) Perl; tests have been rewritten help environment with NO_PERL test the build as much as possible. * ps/test-wo-perl-prereq: t5703: refactor test to not depend on Perl t5316: refactor `max_chain()` to not depend on Perl t0210: refactor trace2 scrubbing to not use Perl t0021: refactor `generate_random_characters()` to not depend on Perl t/lib-httpd: refactor "one-time-perl" CGI script to not depend on Perl t/lib-t6000: refactor `name_from_description()` to not depend on Perl t/lib-gpg: refactor `sanitize_pgp()` to not depend on Perl t: refactor tests depending on Perl for textconv scripts t: refactor tests depending on Perl to print data t: refactor tests depending on Perl substitution operator t: refactor tests depending on Perl transliteration operator Makefile: stop requiring Perl when running tests meson: stop requiring Perl when tests are enabled t: adapt existing PERL prerequisites t: introduce PERL_TEST_HELPERS prerequisite t: adapt `test_readlink()` to not use Perl t: adapt `test_copy_bytes()` to not use Perl t: adapt character translation helpers to not use Perl t: refactor environment sanitization to not use Perl t: skip chain lint when PERL_PATH is unset
2025-04-08tests: remove GIT_TEST_MERGE_ALGORITHM and test_expect_merge_algorithmElijah Newren1-2/+0
Both of these existed to allow us to reuse all the merge-related tests in the testsuite while easily flipping between the 'recursive' and the 'ort' backends. Now that we have removed merge-recursive and remapped 'recursive' to mean 'ort', we don't need this scaffolding anymore. Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-04-07t: introduce PERL_TEST_HELPERS prerequisitePatrick Steinhardt1-0/+1
In the early days of Git, Perl was used quite prominently throughout the project. This has changed significantly as almost all of the executables we ship nowadays have eventually been rewritten in C. Only a handful of subsystems remain that require Perl: - gitweb, a read-only web interface. - A couple of scripts that allow importing repositories from GNU Arch, CVS and Subversion. - git-send-email(1), which can be used to send mails. - git-request-pull(1), which is used to request somebody to pull from a URL by sending an email. - git-filter-branch(1), which uses Perl with the `--state-branch` option. This command is typically recommended against nowadays in favor of git-filter-repo(1). - Our Perl bindings for Git. - The netrc Git credential helper. None of these subsystems can really be considered to be part of the "core" of Git, and an installation without them is fully functional. It is more likely than not that an end user wouldn't even notice that any features are missing if those tools weren't installed. But while Perl nowadays very much is an optional dependency of Git, there is a significant limitation when Perl isn't available: developers cannot run our test suite. Preceding commits have started to lift this restriction by removing the strict dependency on Perl in many central parts of the test library. But there are still many tests that rely on small Perl helpers to do various different things. Introduce a new PERL_TEST_HELPERS prerequisite that guards all tests that require Perl. This prerequisite is explicitly different than the preexisting PERL prerequisite: - PERL records whether or not features depending on the Perl interpreter are built. - PERL_TEST_HELPERS records whether or not a Perl interpreter is available for our tests. By having these two separate prerequisites we can thus distinguish between tests that inherently depend on Perl because the underlying feature does, and those tests that depend on Perl because the test itself is using Perl. Adapt all tests to set the PERL_TEST_HELPERS prerequisite as needed. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-04-07t: refactor environment sanitization to not use PerlPatrick Steinhardt1-18/+14
Before executing tests we first sanitize the environment. Part of the sanitization is to unset a couple of environment variables that we know will change the behaviour of Git. This is done with a small Perl script, which has the consequence that having a Perl interpreter available is a strict requirement for running our unit tests. The logic itself isn't particularly involved: we simply unset every environment variable whose key starts with 'GIT_', but then explicitly allow a subset of these. Refactor the logic to instead use sed(1) so that it becomes possible to execute our tests without Perl. Based-on-patch-by: Johannes Schindelin <Johannes.Schindelin@gmx.de> Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-04-07t: skip chain lint when PERL_PATH is unsetPatrick Steinhardt1-0/+16
Our chainlint script verifies that test files have proper '&&' chains. This script is written in Perl and executed for every test file before executing the test logic itself. In subsequent commits we're about to refactor our test suite so that Perl becomes an optional dependency, only. And while it is already possible to disable this linter, developers that don't have Perl available at all would always have to disable the linter manually, which is rather cumbersome. Disable the chain linter automatically in case PERL_PATH isn't set to make this a bit less annoying. Bail out with an error in case the developer has asked explicitly for the chain linter. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-03-12t: introduce WITH_BREAKING_CHANGES prerequisiteJunio C Hamano1-1/+6
Earlier c5bc9a7f (Makefile: wire up build option for deprecated features, 2025-01-22) made an unfortunate decision to introduce the WITHOUT_BREAKING_CHANGES prerequisite to perform tests that ensure the historical behaviour that may be different from what we will have in the future. It would inevitably invite double-negation when we need to add tests to ensure the behaviour we want to have in the future. Introduce WITH_BREAKING_CHANGES prerequisite and replace the existing uses of WITHOUT_BREAKING_CHANGES prerequisite. To catch any future topics that add more uses of WITHOUT_BREAKING_CHANGES, mark it as a removed prerequisite. Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-02-03Merge branch 'ps/3.0-remote-deprecation'Junio C Hamano1-0/+4
Following the procedure we established to introduce breaking changes for Git 3.0, allow an early opt-in for removing support of $GIT_DIR/branches/ and $GIT_DIR/remotes/ directories to configure remotes. * ps/3.0-remote-deprecation: remote: announce removal of "branches/" and "remotes/" builtin/pack-redundant: remove subcommand with breaking changes ci: repurpose "linux-gcc" job for deprecations ci: merge linux-gcc-default into linux-gcc Makefile: wire up build option for deprecated features
2025-01-22Makefile: wire up build option for deprecated featuresPatrick Steinhardt1-0/+4
With 57ec9254eb (docs: introduce document to announce breaking changes, 2024-06-14), we have introduced a new document that tracks upcoming breaking changes in the Git project. In 2454970930 (BreakingChanges: early adopter option, 2024-10-11) we have amended the document a bit to mention that any introduced breaking changes must be accompanied by logic that allows us to enable the breaking change at compile-time. While we already have two breaking changes lined up, neither of them has such a switch because they predate those instructions. Introduce the proposed `WITH_BREAKING_CHANGES` preprocessor macro and wire it up with both our Makefiles and Meson. This does not yet wire up the build flag for existing deprecations. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-01-07test-lib: add a few comments to LSan log checkingJeff King1-0/+5
Commit b119a687d4 (test-lib: ignore leaks in the sanitizer's thread code, 2025-01-01) added code to suppress a false positive in the leak checker. But if you're just reading the code, the obscure grep call is a bit of a head-scratcher. Let's add a brief comment explaining what's going on (and anybody digging further can find this commit or that one for all the details). Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-01-07test-lib: simplify lsan results checkJeff King1-6/+1
We want to know if there are any leaks logged by LSan in the results directory, so we run "find" on the containing directory and pipe it to xargs. We can accomplish the same thing by just globbing in the shell and passing the result to grep, which has a few advantages: - it's one fewer process to run - we can glob on the TEST_RESULTS_SAN_FILE pattern, which is what we checked at the beginning of the function, and is the same glob used to show the logs in check_test_results_san_file_ - this correctly handles the case where TEST_OUTPUT_DIRECTORY has a space in it. For example doing: mkdir "/tmp/foo bar" TEST_OUTPUT_DIRECTORY="/tmp/foo bar" make SANITIZE=leak test would yield a lot of: grep: /tmp/foo: No such file or directory grep: bar/test-results/t0006-date.leak/trace.test-tool.582311: No such file or directory when there are leaks. We could do the same thing with "xargs --null", but that isn't portable. We are now subject to command-line length limits, but that is also true of the globbing cat used to show the logs themselves. This hasn't been a problem in practice. We do need to use "grep -s" for the case that the glob does not expand (i.e., there are not any log files at all). This option is in POSIX, and has been used in t7407 for several years without anybody complaining. This also also naturally handles the case where the surrounding directory has already been removed (in which case there are likewise no files!), dropping the need to comment about it. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-01-07test-lib: invert return value of check_test_results_san_file_emptyJeff King1-4/+4
We have a function to check whether LSan logged any leaks. It returns success for no leaks, and non-zero otherwise. This is the simplest thing for its callers, who want to say "if no leaks then return early". But because it's implemented as a shell pipeline, you end up with the awkward: ! find ... | xargs grep leaks | grep -v false-positives where the "!" is actually negating the final grep. Switch the return value (and name) to return success when there are leaks. This should make the code a little easier to read, and the negation in the callers still reads pretty naturally. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-01-01test-lib: ignore leaks in the sanitizer's thread codeJeff King1-1/+2
Our CI jobs sometimes see false positive leaks like this: ================================================================= ==3904583==ERROR: LeakSanitizer: detected memory leaks Direct leak of 32 byte(s) in 1 object(s) allocated from: #0 0x7fa790d01986 in __interceptor_realloc ../../../../src/libsanitizer/lsan/lsan_interceptors.cpp:98 #1 0x7fa790add769 in __pthread_getattr_np nptl/pthread_getattr_np.c:180 #2 0x7fa790d117c5 in __sanitizer::GetThreadStackTopAndBottom(bool, unsigned long*, unsigned long*) ../../../../src/libsanitizer/sanitizer_common/sanitizer_linux_libcdep.cpp:150 #3 0x7fa790d11957 in __sanitizer::GetThreadStackAndTls(bool, unsigned long*, unsigned long*, unsigned long*, unsigned long*) ../../../../src/libsanitizer/sanitizer_common/sanitizer_linux_libcdep.cpp:598 #4 0x7fa790d03fe8 in __lsan::ThreadStart(unsigned int, unsigned long long, __sanitizer::ThreadType) ../../../../src/libsanitizer/lsan/lsan_posix.cpp:51 #5 0x7fa790d013fd in __lsan_thread_start_func ../../../../src/libsanitizer/lsan/lsan_interceptors.cpp:440 #6 0x7fa790adc3eb in start_thread nptl/pthread_create.c:444 #7 0x7fa790b5ca5b in clone3 ../sysdeps/unix/sysv/linux/x86_64/clone3.S:81 This is not a leak in our code, but appears to be a race between one thread calling exit() while another one is in LSan's stack setup code. You can reproduce it easily by running t0003 or t5309 with --stress (these trigger it because of the threading in git-grep and index-pack respectively). This may be a bug in LSan, but regardless of whether it is eventually fixed, it is useful to work around it so that we stop seeing these false positives. We can recognize it by the mention of the sanitizer functions in the DEDUP_TOKEN line. With this patch, the scripts mentioned above should run with --stress indefinitely. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-01-01test-lib: check leak logs for presence of DEDUP_TOKENJeff King1-1/+1
When we check the leak logs, our original strategy was to check for any non-empty log file produced by LSan. We later amended that to ignore noisy lines in 370ef7e40d (test-lib: ignore uninteresting LSan output, 2023-08-28). This makes it hard to ignore noise which is more than a single line; we'd have to actually parse the file to determine the meaning of each line. But there's an easy line-oriented solution. Because we always pass the dedup_token_length option, the output will contain a DEDUP_TOKEN line for each leak that has been found. So if we invert our strategy to stop ignoring useless lines and only look for useful ones, we can just count the number of DEDUP_TOKEN lines. If it's non-zero, then we found at least one leak (it would even give us a count of unique leaks, but we really only care if it is non-zero). This should yield the same outcome, but will help us build more false positive detection on top. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-01-01test-lib: simplify leak-log checkingJeff King1-13/+8
We have a function to count the number of leaks found (actually, it is the number of processes which produced a log file). Once upon a time we cared about seeing if this number increased between runs. But we simplified that away in 95c679ad86 (test-lib: stop showing old leak logs, 2024-09-24), and now we only care if it returns any results or not. In preparation for refactoring it further, let's drop the counting function entirely, and roll it into the "is it empty" check. The outcome should be the same, but we'll be free to return a boolean "did we find anything" without worrying about somebody adding a new call to the counting function. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-01-01test-lib: rely on logs to detect leaksJeff King1-0/+1
When we run with sanitizers, we set abort_on_error=1 so that the tests themselves can detect problems directly (when the buggy program exits with SIGABRT). This has one blind spot, though: we don't always check the exit codes for all programs (e.g., helpers like upload-pack invoked behind the scenes). For ASan and UBSan this is mostly fine; they exit as soon as they see an error, so the unexpected abort of the program causes the test to fail anyway. But for LSan, the program runs to completion, since we can only check for leaks at the end. And in that case we could miss leak reports. And thus we started checking LSan logs in faececa53f (test-lib: have the "check" mode for SANITIZE=leak consider leak logs, 2022-07-28). Originally the logs were optional, but logs are generated (and checked) always as of 8c1d6691bc (test-lib: GIT_TEST_SANITIZE_LEAK_LOG enabled by default, 2024-07-11). And we even check them for each test snippet, as of cf1464331b (test-lib: check for leak logs after every test, 2024-09-24). So now aborting on error is superfluous for LSan! We can get everything we need by checking the logs. And checking the logs is actually preferable, since it gives us more control over silencing false positives (something we do not yet do, but will soon). So let's tell LSan to just exit normally, even if it finds leaks. We can do so with exitcode=0, which also suppresses the abort_on_error flag. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-12-30test-lib: use individual lsan dir for --stress runsJeff King1-1/+1
When storing output in test-results/, we usually give each numbered run in a --stress set its own output file. But we don't do that for storing LSan logs, so something like: ./t0003-attributes.sh --stress will have many scripts simultaneously creating, writing to, and deleting the test-results/t0003-attributes.leak directory. This can cause logs from one run to be attributed to another, spurious failures when creation and deletion race, and so on. This has always been broken, but nobody noticed because it's rare to do a --stress run with LSan (since the point is for the code to run quickly many times in order to hit races). But if you're trying to find a race in the leak sanitizing code, it makes sense to use these together. We can fix it by using $TEST_RESULTS_BASE, which already incorporates the stress job suffix. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-12-27GIT-BUILD-OPTIONS: wire up NO_GITWEB optionPatrick Steinhardt1-0/+1
Building our "gitweb" interface is optional in our Makefile and in Meson and not wired up at all with CMake, but disabling it causes a couple of tests in the t950* range that pull in "t/lib-gitweb.sh". This is because the test library knows to execute gitweb-tests based on whether or not Perl is available, but we may have Perl available and still end up not building gitweb e.g. with `make test NO_GITWEB=YesPlease`. Fix this issue by wiring up a new "NO_GITWEB" build option so that we can skip these tests in case gitweb is not built. Note that this new build option requires us to move the configuration of GIT-BUILD-OPTIONS to a later point in our Meson build instructions. But as that file is only consumed by our tests at runtime this change does not cause any issues. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-12-07t: allow overriding build dirPatrick Steinhardt1-1/+2
Our "test-lib.sh" assumes that our build directory is the parent directory of "t/". While true when using our Makefile, it's not when using build systems that support out-of-tree builds. In commit ee9e66e4e7 (cmake: avoid editing t/test-lib.sh, 2022-10-18), we have introduce support for overriding the GIT_BUILD_DIR by creating the file "$GIT_BUILD_DIR/GIT-BUILD-DIR" with its contents pointing to the location of the build directory. The intent was to stop modifying "t/test-lib.sh" with the CMake build systems while allowing out-of-tree builds. But "$GIT_BUILD_DIR" is somewhat misleadingly named, as it in fact points to the _source_ directory. So while that commit solved part of the problem for out-of-tree builds, CMake still has to write files into the source tree. Solve the second part of the problem, namely not having to write any data into the source directory at all, by also supporting an environment variable that allows us to point to a different build directory. This allows us to perform properly self-contained out-of-tree builds. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-12-07t: better support for out-of-tree buildsPatrick Steinhardt1-3/+3
Our in-tree builds used by the Makefile use various different build directories scattered around different locations. The paths to those build directories have to be propagated to our tests such that they can find the contained files. This is done via a mixture of hardcoded paths in our test library and injected variables in our bin-wrappers or "GIT-BUILD-OPTIONS". The latter two mechanisms are preferable over using hardcoded paths. For one, we have all paths which are subject to change stored in a small set of central files instead of having the knowledge of build paths in many files. And second, it allows build systems which build files elsewhere to adapt those paths based on their own needs. This is especially nice in the context of build systems that use out-of-tree builds like CMake or Meson. Remove hardcoded knowledge of build paths from our test library and move it into our bin-wrappers and "GIT-BUILD-OPTIONS". Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-12-07Makefile: use common template for GIT-BUILD-OPTIONSPatrick Steinhardt1-6/+16
The "GIT-BUILD-OPTIONS" file is generated by our build systems to propagate built-in features and paths to our tests. The generation is done ad-hoc, where both our Makefile and the CMake build instructions simply echo a bunch of strings into the file. This makes it very hard to figure out what variables are expected to exist and what format they have, and the written variables can easily get out of sync between build systems. Introduce a new "GIT-BUILD-OPTIONS.in" template to address this issue. This has multiple advantages: - It demonstrates which built options exist in the first place. - It can serve as a spot to document the build options. - Some build systems complain when not all variables could be substituted, alerting us of mismatches. Others don't, but if we forgot to substitute such variables we now have a bogus string that will likely cause our tests to fail, if they have any meaning in the first place. Backfill values that we didn't yet set in our CMake build instructions. While at it, remove the `SUPPORTS_SIMPLE_IPC` variable that we only set up in CMake as it isn't used anywhere. This change requires us to adapt the setup of TEST_OUTPUT_DIRECTORY in "test-lib.sh" such that it does not get overwritten after sourcing when it has been set up via the environment. This is the only instance I could find where we rely on ordering on variables. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-12-04Merge branch 'ps/leakfixes-part-10'Junio C Hamano1-71/+1
Leakfixes. * ps/leakfixes-part-10: (27 commits) t: remove TEST_PASSES_SANITIZE_LEAK annotations test-lib: unconditionally enable leak checking t: remove unneeded !SANITIZE_LEAK prerequisites t: mark some tests as leak free t5601: work around leak sanitizer issue git-compat-util: drop now-unused `UNLEAK()` macro global: drop `UNLEAK()` annotation t/helper: fix leaking commit graph in "read-graph" subcommand builtin/branch: fix leaking sorting options builtin/init-db: fix leaking directory paths builtin/help: fix leaks in `check_git_cmd()` help: fix leaking return value from `help_unknown_cmd()` help: fix leaking `struct cmdnames` help: refactor to not use globals for reading config builtin/sparse-checkout: fix leaking sanitized patterns split-index: fix memory leak in `move_cache_to_base_index()` git: refactor builtin handling to use a `struct strvec` git: refactor alias handling to use a `struct strvec` strvec: introduce new `strvec_splice()` function line-log: fix leak when rewriting commit parents ...
2024-11-22Merge branch 'jk/test-malloc-debug-check'Junio C Hamano1-47/+50
Avoid build/test breakage on a system without working malloc debug support dynamic library. * jk/test-malloc-debug-check: test-lib: move malloc-debug setup after $PATH setup test-lib: check malloc debug LD_PRELOAD before using
2024-11-21test-lib: unconditionally enable leak checkingPatrick Steinhardt1-71/+1
Over the last two releases we have plugged a couple hundred of memory leaks exposed by the Git test suite. With the preceding commits we have finally fixed the last leak exposed by our test suite, which means that we are now basically leak free wherever we have branch coverage. From hereon, the Git test suite should ideally stay free of memory leaks. Most importantly, any test suite that is being added should automatically be subject to the leak checker, and if that test does not pass it is a strong signal that the added code introduced new memory leaks and should not be accepted without further changes. Drop the infrastructure around TEST_PASSES_SANITIZE_LEAK to reflect this new requirement. Like this, all test suites will be subject to the leak checker by default. This is being intentionally strict, but we still have an escape hatch: the SANITIZE_LEAK prerequisite. There is one known case in t5601 where the leak sanitizer itself is buggy, so adding this prereq in such cases is acceptable. Another acceptable situation is when a newly added test uncovers preexisting memory leaks: when fixing that memory leak would be sufficiently complicated it is fine to annotate and document the leak accordingly. But in any case, the burden is now on the patch author to explain why exactly they have to add the SANITIZE_LEAK prerequisite. The TEST_PASSES_SANITIZE_LEAK annotations will be dropped in the next patch. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-11-14test-lib: move malloc-debug setup after $PATH setupJeff King1-50/+50
Originally, the conditional definition of the setup/teardown functions for malloc checking could be run at any time, because they depended only on command-line options and the system getconf function. But since 02d900361c (test-lib: check malloc debug LD_PRELOAD before using, 2024-11-11), we probe the system by running "git version". Since this code runs before we've set $PATH to point to the version of Git we intend to test, we actually run the system version of git. This mostly works, since what we really care about is whether the LD_PRELOAD works, and it should work the same with any program. But there are some corner cases: 1. You might not have a system git at all, in which case the preload will appear to fail, even though it could work with the actual built version of git. 2. Your system git could be linked in a different way. For example, if it was built statically, then it will ignore LD_PRELOAD entirely, and we might assume that the preload works, even though it might not when used with a dynamic build. We could give a more complete path to the version of Git we intend to test, but features like GIT_TEST_INSTALLED make that not entirely trivial. So instead, let's just bump the setup until after we've set up the $PATH. There's no need for us to do it early, as long as it is done before the first test runs. Reported-by: Toon Claes <toon@iotcl.com> Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-11-12test-lib: check malloc debug LD_PRELOAD before usingJeff King1-2/+5
This fixes test failures across the suite on glibc platforms that don't have libc_malloc_debug.so.0. We added support for glibc's malloc checking routines long ago in a731fa916e (Add MALLOC_CHECK_ and MALLOC_PERTURB_ libc env to the test suite for detecting heap corruption, 2012-09-14). Back then we didn't need to do any checks to see if the platform supported it. We were just setting some environment variables which would either enable it or not. That changed in 131b94a10a (test-lib.sh: Use GLIBC_TUNABLES instead of MALLOC_CHECK_ on glibc >= 2.34, 2022-03-04). Now that glibc split this out into libc_malloc_debug.so, we have to add it to LD_PRELOAD. We only do that when we detect glibc, but it's possible to have glibc but not the malloc debug library. In that case LD_PRELOAD will complain to stderr, and tests which check for an empty stderr will fail. You can work around this by setting TEST_NO_MALLOC_CHECK, which disables the feature entirely. But it's not obvious to know you need to do that. Instead, since this malloc checking is best-effort anyway, let's just automatically disable it when the LD_PRELOAD appears not to work. We can check it by running something simple that should work (and produce nothing on stderr) like "git version". Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-10-16t/test-lib: wire up NO_ICONV prerequisitePatrick Steinhardt1-0/+1
The iconv library is used by Git to reencode files, commit messages and other things. As such it is a rather integral part, but given that many platforms nowadays use UTF-8 everywhere you can live without support for reencoding in many situations. It is thus optional to build Git with iconv, and some of our platforms wired up in "config.mak.uname" disable it. But while we support building without it, running our test suite with "NO_ICONV=Yes" causes many test failures. Wire up a new test prerequisite ICONV that gets populated via our GIT-BUILD-OPTIONS. Annotate failing tests accordingly. Note that this commit does not do a deep dive into every single test to assess whether the failure is expected or not. Most of the tests do smell like the expected kind of failure though. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Taylor Blau <me@ttaylorr.com>
2024-10-16t/test-lib: fix quoting of TEST_RESULTS_SAN_FILEPatrick Steinhardt1-1/+1
When assembling our LSAN_OPTIONS that configure the leak sanitizer we end up prepending the string with various different colon-separated options via calls to `prepend_var`. One of the settings we add is the path where the sanitizer should store logs, which can be an arbitrary filesystem path. Naturally, filesystem paths may contain whitespace characters. And while it does seem as if we were quoting the value, we use escaped quotes and consequently split up the value if it does contain spaces. This leads to the following error in t0000 when having a value with whitespaces: .../t/test-lib.sh: eval: line 64: unexpected EOF while looking for matching `"' ++ return 1 error: last command exited with $?=1 not ok 5 - subtest: 3 passing tests The error itself is a bit puzzling at first. The basic problem is that the code sees the leading escaped quote during eval, but because we truncate everything after the space character it doesn't see the trailing escaped quote and thus fails to parse the string. Properly quote the value to fix the issue while using single-quotes to quote the inner value passed to eval. The issue can be reproduced by t0000 with such a path that contains spaces. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Taylor Blau <me@ttaylorr.com>
2024-09-25test-lib: check for leak logs after every testJeff King1-5/+6
If you are trying to find and fix leaks in a large test script, it can be overwhelming to see the leak logs for every test at once. The previous commit let you use "--immediate" to see the logs after the first failing test, but this isn't always the first leak. As discussed there, we may see leaks from previous tests that didn't happen to fail. To catch those, let's check for any logs that appeared after each test snippet is run, meaning that in a SANITIZE=leak build, any leak is an immediate failure of the test snippet. This check is mostly free in non-leak builds (just a "test -z"), and only a few extra processes in a leak build, so I don't think the overhead should matter (if it does, we could probably optimize for the common "no logs" case without even spending a process). Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-09-25test-lib: show leak-sanitizer logs on --immediate failureJeff King1-0/+1
When we've compiled with SANITIZE=leak, at the end of the test script we'll dump any collected logs to stdout. These logs have two uses: 1. Leaks don't always cause a test snippet to fail (e.g., if they happen in a sub-process that we expect to return non-zero). Checking the logs catches these cases that we'd otherwise miss entirely. 2. LSan will dump the leak info to stderr, but that is sometimes hidden (e.g., because it's redirected by the test, or because it's in a sub-process whose stderr goes elsewhere). Dumping the logs is the easiest way for the developer to see them. One downside is that the set of logs for an entire script may be very long, especially when you're trying to fix existing test scripts. You can run with --immediate to stop at the first failing test, which means we'll have accrued fewer logs. But we don't show the logs in that case! Let's start doing so. This can only help case (2), of course (since it depends on test failure). And it's somewhat weakened by the fact that any cases of (1) will pollute the logs. But we can improve things further in the next patch. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-09-25test-lib: stop showing old leak logsJeff King1-33/+2
We ask LSan to record the logs of all leaks in test-results/, which is useful for finding leaks that didn't trigger a test failure. We don't clean out the leak/ directory for each test before running it, though. Instead, we count the number of files it has, and complain only if we ended up with more when the script finishes. So we shouldn't trigger any output if you've made a script leak free. But if you simply _reduced_ the number of leaks, then there is an annoying outcome: we do not record which logs were from this run and which were from previous ones. So when we dump them to stdout, you get a mess of possibly-outdated leaks. This is very confusing when you are in an edit-compile-test cycle trying to fix leaks. The instructions do note that you should "rm -rf test-results/" if you want to avoid this. But I'm having trouble seeing how this cumulative count could ever be useful. It is not even counting the number of leaks, but rather the number of processes with at least one leak! So let's just blow away the per-test leak/ directory before running. We already overwrite the ".out" file in test-results/ in the same way, so this is following that pattern. Running "make test" isn't affected by this, since it blows away all of test-results/ already. This only comes up when you are iterating on a single script that you're running manually. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-09-20Merge branch 'ps/leakfixes-part-6'Junio C Hamano1-1/+10
More leakfixes. * ps/leakfixes-part-6: (22 commits) builtin/repack: fix leaking keep-pack list merge-ort: fix two leaks when handling directory rename modifications match-trees: fix leaking prefixes in `shift_tree()` builtin/fmt-merge-msg: fix leaking buffers builtin/grep: fix leaking object context builtin/pack-objects: plug leaking list of keep-packs builtin/repack: fix leaking line buffer when packing promisors negotiator/skipping: fix leaking commit entries shallow: fix leaking members of `struct shallow_info` shallow: free grafts when unregistering them object: clear grafts when clearing parsed object pool gpg-interface: fix misdesigned signing key interfaces send-pack: fix leaking push cert nonce remote: fix leak in reachability check of a remote-tracking ref remote: fix leaking tracking refs builtin/submodule--helper: fix leaking refs on push-check submodule: fix leaking fetch task data upload-pack: fix leaking child process data on reachability checks builtin/push: fix leaking refspec query result send-pack: fix leaking common object IDs ...