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:
authorJohn Cai <jcai@gitlab.com>2019-06-27 03:56:17 +0300
committerJohn Cai <jcai@gitlab.com>2019-07-16 23:18:06 +0300
commit495a384d41e8b4ed5a6e3e45375eda6aecd4f4fc (patch)
tree840e0d62f118838e80f7d7d4a1cf1a186655b17d /internal/git
parent0e30a325f79450a90565c2ae2dab756566bc2204 (diff)
Add CloneFromPool and CloneFromPoolInternal RPCs
Diffstat (limited to 'internal/git')
-rw-r--r--internal/git/gittest/http_server.go57
-rw-r--r--internal/git/objectpool/link.go11
-rw-r--r--internal/git/objectpool/link_test.go48
-rw-r--r--internal/git/objectpool/testhelper_test.go17
4 files changed, 122 insertions, 11 deletions
diff --git a/internal/git/gittest/http_server.go b/internal/git/gittest/http_server.go
new file mode 100644
index 000000000..4e5d1916a
--- /dev/null
+++ b/internal/git/gittest/http_server.go
@@ -0,0 +1,57 @@
+package gittest
+
+import (
+ "compress/gzip"
+ "context"
+ "fmt"
+ "net/http"
+ "net/http/httptest"
+ "os/exec"
+ "testing"
+
+ "github.com/stretchr/testify/require"
+ "gitlab.com/gitlab-org/gitaly/internal/command"
+)
+
+// RemoteUploadPackServer implements two HTTP routes for git-upload-pack by copying stdin and stdout into and out of the git upload-pack command
+func RemoteUploadPackServer(ctx context.Context, t *testing.T, repoName, httpToken, repoPath string) (*httptest.Server, string) {
+ s := httptest.NewServer(
+ http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ switch r.URL.String() {
+ case fmt.Sprintf("/%s.git/git-upload-pack", repoName):
+ w.WriteHeader(http.StatusOK)
+
+ var err error
+ reader := r.Body
+
+ if r.Header.Get("Content-Encoding") == "gzip" {
+ reader, err = gzip.NewReader(r.Body)
+ require.NoError(t, err)
+ }
+ defer r.Body.Close()
+
+ cmd, err := command.New(ctx, exec.Command("git", "-C", repoPath, "upload-pack", "--stateless-rpc", "."), reader, w, nil)
+ require.NoError(t, err)
+ require.NoError(t, cmd.Wait())
+ case fmt.Sprintf("/%s.git/info/refs?service=git-upload-pack", repoName):
+ if httpToken != "" && r.Header.Get("Authorization") != httpToken {
+ w.WriteHeader(http.StatusUnauthorized)
+ return
+ }
+ w.Header().Set("Content-Type", "application/x-git-upload-pack-advertisement")
+ w.WriteHeader(http.StatusOK)
+
+ w.Write([]byte("001e# service=git-upload-pack\n"))
+ w.Write([]byte("0000"))
+
+ cmd, err := command.New(ctx, exec.Command("git", "-C", repoPath, "upload-pack", "--advertise-refs", "."), nil, w, nil)
+ require.NoError(t, err)
+ require.NoError(t, cmd.Wait())
+ default:
+ w.WriteHeader(http.StatusNotFound)
+ }
+ }),
+ )
+
+ return s, fmt.Sprintf("%s/%s.git", s.URL, repoName)
+}
diff --git a/internal/git/objectpool/link.go b/internal/git/objectpool/link.go
index ad3cfbc5f..0bc9e75e0 100644
--- a/internal/git/objectpool/link.go
+++ b/internal/git/objectpool/link.go
@@ -36,16 +36,19 @@ func (o *ObjectPool) Link(ctx context.Context, repo *gitalypb.Repository) error
expectedContent := filepath.Join(relPath, "objects")
- actualContent, err := ioutil.ReadFile(altPath)
+ actualContentBytes, err := ioutil.ReadFile(altPath)
if err == nil {
- if text.ChompBytes(actualContent) == expectedContent {
+ actualContent := text.ChompBytes(actualContentBytes)
+ if actualContent == expectedContent {
return nil
}
- return fmt.Errorf("unexpected alternates content: %q", actualContent)
+ if filepath.Clean(actualContent) != filepath.Join(o.FullPath(), "objects") {
+ return fmt.Errorf("unexpected alternates content: %q", actualContent)
+ }
}
- if !os.IsNotExist(err) {
+ if err != nil && !os.IsNotExist(err) {
return err
}
diff --git a/internal/git/objectpool/link_test.go b/internal/git/objectpool/link_test.go
index 84f6d0d0a..c3a7318af 100644
--- a/internal/git/objectpool/link_test.go
+++ b/internal/git/objectpool/link_test.go
@@ -19,8 +19,8 @@ func TestLink(t *testing.T) {
testRepo, _, cleanupFn := testhelper.NewTestRepo(t)
defer cleanupFn()
- pool, err := NewObjectPool(testRepo.GetStorageName(), testhelper.NewTestObjectPoolName(t))
- require.NoError(t, err)
+ pool, poolCleanup := NewTestObjectPool(ctx, t, testRepo.GetStorageName())
+ defer poolCleanup()
require.NoError(t, pool.Remove(ctx), "make sure pool does not exist prior to creation")
require.NoError(t, pool.Create(ctx, testRepo), "create pool")
@@ -56,8 +56,8 @@ func TestLinkRemoveBitmap(t *testing.T) {
testRepo, testRepoPath, cleanupFn := testhelper.NewTestRepo(t)
defer cleanupFn()
- pool, err := NewObjectPool(testRepo.GetStorageName(), testhelper.NewTestObjectPoolName(t))
- require.NoError(t, err)
+ pool, poolCleanup := NewTestObjectPool(ctx, t, testRepo.GetStorageName())
+ defer poolCleanup()
require.NoError(t, pool.Init(ctx))
@@ -104,9 +104,8 @@ func TestUnlink(t *testing.T) {
testRepo, _, cleanupFn := testhelper.NewTestRepo(t)
defer cleanupFn()
- pool, err := NewObjectPool(testRepo.GetStorageName(), t.Name())
- require.NoError(t, err)
- defer pool.Remove(ctx)
+ pool, poolCleanup := NewTestObjectPool(ctx, t, testRepo.GetStorageName())
+ defer poolCleanup()
require.Error(t, pool.Unlink(ctx, testRepo), "removing a non-existing pool should be an error")
@@ -118,3 +117,38 @@ func TestUnlink(t *testing.T) {
require.NoError(t, pool.Unlink(ctx, testRepo), "unlink repo")
require.False(t, testhelper.RemoteExists(t, pool.FullPath(), testRepo.GetGlRepository()), "pool remotes should no longer include %v", testRepo)
}
+
+func TestLinkAbsoluteLinkExists(t *testing.T) {
+ ctx, cancel := testhelper.Context()
+ defer cancel()
+
+ testRepo, testRepoPath, cleanupFn := testhelper.NewTestRepo(t)
+ defer cleanupFn()
+
+ pool, poolCleanup := NewTestObjectPool(ctx, t, testRepo.GetStorageName())
+ defer poolCleanup()
+
+ require.NoError(t, pool.Remove(ctx), "make sure pool does not exist prior to creation")
+ require.NoError(t, pool.Create(ctx, testRepo), "create pool")
+
+ altPath, err := git.InfoAlternatesPath(testRepo)
+ require.NoError(t, err)
+
+ fullPath := filepath.Join(pool.FullPath(), "objects")
+
+ require.NoError(t, ioutil.WriteFile(altPath, []byte(fullPath), 0644))
+
+ require.NoError(t, pool.Link(ctx, testRepo), "we expect this call to change the absolute link to a relative link")
+
+ require.FileExists(t, altPath, "alternates file must exist after Link")
+
+ content, err := ioutil.ReadFile(altPath)
+ require.NoError(t, err)
+
+ require.False(t, filepath.IsAbs(string(content)), "expected %q to be relative path", content)
+
+ testRepoObjectsPath := filepath.Join(testRepoPath, "objects")
+ require.Equal(t, fullPath, filepath.Join(testRepoObjectsPath, string(content)), "the content of the alternates file should be the relative version of the absolute pat")
+
+ require.True(t, testhelper.RemoteExists(t, pool.FullPath(), "origin"), "pool remotes should include %v", testRepo)
+}
diff --git a/internal/git/objectpool/testhelper_test.go b/internal/git/objectpool/testhelper_test.go
new file mode 100644
index 000000000..f616fdeae
--- /dev/null
+++ b/internal/git/objectpool/testhelper_test.go
@@ -0,0 +1,17 @@
+package objectpool
+
+import (
+ "context"
+ "testing"
+
+ "github.com/stretchr/testify/require"
+ "gitlab.com/gitlab-org/gitaly/internal/testhelper"
+)
+
+func NewTestObjectPool(ctx context.Context, t *testing.T, storageName string) (*ObjectPool, func()) {
+ pool, err := NewObjectPool(storageName, testhelper.NewTestObjectPoolName(t))
+ require.NoError(t, err)
+ return pool, func() {
+ require.NoError(t, pool.Remove(ctx))
+ }
+}