diff options
author | karthik nayak <knayak@gitlab.com> | 2023-08-15 14:12:12 +0300 |
---|---|---|
committer | karthik nayak <knayak@gitlab.com> | 2023-08-15 14:12:12 +0300 |
commit | 3cd27d67e1d43ed7c7ca1d50e59c1bc161be8784 (patch) | |
tree | 77bf36ce67789967553686235ba5c1ebc4b74783 | |
parent | 5bdafbc7693c7dfacc1c0932cfa8d62004c7097b (diff) | |
parent | 8cd04c5711544c643c58d6f1b53d8b961c5f8e4f (diff) |
Merge branch 'pks-ref-sha256' into 'master'
ref: Refactor some tests to support SHA256
See merge request https://gitlab.com/gitlab-org/gitaly/-/merge_requests/6222
Merged-by: karthik nayak <knayak@gitlab.com>
Approved-by: karthik nayak <knayak@gitlab.com>
Co-authored-by: Patrick Steinhardt <psteinhardt@gitlab.com>
-rw-r--r-- | internal/gitaly/service/ref/find_all_branches_test.go | 371 | ||||
-rw-r--r-- | internal/gitaly/service/ref/find_local_branches_test.go | 544 | ||||
-rw-r--r-- | internal/gitaly/service/ref/find_tag_test.go | 580 | ||||
-rw-r--r-- | internal/gitaly/service/ref/testhelper_test.go | 53 |
4 files changed, 812 insertions, 736 deletions
diff --git a/internal/gitaly/service/ref/find_all_branches_test.go b/internal/gitaly/service/ref/find_all_branches_test.go index f4b2c7e6d..061695302 100644 --- a/internal/gitaly/service/ref/find_all_branches_test.go +++ b/internal/gitaly/service/ref/find_all_branches_test.go @@ -1,216 +1,239 @@ -//go:build !gitaly_test_sha256 - package ref import ( - "io" - "strings" + "fmt" "testing" "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" - "google.golang.org/protobuf/types/known/timestamppb" ) -func TestSuccessfulFindAllBranchesRequest(t *testing.T) { - t.Parallel() - - ctx := testhelper.Context(t) - cfg, repo, repoPath, client := setupRefService(t, ctx) - - remoteBranch := &gitalypb.FindAllBranchesResponse_Branch{ - Name: []byte("refs/remotes/origin/fake-remote-branch"), - Target: &gitalypb.GitCommit{ - Id: "913c66a37b4a45b9769037c55c2d238bd0942d2e", - Subject: []byte("Files, encoding and much more"), - Body: []byte("Files, encoding and much more\n\nSigned-off-by: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>\n"), - BodySize: 98, - ParentIds: []string{"cfe32cf61b73a0d5e9f13e774abde7ff789b1660"}, - Author: &gitalypb.CommitAuthor{ - Name: []byte("Dmitriy Zaporozhets"), - Email: []byte("dmitriy.zaporozhets@gmail.com"), - Date: ×tamppb.Timestamp{Seconds: 1393488896}, - Timezone: []byte("+0200"), - }, - Committer: &gitalypb.CommitAuthor{ - Name: []byte("Dmitriy Zaporozhets"), - Email: []byte("dmitriy.zaporozhets@gmail.com"), - Date: ×tamppb.Timestamp{Seconds: 1393488896}, - Timezone: []byte("+0200"), - }, - SignatureType: gitalypb.SignatureType_PGP, - TreeId: "faafbe7fe23fb83c664c78aaded9566c8f934412", - }, - } - - gittest.WriteRef(t, cfg, repoPath, "refs/remotes/origin/fake-remote-branch", git.ObjectID(remoteBranch.Target.Id)) - - request := &gitalypb.FindAllBranchesRequest{Repository: repo} - c, err := client.FindAllBranches(ctx, request) - require.NoError(t, err) - - branches := readFindAllBranchesResponsesFromClient(t, c) - - // It contains local branches - for name, target := range localBranches { - branch := &gitalypb.FindAllBranchesResponse_Branch{ - Name: []byte(name), - Target: target, - } - assertContainsAllBranchesResponseBranch(t, branches, branch) - } - - // It contains our fake remote branch - assertContainsAllBranchesResponseBranch(t, branches, remoteBranch) -} - -func TestSuccessfulFindAllBranchesRequestWithMergedBranches(t *testing.T) { +func TestFindAllBranches(t *testing.T) { t.Parallel() ctx := testhelper.Context(t) - cfg, repoProto, repoPath, client := setupRefService(t, ctx) - - repo := localrepo.NewTestRepo(t, cfg, repoProto) - - localRefs := gittest.Exec(t, cfg, "-C", repoPath, "for-each-ref", "--format=%(refname:strip=2)", "refs/heads") - for _, ref := range strings.Split(string(localRefs), "\n") { - ref = strings.TrimSpace(ref) - if _, ok := localBranches["refs/heads/"+ref]; ok || ref == "master" || ref == "" { - continue - } - gittest.Exec(t, cfg, "-C", repoPath, "branch", "-D", ref) - } - - expectedRefs := []string{"refs/heads/100%branch", "refs/heads/improve/awesome", "refs/heads/'test'"} + cfg, client := setupRefServiceWithoutRepo(t) - var expectedBranches []*gitalypb.FindAllBranchesResponse_Branch - for _, name := range expectedRefs { - target, ok := localBranches[name] - require.True(t, ok) - - branch := &gitalypb.FindAllBranchesResponse_Branch{ - Name: []byte(name), - Target: target, - } - expectedBranches = append(expectedBranches, branch) - } - - masterCommit, err := repo.ReadCommit(ctx, "master") - require.NoError(t, err) - expectedBranches = append(expectedBranches, &gitalypb.FindAllBranchesResponse_Branch{ - Name: []byte("refs/heads/master"), - Target: masterCommit, - }) - - testCases := []struct { - desc string + type setupData struct { request *gitalypb.FindAllBranchesRequest + expectedErr error expectedBranches []*gitalypb.FindAllBranchesResponse_Branch + } + + for _, tc := range []struct { + desc string + setup func(t *testing.T) setupData }{ { - desc: "all merged branches", - request: &gitalypb.FindAllBranchesRequest{ - Repository: repoProto, - MergedOnly: true, + desc: "empty request", + setup: func(t *testing.T) setupData { + return setupData{ + request: &gitalypb.FindAllBranchesRequest{}, + expectedErr: structerr.NewInvalidArgument("%w", storage.ErrRepositoryNotSet), + } }, - expectedBranches: expectedBranches, }, { - desc: "all merged from a list of branches", - request: &gitalypb.FindAllBranchesRequest{ - Repository: repoProto, - MergedOnly: true, - MergedBranches: [][]byte{ - []byte("refs/heads/100%branch"), - []byte("refs/heads/improve/awesome"), - []byte("refs/heads/gitaly-stuff"), - }, + desc: "invalid storage", + setup: func(t *testing.T) setupData { + return setupData{ + request: &gitalypb.FindAllBranchesRequest{ + Repository: &gitalypb.Repository{ + StorageName: "fake", + RelativePath: "repo", + }, + }, + expectedErr: testhelper.ToInterceptedMetadata(structerr.NewInvalidArgument( + "%w", storage.NewStorageNotFoundError("fake"), + )), + } }, - expectedBranches: expectedBranches[:2], }, - } - - for _, testCase := range testCases { - t.Run(testCase.desc, func(t *testing.T) { - c, err := client.FindAllBranches(ctx, testCase.request) - require.NoError(t, err) - - branches := readFindAllBranchesResponsesFromClient(t, c) - require.Len(t, branches, len(testCase.expectedBranches)) - - for _, branch := range branches { - // The GitCommit object returned by GetCommit() above and the one returned in the response - // vary a lot. We can't guarantee that master will be fixed at a certain commit so we can't create - // a structure for it manually, hence this hack. - if string(branch.Name) == "refs/heads/master" { - continue + { + desc: "empty repository", + setup: func(t *testing.T) setupData { + repo, _ := gittest.CreateRepository(t, ctx, cfg) + + return setupData{ + request: &gitalypb.FindAllBranchesRequest{ + Repository: repo, + }, + } + }, + }, + { + desc: "only non-branch references", + setup: func(t *testing.T) setupData { + repo, repoPath := gittest.CreateRepository(t, ctx, cfg) + + commitID := gittest.WriteCommit(t, cfg, repoPath) + for _, ref := range []git.ReferenceName{ + "refs/keep-around/kept", + "refs/something", + "refs/tags/v1.0.0", + } { + gittest.WriteRef(t, cfg, repoPath, ref, commitID) } - assertContainsAllBranchesResponseBranch(t, testCase.expectedBranches, branch) - } - }) - } -} - -func TestInvalidFindAllBranchesRequest(t *testing.T) { - t.Parallel() - - _, client := setupRefServiceWithoutRepo(t) + return setupData{ + request: &gitalypb.FindAllBranchesRequest{ + Repository: repo, + }, + } + }, + }, + { + desc: "single branch", + setup: func(t *testing.T) setupData { + repo, _ := gittest.CreateRepository(t, ctx, cfg) + _, commit := writeCommit(t, ctx, cfg, repo, gittest.WithBranch("branch")) + + return setupData{ + request: &gitalypb.FindAllBranchesRequest{ + Repository: repo, + }, + expectedBranches: []*gitalypb.FindAllBranchesResponse_Branch{ + {Name: []byte("refs/heads/branch"), Target: commit}, + }, + } + }, + }, + { + desc: "many branches", + setup: func(t *testing.T) setupData { + repo, repoPath := gittest.CreateRepository(t, ctx, cfg) + + commitID, commit := writeCommit(t, ctx, cfg, repo) + + var expectedBranches []*gitalypb.FindAllBranchesResponse_Branch + for i := 0; i < 100; i++ { + ref := fmt.Sprintf("refs/heads/branch-%03d", i) + gittest.WriteRef(t, cfg, repoPath, git.ReferenceName(ref), commitID) + expectedBranches = append(expectedBranches, &gitalypb.FindAllBranchesResponse_Branch{ + Name: []byte(ref), Target: commit, + }) + } - for _, tc := range []struct { - description string - request *gitalypb.FindAllBranchesRequest - expectedErr error - }{ + return setupData{ + request: &gitalypb.FindAllBranchesRequest{ + Repository: repo, + }, + expectedBranches: expectedBranches, + } + }, + }, { - description: "Empty request", - request: &gitalypb.FindAllBranchesRequest{}, - expectedErr: structerr.NewInvalidArgument("%w", storage.ErrRepositoryNotSet), + desc: "mixed branch and non-branch references", + setup: func(t *testing.T) setupData { + repo, repoPath := gittest.CreateRepository(t, ctx, cfg) + + commitID, commit := writeCommit(t, ctx, cfg, repo, gittest.WithBranch("branch")) + gittest.WriteRef(t, cfg, repoPath, "refs/tags/v1.0.0", commitID) + + return setupData{ + request: &gitalypb.FindAllBranchesRequest{ + Repository: repo, + }, + expectedBranches: []*gitalypb.FindAllBranchesResponse_Branch{ + {Name: []byte("refs/heads/branch"), Target: commit}, + }, + } + }, + }, + { + desc: "remote branches", + setup: func(t *testing.T) setupData { + repo, repoPath := gittest.CreateRepository(t, ctx, cfg) + + commitID, commit := writeCommit(t, ctx, cfg, repo, gittest.WithBranch("local-branch")) + gittest.WriteRef(t, cfg, repoPath, "refs/remotes/origin/remote-branch", commitID) + + return setupData{ + request: &gitalypb.FindAllBranchesRequest{ + Repository: repo, + }, + expectedBranches: []*gitalypb.FindAllBranchesResponse_Branch{ + {Name: []byte("refs/heads/local-branch"), Target: commit}, + {Name: []byte("refs/remotes/origin/remote-branch"), Target: commit}, + }, + } + }, }, { - description: "Invalid repo", - request: &gitalypb.FindAllBranchesRequest{ - Repository: &gitalypb.Repository{ - StorageName: "fake", - RelativePath: "repo", - }, + desc: "all merged branches", + setup: func(t *testing.T) setupData { + repo, repoPath := gittest.CreateRepository(t, ctx, cfg) + + root := gittest.WriteCommit(t, cfg, repoPath) + merged, mergedCommit := writeCommit(t, ctx, cfg, repo, gittest.WithBranch("merged"), gittest.WithParents(root), gittest.WithMessage("merged")) + _, mainCommit := writeCommit(t, ctx, cfg, repo, gittest.WithBranch(git.DefaultBranch), gittest.WithParents(root, merged)) + + gittest.WriteCommit(t, cfg, repoPath, gittest.WithBranch("unmerged"), gittest.WithParents(root), gittest.WithMessage("unmerged")) + + return setupData{ + request: &gitalypb.FindAllBranchesRequest{ + Repository: repo, + MergedOnly: true, + }, + expectedBranches: []*gitalypb.FindAllBranchesResponse_Branch{ + {Name: []byte(git.DefaultRef), Target: mainCommit}, + {Name: []byte("refs/heads/merged"), Target: mergedCommit}, + }, + } + }, + }, + { + desc: "merged branches from a list of branches", + setup: func(t *testing.T) setupData { + repo, repoPath := gittest.CreateRepository(t, ctx, cfg) + + root := gittest.WriteCommit(t, cfg, repoPath) + mergedA, mergedCommitA := writeCommit(t, ctx, cfg, repo, gittest.WithBranch("merged-a"), gittest.WithParents(root), gittest.WithMessage("merged A")) + mergedB, _ := writeCommit(t, ctx, cfg, repo, gittest.WithBranch("merged-b"), gittest.WithParents(root), gittest.WithMessage("merged B")) + writeCommit(t, ctx, cfg, repo, gittest.WithBranch(git.DefaultBranch), gittest.WithParents(root, mergedA, mergedB)) + + gittest.WriteCommit(t, cfg, repoPath, gittest.WithBranch("unmerged"), gittest.WithParents(root), gittest.WithMessage("unmerged")) + + return setupData{ + request: &gitalypb.FindAllBranchesRequest{ + Repository: repo, + MergedOnly: true, + MergedBranches: [][]byte{ + []byte("refs/heads/does-not-exist"), + []byte("refs/heads/merged-a"), + []byte("refs/heads/unmerged"), + }, + }, + expectedBranches: []*gitalypb.FindAllBranchesResponse_Branch{ + {Name: []byte("refs/heads/merged-a"), Target: mergedCommitA}, + }, + } }, - expectedErr: testhelper.ToInterceptedMetadata(structerr.NewInvalidArgument( - "%w", storage.NewStorageNotFoundError("fake"), - )), }, } { - t.Run(tc.description, func(t *testing.T) { - ctx := testhelper.Context(t) - c, err := client.FindAllBranches(ctx, tc.request) - require.NoError(t, err) + tc := tc - var recvError error - for recvError == nil { - _, recvError = c.Recv() - } + t.Run(tc.desc, func(t *testing.T) { + t.Parallel() - testhelper.RequireGrpcError(t, tc.expectedErr, recvError) - }) - } -} + setup := tc.setup(t) -func readFindAllBranchesResponsesFromClient(t *testing.T, c gitalypb.RefService_FindAllBranchesClient) (branches []*gitalypb.FindAllBranchesResponse_Branch) { - for { - r, err := c.Recv() - if err == io.EOF { - break - } - require.NoError(t, err) + stream, err := client.FindAllBranches(ctx, setup.request) + require.NoError(t, err) - branches = append(branches, r.GetBranches()...) + branches, err := testhelper.ReceiveAndFold(stream.Recv, func( + result []*gitalypb.FindAllBranchesResponse_Branch, + response *gitalypb.FindAllBranchesResponse, + ) []*gitalypb.FindAllBranchesResponse_Branch { + return append(result, response.GetBranches()...) + }) + testhelper.RequireGrpcError(t, setup.expectedErr, err) + testhelper.ProtoEqual(t, setup.expectedBranches, branches) + }) } - - return } diff --git a/internal/gitaly/service/ref/find_local_branches_test.go b/internal/gitaly/service/ref/find_local_branches_test.go index 5aaba667a..85667317e 100644 --- a/internal/gitaly/service/ref/find_local_branches_test.go +++ b/internal/gitaly/service/ref/find_local_branches_test.go @@ -1,13 +1,13 @@ -//go:build !gitaly_test_sha256 - package ref import ( - "io" + "fmt" "strings" "testing" + "time" "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/gitaly/storage" "gitlab.com/gitlab-org/gitaly/v16/internal/structerr" @@ -15,282 +15,326 @@ import ( "gitlab.com/gitlab-org/gitaly/v16/proto/go/gitalypb" ) -func TestSuccessfulFindLocalBranches(t *testing.T) { +func TestFindLocalBranches(t *testing.T) { t.Parallel() - ctx := testhelper.Context(t) - - _, repo, _, client := setupRefService(t, ctx) - - rpcRequest := &gitalypb.FindLocalBranchesRequest{Repository: repo} - c, err := client.FindLocalBranches(ctx, rpcRequest) - require.NoError(t, err) - - var branches []*gitalypb.Branch - for { - r, err := c.Recv() - if err == io.EOF { - break - } - require.NoError(t, err) - branches = append(branches, r.GetLocalBranches()...) - } - - for name, target := range localBranches { - localBranch := &gitalypb.Branch{ - Name: []byte(name), - TargetCommit: target, - } - assertContainsBranch(t, branches, localBranch) - } -} - -func TestFindLocalBranchesHugeCommitter(t *testing.T) { - t.Parallel() ctx := testhelper.Context(t) + cfg, client := setupRefServiceWithoutRepo(t) - cfg, repo, repoPath, client := setupRefService(t, ctx) - - gittest.WriteCommit(t, cfg, repoPath, - gittest.WithBranch("refs/heads/improve/awesome"), - gittest.WithCommitterName(strings.Repeat("A", 100000)), - ) - - rpcRequest := &gitalypb.FindLocalBranchesRequest{Repository: repo} - - c, err := client.FindLocalBranches(ctx, rpcRequest) - require.NoError(t, err) - - for { - _, err := c.Recv() - if err == io.EOF { - break - } - require.NoError(t, err) + type setupData struct { + request *gitalypb.FindLocalBranchesRequest + expectedErr error + expectedBranches []*gitalypb.Branch } -} -func TestFindLocalBranchesPagination(t *testing.T) { - t.Parallel() - ctx := testhelper.Context(t) - - _, repo, _, client := setupRefService(t, ctx) - - limit := 1 - rpcRequest := &gitalypb.FindLocalBranchesRequest{ - Repository: repo, - PaginationParams: &gitalypb.PaginationParameter{ - Limit: int32(limit), - PageToken: "refs/heads/gitaly/squash-test", + for _, tc := range []struct { + desc string + setup func(t *testing.T) setupData + }{ + { + desc: "empty request", + setup: func(t *testing.T) setupData { + return setupData{ + request: &gitalypb.FindLocalBranchesRequest{}, + expectedErr: structerr.NewInvalidArgument("%w", storage.ErrRepositoryNotSet), + } + }, }, - } - c, err := client.FindLocalBranches(ctx, rpcRequest) - require.NoError(t, err) - - expectedBranch := "refs/heads/improve/awesome" - target := localBranches[expectedBranch] - - var branches []*gitalypb.Branch - for { - r, err := c.Recv() - if err == io.EOF { - break - } - require.NoError(t, err) - branches = append(branches, r.GetLocalBranches()...) - } - - require.Len(t, branches, limit) - - branch := &gitalypb.Branch{ - Name: []byte(expectedBranch), - TargetCommit: target, - } - assertContainsBranch(t, branches, branch) -} - -func TestFindLocalBranchesPaginationSequence(t *testing.T) { - t.Parallel() - ctx := testhelper.Context(t) - - _, repo, _, client := setupRefService(t, ctx) - - limit := 2 - firstRPCRequest := &gitalypb.FindLocalBranchesRequest{ - Repository: repo, - PaginationParams: &gitalypb.PaginationParameter{ - Limit: int32(limit), + { + desc: "missing repository", + setup: func(t *testing.T) setupData { + relativePath := gittest.NewRepositoryName(t) + + return setupData{ + request: &gitalypb.FindLocalBranchesRequest{ + Repository: &gitalypb.Repository{ + StorageName: cfg.Storages[0].Name, + RelativePath: relativePath, + }, + }, + expectedErr: testhelper.ToInterceptedMetadata( + structerr.New("%w", storage.NewRepositoryNotFoundError(cfg.Storages[0].Name, relativePath)), + ), + } + }, }, - } - c, err := client.FindLocalBranches(ctx, firstRPCRequest) - require.NoError(t, err) - - var firstResponseBranches []*gitalypb.Branch - for { - r, err := c.Recv() - if err == io.EOF { - break - } - require.NoError(t, err) - firstResponseBranches = append(firstResponseBranches, r.GetLocalBranches()...) - } - - require.Len(t, firstResponseBranches, limit) - - secondRPCRequest := &gitalypb.FindLocalBranchesRequest{ - Repository: repo, - PaginationParams: &gitalypb.PaginationParameter{ - Limit: 1, - PageToken: string(firstResponseBranches[0].Name), + { + desc: "invalid storage", + setup: func(t *testing.T) setupData { + return setupData{ + request: &gitalypb.FindLocalBranchesRequest{ + Repository: &gitalypb.Repository{ + StorageName: "fake", + RelativePath: "repo", + }, + }, + expectedErr: testhelper.ToInterceptedMetadata(structerr.NewInvalidArgument( + "%w", storage.NewStorageNotFoundError("fake"), + )), + } + }, }, - } - c, err = client.FindLocalBranches(ctx, secondRPCRequest) - require.NoError(t, err) - - var secondResponseBranches []*gitalypb.Branch - for { - r, err := c.Recv() - if err == io.EOF { - break - } - require.NoError(t, err) - secondResponseBranches = append(secondResponseBranches, r.GetLocalBranches()...) - } - - require.Len(t, secondResponseBranches, 1) - require.Equal(t, firstResponseBranches[1], secondResponseBranches[0]) -} - -func TestFindLocalBranchesPaginationWithIncorrectToken(t *testing.T) { - t.Parallel() - ctx := testhelper.Context(t) - - _, repo, _, client := setupRefService(t, ctx) - - limit := 1 - rpcRequest := &gitalypb.FindLocalBranchesRequest{ - Repository: repo, - PaginationParams: &gitalypb.PaginationParameter{ - Limit: int32(limit), - PageToken: "refs/heads/random-unknown-branch", + { + desc: "empty repository", + setup: func(t *testing.T) setupData { + repo, _ := gittest.CreateRepository(t, ctx, cfg) + + return setupData{ + request: &gitalypb.FindLocalBranchesRequest{ + Repository: repo, + }, + } + }, }, - } - c, err := client.FindLocalBranches(ctx, rpcRequest) - require.NoError(t, err) - - _, err = c.Recv() - require.NotEqual(t, err, io.EOF) - testhelper.RequireGrpcError(t, structerr.NewInternal("finding refs: could not find page token"), err) -} - -// Test that `s` contains the elements in `relativeOrder` in that order -// (relative to each other) -func isOrderedSubset(subset, set []string) bool { - subsetIndex := 0 // The string we are currently looking for from `subset` - for _, element := range set { - if element != subset[subsetIndex] { - continue - } - - subsetIndex++ - - if subsetIndex == len(subset) { // We found all elements in that order - return true - } - } - return false -} + { + desc: "only non-branch references", + setup: func(t *testing.T) setupData { + repo, repoPath := gittest.CreateRepository(t, ctx, cfg) + + commitID := gittest.WriteCommit(t, cfg, repoPath) + for _, ref := range []git.ReferenceName{ + "refs/keep-around/kept", + "refs/remotes/origin/remote-branch", + "refs/something", + "refs/tags/v1.0.0", + } { + gittest.WriteRef(t, cfg, repoPath, ref, commitID) + } -func TestFindLocalBranchesSort(t *testing.T) { - t.Parallel() - ctx := testhelper.Context(t) + return setupData{ + request: &gitalypb.FindLocalBranchesRequest{ + Repository: repo, + }, + } + }, + }, + { + desc: "single branch", + setup: func(t *testing.T) setupData { + repo, _ := gittest.CreateRepository(t, ctx, cfg) + _, commit := writeCommit(t, ctx, cfg, repo, gittest.WithBranch("branch")) + + return setupData{ + request: &gitalypb.FindLocalBranchesRequest{ + Repository: repo, + }, + expectedBranches: []*gitalypb.Branch{ + {Name: []byte("refs/heads/branch"), TargetCommit: commit}, + }, + } + }, + }, + { + desc: "many branches", + setup: func(t *testing.T) setupData { + repo, repoPath := gittest.CreateRepository(t, ctx, cfg) + + commitID, commit := writeCommit(t, ctx, cfg, repo) + + var expectedBranches []*gitalypb.Branch + for i := 0; i < 100; i++ { + ref := fmt.Sprintf("refs/heads/branch-%03d", i) + gittest.WriteRef(t, cfg, repoPath, git.ReferenceName(ref), commitID) + expectedBranches = append(expectedBranches, &gitalypb.Branch{ + Name: []byte(ref), TargetCommit: commit, + }) + } - testCases := []struct { - desc string - relativeOrder []string - sortBy gitalypb.FindLocalBranchesRequest_SortBy - }{ + return setupData{ + request: &gitalypb.FindLocalBranchesRequest{ + Repository: repo, + }, + expectedBranches: expectedBranches, + } + }, + }, { - desc: "In ascending order by name", - relativeOrder: []string{"refs/heads/'test'", "refs/heads/100%branch", "refs/heads/improve/awesome", "refs/heads/master"}, - sortBy: gitalypb.FindLocalBranchesRequest_NAME, + desc: "mixed branch and non-branch references", + setup: func(t *testing.T) setupData { + repo, repoPath := gittest.CreateRepository(t, ctx, cfg) + + commitID, commit := writeCommit(t, ctx, cfg, repo, gittest.WithBranch("branch")) + gittest.WriteRef(t, cfg, repoPath, "refs/tags/v1.0.0", commitID) + + return setupData{ + request: &gitalypb.FindLocalBranchesRequest{ + Repository: repo, + }, + expectedBranches: []*gitalypb.Branch{ + {Name: []byte("refs/heads/branch"), TargetCommit: commit}, + }, + } + }, }, { - desc: "In ascending order by commiter date", - relativeOrder: []string{"refs/heads/improve/awesome", "refs/heads/'test'", "refs/heads/100%branch", "refs/heads/master"}, - sortBy: gitalypb.FindLocalBranchesRequest_UPDATED_ASC, + desc: "commit with huge committer name", + setup: func(t *testing.T) setupData { + repo, _ := gittest.CreateRepository(t, ctx, cfg) + + _, commit := writeCommit(t, ctx, cfg, repo, + gittest.WithBranch("branch"), + gittest.WithCommitterName(strings.Repeat("A", 100000)), + ) + + return setupData{ + request: &gitalypb.FindLocalBranchesRequest{ + Repository: repo, + }, + expectedBranches: []*gitalypb.Branch{ + {Name: []byte("refs/heads/branch"), TargetCommit: commit}, + }, + } + }, }, { - desc: "In descending order by commiter date", - relativeOrder: []string{"refs/heads/master", "refs/heads/100%branch", "refs/heads/'test'", "refs/heads/improve/awesome"}, - sortBy: gitalypb.FindLocalBranchesRequest_UPDATED_DESC, + desc: "with pagination limit", + setup: func(t *testing.T) setupData { + repo, _ := gittest.CreateRepository(t, ctx, cfg) + + _, commitA := writeCommit(t, ctx, cfg, repo, gittest.WithBranch("branch-a"), gittest.WithMessage("commit a")) + _, commitB := writeCommit(t, ctx, cfg, repo, gittest.WithBranch("branch-b"), gittest.WithMessage("commit b")) + writeCommit(t, ctx, cfg, repo, gittest.WithBranch("branch-c"), gittest.WithMessage("commit c")) + + return setupData{ + request: &gitalypb.FindLocalBranchesRequest{ + Repository: repo, + PaginationParams: &gitalypb.PaginationParameter{ + Limit: 2, + }, + }, + expectedBranches: []*gitalypb.Branch{ + {Name: []byte("refs/heads/branch-a"), TargetCommit: commitA}, + {Name: []byte("refs/heads/branch-b"), TargetCommit: commitB}, + }, + } + }, }, - } - - _, repo, _, client := setupRefService(t, ctx) - - for _, testCase := range testCases { - t.Run(testCase.desc, func(t *testing.T) { - rpcRequest := &gitalypb.FindLocalBranchesRequest{Repository: repo, SortBy: testCase.sortBy} - - c, err := client.FindLocalBranches(ctx, rpcRequest) - require.NoError(t, err) - - var branches []string - for { - r, err := c.Recv() - if err == io.EOF { - break + { + desc: "with pagination limit and page token", + setup: func(t *testing.T) setupData { + repo, _ := gittest.CreateRepository(t, ctx, cfg) + + writeCommit(t, ctx, cfg, repo, gittest.WithBranch("branch-a"), gittest.WithMessage("commit a")) + _, commitB := writeCommit(t, ctx, cfg, repo, gittest.WithBranch("branch-b"), gittest.WithMessage("commit b")) + writeCommit(t, ctx, cfg, repo, gittest.WithBranch("branch-c"), gittest.WithMessage("commit c")) + + return setupData{ + request: &gitalypb.FindLocalBranchesRequest{ + Repository: repo, + PaginationParams: &gitalypb.PaginationParameter{ + Limit: 1, + PageToken: "refs/heads/branch-a", + }, + }, + expectedBranches: []*gitalypb.Branch{ + {Name: []byte("refs/heads/branch-b"), TargetCommit: commitB}, + }, } - require.NoError(t, err) - - for _, branch := range r.GetLocalBranches() { - branches = append(branches, string(branch.Name)) + }, + }, + { + desc: "invalid page token", + setup: func(t *testing.T) setupData { + repo, _ := gittest.CreateRepository(t, ctx, cfg) + + writeCommit(t, ctx, cfg, repo, gittest.WithBranch("branch-a"), gittest.WithMessage("commit a")) + + return setupData{ + request: &gitalypb.FindLocalBranchesRequest{ + Repository: repo, + PaginationParams: &gitalypb.PaginationParameter{ + PageToken: "refs/heads/does-not-exist", + }, + }, + expectedErr: structerr.NewInternal("finding refs: could not find page token"), } - } - - if !isOrderedSubset(testCase.relativeOrder, branches) { - t.Fatalf("%s: Expected branches to have relative order %v; got them as %v", testCase.desc, testCase.relativeOrder, branches) - } - }) - } -} - -func TestFindLocalBranches_validate(t *testing.T) { - t.Parallel() - ctx := testhelper.Context(t) - - cfg, repo, _, client := setupRefService(t, ctx) - for _, tc := range []struct { - desc string - repo *gitalypb.Repository - expectedErr error - }{ + }, + }, { - desc: "repository not provided", - repo: nil, - expectedErr: structerr.NewInvalidArgument("%w", storage.ErrRepositoryNotSet), + desc: "sort by ascending name", + setup: func(t *testing.T) setupData { + repo, _ := gittest.CreateRepository(t, ctx, cfg) + + _, commitA := writeCommit(t, ctx, cfg, repo, gittest.WithBranch("branch-a"), gittest.WithCommitterDate(time.Date(2020, 1, 1, 1, 1, 1, 1, time.UTC))) + _, commitB := writeCommit(t, ctx, cfg, repo, gittest.WithBranch("branch-b"), gittest.WithCommitterDate(time.Date(2010, 1, 1, 1, 1, 1, 1, time.UTC))) + _, commitC := writeCommit(t, ctx, cfg, repo, gittest.WithBranch("branch-c"), gittest.WithCommitterDate(time.Date(2030, 1, 1, 1, 1, 1, 1, time.UTC))) + + return setupData{ + request: &gitalypb.FindLocalBranchesRequest{ + Repository: repo, + SortBy: gitalypb.FindLocalBranchesRequest_NAME, + }, + expectedBranches: []*gitalypb.Branch{ + {Name: []byte("refs/heads/branch-a"), TargetCommit: commitA}, + {Name: []byte("refs/heads/branch-b"), TargetCommit: commitB}, + {Name: []byte("refs/heads/branch-c"), TargetCommit: commitC}, + }, + } + }, }, { - desc: "repository doesn't exist on disk", - repo: &gitalypb.Repository{StorageName: cfg.Storages[0].Name, RelativePath: "made/up/path"}, - expectedErr: testhelper.ToInterceptedMetadata( - structerr.New("%w", storage.NewRepositoryNotFoundError(cfg.Storages[0].Name, "made/up/path")), - ), + desc: "sort by ascending committer date", + setup: func(t *testing.T) setupData { + repo, _ := gittest.CreateRepository(t, ctx, cfg) + + _, commitA := writeCommit(t, ctx, cfg, repo, gittest.WithBranch("branch-a"), gittest.WithCommitterDate(time.Date(2020, 1, 1, 1, 1, 1, 1, time.UTC))) + _, commitB := writeCommit(t, ctx, cfg, repo, gittest.WithBranch("branch-b"), gittest.WithCommitterDate(time.Date(2010, 1, 1, 1, 1, 1, 1, time.UTC))) + _, commitC := writeCommit(t, ctx, cfg, repo, gittest.WithBranch("branch-c"), gittest.WithCommitterDate(time.Date(2030, 1, 1, 1, 1, 1, 1, time.UTC))) + + return setupData{ + request: &gitalypb.FindLocalBranchesRequest{ + Repository: repo, + SortBy: gitalypb.FindLocalBranchesRequest_UPDATED_ASC, + }, + expectedBranches: []*gitalypb.Branch{ + {Name: []byte("refs/heads/branch-b"), TargetCommit: commitB}, + {Name: []byte("refs/heads/branch-a"), TargetCommit: commitA}, + {Name: []byte("refs/heads/branch-c"), TargetCommit: commitC}, + }, + } + }, }, { - desc: "unknown storage", - repo: &gitalypb.Repository{StorageName: "invalid", RelativePath: repo.GetRelativePath()}, - expectedErr: testhelper.ToInterceptedMetadata(structerr.NewInvalidArgument( - "%w", storage.NewStorageNotFoundError("invalid"), - )), + desc: "sort by descending committer date", + setup: func(t *testing.T) setupData { + repo, _ := gittest.CreateRepository(t, ctx, cfg) + + _, commitA := writeCommit(t, ctx, cfg, repo, gittest.WithBranch("branch-a"), gittest.WithCommitterDate(time.Date(2020, 1, 1, 1, 1, 1, 1, time.UTC))) + _, commitB := writeCommit(t, ctx, cfg, repo, gittest.WithBranch("branch-b"), gittest.WithCommitterDate(time.Date(2010, 1, 1, 1, 1, 1, 1, time.UTC))) + _, commitC := writeCommit(t, ctx, cfg, repo, gittest.WithBranch("branch-c"), gittest.WithCommitterDate(time.Date(2030, 1, 1, 1, 1, 1, 1, time.UTC))) + + return setupData{ + request: &gitalypb.FindLocalBranchesRequest{ + Repository: repo, + SortBy: gitalypb.FindLocalBranchesRequest_UPDATED_DESC, + }, + expectedBranches: []*gitalypb.Branch{ + {Name: []byte("refs/heads/branch-c"), TargetCommit: commitC}, + {Name: []byte("refs/heads/branch-a"), TargetCommit: commitA}, + {Name: []byte("refs/heads/branch-b"), TargetCommit: commitB}, + }, + } + }, }, } { + tc := tc + t.Run(tc.desc, func(t *testing.T) { - stream, err := client.FindLocalBranches(ctx, &gitalypb.FindLocalBranchesRequest{Repository: tc.repo}) + t.Parallel() + + setup := tc.setup(t) + + stream, err := client.FindLocalBranches(ctx, setup.request) require.NoError(t, err) - _, err = stream.Recv() - testhelper.RequireGrpcError(t, tc.expectedErr, err) + + branches, err := testhelper.ReceiveAndFold(stream.Recv, func( + result []*gitalypb.Branch, + response *gitalypb.FindLocalBranchesResponse, + ) []*gitalypb.Branch { + return append(result, response.GetLocalBranches()...) + }) + testhelper.RequireGrpcError(t, setup.expectedErr, err) + testhelper.ProtoEqual(t, setup.expectedBranches, branches) }) } } diff --git a/internal/gitaly/service/ref/find_tag_test.go b/internal/gitaly/service/ref/find_tag_test.go index 41e78affd..3f8126248 100644 --- a/internal/gitaly/service/ref/find_tag_test.go +++ b/internal/gitaly/service/ref/find_tag_test.go @@ -1,336 +1,362 @@ -//go:build !gitaly_test_sha256 - package ref import ( "fmt" "strings" "testing" + "time" "github.com/stretchr/testify/require" - "gitlab.com/gitlab-org/gitaly/v16/internal/git" - "gitlab.com/gitlab-org/gitaly/v16/internal/git/catfile" "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/git/updateref" "gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/storage" "gitlab.com/gitlab-org/gitaly/v16/internal/helper" + "gitlab.com/gitlab-org/gitaly/v16/internal/helper/text" "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" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" "google.golang.org/protobuf/types/known/timestamppb" ) -func TestFindTag_successful(t *testing.T) { +func TestFindTag(t *testing.T) { t.Parallel() ctx := testhelper.Context(t) - cfg, repoProto, repoPath, client := setupRefService(t, ctx) - - repo := localrepo.NewTestRepo(t, cfg, repoProto) - - blobID := git.ObjectID("faaf198af3a36dbf41961466703cc1d47c61d051") - commitID := git.ObjectID("6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9") - - gitCommit := testhelper.GitLabTestCommit(commitID.String()) - - bigCommitID := gittest.WriteCommit(t, cfg, repoPath, - gittest.WithBranch("local-big-commits"), - gittest.WithMessage("An empty commit with REALLY BIG message\n\n"+strings.Repeat("a", helper.MaxCommitOrTagMessageSize+1)), - gittest.WithParents("60ecb67744cb56576c30214ff52294f8ce2def98"), - ) - bigCommit, err := repo.ReadCommit(ctx, git.Revision(bigCommitID)) - require.NoError(t, err) - - annotatedTagID := gittest.WriteTag(t, cfg, repoPath, "v1.2.0", blobID.Revision(), gittest.WriteTagConfig{Message: "Blob tag"}) - - gittest.WriteTag(t, cfg, repoPath, "v1.3.0", commitID.Revision()) - gittest.WriteTag(t, cfg, repoPath, "v1.4.0", blobID.Revision()) - - // To test recursive resolving to a commit - gittest.WriteTag(t, cfg, repoPath, "v1.5.0", "v1.3.0") - - // A tag to commit with a big message - gittest.WriteTag(t, cfg, repoPath, "v1.6.0", bigCommitID.Revision()) - - // A tag with a big message - bigMessage := strings.Repeat("a", 11*1024) - bigMessageTag1ID := gittest.WriteTag(t, cfg, repoPath, "v1.7.0", commitID.Revision(), gittest.WriteTagConfig{Message: bigMessage}) - - // A tag with a commit id as its name - commitTagID := gittest.WriteTag(t, cfg, repoPath, commitID.String(), commitID.Revision(), gittest.WriteTagConfig{Message: "commit tag with a commit sha as the name"}) + cfg, client := setupRefServiceWithoutRepo(t) - // a tag of a tag - tagOfTagID := gittest.WriteTag(t, cfg, repoPath, "tag-of-tag", commitTagID.Revision(), gittest.WriteTagConfig{Message: "tag of a tag"}) + type setupData struct { + request *gitalypb.FindTagRequest + expectedErr error + expectedTag *gitalypb.Tag + } - expectedTags := []*gitalypb.Tag{ - { - Name: []byte(commitID), - Id: commitTagID.String(), - TargetCommit: gitCommit, - Message: []byte("commit tag with a commit sha as the name"), - MessageSize: 40, - Tagger: gittest.DefaultCommitAuthor, - }, - { - Name: []byte("tag-of-tag"), - Id: tagOfTagID.String(), - TargetCommit: gitCommit, - Message: []byte("tag of a tag"), - MessageSize: 12, - Tagger: gittest.DefaultCommitAuthor, - }, + for _, tc := range []struct { + desc string + setup func(t *testing.T) setupData + }{ { - Name: []byte("v1.0.0"), - Id: "f4e6814c3e4e7a0de82a9e7cd20c626cc963a2f8", - TargetCommit: gitCommit, - Message: []byte("Release"), - MessageSize: 7, - Tagger: &gitalypb.CommitAuthor{ - Name: []byte("Dmitriy Zaporozhets"), - Email: []byte("dmitriy.zaporozhets@gmail.com"), - Date: ×tamppb.Timestamp{Seconds: 1393491299}, - Timezone: []byte("+0200"), + desc: "empty request", + setup: func(t *testing.T) setupData { + return setupData{ + request: &gitalypb.FindTagRequest{}, + expectedErr: structerr.NewInvalidArgument("%w", storage.ErrRepositoryNotSet), + } }, - SignatureType: gitalypb.SignatureType_NONE, }, { - Name: []byte("v1.1.0"), - Id: "8a2a6eb295bb170b34c24c76c49ed0e9b2eaf34b", - TargetCommit: testhelper.GitLabTestCommit("5937ac0a7beb003549fc5fd26fc247adbce4a52e"), - Message: []byte("Version 1.1.0"), - MessageSize: 13, - Tagger: &gitalypb.CommitAuthor{ - Name: []byte("Dmitriy Zaporozhets"), - Email: []byte("dmitriy.zaporozhets@gmail.com"), - Date: ×tamppb.Timestamp{Seconds: 1393505709}, - Timezone: []byte("+0200"), + desc: "invalid repo", + setup: func(t *testing.T) setupData { + return setupData{ + request: &gitalypb.FindTagRequest{ + Repository: &gitalypb.Repository{ + StorageName: "fake", + RelativePath: "repo", + }, + }, + expectedErr: testhelper.ToInterceptedMetadata(structerr.NewInvalidArgument( + "%w", storage.NewStorageNotFoundError("fake"), + )), + } }, }, { - Name: []byte("v1.1.1"), - Id: "8f03acbcd11c53d9c9468078f32a2622005a4841", - TargetCommit: testhelper.GitLabTestCommit("189a6c924013fc3fe40d6f1ec1dc20214183bc97"), - Message: []byte("x509 signed tag\n-----BEGIN SIGNED MESSAGE-----\nMIISfwYJKoZIhvcNAQcCoIIScDCCEmwCAQExDTALBglghkgBZQMEAgEwCwYJKoZI\nhvcNAQcBoIIP8zCCB3QwggVcoAMCAQICBBXXLOIwDQYJKoZIhvcNAQELBQAwgbYx\nCzAJBgNVBAYTAkRFMQ8wDQYDVQQIDAZCYXllcm4xETAPBgNVBAcMCE11ZW5jaGVu\nMRAwDgYDVQQKDAdTaWVtZW5zMREwDwYDVQQFEwhaWlpaWlpBNjEdMBsGA1UECwwU\nU2llbWVucyBUcnVzdCBDZW50ZXIxPzA9BgNVBAMMNlNpZW1lbnMgSXNzdWluZyBD\nQSBNZWRpdW0gU3RyZW5ndGggQXV0aGVudGljYXRpb24gMjAxNjAeFw0xNzAyMDMw\nNjU4MzNaFw0yMDAyMDMwNjU4MzNaMFsxETAPBgNVBAUTCFowMDBOV0RIMQ4wDAYD\nVQQqDAVSb2dlcjEOMAwGA1UEBAwFTWVpZXIxEDAOBgNVBAoMB1NpZW1lbnMxFDAS\nBgNVBAMMC01laWVyIFJvZ2VyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC\nAQEAuBNea/68ZCnHYQjpm/k3ZBG0wBpEKSwG6lk9CEQlSxsqVLQHAoAKBIlJm1in\nYVLcK/Sq1yhYJ/qWcY/M53DhK2rpPuhtrWJUdOUy8EBWO20F4bd4Fw9pO7jt8bme\nu33TSrK772vKjuppzB6SeG13Cs08H+BIeD106G27h7ufsO00pvsxoSDL+uc4slnr\npBL+2TAL7nSFnB9QHWmRIK27SPqJE+lESdb0pse11x1wjvqKy2Q7EjL9fpqJdHzX\nNLKHXd2r024TOORTa05DFTNR+kQEKKV96XfpYdtSBomXNQ44cisiPBJjFtYvfnFE\nwgrHa8fogn/b0C+A+HAoICN12wIDAQABo4IC4jCCAt4wHQYDVR0OBBYEFCF+gkUp\nXQ6xGc0kRWXuDFxzA14zMEMGA1UdEQQ8MDqgIwYKKwYBBAGCNxQCA6AVDBNyLm1l\naWVyQHNpZW1lbnMuY29tgRNyLm1laWVyQHNpZW1lbnMuY29tMA4GA1UdDwEB/wQE\nAwIHgDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwQwgcoGA1UdHwSBwjCB\nvzCBvKCBuaCBtoYmaHR0cDovL2NoLnNpZW1lbnMuY29tL3BraT9aWlpaWlpBNi5j\ncmyGQWxkYXA6Ly9jbC5zaWVtZW5zLm5ldC9DTj1aWlpaWlpBNixMPVBLST9jZXJ0\naWZpY2F0ZVJldm9jYXRpb25MaXN0hklsZGFwOi8vY2wuc2llbWVucy5jb20vQ049\nWlpaWlpaQTYsbz1UcnVzdGNlbnRlcj9jZXJ0aWZpY2F0ZVJldm9jYXRpb25MaXN0\nMEUGA1UdIAQ+MDwwOgYNKwYBBAGhaQcCAgMBAzApMCcGCCsGAQUFBwIBFhtodHRw\nOi8vd3d3LnNpZW1lbnMuY29tL3BraS8wDAYDVR0TAQH/BAIwADAfBgNVHSMEGDAW\ngBT4FV1HDGx3e3LEAheRaKK292oJRDCCAQQGCCsGAQUFBwEBBIH3MIH0MDIGCCsG\nAQUFBzAChiZodHRwOi8vYWguc2llbWVucy5jb20vcGtpP1paWlpaWkE2LmNydDBB\nBggrBgEFBQcwAoY1bGRhcDovL2FsLnNpZW1lbnMubmV0L0NOPVpaWlpaWkE2LEw9\nUEtJP2NBQ2VydGlmaWNhdGUwSQYIKwYBBQUHMAKGPWxkYXA6Ly9hbC5zaWVtZW5z\nLmNvbS9DTj1aWlpaWlpBNixvPVRydXN0Y2VudGVyP2NBQ2VydGlmaWNhdGUwMAYI\nKwYBBQUHMAGGJGh0dHA6Ly9vY3NwLnBraS1zZXJ2aWNlcy5zaWVtZW5zLmNvbTAN\nBgkqhkiG9w0BAQsFAAOCAgEAXPVcX6vaEcszJqg5IemF9aFTlwTrX5ITNIpzcqG+\nkD5haOf2mZYLjl+MKtLC1XfmIsGCUZNb8bjP6QHQEI+2d6x/ZOqPq7Kd7PwVu6x6\nxZrkDjUyhUbUntT5+RBy++l3Wf6Cq6Kx+K8ambHBP/bu90/p2U8KfFAG3Kr2gI2q\nfZrnNMOxmJfZ3/sXxssgLkhbZ7hRa+MpLfQ6uFsSiat3vlawBBvTyHnoZ/7oRc8y\nqi6QzWcd76CPpMElYWibl+hJzKbBZUWvc71AzHR6i1QeZ6wubYz7vr+FF5Y7tnxB\nVz6omPC9XAg0F+Dla6Zlz3Awj5imCzVXa+9SjtnsidmJdLcKzTAKyDewewoxYOOJ\nj3cJU7VSjJPl+2fVmDBaQwcNcUcu/TPAKApkegqO7tRF9IPhjhW8QkRnkqMetO3D\nOXmAFVIsEI0Hvb2cdb7B6jSpjGUuhaFm9TCKhQtCk2p8JCDTuaENLm1x34rrJKbT\n2vzyYN0CZtSkUdgD4yQxK9VWXGEzexRisWb4AnZjD2NAquLPpXmw8N0UwFD7MSpC\ndpaX7FktdvZmMXsnGiAdtLSbBgLVWOD1gmJFDjrhNbI8NOaOaNk4jrfGqNh5lhGU\n4DnBT2U6Cie1anLmFH/oZooAEXR2o3Nu+1mNDJChnJp0ovs08aa3zZvBdcloOvfU\nqdowggh3MIIGX6ADAgECAgQtyi/nMA0GCSqGSIb3DQEBCwUAMIGZMQswCQYDVQQG\nEwJERTEPMA0GA1UECAwGQmF5ZXJuMREwDwYDVQQHDAhNdWVuY2hlbjEQMA4GA1UE\nCgwHU2llbWVuczERMA8GA1UEBRMIWlpaWlpaQTExHTAbBgNVBAsMFFNpZW1lbnMg\nVHJ1c3QgQ2VudGVyMSIwIAYDVQQDDBlTaWVtZW5zIFJvb3QgQ0EgVjMuMCAyMDE2\nMB4XDTE2MDcyMDEzNDYxMFoXDTIyMDcyMDEzNDYxMFowgbYxCzAJBgNVBAYTAkRF\nMQ8wDQYDVQQIDAZCYXllcm4xETAPBgNVBAcMCE11ZW5jaGVuMRAwDgYDVQQKDAdT\naWVtZW5zMREwDwYDVQQFEwhaWlpaWlpBNjEdMBsGA1UECwwUU2llbWVucyBUcnVz\ndCBDZW50ZXIxPzA9BgNVBAMMNlNpZW1lbnMgSXNzdWluZyBDQSBNZWRpdW0gU3Ry\nZW5ndGggQXV0aGVudGljYXRpb24gMjAxNjCCAiIwDQYJKoZIhvcNAQEBBQADggIP\nADCCAgoCggIBAL9UfK+JAZEqVMVvECdYF9IK4KSw34AqyNl3rYP5x03dtmKaNu+2\n0fQqNESA1NGzw3s6LmrKLh1cR991nB2cvKOXu7AvEGpSuxzIcOROd4NpvRx+Ej1p\nJIPeqf+ScmVK7lMSO8QL/QzjHOpGV3is9sG+ZIxOW9U1ESooy4Hal6ZNs4DNItsz\npiCKqm6G3et4r2WqCy2RRuSqvnmMza7Y8BZsLy0ZVo5teObQ37E/FxqSrbDI8nxn\nB7nVUve5ZjrqoIGSkEOtyo11003dVO1vmWB9A0WQGDqE/q3w178hGhKfxzRaqzyi\nSoADUYS2sD/CglGTUxVq6u0pGLLsCFjItcCWqW+T9fPYfJ2CEd5b3hvqdCn+pXjZ\n/gdX1XAcdUF5lRnGWifaYpT9n4s4adzX8q6oHSJxTppuAwLRKH6eXALbGQ1I9lGQ\nDSOipD/09xkEsPw6HOepmf2U3YxZK1VU2sHqugFJboeLcHMzp6E1n2ctlNG1GKE9\nFDHmdyFzDi0Nnxtf/GgVjnHF68hByEE1MYdJ4nJLuxoT9hyjYdRW9MpeNNxxZnmz\nW3zh7QxIqP0ZfIz6XVhzrI9uZiqwwojDiM5tEOUkQ7XyW6grNXe75yt6mTj89LlB\nH5fOW2RNmCy/jzBXDjgyskgK7kuCvUYTuRv8ITXbBY5axFA+CpxZqokpAgMBAAGj\nggKmMIICojCCAQUGCCsGAQUFBwEBBIH4MIH1MEEGCCsGAQUFBzAChjVsZGFwOi8v\nYWwuc2llbWVucy5uZXQvQ049WlpaWlpaQTEsTD1QS0k/Y0FDZXJ0aWZpY2F0ZTAy\nBggrBgEFBQcwAoYmaHR0cDovL2FoLnNpZW1lbnMuY29tL3BraT9aWlpaWlpBMS5j\ncnQwSgYIKwYBBQUHMAKGPmxkYXA6Ly9hbC5zaWVtZW5zLmNvbS91aWQ9WlpaWlpa\nQTEsbz1UcnVzdGNlbnRlcj9jQUNlcnRpZmljYXRlMDAGCCsGAQUFBzABhiRodHRw\nOi8vb2NzcC5wa2ktc2VydmljZXMuc2llbWVucy5jb20wHwYDVR0jBBgwFoAUcG2g\nUOyp0CxnnRkV/v0EczXD4tQwEgYDVR0TAQH/BAgwBgEB/wIBADBABgNVHSAEOTA3\nMDUGCCsGAQQBoWkHMCkwJwYIKwYBBQUHAgEWG2h0dHA6Ly93d3cuc2llbWVucy5j\nb20vcGtpLzCBxwYDVR0fBIG/MIG8MIG5oIG2oIGzhj9sZGFwOi8vY2wuc2llbWVu\ncy5uZXQvQ049WlpaWlpaQTEsTD1QS0k/YXV0aG9yaXR5UmV2b2NhdGlvbkxpc3SG\nJmh0dHA6Ly9jaC5zaWVtZW5zLmNvbS9wa2k/WlpaWlpaQTEuY3JshkhsZGFwOi8v\nY2wuc2llbWVucy5jb20vdWlkPVpaWlpaWkExLG89VHJ1c3RjZW50ZXI/YXV0aG9y\naXR5UmV2b2NhdGlvbkxpc3QwJwYDVR0lBCAwHgYIKwYBBQUHAwIGCCsGAQUFBwME\nBggrBgEFBQcDCTAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFPgVXUcMbHd7csQC\nF5Foorb3aglEMA0GCSqGSIb3DQEBCwUAA4ICAQBw+sqMp3SS7DVKcILEmXbdRAg3\nlLO1r457KY+YgCT9uX4VG5EdRKcGfWXK6VHGCi4Dos5eXFV34Mq/p8nu1sqMuoGP\nYjHn604eWDprhGy6GrTYdxzcE/GGHkpkuE3Ir/45UcmZlOU41SJ9SNjuIVrSHMOf\nccSY42BCspR/Q1Z/ykmIqQecdT3/Kkx02GzzSN2+HlW6cEO4GBW5RMqsvd2n0h2d\nfe2zcqOgkLtx7u2JCR/U77zfyxG3qXtcymoz0wgSHcsKIl+GUjITLkHfS9Op8V7C\nGr/dX437sIg5pVHmEAWadjkIzqdHux+EF94Z6kaHywohc1xG0KvPYPX7iSNjkvhz\n4NY53DHmxl4YEMLffZnaS/dqyhe1GTpcpyN8WiR4KuPfxrkVDOsuzWFtMSvNdlOV\ngdI0MXcLMP+EOeANZWX6lGgJ3vWyemo58nzgshKd24MY3w3i6masUkxJH2KvI7UH\n/1Db3SC8oOUjInvSRej6M3ZhYWgugm6gbpUgFoDw/o9Cg6Qm71hY0JtcaPC13rzm\nN8a2Br0+Fa5e2VhwLmAxyfe1JKzqPwuHT0S5u05SQghL5VdzqfA8FCL/j4XC9yI6\ncsZTAQi73xFQYVjZt3+aoSz84lOlTmVo/jgvGMY/JzH9I4mETGgAJRNj34Z/0meh\nM+pKWCojNH/dgyJSwDGCAlIwggJOAgEBMIG/MIG2MQswCQYDVQQGEwJERTEPMA0G\nA1UECAwGQmF5ZXJuMREwDwYDVQQHDAhNdWVuY2hlbjEQMA4GA1UECgwHU2llbWVu\nczERMA8GA1UEBRMIWlpaWlpaQTYxHTAbBgNVBAsMFFNpZW1lbnMgVHJ1c3QgQ2Vu\ndGVyMT8wPQYDVQQDDDZTaWVtZW5zIElzc3VpbmcgQ0EgTWVkaXVtIFN0cmVuZ3Ro\nIEF1dGhlbnRpY2F0aW9uIDIwMTYCBBXXLOIwCwYJYIZIAWUDBAIBoGkwHAYJKoZI\nhvcNAQkFMQ8XDTE5MTEyMDE0NTYyMFowLwYJKoZIhvcNAQkEMSIEIJDnZUpcVLzC\nOdtpkH8gtxwLPIDE0NmAmFC9uM8q2z+OMBgGCSqGSIb3DQEJAzELBgkqhkiG9w0B\nBwEwCwYJKoZIhvcNAQEBBIIBAH/Pqv2xp3a0jSPkwU1K3eGA/1lfoNJMUny4d/PS\nLVWlkgrmedXdLmuBzAGEaaZOJS0lEpNd01pR/reHs7xxZ+RZ0olTs2ufM0CijQSx\nOL9HDl2O3OoD77NWx4tl3Wy1yJCeV3XH/cEI7AkKHCmKY9QMoMYWh16ORBtr+YcS\nYK+gONOjpjgcgTJgZ3HSFgQ50xiD4WT1kFBHsuYsLqaOSbTfTN6Ayyg4edjrPQqa\nVcVf1OQcIrfWA3yMQrnEZfOYfN/D4EPjTfxBV+VCi/F2bdZmMbJ7jNk1FbewSwWO\nSDH1i0K32NyFbnh0BSos7njq7ELqKlYBsoB/sZfaH2vKy5U=\n-----END SIGNED MESSAGE-----"), - MessageSize: 6494, - Tagger: &gitalypb.CommitAuthor{ - Name: []byte("Roger Meier"), - Email: []byte("r.meier@siemens.com"), - Date: ×tamppb.Timestamp{Seconds: 1574261780}, - Timezone: []byte("+0100"), + desc: "empty tag name", + setup: func(t *testing.T) setupData { + repo, _ := gittest.CreateRepository(t, ctx, cfg) + + return setupData{ + request: &gitalypb.FindTagRequest{ + Repository: repo, + }, + expectedErr: structerr.NewInvalidArgument("tag name is empty"), + } }, - SignatureType: gitalypb.SignatureType_X509, }, { - Name: []byte("v1.2.0"), - Id: annotatedTagID.String(), - Message: []byte("Blob tag"), - MessageSize: 8, - Tagger: gittest.DefaultCommitAuthor, - }, - { - Name: []byte("v1.3.0"), - Id: commitID.String(), - TargetCommit: gitCommit, - }, - { - Name: []byte("v1.4.0"), - Id: blobID.String(), + desc: "nonexistent tag", + setup: func(t *testing.T) setupData { + repo, _ := gittest.CreateRepository(t, ctx, cfg) + + return setupData{ + request: &gitalypb.FindTagRequest{ + Repository: repo, + TagName: []byte("does-not-exist"), + }, + expectedErr: structerr.NewNotFound("tag does not exist").WithDetail( + &gitalypb.FindTagError{ + Error: &gitalypb.FindTagError_TagNotFound{ + TagNotFound: &gitalypb.ReferenceNotFoundError{ + ReferenceName: []byte("refs/tags/does-not-exist"), + }, + }, + }, + ), + } + }, }, { - Name: []byte("v1.5.0"), - Id: commitID.String(), - TargetCommit: gitCommit, + desc: "lightweight tag", + setup: func(t *testing.T) setupData { + repo, repoPath := gittest.CreateRepository(t, ctx, cfg) + + commitID, commit := writeCommit(t, ctx, cfg, repo) + tagID := gittest.WriteTag(t, cfg, repoPath, commitID.String(), commitID.Revision()) + + return setupData{ + request: &gitalypb.FindTagRequest{ + Repository: repo, + TagName: []byte(commitID), + }, + expectedTag: &gitalypb.Tag{ + Name: []byte(commitID), + Id: tagID.String(), + TargetCommit: commit, + }, + } + }, }, { - Name: []byte("v1.6.0"), - Id: bigCommitID.String(), - TargetCommit: bigCommit, + desc: "annotated tag", + setup: func(t *testing.T) setupData { + repo, repoPath := gittest.CreateRepository(t, ctx, cfg) + + commitID, commit := writeCommit(t, ctx, cfg, repo) + tagID := gittest.WriteTag(t, cfg, repoPath, commitID.String(), commitID.Revision(), gittest.WriteTagConfig{ + Message: "annotated", + }) + + return setupData{ + request: &gitalypb.FindTagRequest{ + Repository: repo, + TagName: []byte(commitID), + }, + expectedTag: &gitalypb.Tag{ + Name: []byte(commitID), + Id: tagID.String(), + TargetCommit: commit, + Message: []byte("annotated"), + MessageSize: 9, + Tagger: gittest.DefaultCommitAuthor, + }, + } + }, }, { - Name: []byte("v1.7.0"), - Id: bigMessageTag1ID.String(), - Message: []byte(bigMessage[:helper.MaxCommitOrTagMessageSize]), - MessageSize: int64(len(bigMessage)), - TargetCommit: gitCommit, - Tagger: gittest.DefaultCommitAuthor, - }, - } - - for _, expectedTag := range expectedTags { - rpcRequest := &gitalypb.FindTagRequest{Repository: repoProto, TagName: expectedTag.Name} - - resp, err := client.FindTag(ctx, rpcRequest) - require.NoError(t, err) - - testhelper.ProtoEqual(t, expectedTag, resp.GetTag()) - } -} - -func TestFindTag_nestedTag(t *testing.T) { - t.Parallel() - - ctx := testhelper.Context(t) - cfg, repoProto, repoPath, client := setupRefService(t, ctx) - - repo := localrepo.NewTestRepo(t, cfg, repoProto) - - blobID := git.ObjectID("faaf198af3a36dbf41961466703cc1d47c61d051") - commitID := git.ObjectID("6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9") - - testCases := []struct { - description string - depth int - originalOid git.ObjectID - }{ - { - description: "nested 1 deep, points to a commit", - depth: 1, - originalOid: commitID, + desc: "tag pointing to blob", + setup: func(t *testing.T) setupData { + repo, repoPath := gittest.CreateRepository(t, ctx, cfg) + + blobID := gittest.WriteBlob(t, cfg, repoPath, []byte("tagged data")) + tagID := gittest.WriteTag(t, cfg, repoPath, "tagged-blob", blobID.Revision(), gittest.WriteTagConfig{ + Message: "annotated", + }) + + return setupData{ + request: &gitalypb.FindTagRequest{ + Repository: repo, + TagName: []byte("tagged-blob"), + }, + expectedTag: &gitalypb.Tag{ + Name: []byte("tagged-blob"), + Id: tagID.String(), + Message: []byte("annotated"), + MessageSize: 9, + Tagger: gittest.DefaultCommitAuthor, + }, + } + }, }, { - description: "nested 4 deep, points to a commit", - depth: 4, - originalOid: commitID, + desc: "deeply nested tag", + setup: func(t *testing.T) setupData { + repo, repoPath := gittest.CreateRepository(t, ctx, cfg) + + commitID, commit := writeCommit(t, ctx, cfg, repo) + + currentID := commitID + for i := 0; i < 20; i++ { + tagName := fmt.Sprintf("tag-%d", i) + currentID = gittest.WriteTag(t, cfg, repoPath, tagName, currentID.Revision(), gittest.WriteTagConfig{ + Message: tagName, + }) + } + + return setupData{ + request: &gitalypb.FindTagRequest{ + Repository: repo, + TagName: []byte("tag-19"), + }, + expectedTag: &gitalypb.Tag{ + Name: []byte("tag-19"), + Id: currentID.String(), + TargetCommit: commit, + Message: []byte("tag-19"), + MessageSize: 6, + Tagger: gittest.DefaultCommitAuthor, + }, + } + }, }, { - description: "nested 3 deep, points to a blob", - depth: 3, - originalOid: blobID, + desc: "tag with commit ID as name", + setup: func(t *testing.T) setupData { + repo, repoPath := gittest.CreateRepository(t, ctx, cfg) + + commitID, commit := writeCommit(t, ctx, cfg, repo) + tagID := gittest.WriteTag(t, cfg, repoPath, commitID.String(), commitID.Revision(), gittest.WriteTagConfig{ + Message: "message\n", + }) + + return setupData{ + request: &gitalypb.FindTagRequest{ + Repository: repo, + TagName: []byte(commitID), + }, + expectedTag: &gitalypb.Tag{ + Name: []byte(commitID), + Id: tagID.String(), + TargetCommit: commit, + Message: []byte("message"), + MessageSize: 7, + Tagger: gittest.DefaultCommitAuthor, + }, + } + }, }, { - description: "nested 20 deep, points to a commit", - depth: 20, - originalOid: commitID, - }, - } - - for _, tc := range testCases { - t.Run(tc.description, func(t *testing.T) { - tags, err := repo.GetReferences(ctx, "refs/tags/") - require.NoError(t, err) - - updater, err := updateref.New(ctx, repo) - require.NoError(t, err) - defer testhelper.MustClose(t, updater) - - require.NoError(t, updater.Start()) - for _, tag := range tags { - require.NoError(t, updater.Delete(tag.Name)) - } - require.NoError(t, updater.Commit()) - - catfileCache := catfile.NewCache(cfg) - defer catfileCache.Stop() - - objectReader, cancel, err := catfileCache.ObjectReader(ctx, repo) - require.NoError(t, err) - defer cancel() - - objectInfoReader, cancel, err := catfileCache.ObjectInfoReader(ctx, repo) - require.NoError(t, err) - defer cancel() - - info, err := objectInfoReader.Info(ctx, git.Revision(tc.originalOid)) - require.NoError(t, err) - - tagID := tc.originalOid - var tagName, tagMessage string - - for depth := 0; depth < tc.depth; depth++ { - tagName = fmt.Sprintf("tag-depth-%d", depth) - tagMessage = fmt.Sprintf("a commit %d deep", depth) - tagID = gittest.WriteTag(t, cfg, repoPath, tagName, tagID.Revision(), gittest.WriteTagConfig{Message: tagMessage}) - } - expectedTag := &gitalypb.Tag{ - Name: []byte(tagName), - Id: tagID.String(), - Message: []byte(tagMessage), - MessageSize: int64(len([]byte(tagMessage))), - Tagger: gittest.DefaultCommitAuthor, - } - if info.Type == "commit" { - commit, err := catfile.GetCommit(ctx, objectReader, git.Revision(tc.originalOid)) - require.NoError(t, err) - expectedTag.TargetCommit = commit - } - rpcRequest := &gitalypb.FindTagRequest{Repository: repoProto, TagName: []byte(tagName)} - - resp, err := client.FindTag(ctx, rpcRequest) - require.NoError(t, err) - testhelper.ProtoEqual(t, expectedTag, resp.GetTag()) - }) - } -} - -func TestFindTag_notFound(t *testing.T) { - t.Parallel() - - ctx := testhelper.Context(t) - cfg, client := setupRefServiceWithoutRepo(t) - repoProto, _ := gittest.CreateRepository(t, ctx, cfg) - - response, err := client.FindTag(ctx, &gitalypb.FindTagRequest{ - Repository: repoProto, - TagName: []byte("does-not-exist"), - }) - require.Nil(t, response) - - expectedErr := structerr.NewNotFound("tag does not exist").WithDetail( - &gitalypb.FindTagError{ - Error: &gitalypb.FindTagError_TagNotFound{ - TagNotFound: &gitalypb.ReferenceNotFoundError{ - ReferenceName: []byte("refs/tags/does-not-exist"), - }, + desc: "tag of tag", + setup: func(t *testing.T) setupData { + repo, repoPath := gittest.CreateRepository(t, ctx, cfg) + + commitID, commit := writeCommit(t, ctx, cfg, repo) + parentTagID := gittest.WriteTag(t, cfg, repoPath, "parent-tag", commitID.Revision(), gittest.WriteTagConfig{ + Message: "parent message\n", + }) + childTagID := gittest.WriteTag(t, cfg, repoPath, "child-tag", parentTagID.Revision(), gittest.WriteTagConfig{ + Message: "child message\n", + }) + + return setupData{ + request: &gitalypb.FindTagRequest{ + Repository: repo, + TagName: []byte("child-tag"), + }, + expectedTag: &gitalypb.Tag{ + Name: []byte("child-tag"), + Id: childTagID.String(), + TargetCommit: commit, + Message: []byte("child message"), + MessageSize: 13, + Tagger: gittest.DefaultCommitAuthor, + }, + } }, }, - ) - testhelper.RequireGrpcError(t, expectedErr, err) -} - -func TestFindTag_invalidRequest(t *testing.T) { - t.Parallel() - - ctx := testhelper.Context(t) - _, repo, _, client := setupRefService(t, ctx) - - testCases := []struct { - desc string - request *gitalypb.FindTagRequest - expectedErr error - }{ { - desc: "empty request", - request: &gitalypb.FindTagRequest{}, - expectedErr: structerr.NewInvalidArgument("%w", storage.ErrRepositoryNotSet), + desc: "tag of commit with huge commit message", + setup: func(t *testing.T) setupData { + repo, repoPath := gittest.CreateRepository(t, ctx, cfg) + + commitMessage := "An empty commit with REALLY BIG message\n\n" + strings.Repeat("a", helper.MaxCommitOrTagMessageSize+1) + commitID, commit := writeCommit(t, ctx, cfg, repo, + gittest.WithMessage(commitMessage), + ) + tagID := gittest.WriteTag(t, cfg, repoPath, "tag", commitID.Revision()) + + return setupData{ + request: &gitalypb.FindTagRequest{ + Repository: repo, + TagName: []byte("tag"), + }, + expectedTag: &gitalypb.Tag{ + Name: []byte("tag"), + Id: tagID.String(), + TargetCommit: commit, + }, + } + }, }, { - desc: "invalid repo", - request: &gitalypb.FindTagRequest{ - Repository: &gitalypb.Repository{ - StorageName: "fake", - RelativePath: "repo", - }, + desc: "tag with huge tag message", + setup: func(t *testing.T) setupData { + repo, repoPath := gittest.CreateRepository(t, ctx, cfg) + + commitID, commit := writeCommit(t, ctx, cfg, repo) + tagMessage := strings.Repeat("a", 11*1024) + tagID := gittest.WriteTag(t, cfg, repoPath, "tag", commitID.Revision(), gittest.WriteTagConfig{ + Message: tagMessage, + }) + + return setupData{ + request: &gitalypb.FindTagRequest{ + Repository: repo, + TagName: []byte("tag"), + }, + expectedTag: &gitalypb.Tag{ + Name: []byte("tag"), + Id: tagID.String(), + TargetCommit: commit, + Message: []byte(tagMessage[:helper.MaxCommitOrTagMessageSize]), + MessageSize: int64(len(tagMessage)), + Tagger: gittest.DefaultCommitAuthor, + }, + } }, - expectedErr: testhelper.ToInterceptedMetadata(structerr.NewInvalidArgument( - "%w", storage.NewStorageNotFoundError("fake"), - )), }, { - desc: "empty tag name", - request: &gitalypb.FindTagRequest{ - Repository: repo, + desc: "tag with signature", + setup: func(t *testing.T) setupData { + repo, repoPath := gittest.CreateRepository(t, ctx, cfg) + + commitID, commit := writeCommit(t, ctx, cfg, repo) + output := gittest.ExecOpts(t, cfg, gittest.ExecConfig{ + Stdin: strings.NewReader(fmt.Sprintf( + `object %[1]s +type commit +tag signed-tag +tagger Some Author <some.author@example.com> 100000000 +0100 +gpgsig -----BEGIN PGP SIGNATURE----- + this is a pseude PGP signature + -----END PGP SIGNATURE----- + +signed tag message +`, commitID)), + }, "-C", repoPath, "hash-object", "-t", "tag", "--stdin", "-w") + tagID, err := gittest.DefaultObjectHash.FromHex(text.ChompBytes(output)) + require.NoError(t, err) + gittest.WriteRef(t, cfg, repoPath, "refs/tags/signed-tag", tagID) + + return setupData{ + request: &gitalypb.FindTagRequest{ + Repository: repo, + TagName: []byte("signed-tag"), + }, + expectedTag: &gitalypb.Tag{ + Name: []byte("signed-tag"), + Id: tagID.String(), + TargetCommit: commit, + Message: []byte("signed tag message"), + MessageSize: 18, + Tagger: &gitalypb.CommitAuthor{ + Name: []byte("Some Author"), + Email: []byte("some.author@example.com"), + Timezone: []byte("+0100"), + Date: timestamppb.New(time.Unix(100000000, 0)), + }, + }, + } }, - expectedErr: status.Error(codes.InvalidArgument, "tag name is empty"), }, - } + } { + tc := tc - for _, tc := range testCases { t.Run(tc.desc, func(t *testing.T) { - _, err := client.FindTag(ctx, tc.request) - testhelper.RequireGrpcError(t, tc.expectedErr, err) + t.Parallel() + + setup := tc.setup(t) + + response, err := client.FindTag(ctx, setup.request) + testhelper.RequireGrpcError(t, setup.expectedErr, err) + testhelper.ProtoEqual(t, setup.expectedTag, response.GetTag()) }) } } diff --git a/internal/gitaly/service/ref/testhelper_test.go b/internal/gitaly/service/ref/testhelper_test.go index cf5615ddf..a76cf03df 100644 --- a/internal/gitaly/service/ref/testhelper_test.go +++ b/internal/gitaly/service/ref/testhelper_test.go @@ -1,12 +1,13 @@ package ref import ( - "bytes" "context" "testing" "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/config" "gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/service" hookservice "gitlab.com/gitlab-org/gitaly/v16/internal/gitaly/service/hook" @@ -20,12 +21,6 @@ import ( "google.golang.org/grpc/credentials/insecure" ) -var localBranches = map[string]*gitalypb.GitCommit{ - "refs/heads/100%branch": testhelper.GitLabTestCommit("1b12f15a11fc6e62177bef08f47bc7b5ce50b141"), - "refs/heads/improve/awesome": testhelper.GitLabTestCommit("5937ac0a7beb003549fc5fd26fc247adbce4a52e"), - "refs/heads/'test'": testhelper.GitLabTestCommit("e56497bb5f03a90a51293fc6d516788730953899"), -} - func TestMain(m *testing.M) { testhelper.Run(m, testhelper.WithSetup(func() error { // Force small messages to test that fragmenting the @@ -98,34 +93,22 @@ func newRefServiceClient(tb testing.TB, serverSocketPath string) (gitalypb.RefSe return gitalypb.NewRefServiceClient(conn), conn } -func assertContainsAllBranchesResponseBranch(t *testing.T, branches []*gitalypb.FindAllBranchesResponse_Branch, branch *gitalypb.FindAllBranchesResponse_Branch) { - t.Helper() - - var branchNames [][]byte - - for _, b := range branches { - if bytes.Equal(branch.Name, b.Name) { - testhelper.ProtoEqual(t, b.Target, branch.Target) - return // Found the branch and it matches. Success! - } - branchNames = append(branchNames, b.Name) - } - - t.Errorf("Expected to find branch %q in branches %s", branch.Name, branchNames) -} - -func assertContainsBranch(t *testing.T, branches []*gitalypb.Branch, branch *gitalypb.Branch) { - t.Helper() - - var branchNames [][]byte +func writeCommit( + tb testing.TB, + ctx context.Context, + cfg config.Cfg, + repoProto *gitalypb.Repository, + opts ...gittest.WriteCommitOption, +) (git.ObjectID, *gitalypb.GitCommit) { + tb.Helper() + + repo := localrepo.NewTestRepo(tb, cfg, repoProto) + repoPath, err := repo.Path() + require.NoError(tb, err) - for _, b := range branches { - if bytes.Equal(branch.Name, b.Name) { - testhelper.ProtoEqual(t, b.TargetCommit, branch.TargetCommit) - return // Found the branch and it matches. Success! - } - branchNames = append(branchNames, b.Name) - } + commitID := gittest.WriteCommit(tb, cfg, repoPath, opts...) + commitProto, err := repo.ReadCommit(ctx, commitID.Revision()) + require.NoError(tb, err) - t.Errorf("Expected to find branch %q in branches %s", branch.Name, branchNames) + return commitID, commitProto } |