diff options
author | Zeger-Jan van de Weg <zegerjan@gitlab.com> | 2018-10-05 17:58:24 +0300 |
---|---|---|
committer | Zeger-Jan van de Weg <zegerjan@gitlab.com> | 2018-10-05 17:58:24 +0300 |
commit | 7486edf6d1b0b92c984435be1a189622a50c6375 (patch) | |
tree | 4a90d9d31d89c7ba5f9676b29aa34f1240c915d5 | |
parent | df6a8dc7ef30e0a6cc12c6e5d5e26e0458ab8a38 (diff) | |
parent | 99f98539d7b231e75c69335d60f6141b764efd99 (diff) |
Merge branch 'add-git-protocol-v2' into 'master'
Support Git protocol v2
See merge request gitlab-org/gitaly!844
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | changelogs/unreleased/add-git-protocol-v2.yml | 5 | ||||
-rw-r--r-- | internal/git/helper.go | 23 | ||||
-rw-r--r-- | internal/git/pktline/pktline.go | 9 | ||||
-rw-r--r-- | internal/git/protocol.go | 24 | ||||
-rw-r--r-- | internal/service/smarthttp/inforefs.go | 8 | ||||
-rw-r--r-- | internal/service/smarthttp/inforefs_test.go | 43 | ||||
-rw-r--r-- | internal/service/smarthttp/receive_pack.go | 3 | ||||
-rw-r--r-- | internal/service/smarthttp/receive_pack_test.go | 35 | ||||
-rw-r--r-- | internal/service/smarthttp/upload_pack.go | 8 | ||||
-rw-r--r-- | internal/service/smarthttp/upload_pack_test.go | 51 | ||||
-rw-r--r-- | internal/service/ssh/receive_pack.go | 1 | ||||
-rw-r--r-- | internal/service/ssh/receive_pack_test.go | 34 | ||||
-rw-r--r-- | internal/service/ssh/upload_pack.go | 8 | ||||
-rw-r--r-- | internal/service/ssh/upload_pack_test.go | 54 | ||||
-rwxr-xr-x | internal/testhelper/env_git | 4 | ||||
-rw-r--r-- | internal/testhelper/testhelper.go | 12 |
17 files changed, 307 insertions, 16 deletions
diff --git a/.gitignore b/.gitignore index 4b01bfbd4..5799f37c0 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,4 @@ /ruby/.bundle /ruby/tmp *.socket +git-env diff --git a/changelogs/unreleased/add-git-protocol-v2.yml b/changelogs/unreleased/add-git-protocol-v2.yml new file mode 100644 index 000000000..b047c3625 --- /dev/null +++ b/changelogs/unreleased/add-git-protocol-v2.yml @@ -0,0 +1,5 @@ +--- +title: Support Git protocol v2 +merge_request: 844 +author: +type: added diff --git a/internal/git/helper.go b/internal/git/helper.go index 8af8511d9..e2067a6fe 100644 --- a/internal/git/helper.go +++ b/internal/git/helper.go @@ -11,6 +11,15 @@ import ( "gitlab.com/gitlab-org/gitaly/internal/command" ) +// ProtocolV2 Git sets the protocol 2 string as in the environment +const ProtocolV2 = "version=2" + +// GitV1 Indicates Git protocol 1 is used +const GitV1 = "v1" + +// GitV2 Indicates Git protocol 2 is used +const GitV2 = "v2" + // FallbackTimeValue is the value returned by `SafeTimeParse` in case it // encounters a parse error. It's the maximum time value possible in golang. // See https://gitlab.com/gitlab-org/gitaly/issues/556#note_40289573 @@ -72,3 +81,17 @@ func BuildGitOptions(gitOpts []string, otherOpts ...string) []string { return append(args, otherOpts...) } + +// AddGitProtocolEnv checks whether the request has Git protocol v2 +// and sets this in the environment. +func AddGitProtocolEnv(req RequestWithGitProtocol, env []string) []string { + if req.GetGitProtocol() == ProtocolV2 { + env = append(env, fmt.Sprintf("GIT_PROTOCOL=%s", req.GetGitProtocol())) + + gitProtocolRequests.WithLabelValues(GitV2) + } else { + gitProtocolRequests.WithLabelValues(GitV1) + } + + return env +} diff --git a/internal/git/pktline/pktline.go b/internal/git/pktline/pktline.go index c53463a0a..3fe7d9af7 100644 --- a/internal/git/pktline/pktline.go +++ b/internal/git/pktline/pktline.go @@ -15,6 +15,7 @@ import ( const ( maxPktSize = 0xffff + pktDelim = "0001" ) var ( @@ -55,12 +56,18 @@ func WriteString(w io.Writer, str string) (int, error) { return fmt.Fprintf(w, "%04x%s", pktLen, str) } -// WriteFlush write a pkt flush packet. +// WriteFlush writes a pkt flush packet. func WriteFlush(w io.Writer) error { _, err := w.Write(flush) return err } +// WriteDelim writes a pkt delim packet. +func WriteDelim(w io.Writer) error { + _, err := fmt.Fprint(w, pktDelim) + return err +} + func pktLineSplitter(data []byte, atEOF bool) (advance int, token []byte, err error) { if len(data) < 4 { if atEOF && len(data) > 0 { diff --git a/internal/git/protocol.go b/internal/git/protocol.go new file mode 100644 index 000000000..0a2458080 --- /dev/null +++ b/internal/git/protocol.go @@ -0,0 +1,24 @@ +package git + +import ( + "github.com/prometheus/client_golang/prometheus" +) + +// RequestWithGitProtocol holds requests that respond to GitProtocol +type RequestWithGitProtocol interface { + GetGitProtocol() string +} + +var ( + gitProtocolRequests = prometheus.NewCounterVec( + prometheus.CounterOpts{ + Name: "gitaly_protocol_requests_total", + Help: "Counter of Git protocol requests", + }, + []string{"protocol"}, + ) +) + +func init() { + prometheus.MustRegister(gitProtocolRequests) +} diff --git a/internal/service/smarthttp/inforefs.go b/internal/service/smarthttp/inforefs.go index bd7418647..533a32d42 100644 --- a/internal/service/smarthttp/inforefs.go +++ b/internal/service/smarthttp/inforefs.go @@ -4,10 +4,12 @@ import ( "context" "fmt" "io" + "os/exec" "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus" log "github.com/sirupsen/logrus" "gitlab.com/gitlab-org/gitaly-proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/internal/command" "gitlab.com/gitlab-org/gitaly/internal/git" "gitlab.com/gitlab-org/gitaly/internal/git/pktline" "gitlab.com/gitlab-org/gitaly/internal/helper" @@ -36,6 +38,8 @@ func handleInfoRefs(ctx context.Context, service string, req *gitalypb.InfoRefsR "service": service, }).Debug("handleInfoRefs") + env := git.AddGitProtocolEnv(req, []string{}) + repoPath, err := helper.GetRepoPath(req.Repository) if err != nil { return err @@ -48,7 +52,9 @@ func handleInfoRefs(ctx context.Context, service string, req *gitalypb.InfoRefsR args = append(args, service, "--stateless-rpc", "--advertise-refs", repoPath) - cmd, err := git.Command(ctx, req.Repository, args...) + osCommand := exec.Command(command.GitPath(), args...) + cmd, err := command.New(ctx, osCommand, nil, nil, nil, env...) + if err != nil { if _, ok := status.FromError(err); ok { return err diff --git a/internal/service/smarthttp/inforefs_test.go b/internal/service/smarthttp/inforefs_test.go index 51570d4e7..50777fc29 100644 --- a/internal/service/smarthttp/inforefs_test.go +++ b/internal/service/smarthttp/inforefs_test.go @@ -1,11 +1,15 @@ package smarthttp import ( + "fmt" + "io" "io/ioutil" "strings" "testing" "gitlab.com/gitlab-org/gitaly-proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/internal/config" + "gitlab.com/gitlab-org/gitaly/internal/git" "gitlab.com/gitlab-org/gitaly/internal/testhelper" "gitlab.com/gitlab-org/gitaly/streamio" @@ -50,6 +54,45 @@ func TestSuccessfulInfoRefsUploadPackWithGitConfigOptions(t *testing.T) { assertGitRefAdvertisement(t, "InfoRefsUploadPack", string(response), "001e# service=git-upload-pack", "0000", []string{}) } +func TestSuccessfulInfoRefsUploadPackWithGitProtocol(t *testing.T) { + defer func(old string) { + config.Config.Git.BinPath = old + }(config.Config.Git.BinPath) + config.Config.Git.BinPath = "../../testhelper/env_git" + + server, serverSocketPath := runSmartHTTPServer(t) + defer server.Stop() + + testRepo, _, cleanupFn := testhelper.NewTestRepo(t) + defer cleanupFn() + + rpcRequest := &gitalypb.InfoRefsRequest{ + Repository: testRepo, + GitProtocol: git.ProtocolV2, + } + + client, _ := newSmartHTTPClient(t, serverSocketPath) + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + c, err := client.InfoRefsUploadPack(ctx, rpcRequest) + + for { + _, err := c.Recv() + if err != nil { + require.Equal(t, io.EOF, err) + break + } + } + + require.NoError(t, err) + + envData, err := testhelper.GetGitEnvData() + + require.NoError(t, err) + require.Equal(t, fmt.Sprintf("GIT_PROTOCOL=%s\n", git.ProtocolV2), envData) +} + func makeInfoRefsUploadPackRequest(t *testing.T, serverSocketPath string, rpcRequest *gitalypb.InfoRefsRequest) ([]byte, error) { client, conn := newSmartHTTPClient(t, serverSocketPath) defer conn.Close() diff --git a/internal/service/smarthttp/receive_pack.go b/internal/service/smarthttp/receive_pack.go index c48800676..9c8683f99 100644 --- a/internal/service/smarthttp/receive_pack.go +++ b/internal/service/smarthttp/receive_pack.go @@ -50,6 +50,9 @@ func (s *server) PostReceivePack(stream gitalypb.SmartHTTPService_PostReceivePac if req.GlUsername != "" { env = append(env, fmt.Sprintf("GL_USERNAME=%s", req.GlUsername)) } + + env = git.AddGitProtocolEnv(req, env) + repoPath, err := helper.GetRepoPath(req.Repository) if err != nil { return err diff --git a/internal/service/smarthttp/receive_pack_test.go b/internal/service/smarthttp/receive_pack_test.go index 3da59252c..d51bcc234 100644 --- a/internal/service/smarthttp/receive_pack_test.go +++ b/internal/service/smarthttp/receive_pack_test.go @@ -11,6 +11,7 @@ import ( "time" "gitlab.com/gitlab-org/gitaly-proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/internal/config" "gitlab.com/gitlab-org/gitaly/internal/git" "gitlab.com/gitlab-org/gitaly/internal/testhelper" @@ -75,6 +76,40 @@ func TestSuccessfulReceivePackRequestWithGitOpts(t *testing.T) { testhelper.MustRunCommand(t, nil, "git", "-C", repoPath, "show", push.newHead) } +func TestSuccessfulReceivePackRequestWithGitProtocol(t *testing.T) { + defer func(old string) { + config.Config.Git.BinPath = old + }(config.Config.Git.BinPath) + config.Config.Git.BinPath = "../../testhelper/env_git" + + server, serverSocketPath := runSmartHTTPServer(t) + defer server.Stop() + + repo, repoPath, cleanup := testhelper.NewTestRepo(t) + defer cleanup() + + client, conn := newSmartHTTPClient(t, serverSocketPath) + defer conn.Close() + + ctx, cancel := testhelper.Context() + defer cancel() + + stream, err := client.PostReceivePack(ctx) + require.NoError(t, err) + + push := newTestPush(t, nil) + firstRequest := &gitalypb.PostReceivePackRequest{Repository: repo, GlId: "user-123", GlRepository: "project-123", GitProtocol: git.ProtocolV2} + doPush(t, stream, firstRequest, push.body) + + envData, err := testhelper.GetGitEnvData() + + require.NoError(t, err) + require.Equal(t, fmt.Sprintf("GIT_PROTOCOL=%s\n", git.ProtocolV2), envData) + + // The fact that this command succeeds means that we got the commit correctly, no further checks should be needed. + testhelper.MustRunCommand(t, nil, "git", "-C", repoPath, "show", push.newHead) +} + func TestFailedReceivePackRequestWithGitOpts(t *testing.T) { currentGitVersion, _ := git.Version() if currentGitVersion == "2.9.0" { diff --git a/internal/service/smarthttp/upload_pack.go b/internal/service/smarthttp/upload_pack.go index 35b8253b5..03fbc4d3e 100644 --- a/internal/service/smarthttp/upload_pack.go +++ b/internal/service/smarthttp/upload_pack.go @@ -4,6 +4,8 @@ import ( "io" "os/exec" + "gitlab.com/gitlab-org/gitaly/internal/git" + "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus" "gitlab.com/gitlab-org/gitaly-proto/go/gitalypb" "gitlab.com/gitlab-org/gitaly/internal/command" @@ -36,6 +38,7 @@ func (s *server) PostUploadPack(stream gitalypb.SmartHTTPService_PostUploadPackS if err != nil { return err } + if err := validateUploadPackRequest(req); err != nil { return err } @@ -55,6 +58,9 @@ func (s *server) PostUploadPack(stream gitalypb.SmartHTTPService_PostUploadPackS stdout := streamio.NewWriter(func(p []byte) error { return stream.Send(&gitalypb.PostUploadPackResponse{Data: p}) }) + + env := git.AddGitProtocolEnv(req, []string{}) + repoPath, err := helper.GetRepoPath(req.Repository) if err != nil { return err @@ -68,7 +74,7 @@ func (s *server) PostUploadPack(stream gitalypb.SmartHTTPService_PostUploadPackS args = append(args, "upload-pack", "--stateless-rpc", repoPath) osCommand := exec.Command(command.GitPath(), args...) - cmd, err := command.New(stream.Context(), osCommand, stdin, stdout, nil) + cmd, err := command.New(stream.Context(), osCommand, stdin, stdout, nil, env...) if err != nil { return status.Errorf(codes.Unavailable, "PostUploadPack: cmd: %v", err) diff --git a/internal/service/smarthttp/upload_pack_test.go b/internal/service/smarthttp/upload_pack_test.go index 27a4274d6..d2cb3a957 100644 --- a/internal/service/smarthttp/upload_pack_test.go +++ b/internal/service/smarthttp/upload_pack_test.go @@ -7,10 +7,14 @@ import ( "io" "os" "path" + "path/filepath" "testing" "time" "gitlab.com/gitlab-org/gitaly-proto/go/gitalypb" + "gitlab.com/gitlab-org/gitaly/internal/git" + + "gitlab.com/gitlab-org/gitaly/internal/config" "gitlab.com/gitlab-org/gitaly/internal/git/pktline" "gitlab.com/gitlab-org/gitaly/internal/helper" "gitlab.com/gitlab-org/gitaly/internal/testhelper" @@ -24,7 +28,7 @@ import ( ) const ( - clientCapabilities = `multi_ack_detailed no-done side-band-64k thin-pack include-tag ofs-delta deepen-since deepen-not agent=git/2.12.2` + clientCapabilities = `multi_ack_detailed no-done side-band-64k thin-pack include-tag ofs-delta deepen-since deepen-not agent=git/2.18.0` ) func TestSuccessfulUploadPackRequest(t *testing.T) { @@ -147,6 +151,51 @@ func TestUploadPackRequestWithGitConfigOptions(t *testing.T) { assert.Equal(t, response.String(), "", "Ref is hidden so no response should be received") } +func TestUploadPackRequestWithGitProtocol(t *testing.T) { + defer func(old string) { + config.Config.Git.BinPath = old + }(config.Config.Git.BinPath) + config.Config.Git.BinPath = "../../testhelper/env_git" + + server, serverSocketPath := runSmartHTTPServer(t) + defer server.Stop() + + testRepo := testhelper.TestRepository() + testRepoPath, err := helper.GetRepoPath(testRepo) + require.NoError(t, err) + + storagePath := testhelper.GitlabTestStoragePath() + relativePath, err := filepath.Rel(storagePath, testRepoPath) + require.NoError(t, err) + + requestBody := &bytes.Buffer{} + + pktline.WriteString(requestBody, "command=ls-refs\n") + pktline.WriteDelim(requestBody) + pktline.WriteString(requestBody, "peel\n") + pktline.WriteString(requestBody, "symrefs\n") + pktline.WriteFlush(requestBody) + + // Only a Git server with v2 will recognize this request. + // Git v1 will throw a protocol error. + rpcRequest := &gitalypb.PostUploadPackRequest{ + Repository: &gitalypb.Repository{ + StorageName: "default", + RelativePath: relativePath, + }, + GitProtocol: git.ProtocolV2, + } + + // The ref is successfully requested as it is not hidden + _, err = makePostUploadPackRequest(t, serverSocketPath, rpcRequest, requestBody) + require.NoError(t, err) + + envData, err := testhelper.GetGitEnvData() + + require.NoError(t, err) + require.Equal(t, fmt.Sprintf("GIT_PROTOCOL=%s\n", git.ProtocolV2), envData) +} + // This test is here because git-upload-pack returns a non-zero exit code // on 'deepen' requests even though the request is being handled just // fine from the client perspective. diff --git a/internal/service/ssh/receive_pack.go b/internal/service/ssh/receive_pack.go index e5792f8a1..b291eb9a3 100644 --- a/internal/service/ssh/receive_pack.go +++ b/internal/service/ssh/receive_pack.go @@ -51,6 +51,7 @@ func (s *server) SSHReceivePack(stream gitalypb.SSHService_SSHReceivePackServer) if req.GlRepository != "" { env = append(env, fmt.Sprintf("GL_REPOSITORY=%s", req.GlRepository)) } + env = git.AddGitProtocolEnv(req, env) repoPath, err := helper.GetRepoPath(req.Repository) if err != nil { diff --git a/internal/service/ssh/receive_pack_test.go b/internal/service/ssh/receive_pack_test.go index 74bf9ebb7..e5e3d3a56 100644 --- a/internal/service/ssh/receive_pack_test.go +++ b/internal/service/ssh/receive_pack_test.go @@ -7,10 +7,11 @@ import ( "os" "os/exec" "path" - "strings" "testing" "time" + "gitlab.com/gitlab-org/gitaly/internal/config" + "github.com/golang/protobuf/jsonpb" "github.com/stretchr/testify/require" @@ -84,17 +85,36 @@ func TestReceivePackPushSuccess(t *testing.T) { if err != nil { t.Fatal(err) } - if strings.Compare(lHead, rHead) != 0 { - t.Errorf("local and remote head not equal. push failed: %q != %q", lHead, rHead) - } + require.Equal(t, lHead, rHead, "local and remote head not equal. push failed") lHead, rHead, err = testCloneAndPush(t, serverSocketPath, pushParams{storageName: testRepo.GetStorageName(), glID: "1", gitConfigOptions: []string{"receive.MaxInputSize=10000"}}) if err != nil { t.Fatal(err) } - if strings.Compare(lHead, rHead) != 0 { - t.Errorf("local and remote head not equal. push failed: %q != %q", lHead, rHead) + + require.Equal(t, lHead, rHead, "local and remote head not equal. push failed") +} + +func TestReceivePackPushSuccessWithGitProtocol(t *testing.T) { + defer func(old string) { + config.Config.Git.BinPath = old + }(config.Config.Git.BinPath) + config.Config.Git.BinPath = "../../testhelper/env_git" + + server, serverSocketPath := runSSHServer(t) + defer server.Stop() + + lHead, rHead, err := testCloneAndPush(t, serverSocketPath, pushParams{storageName: testRepo.GetStorageName(), glID: "1", gitProtocol: git.ProtocolV2}) + if err != nil { + t.Fatal(err) } + + require.Equal(t, lHead, rHead, "local and remote head not equal. push failed") + + envData, err := testhelper.GetGitEnvData() + + require.NoError(t, err) + require.Equal(t, fmt.Sprintf("GIT_PROTOCOL=%s\n", git.ProtocolV2), envData) } func TestReceivePackPushFailure(t *testing.T) { @@ -152,6 +172,7 @@ func testCloneAndPush(t *testing.T, serverSocketPath string, params pushParams) GlRepository: pbTempRepo.GetRelativePath(), GlId: params.glID, GitConfigOptions: params.gitConfigOptions, + GitProtocol: params.gitProtocol, }) require.NoError(t, err) @@ -216,4 +237,5 @@ type pushParams struct { storageName string glID string gitConfigOptions []string + gitProtocol string } diff --git a/internal/service/ssh/upload_pack.go b/internal/service/ssh/upload_pack.go index 7867b0a3c..28d3f5296 100644 --- a/internal/service/ssh/upload_pack.go +++ b/internal/service/ssh/upload_pack.go @@ -3,6 +3,8 @@ package ssh import ( "os/exec" + "gitlab.com/gitlab-org/gitaly/internal/git" + "github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus" "gitlab.com/gitlab-org/gitaly-proto/go/gitalypb" "gitlab.com/gitlab-org/gitaly/internal/command" @@ -19,6 +21,7 @@ func (s *server) SSHUploadPack(stream gitalypb.SSHService_SSHUploadPackServer) e if err != nil { return err } + if err = validateFirstUploadPackRequest(req); err != nil { return err } @@ -33,6 +36,9 @@ func (s *server) SSHUploadPack(stream gitalypb.SSHService_SSHUploadPackServer) e stderr := streamio.NewWriter(func(p []byte) error { return stream.Send(&gitalypb.SSHUploadPackResponse{Stderr: p}) }) + + env := git.AddGitProtocolEnv(req, []string{}) + repoPath, err := helper.GetRepoPath(req.Repository) if err != nil { return err @@ -48,7 +54,7 @@ func (s *server) SSHUploadPack(stream gitalypb.SSHService_SSHUploadPackServer) e osCommand := exec.Command(command.GitPath(), args...) - cmd, err := command.New(stream.Context(), osCommand, stdin, stdout, stderr) + cmd, err := command.New(stream.Context(), osCommand, stdin, stdout, stderr, env...) if err != nil { return status.Errorf(codes.Unavailable, "SSHUploadPack: cmd: %v", err) diff --git a/internal/service/ssh/upload_pack_test.go b/internal/service/ssh/upload_pack_test.go index 4dbd53d17..34e76a86e 100644 --- a/internal/service/ssh/upload_pack_test.go +++ b/internal/service/ssh/upload_pack_test.go @@ -9,6 +9,10 @@ import ( "strings" "testing" + "gitlab.com/gitlab-org/gitaly/internal/git" + + "gitlab.com/gitlab-org/gitaly/internal/config" + "github.com/golang/protobuf/jsonpb" "github.com/stretchr/testify/require" @@ -90,9 +94,48 @@ func TestUploadPackCloneSuccess(t *testing.T) { for _, tc := range tests { t.Run(tc.desc, func(t *testing.T) { - lHead, rHead, _, _, err := testClone(t, serverSocketPath, testRepo.GetStorageName(), testRepo.GetRelativePath(), localRepoPath, "", tc.cmd) + lHead, rHead, _, _, err := testClone(t, serverSocketPath, testRepo.GetStorageName(), testRepo.GetRelativePath(), localRepoPath, "", tc.cmd, "") + require.NoError(t, err, "clone failed") + require.Equal(t, lHead, rHead, "local and remote head not equal") + }) + } +} + +func TestUploadPackCloneSuccessWithGitProtocol(t *testing.T) { + defer func(old string) { + config.Config.Git.BinPath = old + }(config.Config.Git.BinPath) + config.Config.Git.BinPath = "../../testhelper/env_git" + + server, serverSocketPath := runSSHServer(t) + defer server.Stop() + + localRepoPath := path.Join(testRepoRoot, "gitlab-test-upload-pack-local") + + tests := []struct { + cmd *exec.Cmd + desc string + }{ + { + cmd: exec.Command("git", "clone", "git@localhost:test/test.git", localRepoPath), + desc: "full clone", + }, + { + cmd: exec.Command("git", "clone", "--depth", "1", "git@localhost:test/test.git", localRepoPath), + desc: "shallow clone", + }, + } + + for _, tc := range tests { + t.Run(tc.desc, func(t *testing.T) { + lHead, rHead, _, _, err := testClone(t, serverSocketPath, testRepo.GetStorageName(), testRepo.GetRelativePath(), localRepoPath, "", tc.cmd, git.ProtocolV2) require.NoError(t, err, "clone failed") require.Equal(t, lHead, rHead, "local and remote head not equal") + + envData, err := testhelper.GetGitEnvData() + + require.NoError(t, err) + require.Equal(t, fmt.Sprintf("GIT_PROTOCOL=%s\n", git.ProtocolV2), envData) }) } } @@ -105,7 +148,7 @@ func TestUploadPackCloneHideTags(t *testing.T) { cmd := exec.Command("git", "clone", "--mirror", "git@localhost:test/test.git", localRepoPath) - _, _, lTags, rTags, err := testClone(t, serverSocketPath, testRepo.GetStorageName(), testRepo.GetRelativePath(), localRepoPath, "transfer.hideRefs=refs/tags", cmd) + _, _, lTags, rTags, err := testClone(t, serverSocketPath, testRepo.GetStorageName(), testRepo.GetRelativePath(), localRepoPath, "transfer.hideRefs=refs/tags", cmd, "") if err != nil { t.Fatalf("clone failed: %v", err) @@ -126,18 +169,19 @@ func TestUploadPackCloneFailure(t *testing.T) { cmd := exec.Command("git", "clone", "git@localhost:test/test.git", localRepoPath) - _, _, _, _, err := testClone(t, serverSocketPath, "foobar", testRepo.GetRelativePath(), localRepoPath, "", cmd) + _, _, _, _, err := testClone(t, serverSocketPath, "foobar", testRepo.GetRelativePath(), localRepoPath, "", cmd, "") if err == nil { t.Fatalf("clone didn't fail") } } -func testClone(t *testing.T, serverSocketPath, storageName, relativePath, localRepoPath string, gitConfig string, cmd *exec.Cmd) (string, string, string, string, error) { +func testClone(t *testing.T, serverSocketPath, storageName, relativePath, localRepoPath string, gitConfig string, cmd *exec.Cmd, gitProtocol string) (string, string, string, string, error) { defer os.RemoveAll(localRepoPath) pbTempRepo := &gitalypb.Repository{StorageName: storageName, RelativePath: relativePath} req := &gitalypb.SSHUploadPackRequest{ - Repository: pbTempRepo, + Repository: pbTempRepo, + GitProtocol: gitProtocol, } if gitConfig != "" { req.GitConfigOptions = strings.Split(gitConfig, " ") diff --git a/internal/testhelper/env_git b/internal/testhelper/env_git new file mode 100755 index 000000000..7739eaeef --- /dev/null +++ b/internal/testhelper/env_git @@ -0,0 +1,4 @@ +#!/bin/sh +mkdir -p testdata +env | grep ^GIT_PROTOCOL= > testdata/git-env +exec git "$@" diff --git a/internal/testhelper/testhelper.go b/internal/testhelper/testhelper.go index 5779e54db..3770519e8 100644 --- a/internal/testhelper/testhelper.go +++ b/internal/testhelper/testhelper.go @@ -41,6 +41,7 @@ const ( TestRelativePath = "gitlab-test.git" RepositoryAuthToken = "the-secret-token" DefaultStorageName = "default" + testGitEnv = "testdata/git-env" ) func init() { @@ -256,6 +257,17 @@ func ConfigureRuby() { } } +// GetGitEnvData reads and returns the content of testGitEnv +func GetGitEnvData() (string, error) { + gitEnvBytes, err := ioutil.ReadFile(testGitEnv) + + if err != nil { + return "", err + } + + return string(gitEnvBytes), nil +} + // NewTestGrpcServer creates a GRPC Server for testing purposes func NewTestGrpcServer(t *testing.T, streamInterceptors []grpc.StreamServerInterceptor, unaryInterceptors []grpc.UnaryServerInterceptor) *grpc.Server { logger := NewTestLogger(t) |