Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitaly.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Steinhardt <psteinhardt@gitlab.com>2023-08-22 14:57:42 +0300
committerPatrick Steinhardt <psteinhardt@gitlab.com>2023-08-22 14:57:42 +0300
commit1b371cce53288b28e360da0c869460b0b56eead1 (patch)
treef8142eb81cdc5188cc4de8ad2cda4ef70f3cd7d6
parentc43d2945b2ae269e1661f41c12523648b4993a23 (diff)
parent45ee171ed5b08c707cb219deb8d6b1b7e3e2f479 (diff)
Merge branch 'pks-find-commits-sha256' into 'master'
commit: Convert FindCommits tests to support SHA256 See merge request https://gitlab.com/gitlab-org/gitaly/-/merge_requests/6241 Merged-by: Patrick Steinhardt <psteinhardt@gitlab.com> Approved-by: karthik nayak <knayak@gitlab.com> Approved-by: Will Chandler <wchandler@gitlab.com>
-rw-r--r--internal/gitaly/service/commit/find_commits_test.go1356
1 files changed, 570 insertions, 786 deletions
diff --git a/internal/gitaly/service/commit/find_commits_test.go b/internal/gitaly/service/commit/find_commits_test.go
index 8cbef97cf..0f68c6a87 100644
--- a/internal/gitaly/service/commit/find_commits_test.go
+++ b/internal/gitaly/service/commit/find_commits_test.go
@@ -1,5 +1,3 @@
-//go:build !gitaly_test_sha256
-
package commit
import (
@@ -8,447 +6,645 @@ import (
"io"
"path/filepath"
"testing"
+ "time"
- "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
+ "gitlab.com/gitlab-org/gitaly/v16/internal/git"
"gitlab.com/gitlab-org/gitaly/v16/internal/git/gittest"
+ "gitlab.com/gitlab-org/gitaly/v16/internal/git/localrepo"
"gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/storage"
"gitlab.com/gitlab-org/gitaly/v16/internal/structerr"
"gitlab.com/gitlab-org/gitaly/v16/internal/testhelper"
"gitlab.com/gitlab-org/gitaly/v16/proto/go/gitalypb"
+ "golang.org/x/text/encoding/charmap"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"google.golang.org/protobuf/types/known/timestamppb"
)
-func TestFindCommitsFields(t *testing.T) {
+func TestFindCommits(t *testing.T) {
t.Parallel()
- windows1251Message := testhelper.MustReadFile(t, "testdata/commit-c809470461118b7bcab850f6e9a7ca97ac42f8ea-message.txt")
ctx := testhelper.Context(t)
- _, repo, _, client := setupCommitServiceWithRepo(t, ctx)
+ cfg, client := setupCommitService(t, ctx)
+
+ writeCommit := func(t *testing.T, repoProto *gitalypb.Repository, opts ...gittest.WriteCommitOption) (git.ObjectID, *gitalypb.GitCommit) {
+ t.Helper()
+
+ repo := localrepo.NewTestRepo(t, cfg, repoProto)
+ repoPath, err := repo.Path()
+ require.NoError(t, err)
+
+ commitID := gittest.WriteCommit(t, cfg, repoPath, opts...)
+ commitProto, err := repo.ReadCommit(ctx, commitID.Revision())
+ require.NoError(t, err)
+
+ return commitID, commitProto
+ }
+
+ type setupData struct {
+ request *gitalypb.FindCommitsRequest
+ expectedErr error
+ expectedCommits []*gitalypb.GitCommit
+ }
- testCases := []struct {
- id string
- trailers bool
- commit *gitalypb.GitCommit
+ for _, tc := range []struct {
+ desc string
+ setup func(t *testing.T) setupData
}{
{
- id: "b83d6e391c22777fca1ed3012fce84f633d7fed0",
- commit: testhelper.GitLabTestCommit("b83d6e391c22777fca1ed3012fce84f633d7fed0"),
+ desc: "unset repository",
+ setup: func(t *testing.T) setupData {
+ return setupData{
+ request: &gitalypb.FindCommitsRequest{
+ Repository: nil,
+ },
+ expectedErr: structerr.NewInvalidArgument("%w", storage.ErrRepositoryNotSet),
+ }
+ },
},
{
- id: "c809470461118b7bcab850f6e9a7ca97ac42f8ea",
- commit: &gitalypb.GitCommit{
- Id: "c809470461118b7bcab850f6e9a7ca97ac42f8ea",
- Subject: windows1251Message[:len(windows1251Message)-1],
- Body: windows1251Message,
- Author: &gitalypb.CommitAuthor{
- Name: []byte("Jacob Vosmaer"),
- Email: []byte("jacob@gitlab.com"),
- Date: &timestamppb.Timestamp{Seconds: 1512132977},
- Timezone: []byte("+0100"),
- },
- Committer: &gitalypb.CommitAuthor{
- Name: []byte("Jacob Vosmaer"),
- Email: []byte("jacob@gitlab.com"),
- Date: &timestamppb.Timestamp{Seconds: 1512132977},
- Timezone: []byte("+0100"),
- },
- ParentIds: []string{"e63f41fe459e62e1228fcef60d7189127aeba95a"},
- BodySize: 49,
- TreeId: "86ec18bfe87ad42a782fdabd8310f9b7ac750f51",
- Encoding: "windows-1251",
+ desc: "paths with empty string",
+ setup: func(t *testing.T) setupData {
+ repo, _ := gittest.CreateRepository(t, ctx, cfg)
+
+ return setupData{
+ request: &gitalypb.FindCommitsRequest{
+ Repository: repo,
+ Paths: [][]byte{[]byte("")},
+ },
+ expectedErr: status.Error(codes.InvalidArgument, "path is empty string"),
+ }
},
},
{
- id: "0999bb770f8dc92ab5581cc0b474b3e31a96bf5c",
- commit: testhelper.GitLabTestCommit("0999bb770f8dc92ab5581cc0b474b3e31a96bf5c"),
+ desc: "invalid revision",
+ setup: func(t *testing.T) setupData {
+ repo, _ := gittest.CreateRepository(t, ctx, cfg)
+
+ return setupData{
+ request: &gitalypb.FindCommitsRequest{
+ Repository: repo,
+ Revision: []byte("--output=/meow"),
+ },
+ expectedErr: status.Error(codes.InvalidArgument, "revision can't start with '-'"),
+ }
+ },
},
+
{
- id: "77e835ef0856f33c4f0982f84d10bdb0567fe440",
- commit: testhelper.GitLabTestCommit("77e835ef0856f33c4f0982f84d10bdb0567fe440"),
+ desc: "plain commit",
+ setup: func(t *testing.T) setupData {
+ repo, _ := gittest.CreateRepository(t, ctx, cfg)
+ commitID, commit := writeCommit(t, repo)
+
+ return setupData{
+ request: &gitalypb.FindCommitsRequest{
+ Repository: repo,
+ Revision: []byte(commitID),
+ Limit: 1,
+ },
+ expectedCommits: []*gitalypb.GitCommit{commit},
+ }
+ },
},
{
- id: "189a6c924013fc3fe40d6f1ec1dc20214183bc97",
- commit: testhelper.GitLabTestCommit("189a6c924013fc3fe40d6f1ec1dc20214183bc97"),
+ desc: "encoded commit message",
+ setup: func(t *testing.T) setupData {
+ repo, _ := gittest.CreateRepository(t, ctx, cfg)
+
+ windows1250, err := charmap.Windows1250.NewEncoder().String("üöä")
+ require.NoError(t, err)
+
+ commitID, commit := writeCommit(t, repo, gittest.WithMessage(windows1250), gittest.WithEncoding("windows-1250"))
+ commit.Body = []byte(windows1250)
+ commit.Encoding = "windows-1250"
+
+ return setupData{
+ request: &gitalypb.FindCommitsRequest{
+ Repository: repo,
+ Revision: []byte(commitID),
+ Limit: 1,
+ },
+ expectedCommits: []*gitalypb.GitCommit{commit},
+ }
+ },
},
{
- id: "5937ac0a7beb003549fc5fd26fc247adbce4a52e",
- trailers: false,
- commit: &gitalypb.GitCommit{
- Id: "5937ac0a7beb003549fc5fd26fc247adbce4a52e",
- Subject: []byte("Add submodule from gitlab.com"),
- Body: []byte("Add submodule from gitlab.com\n\nSigned-off-by: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>\n"),
- Author: &gitalypb.CommitAuthor{
- Name: []byte("Dmitriy Zaporozhets"),
- Email: []byte("dmitriy.zaporozhets@gmail.com"),
- Date: &timestamppb.Timestamp{Seconds: 1393491698},
- Timezone: []byte("+0200"),
- },
- Committer: &gitalypb.CommitAuthor{
- Name: []byte("Dmitriy Zaporozhets"),
- Email: []byte("dmitriy.zaporozhets@gmail.com"),
- Date: &timestamppb.Timestamp{Seconds: 1393491698},
- Timezone: []byte("+0200"),
- },
- ParentIds: []string{"570e7b2abdd848b95f2f578043fc23bd6f6fd24d"},
- BodySize: 98,
- SignatureType: gitalypb.SignatureType_PGP,
- TreeId: "a6973545d42361b28bfba5ced3b75dba5848b955",
+ desc: "without commit trailers",
+ setup: func(t *testing.T) setupData {
+ repo, _ := gittest.CreateRepository(t, ctx, cfg)
+
+ commitID, commit := writeCommit(t, repo, gittest.WithMessage("message\n\nSigned-off-by: me\n"))
+ commit.Trailers = nil
+
+ return setupData{
+ request: &gitalypb.FindCommitsRequest{
+ Repository: repo,
+ Revision: []byte(commitID),
+ Trailers: false,
+ Limit: 1,
+ },
+ expectedCommits: []*gitalypb.GitCommit{commit},
+ }
},
},
{
- id: "5937ac0a7beb003549fc5fd26fc247adbce4a52e",
- trailers: true,
- commit: &gitalypb.GitCommit{
- Id: "5937ac0a7beb003549fc5fd26fc247adbce4a52e",
- Subject: []byte("Add submodule from gitlab.com"),
- Body: []byte("Add submodule from gitlab.com\n\nSigned-off-by: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>\n"),
- Author: &gitalypb.CommitAuthor{
- Name: []byte("Dmitriy Zaporozhets"),
- Email: []byte("dmitriy.zaporozhets@gmail.com"),
- Date: &timestamppb.Timestamp{Seconds: 1393491698},
- Timezone: []byte("+0200"),
- },
- Committer: &gitalypb.CommitAuthor{
- Name: []byte("Dmitriy Zaporozhets"),
- Email: []byte("dmitriy.zaporozhets@gmail.com"),
- Date: &timestamppb.Timestamp{Seconds: 1393491698},
- Timezone: []byte("+0200"),
- },
- ParentIds: []string{"570e7b2abdd848b95f2f578043fc23bd6f6fd24d"},
- BodySize: 98,
- SignatureType: gitalypb.SignatureType_PGP,
- TreeId: "a6973545d42361b28bfba5ced3b75dba5848b955",
- Trailers: []*gitalypb.CommitTrailer{
- {
- Key: []byte("Signed-off-by"),
- Value: []byte("Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>"),
+ desc: "with commit trailers",
+ setup: func(t *testing.T) setupData {
+ repo, _ := gittest.CreateRepository(t, ctx, cfg)
+
+ commitID, commit := writeCommit(t, repo, gittest.WithMessage("message\n\nSigned-off-by: me\n"))
+ commit.Trailers = []*gitalypb.CommitTrailer{
+ {Key: []byte("Signed-off-by"), Value: []byte("me")},
+ }
+
+ return setupData{
+ request: &gitalypb.FindCommitsRequest{
+ Repository: repo,
+ Revision: []byte(commitID),
+ Trailers: true,
+ Limit: 1,
},
- },
+ expectedCommits: []*gitalypb.GitCommit{commit},
+ }
},
},
{
- id: "c1c67abbaf91f624347bb3ae96eabe3a1b742478",
- commit: &gitalypb.GitCommit{
- Id: "c1c67abbaf91f624347bb3ae96eabe3a1b742478",
- Subject: []byte("Add file with a _flattable_ path"),
- Body: []byte("Add file with a _flattable_ path\n\n\n(cherry picked from commit ce369011c189f62c815f5971d096b26759bab0d1)"),
- Author: &gitalypb.CommitAuthor{
- Name: []byte("Alejandro Rodríguez"),
- Email: []byte("alejorro70@gmail.com"),
- Date: &timestamppb.Timestamp{Seconds: 1504382739},
- Timezone: []byte("+0000"),
- },
- Committer: &gitalypb.CommitAuthor{
- Name: []byte("Drew Blessing"),
- Email: []byte("drew@blessing.io"),
- Date: &timestamppb.Timestamp{Seconds: 1540823671},
- Timezone: []byte("+0000"),
- },
- ParentIds: []string{"7975be0116940bf2ad4321f79d02a55c5f7779aa"},
- BodySize: 103,
- TreeId: "07f8147e8e73aab6c935c296e8cdc5194dee729b",
+ desc: "by author",
+ setup: func(t *testing.T) setupData {
+ repo, _ := gittest.CreateRepository(t, ctx, cfg)
+
+ parentID, parent := writeCommit(t, repo, gittest.WithAuthorName("Some author"))
+ childID, _ := writeCommit(t, repo, gittest.WithParents(parentID))
+
+ return setupData{
+ request: &gitalypb.FindCommitsRequest{
+ Repository: repo,
+ Revision: []byte(childID),
+ Author: []byte("Some author"),
+ Limit: 9000,
+ },
+ expectedCommits: []*gitalypb.GitCommit{parent},
+ }
},
},
- }
+ {
+ desc: "limit by count",
+ setup: func(t *testing.T) setupData {
+ repo, _ := gittest.CreateRepository(t, ctx, cfg)
- for _, tc := range testCases {
- t.Run(tc.id, func(t *testing.T) {
- request := &gitalypb.FindCommitsRequest{
- Repository: repo,
- Revision: []byte(tc.id),
- Trailers: tc.trailers,
- Limit: 1,
- }
- stream, err := client.FindCommits(ctx, request)
- require.NoError(t, err)
+ commitAID, _ := writeCommit(t, repo)
+ commitBID, commitB := writeCommit(t, repo, gittest.WithParents(commitAID))
+ commitCID, commitC := writeCommit(t, repo, gittest.WithParents(commitBID))
- resp, err := stream.Recv()
- require.NoError(t, err)
+ return setupData{
+ request: &gitalypb.FindCommitsRequest{
+ Repository: repo,
+ Revision: []byte(commitCID),
+ Limit: 2,
+ },
+ expectedCommits: []*gitalypb.GitCommit{commitC, commitB},
+ }
+ },
+ },
+ {
+ desc: "default limit returns no commits",
+ setup: func(t *testing.T) setupData {
+ repo, _ := gittest.CreateRepository(t, ctx, cfg)
+ commitID, _ := writeCommit(t, repo)
- require.Equal(t, 1, len(resp.Commits), "expected exactly one commit in the first message")
- firstCommit := resp.Commits[0]
+ return setupData{
+ request: &gitalypb.FindCommitsRequest{
+ Repository: repo,
+ Revision: []byte(commitID),
+ Limit: 0,
+ },
+ }
+ },
+ },
+ {
+ desc: "limit by path",
+ setup: func(t *testing.T) setupData {
+ repo, _ := gittest.CreateRepository(t, ctx, cfg)
- testhelper.ProtoEqual(t, tc.commit, firstCommit)
+ commitAID, commitA := writeCommit(t, repo, gittest.WithTreeEntries(
+ gittest.TreeEntry{Path: "a", Mode: "100644", Content: "a"},
+ ))
+ commitBID, _ := writeCommit(t, repo, gittest.WithTreeEntries(
+ gittest.TreeEntry{Path: "a", Mode: "100644", Content: "a"},
+ gittest.TreeEntry{Path: "b", Mode: "100644", Content: "b"},
+ ), gittest.WithParents(commitAID))
- _, err = stream.Recv()
- require.Equal(t, io.EOF, err, "there should be no further messages in the stream")
- })
- }
-}
+ return setupData{
+ request: &gitalypb.FindCommitsRequest{
+ Repository: repo,
+ Revision: []byte(commitBID),
+ Paths: [][]byte{
+ []byte("a"),
+ },
+ Limit: 9000,
+ },
+ expectedCommits: []*gitalypb.GitCommit{commitA},
+ }
+ },
+ },
+ {
+ desc: "limit by path with wildcard",
+ setup: func(t *testing.T) setupData {
+ repo, _ := gittest.CreateRepository(t, ctx, cfg)
-func TestSuccessfulFindCommitsRequest(t *testing.T) {
- t.Parallel()
+ commitAID, commitA := writeCommit(t, repo, gittest.WithTreeEntries(
+ gittest.TreeEntry{Path: "a-foo", Mode: "100644", Content: "a"},
+ ))
+ commitBID, _ := writeCommit(t, repo, gittest.WithTreeEntries(
+ gittest.TreeEntry{Path: "a-foo", Mode: "100644", Content: "a"},
+ gittest.TreeEntry{Path: "b-foo", Mode: "100644", Content: "b"},
+ ), gittest.WithParents(commitAID))
- ctx := testhelper.Context(t)
- _, repo, _, client := setupCommitServiceWithRepo(t, ctx)
-
- testCases := []struct {
- desc string
- request *gitalypb.FindCommitsRequest
- // Use 'ids' if you know the exact commits id's that should be returned
- ids []string
- // Use minCommits if you don't know the exact commit id's
- minCommits int
- }{
- {
- desc: "commit by author",
- request: &gitalypb.FindCommitsRequest{
- Repository: repo,
- Revision: []byte("0031876facac3f2b2702a0e53a26e89939a42209"),
- Author: []byte("Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>"),
- Limit: 20,
+ return setupData{
+ request: &gitalypb.FindCommitsRequest{
+ Repository: repo,
+ Revision: []byte(commitBID),
+ Paths: [][]byte{
+ []byte("a-*"),
+ },
+ Limit: 9000,
+ },
+ expectedCommits: []*gitalypb.GitCommit{commitA},
+ }
},
- ids: []string{"1a0b36b3cdad1d2ee32457c102a8c0b7056fa863"},
},
{
- desc: "only revision, limit commits",
- request: &gitalypb.FindCommitsRequest{
- Repository: repo,
- Revision: []byte("0031876facac3f2b2702a0e53a26e89939a42209"),
- Limit: 3,
- },
- ids: []string{
- "0031876facac3f2b2702a0e53a26e89939a42209",
- "bf6e164cac2dc32b1f391ca4290badcbe4ffc5fb",
- "48ca272b947f49eee601639d743784a176574a09",
+ desc: "limit by path with non-existent literal pathspec",
+ setup: func(t *testing.T) setupData {
+ repo, _ := gittest.CreateRepository(t, ctx, cfg)
+
+ commitAID, _ := writeCommit(t, repo, gittest.WithTreeEntries(
+ gittest.TreeEntry{Path: "a-foo", Mode: "100644", Content: "a"},
+ ))
+ commitBID, _ := writeCommit(t, repo, gittest.WithTreeEntries(
+ gittest.TreeEntry{Path: "a-foo", Mode: "100644", Content: "a"},
+ gittest.TreeEntry{Path: "b-foo", Mode: "100644", Content: "b"},
+ ), gittest.WithParents(commitAID))
+
+ return setupData{
+ request: &gitalypb.FindCommitsRequest{
+ Repository: repo,
+ Revision: []byte(commitBID),
+ Paths: [][]byte{
+ []byte("a-*"),
+ },
+ Limit: 9000,
+ GlobalOptions: &gitalypb.GlobalOptions{LiteralPathspecs: true},
+ },
+ expectedCommits: nil,
+ }
},
},
{
- desc: "revision, default commit limit",
- request: &gitalypb.FindCommitsRequest{
- Repository: repo,
- Revision: []byte("0031876facac3f2b2702a0e53a26e89939a42209"),
+ desc: "empty revision uses default branch",
+ setup: func(t *testing.T) setupData {
+ repo, _ := gittest.CreateRepository(t, ctx, cfg)
+
+ _, commit := writeCommit(t, repo, gittest.WithBranch(git.DefaultBranch))
+
+ return setupData{
+ request: &gitalypb.FindCommitsRequest{
+ Repository: repo,
+ Limit: 9000,
+ },
+ expectedCommits: []*gitalypb.GitCommit{commit},
+ }
},
},
{
- desc: "revision, default commit limit, bypassing rugged walk",
- request: &gitalypb.FindCommitsRequest{
- Repository: repo,
- Revision: []byte("0031876facac3f2b2702a0e53a26e89939a42209"),
- DisableWalk: true,
+ desc: "limit by date",
+ setup: func(t *testing.T) setupData {
+ repo, _ := gittest.CreateRepository(t, ctx, cfg)
+
+ oldDate := time.Date(2000, 1, 1, 1, 1, 1, 0, time.UTC)
+ medDate := time.Date(2010, 1, 1, 1, 1, 1, 0, time.UTC)
+ newDate := time.Date(2020, 1, 1, 1, 1, 1, 0, time.UTC)
+
+ oldCommitID, _ := writeCommit(t, repo, gittest.WithCommitterDate(oldDate))
+ medCommitID, medCommit := writeCommit(t, repo, gittest.WithCommitterDate(medDate), gittest.WithParents(oldCommitID))
+ newCommitID, _ := writeCommit(t, repo, gittest.WithCommitterDate(newDate), gittest.WithParents(medCommitID))
+
+ return setupData{
+ request: &gitalypb.FindCommitsRequest{
+ Repository: repo,
+ Revision: []byte(newCommitID),
+ Before: timestamppb.New(newDate.Add(-1 * time.Second)),
+ After: timestamppb.New(oldDate.Add(+1 * time.Second)),
+ Limit: 9000,
+ },
+ expectedCommits: []*gitalypb.GitCommit{medCommit},
+ }
},
},
{
- desc: "revision and paths",
- request: &gitalypb.FindCommitsRequest{
- Repository: repo,
- Revision: []byte("0031876facac3f2b2702a0e53a26e89939a42209"),
- Paths: [][]byte{[]byte("LICENSE")},
- Limit: 10,
+ desc: "skip merges",
+ setup: func(t *testing.T) setupData {
+ repo, _ := gittest.CreateRepository(t, ctx, cfg)
+
+ mergeBaseID, mergeBase := writeCommit(t, repo)
+ leftCommitID, leftCommit := writeCommit(t, repo, gittest.WithMessage("left"), gittest.WithParents(mergeBaseID))
+ rightCommitID, rightCommit := writeCommit(t, repo, gittest.WithMessage("right"), gittest.WithParents(mergeBaseID))
+ mergeCommitID, _ := writeCommit(t, repo, gittest.WithParents(leftCommitID, rightCommitID))
+
+ return setupData{
+ request: &gitalypb.FindCommitsRequest{
+ Repository: repo,
+ Revision: []byte(mergeCommitID),
+ SkipMerges: true,
+ Limit: 9000,
+ },
+ expectedCommits: []*gitalypb.GitCommit{leftCommit, rightCommit, mergeBase},
+ }
},
- ids: []string{"1a0b36b3cdad1d2ee32457c102a8c0b7056fa863"},
},
{
- desc: "revision and wildcard pathspec",
- request: &gitalypb.FindCommitsRequest{
- Repository: repo,
- Revision: []byte("0031876facac3f2b2702a0e53a26e89939a42209"),
- Paths: [][]byte{[]byte("LICEN*")},
- Limit: 10,
+ desc: "follow renames",
+ setup: func(t *testing.T) setupData {
+ repo, _ := gittest.CreateRepository(t, ctx, cfg)
+
+ commitAID, commitA := writeCommit(t, repo, gittest.WithTreeEntries(
+ gittest.TreeEntry{Path: "rename-me", Mode: "100644", Content: "something\n"},
+ ))
+ commitBID, commitB := writeCommit(t, repo, gittest.WithTreeEntries(
+ gittest.TreeEntry{Path: "renamed", Mode: "100644", Content: "something\n"},
+ ), gittest.WithParents(commitAID))
+
+ return setupData{
+ request: &gitalypb.FindCommitsRequest{
+ Repository: repo,
+ Revision: []byte(commitBID),
+ Paths: [][]byte{
+ []byte("renamed"),
+ },
+ Follow: true,
+ Limit: 9000,
+ },
+ expectedCommits: []*gitalypb.GitCommit{commitB, commitA},
+ }
},
- ids: []string{"1a0b36b3cdad1d2ee32457c102a8c0b7056fa863"},
},
{
- desc: "revision and non-existent literal pathspec",
- request: &gitalypb.FindCommitsRequest{
- Repository: repo,
- Revision: []byte("0031876facac3f2b2702a0e53a26e89939a42209"),
- Paths: [][]byte{[]byte("LICEN*")},
- Limit: 10,
- GlobalOptions: &gitalypb.GlobalOptions{LiteralPathspecs: true},
+ desc: "all references",
+ setup: func(t *testing.T) setupData {
+ repo, _ := gittest.CreateRepository(t, ctx, cfg)
+
+ _, commitA := writeCommit(t, repo, gittest.WithMessage("a"), gittest.WithBranch("a"))
+ _, commitB := writeCommit(t, repo, gittest.WithMessage("b"), gittest.WithBranch("b"))
+
+ return setupData{
+ request: &gitalypb.FindCommitsRequest{
+ Repository: repo,
+ All: true,
+ Limit: 9000,
+ },
+ expectedCommits: []*gitalypb.GitCommit{commitB, commitA},
+ }
},
- ids: []string{},
},
{
- desc: "empty revision",
- request: &gitalypb.FindCommitsRequest{
- Repository: repo,
- Limit: 35,
+ desc: "first parents",
+ setup: func(t *testing.T) setupData {
+ repo, _ := gittest.CreateRepository(t, ctx, cfg)
+
+ mergeBaseID, mergeBase := writeCommit(t, repo)
+ leftCommitID, leftCommit := writeCommit(t, repo, gittest.WithMessage("left"), gittest.WithParents(mergeBaseID))
+ rightCommitID, _ := writeCommit(t, repo, gittest.WithMessage("right"), gittest.WithParents(mergeBaseID))
+ mergeCommitID, mergeCommit := writeCommit(t, repo, gittest.WithParents(leftCommitID, rightCommitID))
+
+ return setupData{
+ request: &gitalypb.FindCommitsRequest{
+ Repository: repo,
+ Revision: []byte(mergeCommitID),
+ FirstParent: true,
+ Limit: 9000,
+ },
+ expectedCommits: []*gitalypb.GitCommit{mergeCommit, leftCommit, mergeBase},
+ }
},
- minCommits: 35,
},
{
- desc: "before and after",
- request: &gitalypb.FindCommitsRequest{
- Repository: repo,
- Before: &timestamppb.Timestamp{Seconds: 1483225200},
- After: &timestamppb.Timestamp{Seconds: 1472680800},
- Limit: 10,
- },
- ids: []string{
- "b83d6e391c22777fca1ed3012fce84f633d7fed0",
- "498214de67004b1da3d820901307bed2a68a8ef6",
+ desc: "order by none",
+ setup: func(t *testing.T) setupData {
+ repo, _ := gittest.CreateRepository(t, ctx, cfg)
+
+ mergeBaseID, mergeBase := writeCommit(t, repo)
+ leftCommitID, leftCommit := writeCommit(t, repo, gittest.WithParents(mergeBaseID), gittest.WithCommitterDate(time.Date(2020, 1, 1, 1, 1, 1, 0, time.UTC)))
+ rightCommitID, rightCommit := writeCommit(t, repo, gittest.WithParents(mergeBaseID), gittest.WithCommitterDate(time.Date(2000, 1, 1, 1, 1, 1, 0, time.UTC)))
+ mergeCommitID, mergeCommit := writeCommit(t, repo, gittest.WithParents(leftCommitID, rightCommitID))
+
+ return setupData{
+ request: &gitalypb.FindCommitsRequest{
+ Repository: repo,
+ Revision: []byte(mergeCommitID),
+ Order: gitalypb.FindCommitsRequest_NONE,
+ Limit: 9000,
+ },
+ expectedCommits: []*gitalypb.GitCommit{mergeCommit, leftCommit, mergeBase, rightCommit},
+ }
},
},
{
- desc: "no merges",
- request: &gitalypb.FindCommitsRequest{
- Repository: repo,
- Revision: []byte("e63f41fe459e62e1228fcef60d7189127aeba95a"),
- SkipMerges: true,
- Limit: 10,
- },
- ids: []string{
- "4a24d82dbca5c11c61556f3b35ca472b7463187e",
- "498214de67004b1da3d820901307bed2a68a8ef6",
- "38008cb17ce1466d8fec2dfa6f6ab8dcfe5cf49e",
- "c347ca2e140aa667b968e51ed0ffe055501fe4f4",
- "d59c60028b053793cecfb4022de34602e1a9218e",
- "a5391128b0ef5d21df5dd23d98557f4ef12fae20",
- "54fcc214b94e78d7a41a9a8fe6d87a5e59500e51",
- "048721d90c449b244b7b4c53a9186b04330174ec",
- "5f923865dde3436854e9ceb9cdb7815618d4e849",
- "2ea1f3dec713d940208fb5ce4a38765ecb5d3f73",
+ desc: "order by topo",
+ setup: func(t *testing.T) setupData {
+ repo, _ := gittest.CreateRepository(t, ctx, cfg)
+
+ mergeBaseID, mergeBase := writeCommit(t, repo)
+ leftCommitID, leftCommit := writeCommit(t, repo, gittest.WithParents(mergeBaseID), gittest.WithCommitterDate(time.Date(2020, 1, 1, 1, 1, 1, 0, time.UTC)))
+ rightCommitID, rightCommit := writeCommit(t, repo, gittest.WithParents(mergeBaseID), gittest.WithCommitterDate(time.Date(2000, 1, 1, 1, 1, 1, 0, time.UTC)))
+ mergeCommitID, mergeCommit := writeCommit(t, repo, gittest.WithParents(leftCommitID, rightCommitID))
+
+ return setupData{
+ request: &gitalypb.FindCommitsRequest{
+ Repository: repo,
+ Revision: []byte(mergeCommitID),
+ Order: gitalypb.FindCommitsRequest_TOPO,
+ Limit: 9000,
+ },
+ // Note how the right commit is sorted immediately after the merge commit now
+ // and compare this with the preceding test where it is sorted towards the end.
+ expectedCommits: []*gitalypb.GitCommit{mergeCommit, rightCommit, leftCommit, mergeBase},
+ }
},
},
{
- desc: "following renames",
- request: &gitalypb.FindCommitsRequest{
- Repository: repo,
- Revision: []byte("94bb47ca1297b7b3731ff2a36923640991e9236f"),
- Paths: [][]byte{[]byte("CHANGELOG.md")},
- Follow: true,
- Limit: 10,
- },
- ids: []string{
- "94bb47ca1297b7b3731ff2a36923640991e9236f",
- "5f923865dde3436854e9ceb9cdb7815618d4e849",
- "913c66a37b4a45b9769037c55c2d238bd0942d2e",
+ desc: "ambiguous reference",
+ setup: func(t *testing.T) setupData {
+ repo, _ := gittest.CreateRepository(t, ctx, cfg)
+
+ // The second commit is created with the first commit's object ID as branch name, thus
+ // creating ambiguity.
+ commitAID, commitA := writeCommit(t, repo, gittest.WithMessage("a"))
+ writeCommit(t, repo, gittest.WithMessage("b"), gittest.WithBranch(commitAID.String()))
+
+ return setupData{
+ request: &gitalypb.FindCommitsRequest{
+ Repository: repo,
+ Revision: []byte(commitAID),
+ Limit: 9000,
+ },
+ expectedCommits: []*gitalypb.GitCommit{commitA},
+ }
},
},
{
- desc: "all refs",
- request: &gitalypb.FindCommitsRequest{
- Repository: repo,
- All: true,
- Limit: 90,
+ desc: "exceeding offset",
+ setup: func(t *testing.T) setupData {
+ repo, _ := gittest.CreateRepository(t, ctx, cfg)
+
+ commitID, _ := writeCommit(t, repo, gittest.WithMessage("a"))
+
+ return setupData{
+ request: &gitalypb.FindCommitsRequest{
+ Repository: repo,
+ Revision: []byte(commitID),
+ Limit: 9000,
+ Offset: 9000,
+ },
+ expectedCommits: nil,
+ }
},
- minCommits: 90,
},
{
- desc: "first parents",
- request: &gitalypb.FindCommitsRequest{
- Repository: repo,
- Revision: []byte("e63f41fe459e62e1228fcef60d7189127aeba95a"),
- FirstParent: true,
- Limit: 10,
- },
- ids: []string{
- "e63f41fe459e62e1228fcef60d7189127aeba95a",
- "b83d6e391c22777fca1ed3012fce84f633d7fed0",
- "1b12f15a11fc6e62177bef08f47bc7b5ce50b141",
- "6907208d755b60ebeacb2e9dfea74c92c3449a1f",
- "281d3a76f31c812dbf48abce82ccf6860adedd81",
- "54fcc214b94e78d7a41a9a8fe6d87a5e59500e51",
- "be93687618e4b132087f430a4d8fc3a609c9b77c",
- "5f923865dde3436854e9ceb9cdb7815618d4e849",
- "d2d430676773caa88cdaf7c55944073b2fd5561a",
- "59e29889be61e6e0e5e223bfa9ac2721d31605b8",
+ desc: "referenced by tags and branches",
+ setup: func(t *testing.T) setupData {
+ repo, repoPath := gittest.CreateRepository(t, ctx, cfg)
+
+ commitID, commit := writeCommit(t, repo, gittest.WithBranch("branch"))
+ gittest.WriteTag(t, cfg, repoPath, "v1.0.0", commitID.Revision())
+
+ commit.ReferencedBy = [][]byte{
+ []byte("refs/tags/v1.0.0"),
+ []byte("refs/heads/branch"),
+ }
+
+ return setupData{
+ request: &gitalypb.FindCommitsRequest{
+ Repository: repo,
+ Revision: []byte(commitID),
+ Limit: 9000,
+ IncludeReferencedBy: [][]byte{
+ []byte("refs/heads/"),
+ []byte("refs/tags"),
+ },
+ },
+ expectedCommits: []*gitalypb.GitCommit{commit},
+ }
},
},
{
- // Ordering by none implies that commits appear in
- // chronological order:
- //
- // git log --graph -n 6 --pretty=format:"%h" --date-order 0031876
- // * 0031876
- // |\
- // * | bf6e164
- // | * 48ca272
- // * | 9d526f8
- // | * 335bc94
- // |/
- // * 1039376
- desc: "ordered by none",
- request: &gitalypb.FindCommitsRequest{
- Repository: repo,
- Revision: []byte("0031876"),
- Order: gitalypb.FindCommitsRequest_NONE,
- Limit: 6,
- },
- ids: []string{
- "0031876facac3f2b2702a0e53a26e89939a42209",
- "bf6e164cac2dc32b1f391ca4290badcbe4ffc5fb",
- "48ca272b947f49eee601639d743784a176574a09",
- "9d526f87b82e2b2fd231ca44c95508e5e85624ca",
- "335bc94d5b7369b10251e612158da2e4a4aaa2a5",
- "1039376155a0d507eba0ea95c29f8f5b983ea34b",
+ desc: "referenced by tags only",
+ setup: func(t *testing.T) setupData {
+ repo, repoPath := gittest.CreateRepository(t, ctx, cfg)
+
+ commitID, commit := writeCommit(t, repo, gittest.WithBranch("branch"))
+ gittest.WriteTag(t, cfg, repoPath, "v1.0.0", commitID.Revision())
+ commit.ReferencedBy = [][]byte{
+ []byte("refs/tags/v1.0.0"),
+ }
+
+ return setupData{
+ request: &gitalypb.FindCommitsRequest{
+ Repository: repo,
+ Revision: []byte(commitID),
+ Limit: 9000,
+ IncludeReferencedBy: [][]byte{
+ []byte("refs/tags"),
+ },
+ },
+ expectedCommits: []*gitalypb.GitCommit{commit},
+ }
},
},
{
- // When ordering by topology, all commit children will
- // be shown before parents:
- //
- // git log --graph -n 6 --pretty=format:"%h" --topo-order 0031876
- // * 0031876
- // |\
- // | * 48ca272
- // | * 335bc94
- // * | bf6e164
- // * | 9d526f8
- // |/
- // * 1039376
- desc: "ordered by topo",
- request: &gitalypb.FindCommitsRequest{
- Repository: repo,
- Revision: []byte("0031876"),
- Order: gitalypb.FindCommitsRequest_TOPO,
- Limit: 6,
- },
- ids: []string{
- "0031876facac3f2b2702a0e53a26e89939a42209",
- "48ca272b947f49eee601639d743784a176574a09",
- "335bc94d5b7369b10251e612158da2e4a4aaa2a5",
- "bf6e164cac2dc32b1f391ca4290badcbe4ffc5fb",
- "9d526f87b82e2b2fd231ca44c95508e5e85624ca",
- "1039376155a0d507eba0ea95c29f8f5b983ea34b",
+ desc: "referenced by HEAD",
+ setup: func(t *testing.T) setupData {
+ repo, _ := gittest.CreateRepository(t, ctx, cfg)
+
+ commitID, commit := writeCommit(t, repo, gittest.WithBranch(git.DefaultBranch))
+ commit.ReferencedBy = [][]byte{
+ []byte("HEAD"),
+ }
+
+ return setupData{
+ request: &gitalypb.FindCommitsRequest{
+ Repository: repo,
+ Revision: []byte(commitID),
+ Limit: 9000,
+ IncludeReferencedBy: [][]byte{
+ []byte("HEAD"),
+ },
+ },
+ expectedCommits: []*gitalypb.GitCommit{commit},
+ }
},
},
- }
+ {
+ desc: "with short stats",
+ setup: func(t *testing.T) setupData {
+ repo, _ := gittest.CreateRepository(t, ctx, cfg)
- for _, tc := range testCases {
- t.Run(tc.desc, func(t *testing.T) {
- stream, err := client.FindCommits(ctx, tc.request)
- require.NoError(t, err)
+ commitAID, commitA := writeCommit(t, repo, gittest.WithTreeEntries(
+ gittest.TreeEntry{Path: "deleted", Mode: "100644", Content: "to be deleted\n"},
+ gittest.TreeEntry{Path: "modified", Mode: "100644", Content: "to be modified\n"},
+ ))
+ commitA.ShortStats = &gitalypb.CommitStatInfo{
+ Additions: 2, ChangedFiles: 2,
+ }
- var ids []string
- for err == nil {
- var resp *gitalypb.FindCommitsResponse
- resp, err = stream.Recv()
- for _, c := range resp.GetCommits() {
- ids = append(ids, c.Id)
+ commitBID, commitB := writeCommit(t, repo, gittest.WithTreeEntries(
+ gittest.TreeEntry{Path: "created", Mode: "100644", Content: "created\n"},
+ gittest.TreeEntry{Path: "modified", Mode: "100644", Content: "modified\n"},
+ ), gittest.WithParents(commitAID))
+ commitB.ShortStats = &gitalypb.CommitStatInfo{
+ Additions: 2, Deletions: 2, ChangedFiles: 3,
}
- }
- require.Equal(t, io.EOF, err)
- if tc.minCommits > 0 {
- require.True(t, len(ids) >= tc.minCommits, "expected at least %d commits, got %d", tc.minCommits, len(ids))
- return
- }
+ return setupData{
+ request: &gitalypb.FindCommitsRequest{
+ Repository: repo,
+ Revision: []byte(commitBID),
+ Limit: 9000,
+ IncludeShortstat: true,
+ },
+ expectedCommits: []*gitalypb.GitCommit{commitB, commitA},
+ }
+ },
+ },
+ } {
+ tc := tc
- require.Equal(t, len(tc.ids), len(ids))
- for i, id := range tc.ids {
- require.Equal(t, id, ids[i])
- }
+ t.Run(tc.desc, func(t *testing.T) {
+ t.Parallel()
+
+ setup := tc.setup(t)
+
+ commits, err := getCommits(t, ctx, client, setup.request)
+ testhelper.RequireGrpcError(t, setup.expectedErr, err)
+ testhelper.ProtoEqual(t, setup.expectedCommits, commits)
})
}
}
-func TestSuccessfulFindCommitsRequestWithAltGitObjectDirs(t *testing.T) {
+func TestFindCommits_quarantine(t *testing.T) {
t.Parallel()
ctx := testhelper.Context(t)
- cfg, repo, repoPath, client := setupCommitServiceWithRepo(t, ctx)
+ cfg, client := setupCommitService(t, ctx)
+ repo, repoPath := gittest.CreateRepository(t, ctx, cfg)
altObjectsDir := "./alt-objects"
commitID := gittest.WriteCommit(t, cfg, repoPath,
gittest.WithAlternateObjectDirectory(filepath.Join(repoPath, altObjectsDir)),
)
- testCases := []struct {
+ for _, tc := range []struct {
desc string
altDirs []string
expectedCount int
@@ -463,485 +659,73 @@ func TestSuccessfulFindCommitsRequestWithAltGitObjectDirs(t *testing.T) {
altDirs: []string{},
expectedCount: 0,
},
- }
+ } {
+ t.Run(tc.desc, func(t *testing.T) {
+ repo.GitAlternateObjectDirectories = tc.altDirs
- for _, testCase := range testCases {
- t.Run(testCase.desc, func(t *testing.T) {
- repo.GitAlternateObjectDirectories = testCase.altDirs
- request := &gitalypb.FindCommitsRequest{
+ commits, err := getCommits(t, ctx, client, &gitalypb.FindCommitsRequest{
Repository: repo,
Revision: []byte(commitID.String()),
Limit: 1,
- }
-
- c, err := client.FindCommits(ctx, request)
+ })
require.NoError(t, err)
-
- receivedCommits := getAllCommits(t, func() (gitCommitsGetter, error) { return c.Recv() })
-
- require.Equal(t, testCase.expectedCount, len(receivedCommits), "number of commits received")
+ require.Len(t, commits, tc.expectedCount)
})
}
}
-func TestSuccessfulFindCommitsRequestWithAmbiguousRef(t *testing.T) {
+func TestFindCommits_followWithOffset(t *testing.T) {
t.Parallel()
ctx := testhelper.Context(t)
- cfg, repo, repoPath, client := setupCommitServiceWithRepo(t, ctx)
+ cfg, client := setupCommitService(t, ctx)
- // These are arbitrary SHAs in the repository. The important part is
- // that we create a branch using one of them with a different SHA so
- // that Git detects an ambiguous reference.
- branchName := "1e292f8fedd741b75372e19097c76d327140c312"
- commitSha := "6907208d755b60ebeacb2e9dfea74c92c3449a1f"
+ repo, repoPath := gittest.CreateRepository(t, ctx, cfg)
- gittest.Exec(t, cfg, "-C", repoPath, "branch", branchName, commitSha)
+ var commitID git.ObjectID
+ for i := 0; i < 10; i++ {
+ var parents []git.ObjectID
+ if commitID != "" {
+ parents = []git.ObjectID{commitID}
+ }
- request := &gitalypb.FindCommitsRequest{
- Repository: repo,
- Revision: []byte(branchName),
- Limit: 1,
+ commitID = gittest.WriteCommit(t, cfg, repoPath, gittest.WithParents(parents...), gittest.WithTreeEntries(
+ gittest.TreeEntry{Path: fmt.Sprintf("%d", i), Mode: "100644", Content: "content that is being moved around\n"},
+ ))
}
- c, err := client.FindCommits(ctx, request)
- require.NoError(t, err)
-
- receivedCommits := getAllCommits(t, func() (gitCommitsGetter, error) { return c.Recv() })
-
- require.Equal(t, 1, len(receivedCommits), "number of commits received")
-}
-
-func TestFailureFindCommitsRequest(t *testing.T) {
- t.Parallel()
-
- ctx := testhelper.Context(t)
- _, repo, _, client := setupCommitServiceWithRepo(t, ctx)
-
- testCases := []struct {
- desc string
- request *gitalypb.FindCommitsRequest
- expectedErr error
- }{
- {
- desc: "no repository provided",
- request: &gitalypb.FindCommitsRequest{
- Repository: nil,
- Revision: []byte("HEAD"),
- },
- expectedErr: structerr.NewInvalidArgument("%w", storage.ErrRepositoryNotSet),
- },
- {
- desc: "empty path string",
- request: &gitalypb.FindCommitsRequest{
- Repository: repo,
- Paths: [][]byte{[]byte("")},
- },
- expectedErr: status.Error(codes.InvalidArgument, "path is empty string"),
- },
- {
- desc: "invalid revision",
- request: &gitalypb.FindCommitsRequest{
+ for offset := 0; offset < 10; offset++ {
+ t.Run(fmt.Sprintf("testing with offset %d", offset), func(t *testing.T) {
+ commits, err := getCommits(t, ctx, client, &gitalypb.FindCommitsRequest{
Repository: repo,
- Revision: []byte("--output=/meow"),
- Limit: 1,
- },
- expectedErr: status.Error(codes.InvalidArgument, "revision can't start with '-'"),
- },
- }
-
- for _, tc := range testCases {
- t.Run(tc.desc, func(t *testing.T) {
- stream, err := client.FindCommits(ctx, tc.request)
+ Revision: []byte(commitID),
+ Follow: true,
+ Paths: [][]byte{[]byte("9")},
+ Offset: int32(offset),
+ Limit: 9000,
+ })
require.NoError(t, err)
-
- for err == nil {
- _, err = stream.Recv()
- }
-
- testhelper.RequireGrpcError(t, tc.expectedErr, err)
- })
- }
-}
-
-func TestFindCommitsRequestWithFollowAndOffset(t *testing.T) {
- t.Parallel()
-
- ctx := testhelper.Context(t)
- _, repo, _, client := setupCommitServiceWithRepo(t, ctx)
-
- request := &gitalypb.FindCommitsRequest{
- Repository: repo,
- Follow: true,
- Paths: [][]byte{[]byte("CHANGELOG")},
- Limit: 100,
- }
- allCommits := getCommits(t, ctx, request, client)
- totalCommits := len(allCommits)
-
- for offset := 0; offset < totalCommits; offset++ {
- t.Run(fmt.Sprintf("testing with offset %d", offset), func(t *testing.T) {
- ctx := testhelper.Context(t)
- request.Offset = int32(offset)
- request.Limit = int32(totalCommits)
- commits := getCommits(t, ctx, request, client)
- assert.Len(t, commits, totalCommits-offset)
- assert.Equal(t, allCommits[offset:], commits)
+ require.Len(t, commits, 10-offset)
})
}
}
-func TestFindCommitsWithExceedingOffset(t *testing.T) {
- t.Parallel()
-
- ctx := testhelper.Context(t)
- _, repo, _, client := setupCommitServiceWithRepo(t, ctx)
-
- stream, err := client.FindCommits(ctx, &gitalypb.FindCommitsRequest{
- Repository: repo,
- Follow: true,
- Paths: [][]byte{[]byte("CHANGELOG")},
- Offset: 9000,
- })
- require.NoError(t, err)
-
- response, err := stream.Recv()
- require.Nil(t, response)
- require.EqualError(t, err, "EOF")
-}
-
-func getCommits(t *testing.T, ctx context.Context, request *gitalypb.FindCommitsRequest, client gitalypb.CommitServiceClient) []*gitalypb.GitCommit {
+func getCommits(t *testing.T, ctx context.Context, client gitalypb.CommitServiceClient, request *gitalypb.FindCommitsRequest) ([]*gitalypb.GitCommit, error) {
t.Helper()
stream, err := client.FindCommits(ctx, request)
require.NoError(t, err)
- var commits []*gitalypb.GitCommit
- for err == nil {
- var resp *gitalypb.FindCommitsResponse
- resp, err = stream.Recv()
- commits = append(commits, resp.GetCommits()...)
- }
-
- require.Equal(t, io.EOF, err)
- return commits
-}
-
-func TestFindCommits_withReferencedBy(t *testing.T) {
- t.Parallel()
-
- ctx := testhelper.Context(t)
- cfg, repo, repoPath, client := setupCommitServiceWithRepo(t, ctx)
-
- type commitInfo struct {
- id string
- shortStats *gitalypb.CommitStatInfo
- refs [][]byte
- }
-
- gittest.WriteTag(t, cfg, repoPath, "a-tag", "570e7b2abdd848b95f2f578043fc23bd6f6fd24d")
- gittest.WriteTag(t, cfg, repoPath, "another-tag", "570e7b2abdd848b95f2f578043fc23bd6f6fd24d")
-
- testCases := []struct {
- desc string
- request *gitalypb.FindCommitsRequest
- commitStats []commitInfo
- }{
- {
- desc: "with stats and trailers",
- request: &gitalypb.FindCommitsRequest{
- Repository: repo,
- Revision: []byte("4cd80ccab63c82b4bad16faa5193fbd2aa06df40"),
- Limit: 3,
- SkipMerges: true,
- IncludeShortstat: true,
- Trailers: true,
- IncludeReferencedBy: [][]byte{[]byte("refs/tags"), []byte("refs/heads")},
- },
- commitStats: []commitInfo{
- {
- id: "4cd80ccab63c82b4bad16faa5193fbd2aa06df40",
- shortStats: &gitalypb.CommitStatInfo{
- Additions: 0,
- Deletions: 0,
- ChangedFiles: 1,
- },
- refs: nil,
- },
- {
- id: "5937ac0a7beb003549fc5fd26fc247adbce4a52e",
- shortStats: &gitalypb.CommitStatInfo{
- Additions: 4,
- Deletions: 0,
- ChangedFiles: 2,
- },
- refs: [][]byte{[]byte("refs/tags/v1.1.0"), []byte("refs/heads/improve/awesome")},
- },
- {
- id: "570e7b2abdd848b95f2f578043fc23bd6f6fd24d",
- shortStats: &gitalypb.CommitStatInfo{
- Additions: 11,
- Deletions: 6,
- ChangedFiles: 2,
- },
- refs: [][]byte{[]byte("refs/tags/another-tag"), []byte("refs/tags/a-tag")},
- },
- },
- },
- {
- desc: "without stats or trailers",
- request: &gitalypb.FindCommitsRequest{
- Repository: repo,
- Revision: []byte("4cd80ccab63c82b4bad16faa5193fbd2aa06df40"),
- Limit: 3,
- IncludeShortstat: false,
- SkipMerges: true,
- Trailers: false,
- IncludeReferencedBy: [][]byte{[]byte("refs/tags"), []byte("refs/heads/")},
- },
- commitStats: []commitInfo{
- {
- id: "4cd80ccab63c82b4bad16faa5193fbd2aa06df40",
- shortStats: nil,
- refs: nil,
- },
- {
- id: "5937ac0a7beb003549fc5fd26fc247adbce4a52e",
- shortStats: nil,
- refs: [][]byte{[]byte("refs/tags/v1.1.0"), []byte("refs/heads/improve/awesome")},
- },
- {
- id: "570e7b2abdd848b95f2f578043fc23bd6f6fd24d",
- shortStats: nil,
- refs: [][]byte{[]byte("refs/tags/another-tag"), []byte("refs/tags/a-tag")},
- },
- },
- },
- {
- desc: "only tags",
- request: &gitalypb.FindCommitsRequest{
- Repository: repo,
- Revision: []byte("5937ac0a7beb003549fc5fd26fc247adbce4a52e"),
- Limit: 1,
- IncludeShortstat: false,
- SkipMerges: true,
- Trailers: false,
- IncludeReferencedBy: [][]byte{[]byte("refs/tags")},
- },
- commitStats: []commitInfo{
- {
- id: "5937ac0a7beb003549fc5fd26fc247adbce4a52e",
- shortStats: nil,
- refs: [][]byte{[]byte("refs/tags/v1.1.0")},
- },
- },
- },
- {
- desc: "with HEAD",
- request: &gitalypb.FindCommitsRequest{
- Repository: repo,
- Revision: []byte("refs/heads/master"),
- Limit: 1,
- IncludeReferencedBy: [][]byte{[]byte("HEAD")},
- },
- commitStats: []commitInfo{
- {
- id: "1e292f8fedd741b75372e19097c76d327140c312",
- refs: [][]byte{[]byte("HEAD")},
- },
- },
- },
- {
- desc: "with HEAD pointing to another branch in the set",
- request: &gitalypb.FindCommitsRequest{
- Repository: repo,
- Revision: []byte("refs/heads/master"),
- Limit: 1,
- IncludeReferencedBy: [][]byte{[]byte("refs/heads"), []byte("HEAD")},
- },
- commitStats: []commitInfo{
- {
- id: "1e292f8fedd741b75372e19097c76d327140c312",
- refs: [][]byte{[]byte("HEAD"), []byte("refs/heads/master")},
- },
- },
- },
- }
-
- for _, tc := range testCases {
- t.Run(tc.desc, func(t *testing.T) {
- commits := getCommits(t, ctx, tc.request, client)
- assert.Equal(t, len(tc.commitStats), len(commits))
-
- for i, commit := range commits {
- assert.Equal(t, tc.commitStats[i].id, commit.Id)
- assert.Equal(t, tc.commitStats[i].shortStats, commit.ShortStats)
- assert.Equal(t, tc.commitStats[i].refs, commit.ReferencedBy)
- }
- })
- }
-}
-
-func TestFindCommits_withStats(t *testing.T) {
- t.Parallel()
-
- ctx := testhelper.Context(t)
- _, repo, _, client := setupCommitServiceWithRepo(t, ctx)
-
- type commitInfo struct {
- id string
- shortStats *gitalypb.CommitStatInfo
- }
-
- testCases := []struct {
- desc string
- request *gitalypb.FindCommitsRequest
- commitStats []commitInfo
- }{
- {
- desc: "no merges",
- request: &gitalypb.FindCommitsRequest{
- Repository: repo,
- Limit: 10,
- SkipMerges: true,
- IncludeShortstat: true,
- Trailers: true,
- },
- commitStats: []commitInfo{
- {
- id: "c1c67abbaf91f624347bb3ae96eabe3a1b742478",
- shortStats: &gitalypb.CommitStatInfo{
- Additions: 0,
- Deletions: 0,
- ChangedFiles: 1,
- },
- },
- {
- id: "c84ff944ff4529a70788a5e9003c2b7feae29047",
- shortStats: &gitalypb.CommitStatInfo{
- Additions: 0,
- Deletions: 0,
- ChangedFiles: 1,
- },
- },
- {
- id: "55bc176024cfa3baaceb71db584c7e5df900ea65",
- shortStats: &gitalypb.CommitStatInfo{
- Additions: 1,
- Deletions: 0,
- ChangedFiles: 1,
- },
- },
- {
- id: "4a24d82dbca5c11c61556f3b35ca472b7463187e",
- shortStats: &gitalypb.CommitStatInfo{
- Additions: 12,
- Deletions: 0,
- ChangedFiles: 1,
- },
- },
- {
- id: "498214de67004b1da3d820901307bed2a68a8ef6",
- shortStats: &gitalypb.CommitStatInfo{
- Additions: 1,
- Deletions: 0,
- ChangedFiles: 1,
- },
- },
- {
- id: "38008cb17ce1466d8fec2dfa6f6ab8dcfe5cf49e",
- shortStats: &gitalypb.CommitStatInfo{
- Additions: 1,
- Deletions: 0,
- ChangedFiles: 1,
- },
- },
- {
- id: "c347ca2e140aa667b968e51ed0ffe055501fe4f4",
- shortStats: &gitalypb.CommitStatInfo{
- Additions: 6,
- Deletions: 0,
- ChangedFiles: 1,
- },
- },
- {
- id: "d59c60028b053793cecfb4022de34602e1a9218e",
- shortStats: &gitalypb.CommitStatInfo{
- Additions: 0,
- Deletions: 6,
- ChangedFiles: 1,
- },
- },
- {
- id: "a5391128b0ef5d21df5dd23d98557f4ef12fae20",
- shortStats: &gitalypb.CommitStatInfo{
- Additions: 6,
- Deletions: 0,
- ChangedFiles: 2,
- },
- },
- {
- id: "54fcc214b94e78d7a41a9a8fe6d87a5e59500e51",
- shortStats: &gitalypb.CommitStatInfo{
- Additions: 1,
- Deletions: 0,
- ChangedFiles: 1,
- },
- },
- },
- },
- {
- desc: "with merges",
- request: &gitalypb.FindCommitsRequest{
- Repository: repo,
- Limit: 5,
- IncludeShortstat: true,
- Trailers: true,
- },
- commitStats: []commitInfo{
- {
- id: "1e292f8fedd741b75372e19097c76d327140c312",
- shortStats: nil,
- },
- {
- id: "c1c67abbaf91f624347bb3ae96eabe3a1b742478",
- shortStats: &gitalypb.CommitStatInfo{
- Additions: 0,
- Deletions: 0,
- ChangedFiles: 1,
- },
- },
- {
- id: "7975be0116940bf2ad4321f79d02a55c5f7779aa",
- shortStats: nil,
- },
- {
- id: "c84ff944ff4529a70788a5e9003c2b7feae29047",
- shortStats: &gitalypb.CommitStatInfo{
- Additions: 0,
- Deletions: 0,
- ChangedFiles: 1,
- },
- },
- {
- id: "60ecb67744cb56576c30214ff52294f8ce2def98",
- shortStats: nil,
- },
- },
- },
- }
-
- for _, tc := range testCases {
- t.Run(tc.desc, func(t *testing.T) {
- commits := getCommits(t, ctx, tc.request, client)
- assert.Equal(t, len(tc.commitStats), len(commits))
+ return testhelper.ReceiveAndFold(stream.Recv, func(
+ result []*gitalypb.GitCommit,
+ response *gitalypb.FindCommitsResponse,
+ ) []*gitalypb.GitCommit {
+ if response == nil {
+ return result
+ }
- for i, commit := range commits {
- assert.Equal(t, tc.commitStats[i].id, commit.Id)
- assert.Equal(t, tc.commitStats[i].shortStats, commit.ShortStats)
- }
- })
- }
+ return append(result, response.GetCommits()...)
+ })
}
func BenchmarkCommitStats(b *testing.B) {