diff options
author | Patrick Steinhardt <psteinhardt@gitlab.com> | 2022-07-19 11:13:52 +0300 |
---|---|---|
committer | Patrick Steinhardt <psteinhardt@gitlab.com> | 2022-07-21 07:43:09 +0300 |
commit | 116e021a150ea9cc84cfff74417f7fdacf54e162 (patch) | |
tree | c56050f5b2cf435e64cde7d72897a38aacf624ba | |
parent | a0eef03d641e0b729c8ccca1feaf32f3f31765ec (diff) |
repository: Verify ReplicateRepository works with internal refs
ReplicateRepository must know to replicate all internal references, even
when they're hidden by default. Add testcases to assert that this works
as expected both for the initial seeding and when performing incremental
replication.
-rw-r--r-- | internal/gitaly/service/repository/replicate_test.go | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/internal/gitaly/service/repository/replicate_test.go b/internal/gitaly/service/repository/replicate_test.go index d11706ee8..1ca8258b0 100644 --- a/internal/gitaly/service/repository/replicate_test.go +++ b/internal/gitaly/service/repository/replicate_test.go @@ -18,6 +18,7 @@ import ( "github.com/stretchr/testify/require" "gitlab.com/gitlab-org/gitaly/v15/client" "gitlab.com/gitlab-org/gitaly/v15/internal/backchannel" + "gitlab.com/gitlab-org/gitaly/v15/internal/git" "gitlab.com/gitlab-org/gitaly/v15/internal/git/gittest" "gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo" "gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/config" @@ -107,6 +108,88 @@ func TestReplicateRepository(t *testing.T) { gittest.Exec(t, cfg, "-C", targetRepoPath, "cat-file", "-p", blobID) } +func TestReplicateRepository_hiddenRefs(t *testing.T) { + t.Parallel() + + ctx := testhelper.Context(t) + cfgBuilder := testcfg.NewGitalyCfgBuilder(testcfg.WithStorages("default", "replica")) + cfg := cfgBuilder.Build(t) + + testcfg.BuildGitalyHooks(t, cfg) + testcfg.BuildGitalySSH(t, cfg) + + client, serverSocketPath := runRepositoryService(t, cfg, nil, testserver.WithDisablePraefect()) + cfg.SocketPath = serverSocketPath + + ctx = testhelper.MergeOutgoingMetadata(ctx, testcfg.GitalyServersMetadataFromCfg(t, cfg)) + + t.Run("initial seeding", func(t *testing.T) { + sourceRepo, sourceRepoPath := gittest.InitRepo(t, cfg, cfg.Storages[0]) + + // Create a bunch of internal references, regardless of whether we classify them as hidden + // or read-only. We should be able to replicate all of them. + var expectedRefs []string + for _, refPrefix := range git.InternalRefPrefixes { + commitID := gittest.WriteCommit(t, cfg, sourceRepoPath, gittest.WithParents(), gittest.WithMessage(refPrefix)) + gittest.Exec(t, cfg, "-C", sourceRepoPath, "update-ref", refPrefix+"1", commitID.String()) + expectedRefs = append(expectedRefs, fmt.Sprintf("%s commit\t%s", commitID, refPrefix+"1")) + } + + targetRepo := proto.Clone(sourceRepo).(*gitalypb.Repository) + targetRepo.StorageName = cfg.Storages[1].Name + targetRepoPath := filepath.Join(cfg.Storages[1].Path, targetRepo.GetRelativePath()) + + _, err := client.ReplicateRepository(ctx, &gitalypb.ReplicateRepositoryRequest{ + Repository: targetRepo, + Source: sourceRepo, + }) + require.NoError(t, err) + + require.ElementsMatch(t, expectedRefs, strings.Split(text.ChompBytes(gittest.Exec(t, cfg, "-C", targetRepoPath, "for-each-ref")), "\n")) + + // Perform another sanity-check to verify that source and target repository have the + // same references now. + require.Equal(t, + text.ChompBytes(gittest.Exec(t, cfg, "-C", sourceRepoPath, "for-each-ref")), + text.ChompBytes(gittest.Exec(t, cfg, "-C", targetRepoPath, "for-each-ref")), + ) + }) + + t.Run("incremental replication", func(t *testing.T) { + sourceRepo, sourceRepoPath := gittest.InitRepo(t, cfg, cfg.Storages[0]) + targetRepo, targetRepoPath := gittest.InitRepo(t, cfg, cfg.Storages[1], gittest.InitRepoOpts{ + WithRelativePath: sourceRepo.GetRelativePath(), + }) + + // Create the same commit in both repositories so that they're in a known-good + // state. + sourceCommitID := gittest.WriteCommit(t, cfg, sourceRepoPath, gittest.WithParents(), gittest.WithMessage("base"), gittest.WithBranch("main")) + targetCommitID := gittest.WriteCommit(t, cfg, targetRepoPath, gittest.WithParents(), gittest.WithMessage("base"), gittest.WithBranch("main")) + require.Equal(t, sourceCommitID, targetCommitID) + + // Create the internal references now. + for _, refPrefix := range git.InternalRefPrefixes { + commitID := gittest.WriteCommit(t, cfg, sourceRepoPath, gittest.WithParents(), gittest.WithMessage(refPrefix)) + gittest.Exec(t, cfg, "-C", sourceRepoPath, "update-ref", refPrefix+"1", commitID.String()) + } + + // And now replicate the with the new internal references having been created. + // Because the target repository exists already we'll do a fetch instead of + // replicating via an archive. + _, err := client.ReplicateRepository(ctx, &gitalypb.ReplicateRepositoryRequest{ + Repository: targetRepo, + Source: sourceRepo, + }) + require.NoError(t, err) + + // Verify that the references for both repositories match. + require.Equal(t, + text.ChompBytes(gittest.Exec(t, cfg, "-C", sourceRepoPath, "for-each-ref")), + text.ChompBytes(gittest.Exec(t, cfg, "-C", targetRepoPath, "for-each-ref")), + ) + }) +} + func TestReplicateRepositoryTransactional(t *testing.T) { t.Parallel() |