Diff options
| -rwxr-xr-x | tests/t0110-snapshot.sh | 266 |
1 file changed, 197 insertions, 69 deletions
diff --git a/tests/t0110-snapshot.sh b/tests/t0110-snapshot.sh index 2078a71..125cb7f 100755 --- a/tests/t0110-snapshot.sh +++ b/tests/t0110-snapshot.sh @@ -4,7 +4,9 @@ # byte for byte to the archive git itself writes, once decompressed where cgit # pipes through a compressor, and each compressed format needs the same tool # on the server and here, so one missing tool skips that format on both -# grounds at once. The tags after them check how a snapshot is named. +# grounds at once. The rest covers how a snapshot is named and found again from +# its name, with a repository of its own for each set of refs, and the +# requests that are refused. test_description='Verify snapshot' . ./setup.sh @@ -86,51 +88,181 @@ test_expect_success UNZIP 'a zip snapshot unzips' ' check_snapshot_content ' -# A tag named v1.0 sheds its v in the snapshot name unless dropping it would -# merge two tags. The first tag below stays a loose ref on purpose, because on -# a case-insensitive filesystem a ref lookup for V1.0 finds the loose v1.0 -# file, and deciding by lookups called every fresh tag ambiguous and kept its -# v until git happened to pack the refs. -test_expect_success 'set up a repo with a versioned tag' ' +# The tags sit on the older commit, so a name that led to master instead +# would bring file-2 with it. On a case-insensitive filesystem a ref lookup +# for one case finds a loose file of the other. v1.0 stays loose on purpose, +# because deciding by lookups called every fresh tag ambiguous and kept its v +# until git happened to pack the refs. The rest are packed, so that a lookup +# for v2.0 cannot find V2.0. Reftable keeps no file per ref, so v1.0 is +# looked for as a file only under the files backend. +test_expect_success 'set up a repo with tags of every shape' ' mkrepo repos/vtags 2 && - git -C repos/vtags update-ref refs/tags/v1.0 HEAD && - cgitrc_repo vtagsrc vtags snapshots=tar.gz + git -C repos/vtags update-ref refs/tags/V2.0 HEAD~1 && + git -C repos/vtags update-ref refs/tags/vtags-3.0 HEAD~1 && + git -C repos/vtags update-ref refs/tags/release/2.0 HEAD~1 && + git -C repos/vtags update-ref refs/heads/topic/x HEAD~1 && + git -C repos/vtags pack-refs --all && + git -C repos/vtags update-ref refs/tags/v1.0 HEAD~1 && + { + ! test_have_prereq REFFILES || + test_path_is_file repos/vtags/.git/refs/tags/v1.0 + } && + cgitrc_repo vtagsrc vtags snapshots=tar +' + +# A tag named v1.0 sheds its v in the snapshot name unless dropping it would +# merge two tags, and the name still leads back to the tag. +test_expect_success 'a loose v tag sheds its v and the name leads back to it' ' + cgit_ok vtagsrc "url=vtags/refs/" >tmp && + grep "<a href=./vtags/snapshot/vtags-1.0.tar.>vtags-1.0.tar</a>" tmp && + ! grep "vtags-v1.0.tar" tmp && + cgit_ok vtagsrc "url=vtags/snapshot/vtags-1.0.tar" >tmp && + snapshot_members && + grep "^vtags-1.0/file-1$" members && + ! grep "file-2" members +' + +test_expect_success 'an underscore after the prefix leads back to the tag too' ' + cgit_ok vtagsrc "url=vtags/snapshot/vtags_1.0.tar" >tmp && + snapshot_members && + grep "^vtags_1.0/file-1$" members && + ! grep "file-2" members +' + +test_expect_success 'a V tag sheds its V and the name leads back to it' ' + cgit_ok vtagsrc "url=vtags/refs/" >tmp && + grep "<a href=./vtags/snapshot/vtags-2.0.tar.>vtags-2.0.tar</a>" tmp && + cgit_ok vtagsrc "url=vtags/snapshot/vtags-2.0.tar" >tmp && + snapshot_members && + grep "^vtags-2.0/file-1$" members && + ! grep "file-2" members +' + +test_expect_success 'a tag that starts with the prefix is not prefixed again' ' + cgit_ok vtagsrc "url=vtags/refs/" >tmp && + grep "<a href=./vtags/snapshot/vtags-3.0.tar.>vtags-3.0.tar</a>" tmp && + ! grep "vtags-vtags-3.0" tmp && + cgit_ok vtagsrc "url=vtags/snapshot/vtags-3.0.tar" >tmp && + snapshot_members && + grep "^vtags-3.0/file-1$" members && + ! grep "file-2" members +' + +test_expect_success 'a snapshot-prefix names the snapshots in its place' ' + cgitrc_repo prefixrc vtags snapshots=tar repo.snapshot-prefix=proj && + cgit_ok prefixrc "url=vtags/refs/" >tmp && + grep "<a href=./vtags/snapshot/proj-1.0.tar.>proj-1.0.tar</a>" tmp && + cgit_ok prefixrc "url=vtags/snapshot/proj-1.0.tar" >tmp && + snapshot_members && + grep "^proj-1.0/file-1$" members && + ! grep "file-2" members +' + +test_expect_success 'snapshots=all offers every format' ' + cgitrc_repo allrc vtags snapshots=all && + cgit_ok allrc "url=vtags/refs/" >tmp && + for suffix in tar tar.gz tar.bz2 tar.lz tar.xz tar.zst zip + do + grep ">vtags-1.0.$suffix</a>" tmp || return 1 + done +' + +# A snapshot name is never worked back to a ref holding a slash, so such a +# ref is offered under a dashed name and passed along with it, even from a +# page whose own head is that ref. The dashed name is no ref, so the archive +# unpacks into the repository's own prefix. +test_expect_success 'a ref with a slash is linked under a dashed name' ' + cgit_ok vtagsrc "url=vtags/refs/" >tmp && + grep "<a href=./vtags/snapshot/vtags-release-2.0.tar?id=release/2.0.>vtags-release-2.0.tar</a>" tmp && + cgit_ok vtagsrc "url=vtags/commit/&h=topic/x" >tmp && + grep "<a href=./vtags/snapshot/vtags-topic-x.tar?id=topic/x.>vtags-topic-x.tar</a>" tmp +' + +test_expect_success 'the dashed name serves the ref under the repository prefix' ' + cgit_ok vtagsrc "url=vtags/snapshot/vtags-release-2.0.tar&id=release/2.0" >tmp && + snapshot_members && + commit=$(git -C repos/vtags get-tar-commit-id <snapshot.tar) && + want=$(git -C repos/vtags rev-parse "release/2.0^{commit}") && + test -n "$want" && + test "$commit" = "$want" && + grep "^vtags/file-1$" members && + ! grep "^vtags-release" members +' + +test_expect_success 'a format the repository does not offer is refused' ' + cgit_rc vtagsrc "url=vtags/snapshot/vtags-1.0.zip" >tmp && + grep "^Status: 400" tmp && + grep "<div class=.error.>Unsupported snapshot format: vtags-1.0.zip</div>" tmp && + cgit_rc vtagsrc "url=vtags/snapshot/vtags-1.0.tar.xz" >tmp && + grep "^Status: 400" tmp && + grep "<div class=.error.>Unsupported snapshot format: vtags-1.0.tar.xz</div>" tmp ' -test_expect_success 'a loose v tag still sheds its v in the snapshot name' ' - cgit_rc vtagsrc "url=vtags/refs/" >tmp && - grep "vtags-1.0.tar.gz" tmp && - ! grep "vtags-v1.0.tar.gz" tmp +test_expect_success 'a request naming no snapshot is refused' ' + cgit_rc vtagsrc "url=vtags/snapshot/" >tmp && + grep "^Status: 400" tmp && + grep "<div class=.error.>No snapshot name specified</div>" tmp +' + +test_expect_success 'an id naming no commit is refused' ' + cgit_rc vtagsrc "url=vtags/snapshot/vtags.tar&id=nosuchref" >tmp && + grep "^Status: 404" tmp && + grep "<div class=.error.>Bad object id: nosuchref</div>" tmp +' + +# Two tags differing only in the case of their v keep it on both names. Two +# loose files differing in case alone cannot coexist on a case-insensitive +# filesystem, so the first is packed before the second goes in, and both are +# packed after, so that each name is looked up exactly. +test_expect_success 'set up a repo whose tags differ only in case' ' + mkrepo repos/vcase 2 && + git -C repos/vcase update-ref refs/tags/v1.0 HEAD && + git -C repos/vcase pack-refs --all && + git -C repos/vcase update-ref refs/tags/V1.0 HEAD~1 && + git -C repos/vcase pack-refs --all && + cgitrc_repo vcaserc vcase snapshots=tar ' -# The second tag goes in only after the first is packed, since two loose files -# differing in case alone cannot coexist on a case-insensitive filesystem. test_expect_success 'a real case collision keeps the v on both tags' ' - git -C repos/vtags pack-refs --all && - git -C repos/vtags update-ref refs/tags/V1.0 HEAD~1 && - cgit_rc vtagsrc "url=vtags/refs/" >tmp && - grep "vtags-v1.0.tar.gz" tmp && - grep "vtags-V1.0.tar.gz" tmp && - ! grep "vtags-1.0.tar.gz" tmp + cgit_ok vcaserc "url=vcase/refs/" >tmp && + grep ">vcase-v1.0.tar</a>" tmp && + grep ">vcase-V1.0.tar</a>" tmp && + ! grep ">vcase-1.0.tar</a>" tmp +' + +test_expect_success 'each of those names leads back to its own tag' ' + cgit_ok vcaserc "url=vcase/snapshot/vcase-v1.0.tar" >tmp && + snapshot_members && + grep "^vcase-v1.0/file-2$" members && + cgit_ok vcaserc "url=vcase/snapshot/vcase-V1.0.tar" >tmp && + snapshot_members && + grep "^vcase-V1.0/file-1$" members && + ! grep "file-2" members +' + +# A name that is all suffix names no revision, though the lookup would settle +# on the branch called v that the full name finds. +test_expect_success 'set up a repo with a branch named v' ' + mkrepo repos/stem 1 && + git -C repos/stem branch v HEAD && + cgitrc_repo stemrc stem snapshots=tar ' -# A name that is all suffix names no revision, and an empty snapshot-prefix -# gives the members no leading directory rather than a leading slash. test_expect_success 'a snapshot name with nothing before its suffix is refused' ' - git -C repos/vtags branch v HEAD && - sed "s/^snapshots=tar.gz$/snapshots=tar/" vtagsrc >vtagstarrc && - cgit_rc vtagstarrc "url=vtags/snapshot/.tar" >tmp && - grep "^Status: 404" tmp + cgit_rc stemrc "url=stem/snapshot/.tar" >tmp && + grep "^Status: 404" tmp && + grep "<div class=.error.>Not found</div>" tmp && + cgit_ok stemrc "url=stem/snapshot/stem-v.tar" >tmp && + snapshot_members && + grep "^stem-v/file-1$" members ' +# An empty snapshot-prefix gives the members no leading directory rather than +# a leading slash. test_expect_success 'an empty snapshot-prefix puts no slash ahead of the members' ' - { - cat vtagstarrc && - echo "repo.snapshot-prefix=" - } >noprefixrc && - cgit_rc noprefixrc "url=vtags/snapshot/vtags.tar&id=master" >tmp && - strip_headers <tmp >noprefix.tar && - tar -tf noprefix.tar >members && + cgitrc_repo noprefixrc stem snapshots=tar repo.snapshot-prefix= && + cgit_ok noprefixrc "url=stem/snapshot/stem.tar&id=master" >tmp && + snapshot_members && grep "^file-1$" members && ! grep "^/" members ' @@ -152,40 +284,55 @@ test_expect_success 'set up repositories whose urls end in .git' ' ' test_expect_success 'a url of .git names a snapshot after the ref alone' ' - cgit_rc dotgitrc "url=.git/refs/" >tmp && + cgit_ok dotgitrc "url=.git/refs/" >tmp && grep ">v1.0.tar<" tmp && - cgit_rc dotgitrc "url=.git/snapshot/v1.0.tar" >tmp && - strip_headers <tmp >dotgit.tar && - tar -tf dotgit.tar >members && + cgit_ok dotgitrc "url=.git/snapshot/v1.0.tar" >tmp && + snapshot_members && grep "^v1.0/file-1$" members ' test_expect_success 'a url ending in /.git names a snapshot after its directory' ' - cgit_rc dotgitrc "url=sub/.git/refs/" >tmp && - grep ">sub-1.0.tar<" tmp + cgit_ok dotgitrc "url=sub/.git/refs/" >tmp && + grep ">sub-1.0.tar<" tmp && + cgit_ok dotgitrc "url=sub/.git/snapshot/sub-1.0.tar" >tmp && + snapshot_members && + grep "^sub-1.0/file-1$" members ' +test -n "$CGIT_VALGRIND" || test_set_prereq NO_VALGRIND + # A server may run cgit with no PATH at all, and the compressor is then looked -# for on the default path execvp searches. -test_expect_success GZIP 'a compressed snapshot is made without a PATH' ' +# for on the default path execvp searches. Under valgrind the cgit found here +# is a wrapper script, which needs a PATH of its own. +test_expect_success GZIP,NO_VALGRIND 'a compressed snapshot is made without a PATH' ' cgitrc_copy nopathrc && cgit_bin=$(command -v cgit) && ( unset PATH && - CGIT_CONFIG="$PWD/nopathrc" QUERY_STRING="url=foo/snapshot/master.tar.gz" "$cgit_bin" >tmp + CGIT_CONFIG="$PWD/nopathrc" QUERY_STRING="url=foo/snapshot/master.tar.gz" "$cgit_bin" >tmp 2>err ) && + test_must_be_empty err && grep "^Status: 200" tmp && strip_headers <tmp >nopath.tar.gz && - gzip -t nopath.tar.gz + gzip -dc nopath.tar.gz >nopath.tar && + test_cmp_bin expect.tar nopath.tar ' # A link offers the snapshot of a tag, and the name on it has to lead back to -# that tag even when a branch is spelled like the tag's stem. -test_expect_success GZIP 'a snapshot name leads to the tag ahead of a branch' ' - git -C repos/vtags update-ref refs/heads/1.0 $(git -C repos/vtags commit-tree -m shadow HEAD^{tree}) && - cgit_rc vtagsrc "url=vtags/snapshot/vtags-1.0.tar.gz" >tmp && - strip_headers <tmp >tag.tar.gz && - test "$(gzip -dc tag.tar.gz | git -C repos/vtags get-tar-commit-id)" = "$(git -C repos/vtags rev-parse refs/tags/v1.0^{commit})" +# that tag even when a branch is spelled like the tag's stem. The branch holds +# the same tree, so only the commit the archive records tells them apart. +test_expect_success 'a snapshot name leads to the tag ahead of a branch' ' + mkrepo repos/shadow 1 && + git -C repos/shadow tag v1.0 && + shadow=$(git -C repos/shadow commit-tree -m shadow "HEAD^{tree}") && + git -C repos/shadow update-ref refs/heads/1.0 "$shadow" && + cgitrc_repo shadowrc shadow snapshots=tar && + cgit_ok shadowrc "url=shadow/snapshot/shadow-1.0.tar" >tmp && + strip_headers <tmp >tag.tar && + commit=$(git -C repos/shadow get-tar-commit-id <tag.tar) && + want=$(git -C repos/shadow rev-parse "v1.0^{commit}") && + test -n "$want" && + test "$commit" = "$want" ' # A signature is a note a pusher stored, held to max-blob-size like any blob. @@ -216,23 +363,4 @@ test_expect_success 'a snapshot and its signature are linked as one unit' ' grep "<span class=.snapshot.><a href=./signed/snapshot/signed-one.tar.gz.>signed-one.tar.gz</a> (<a href=./signed/snapshot/signed-one.tar.gz.asc.>sig</a>)</span>" tmp ' -# A snapshot name is never worked back to a ref holding a slash, so such a -# ref is offered under a dashed name and passed along with it, even from a -# page whose own head is that ref. -test_expect_success 'a ref with a slash is linked under a dashed name' ' - git -C repos/vtags tag release/2.0 HEAD && - git -C repos/vtags branch topic/x HEAD && - cgit_rc vtagsrc "url=vtags/refs/" >tmp && - grep "<a href=./vtags/snapshot/vtags-release-2.0.tar.gz?id=release/2.0.>vtags-release-2.0.tar.gz</a>" tmp && - cgit_rc vtagsrc "url=vtags/commit/&h=topic/x" >tmp && - grep "<a href=./vtags/snapshot/vtags-topic-x.tar.gz?id=topic/x.>vtags-topic-x.tar.gz</a>" tmp -' - -test_expect_success GZIP 'the dashed name serves the ref' ' - cgit_rc vtagsrc "url=vtags/snapshot/vtags-release-2.0.tar.gz&id=release/2.0" >tmp && - grep "^Status: 200" tmp && - strip_headers <tmp >slash.tar.gz && - test "$(gzip -dc slash.tar.gz | git -C repos/vtags get-tar-commit-id)" = "$(git -C repos/vtags rev-parse release/2.0^{commit})" -' - test_done |
