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:
Diffstat (limited to 'cmd/gitaly-git2go/conflicts_test.go')
-rw-r--r--cmd/gitaly-git2go/conflicts_test.go278
1 files changed, 278 insertions, 0 deletions
diff --git a/cmd/gitaly-git2go/conflicts_test.go b/cmd/gitaly-git2go/conflicts_test.go
new file mode 100644
index 000000000..c8e9848eb
--- /dev/null
+++ b/cmd/gitaly-git2go/conflicts_test.go
@@ -0,0 +1,278 @@
+//go:build static && system_libgit2 && !gitaly_test_sha256
+
+package main
+
+import (
+ "fmt"
+ "testing"
+
+ "github.com/stretchr/testify/require"
+ glgit "gitlab.com/gitlab-org/gitaly/v15/internal/git"
+ "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest"
+ "gitlab.com/gitlab-org/gitaly/v15/internal/git2go"
+ "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper"
+ "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg"
+ "google.golang.org/grpc/codes"
+ "google.golang.org/grpc/status"
+)
+
+func TestConflicts(t *testing.T) {
+ testcases := []struct {
+ desc string
+ base []gittest.TreeEntry
+ ours []gittest.TreeEntry
+ theirs []gittest.TreeEntry
+ conflicts []git2go.Conflict
+ }{
+ {
+ desc: "no conflicts",
+ base: []gittest.TreeEntry{
+ {Path: "file", Content: "a", Mode: "100644"},
+ },
+ ours: []gittest.TreeEntry{
+ {Path: "file", Content: "a", Mode: "100644"},
+ },
+ theirs: []gittest.TreeEntry{
+ {Path: "file", Content: "b", Mode: "100644"},
+ },
+ conflicts: nil,
+ },
+ {
+ desc: "single file",
+ base: []gittest.TreeEntry{
+ {Path: "file", Content: "a", Mode: "100644"},
+ },
+ ours: []gittest.TreeEntry{
+ {Path: "file", Content: "b", Mode: "100644"},
+ },
+ theirs: []gittest.TreeEntry{
+ {Path: "file", Content: "c", Mode: "100644"},
+ },
+ conflicts: []git2go.Conflict{
+ {
+ Ancestor: git2go.ConflictEntry{Path: "file", Mode: 0o100644},
+ Our: git2go.ConflictEntry{Path: "file", Mode: 0o100644},
+ Their: git2go.ConflictEntry{Path: "file", Mode: 0o100644},
+ Content: []byte("<<<<<<< file\nb\n=======\nc\n>>>>>>> file\n"),
+ },
+ },
+ },
+ {
+ desc: "multiple files with single conflict",
+ base: []gittest.TreeEntry{
+ {Path: "file-1", Content: "a", Mode: "100644"},
+ {Path: "file-2", Content: "a", Mode: "100644"},
+ },
+ ours: []gittest.TreeEntry{
+ {Path: "file-1", Content: "b", Mode: "100644"},
+ {Path: "file-2", Content: "b", Mode: "100644"},
+ },
+ theirs: []gittest.TreeEntry{
+ {Path: "file-1", Content: "a", Mode: "100644"},
+ {Path: "file-2", Content: "c", Mode: "100644"},
+ },
+ conflicts: []git2go.Conflict{
+ {
+ Ancestor: git2go.ConflictEntry{Path: "file-2", Mode: 0o100644},
+ Our: git2go.ConflictEntry{Path: "file-2", Mode: 0o100644},
+ Their: git2go.ConflictEntry{Path: "file-2", Mode: 0o100644},
+ Content: []byte("<<<<<<< file-2\nb\n=======\nc\n>>>>>>> file-2\n"),
+ },
+ },
+ },
+ {
+ desc: "multiple conflicts",
+ base: []gittest.TreeEntry{
+ {Path: "file-1", Content: "a", Mode: "100644"},
+ {Path: "file-2", Content: "a", Mode: "100644"},
+ },
+ ours: []gittest.TreeEntry{
+ {Path: "file-1", Content: "b", Mode: "100644"},
+ {Path: "file-2", Content: "b", Mode: "100644"},
+ },
+ theirs: []gittest.TreeEntry{
+ {Path: "file-1", Content: "c", Mode: "100644"},
+ {Path: "file-2", Content: "c", Mode: "100644"},
+ },
+ conflicts: []git2go.Conflict{
+ {
+ Ancestor: git2go.ConflictEntry{Path: "file-1", Mode: 0o100644},
+ Our: git2go.ConflictEntry{Path: "file-1", Mode: 0o100644},
+ Their: git2go.ConflictEntry{Path: "file-1", Mode: 0o100644},
+ Content: []byte("<<<<<<< file-1\nb\n=======\nc\n>>>>>>> file-1\n"),
+ },
+ {
+ Ancestor: git2go.ConflictEntry{Path: "file-2", Mode: 0o100644},
+ Our: git2go.ConflictEntry{Path: "file-2", Mode: 0o100644},
+ Their: git2go.ConflictEntry{Path: "file-2", Mode: 0o100644},
+ Content: []byte("<<<<<<< file-2\nb\n=======\nc\n>>>>>>> file-2\n"),
+ },
+ },
+ },
+ {
+ desc: "modified-delete-conflict",
+ base: []gittest.TreeEntry{
+ {Path: "file", Content: "content", Mode: "100644"},
+ },
+ ours: []gittest.TreeEntry{
+ {Path: "file", Content: "changed", Mode: "100644"},
+ },
+ theirs: []gittest.TreeEntry{
+ {Path: "different-file", Content: "unrelated", Mode: "100644"},
+ },
+ conflicts: []git2go.Conflict{
+ {
+ Ancestor: git2go.ConflictEntry{Path: "file", Mode: 0o100644},
+ Our: git2go.ConflictEntry{Path: "file", Mode: 0o100644},
+ Their: git2go.ConflictEntry{},
+ Content: []byte("<<<<<<< file\nchanged\n=======\n>>>>>>> \n"),
+ },
+ },
+ },
+ {
+ // Ruby code doesn't call `merge_commits` with rename
+ // detection and so don't we. The rename conflict is
+ // thus split up into three conflicts.
+ desc: "rename-rename-conflict",
+ base: []gittest.TreeEntry{
+ {Path: "file", Content: "a\nb\nc\nd\ne\nf\ng\n", Mode: "100644"},
+ },
+ ours: []gittest.TreeEntry{
+ {Path: "renamed-1", Content: "a\nb\nc\nd\ne\nf\ng\n", Mode: "100644"},
+ },
+ theirs: []gittest.TreeEntry{
+ {Path: "renamed-2", Content: "a\nb\nc\nd\ne\nf\ng\n", Mode: "100644"},
+ },
+ conflicts: []git2go.Conflict{
+ {
+ Ancestor: git2go.ConflictEntry{Path: "file", Mode: 0o100644},
+ Our: git2go.ConflictEntry{},
+ Their: git2go.ConflictEntry{},
+ Content: nil,
+ },
+ {
+ Ancestor: git2go.ConflictEntry{},
+ Our: git2go.ConflictEntry{Path: "renamed-1", Mode: 0o100644},
+ Their: git2go.ConflictEntry{},
+ Content: []byte("a\nb\nc\nd\ne\nf\ng\n"),
+ },
+ {
+ Ancestor: git2go.ConflictEntry{},
+ Our: git2go.ConflictEntry{},
+ Their: git2go.ConflictEntry{Path: "renamed-2", Mode: 0o100644},
+ Content: []byte("a\nb\nc\nd\ne\nf\ng\n"),
+ },
+ },
+ },
+ }
+
+ for _, tc := range testcases {
+ cfg, repo, repoPath := testcfg.BuildWithRepo(t)
+ executor := buildExecutor(t, cfg)
+
+ testcfg.BuildGitalyGit2Go(t, cfg)
+
+ base := gittest.WriteCommit(t, cfg, repoPath, gittest.WithTreeEntries(tc.base...))
+ ours := gittest.WriteCommit(t, cfg, repoPath, gittest.WithParents(base), gittest.WithTreeEntries(tc.ours...))
+ theirs := gittest.WriteCommit(t, cfg, repoPath, gittest.WithParents(base), gittest.WithTreeEntries(tc.theirs...))
+
+ t.Run(tc.desc, func(t *testing.T) {
+ ctx := testhelper.Context(t)
+
+ response, err := executor.Conflicts(ctx, repo, git2go.ConflictsCommand{
+ Repository: repoPath,
+ Ours: ours.String(),
+ Theirs: theirs.String(),
+ })
+
+ require.NoError(t, err)
+ require.Equal(t, tc.conflicts, response.Conflicts)
+ })
+ }
+}
+
+func TestConflicts_checkError(t *testing.T) {
+ cfg, repo, repoPath := testcfg.BuildWithRepo(t)
+ base := gittest.WriteCommit(t, cfg, repoPath, gittest.WithTreeEntries())
+ validOID := glgit.ObjectID(base.String())
+ executor := buildExecutor(t, cfg)
+
+ testcfg.BuildGitalyGit2Go(t, cfg)
+
+ testcases := []struct {
+ desc string
+ overrideRepoPath string
+ ours glgit.ObjectID
+ theirs glgit.ObjectID
+ expErr error
+ }{
+ {
+ desc: "ours is not set",
+ ours: "",
+ theirs: validOID,
+ expErr: fmt.Errorf("conflicts: %w: missing ours", git2go.ErrInvalidArgument),
+ },
+ {
+ desc: "theirs is not set",
+ ours: validOID,
+ theirs: "",
+ expErr: fmt.Errorf("conflicts: %w: missing theirs", git2go.ErrInvalidArgument),
+ },
+ {
+ desc: "invalid repository",
+ overrideRepoPath: "not/existing/path.git",
+ ours: validOID,
+ theirs: validOID,
+ expErr: status.Error(codes.Internal, "could not open repository: failed to resolve path 'not/existing/path.git': No such file or directory"),
+ },
+ {
+ desc: "ours is invalid",
+ ours: "1",
+ theirs: validOID,
+ expErr: status.Error(codes.InvalidArgument, "encoding/hex: odd length hex string"),
+ },
+ {
+ desc: "theirs is invalid",
+ ours: validOID,
+ theirs: "1",
+ expErr: status.Error(codes.InvalidArgument, "encoding/hex: odd length hex string"),
+ },
+ {
+ desc: "ours OID doesn't exist",
+ ours: glgit.ObjectHashSHA1.ZeroOID,
+ theirs: validOID,
+ expErr: status.Error(codes.InvalidArgument, "odb: cannot read object: null OID cannot exist"),
+ },
+ {
+ desc: "invalid object type",
+ ours: glgit.ObjectHashSHA1.EmptyTreeOID,
+ theirs: validOID,
+ expErr: status.Error(codes.InvalidArgument, "the requested type does not match the type in the ODB"),
+ },
+ {
+ desc: "theirs OID doesn't exist",
+ ours: validOID,
+ theirs: glgit.ObjectHashSHA1.ZeroOID,
+ expErr: status.Error(codes.InvalidArgument, "odb: cannot read object: null OID cannot exist"),
+ },
+ }
+
+ for _, tc := range testcases {
+ t.Run(tc.desc, func(t *testing.T) {
+ repoPath := repoPath
+ if tc.overrideRepoPath != "" {
+ repoPath = tc.overrideRepoPath
+ }
+ ctx := testhelper.Context(t)
+
+ _, err := executor.Conflicts(ctx, repo, git2go.ConflictsCommand{
+ Repository: repoPath,
+ Ours: tc.ours.String(),
+ Theirs: tc.theirs.String(),
+ })
+
+ require.Error(t, err)
+ require.Equal(t, tc.expErr, err)
+ })
+ }
+}