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:
authorPatrick Steinhardt <psteinhardt@gitlab.com>2021-12-15 14:50:11 +0300
committerPatrick Steinhardt <psteinhardt@gitlab.com>2021-12-15 16:39:49 +0300
commitefb0b8d78638607915dd6a0dfa772edd3d1ba1c6 (patch)
treed22f6d8a290fdd8cc8a7524fbe859eb382e69453
parent0abd8d93ab7f70f444cd10a65ad9d3f616adaf57 (diff)
repository: Rewrite tests which write commits into alternate ODBs
Rewrite tests which write commits into alternate ODBs to use `gittest.WriteCommit()`. Note that the tests are converted to use bare Git repositories because the helper doesn't need a working tree. This is closer to how repositories would look like in production.
-rw-r--r--internal/gitaly/service/repository/repack_test.go28
-rw-r--r--internal/gitaly/service/repository/snapshot_test.go170
2 files changed, 104 insertions, 94 deletions
diff --git a/internal/gitaly/service/repository/repack_test.go b/internal/gitaly/service/repository/repack_test.go
index 643e5bea6..9757f9459 100644
--- a/internal/gitaly/service/repository/repack_test.go
+++ b/internal/gitaly/service/repository/repack_test.go
@@ -1,7 +1,6 @@
package repository
import (
- "os/exec"
"path/filepath"
"testing"
"time"
@@ -60,18 +59,23 @@ func TestRepackIncrementalCollectLogStatistics(t *testing.T) {
func TestRepackLocal(t *testing.T) {
t.Parallel()
- cfg, repo, repoPath, client := setupRepositoryServiceWithWorktree(t)
- commiterArgs := []string{"-c", "user.name=Scrooge McDuck", "-c", "user.email=scrooge@mcduck.com"}
- cmdArgs := append(commiterArgs, "-C", repoPath, "commit", "--allow-empty", "-m", "An empty commit")
- cmd := exec.Command(cfg.Git.BinPath, cmdArgs...)
+ cfg, repo, repoPath, client := setupRepositoryService(t)
+
altObjectsDir := "./alt-objects"
- altDirsCommit := gittest.CreateCommitInAlternateObjectDirectory(t, cfg.Git.BinPath, repoPath, altObjectsDir, cmd)
+ alternateCommit := gittest.WriteCommit(t, cfg, repoPath,
+ gittest.WithMessage("alternate commit"),
+ gittest.WithAlternateObjectDirectory(filepath.Join(repoPath, altObjectsDir)),
+ gittest.WithBranch("alternate-odb"),
+ )
- repoCommit := gittest.WriteCommit(t, cfg, repoPath, gittest.WithBranch(t.Name()))
+ repoCommit := gittest.WriteCommit(t, cfg, repoPath,
+ gittest.WithMessage("main commit"),
+ gittest.WithBranch("main-odb"),
+ )
- ctx, cancelFn := testhelper.Context()
- defer cancelFn()
+ ctx, cancel := testhelper.Context()
+ defer cancel()
// Set GIT_ALTERNATE_OBJECT_DIRECTORIES on the outgoing request. The
// intended use case of the behavior we're testing here is that
@@ -82,13 +86,13 @@ func TestRepackLocal(t *testing.T) {
_, err := client.RepackFull(ctx, &gitalypb.RepackFullRequest{Repository: repo})
require.NoError(t, err)
- packFiles, err := filepath.Glob(filepath.Join(repoPath, ".git", "objects", "pack", "pack-*.pack"))
+ packFiles, err := filepath.Glob(filepath.Join(repoPath, "objects", "pack", "pack-*.pack"))
require.NoError(t, err)
require.Len(t, packFiles, 1)
packContents := gittest.Exec(t, cfg, "-C", repoPath, "verify-pack", "-v", packFiles[0])
- require.NotContains(t, string(packContents), string(altDirsCommit))
- require.Contains(t, string(packContents), repoCommit)
+ require.NotContains(t, string(packContents), alternateCommit.String())
+ require.Contains(t, string(packContents), repoCommit.String())
}
func TestRepackIncrementalFailure(t *testing.T) {
diff --git a/internal/gitaly/service/repository/snapshot_test.go b/internal/gitaly/service/repository/snapshot_test.go
index bf276a189..321909607 100644
--- a/internal/gitaly/service/repository/snapshot_test.go
+++ b/internal/gitaly/service/repository/snapshot_test.go
@@ -7,17 +7,12 @@ import (
"io"
"net/http/httptest"
"os"
- "os/exec"
"path/filepath"
"strings"
"testing"
- "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
- "gitlab.com/gitlab-org/gitaly/v14/internal/git"
- "gitlab.com/gitlab-org/gitaly/v14/internal/git/catfile"
"gitlab.com/gitlab-org/gitaly/v14/internal/git/gittest"
- "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo"
"gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/archive"
"gitlab.com/gitlab-org/gitaly/v14/internal/gitaly/config"
"gitlab.com/gitlab-org/gitaly/v14/internal/metadata/featureflag"
@@ -95,7 +90,7 @@ func TestGetSnapshotWithDedupe(t *testing.T) {
func testGetSnapshotWithDedupe(t *testing.T, ctx context.Context) {
for _, tc := range []struct {
desc string
- alternatePathFunc func(t *testing.T, storageDir, objDir string) string
+ alternatePathFunc func(t *testing.T, storageDir, repoPath string) string
}{
{
desc: "subdirectory",
@@ -119,46 +114,40 @@ func testGetSnapshotWithDedupe(t *testing.T, ctx context.Context) {
},
} {
t.Run(tc.desc, func(t *testing.T) {
- cfg, repoProto, repoPath, client := setupRepositoryServiceWithWorktree(t)
- repo := localrepo.NewTestRepo(t, cfg, repoProto)
+ cfg, repoProto, repoPath, client := setupRepositoryService(t)
- const committerName = "Scrooge McDuck"
- const committerEmail = "scrooge@mcduck.com"
-
- cmd := exec.Command(cfg.Git.BinPath, "-C", repoPath,
- "-c", fmt.Sprintf("user.name=%s", committerName),
- "-c", fmt.Sprintf("user.email=%s", committerEmail),
- "commit", "--allow-empty", "-m", "An empty commit")
alternateObjDir := tc.alternatePathFunc(t, cfg.Storages[0].Path, filepath.Join(repoPath, "objects"))
- commitSha := gittest.CreateCommitInAlternateObjectDirectory(t, cfg.Git.BinPath, repoPath, alternateObjDir, cmd)
- originalAlternatesCommit := string(commitSha)
+ absoluteAlternateObjDir := alternateObjDir
+ if !filepath.IsAbs(alternateObjDir) {
+ absoluteAlternateObjDir = filepath.Join(repoPath, "objects", alternateObjDir)
+ }
+
+ firstCommitID := gittest.WriteCommit(t, cfg, repoPath,
+ gittest.WithMessage("An empty commit"),
+ gittest.WithAlternateObjectDirectory(absoluteAlternateObjDir),
+ )
locator := config.NewLocator(cfg)
- catfileCache := catfile.NewCache(cfg)
- defer catfileCache.Stop()
- // ensure commit cannot be found in current repository
- objectInfoReader, err := catfileCache.ObjectInfoReader(ctx, repo)
- require.NoError(t, err)
- _, err = objectInfoReader.Info(ctx, git.Revision(originalAlternatesCommit))
- require.True(t, catfile.IsNotFound(err))
+ // We haven't yet written the alternates file, and thus we shouldn't be able
+ // to find this commit yet.
+ gittest.RequireObjectNotExists(t, cfg, repoPath, firstCommitID)
- // write alternates file to point to alt objects folder
+ // Write alternates file to point to alt objects folder.
alternatesPath, err := locator.InfoAlternatesPath(repoProto)
require.NoError(t, err)
- require.NoError(t, os.WriteFile(alternatesPath, []byte(filepath.Join(repoPath, ".git", fmt.Sprintf("%s\n", alternateObjDir))), 0o644))
+ require.NoError(t, os.WriteFile(alternatesPath, []byte(fmt.Sprintf("%s\n", alternateObjDir)), 0o644))
- // write another commit and ensure we can find it
- cmd = exec.Command(cfg.Git.BinPath, "-C", repoPath,
- "-c", fmt.Sprintf("user.name=%s", committerName),
- "-c", fmt.Sprintf("user.email=%s", committerEmail),
- "commit", "--allow-empty", "-m", "Another empty commit")
- commitSha = gittest.CreateCommitInAlternateObjectDirectory(t, cfg.Git.BinPath, repoPath, alternateObjDir, cmd)
+ // Write another commit into the alternate object directory.
+ secondCommitID := gittest.WriteCommit(t, cfg, repoPath,
+ gittest.WithMessage("Another empty commit"),
+ gittest.WithAlternateObjectDirectory(absoluteAlternateObjDir),
+ )
- objectInfoReader, err = catfileCache.ObjectInfoReader(ctx, repo)
- require.NoError(t, err)
- _, err = objectInfoReader.Info(ctx, git.Revision(commitSha))
- require.NoError(t, err)
+ // We should now be able to find both commits given that the alternates file
+ // points to the object directory we've created them in.
+ gittest.RequireObjectExists(t, cfg, repoPath, firstCommitID)
+ gittest.RequireObjectExists(t, cfg, repoPath, secondCommitID)
repoCopy, _ := copyRepoUsingSnapshot(t, ctx, cfg, client, repoProto)
repoCopy.RelativePath = getReplicaPath(ctx, t, client, repoCopy)
@@ -166,75 +155,92 @@ func testGetSnapshotWithDedupe(t *testing.T, ctx context.Context) {
require.NoError(t, err)
// ensure the sha committed to the alternates directory can be accessed
- gittest.Exec(t, cfg, "-C", repoCopyPath, "cat-file", "-p", originalAlternatesCommit)
+ gittest.Exec(t, cfg, "-C", repoCopyPath, "cat-file", "-p", firstCommitID.String())
gittest.Exec(t, cfg, "-C", repoCopyPath, "fsck")
})
}
}
-func TestGetSnapshotWithDedupeSoftFailures(t *testing.T) {
+func TestGetSnapshot_alternateObjectDirectory(t *testing.T) {
t.Parallel()
- testhelper.NewFeatureSets(featureflag.TxAtomicRepositoryCreation).Run(t, testGetSnapshotWithDedupeSoftFailures)
+ testhelper.NewFeatureSets(featureflag.TxAtomicRepositoryCreation).Run(t, testGetSnapshotAlternateObjectDirectory)
}
-func testGetSnapshotWithDedupeSoftFailures(t *testing.T, ctx context.Context) {
+func testGetSnapshotAlternateObjectDirectory(t *testing.T, ctx context.Context) {
cfg, client := setupRepositoryServiceWithoutRepo(t)
- testRepo, repoPath := gittest.CloneRepo(t, cfg, cfg.Storages[0], gittest.CloneRepoOpts{
- WithWorktree: true,
- })
+ repo, repoPath := gittest.CloneRepo(t, cfg, cfg.Storages[0])
locator := config.NewLocator(cfg)
-
- // write alternates file to point to alternates objects folder that doesn't exist
- alternateObjDir := "./alt-objects"
- alternateObjPath := filepath.Join(repoPath, ".git", alternateObjDir)
- alternatesPath, err := locator.InfoAlternatesPath(testRepo)
+ alternatesFile, err := locator.InfoAlternatesPath(repo)
require.NoError(t, err)
- require.NoError(t, os.WriteFile(alternatesPath, []byte(fmt.Sprintf("%s\n", alternateObjPath)), 0o644))
- req := &gitalypb.GetSnapshotRequest{Repository: testRepo}
- _, err = getSnapshot(client, req)
- assert.NoError(t, err)
- require.NoError(t, os.Remove(alternatesPath))
+ req := &gitalypb.GetSnapshotRequest{Repository: repo}
+
+ t.Run("nonexistent", func(t *testing.T) {
+ alternateObjectDir := filepath.Join(repoPath, "does-not-exist")
- // write alternates file to point outside storage root
- storageRoot, err := locator.GetStorageByName(testRepo.GetStorageName())
- require.NoError(t, err)
- require.NoError(t, os.WriteFile(alternatesPath, []byte(filepath.Join(storageRoot, "..")), 0o600))
+ require.NoError(t, os.WriteFile(alternatesFile, []byte(fmt.Sprintf("%s\n", alternateObjectDir)), 0o644))
+ defer func() {
+ require.NoError(t, os.Remove(alternatesFile))
+ }()
+
+ _, err = getSnapshot(client, req)
+ require.NoError(t, err)
+ })
- _, err = getSnapshot(client, &gitalypb.GetSnapshotRequest{Repository: testRepo})
- assert.NoError(t, err)
- require.NoError(t, os.Remove(alternatesPath))
+ t.Run("escape storage root", func(t *testing.T) {
+ storageRoot, err := locator.GetStorageByName(repo.GetStorageName())
+ require.NoError(t, err)
- // write alternates file with bad permissions
- require.NoError(t, os.WriteFile(alternatesPath, []byte(fmt.Sprintf("%s\n", alternateObjPath)), 0o000))
- _, err = getSnapshot(client, req)
- assert.NoError(t, err)
- require.NoError(t, os.Remove(alternatesPath))
+ alternateObjectDir := filepath.Join(storageRoot, "..")
- // write alternates file without newline
- committerName := "Scrooge McDuck"
- committerEmail := "scrooge@mcduck.com"
+ require.NoError(t, os.WriteFile(alternatesFile, []byte(alternateObjectDir), 0o600))
+ defer func() {
+ require.NoError(t, os.Remove(alternatesFile))
+ }()
- cmd := exec.Command(cfg.Git.BinPath, "-C", repoPath,
- "-c", fmt.Sprintf("user.name=%s", committerName),
- "-c", fmt.Sprintf("user.email=%s", committerEmail),
- "commit", "--allow-empty", "-m", "An empty commit")
+ _, err = getSnapshot(client, &gitalypb.GetSnapshotRequest{Repository: repo})
+ require.NoError(t, err)
+ })
- commitSha := gittest.CreateCommitInAlternateObjectDirectory(t, cfg.Git.BinPath, repoPath, alternateObjDir, cmd)
- originalAlternatesCommit := string(commitSha)
+ t.Run("bad permissions", func(t *testing.T) {
+ alternateObjectDir := filepath.Join(repoPath, "bad-permissions")
- require.NoError(t, os.WriteFile(alternatesPath, []byte(alternateObjPath), 0o644))
+ require.NoError(t, os.WriteFile(alternatesFile, []byte(fmt.Sprintf("%s\n", alternateObjectDir)), 0o000))
+ defer func() {
+ require.NoError(t, os.Remove(alternatesFile))
+ }()
- repoCopy, _ := copyRepoUsingSnapshot(t, ctx, cfg, client, testRepo)
- repoCopy.RelativePath = getReplicaPath(ctx, t, client, repoCopy)
- repoCopyPath, err := locator.GetRepoPath(repoCopy)
- require.NoError(t, err)
+ _, err = getSnapshot(client, req)
+ require.NoError(t, err)
+ })
- // ensure the sha committed to the alternates directory can be accessed
- gittest.Exec(t, cfg, "-C", repoCopyPath, "cat-file", "-p", originalAlternatesCommit)
- gittest.Exec(t, cfg, "-C", repoCopyPath, "fsck")
+ t.Run("valid alternate object directory", func(t *testing.T) {
+ alternateObjectDir := filepath.Join(repoPath, "valid-odb")
+
+ commitID := gittest.WriteCommit(t, cfg, repoPath,
+ gittest.WithAlternateObjectDirectory(alternateObjectDir),
+ // Create a branch with the commit such that the snapshot would indeed treat
+ // this commit as referenced.
+ gittest.WithBranch("some-branch"),
+ )
+
+ require.NoError(t, os.WriteFile(alternatesFile, []byte(alternateObjectDir), 0o644))
+ defer func() {
+ require.NoError(t, os.Remove(alternatesFile))
+ }()
+
+ repoCopy, _ := copyRepoUsingSnapshot(t, ctx, cfg, client, repo)
+ repoCopy.RelativePath = getReplicaPath(ctx, t, client, repoCopy)
+ repoCopyPath, err := locator.GetRepoPath(repoCopy)
+ require.NoError(t, err)
+
+ // Ensure the object committed to the alternates directory can be accessed and that
+ // the repository is consistent.
+ gittest.Exec(t, cfg, "-C", repoCopyPath, "cat-file", "-p", commitID.String())
+ gittest.Exec(t, cfg, "-C", repoCopyPath, "fsck")
+ })
}
// copyRepoUsingSnapshot creates a tarball snapshot, then creates a new repository from that snapshot