diff options
Diffstat (limited to 't')
| -rwxr-xr-x | t/t0410-partial-clone.sh | 6 | ||||
| -rwxr-xr-x | t/t0610-reftable-basics.sh | 8 | ||||
| -rwxr-xr-x | t/t1016-compatObjectFormat.sh | 262 | ||||
| -rwxr-xr-x | t/t5300-pack-object.sh | 10 | ||||
| -rwxr-xr-x | t/t5310-pack-bitmaps.sh | 12 | ||||
| -rwxr-xr-x | t/t5330-no-lazy-fetch-with-commit-graph.sh | 4 | ||||
| -rwxr-xr-x | t/t5332-multi-pack-reuse.sh | 22 | ||||
| -rwxr-xr-x | t/t5500-fetch-pack.sh | 7 | ||||
| -rwxr-xr-x | t/t5582-fetch-negative-refspec.sh | 4 | ||||
| -rwxr-xr-x | t/t5616-partial-clone.sh | 30 | ||||
| -rwxr-xr-x | t/t7800-difftool.sh | 4 | ||||
| -rw-r--r-- | t/test-lib.sh | 97 | ||||
| -rw-r--r-- | t/unit-tests/clar/.editorconfig | 13 | ||||
| -rw-r--r-- | t/unit-tests/clar/.github/workflows/ci.yml | 20 | ||||
| -rw-r--r-- | t/unit-tests/clar/.gitignore | 1 | ||||
| -rw-r--r-- | t/unit-tests/clar/CMakeLists.txt | 28 | ||||
| -rw-r--r-- | t/unit-tests/clar/clar.c | 127 | ||||
| -rw-r--r-- | t/unit-tests/clar/clar/print.h | 11 | ||||
| -rw-r--r-- | t/unit-tests/clar/clar/sandbox.h | 17 | ||||
| -rw-r--r-- | t/unit-tests/clar/clar/summary.h | 14 | ||||
| -rw-r--r-- | t/unit-tests/clar/test/.gitignore | 4 | ||||
| -rw-r--r-- | t/unit-tests/clar/test/CMakeLists.txt | 39 | ||||
| -rw-r--r-- | t/unit-tests/clar/test/Makefile | 39 | ||||
| -rwxr-xr-x | t/unit-tests/generate-clar-decls.sh | 16 |
24 files changed, 479 insertions, 316 deletions
diff --git a/t/t0410-partial-clone.sh b/t/t0410-partial-clone.sh index 34bdb3ab1f..2a5bdbeeb8 100755 --- a/t/t0410-partial-clone.sh +++ b/t/t0410-partial-clone.sh @@ -240,7 +240,7 @@ test_expect_success 'fetching of missing objects works with ref-in-want enabled' grep "fetch< fetch=.*ref-in-want" trace ' -test_expect_success 'fetching of missing objects from another promisor remote' ' +test_expect_success 'fetching from another promisor remote' ' git clone "file://$(pwd)/server" server2 && test_commit -C server2 bar && git -C server2 repack -a -d --write-bitmap-index && @@ -263,8 +263,8 @@ test_expect_success 'fetching of missing objects from another promisor remote' ' grep "$HASH2" out ' -test_expect_success 'fetching of missing objects configures a promisor remote' ' - git clone "file://$(pwd)/server" server3 && +test_expect_success 'fetching with --filter configures a promisor remote' ' + test_create_repo server3 && test_commit -C server3 baz && git -C server3 repack -a -d --write-bitmap-index && HASH3=$(git -C server3 rev-parse baz) && diff --git a/t/t0610-reftable-basics.sh b/t/t0610-reftable-basics.sh index 67bf3a82f6..4618ffc108 100755 --- a/t/t0610-reftable-basics.sh +++ b/t/t0610-reftable-basics.sh @@ -449,10 +449,12 @@ test_expect_success 'ref transaction: retry acquiring tables.list lock' ' ) ' -# This test fails most of the time on Windows systems. The root cause is +# This test fails most of the time on Cygwin systems. The root cause is # that Windows does not allow us to rename the "tables.list.lock" file into -# place when "tables.list" is open for reading by a concurrent process. -test_expect_success !WINDOWS 'ref transaction: many concurrent writers' ' +# place when "tables.list" is open for reading by a concurrent process. We have +# worked around that in our MinGW-based rename emulation, but the Cygwin +# emulation seems to be insufficient. +test_expect_success !CYGWIN 'ref transaction: many concurrent writers' ' test_when_finished "rm -rf repo" && git init repo && ( diff --git a/t/t1016-compatObjectFormat.sh b/t/t1016-compatObjectFormat.sh index 5641271b23..e88362fbe4 100755 --- a/t/t1016-compatObjectFormat.sh +++ b/t/t1016-compatObjectFormat.sh @@ -23,84 +23,83 @@ test_description='Test how well compatObjectFormat works' # the commit is identical to the commit in the other repository. compat_hash () { - case "$1" in - "sha1") - echo "sha256" - ;; - "sha256") - echo "sha1" - ;; - esac + case "$1" in + "sha1") + echo "sha256" + ;; + "sha256") + echo "sha1" + ;; + esac } hello_oid () { - case "$1" in - "sha1") - echo "$hello_sha1_oid" - ;; - "sha256") - echo "$hello_sha256_oid" - ;; - esac + case "$1" in + "sha1") + echo "$hello_sha1_oid" + ;; + "sha256") + echo "$hello_sha256_oid" + ;; + esac } tree_oid () { - case "$1" in - "sha1") - echo "$tree_sha1_oid" - ;; - "sha256") - echo "$tree_sha256_oid" - ;; - esac + case "$1" in + "sha1") + echo "$tree_sha1_oid" + ;; + "sha256") + echo "$tree_sha256_oid" + ;; + esac } commit_oid () { - case "$1" in - "sha1") - echo "$commit_sha1_oid" - ;; - "sha256") - echo "$commit_sha256_oid" - ;; - esac + case "$1" in + "sha1") + echo "$commit_sha1_oid" + ;; + "sha256") + echo "$commit_sha256_oid" + ;; + esac } commit2_oid () { - case "$1" in - "sha1") - echo "$commit2_sha1_oid" - ;; - "sha256") - echo "$commit2_sha256_oid" - ;; - esac + case "$1" in + "sha1") + echo "$commit2_sha1_oid" + ;; + "sha256") + echo "$commit2_sha256_oid" + ;; + esac } del_sigcommit () { - local delete="$1" - - if test "$delete" = "sha256" ; then - local pattern="gpgsig-sha256" - else - local pattern="gpgsig" - fi - test-tool delete-gpgsig "$pattern" + local delete="$1" + + if test "$delete" = "sha256" ; then + local pattern="gpgsig-sha256" + else + local pattern="gpgsig" + fi + test-tool delete-gpgsig "$pattern" } - del_sigtag () { - local storage="$1" - local delete="$2" - - if test "$storage" = "$delete" ; then - local pattern="trailer" - elif test "$storage" = "sha256" ; then - local pattern="gpgsig" - else - local pattern="gpgsig-sha256" - fi - test-tool delete-gpgsig "$pattern" + local storage="$1" + local delete="$2" + + if test "$storage" = "$delete" ; then + local pattern="trailer" + elif test "$storage" = "sha256" ; then + local pattern="gpgsig" + else + local pattern="gpgsig-sha256" + fi + test-tool delete-gpgsig "$pattern" } base=$(pwd) @@ -145,9 +144,9 @@ do ' test_expect_success "create a $hash branch" ' git checkout -b branch $(commit_oid $hash) && - echo "More more more give me more!" > more && + echo "More more more give me more!" >more && eval more_${hash}_oid=$(git hash-object more) && - echo "Another and another and another" > another && + echo "Another and another and another" >another && eval another_${hash}_oid=$(git hash-object another) && git update-index --add more another && git commit -m "Add more files!" && @@ -164,15 +163,15 @@ do ' test_expect_success GPG2 "create additional $hash signed commits" ' git commit --gpg-sign --allow-empty -m "This is an additional signed commit" && - git cat-file commit HEAD | del_sigcommit sha256 > "../${hash}_signedcommit3" && - git cat-file commit HEAD | del_sigcommit sha1 > "../${hash}_signedcommit4" && + git cat-file commit HEAD | del_sigcommit sha256 >"../${hash}_signedcommit3" && + git cat-file commit HEAD | del_sigcommit sha1 >"../${hash}_signedcommit4" && eval signedcommit3_${hash}_oid=$(git hash-object -t commit -w ../${hash}_signedcommit3) && eval signedcommit4_${hash}_oid=$(git hash-object -t commit -w ../${hash}_signedcommit4) ' test_expect_success GPG2 "create additional $hash signed tags" ' git tag -s -m "This is an additional signed tag" signedtag34 HEAD && - git cat-file tag signedtag34 | del_sigtag "${hash}" sha256 > ../${hash}_signedtag3 && - git cat-file tag signedtag34 | del_sigtag "${hash}" sha1 > ../${hash}_signedtag4 && + git cat-file tag signedtag34 | del_sigtag "${hash}" sha256 >../${hash}_signedtag3 && + git cat-file tag signedtag34 | del_sigtag "${hash}" sha1 >../${hash}_signedtag4 && eval signedtag3_${hash}_oid=$(git hash-object -t tag -w ../${hash}_signedtag3) && eval signedtag4_${hash}_oid=$(git hash-object -t tag -w ../${hash}_signedtag4) ' @@ -180,81 +179,80 @@ done cd "$base" compare_oids () { - test "$#" = 5 && { local PREREQ="$1"; shift; } || PREREQ= - local type="$1" - local name="$2" - local sha1_oid="$3" - local sha256_oid="$4" - - echo ${sha1_oid} > ${name}_sha1_expected - echo ${sha256_oid} > ${name}_sha256_expected - echo ${type} > ${name}_type_expected - - git --git-dir=repo-sha1/.git rev-parse --output-object-format=sha256 ${sha1_oid} > ${name}_sha1_sha256_found - git --git-dir=repo-sha256/.git rev-parse --output-object-format=sha1 ${sha256_oid} > ${name}_sha256_sha1_found - local sha1_sha256_oid="$(cat ${name}_sha1_sha256_found)" - local sha256_sha1_oid="$(cat ${name}_sha256_sha1_found)" - - test_expect_success $PREREQ "Verify ${type} ${name}'s sha1 oid" ' - git --git-dir=repo-sha256/.git rev-parse --output-object-format=sha1 ${sha256_oid} > ${name}_sha1 && - test_cmp ${name}_sha1 ${name}_sha1_expected -' - - test_expect_success $PREREQ "Verify ${type} ${name}'s sha256 oid" ' - git --git-dir=repo-sha1/.git rev-parse --output-object-format=sha256 ${sha1_oid} > ${name}_sha256 && - test_cmp ${name}_sha256 ${name}_sha256_expected -' + test "$#" = 5 && { local PREREQ="$1"; shift; } || PREREQ= + local type="$1" + local name="$2" + local sha1_oid="$3" + local sha256_oid="$4" + + echo ${sha1_oid} >${name}_sha1_expected + echo ${sha256_oid} >${name}_sha256_expected + echo ${type} >${name}_type_expected + + git --git-dir=repo-sha1/.git rev-parse --output-object-format=sha256 ${sha1_oid} >${name}_sha1_sha256_found + git --git-dir=repo-sha256/.git rev-parse --output-object-format=sha1 ${sha256_oid} >${name}_sha256_sha1_found + local sha1_sha256_oid="$(cat ${name}_sha1_sha256_found)" + local sha256_sha1_oid="$(cat ${name}_sha256_sha1_found)" + + test_expect_success $PREREQ "Verify ${type} ${name}'s sha1 oid" ' + git --git-dir=repo-sha256/.git rev-parse --output-object-format=sha1 ${sha256_oid} >${name}_sha1 && + test_cmp ${name}_sha1 ${name}_sha1_expected + ' - test_expect_success $PREREQ "Verify ${name}'s sha1 type" ' - git --git-dir=repo-sha1/.git cat-file -t ${sha1_oid} > ${name}_type1 && - git --git-dir=repo-sha256/.git cat-file -t ${sha256_sha1_oid} > ${name}_type2 && - test_cmp ${name}_type1 ${name}_type2 && - test_cmp ${name}_type1 ${name}_type_expected -' + test_expect_success $PREREQ "Verify ${type} ${name}'s sha256 oid" ' + git --git-dir=repo-sha1/.git rev-parse --output-object-format=sha256 ${sha1_oid} >${name}_sha256 && + test_cmp ${name}_sha256 ${name}_sha256_expected + ' - test_expect_success $PREREQ "Verify ${name}'s sha256 type" ' - git --git-dir=repo-sha256/.git cat-file -t ${sha256_oid} > ${name}_type3 && - git --git-dir=repo-sha1/.git cat-file -t ${sha1_sha256_oid} > ${name}_type4 && - test_cmp ${name}_type3 ${name}_type4 && - test_cmp ${name}_type3 ${name}_type_expected -' + test_expect_success $PREREQ "Verify ${name}'s sha1 type" ' + git --git-dir=repo-sha1/.git cat-file -t ${sha1_oid} >${name}_type1 && + git --git-dir=repo-sha256/.git cat-file -t ${sha256_sha1_oid} >${name}_type2 && + test_cmp ${name}_type1 ${name}_type2 && + test_cmp ${name}_type1 ${name}_type_expected + ' - test_expect_success $PREREQ "Verify ${name}'s sha1 size" ' - git --git-dir=repo-sha1/.git cat-file -s ${sha1_oid} > ${name}_size1 && - git --git-dir=repo-sha256/.git cat-file -s ${sha256_sha1_oid} > ${name}_size2 && - test_cmp ${name}_size1 ${name}_size2 -' + test_expect_success $PREREQ "Verify ${name}'s sha256 type" ' + git --git-dir=repo-sha256/.git cat-file -t ${sha256_oid} >${name}_type3 && + git --git-dir=repo-sha1/.git cat-file -t ${sha1_sha256_oid} >${name}_type4 && + test_cmp ${name}_type3 ${name}_type4 && + test_cmp ${name}_type3 ${name}_type_expected + ' - test_expect_success $PREREQ "Verify ${name}'s sha256 size" ' - git --git-dir=repo-sha256/.git cat-file -s ${sha256_oid} > ${name}_size3 && - git --git-dir=repo-sha1/.git cat-file -s ${sha1_sha256_oid} > ${name}_size4 && - test_cmp ${name}_size3 ${name}_size4 -' + test_expect_success $PREREQ "Verify ${name}'s sha1 size" ' + git --git-dir=repo-sha1/.git cat-file -s ${sha1_oid} >${name}_size1 && + git --git-dir=repo-sha256/.git cat-file -s ${sha256_sha1_oid} >${name}_size2 && + test_cmp ${name}_size1 ${name}_size2 + ' - test_expect_success $PREREQ "Verify ${name}'s sha1 pretty content" ' - git --git-dir=repo-sha1/.git cat-file -p ${sha1_oid} > ${name}_content1 && - git --git-dir=repo-sha256/.git cat-file -p ${sha256_sha1_oid} > ${name}_content2 && - test_cmp ${name}_content1 ${name}_content2 -' + test_expect_success $PREREQ "Verify ${name}'s sha256 size" ' + git --git-dir=repo-sha256/.git cat-file -s ${sha256_oid} >${name}_size3 && + git --git-dir=repo-sha1/.git cat-file -s ${sha1_sha256_oid} >${name}_size4 && + test_cmp ${name}_size3 ${name}_size4 + ' - test_expect_success $PREREQ "Verify ${name}'s sha256 pretty content" ' - git --git-dir=repo-sha256/.git cat-file -p ${sha256_oid} > ${name}_content3 && - git --git-dir=repo-sha1/.git cat-file -p ${sha1_sha256_oid} > ${name}_content4 && - test_cmp ${name}_content3 ${name}_content4 -' + test_expect_success $PREREQ "Verify ${name}'s sha1 pretty content" ' + git --git-dir=repo-sha1/.git cat-file -p ${sha1_oid} >${name}_content1 && + git --git-dir=repo-sha256/.git cat-file -p ${sha256_sha1_oid} >${name}_content2 && + test_cmp ${name}_content1 ${name}_content2 + ' - test_expect_success $PREREQ "Verify ${name}'s sha1 content" ' - git --git-dir=repo-sha1/.git cat-file ${type} ${sha1_oid} > ${name}_content5 && - git --git-dir=repo-sha256/.git cat-file ${type} ${sha256_sha1_oid} > ${name}_content6 && - test_cmp ${name}_content5 ${name}_content6 -' + test_expect_success $PREREQ "Verify ${name}'s sha256 pretty content" ' + git --git-dir=repo-sha256/.git cat-file -p ${sha256_oid} >${name}_content3 && + git --git-dir=repo-sha1/.git cat-file -p ${sha1_sha256_oid} >${name}_content4 && + test_cmp ${name}_content3 ${name}_content4 + ' - test_expect_success $PREREQ "Verify ${name}'s sha256 content" ' - git --git-dir=repo-sha256/.git cat-file ${type} ${sha256_oid} > ${name}_content7 && - git --git-dir=repo-sha1/.git cat-file ${type} ${sha1_sha256_oid} > ${name}_content8 && - test_cmp ${name}_content7 ${name}_content8 -' + test_expect_success $PREREQ "Verify ${name}'s sha1 content" ' + git --git-dir=repo-sha1/.git cat-file ${type} ${sha1_oid} >${name}_content5 && + git --git-dir=repo-sha256/.git cat-file ${type} ${sha256_sha1_oid} >${name}_content6 && + test_cmp ${name}_content5 ${name}_content6 + ' + test_expect_success $PREREQ "Verify ${name}'s sha256 content" ' + git --git-dir=repo-sha256/.git cat-file ${type} ${sha256_oid} >${name}_content7 && + git --git-dir=repo-sha1/.git cat-file ${type} ${sha1_sha256_oid} >${name}_content8 && + test_cmp ${name}_content7 ${name}_content8 + ' } compare_oids 'blob' hello "$hello_sha1_oid" "$hello_sha256_oid" diff --git a/t/t5300-pack-object.sh b/t/t5300-pack-object.sh index e13f289dd5..999d028a4c 100755 --- a/t/t5300-pack-object.sh +++ b/t/t5300-pack-object.sh @@ -155,6 +155,11 @@ test_expect_success 'pack without delta' ' check_deltas stderr = 0 ' +test_expect_success 'negative window clamps to 0' ' + git pack-objects --progress --window=-1 neg-window <obj-list 2>stderr && + check_deltas stderr = 0 +' + test_expect_success 'pack-objects with bogus arguments' ' test_must_fail git pack-objects --window=0 test-1 blah blah <obj-list ' @@ -629,11 +634,6 @@ test_expect_success 'prefetch objects' ' test_line_count = 1 donelines ' -test_expect_success 'negative window clamps to 0' ' - git pack-objects --progress --window=-1 neg-window <obj-list 2>stderr && - check_deltas stderr = 0 -' - for hash in sha1 sha256 do test_expect_success "verify-pack with $hash packfile" ' diff --git a/t/t5310-pack-bitmaps.sh b/t/t5310-pack-bitmaps.sh index a6de7c5764..eabfcd7ff6 100755 --- a/t/t5310-pack-bitmaps.sh +++ b/t/t5310-pack-bitmaps.sh @@ -502,6 +502,18 @@ test_expect_success 'boundary-based traversal is used when requested' ' done ' +test_expect_success 'left-right not confused by bitmap index' ' + git rev-list --left-right other...HEAD >expect && + git rev-list --use-bitmap-index --left-right other...HEAD >actual && + test_cmp expect actual +' + +test_expect_success 'left-right count not confused by bitmap-index' ' + git rev-list --left-right --count other...HEAD >expect && + git rev-list --use-bitmap-index --left-right --count other...HEAD >actual && + test_cmp expect actual +' + test_bitmap_cases "pack.writeBitmapLookupTable" test_expect_success 'verify writing bitmap lookup table when enabled' ' diff --git a/t/t5330-no-lazy-fetch-with-commit-graph.sh b/t/t5330-no-lazy-fetch-with-commit-graph.sh index 2cc7fd7a47..313eadba98 100755 --- a/t/t5330-no-lazy-fetch-with-commit-graph.sh +++ b/t/t5330-no-lazy-fetch-with-commit-graph.sh @@ -37,9 +37,9 @@ test_expect_success 'fetch any commit from promisor with the usage of the commit git -C with-commit-graph config remote.origin.partialclonefilter blob:none && test_commit -C with-commit any-commit && anycommit=$(git -C with-commit rev-parse HEAD) && - GIT_TRACE="$(pwd)/trace.txt" \ + test_must_fail env GIT_TRACE="$(pwd)/trace.txt" \ git -C with-commit-graph fetch origin $anycommit 2>err && - ! grep "fatal: promisor-remote: unable to fork off fetch subprocess" err && + test_grep ! "fatal: promisor-remote: unable to fork off fetch subprocess" err && grep "git fetch origin" trace.txt >actual && test_line_count = 1 actual ' diff --git a/t/t5332-multi-pack-reuse.sh b/t/t5332-multi-pack-reuse.sh index a1b547b90c..57cad7708f 100755 --- a/t/t5332-multi-pack-reuse.sh +++ b/t/t5332-multi-pack-reuse.sh @@ -258,4 +258,26 @@ test_expect_success 'duplicate objects' ' ) ' +test_expect_success 'duplicate objects with verbatim reuse' ' + git init duplicate-objects-verbatim && + ( + cd duplicate-objects-verbatim && + + git config pack.allowPackReuse multi && + + test_commit_bulk 64 && + + # take the first object from the main pack... + git show-index <$(ls $packdir/pack-*.idx) >obj.raw && + sort -nk1 <obj.raw | head -n1 | cut -d" " -f2 >in && + + # ...and create a separate pack containing just that object + p="$(git pack-objects $packdir/pack <in)" && + + git multi-pack-index write --bitmap --preferred-pack=pack-$p.idx && + + test_pack_objects_reused_all 192 2 + ) +' + test_done diff --git a/t/t5500-fetch-pack.sh b/t/t5500-fetch-pack.sh index 509133c1f9..2677cd5faa 100755 --- a/t/t5500-fetch-pack.sh +++ b/t/t5500-fetch-pack.sh @@ -925,6 +925,13 @@ test_expect_success 'fetch exclude tag one' ' test_cmp expected actual ' +test_expect_success 'fetch exclude tag one as revision' ' + test_when_finished rm -f rev err && + git -C shallow-exclude rev-parse one >rev && + test_must_fail git -C shallow12 fetch --shallow-exclude $(cat rev) origin 2>err && + grep "deepen-not is not a ref:" err +' + test_expect_success 'fetching deepen' ' test_create_repo shallow-deepen && ( diff --git a/t/t5582-fetch-negative-refspec.sh b/t/t5582-fetch-negative-refspec.sh index 7a80e47c2b..ae32f8178a 100755 --- a/t/t5582-fetch-negative-refspec.sh +++ b/t/t5582-fetch-negative-refspec.sh @@ -282,4 +282,8 @@ test_expect_success '--prefetch succeeds when refspec becomes empty' ' git -C one fetch --prefetch ' +test_expect_success '--prefetch succeeds with empty command line refspec' ' + git -C one fetch --prefetch origin +refs/tags/extra +' + test_done diff --git a/t/t5616-partial-clone.sh b/t/t5616-partial-clone.sh index 8415884754..4650451964 100755 --- a/t/t5616-partial-clone.sh +++ b/t/t5616-partial-clone.sh @@ -693,6 +693,36 @@ test_expect_success 'lazy-fetch in submodule succeeds' ' git -C client restore --recurse-submodules --source=HEAD^ :/ ' +test_expect_success 'after fetching descendants of non-promisor commits, gc works' ' + # Setup + git init full && + git -C full config uploadpack.allowfilter 1 && + git -C full config uploadpack.allowanysha1inwant 1 && + touch full/foo && + git -C full add foo && + git -C full commit -m "commit 1" && + git -C full checkout --detach && + + # Partial clone and push commit to remote + git clone "file://$(pwd)/full" --filter=blob:none partial && + echo "hello" > partial/foo && + git -C partial commit -a -m "commit 2" && + git -C partial push && + + # gc in partial repo + git -C partial gc --prune=now && + + # Create another commit in normal repo + git -C full checkout main && + echo " world" >> full/foo && + git -C full commit -a -m "commit 3" && + + # Pull from remote in partial repo, and run gc again + git -C partial pull && + git -C partial gc --prune=now +' + + . "$TEST_DIRECTORY"/lib-httpd.sh start_httpd diff --git a/t/t7800-difftool.sh b/t/t7800-difftool.sh index cc917b257e..9b74db5563 100755 --- a/t/t7800-difftool.sh +++ b/t/t7800-difftool.sh @@ -665,6 +665,10 @@ run_dir_diff_test 'difftool --dir-diff syncs worktree without unstaged change' ' test_cmp expect file ' +run_dir_diff_test 'difftool --dir-diff with no diff' ' + git difftool -d main main +' + write_script modify-file <<\EOF echo "new content" >file EOF diff --git a/t/test-lib.sh b/t/test-lib.sh index 508b5fe1f5..426036b33a 100644 --- a/t/test-lib.sh +++ b/t/test-lib.sh @@ -577,53 +577,6 @@ case $GIT_TEST_FSYNC in ;; esac -# Add libc MALLOC and MALLOC_PERTURB test only if we are not executing -# the test with valgrind and have not compiled with conflict SANITIZE -# options. -if test -n "$valgrind" || - test -n "$SANITIZE_ADDRESS" || - test -n "$SANITIZE_LEAK" || - test -n "$TEST_NO_MALLOC_CHECK" -then - setup_malloc_check () { - : nothing - } - teardown_malloc_check () { - : nothing - } -else - _USE_GLIBC_TUNABLES= - if _GLIBC_VERSION=$(getconf GNU_LIBC_VERSION 2>/dev/null) && - _GLIBC_VERSION=${_GLIBC_VERSION#"glibc "} && - expr 2.34 \<= "$_GLIBC_VERSION" >/dev/null - then - _USE_GLIBC_TUNABLES=YesPlease - fi - setup_malloc_check () { - local g - local t - MALLOC_CHECK_=3 MALLOC_PERTURB_=165 - export MALLOC_CHECK_ MALLOC_PERTURB_ - if test -n "$_USE_GLIBC_TUNABLES" - then - g= - LD_PRELOAD="libc_malloc_debug.so.0" - for t in \ - glibc.malloc.check=1 \ - glibc.malloc.perturb=165 - do - g="${g#:}:$t" - done - GLIBC_TUNABLES=$g - export LD_PRELOAD GLIBC_TUNABLES - fi - } - teardown_malloc_check () { - unset MALLOC_CHECK_ MALLOC_PERTURB_ - unset LD_PRELOAD GLIBC_TUNABLES - } -fi - # Protect ourselves from common misconfiguration to export # CDPATH into the environment unset CDPATH @@ -1462,6 +1415,56 @@ GIT_ATTR_NOSYSTEM=1 GIT_CEILING_DIRECTORIES="$TRASH_DIRECTORY/.." export PATH GIT_EXEC_PATH GIT_TEMPLATE_DIR GIT_CONFIG_NOSYSTEM GIT_ATTR_NOSYSTEM GIT_CEILING_DIRECTORIES +# Add libc MALLOC and MALLOC_PERTURB test only if we are not executing +# the test with valgrind and have not compiled with conflict SANITIZE +# options. +if test -n "$valgrind" || + test -n "$SANITIZE_ADDRESS" || + test -n "$SANITIZE_LEAK" || + test -n "$TEST_NO_MALLOC_CHECK" +then + setup_malloc_check () { + : nothing + } + teardown_malloc_check () { + : nothing + } +else + _USE_GLIBC_TUNABLES= + _USE_GLIBC_PRELOAD=libc_malloc_debug.so.0 + if _GLIBC_VERSION=$(getconf GNU_LIBC_VERSION 2>/dev/null) && + _GLIBC_VERSION=${_GLIBC_VERSION#"glibc "} && + expr 2.34 \<= "$_GLIBC_VERSION" >/dev/null && + stderr=$(LD_PRELOAD=$_USE_GLIBC_PRELOAD git version 2>&1 >/dev/null) && + test -z "$stderr" + then + _USE_GLIBC_TUNABLES=YesPlease + fi + setup_malloc_check () { + local g + local t + MALLOC_CHECK_=3 MALLOC_PERTURB_=165 + export MALLOC_CHECK_ MALLOC_PERTURB_ + if test -n "$_USE_GLIBC_TUNABLES" + then + g= + LD_PRELOAD=$_USE_GLIBC_PRELOAD + for t in \ + glibc.malloc.check=1 \ + glibc.malloc.perturb=165 + do + g="${g#:}:$t" + done + GLIBC_TUNABLES=$g + export LD_PRELOAD GLIBC_TUNABLES + fi + } + teardown_malloc_check () { + unset MALLOC_CHECK_ MALLOC_PERTURB_ + unset LD_PRELOAD GLIBC_TUNABLES + } +fi + if test -z "$GIT_TEST_CMP" then if test -n "$GIT_TEST_CMP_USE_COPIED_CONTEXT" diff --git a/t/unit-tests/clar/.editorconfig b/t/unit-tests/clar/.editorconfig new file mode 100644 index 0000000000..aa343a4288 --- /dev/null +++ b/t/unit-tests/clar/.editorconfig @@ -0,0 +1,13 @@ +root = true + +[*] +charset = utf-8 +insert_final_newline = true + +[*.{c,h}] +indent_style = tab +tab_width = 8 + +[CMakeLists.txt] +indent_style = tab +tab_width = 8 diff --git a/t/unit-tests/clar/.github/workflows/ci.yml b/t/unit-tests/clar/.github/workflows/ci.yml index b1ac2de460..0065843d17 100644 --- a/t/unit-tests/clar/.github/workflows/ci.yml +++ b/t/unit-tests/clar/.github/workflows/ci.yml @@ -10,14 +10,26 @@ jobs: build: strategy: matrix: - os: [ ubuntu-latest, macos-latest ] + platform: + - os: ubuntu-latest + generator: Unix Makefiles + - os: macos-latest + generator: Unix Makefiles + - os: windows-latest + generator: Visual Studio 17 2022 + - os: windows-latest + generator: MSYS Makefiles + - os: windows-latest + generator: MinGW Makefiles - runs-on: ${{ matrix.os }} + runs-on: ${{ matrix.platform.os }} steps: - name: Check out uses: actions/checkout@v2 - name: Build run: | - cd test - make + mkdir build + cd build + cmake .. -G "${{matrix.platform.generator}}" + cmake --build . diff --git a/t/unit-tests/clar/.gitignore b/t/unit-tests/clar/.gitignore new file mode 100644 index 0000000000..84c048a73c --- /dev/null +++ b/t/unit-tests/clar/.gitignore @@ -0,0 +1 @@ +/build/ diff --git a/t/unit-tests/clar/CMakeLists.txt b/t/unit-tests/clar/CMakeLists.txt new file mode 100644 index 0000000000..12d4af114f --- /dev/null +++ b/t/unit-tests/clar/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 3.16..3.29) + +project(clar LANGUAGES C) + +option(BUILD_TESTS "Build test executable" ON) + +add_library(clar INTERFACE) +target_sources(clar INTERFACE + clar.c + clar.h + clar/fixtures.h + clar/fs.h + clar/print.h + clar/sandbox.h + clar/summary.h +) +set_target_properties(clar PROPERTIES + C_STANDARD 90 + C_STANDARD_REQUIRED ON + C_EXTENSIONS OFF +) + +if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME) + include(CTest) + if(BUILD_TESTING) + add_subdirectory(test) + endif() +endif() diff --git a/t/unit-tests/clar/clar.c b/t/unit-tests/clar/clar.c index cef0f023c2..d54e455367 100644 --- a/t/unit-tests/clar/clar.c +++ b/t/unit-tests/clar/clar.c @@ -4,7 +4,12 @@ * This file is part of clar, distributed under the ISC license. * For full terms see the included COPYING file. */ -#include <assert.h> + +#define _BSD_SOURCE +#define _DARWIN_C_SOURCE +#define _DEFAULT_SOURCE + +#include <errno.h> #include <setjmp.h> #include <stdlib.h> #include <stdio.h> @@ -13,11 +18,22 @@ #include <stdarg.h> #include <wchar.h> #include <time.h> +#include <inttypes.h> /* required for sandboxing */ #include <sys/types.h> #include <sys/stat.h> +#if defined(__UCLIBC__) && ! defined(__UCLIBC_HAS_WCHAR__) + /* + * uClibc can optionally be built without wchar support, in which case + * the installed <wchar.h> is a stub that only defines the `whar_t` + * type but none of the functions typically declared by it. + */ +#else +# define CLAR_HAVE_WCHAR +#endif + #ifdef _WIN32 # define WIN32_LEAN_AND_MEAN # include <windows.h> @@ -28,6 +44,9 @@ # ifndef stat # define stat(path, st) _stat(path, st) + typedef struct _stat STAT_T; +# else + typedef struct stat STAT_T; # endif # ifndef mkdir # define mkdir(path, mode) _mkdir(path) @@ -60,30 +79,11 @@ # else # define p_snprintf snprintf # endif - -# ifndef PRIuZ -# define PRIuZ "Iu" -# endif -# ifndef PRIxZ -# define PRIxZ "Ix" -# endif - -# if defined(_MSC_VER) || (defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR)) - typedef struct stat STAT_T; -# else - typedef struct _stat STAT_T; -# endif #else # include <sys/wait.h> /* waitpid(2) */ # include <unistd.h> # define _MAIN_CC # define p_snprintf snprintf -# ifndef PRIuZ -# define PRIuZ "zu" -# endif -# ifndef PRIxZ -# define PRIxZ "zx" -# endif typedef struct stat STAT_T; #endif @@ -102,7 +102,7 @@ fixture_path(const char *base, const char *fixture_name); struct clar_error { const char *file; const char *function; - size_t line_number; + uintmax_t line_number; const char *error_msg; char *description; @@ -195,11 +195,12 @@ static void clar_print_shutdown(int test_count, int suite_count, int error_count static void clar_print_error(int num, const struct clar_report *report, const struct clar_error *error); static void clar_print_ontest(const char *suite_name, const char *test_name, int test_number, enum cl_test_status failed); static void clar_print_onsuite(const char *suite_name, int suite_index); +static void clar_print_onabortv(const char *msg, va_list argp); static void clar_print_onabort(const char *msg, ...); /* From clar_sandbox.c */ static void clar_unsandbox(void); -static int clar_sandbox(void); +static void clar_sandbox(void); /* From summary.h */ static struct clar_summary *clar_summary_init(const char *filename); @@ -218,6 +219,15 @@ static int clar_summary_shutdown(struct clar_summary *fp); _clar.trace_payload); \ } while (0) +static void clar_abort(const char *msg, ...) +{ + va_list argp; + va_start(argp, msg); + clar_print_onabortv(msg, argp); + va_end(argp); + exit(-1); +} + void cl_trace_register(cl_trace_cb *cb, void *payload) { _clar.pfn_trace_cb = cb; @@ -271,9 +281,7 @@ static double clar_time_diff(clar_time *start, clar_time *end) static void clar_time_now(clar_time *out) { - struct timezone tz; - - gettimeofday(out, &tz); + gettimeofday(out, NULL); } static double clar_time_diff(clar_time *start, clar_time *end) @@ -386,7 +394,8 @@ clar_run_suite(const struct clar_suite *suite, const char *filter) _clar.active_test = test[i].name; - report = calloc(1, sizeof(struct clar_report)); + if ((report = calloc(1, sizeof(*report))) == NULL) + clar_abort("Failed to allocate report.\n"); report->suite = _clar.active_suite; report->test = _clar.active_test; report->test_number = _clar.tests_ran; @@ -479,9 +488,10 @@ clar_parse_args(int argc, char **argv) switch (action) { case 's': { - struct clar_explicit *explicit = - calloc(1, sizeof(struct clar_explicit)); - assert(explicit); + struct clar_explicit *explicit; + + if ((explicit = calloc(1, sizeof(*explicit))) == NULL) + clar_abort("Failed to allocate explicit test.\n"); explicit->suite_idx = j; explicit->filter = argument; @@ -505,10 +515,8 @@ clar_parse_args(int argc, char **argv) } } - if (!found) { - clar_print_onabort("No suite matching '%s' found.\n", argument); - exit(-1); - } + if (!found) + clar_abort("No suite matching '%s' found.\n", argument); break; } @@ -540,11 +548,17 @@ clar_parse_args(int argc, char **argv) case 'r': _clar.write_summary = 1; free(_clar.summary_filename); - _clar.summary_filename = *(argument + 2) ? strdup(argument + 2) : NULL; + if (*(argument + 2)) { + if ((_clar.summary_filename = strdup(argument + 2)) == NULL) + clar_abort("Failed to allocate summary filename.\n"); + } else { + _clar.summary_filename = NULL; + } break; default: - assert(!"Unexpected commandline argument!"); + clar_abort("Unexpected commandline argument '%s'.\n", + argument[1]); } } } @@ -566,22 +580,18 @@ clar_test_init(int argc, char **argv) if (!_clar.summary_filename && (summary_env = getenv("CLAR_SUMMARY")) != NULL) { _clar.write_summary = 1; - _clar.summary_filename = strdup(summary_env); + if ((_clar.summary_filename = strdup(summary_env)) == NULL) + clar_abort("Failed to allocate summary filename.\n"); } if (_clar.write_summary && !_clar.summary_filename) - _clar.summary_filename = strdup("summary.xml"); + if ((_clar.summary_filename = strdup("summary.xml")) == NULL) + clar_abort("Failed to allocate summary filename.\n"); - if (_clar.write_summary && - !(_clar.summary = clar_summary_init(_clar.summary_filename))) { - clar_print_onabort("Failed to open the summary file\n"); - exit(-1); - } + if (_clar.write_summary) + _clar.summary = clar_summary_init(_clar.summary_filename); - if (clar_sandbox() < 0) { - clar_print_onabort("Failed to sandbox the test runner.\n"); - exit(-1); - } + clar_sandbox(); } int @@ -615,10 +625,9 @@ clar_test_shutdown(void) clar_unsandbox(); - if (_clar.write_summary && clar_summary_shutdown(_clar.summary) < 0) { - clar_print_onabort("Failed to write the summary file\n"); - exit(-1); - } + if (_clar.write_summary && clar_summary_shutdown(_clar.summary) < 0) + clar_abort("Failed to write the summary file '%s: %s.\n", + _clar.summary_filename, strerror(errno)); for (explicit = _clar.explicit; explicit; explicit = explicit_next) { explicit_next = explicit->next; @@ -649,7 +658,7 @@ static void abort_test(void) { if (!_clar.trampoline_enabled) { clar_print_onabort( - "Fatal error: a cleanup method raised an exception."); + "Fatal error: a cleanup method raised an exception.\n"); clar_report_errors(_clar.last_report); exit(-1); } @@ -673,7 +682,10 @@ void clar__fail( const char *description, int should_abort) { - struct clar_error *error = calloc(1, sizeof(struct clar_error)); + struct clar_error *error; + + if ((error = calloc(1, sizeof(*error))) == NULL) + clar_abort("Failed to allocate error.\n"); if (_clar.last_report->errors == NULL) _clar.last_report->errors = error; @@ -688,8 +700,9 @@ void clar__fail( error->line_number = line; error->error_msg = error_msg; - if (description != NULL) - error->description = strdup(description); + if (description != NULL && + (error->description = strdup(description)) == NULL) + clar_abort("Failed to allocate description.\n"); _clar.total_errors++; _clar.last_report->status = CL_TEST_FAILURE; @@ -763,6 +776,7 @@ void clar__assert_equal( } } } +#ifdef CLAR_HAVE_WCHAR else if (!strcmp("%ls", fmt)) { const wchar_t *wcs1 = va_arg(args, const wchar_t *); const wchar_t *wcs2 = va_arg(args, const wchar_t *); @@ -798,8 +812,9 @@ void clar__assert_equal( } } } - else if (!strcmp("%"PRIuZ, fmt) || !strcmp("%"PRIxZ, fmt)) { - size_t sz1 = va_arg(args, size_t), sz2 = va_arg(args, size_t); +#endif /* CLAR_HAVE_WCHAR */ + else if (!strcmp("%"PRIuMAX, fmt) || !strcmp("%"PRIxMAX, fmt)) { + uintmax_t sz1 = va_arg(args, uintmax_t), sz2 = va_arg(args, uintmax_t); is_equal = (sz1 == sz2); if (!is_equal) { int offset = p_snprintf(buf, sizeof(buf), fmt, sz1); diff --git a/t/unit-tests/clar/clar/print.h b/t/unit-tests/clar/clar/print.h index c17e2f693b..69d0ee967e 100644 --- a/t/unit-tests/clar/clar/print.h +++ b/t/unit-tests/clar/clar/print.h @@ -21,7 +21,7 @@ static void clar_print_clap_error(int num, const struct clar_report *report, con { printf(" %d) Failure:\n", num); - printf("%s::%s [%s:%"PRIuZ"]\n", + printf("%s::%s [%s:%"PRIuMAX"]\n", report->suite, report->test, error->file, @@ -136,7 +136,7 @@ static void clar_print_tap_ontest(const char *suite_name, const char *test_name, printf(" at:\n"); printf(" file: '"); print_escaped(error->file); printf("'\n"); - printf(" line: %" PRIuZ "\n", error->line_number); + printf(" line: %" PRIuMAX "\n", error->line_number); printf(" function: '%s'\n", error->function); printf(" ---\n"); @@ -202,10 +202,15 @@ static void clar_print_onsuite(const char *suite_name, int suite_index) PRINT(onsuite, suite_name, suite_index); } +static void clar_print_onabortv(const char *msg, va_list argp) +{ + PRINT(onabort, msg, argp); +} + static void clar_print_onabort(const char *msg, ...) { va_list argp; va_start(argp, msg); - PRINT(onabort, msg, argp); + clar_print_onabortv(msg, argp); va_end(argp); } diff --git a/t/unit-tests/clar/clar/sandbox.h b/t/unit-tests/clar/clar/sandbox.h index e25057b7c4..bc960f50e0 100644 --- a/t/unit-tests/clar/clar/sandbox.h +++ b/t/unit-tests/clar/clar/sandbox.h @@ -122,14 +122,14 @@ static int build_sandbox_path(void) if (mkdir(_clar_path, 0700) != 0) return -1; -#elif defined(__TANDEM) - if (mktemp(_clar_path) == NULL) +#elif defined(_WIN32) + if (_mktemp_s(_clar_path, sizeof(_clar_path)) != 0) return -1; if (mkdir(_clar_path, 0700) != 0) return -1; -#elif defined(_WIN32) - if (_mktemp_s(_clar_path, sizeof(_clar_path)) != 0) +#elif defined(__sun) || defined(__TANDEM) + if (mktemp(_clar_path) == NULL) return -1; if (mkdir(_clar_path, 0700) != 0) @@ -142,15 +142,14 @@ static int build_sandbox_path(void) return 0; } -static int clar_sandbox(void) +static void clar_sandbox(void) { if (_clar_path[0] == '\0' && build_sandbox_path() < 0) - return -1; + clar_abort("Failed to build sandbox path.\n"); if (chdir(_clar_path) != 0) - return -1; - - return 0; + clar_abort("Failed to change into sandbox directory '%s': %s.\n", + _clar_path, strerror(errno)); } const char *clar_sandbox_path(void) diff --git a/t/unit-tests/clar/clar/summary.h b/t/unit-tests/clar/clar/summary.h index 4dd352e28b..0d0b646fe7 100644 --- a/t/unit-tests/clar/clar/summary.h +++ b/t/unit-tests/clar/clar/summary.h @@ -66,16 +66,12 @@ struct clar_summary *clar_summary_init(const char *filename) struct clar_summary *summary; FILE *fp; - if ((fp = fopen(filename, "w")) == NULL) { - perror("fopen"); - return NULL; - } + if ((fp = fopen(filename, "w")) == NULL) + clar_abort("Failed to open the summary file '%s': %s.\n", + filename, strerror(errno)); - if ((summary = malloc(sizeof(struct clar_summary))) == NULL) { - perror("malloc"); - fclose(fp); - return NULL; - } + if ((summary = malloc(sizeof(struct clar_summary))) == NULL) + clar_abort("Failed to allocate summary.\n"); summary->filename = filename; summary->fp = fp; diff --git a/t/unit-tests/clar/test/.gitignore b/t/unit-tests/clar/test/.gitignore deleted file mode 100644 index a477d0c40c..0000000000 --- a/t/unit-tests/clar/test/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -clar.suite -.clarcache -clar_test -*.o diff --git a/t/unit-tests/clar/test/CMakeLists.txt b/t/unit-tests/clar/test/CMakeLists.txt new file mode 100644 index 0000000000..7f2c1dc17a --- /dev/null +++ b/t/unit-tests/clar/test/CMakeLists.txt @@ -0,0 +1,39 @@ +find_package(Python COMPONENTS Interpreter REQUIRED) + +add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/clar.suite" + COMMAND "${Python_EXECUTABLE}" "${CMAKE_SOURCE_DIR}/generate.py" --output "${CMAKE_CURRENT_BINARY_DIR}" + DEPENDS main.c sample.c clar_test.h + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" +) + +add_executable(clar_test) +set_target_properties(clar_test PROPERTIES + C_STANDARD 90 + C_STANDARD_REQUIRED ON + C_EXTENSIONS OFF +) + +# MSVC generates all kinds of warnings. We may want to fix these in the future +# and then unconditionally treat warnings as errors. +if(NOT MSVC) + set_target_properties(clar_test PROPERTIES + COMPILE_WARNING_AS_ERROR ON + ) +endif() + +target_sources(clar_test PRIVATE + main.c + sample.c + "${CMAKE_CURRENT_BINARY_DIR}/clar.suite" +) +target_compile_definitions(clar_test PRIVATE + CLAR_FIXTURE_PATH="${CMAKE_CURRENT_SOURCE_DIR}/resources/" +) +target_compile_options(clar_test PRIVATE + $<IF:$<CXX_COMPILER_ID:MSVC>,/W4,-Wall> +) +target_include_directories(clar_test PRIVATE + "${CMAKE_SOURCE_DIR}" + "${CMAKE_CURRENT_BINARY_DIR}" +) +target_link_libraries(clar_test clar) diff --git a/t/unit-tests/clar/test/Makefile b/t/unit-tests/clar/test/Makefile deleted file mode 100644 index 93c6b2ad32..0000000000 --- a/t/unit-tests/clar/test/Makefile +++ /dev/null @@ -1,39 +0,0 @@ -# -# Copyright (c) Vicent Marti. All rights reserved. -# -# This file is part of clar, distributed under the ISC license. -# For full terms see the included COPYING file. -# - -# -# Set up the path to the clar sources and to the fixtures directory -# -# The fixture path needs to be an absolute path so it can be used -# even after we have chdir'ed into the test directory while testing. -# -CURRENT_MAKEFILE := $(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST)) -TEST_DIRECTORY := $(abspath $(dir $(CURRENT_MAKEFILE))) -CLAR_PATH := $(dir $(TEST_DIRECTORY)) -CLAR_FIXTURE_PATH := $(TEST_DIRECTORY)/resources/ - -CFLAGS=-g -I.. -I. -Wall -DCLAR_FIXTURE_PATH=\"$(CLAR_FIXTURE_PATH)\" - -.PHONY: clean - -# list the objects that go into our test -objects = main.o sample.o - -# build the test executable itself -clar_test: $(objects) clar_test.h clar.suite $(CLAR_PATH)clar.c - $(CC) $(CFLAGS) -o $@ "$(CLAR_PATH)clar.c" $(objects) - -# test object files depend on clar macros -$(objects) : $(CLAR_PATH)clar.h - -# build the clar.suite file of test metadata -clar.suite: - python "$(CLAR_PATH)generate.py" . - -# remove all generated files -clean: - $(RM) -rf *.o clar.suite .clarcache clar_test clar_test.dSYM diff --git a/t/unit-tests/generate-clar-decls.sh b/t/unit-tests/generate-clar-decls.sh new file mode 100755 index 0000000000..688e0885f4 --- /dev/null +++ b/t/unit-tests/generate-clar-decls.sh @@ -0,0 +1,16 @@ +#!/bin/sh + +if test $# -lt 2 +then + echo "USAGE: $0 <OUTPUT> <SUITE>..." 2>&1 + exit 1 +fi + +OUTPUT="$1" +shift + +for suite in "$@" +do + sed -ne "s/^\(void test_$(basename "${suite%.c}")__[a-zA-Z_0-9][a-zA-Z_0-9]*(void)\)$/extern \1;/p" "$suite" || + exit 1 +done >"$OUTPUT" |
