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:
authorJacob Vosmaer (GitLab) <jacob@gitlab.com>2018-08-07 16:27:51 +0300
committerAlejandro Rodríguez <alejorro70@gmail.com>2018-08-07 16:27:51 +0300
commit7d3cff8788d5c4687dc8c98e9b3b4979f7b2d69b (patch)
tree0e25c72f150c660411445add1b4a0ca4be141b66
parenta585f9f5b4360346afecfaf793d28ca6270d60d8 (diff)
Refactor PostReceivePack test
-rw-r--r--internal/service/smarthttp/receive_pack_test.go133
1 files changed, 78 insertions, 55 deletions
diff --git a/internal/service/smarthttp/receive_pack_test.go b/internal/service/smarthttp/receive_pack_test.go
index 7575d77e1..84230327f 100644
--- a/internal/service/smarthttp/receive_pack_test.go
+++ b/internal/service/smarthttp/receive_pack_test.go
@@ -4,8 +4,9 @@ import (
"bytes"
"fmt"
"io"
- "os"
+ "io/ioutil"
"path"
+ "strings"
"testing"
"time"
@@ -23,47 +24,76 @@ func TestSuccessfulReceivePackRequest(t *testing.T) {
server, serverSocketPath := runSmartHTTPServer(t)
defer server.Stop()
- testRepo := testhelper.TestRepository()
- storagePath := testhelper.GitlabTestStoragePath()
- remoteRepoRelativePath := "gitlab-test-remote"
- localRepoRelativePath := "gitlab-test-local"
- testRepoPath := path.Join(storagePath, testRepo.RelativePath)
- remoteRepoPath := path.Join(storagePath, remoteRepoRelativePath)
- localRepoPath := path.Join(storagePath, localRepoRelativePath)
- // Make a non-bare clone of the test repo to act as a local one
- testhelper.MustRunCommand(t, nil, "git", "clone", testRepoPath, localRepoPath)
- // Make a bare clone of the test repo to act as a remote one and to leave the original repo intact for other tests
- testhelper.MustRunCommand(t, nil, "git", "clone", "--bare", testRepoPath, remoteRepoPath)
- defer os.RemoveAll(remoteRepoPath)
- defer os.RemoveAll(localRepoPath)
+ repo, repoPath, cleanup := testhelper.NewTestRepo(t)
+ defer cleanup()
- commitMsg := fmt.Sprintf("Testing ReceivePack RPC around %d", time.Now().Unix())
- committerName := "Scrooge McDuck"
- committerEmail := "scrooge@mcduck.com"
- clientCapabilities := "report-status side-band-64k agent=git/2.12.0"
+ client, conn := newSmartHTTPClient(t, serverSocketPath)
+ defer conn.Close()
- // The latest commit ID on the remote repo
- oldHead := bytes.TrimSpace(testhelper.MustRunCommand(t, nil, "git", "-C", localRepoPath, "rev-parse", "master"))
+ ctx, cancel := context.WithCancel(context.Background())
+ defer cancel()
- testhelper.MustRunCommand(t, nil, "git", "-C", localRepoPath,
- "-c", fmt.Sprintf("user.name=%s", committerName),
- "-c", fmt.Sprintf("user.email=%s", committerEmail),
- "commit", "--allow-empty", "-m", commitMsg)
+ stream, err := client.PostReceivePack(ctx)
+ require.NoError(t, err)
- // The commit ID we want to push to the remote repo
- newHead := bytes.TrimSpace(testhelper.MustRunCommand(t, nil, "git", "-C", localRepoPath, "rev-parse", "master"))
+ push := newTestPush(t, nil)
+ firstRequest := &pb.PostReceivePackRequest{Repository: repo, GlId: "user-123", GlRepository: "project-123"}
+ response := doPush(t, stream, firstRequest, push.body)
+
+ expectedResponse := "0030\x01000eunpack ok\n0019ok refs/heads/master\n00000000"
+ require.Equal(t, expectedResponse, string(response), "Expected response to be %q, got %q", expectedResponse, response)
+
+ // 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 doPush(t *testing.T, stream pb.SmartHTTPService_PostReceivePackClient, firstRequest *pb.PostReceivePackRequest, body io.Reader) []byte {
+ require.NoError(t, stream.Send(firstRequest))
+
+ sw := streamio.NewWriter(func(p []byte) error {
+ return stream.Send(&pb.PostReceivePackRequest{Data: p})
+ })
+ _, err := io.Copy(sw, body)
+ require.NoError(t, err)
+
+ require.NoError(t, stream.CloseSend())
+
+ responseBuffer := bytes.Buffer{}
+ rr := streamio.NewReader(func() ([]byte, error) {
+ resp, err := stream.Recv()
+ return resp.GetData(), err
+ })
+ _, err = io.Copy(&responseBuffer, rr)
+ require.NoError(t, err)
+
+ return responseBuffer.Bytes()
+}
+
+type pushData struct {
+ newHead string
+ body io.Reader
+}
+
+func newTestPush(t *testing.T, fileContents []byte) *pushData {
+ _, repoPath, localCleanup := testhelper.NewTestRepoWithWorktree(t)
+ defer localCleanup()
+
+ oldHead, newHead := createCommit(t, repoPath, fileContents)
// ReceivePack request is a packet line followed by a packet flush, then the pack file of the objects we want to push.
// This is explained a bit in https://git-scm.com/book/en/v2/Git-Internals-Transfer-Protocols#_uploading_data
// We form the packet line the same way git executable does: https://github.com/git/git/blob/d1a13d3fcb252631361a961cb5e2bf10ed467cba/send-pack.c#L524-L527
+ clientCapabilities := "report-status side-band-64k agent=git/2.12.0"
pkt := fmt.Sprintf("%s %s refs/heads/master\x00 %s", oldHead, newHead, clientCapabilities)
+
// We need to get a pack file containing the objects we want to push, so we use git pack-objects
// which expects a list of revisions passed through standard input. The list format means
// pack the objects needed if I have oldHead but not newHead (think of it from the perspective of the remote repo).
// For more info, check the man pages of both `git-pack-objects` and `git-rev-list --objects`.
- stdin := bytes.NewBufferString(fmt.Sprintf("^%s\n%s\n", oldHead, newHead))
+ stdin := strings.NewReader(fmt.Sprintf("^%s\n%s\n", oldHead, newHead))
+
// The options passed are the same ones used when doing an actual push.
- pack := testhelper.MustRunCommand(t, stdin, "git", "-C", localRepoPath, "pack-objects", "--stdout", "--revs", "--thin", "--delta-base-offset", "-q")
+ pack := testhelper.MustRunCommand(t, stdin, "git", "-C", repoPath, "pack-objects", "--stdout", "--revs", "--thin", "--delta-base-offset", "-q")
// We chop the request into multiple small pieces to exercise the server code that handles
// the stream sent by the client, so we use a buffer to read chunks of data in a nice way.
@@ -71,39 +101,32 @@ func TestSuccessfulReceivePackRequest(t *testing.T) {
fmt.Fprintf(requestBuffer, "%04x%s%s", len(pkt)+4, pkt, pktFlushStr)
requestBuffer.Write(pack)
- client, conn := newSmartHTTPClient(t, serverSocketPath)
- defer conn.Close()
- repo := &pb.Repository{StorageName: "default", RelativePath: remoteRepoRelativePath}
- rpcRequest := &pb.PostReceivePackRequest{Repository: repo, GlId: "user-123", GlRepository: "project-123"}
- ctx, cancel := context.WithCancel(context.Background())
- defer cancel()
- stream, err := client.PostReceivePack(ctx)
- require.NoError(t, err)
+ return &pushData{newHead: newHead, body: requestBuffer}
+}
- require.NoError(t, stream.Send(rpcRequest))
+// createCommit creates a commit on HEAD with a file containing the
+// specified contents.
+func createCommit(t *testing.T, repoPath string, fileContents []byte) (oldHead string, newHead string) {
+ commitMsg := fmt.Sprintf("Testing ReceivePack RPC around %d", time.Now().Unix())
+ committerName := "Scrooge McDuck"
+ committerEmail := "scrooge@mcduck.com"
- sw := streamio.NewWriter(func(p []byte) error {
- return stream.Send(&pb.PostReceivePackRequest{Data: p})
- })
- _, err = io.Copy(sw, requestBuffer)
- require.NoError(t, err)
+ // The latest commit ID on the remote repo
+ oldHead = strings.TrimSpace(string(testhelper.MustRunCommand(t, nil, "git", "-C", repoPath, "rev-parse", "master")))
- stream.CloseSend()
+ changedFile := "README.md"
+ require.NoError(t, ioutil.WriteFile(path.Join(repoPath, changedFile), fileContents, 0644))
- // Verify everything is going as planned
- responseBuffer := bytes.Buffer{}
- rr := streamio.NewReader(func() ([]byte, error) {
- resp, err := stream.Recv()
- return resp.GetData(), err
- })
- _, err = io.Copy(&responseBuffer, rr)
- require.NoError(t, err)
+ testhelper.MustRunCommand(t, nil, "git", "-C", repoPath, "add", changedFile)
+ testhelper.MustRunCommand(t, nil, "git", "-C", repoPath,
+ "-c", fmt.Sprintf("user.name=%s", committerName),
+ "-c", fmt.Sprintf("user.email=%s", committerEmail),
+ "commit", "-m", commitMsg)
- expectedResponse := "0030\x01000eunpack ok\n0019ok refs/heads/master\n00000000"
- require.Equal(t, expectedResponse, responseBuffer.String(), "Expected response to be %q, got %q", expectedResponse, responseBuffer.String())
+ // The commit ID we want to push to the remote repo
+ newHead = strings.TrimSpace(string(testhelper.MustRunCommand(t, nil, "git", "-C", repoPath, "rev-parse", "master")))
- // 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", remoteRepoPath, "show", string(newHead))
+ return oldHead, newHead
}
func TestFailedReceivePackRequestDueToValidationError(t *testing.T) {