From a605257574fb74d9c5bc430a9d8c0c5c37f86fd2 Mon Sep 17 00:00:00 2001 From: Pavlo Strokov Date: Wed, 3 Mar 2021 11:49:09 +0200 Subject: partial building Part of: https://gitlab.com/gitlab-org/gitaly/-/issues/2699 --- cmd/gitaly-hooks/hooks_test.go | 2 +- cmd/gitaly-ssh/auth_test.go | 2 +- internal/git/gittest/commit.go | 4 +- internal/git/gittest/protocol.go | 2 +- internal/git/gittest/repo.go | 8 + internal/git/localrepo/remote_test.go | 2 +- internal/git2go/apply_test.go | 2 +- internal/git2go/commit_test.go | 2 +- internal/gitaly/service/blob/lfs_pointers_test.go | 4 +- .../gitaly/service/commit/find_commits_test.go | 5 +- internal/gitaly/service/commit/isancestor_test.go | 5 +- internal/gitaly/service/operations/merge_test.go | 4 +- internal/gitaly/service/operations/tags_test.go | 12 +- internal/gitaly/service/ref/refs_test.go | 4 +- .../service/repository/calculate_checksum_test.go | 2 +- internal/gitaly/service/repository/cleanup_test.go | 2 +- .../service/repository/clone_from_pool_test.go | 3 +- .../repository/redirecting_test_server_test.go | 3 +- internal/gitaly/service/repository/rename_test.go | 4 +- internal/gitaly/service/repository/repack_test.go | 4 +- .../gitaly/service/repository/snapshot_test.go | 12 +- internal/gitaly/service/smarthttp/inforefs_test.go | 171 +++++++------- .../gitaly/service/smarthttp/receive_pack_test.go | 248 +++++++++++---------- .../gitaly/service/smarthttp/testhelper_test.go | 12 - .../gitaly/service/smarthttp/upload_pack_test.go | 137 ++++++------ internal/gitaly/service/ssh/receive_pack_test.go | 145 ++++++------ internal/gitaly/service/ssh/testhelper_test.go | 16 +- internal/gitaly/service/ssh/upload_archive_test.go | 8 +- internal/gitaly/service/ssh/upload_pack_test.go | 115 +++++----- internal/testhelper/configure.go | 51 +++++ internal/testhelper/testcfg/gitaly_builder.go | 60 +++-- internal/testhelper/testserver.go | 6 +- 32 files changed, 588 insertions(+), 469 deletions(-) diff --git a/cmd/gitaly-hooks/hooks_test.go b/cmd/gitaly-hooks/hooks_test.go index 002957471..d15a19f99 100644 --- a/cmd/gitaly-hooks/hooks_test.go +++ b/cmd/gitaly-hooks/hooks_test.go @@ -695,7 +695,7 @@ func TestGitalyHooksPackObjects(t *testing.T) { env := envForHooks(t, logDir, testRepo, glHookValues{}, proxyValues{}) baseArgs := []string{ - config.Config.Git.BinPath, + "git", "clone", "-u", "git -c uploadpack.allowFilter -c uploadpack.packObjectsHook=" + config.Config.BinDir + "/gitaly-hooks upload-pack", diff --git a/cmd/gitaly-ssh/auth_test.go b/cmd/gitaly-ssh/auth_test.go index 50160eb0c..b5a46654a 100644 --- a/cmd/gitaly-ssh/auth_test.go +++ b/cmd/gitaly-ssh/auth_test.go @@ -102,7 +102,7 @@ func TestConnectivity(t *testing.T) { require.NoError(t, err) for _, testcase := range testCases { t.Run(testcase.name, func(t *testing.T) { - cmd := exec.Command(config.Config.Git.BinPath, "ls-remote", "git@localhost:test/test.git", "refs/heads/master") + cmd := exec.Command("git", "ls-remote", "git@localhost:test/test.git", "refs/heads/master") cmd.Stderr = os.Stderr cmd.Env = []string{ fmt.Sprintf("GITALY_PAYLOAD=%s", payload), diff --git a/internal/git/gittest/commit.go b/internal/git/gittest/commit.go index 29a3ea6e5..e6ea283d2 100644 --- a/internal/git/gittest/commit.go +++ b/internal/git/gittest/commit.go @@ -64,7 +64,7 @@ func CreateCommit(t testing.TB, repoPath, branchName string, opts *CreateCommitO // CreateCommitInAlternateObjectDirectory runs a command such that its created // objects will live in an alternate objects directory. It returns the current // head after the command is run and the alternate objects directory path -func CreateCommitInAlternateObjectDirectory(t testing.TB, gitBin, repoPath, altObjectsDir string, cmd *exec.Cmd) (currentHead []byte) { +func CreateCommitInAlternateObjectDirectory(t testing.TB, repoPath, altObjectsDir string, cmd *exec.Cmd) (currentHead []byte) { gitPath := filepath.Join(repoPath, ".git") altObjectsPath := filepath.Join(gitPath, altObjectsDir) @@ -82,7 +82,7 @@ func CreateCommitInAlternateObjectDirectory(t testing.TB, gitBin, repoPath, altO t.Fatalf("stdout: %s, stderr: %s", output, stderr) } - cmd = exec.Command(gitBin, "-C", repoPath, "rev-parse", "HEAD") + cmd = exec.Command("git", "-C", repoPath, "rev-parse", "HEAD") cmd.Env = gitObjectEnv currentHead, err := cmd.Output() require.NoError(t, err) diff --git a/internal/git/gittest/protocol.go b/internal/git/gittest/protocol.go index fb5c61d23..bf45c3f64 100644 --- a/internal/git/gittest/protocol.go +++ b/internal/git/gittest/protocol.go @@ -23,7 +23,7 @@ func EnableGitProtocolV2Support(t testing.TB, cfg config.Cfg) (func() string, co script := fmt.Sprintf(`#!/bin/sh env | grep ^GIT_PROTOCOL= >>"%s" exec "%s" "$@" -`, envPath, config.Config.Git.BinPath) +`, envPath, cfg.Git.BinPath) cleanupExe := testhelper.WriteExecutable(t, gitPath, []byte(script)) diff --git a/internal/git/gittest/repo.go b/internal/git/gittest/repo.go index 53bac2e1a..44e1d401b 100644 --- a/internal/git/gittest/repo.go +++ b/internal/git/gittest/repo.go @@ -118,6 +118,14 @@ func CloneRepoWithWorktree(t testing.TB) (repo *gitalypb.Repository, repoPath st return cloneRepo(t, testhelper.GitlabTestStoragePath(), NewRepositoryName(t, false), false) } +// CloneRepoWithWorktree creates a copy of the test repository with a worktree. This is allows you +// to run normal 'non-bare' Git commands. +func CloneRepoWithWorktreeAtStorage(t testing.TB, storage config.Storage) (*gitalypb.Repository, string, testhelper.Cleanup) { + repo, repoPath, cleanup := cloneRepo(t, storage.Path, NewRepositoryName(t, false), false) + repo.StorageName = storage.Name + return repo, repoPath, cleanup +} + // testRepositoryPath returns the absolute path of local 'gitlab-org/gitlab-test.git' clone. // It is cloned under the path by the test preparing step of make. func testRepositoryPath(t testing.TB) string { diff --git a/internal/git/localrepo/remote_test.go b/internal/git/localrepo/remote_test.go index 5e4cd31b5..9b01ac32c 100644 --- a/internal/git/localrepo/remote_test.go +++ b/internal/git/localrepo/remote_test.go @@ -321,7 +321,7 @@ func TestRepo_FetchRemote(t *testing.T) { testRepo, testRepoPath, cleanup := gittest.InitBareRepo(t) - cmd := exec.Command(config.Config.Git.BinPath, "-C", testRepoPath, "remote", "add", remote, remoteRepoPath) + cmd := exec.Command("git", "-C", testRepoPath, "remote", "add", remote, remoteRepoPath) err := cmd.Run() if err != nil { cleanup() diff --git a/internal/git2go/apply_test.go b/internal/git2go/apply_test.go index 2c499ae92..1aa38f0ff 100644 --- a/internal/git2go/apply_test.go +++ b/internal/git2go/apply_test.go @@ -20,7 +20,7 @@ func TestExecutor_Apply(t *testing.T) { defer clean() repo := localrepo.New(git.NewExecCommandFactory(config.Config), pbRepo, config.Config) - executor := New(filepath.Join(config.Config.BinDir, "gitaly-git2go"), config.Config.Git.BinPath) + executor := New(filepath.Join(config.Config.BinDir, "gitaly-git2go"), "git") ctx, cancel := testhelper.Context() defer cancel() diff --git a/internal/git2go/commit_test.go b/internal/git2go/commit_test.go index 2dba64404..d15b70734 100644 --- a/internal/git2go/commit_test.go +++ b/internal/git2go/commit_test.go @@ -65,7 +65,7 @@ func TestExecutor_Commit(t *testing.T) { updatedFile, err := repo.WriteBlob(ctx, "file", bytes.NewBufferString("updated")) require.NoError(t, err) - executor := New(filepath.Join(config.Config.BinDir, "gitaly-git2go"), config.Config.Git.BinPath) + executor := New(filepath.Join(config.Config.BinDir, "gitaly-git2go"), "git") for _, tc := range []struct { desc string diff --git a/internal/gitaly/service/blob/lfs_pointers_test.go b/internal/gitaly/service/blob/lfs_pointers_test.go index 7187edb7f..e3685c029 100644 --- a/internal/gitaly/service/blob/lfs_pointers_test.go +++ b/internal/gitaly/service/blob/lfs_pointers_test.go @@ -189,11 +189,11 @@ func testSuccessfulGetNewLFSPointersRequest(t *testing.T, ctx context.Context) { revision := []byte("46abbb087fcc0fd02c340f0f2f052bd2c7708da3") commiterArgs := []string{"-c", "user.name=Scrooge McDuck", "-c", "user.email=scrooge@mcduck.com"} cmdArgs := append(commiterArgs, "-C", testRepoPath, "cherry-pick", string(revision)) - cmd := exec.Command(config.Config.Git.BinPath, cmdArgs...) + cmd := exec.Command("git", cmdArgs...) // Skip smudge since it doesn't work with file:// remotes and we don't need it cmd.Env = append(cmd.Env, "GIT_LFS_SKIP_SMUDGE=1") altDirs := "./alt-objects" - altDirsCommit := gittest.CreateCommitInAlternateObjectDirectory(t, config.Config.Git.BinPath, testRepoPath, altDirs, cmd) + altDirsCommit := gittest.CreateCommitInAlternateObjectDirectory(t, testRepoPath, altDirs, cmd) // Create a commit not pointed at by any ref to emulate being in the // pre-receive hook so that `--not --all` returns some objects diff --git a/internal/gitaly/service/commit/find_commits_test.go b/internal/gitaly/service/commit/find_commits_test.go index 2a89f693f..a196f768f 100644 --- a/internal/gitaly/service/commit/find_commits_test.go +++ b/internal/gitaly/service/commit/find_commits_test.go @@ -12,7 +12,6 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "gitlab.com/gitlab-org/gitaly/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/internal/gitaly/config" "gitlab.com/gitlab-org/gitaly/internal/testhelper" "gitlab.com/gitlab-org/gitaly/proto/go/gitalypb" "google.golang.org/grpc/codes" @@ -461,12 +460,12 @@ func TestSuccessfulFindCommitsRequestWithAltGitObjectDirs(t *testing.T) { testRepoCopy, testRepoCopyPath, cleanupFn := gittest.CloneRepoWithWorktree(t) defer cleanupFn() - cmd := exec.Command(config.Config.Git.BinPath, "-C", testRepoCopyPath, + cmd := exec.Command("git", "-C", testRepoCopyPath, "-c", fmt.Sprintf("user.name=%s", committerName), "-c", fmt.Sprintf("user.email=%s", committerEmail), "commit", "--allow-empty", "-m", "An empty commit") altObjectsDir := "./alt-objects" - currentHead := gittest.CreateCommitInAlternateObjectDirectory(t, config.Config.Git.BinPath, testRepoCopyPath, altObjectsDir, cmd) + currentHead := gittest.CreateCommitInAlternateObjectDirectory(t, testRepoCopyPath, altObjectsDir, cmd) testCases := []struct { desc string diff --git a/internal/gitaly/service/commit/isancestor_test.go b/internal/gitaly/service/commit/isancestor_test.go index 8720b18e1..9f7ed5eba 100644 --- a/internal/gitaly/service/commit/isancestor_test.go +++ b/internal/gitaly/service/commit/isancestor_test.go @@ -7,7 +7,6 @@ import ( "github.com/stretchr/testify/require" "gitlab.com/gitlab-org/gitaly/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/internal/gitaly/config" "gitlab.com/gitlab-org/gitaly/internal/helper" "gitlab.com/gitlab-org/gitaly/internal/testhelper" "gitlab.com/gitlab-org/gitaly/proto/go/gitalypb" @@ -192,12 +191,12 @@ func TestSuccessfulIsAncestorRequestWithAltGitObjectDirs(t *testing.T) { previousHead := testhelper.MustRunCommand(t, nil, "git", "-C", testRepoCopyPath, "show", "--format=format:%H", "--no-patch", "HEAD") - cmd := exec.Command(config.Config.Git.BinPath, "-C", testRepoCopyPath, + cmd := exec.Command("git", "-C", testRepoCopyPath, "-c", fmt.Sprintf("user.name=%s", committerName), "-c", fmt.Sprintf("user.email=%s", committerEmail), "commit", "--allow-empty", "-m", "An empty commit") altObjectsDir := "./alt-objects" - currentHead := gittest.CreateCommitInAlternateObjectDirectory(t, config.Config.Git.BinPath, testRepoCopyPath, altObjectsDir, cmd) + currentHead := gittest.CreateCommitInAlternateObjectDirectory(t, testRepoCopyPath, altObjectsDir, cmd) testCases := []struct { desc string diff --git a/internal/gitaly/service/operations/merge_test.go b/internal/gitaly/service/operations/merge_test.go index 74df8510e..5902eac12 100644 --- a/internal/gitaly/service/operations/merge_test.go +++ b/internal/gitaly/service/operations/merge_test.go @@ -689,7 +689,7 @@ func TestSuccessfulUserMergeToRefRequest(t *testing.T) { // Writes in existingTargetRef beforeRefreshCommitSha := "a5391128b0ef5d21df5dd23d98557f4ef12fae20" - out, err := exec.Command(config.Config.Git.BinPath, "-C", repoPath, "update-ref", string(existingTargetRef), beforeRefreshCommitSha).CombinedOutput() + out, err := exec.Command("git", "-C", repoPath, "update-ref", string(existingTargetRef), beforeRefreshCommitSha).CombinedOutput() require.NoError(t, err, "give an existing state to the target ref: %s", out) testCases := []struct { @@ -808,7 +808,7 @@ func TestConflictsOnUserMergeToRefRequest(t *testing.T) { require.NoError(t, err) var buf bytes.Buffer - cmd := exec.Command(config.Config.Git.BinPath, "-C", testRepoPath, "show", resp.CommitId) + cmd := exec.Command("git", "-C", testRepoPath, "show", resp.CommitId) cmd.Stdout = &buf require.NoError(t, cmd.Run()) diff --git a/internal/gitaly/service/operations/tags_test.go b/internal/gitaly/service/operations/tags_test.go index 50ee82327..d378bb27c 100644 --- a/internal/gitaly/service/operations/tags_test.go +++ b/internal/gitaly/service/operations/tags_test.go @@ -104,7 +104,7 @@ func testSuccessfulGitHooksForUserDeleteTagRequest(t *testing.T, ctx context.Con func writeAssertObjectTypePreReceiveHook(t *testing.T) (string, func()) { t.Helper() - hook := fmt.Sprintf(`#!/usr/bin/env ruby + hook := `#!/usr/bin/env ruby # We match a non-ASCII ref_name below Encoding.default_external = Encoding::UTF_8 @@ -119,7 +119,7 @@ end old_value, new_value, ref_name = commands[0].split(' ', 3) abort 'missing new_value' unless new_value -out = IO.popen(%%W[%s cat-file -t #{new_value}], &:read) +out = IO.popen(%%W[git cat-file -t #{new_value}], &:read) abort 'cat-file failed' unless $?.success? if ref_name =~ /^refs\/[^\/]+\/skip-type-check-/ @@ -128,7 +128,7 @@ end unless out.chomp == expected_object_type abort "pre-receive hook error: expected '#{ref_name}' update of '#{old_value}' (a) -> '#{new_value}' (b) for 'b' to be a '#{expected_object_type}' object, got '#{out}'" -end`, config.Config.Git.BinPath) +end` dir, cleanup := testhelper.TempDir(t) hookPath := filepath.Join(dir, "pre-receive") @@ -141,7 +141,7 @@ end`, config.Config.Git.BinPath) func writeAssertObjectTypeUpdateHook(t *testing.T) (string, func()) { t.Helper() - hook := fmt.Sprintf(`#!/usr/bin/env ruby + hook := `#!/usr/bin/env ruby # We match a non-ASCII ref_name below Encoding.default_external = Encoding::UTF_8 @@ -152,7 +152,7 @@ ref_name, old_value, new_value = ARGV[0..2] abort "missing new_value" unless new_value -out = IO.popen(%%W[%s cat-file -t #{new_value}], &:read) +out = IO.popen(%%W[git cat-file -t #{new_value}], &:read) abort 'cat-file failed' unless $?.success? if ref_name =~ /^refs\/[^\/]+\/skip-type-check-/ @@ -161,7 +161,7 @@ end unless out.chomp == expected_object_type abort "update hook error: expected '#{ref_name}' update of '#{old_value}' (a) -> '#{new_value}' (b) for 'b' to be a '#{expected_object_type}' object, got '#{out}'" -end`, config.Config.Git.BinPath) +end` dir, cleanup := testhelper.TempDir(t) hookPath := filepath.Join(dir, "pre-receive") diff --git a/internal/gitaly/service/ref/refs_test.go b/internal/gitaly/service/ref/refs_test.go index bca8c1fb9..e097b8436 100644 --- a/internal/gitaly/service/ref/refs_test.go +++ b/internal/gitaly/service/ref/refs_test.go @@ -723,7 +723,7 @@ func TestFindAllTagNestedTags(t *testing.T) { for _, tc := range testCases { t.Run(tc.description, func(t *testing.T) { tags := bytes.NewReader(testhelper.MustRunCommand(t, nil, "git", "-C", testRepoCopyPath, "tag")) - testhelper.MustRunCommand(t, tags, "xargs", config.Config.Git.BinPath, "-C", testRepoCopyPath, "tag", "-d") + testhelper.MustRunCommand(t, tags, "xargs", "git", "-C", testRepoCopyPath, "tag", "-d") batch, err := catfile.New(ctx, git.NewExecCommandFactory(config.Config), testRepoCopy) require.NoError(t, err) @@ -1656,7 +1656,7 @@ func TestFindTagNestedTag(t *testing.T) { t.Run(tc.description, func(t *testing.T) { tags := bytes.NewReader(testhelper.MustRunCommand(t, nil, "git", "-C", testRepoCopyPath, "tag")) - testhelper.MustRunCommand(t, tags, "xargs", config.Config.Git.BinPath, "-C", testRepoCopyPath, "tag", "-d") + testhelper.MustRunCommand(t, tags, "xargs", "git", "-C", testRepoCopyPath, "tag", "-d") batch, err := catfile.New(ctx, git.NewExecCommandFactory(config.Config), testRepoCopy) require.NoError(t, err) diff --git a/internal/gitaly/service/repository/calculate_checksum_test.go b/internal/gitaly/service/repository/calculate_checksum_test.go index 1c370c940..3240b45e5 100644 --- a/internal/gitaly/service/repository/calculate_checksum_test.go +++ b/internal/gitaly/service/repository/calculate_checksum_test.go @@ -32,7 +32,7 @@ func TestSuccessfulCalculateChecksum(t *testing.T) { require.NoError(t, os.MkdirAll(filepath.Join(testRepoPath, d), 0755)) } require.NoError(t, exec.Command("cp", "testdata/checksum-test-packed-refs", filepath.Join(testRepoPath, "packed-refs")).Run()) - require.NoError(t, exec.Command(config.Config.Git.BinPath, "-C", testRepoPath, "symbolic-ref", "HEAD", "refs/heads/feature").Run()) + require.NoError(t, exec.Command("git", "-C", testRepoPath, "symbolic-ref", "HEAD", "refs/heads/feature").Run()) request := &gitalypb.CalculateChecksumRequest{Repository: testRepo} testCtx, cancelCtx := testhelper.Context() diff --git a/internal/gitaly/service/repository/cleanup_test.go b/internal/gitaly/service/repository/cleanup_test.go index b23d2f5f8..5b1372ea2 100644 --- a/internal/gitaly/service/repository/cleanup_test.go +++ b/internal/gitaly/service/repository/cleanup_test.go @@ -233,7 +233,7 @@ func TestCleanupDisconnectedWorktrees(t *testing.T) { "disconnecting worktree by removing work tree at %s should succeed", worktreePath, ) - err = exec.Command(config.Config.Git.BinPath, gittest.AddWorktreeArgs(testRepoPath, worktreePath)...).Run() + err = exec.Command("git", gittest.AddWorktreeArgs(testRepoPath, worktreePath)...).Run() require.Error(t, err, "creating a new work tree at the same path as a disconnected work tree should fail") // cleanup should prune the disconnected worktree administrative files diff --git a/internal/gitaly/service/repository/clone_from_pool_test.go b/internal/gitaly/service/repository/clone_from_pool_test.go index d71251908..fdbfa6125 100644 --- a/internal/gitaly/service/repository/clone_from_pool_test.go +++ b/internal/gitaly/service/repository/clone_from_pool_test.go @@ -7,7 +7,6 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "gitlab.com/gitlab-org/gitaly/internal/git/gittest" - "gitlab.com/gitlab-org/gitaly/internal/gitaly/config" "gitlab.com/gitlab-org/gitaly/internal/gitaly/service/repository" "gitlab.com/gitlab-org/gitaly/internal/testhelper" "gitlab.com/gitlab-org/gitaly/proto/go/gitalypb" @@ -44,7 +43,7 @@ func TestCloneFromPoolHTTP(t *testing.T) { defer forkRepoCleanup() authorizationHeader := "ABCefg0999182" - _, remoteURL := gittest.RemoteUploadPackServer(ctx, t, config.Config.Git.BinPath, "my-repo", authorizationHeader, testRepoPath) + _, remoteURL := gittest.RemoteUploadPackServer(ctx, t, "git", "my-repo", authorizationHeader, testRepoPath) req := &gitalypb.CloneFromPoolRequest{ Repository: forkedRepo, diff --git a/internal/gitaly/service/repository/redirecting_test_server_test.go b/internal/gitaly/service/repository/redirecting_test_server_test.go index 1c8957502..35ea4f257 100644 --- a/internal/gitaly/service/repository/redirecting_test_server_test.go +++ b/internal/gitaly/service/repository/redirecting_test_server_test.go @@ -8,7 +8,6 @@ import ( "github.com/stretchr/testify/require" "gitlab.com/gitlab-org/gitaly/internal/command" - "gitlab.com/gitlab-org/gitaly/internal/gitaly/config" "gitlab.com/gitlab-org/gitaly/internal/testhelper" ) @@ -44,7 +43,7 @@ func TestRedirectingServerRedirects(t *testing.T) { httpServerState, redirectingServer := StartRedirectingTestServer() // we only test for redirection, this command can fail after that - cmd := exec.Command(config.Config.Git.BinPath, "-c", "http.followRedirects=true", "clone", "--bare", redirectingServer.URL, dir) + cmd := exec.Command("git", "-c", "http.followRedirects=true", "clone", "--bare", redirectingServer.URL, dir) cmd.Env = append(command.GitEnv, cmd.Env...) cmd.Run() diff --git a/internal/gitaly/service/repository/rename_test.go b/internal/gitaly/service/repository/rename_test.go index 1efe13275..94a752916 100644 --- a/internal/gitaly/service/repository/rename_test.go +++ b/internal/gitaly/service/repository/rename_test.go @@ -40,7 +40,7 @@ func TestRenameRepositorySuccess(t *testing.T) { require.True(t, storage.IsGitDirectory(newDirectory), "moved Git repository has been corrupted") // ensure the git directory that got renamed contains a sha in the seed repo - gittest.GitObjectMustExist(t, config.Config.Git.BinPath, newDirectory, "913c66a37b4a45b9769037c55c2d238bd0942d2e") + gittest.GitObjectMustExist(t, newDirectory, "913c66a37b4a45b9769037c55c2d238bd0942d2e") } func TestRenameRepositoryDestinationExists(t *testing.T) { @@ -68,7 +68,7 @@ func TestRenameRepositoryDestinationExists(t *testing.T) { testhelper.RequireGrpcError(t, err, codes.FailedPrecondition) // ensure the git directory that already existed didn't get overwritten - gittest.GitObjectMustExist(t, config.Config.Git.BinPath, destinationRepoPath, sha) + gittest.GitObjectMustExist(t, destinationRepoPath, sha) } func TestRenameRepositoryInvalidRequest(t *testing.T) { diff --git a/internal/gitaly/service/repository/repack_test.go b/internal/gitaly/service/repository/repack_test.go index cf81b4ab5..a5d3902a9 100644 --- a/internal/gitaly/service/repository/repack_test.go +++ b/internal/gitaly/service/repository/repack_test.go @@ -92,9 +92,9 @@ func TestRepackLocal(t *testing.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(config.Config.Git.BinPath, cmdArgs...) + cmd := exec.Command("git", cmdArgs...) altObjectsDir := "./alt-objects" - altDirsCommit := gittest.CreateCommitInAlternateObjectDirectory(t, config.Config.Git.BinPath, repoPath, altObjectsDir, cmd) + altDirsCommit := gittest.CreateCommitInAlternateObjectDirectory(t, repoPath, altObjectsDir, cmd) repoCommit := gittest.CreateCommit(t, repoPath, t.Name(), &gittest.CreateCommitOpts{Message: t.Name()}) diff --git a/internal/gitaly/service/repository/snapshot_test.go b/internal/gitaly/service/repository/snapshot_test.go index 3ce7b4c65..db0ec57e4 100644 --- a/internal/gitaly/service/repository/snapshot_test.go +++ b/internal/gitaly/service/repository/snapshot_test.go @@ -128,12 +128,12 @@ func TestGetSnapshotWithDedupe(t *testing.T) { const committerName = "Scrooge McDuck" const committerEmail = "scrooge@mcduck.com" - cmd := exec.Command(config.Config.Git.BinPath, "-C", repoPath, + cmd := exec.Command("git", "-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, filepath.Join(repoPath, "objects")) - commitSha := gittest.CreateCommitInAlternateObjectDirectory(t, config.Config.Git.BinPath, repoPath, alternateObjDir, cmd) + commitSha := gittest.CreateCommitInAlternateObjectDirectory(t, repoPath, alternateObjDir, cmd) originalAlternatesCommit := string(commitSha) locator := config.NewLocator(config.Config) @@ -151,11 +151,11 @@ func TestGetSnapshotWithDedupe(t *testing.T) { require.NoError(t, ioutil.WriteFile(alternatesPath, []byte(filepath.Join(repoPath, ".git", fmt.Sprintf("%s\n", alternateObjDir))), 0644)) // write another commit and ensure we can find it - cmd = exec.Command(config.Config.Git.BinPath, "-C", repoPath, + cmd = exec.Command("git", "-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, config.Config.Git.BinPath, repoPath, alternateObjDir, cmd) + commitSha = gittest.CreateCommitInAlternateObjectDirectory(t, repoPath, alternateObjDir, cmd) c, err = catfile.New(ctx, gitCmdFactory, testRepo) require.NoError(t, err) @@ -209,12 +209,12 @@ func TestGetSnapshotWithDedupeSoftFailures(t *testing.T) { committerName := "Scrooge McDuck" committerEmail := "scrooge@mcduck.com" - cmd := exec.Command(config.Config.Git.BinPath, "-C", repoPath, + cmd := exec.Command("git", "-C", repoPath, "-c", fmt.Sprintf("user.name=%s", committerName), "-c", fmt.Sprintf("user.email=%s", committerEmail), "commit", "--allow-empty", "-m", "An empty commit") - commitSha := gittest.CreateCommitInAlternateObjectDirectory(t, config.Config.Git.BinPath, repoPath, alternateObjDir, cmd) + commitSha := gittest.CreateCommitInAlternateObjectDirectory(t, repoPath, alternateObjDir, cmd) originalAlternatesCommit := string(commitSha) require.NoError(t, ioutil.WriteFile(alternatesPath, []byte(alternateObjPath), 0644)) diff --git a/internal/gitaly/service/smarthttp/inforefs_test.go b/internal/gitaly/service/smarthttp/inforefs_test.go index 94c5b288f..85bfcef36 100644 --- a/internal/gitaly/service/smarthttp/inforefs_test.go +++ b/internal/gitaly/service/smarthttp/inforefs_test.go @@ -21,26 +21,28 @@ import ( "gitlab.com/gitlab-org/gitaly/internal/git/objectpool" "gitlab.com/gitlab-org/gitaly/internal/git/stats" "gitlab.com/gitlab-org/gitaly/internal/gitaly/config" - "gitlab.com/gitlab-org/gitaly/internal/tempdir" + "gitlab.com/gitlab-org/gitaly/internal/storage" "gitlab.com/gitlab-org/gitaly/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/internal/testhelper/testcfg" "gitlab.com/gitlab-org/gitaly/proto/go/gitalypb" "gitlab.com/gitlab-org/gitaly/streamio" "google.golang.org/grpc/codes" ) func TestSuccessfulInfoRefsUploadPack(t *testing.T) { - serverSocketPath, stop := runSmartHTTPServer(t, config.Config) - defer stop() + cfgBuilder := testcfg.NewGitalyCfgBuilder() + defer cfgBuilder.Cleanup() + cfg, repos := cfgBuilder.BuildWithRepoAt(t, t.Name()) - testRepo, _, cleanupFn := gittest.CloneRepo(t) - defer cleanupFn() + serverSocketPath, stop := runSmartHTTPServer(t, cfg) + defer stop() - rpcRequest := &gitalypb.InfoRefsRequest{Repository: testRepo} + rpcRequest := &gitalypb.InfoRefsRequest{Repository: repos[0]} ctx, cancel := testhelper.Context() defer cancel() - response, err := makeInfoRefsUploadPackRequest(ctx, t, serverSocketPath, config.Config.Auth.Token, rpcRequest) + response, err := makeInfoRefsUploadPackRequest(ctx, t, serverSocketPath, cfg.Auth.Token, rpcRequest) require.NoError(t, err) assertGitRefAdvertisement(t, "InfoRefsUploadPack", string(response), "001e# service=git-upload-pack", "0000", []string{ "003ef4e6814c3e4e7a0de82a9e7cd20c626cc963a2f8 refs/tags/v1.0.0", @@ -49,20 +51,21 @@ func TestSuccessfulInfoRefsUploadPack(t *testing.T) { } func TestSuccessfulInfoRefsUploadWithPartialClone(t *testing.T) { - serverSocketPath, stop := runSmartHTTPServer(t, config.Config) + cfgBuilder := testcfg.NewGitalyCfgBuilder() + defer cfgBuilder.Cleanup() + cfg, repos := cfgBuilder.BuildWithRepoAt(t, t.Name()) + + serverSocketPath, stop := runSmartHTTPServer(t, cfg) defer stop() ctx, cancel := testhelper.Context() defer cancel() - testRepo, _, cleanup := gittest.CloneRepo(t) - defer cleanup() - request := &gitalypb.InfoRefsRequest{ - Repository: testRepo, + Repository: repos[0], } - partialResponse, err := makeInfoRefsUploadPackRequest(ctx, t, serverSocketPath, config.Config.Auth.Token, request) + partialResponse, err := makeInfoRefsUploadPackRequest(ctx, t, serverSocketPath, cfg.Auth.Token, request) require.NoError(t, err) partialRefs := stats.Get{} err = partialRefs.Parse(bytes.NewReader(partialResponse)) @@ -74,61 +77,58 @@ func TestSuccessfulInfoRefsUploadWithPartialClone(t *testing.T) { } func TestSuccessfulInfoRefsUploadPackWithGitConfigOptions(t *testing.T) { - serverSocketPath, stop := runSmartHTTPServer(t, config.Config) - defer stop() + cfgBuilder := testcfg.NewGitalyCfgBuilder() + defer cfgBuilder.Cleanup() + cfg, repos := cfgBuilder.BuildWithRepoAt(t, t.Name()) - testRepo, _, cleanupFn := gittest.CloneRepo(t) - defer cleanupFn() + serverSocketPath, stop := runSmartHTTPServer(t, cfg) + defer stop() // transfer.hideRefs=refs will hide every ref that info-refs would normally // output, allowing us to test that the custom configuration is respected rpcRequest := &gitalypb.InfoRefsRequest{ - Repository: testRepo, + Repository: repos[0], GitConfigOptions: []string{"transfer.hideRefs=refs"}, } ctx, cancel := testhelper.Context() defer cancel() - response, err := makeInfoRefsUploadPackRequest(ctx, t, serverSocketPath, config.Config.Auth.Token, rpcRequest) + response, err := makeInfoRefsUploadPackRequest(ctx, t, serverSocketPath, cfg.Auth.Token, rpcRequest) require.NoError(t, err) assertGitRefAdvertisement(t, "InfoRefsUploadPack", string(response), "001e# service=git-upload-pack", "0000", []string{}) } func TestSuccessfulInfoRefsUploadPackWithGitProtocol(t *testing.T) { - defer func(old config.Cfg) { config.Config = old }(config.Config) + cfgBuilder := testcfg.NewGitalyCfgBuilder() + defer cfgBuilder.Cleanup() + cfg, repos := cfgBuilder.BuildWithRepoAt(t, t.Name()) - readProtocol, cfg, restore := gittest.EnableGitProtocolV2Support(t, config.Config) + readProtocol, cfg, restore := gittest.EnableGitProtocolV2Support(t, cfg) defer restore() - config.Config = cfg - serverSocketPath, stop := runSmartHTTPServer(t, config.Config) + serverSocketPath, stop := runSmartHTTPServer(t, cfg) defer stop() - testRepo, _, cleanupFn := gittest.CloneRepo(t) - defer cleanupFn() - rpcRequest := &gitalypb.InfoRefsRequest{ - Repository: testRepo, + Repository: repos[0], GitProtocol: git.ProtocolV2, } - client, _ := newSmartHTTPClient(t, serverSocketPath, config.Config.Auth.Token) + client, _ := newSmartHTTPClient(t, serverSocketPath, cfg.Auth.Token) ctx, cancel := testhelper.Context() defer cancel() c, err := client.InfoRefsUploadPack(ctx, rpcRequest) + require.NoError(t, err) for { - _, err := c.Recv() - if err != nil { + if _, err := c.Recv(); err != nil { require.Equal(t, io.EOF, err) break } } - require.NoError(t, err) - envData := readProtocol() require.Contains(t, envData, fmt.Sprintf("GIT_PROTOCOL=%s\n", git.ProtocolV2)) } @@ -151,31 +151,28 @@ func makeInfoRefsUploadPackRequest(ctx context.Context, t *testing.T, serverSock } func TestSuccessfulInfoRefsReceivePack(t *testing.T) { - serverSocketPath, stop := runSmartHTTPServer(t, config.Config) + cfgBuilder := testcfg.NewGitalyCfgBuilder() + defer cfgBuilder.Cleanup() + cfg, repos := cfgBuilder.BuildWithRepoAt(t, t.Name()) + + serverSocketPath, stop := runSmartHTTPServer(t, cfg) defer stop() - client, conn := newSmartHTTPClient(t, serverSocketPath, config.Config.Auth.Token) + client, conn := newSmartHTTPClient(t, serverSocketPath, cfg.Auth.Token) defer conn.Close() - testRepo, _, cleanupFn := gittest.CloneRepo(t) - defer cleanupFn() - - rpcRequest := &gitalypb.InfoRefsRequest{Repository: testRepo} + rpcRequest := &gitalypb.InfoRefsRequest{Repository: repos[0]} ctx, cancel := testhelper.Context() defer cancel() c, err := client.InfoRefsReceivePack(ctx, rpcRequest) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) response, err := ioutil.ReadAll(streamio.NewReader(func() ([]byte, error) { resp, err := c.Recv() return resp.GetData(), err })) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) assertGitRefAdvertisement(t, "InfoRefsReceivePack", string(response), "001f# service=git-receive-pack", "0000", []string{ "003ef4e6814c3e4e7a0de82a9e7cd20c626cc963a2f8 refs/tags/v1.0.0", @@ -184,29 +181,32 @@ func TestSuccessfulInfoRefsReceivePack(t *testing.T) { } func TestObjectPoolRefAdvertisementHiding(t *testing.T) { - serverSocketPath, stop := runSmartHTTPServer(t, config.Config) + cfgBuilder := testcfg.NewGitalyCfgBuilder() + defer cfgBuilder.Cleanup() + cfg, repos := cfgBuilder.BuildWithRepoAt(t, t.Name()) + + testhelper.ConfigureGitalyHooksBin(t, cfg) + + serverSocketPath, stop := runSmartHTTPServer(t, cfg) defer stop() - client, conn := newSmartHTTPClient(t, serverSocketPath, config.Config.Auth.Token) + client, conn := newSmartHTTPClient(t, serverSocketPath, cfg.Auth.Token) defer conn.Close() - repo, _, cleanupFn := gittest.CloneRepo(t) - defer cleanupFn() - ctx, cancel := testhelper.Context() defer cancel() - pool, err := objectpool.NewObjectPool(config.Config, config.NewLocator(config.Config), git.NewExecCommandFactory(config.Config), repo.GetStorageName(), gittest.NewObjectPoolName(t)) + pool, err := objectpool.NewObjectPool(cfg, config.NewLocator(cfg), git.NewExecCommandFactory(cfg), repos[0].GetStorageName(), gittest.NewObjectPoolName(t)) require.NoError(t, err) - require.NoError(t, pool.Create(ctx, repo)) + require.NoError(t, pool.Create(ctx, repos[0])) defer pool.Remove(ctx) commitID := gittest.CreateCommit(t, pool.FullPath(), t.Name(), nil) - require.NoError(t, pool.Link(ctx, repo)) + require.NoError(t, pool.Link(ctx, repos[0])) - rpcRequest := &gitalypb.InfoRefsRequest{Repository: repo} + rpcRequest := &gitalypb.InfoRefsRequest{Repository: repos[0]} c, err := client.InfoRefsReceivePack(ctx, rpcRequest) require.NoError(t, err) @@ -221,12 +221,16 @@ func TestObjectPoolRefAdvertisementHiding(t *testing.T) { } func TestFailureRepoNotFoundInfoRefsReceivePack(t *testing.T) { - serverSocketPath, stop := runSmartHTTPServer(t, config.Config) + cfgBuilder := testcfg.NewGitalyCfgBuilder() + defer cfgBuilder.Cleanup() + cfg := cfgBuilder.Build(t) + + serverSocketPath, stop := runSmartHTTPServer(t, cfg) defer stop() - client, conn := newSmartHTTPClient(t, serverSocketPath, config.Config.Auth.Token) + client, conn := newSmartHTTPClient(t, serverSocketPath, cfg.Auth.Token) defer conn.Close() - repo := &gitalypb.Repository{StorageName: "default", RelativePath: "testdata/scratch/another_repo"} + repo := &gitalypb.Repository{StorageName: cfg.Storages[0].Name, RelativePath: "testdata/scratch/another_repo"} rpcRequest := &gitalypb.InfoRefsRequest{Repository: repo} ctx, cancel := testhelper.Context() @@ -243,10 +247,14 @@ func TestFailureRepoNotFoundInfoRefsReceivePack(t *testing.T) { } func TestFailureRepoNotSetInfoRefsReceivePack(t *testing.T) { - serverSocketPath, stop := runSmartHTTPServer(t, config.Config) + cfgBuilder := testcfg.NewGitalyCfgBuilder() + defer cfgBuilder.Cleanup() + cfg := cfgBuilder.Build(t) + + serverSocketPath, stop := runSmartHTTPServer(t, cfg) defer stop() - client, conn := newSmartHTTPClient(t, serverSocketPath, config.Config.Auth.Token) + client, conn := newSmartHTTPClient(t, serverSocketPath, cfg.Auth.Token) defer conn.Close() rpcRequest := &gitalypb.InfoRefsRequest{} @@ -295,15 +303,14 @@ func (ms mockStreamer) PutStream(ctx context.Context, repo *gitalypb.Repository, } func TestCacheInfoRefsUploadPack(t *testing.T) { - clearCache(t) + cfgBuilder := testcfg.NewGitalyCfgBuilder() + defer cfgBuilder.Cleanup() + cfg, repos := cfgBuilder.BuildWithRepoAt(t, t.Name()) - serverSocketPath, stop := runSmartHTTPServer(t, config.Config) + serverSocketPath, stop := runSmartHTTPServer(t, cfg) defer stop() - testRepo, _, cleanupFn := gittest.CloneRepo(t) - defer cleanupFn() - - rpcRequest := &gitalypb.InfoRefsRequest{Repository: testRepo} + rpcRequest := &gitalypb.InfoRefsRequest{Repository: repos[0]} ctx, cancel := testhelper.Context() defer cancel() @@ -312,7 +319,7 @@ func TestCacheInfoRefsUploadPack(t *testing.T) { ctx, cancel := context.WithTimeout(ctx, 5*time.Second) defer cancel() - response, err := makeInfoRefsUploadPackRequest(ctx, t, serverSocketPath, config.Config.Auth.Token, rpcRequest) + response, err := makeInfoRefsUploadPackRequest(ctx, t, serverSocketPath, cfg.Auth.Token, rpcRequest) require.NoError(t, err) assertGitRefAdvertisement(t, "InfoRefsUploadPack", string(response), @@ -325,7 +332,7 @@ func TestCacheInfoRefsUploadPack(t *testing.T) { } assertNormalResponse() - require.FileExists(t, pathToCachedResponse(t, ctx, rpcRequest)) + require.FileExists(t, pathToCachedResponse(t, ctx, config.NewLocator(cfg), rpcRequest)) replacedContents := []string{ "first line", @@ -335,15 +342,15 @@ func TestCacheInfoRefsUploadPack(t *testing.T) { } // replace cached response file to prove the info-ref uses the cache - replaceCachedResponse(t, ctx, rpcRequest, strings.Join(replacedContents, "\n")) - response, err := makeInfoRefsUploadPackRequest(ctx, t, serverSocketPath, config.Config.Auth.Token, rpcRequest) + replaceCachedResponse(t, ctx, cfg, rpcRequest, strings.Join(replacedContents, "\n")) + response, err := makeInfoRefsUploadPackRequest(ctx, t, serverSocketPath, cfg.Auth.Token, rpcRequest) require.NoError(t, err) assertGitRefAdvertisement(t, "InfoRefsUploadPack", string(response), replacedContents[0], replacedContents[3], replacedContents[1:3], ) invalidateCacheForRepo := func() { - ender, err := cache.NewLeaseKeyer(config.NewLocator(config.Config)).StartLease(rpcRequest.Repository) + ender, err := cache.NewLeaseKeyer(config.NewLocator(cfg)).StartLease(rpcRequest.Repository) require.NoError(t, err) require.NoError(t, ender.EndLease(setInfoRefsUploadPackMethod(ctx))) } @@ -357,22 +364,22 @@ func TestCacheInfoRefsUploadPack(t *testing.T) { invalidReq := &gitalypb.InfoRefsRequest{ Repository: &gitalypb.Repository{ RelativePath: "fake_repo", - StorageName: testRepo.StorageName, + StorageName: repos[0].StorageName, }, } // invalid request because repo is empty invalidRepoCleanup := createInvalidRepo(t, filepath.Join(testhelper.GitlabTestStoragePath(), invalidReq.Repository.RelativePath)) defer invalidRepoCleanup() - _, err = makeInfoRefsUploadPackRequest(ctx, t, serverSocketPath, config.Config.Auth.Token, invalidReq) - testhelper.RequireGrpcError(t, err, codes.Internal) - testhelper.AssertPathNotExists(t, pathToCachedResponse(t, ctx, invalidReq)) + _, err = makeInfoRefsUploadPackRequest(ctx, t, serverSocketPath, cfg.Auth.Token, invalidReq) + testhelper.RequireGrpcError(t, err, codes.NotFound) + testhelper.AssertPathNotExists(t, pathToCachedResponse(t, ctx, config.NewLocator(cfg), invalidReq)) // if an error occurs while putting stream, it should not interrupt // request from being served happened := false mockInfoRefCache := newInfoRefCache(mockStreamer{ - streamer: cache.NewStreamDB(cache.NewLeaseKeyer(config.NewLocator(config.Config))), + streamer: cache.NewStreamDB(cache.NewLeaseKeyer(config.NewLocator(cfg))), putStream: func(context.Context, *gitalypb.Repository, proto.Message, io.Reader) error { happened = true return errors.New("oopsie") @@ -380,7 +387,7 @@ func TestCacheInfoRefsUploadPack(t *testing.T) { }) stop() - serverSocketPath, stop = runSmartHTTPServer(t, config.Config, withInfoRefCache(mockInfoRefCache)) + serverSocketPath, stop = runSmartHTTPServer(t, cfg, withInfoRefCache(mockInfoRefCache)) defer stop() invalidateCacheForRepo() @@ -401,24 +408,18 @@ func createInvalidRepo(t testing.TB, repoDir string) func() { return func() { require.NoError(t, os.RemoveAll(repoDir)) } } -func replaceCachedResponse(t testing.TB, ctx context.Context, req *gitalypb.InfoRefsRequest, newContents string) { - path := pathToCachedResponse(t, ctx, req) +func replaceCachedResponse(t testing.TB, ctx context.Context, cfg config.Cfg, req *gitalypb.InfoRefsRequest, newContents string) { + path := pathToCachedResponse(t, ctx, config.NewLocator(cfg), req) require.NoError(t, ioutil.WriteFile(path, []byte(newContents), 0644)) } -func clearCache(t testing.TB) { - for _, storage := range config.Config.Storages { - require.NoError(t, os.RemoveAll(tempdir.CacheDir(storage))) - } -} - func setInfoRefsUploadPackMethod(ctx context.Context) context.Context { return testhelper.SetCtxGrpcMethod(ctx, "/gitaly.SmartHTTPService/InfoRefsUploadPack") } -func pathToCachedResponse(t testing.TB, ctx context.Context, req *gitalypb.InfoRefsRequest) string { +func pathToCachedResponse(t testing.TB, ctx context.Context, locator storage.Locator, req *gitalypb.InfoRefsRequest) string { ctx = setInfoRefsUploadPackMethod(ctx) - path, err := cache.NewLeaseKeyer(config.NewLocator(config.Config)).KeyPath(ctx, req.GetRepository(), req) + path, err := cache.NewLeaseKeyer(locator).KeyPath(ctx, req.GetRepository(), req) require.NoError(t, err) return path } diff --git a/internal/gitaly/service/smarthttp/receive_pack_test.go b/internal/gitaly/service/smarthttp/receive_pack_test.go index a1e38af99..39d1e3f3f 100644 --- a/internal/gitaly/service/smarthttp/receive_pack_test.go +++ b/internal/gitaly/service/smarthttp/receive_pack_test.go @@ -28,6 +28,7 @@ import ( pconfig "gitlab.com/gitlab-org/gitaly/internal/praefect/config" "gitlab.com/gitlab-org/gitaly/internal/praefect/metadata" "gitlab.com/gitlab-org/gitaly/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/internal/testhelper/testcfg" "gitlab.com/gitlab-org/gitaly/proto/go/gitalypb" "gitlab.com/gitlab-org/gitaly/streamio" "google.golang.org/grpc" @@ -42,19 +43,19 @@ const ( ) func TestSuccessfulReceivePackRequest(t *testing.T) { - defer func(dir string) { config.Config.GitlabShell.Dir = dir }(config.Config.GitlabShell.Dir) - config.Config.GitlabShell.Dir = "/foo/bar/gitlab-shell" + cfgBuilder := testcfg.NewGitalyCfgBuilder() + defer cfgBuilder.Cleanup() + cfg, repos := cfgBuilder.BuildWithRepoAt(t, t.Name()) + + cfg.GitlabShell.Dir = "/foo/bar/gitlab-shell" hookOutputFile, cleanup := gittest.CaptureHookEnv(t) defer cleanup() - serverSocketPath, stop := runSmartHTTPServer(t, config.Config) + serverSocketPath, stop := runSmartHTTPServer(t, cfg) defer stop() - repo, repoPath, cleanup := gittest.CloneRepo(t) - defer cleanup() - - client, conn := newSmartHTTPClient(t, serverSocketPath, config.Config.Auth.Token) + client, conn := newSmartHTTPClient(t, serverSocketPath, cfg.Auth.Token) defer conn.Close() ctx, cancel := testhelper.Context() @@ -63,17 +64,18 @@ func TestSuccessfulReceivePackRequest(t *testing.T) { stream, err := client.PostReceivePack(ctx) require.NoError(t, err) - push := newTestPush(t, nil) + push := newTestPush(t, cfg, nil) projectPath := "project/path" - repo.GlProjectPath = projectPath - firstRequest := &gitalypb.PostReceivePackRequest{Repository: repo, GlUsername: "user", GlId: "123", GlRepository: "project-456"} + repos[0].GlProjectPath = projectPath + firstRequest := &gitalypb.PostReceivePackRequest{Repository: repos[0], GlUsername: "user", GlId: "123", GlRepository: "project-456"} response := doPush(t, stream, firstRequest, push.body) expectedResponse := "0049\x01000eunpack ok\n0019ok refs/heads/master\n0019ok refs/heads/branch\n00000000" require.Equal(t, expectedResponse, string(response), "Expected response to be %q, got %q", expectedResponse, response) + repoPath := filepath.Join(cfg.Storages[0].Path, repos[0].RelativePath) // 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) @@ -85,7 +87,7 @@ func TestSuccessfulReceivePackRequest(t *testing.T) { // Compare the repository up front so that we can use require.Equal for // the remaining values. - testhelper.ProtoEqual(t, repo, payload.Repo) + testhelper.ProtoEqual(t, repos[0], payload.Repo) payload.Repo = nil // If running tests with Praefect, then these would be set, but we have @@ -95,10 +97,10 @@ func TestSuccessfulReceivePackRequest(t *testing.T) { payload.Praefect = nil require.Equal(t, git.HooksPayload{ - BinDir: config.Config.BinDir, - GitPath: config.Config.Git.BinPath, - InternalSocket: config.Config.GitalyInternalSocketPath(), - InternalSocketToken: config.Config.Auth.Token, + BinDir: cfg.BinDir, + GitPath: cfg.Git.BinPath, + InternalSocket: cfg.GitalyInternalSocketPath(), + InternalSocketToken: cfg.Auth.Token, ReceiveHooksPayload: &git.ReceiveHooksPayload{ UserID: "123", Username: "user", @@ -109,19 +111,19 @@ func TestSuccessfulReceivePackRequest(t *testing.T) { } func TestSuccessfulReceivePackRequestWithGitProtocol(t *testing.T) { - defer func(old config.Cfg) { config.Config = old }(config.Config) + cfgBuilder := testcfg.NewGitalyCfgBuilder() + defer cfgBuilder.Cleanup() + cfg, repos := cfgBuilder.BuildWithRepoAt(t, t.Name()) - readProto, cfg, restore := gittest.EnableGitProtocolV2Support(t, config.Config) + testhelper.ConfigureGitalyHooksBin(t, cfg) + + readProto, cfg, restore := gittest.EnableGitProtocolV2Support(t, cfg) defer restore() - config.Config = cfg - serverSocketPath, stop := runSmartHTTPServer(t, config.Config) + serverSocketPath, stop := runSmartHTTPServer(t, cfg) defer stop() - repo, repoPath, cleanup := gittest.CloneRepo(t) - defer cleanup() - - client, conn := newSmartHTTPClient(t, serverSocketPath, config.Config.Auth.Token) + client, conn := newSmartHTTPClient(t, serverSocketPath, cfg.Auth.Token) defer conn.Close() ctx, cancel := testhelper.Context() @@ -130,25 +132,27 @@ func TestSuccessfulReceivePackRequestWithGitProtocol(t *testing.T) { 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} + push := newTestPush(t, cfg, nil) + firstRequest := &gitalypb.PostReceivePackRequest{Repository: repos[0], GlId: "user-123", GlRepository: "project-123", GitProtocol: git.ProtocolV2} doPush(t, stream, firstRequest, push.body) envData := readProto() require.Equal(t, fmt.Sprintf("GIT_PROTOCOL=%s\n", git.ProtocolV2), envData) + repoPath := filepath.Join(cfg.Storages[0].Path, repos[0].RelativePath) // 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) { - serverSocketPath, stop := runSmartHTTPServer(t, config.Config) - defer stop() + cfgBuilder := testcfg.NewGitalyCfgBuilder() + defer cfgBuilder.Cleanup() + cfg, repos := cfgBuilder.BuildWithRepoAt(t, t.Name()) - repo, _, cleanup := gittest.CloneRepo(t) - defer cleanup() + serverSocketPath, stop := runSmartHTTPServer(t, cfg) + defer stop() - client, conn := newSmartHTTPClient(t, serverSocketPath, config.Config.Auth.Token) + client, conn := newSmartHTTPClient(t, serverSocketPath, cfg.Auth.Token) defer conn.Close() ctx, cancel := testhelper.Context() @@ -157,8 +161,8 @@ func TestFailedReceivePackRequestWithGitOpts(t *testing.T) { stream, err := client.PostReceivePack(ctx) require.NoError(t, err) - push := newTestPush(t, nil) - firstRequest := &gitalypb.PostReceivePackRequest{Repository: repo, GlId: "user-123", GlRepository: "project-123", GitConfigOptions: []string{"receive.MaxInputSize=1"}} + push := newTestPush(t, cfg, nil) + firstRequest := &gitalypb.PostReceivePackRequest{Repository: repos[0], GlId: "user-123", GlRepository: "project-123", GitConfigOptions: []string{"receive.MaxInputSize=1"}} response := doPush(t, stream, firstRequest, push.body) expectedResponse := "002e\x02fatal: pack exceeds maximum allowed size\n0081\x010028unpack unpack-objects abnormal exit\n0028ng refs/heads/master unpacker error\n0028ng refs/heads/branch unpacker error\n00000000" @@ -166,6 +170,10 @@ func TestFailedReceivePackRequestWithGitOpts(t *testing.T) { } func TestFailedReceivePackRequestDueToHooksFailure(t *testing.T) { + cfgBuilder := testcfg.NewGitalyCfgBuilder() + defer cfgBuilder.Cleanup() + cfg, repos := cfgBuilder.BuildWithRepoAt(t, t.Name()) + hookDir, cleanup := testhelper.TempDir(t) defer cleanup() @@ -174,18 +182,15 @@ func TestFailedReceivePackRequestDueToHooksFailure(t *testing.T) { }(hooks.Override) hooks.Override = hookDir - require.NoError(t, os.MkdirAll(hooks.Path(config.Config), 0755)) + require.NoError(t, os.MkdirAll(hooks.Path(cfg), 0755)) hookContent := []byte("#!/bin/sh\nexit 1") - ioutil.WriteFile(filepath.Join(hooks.Path(config.Config), "pre-receive"), hookContent, 0755) + ioutil.WriteFile(filepath.Join(hooks.Path(cfg), "pre-receive"), hookContent, 0755) - serverSocketPath, stop := runSmartHTTPServer(t, config.Config) + serverSocketPath, stop := runSmartHTTPServer(t, cfg) defer stop() - repo, _, cleanup := gittest.CloneRepo(t) - defer cleanup() - - client, conn := newSmartHTTPClient(t, serverSocketPath, config.Config.Auth.Token) + client, conn := newSmartHTTPClient(t, serverSocketPath, cfg.Auth.Token) defer conn.Close() ctx, cancel := testhelper.Context() @@ -194,8 +199,8 @@ func TestFailedReceivePackRequestDueToHooksFailure(t *testing.T) { stream, err := client.PostReceivePack(ctx) require.NoError(t, err) - push := newTestPush(t, nil) - firstRequest := &gitalypb.PostReceivePackRequest{Repository: repo, GlId: "user-123", GlRepository: "project-123"} + push := newTestPush(t, cfg, nil) + firstRequest := &gitalypb.PostReceivePackRequest{Repository: repos[0], GlId: "user-123", GlRepository: "project-123"} response := doPush(t, stream, firstRequest, push.body) expectedResponse := "007d\x01000eunpack ok\n0033ng refs/heads/master pre-receive hook declined\n0033ng refs/heads/branch pre-receive hook declined\n00000000" @@ -229,8 +234,8 @@ type pushData struct { body io.Reader } -func newTestPush(t *testing.T, fileContents []byte) *pushData { - _, repoPath, localCleanup := gittest.CloneRepoWithWorktree(t) +func newTestPush(t *testing.T, cfg config.Cfg, fileContents []byte) *pushData { + _, repoPath, localCleanup := gittest.CloneRepoWithWorktreeAtStorage(t, cfg.Storages[0]) defer localCleanup() oldHead, newHead := createCommit(t, repoPath, fileContents) @@ -287,17 +292,21 @@ func createCommit(t *testing.T, repoPath string, fileContents []byte) (oldHead s } func TestFailedReceivePackRequestDueToValidationError(t *testing.T) { - serverSocketPath, stop := runSmartHTTPServer(t, config.Config) + cfgBuilder := testcfg.NewGitalyCfgBuilder() + defer cfgBuilder.Cleanup() + cfg := cfgBuilder.Build(t) + + serverSocketPath, stop := runSmartHTTPServer(t, cfg) defer stop() - client, conn := newSmartHTTPClient(t, serverSocketPath, config.Config.Auth.Token) + client, conn := newSmartHTTPClient(t, serverSocketPath, cfg.Auth.Token) defer conn.Close() rpcRequests := []gitalypb.PostReceivePackRequest{ {Repository: &gitalypb.Repository{StorageName: "fake", RelativePath: "path"}, GlId: "user-123"}, // Repository doesn't exist {Repository: nil, GlId: "user-123"}, // Repository is nil - {Repository: &gitalypb.Repository{StorageName: "default", RelativePath: "path/to/repo"}, GlId: ""}, // Empty GlId - {Repository: &gitalypb.Repository{StorageName: "default", RelativePath: "path/to/repo"}, GlId: "user-123", Data: []byte("Fail")}, // Data exists on first request + {Repository: &gitalypb.Repository{StorageName: cfg.Storages[0].Name, RelativePath: "path/to/repo"}, GlId: ""}, // Empty GlId + {Repository: &gitalypb.Repository{StorageName: cfg.Storages[0].Name, RelativePath: "path/to/repo"}, GlId: "user-123", Data: []byte("Fail")}, // Data exists on first request } for _, rpcRequest := range rpcRequests { @@ -317,7 +326,11 @@ func TestFailedReceivePackRequestDueToValidationError(t *testing.T) { } func TestInvalidTimezone(t *testing.T) { - _, localRepoPath, localCleanup := gittest.CloneRepoWithWorktree(t) + cfgBuilder := testcfg.NewGitalyCfgBuilder() + defer cfgBuilder.Cleanup() + cfg, repos := cfgBuilder.BuildWithRepoAt(t, t.Name()) + + _, localRepoPath, localCleanup := gittest.CloneRepoWithWorktreeAtStorage(t, cfg.Storages[0]) defer localCleanup() head := text.ChompBytes(testhelper.MustRunCommand(t, nil, "git", "-C", localRepoPath, "rev-parse", "HEAD")) @@ -343,13 +356,10 @@ func TestInvalidTimezone(t *testing.T) { _, cleanup := gittest.CaptureHookEnv(t) defer cleanup() - socket, stop := runSmartHTTPServer(t, config.Config) + socket, stop := runSmartHTTPServer(t, cfg) defer stop() - repo, repoPath, cleanup := gittest.CloneRepo(t) - defer cleanup() - - client, conn := newSmartHTTPClient(t, socket, config.Config.Auth.Token) + client, conn := newSmartHTTPClient(t, socket, cfg.Auth.Token) defer conn.Close() ctx, cancel := testhelper.Context() @@ -358,13 +368,14 @@ func TestInvalidTimezone(t *testing.T) { stream, err := client.PostReceivePack(ctx) require.NoError(t, err) firstRequest := &gitalypb.PostReceivePackRequest{ - Repository: repo, + Repository: repos[0], GlId: "user-123", GlRepository: "project-456", GitConfigOptions: []string{"receive.fsckObjects=true"}, } response := doPush(t, stream, firstRequest, body) + repoPath := filepath.Join(cfg.Storages[0].Path, repos[0].RelativePath) expectedResponse := "0030\x01000eunpack ok\n0019ok refs/heads/master\n00000000" require.Equal(t, expectedResponse, string(response), "Expected response to be %q, got %q", expectedResponse, response) testhelper.MustRunCommand(t, nil, "git", "-C", repoPath, "show", commit) @@ -379,38 +390,32 @@ func drainPostReceivePackResponse(stream gitalypb.SmartHTTPService_PostReceivePa } func TestPostReceivePackToHooks(t *testing.T) { - ctx, cancel := testhelper.Context() - defer cancel() + cfgBuilder := testcfg.NewGitalyCfgBuilder() + defer cfgBuilder.Cleanup() + cfg, repos := cfgBuilder.BuildWithRepoAt(t, t.Name()) - secretToken := "secret token" - glRepository := "some_repo" - glID := "key-123" - - config.Config.Auth.Token = "abc123" + testhelper.ConfigureGitalyHooksBin(t, cfg) - server, socket := runSmartHTTPHookServiceServer(t, config.Config) - defer server.Stop() - - client, conn := newSmartHTTPClient(t, "unix://"+socket, config.Config.Auth.Token) - defer conn.Close() + const ( + secretToken = "secret token" + glRepository = "some_repo" + glID = "key-123" + ) - tempGitlabShellDir, cleanup := testhelper.TempDir(t) + var cleanup testhelper.Cleanup + cfg.GitlabShell.Dir, cleanup = testhelper.TempDir(t) defer cleanup() - defer func(cfg config.Cfg) { - config.Config = cfg - }(config.Config) - config.Config.GitlabShell.Dir = tempGitlabShellDir + cfg.Auth.Token = "abc123" + cfg.Gitlab.SecretFile = testhelper.WriteShellSecretFile(t, cfg.GitlabShell.Dir, secretToken) - repo, testRepoPath, cleanup := gittest.CloneRepo(t) - defer cleanup() - - push := newTestPush(t, nil) + push := newTestPush(t, cfg, nil) + testRepoPath := filepath.Join(cfg.Storages[0].Path, repos[0].RelativePath) oldHead := text.ChompBytes(testhelper.MustRunCommand(t, nil, "git", "-C", testRepoPath, "rev-parse", "HEAD")) changes := fmt.Sprintf("%s %s refs/heads/master\n", oldHead, push.newHead) - serverURL, cleanup := testhelper.NewGitlabTestServer(t, testhelper.GitlabTestServerOptions{ + cfg.Gitlab.URL, cleanup = testhelper.NewGitlabTestServer(t, testhelper.GitlabTestServerOptions{ User: "", Password: "", SecretToken: secretToken, @@ -422,19 +427,23 @@ func TestPostReceivePackToHooks(t *testing.T) { }) defer cleanup() - testhelper.WriteShellSecretFile(t, tempGitlabShellDir, secretToken) - - cleanup = gittest.WriteCheckNewObjectExistsHook(t, config.Config.Git.BinPath, testRepoPath) + cleanup = gittest.WriteCheckNewObjectExistsHook(t, cfg.Git.BinPath, testRepoPath) defer cleanup() - config.Config.Gitlab.URL = serverURL - config.Config.Gitlab.SecretFile = filepath.Join(tempGitlabShellDir, ".gitlab_shell_secret") + ctx, cancel := testhelper.Context() + defer cancel() + + server, socket := runSmartHTTPHookServiceServer(t, cfg) + defer server.Stop() + + client, conn := newSmartHTTPClient(t, "unix://"+socket, cfg.Auth.Token) + defer conn.Close() stream, err := client.PostReceivePack(ctx) require.NoError(t, err) firstRequest := &gitalypb.PostReceivePackRequest{ - Repository: repo, + Repository: repos[0], GlId: glID, GlRepository: glRepository, } @@ -481,9 +490,11 @@ func TestPostReceiveWithTransactionsViaPraefect(t *testing.T) { } func testPostReceiveWithTransactionsViaPraefect(t *testing.T, ctx context.Context) { - defer func(cfg config.Cfg) { - config.Config = cfg - }(config.Config) + cfgBuilder := testcfg.NewGitalyCfgBuilder() + defer cfgBuilder.Cleanup() + cfg, repos := cfgBuilder.BuildWithRepoAt(t, t.Name()) + + testhelper.ConfigureGitalyHooksBin(t, cfg) secretToken := "secret token" glID := "key-1234" @@ -491,9 +502,7 @@ func testPostReceiveWithTransactionsViaPraefect(t *testing.T, ctx context.Contex gitlabUser := "gitlab_user-1234" gitlabPassword := "gitlabsecret9887" - repo, repoPath, cleanup := gittest.CloneRepo(t) - defer cleanup() - + repoPath := filepath.Join(cfg.Storages[0].Path, repos[0].RelativePath) opts := testhelper.GitlabTestServerOptions{ User: gitlabUser, Password: gitlabPassword, @@ -508,28 +517,28 @@ func testPostReceiveWithTransactionsViaPraefect(t *testing.T, ctx context.Contex gitlabShellDir, cleanup := testhelper.TempDir(t) defer cleanup() - config.Config.GitlabShell.Dir = gitlabShellDir - config.Config.Gitlab.URL = serverURL - config.Config.Gitlab.HTTPSettings.User = gitlabUser - config.Config.Gitlab.HTTPSettings.Password = gitlabPassword - config.Config.Gitlab.SecretFile = filepath.Join(gitlabShellDir, ".gitlab_shell_secret") + cfg.GitlabShell.Dir = gitlabShellDir + cfg.Gitlab.URL = serverURL + cfg.Gitlab.HTTPSettings.User = gitlabUser + cfg.Gitlab.HTTPSettings.Password = gitlabPassword + cfg.Gitlab.SecretFile = filepath.Join(gitlabShellDir, ".gitlab_shell_secret") testhelper.WriteShellSecretFile(t, gitlabShellDir, secretToken) - locator := config.NewLocator(config.Config) - txManager := transaction.NewManager(config.Config) - hookManager := gitalyhook.NewManager(locator, txManager, gitalyhook.GitlabAPIStub, config.Config) - gitCmdFactory := git.NewExecCommandFactory(config.Config) + locator := config.NewLocator(cfg) + txManager := transaction.NewManager(cfg) + hookManager := gitalyhook.NewManager(locator, txManager, gitalyhook.GitlabAPIStub, cfg) + gitCmdFactory := git.NewExecCommandFactory(cfg) - gitalyServer := testhelper.NewServerWithAuth(t, nil, nil, config.Config.Auth.Token) + gitalyServer := testhelper.NewServerWithAuth(t, nil, nil, cfg.Auth.Token) - gitalypb.RegisterSmartHTTPServiceServer(gitalyServer.GrpcServer(), NewServer(config.Config, locator, gitCmdFactory)) - gitalypb.RegisterHookServiceServer(gitalyServer.GrpcServer(), hook.NewServer(config.Config, hookManager, gitCmdFactory)) + gitalypb.RegisterSmartHTTPServiceServer(gitalyServer.GrpcServer(), NewServer(cfg, locator, gitCmdFactory)) + gitalypb.RegisterHookServiceServer(gitalyServer.GrpcServer(), hook.NewServer(cfg, hookManager, gitCmdFactory)) reflection.Register(gitalyServer.GrpcServer()) gitalyServer.Start(t) defer gitalyServer.Stop() - internalSocket := config.Config.GitalyInternalSocketPath() + internalSocket := cfg.GitalyInternalSocketPath() internalListener, err := net.Listen("unix", internalSocket) require.NoError(t, err) @@ -537,14 +546,14 @@ func testPostReceiveWithTransactionsViaPraefect(t *testing.T, ctx context.Contex gitalyServer.GrpcServer().Serve(internalListener) }() - client, conn := newSmartHTTPClient(t, "unix://"+gitalyServer.Socket(), config.Config.Auth.Token) + client, conn := newSmartHTTPClient(t, "unix://"+gitalyServer.Socket(), cfg.Auth.Token) defer conn.Close() stream, err := client.PostReceivePack(ctx) require.NoError(t, err) - push := newTestPush(t, nil) - request := &gitalypb.PostReceivePackRequest{Repository: repo, GlId: glID, GlRepository: glRepository} + push := newTestPush(t, cfg, nil) + request := &gitalypb.PostReceivePackRequest{Repository: repos[0], GlId: glID, GlRepository: glRepository} response := doPush(t, stream, request, push.body) expectedResponse := "0049\x01000eunpack ok\n0019ok refs/heads/master\n0019ok refs/heads/branch\n00000000" @@ -564,16 +573,22 @@ func (t *testTransactionServer) VoteTransaction(ctx context.Context, in *gitalyp } func TestPostReceiveWithReferenceTransactionHook(t *testing.T) { + cfgBuilder := testcfg.NewGitalyCfgBuilder() + defer cfgBuilder.Cleanup() + cfg := cfgBuilder.Build(t) + + testhelper.ConfigureGitalyHooksBin(t, cfg) + refTransactionServer := &testTransactionServer{} - locator := config.NewLocator(config.Config) - txManager := transaction.NewManager(config.Config) - hookManager := gitalyhook.NewManager(locator, txManager, gitalyhook.GitlabAPIStub, config.Config) - gitCmdFactory := git.NewExecCommandFactory(config.Config) + locator := config.NewLocator(cfg) + txManager := transaction.NewManager(cfg) + hookManager := gitalyhook.NewManager(locator, txManager, gitalyhook.GitlabAPIStub, cfg) + gitCmdFactory := git.NewExecCommandFactory(cfg) gitalyServer := testhelper.NewTestGrpcServer(t, nil, nil) - gitalypb.RegisterSmartHTTPServiceServer(gitalyServer, NewServer(config.Config, locator, gitCmdFactory)) - gitalypb.RegisterHookServiceServer(gitalyServer, hook.NewServer(config.Config, hookManager, gitCmdFactory)) + gitalypb.RegisterSmartHTTPServiceServer(gitalyServer, NewServer(cfg, locator, gitCmdFactory)) + gitalypb.RegisterHookServiceServer(gitalyServer, hook.NewServer(cfg, hookManager, gitCmdFactory)) gitalypb.RegisterRefTransactionServer(gitalyServer, refTransactionServer) healthpb.RegisterHealthServer(gitalyServer, health.NewServer()) reflection.Register(gitalyServer) @@ -582,14 +597,14 @@ func TestPostReceiveWithReferenceTransactionHook(t *testing.T) { listener, err := net.Listen("unix", gitalySocketPath) require.NoError(t, err) - internalListener, err := net.Listen("unix", config.Config.GitalyInternalSocketPath()) + internalListener, err := net.Listen("unix", cfg.GitalyInternalSocketPath()) require.NoError(t, err) go gitalyServer.Serve(listener) go gitalyServer.Serve(internalListener) defer gitalyServer.Stop() - client, conn := newSmartHTTPClient(t, "unix://"+gitalySocketPath, config.Config.Auth.Token) + client, conn := newSmartHTTPClient(t, "unix://"+gitalySocketPath, cfg.Auth.Token) defer conn.Close() // As we ain't got a Praefect server setup, we instead hooked up the @@ -613,11 +628,10 @@ func TestPostReceiveWithReferenceTransactionHook(t *testing.T) { stream, err := client.PostReceivePack(ctx) require.NoError(t, err) - repo, _, cleanup := gittest.CloneRepo(t) - defer cleanup() + repo := gittest.CloneRepoAtStorage(t, cfg.Storages[0], t.Name()) request := &gitalypb.PostReceivePackRequest{Repository: repo, GlId: "key-1234", GlRepository: "some_repo"} - response := doPush(t, stream, request, newTestPush(t, nil).body) + response := doPush(t, stream, request, newTestPush(t, cfg, nil).body) expectedResponse := "0049\x01000eunpack ok\n0019ok refs/heads/master\n0019ok refs/heads/branch\n00000000" require.Equal(t, expectedResponse, string(response), "Expected response to be %q, got %q", expectedResponse, response) @@ -630,8 +644,8 @@ func TestPostReceiveWithReferenceTransactionHook(t *testing.T) { stream, err := client.PostReceivePack(ctx) require.NoError(t, err) - repo, repoPath, cleanup := gittest.CloneRepo(t) - defer cleanup() + repo := gittest.CloneRepoAtStorage(t, cfg.Storages[0], t.Name()) + repoPath := filepath.Join(cfg.Storages[0].Path, repo.RelativePath) // Create a new branch which we're about to delete. We also pack references because // this used to generate two transactions: one for the packed-refs file and one for diff --git a/internal/gitaly/service/smarthttp/testhelper_test.go b/internal/gitaly/service/smarthttp/testhelper_test.go index 3b69fc0c0..906284544 100644 --- a/internal/gitaly/service/smarthttp/testhelper_test.go +++ b/internal/gitaly/service/smarthttp/testhelper_test.go @@ -2,10 +2,8 @@ package smarthttp import ( "os" - "path/filepath" "testing" - log "github.com/sirupsen/logrus" "github.com/stretchr/testify/require" gitalyauth "gitlab.com/gitlab-org/gitaly/auth" diskcache "gitlab.com/gitlab-org/gitaly/internal/cache" @@ -35,16 +33,6 @@ func testMain(m *testing.M) int { cleanup := testhelper.Configure() defer cleanup() - cwd, err := os.Getwd() - if err != nil { - log.Error(err) - return 1 - } - - config.Config.Ruby.Dir = filepath.Join(cwd, "../../../../ruby") - - testhelper.ConfigureGitalyHooksBinary(config.Config.BinDir) - return m.Run() } diff --git a/internal/gitaly/service/smarthttp/upload_pack_test.go b/internal/gitaly/service/smarthttp/upload_pack_test.go index 8990e9bc9..187c1efdd 100644 --- a/internal/gitaly/service/smarthttp/upload_pack_test.go +++ b/internal/gitaly/service/smarthttp/upload_pack_test.go @@ -18,9 +18,9 @@ import ( "gitlab.com/gitlab-org/gitaly/internal/git" "gitlab.com/gitlab-org/gitaly/internal/git/gittest" "gitlab.com/gitlab-org/gitaly/internal/git/pktline" - "gitlab.com/gitlab-org/gitaly/internal/gitaly/config" "gitlab.com/gitlab-org/gitaly/internal/metadata/featureflag" "gitlab.com/gitlab-org/gitaly/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/internal/testhelper/testcfg" "gitlab.com/gitlab-org/gitaly/proto/go/gitalypb" "gitlab.com/gitlab-org/gitaly/streamio" "google.golang.org/grpc/codes" @@ -37,21 +37,25 @@ func TestSuccessfulUploadPackRequest(t *testing.T) { } func testSuccessfulUploadPackRequest(t *testing.T, ctx context.Context) { + cfgBuilder := testcfg.NewGitalyCfgBuilder() + defer cfgBuilder.Cleanup() + cfg, repos := cfgBuilder.BuildWithRepoAt(t, t.Name()) + + testhelper.ConfigureGitalyHooksBin(t, cfg) + negotiationMetrics := prometheus.NewCounterVec(prometheus.CounterOpts{}, []string{"feature"}) serverSocketPath, stop := runSmartHTTPServer( - t, config.Config, WithPackfileNegotiationMetrics(negotiationMetrics), + t, cfg, WithPackfileNegotiationMetrics(negotiationMetrics), ) defer stop() - _, testRepoPath, cleanup := gittest.CloneRepo(t) - defer cleanup() - - storagePath := testhelper.GitlabTestStoragePath() + storagePath := cfg.Storages[0].Path remoteRepoRelativePath := "gitlab-test-remote" localRepoRelativePath := "gitlab-test-local" remoteRepoPath := filepath.Join(storagePath, remoteRepoRelativePath) localRepoPath := filepath.Join(storagePath, localRepoRelativePath) + testRepoPath := filepath.Join(storagePath, repos[0].RelativePath) // Make a non-bare clone of the test repo to act as a remote one testhelper.MustRunCommand(t, nil, "git", "clone", testRepoPath, remoteRepoPath) // Make a bare clone of the test repo to act as a local one and to leave the original repo intact for other tests @@ -84,11 +88,11 @@ func testSuccessfulUploadPackRequest(t *testing.T, ctx context.Context) { req := &gitalypb.PostUploadPackRequest{ Repository: &gitalypb.Repository{ - StorageName: "default", + StorageName: cfg.Storages[0].Name, RelativePath: filepath.Join(remoteRepoRelativePath, ".git"), }, } - responseBuffer, err := makePostUploadPackRequest(ctx, t, serverSocketPath, config.Config.Auth.Token, req, requestBuffer) + responseBuffer, err := makePostUploadPackRequest(ctx, t, serverSocketPath, cfg.Auth.Token, req, requestBuffer) require.NoError(t, err) // There's no git command we can pass it this response and do the work for us (extracting pack file, ...), @@ -113,15 +117,19 @@ func TestUploadPackRequestWithGitConfigOptions(t *testing.T) { } func testUploadPackRequestWithGitConfigOptions(t *testing.T, ctx context.Context) { - serverSocketPath, stop := runSmartHTTPServer(t, config.Config) - defer stop() + cfgBuilder := testcfg.NewGitalyCfgBuilder() + defer cfgBuilder.Cleanup() + cfg, repos := cfgBuilder.BuildWithRepoAt(t, t.Name()) - _, testRepoPath, cleanup := gittest.CloneRepo(t) - defer cleanup() + testhelper.ConfigureGitalyHooksBin(t, cfg) - storagePath := testhelper.GitlabTestStoragePath() + serverSocketPath, stop := runSmartHTTPServer(t, cfg) + defer stop() + + storagePath := cfg.Storages[0].Path ourRepoRelativePath := "gitlab-test-remote" ourRepoPath := filepath.Join(storagePath, ourRepoRelativePath) + testRepoPath := filepath.Join(storagePath, repos[0].RelativePath) // Make a clone of the test repo to modify testhelper.MustRunCommand(t, nil, "git", "clone", "--bare", testRepoPath, ourRepoPath) @@ -148,13 +156,13 @@ func testUploadPackRequestWithGitConfigOptions(t *testing.T, ctx context.Context rpcRequest := &gitalypb.PostUploadPackRequest{ Repository: &gitalypb.Repository{ - StorageName: "default", + StorageName: cfg.Storages[0].Name, RelativePath: ourRepoRelativePath, }, } // The ref is successfully requested as it is not hidden - response, err := makePostUploadPackRequest(ctx, t, serverSocketPath, config.Config.Auth.Token, rpcRequest, requestBody) + response, err := makePostUploadPackRequest(ctx, t, serverSocketPath, cfg.Auth.Token, rpcRequest, requestBody) require.NoError(t, err) _, _, count := extractPackDataFromResponse(t, response) assert.Equal(t, 5, count, "pack should have 5 entries") @@ -165,7 +173,7 @@ func testUploadPackRequestWithGitConfigOptions(t *testing.T, ctx context.Context // we need to set uploadpack.allowAnySHA1InWant=false, because if it's true then we won't encounter an error from setting // uploadpack.hideRefs=refs/hidden. We are setting uploadpack.allowAnySHA1InWant=true in the RPC to enable partial clones rpcRequest.GitConfigOptions = []string{"uploadpack.hideRefs=refs/hidden", "uploadpack.allowAnySHA1InWant=false"} - response, err = makePostUploadPackRequest(ctx, t, serverSocketPath, config.Config.Auth.Token, rpcRequest, requestBodyCopy) + response, err = makePostUploadPackRequest(ctx, t, serverSocketPath, cfg.Auth.Token, rpcRequest, requestBodyCopy) testhelper.RequireGrpcError(t, err, codes.Unavailable) expected := fmt.Sprintf("0049ERR upload-pack: not our ref %v", want) @@ -179,19 +187,18 @@ func TestUploadPackRequestWithGitProtocol(t *testing.T) { } func testUploadPackRequestWithGitProtocol(t *testing.T, ctx context.Context) { - defer func(old config.Cfg) { config.Config = old }(config.Config) + cfgBuilder := testcfg.NewGitalyCfgBuilder() + defer cfgBuilder.Cleanup() + cfg, repos := cfgBuilder.BuildWithRepoAt(t, t.Name()) - readProto, cfg, restore := gittest.EnableGitProtocolV2Support(t, config.Config) + readProto, cfg, restore := gittest.EnableGitProtocolV2Support(t, cfg) defer restore() - config.Config = cfg - serverSocketPath, stop := runSmartHTTPServer(t, config.Config) + serverSocketPath, stop := runSmartHTTPServer(t, cfg) defer stop() - _, testRepoPath, cleanup := gittest.CloneRepo(t) - defer cleanup() - - storagePath := testhelper.GitlabTestStoragePath() + storagePath := cfg.Storages[0].Path + testRepoPath := filepath.Join(storagePath, repos[0].RelativePath) relativePath, err := filepath.Rel(storagePath, testRepoPath) require.NoError(t, err) @@ -207,14 +214,14 @@ func testUploadPackRequestWithGitProtocol(t *testing.T, ctx context.Context) { // Git v1 will throw a protocol error. rpcRequest := &gitalypb.PostUploadPackRequest{ Repository: &gitalypb.Repository{ - StorageName: "default", + StorageName: cfg.Storages[0].Name, RelativePath: relativePath, }, GitProtocol: git.ProtocolV2, } // The ref is successfully requested as it is not hidden - _, err = makePostUploadPackRequest(ctx, t, serverSocketPath, config.Config.Auth.Token, rpcRequest, requestBody) + _, err = makePostUploadPackRequest(ctx, t, serverSocketPath, cfg.Auth.Token, rpcRequest, requestBody) require.NoError(t, err) envData := readProto() @@ -231,19 +238,20 @@ func TestSuccessfulUploadPackDeepenRequest(t *testing.T) { } func testSuccessfulUploadPackDeepenRequest(t *testing.T, ctx context.Context) { - serverSocketPath, stop := runSmartHTTPServer(t, config.Config) - defer stop() + cfgBuilder := testcfg.NewGitalyCfgBuilder() + defer cfgBuilder.Cleanup() + cfg, repos := cfgBuilder.BuildWithRepoAt(t, t.Name()) - testRepo, _, cleanup := gittest.CloneRepo(t) - defer cleanup() + serverSocketPath, stop := runSmartHTTPServer(t, cfg) + defer stop() requestBody := &bytes.Buffer{} pktline.WriteString(requestBody, fmt.Sprintf("want e63f41fe459e62e1228fcef60d7189127aeba95a %s\n", clientCapabilities)) pktline.WriteString(requestBody, "deepen 1") pktline.WriteFlush(requestBody) - rpcRequest := &gitalypb.PostUploadPackRequest{Repository: testRepo} - response, err := makePostUploadPackRequest(ctx, t, serverSocketPath, config.Config.Auth.Token, rpcRequest, requestBody) + rpcRequest := &gitalypb.PostUploadPackRequest{Repository: repos[0]} + response, err := makePostUploadPackRequest(ctx, t, serverSocketPath, cfg.Auth.Token, rpcRequest, requestBody) // This assertion is the main reason this test exists. assert.NoError(t, err) @@ -251,17 +259,17 @@ func testSuccessfulUploadPackDeepenRequest(t *testing.T, ctx context.Context) { } func TestUploadPackWithPackObjectsHook(t *testing.T) { - hookDir, cleanup := testhelper.TempDir(t) - defer cleanup() + cfgBuilder := testcfg.NewGitalyCfgBuilder() + defer cfgBuilder.Cleanup() + cfg, repos := cfgBuilder.BuildWithRepoAt(t, t.Name()) + repoPath := filepath.Join(cfg.Storages[0].Path, repos[0].RelativePath) - defer func(old string) { - config.Config.BinDir = old - }(config.Config.BinDir) - config.Config.BinDir = hookDir + var cleanup testhelper.Cleanup + cfg.BinDir, cleanup = testhelper.TempDir(t) + defer cleanup() - outputPath := filepath.Join(hookDir, "output") - hookScript := fmt.Sprintf("#!/bin/sh\necho 'I was invoked' >'%s'\nshift\nexec '%s' \"$@\"\n", - outputPath, config.Config.Git.BinPath) + outputPath := filepath.Join(cfg.BinDir, "output") + hookScript := fmt.Sprintf("#!/bin/sh\necho 'I was invoked' >'%s'\nshift\nexec '%s' \"$@\"\n", outputPath, cfg.Git.BinPath) // We're using a custom pack-objects hook for git-upload-pack. In order // to assure that it's getting executed as expected, we're writing a @@ -270,15 +278,12 @@ func TestUploadPackWithPackObjectsHook(t *testing.T) { // out. In the best case we'd have just printed the error to stderr and // check the return error message. But it's unfortunately not // transferred back. - cleanup = testhelper.WriteExecutable(t, filepath.Join(hookDir, "gitaly-hooks"), []byte(hookScript)) + cleanup = testhelper.WriteExecutable(t, filepath.Join(cfg.BinDir, "gitaly-hooks"), []byte(hookScript)) defer cleanup() - serverSocketPath, stop := runSmartHTTPServer(t, config.Config) + serverSocketPath, stop := runSmartHTTPServer(t, cfg) defer stop() - repo, repoPath, cleanup := gittest.CloneRepo(t) - defer cleanup() - oldHead := bytes.TrimSpace(testhelper.MustRunCommand(t, nil, "git", "-C", repoPath, "rev-parse", "master~")) newHead := bytes.TrimSpace(testhelper.MustRunCommand(t, nil, "git", "-C", repoPath, "rev-parse", "master")) @@ -291,8 +296,8 @@ func TestUploadPackWithPackObjectsHook(t *testing.T) { ctx, cancel := testhelper.Context() defer cancel() - _, err := makePostUploadPackRequest(ctx, t, serverSocketPath, config.Config.Auth.Token, &gitalypb.PostUploadPackRequest{ - Repository: repo, + _, err := makePostUploadPackRequest(ctx, t, serverSocketPath, cfg.Auth.Token, &gitalypb.PostUploadPackRequest{ + Repository: repos[0], }, requestBuffer) require.NoError(t, err) @@ -307,18 +312,22 @@ func TestFailedUploadPackRequestDueToValidationError(t *testing.T) { } func testFailedUploadPackRequestDueToValidationError(t *testing.T, ctx context.Context) { - serverSocketPath, stop := runSmartHTTPServer(t, config.Config) + cfgBuilder := testcfg.NewGitalyCfgBuilder() + defer cfgBuilder.Cleanup() + cfg := cfgBuilder.Build(t) + + serverSocketPath, stop := runSmartHTTPServer(t, cfg) defer stop() rpcRequests := []gitalypb.PostUploadPackRequest{ {Repository: &gitalypb.Repository{StorageName: "fake", RelativePath: "path"}}, // Repository doesn't exist {Repository: nil}, // Repository is nil - {Repository: &gitalypb.Repository{StorageName: "default", RelativePath: "path/to/repo"}, Data: []byte("Fail")}, // Data exists on first request + {Repository: &gitalypb.Repository{StorageName: cfg.Storages[0].Name, RelativePath: "path/to/repo"}, Data: []byte("Fail")}, // Data exists on first request } for _, rpcRequest := range rpcRequests { t.Run(fmt.Sprintf("%v", rpcRequest), func(t *testing.T) { - _, err := makePostUploadPackRequest(ctx, t, serverSocketPath, config.Config.Auth.Token, &rpcRequest, bytes.NewBuffer(nil)) + _, err := makePostUploadPackRequest(ctx, t, serverSocketPath, cfg.Auth.Token, &rpcRequest, bytes.NewBuffer(nil)) testhelper.RequireGrpcError(t, err, codes.InvalidArgument) }) } @@ -399,21 +408,25 @@ func TestUploadPackRequestForPartialCloneSuccess(t *testing.T) { } func testUploadPackRequestForPartialCloneSuccess(t *testing.T, ctx context.Context) { + cfgBuilder := testcfg.NewGitalyCfgBuilder() + defer cfgBuilder.Cleanup() + cfg, repos := cfgBuilder.BuildWithRepoAt(t, t.Name()) + + testhelper.ConfigureGitalyHooksBin(t, cfg) + negotiationMetrics := prometheus.NewCounterVec(prometheus.CounterOpts{}, []string{"feature"}) serverSocketPath, stop := runSmartHTTPServer( - t, config.Config, WithPackfileNegotiationMetrics(negotiationMetrics), + t, cfg, WithPackfileNegotiationMetrics(negotiationMetrics), ) defer stop() - _, testRepoPath, cleanup := gittest.CloneRepo(t) - defer cleanup() - - storagePath := testhelper.GitlabTestStoragePath() + storagePath := cfg.Storages[0].Path remoteRepoRelativePath := "gitlab-test-remote" localRepoRelativePath := "gitlab-test-local" remoteRepoPath := filepath.Join(storagePath, remoteRepoRelativePath) localRepoPath := filepath.Join(storagePath, localRepoRelativePath) + testRepoPath := filepath.Join(storagePath, repos[0].RelativePath) // Make a non-bare clone of the test repo to act as a remote one testhelper.MustRunCommand(t, nil, "git", "clone", testRepoPath, remoteRepoPath) // Make a bare clone of the test repo to act as a local one and to leave the original repo intact for other tests @@ -447,12 +460,12 @@ func testUploadPackRequestForPartialCloneSuccess(t *testing.T, ctx context.Conte req := &gitalypb.PostUploadPackRequest{ Repository: &gitalypb.Repository{ - StorageName: "default", + StorageName: cfg.Storages[0].Name, RelativePath: filepath.Join(remoteRepoRelativePath, ".git"), }, } - responseBuffer, err := makePostUploadPackRequest(ctx, t, serverSocketPath, config.Config.Auth.Token, req, &requestBuffer) + responseBuffer, err := makePostUploadPackRequest(ctx, t, serverSocketPath, cfg.Auth.Token, req, &requestBuffer) require.NoError(t, err) pack, version, entries := extractPackDataFromResponse(t, responseBuffer) @@ -466,9 +479,9 @@ func testUploadPackRequestForPartialCloneSuccess(t *testing.T, ctx context.Conte // c1788657b95998a2f177a4f86d68a60f2a80117f is CONTRIBUTING.md, which is > 200 bytese blobGreaterThanLimit := "c1788657b95998a2f177a4f86d68a60f2a80117f" - gittest.GitObjectMustExist(t, config.Config.Git.BinPath, localRepoPath, blobLessThanLimit) - gittest.GitObjectMustExist(t, config.Config.Git.BinPath, remoteRepoPath, blobGreaterThanLimit) - gittest.GitObjectMustNotExist(t, config.Config.Git.BinPath, localRepoPath, blobGreaterThanLimit) + gittest.GitObjectMustExist(t, cfg.Git.BinPath, localRepoPath, blobLessThanLimit) + gittest.GitObjectMustExist(t, cfg.Git.BinPath, remoteRepoPath, blobGreaterThanLimit) + gittest.GitObjectMustNotExist(t, cfg.Git.BinPath, localRepoPath, blobGreaterThanLimit) newBranch := "new-branch" newHead = []byte(gittest.CreateCommit(t, remoteRepoPath, newBranch, &gittest.CreateCommitOpts{ @@ -484,7 +497,7 @@ func testUploadPackRequestForPartialCloneSuccess(t *testing.T, ctx context.Conte pktline.WriteFlush(&requestBuffer) pktline.WriteFlush(&requestBuffer) - _, err = makePostUploadPackRequest(ctx, t, serverSocketPath, config.Config.Auth.Token, req, &requestBuffer) + _, err = makePostUploadPackRequest(ctx, t, serverSocketPath, cfg.Auth.Token, req, &requestBuffer) require.NoError(t, err) metric, err := negotiationMetrics.GetMetricWithLabelValues("filter") diff --git a/internal/gitaly/service/ssh/receive_pack_test.go b/internal/gitaly/service/ssh/receive_pack_test.go index ca6f40013..2643b3a27 100644 --- a/internal/gitaly/service/ssh/receive_pack_test.go +++ b/internal/gitaly/service/ssh/receive_pack_test.go @@ -20,21 +20,23 @@ import ( "gitlab.com/gitlab-org/gitaly/internal/git/objectpool" "gitlab.com/gitlab-org/gitaly/internal/gitaly/config" "gitlab.com/gitlab-org/gitaly/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/internal/testhelper/testcfg" "gitlab.com/gitlab-org/gitaly/proto/go/gitalypb" "gitlab.com/gitlab-org/gitaly/streamio" "google.golang.org/grpc/codes" ) func TestFailedReceivePackRequestDueToValidationError(t *testing.T) { - serverSocketPath, stop := runSSHServer(t) + cfgBuilder := testcfg.NewGitalyCfgBuilder() + defer cfgBuilder.Cleanup() + cfg, repos := cfgBuilder.BuildWithRepoAt(t, t.Name()) + + serverSocketPath, stop := runSSHServer(t, cfg) defer stop() client, conn := newSSHClient(t, serverSocketPath) defer conn.Close() - testRepo, _, cleanup := gittest.CloneRepo(t) - defer cleanup() - tests := []struct { Desc string Req *gitalypb.SSHReceivePackRequest @@ -42,7 +44,7 @@ func TestFailedReceivePackRequestDueToValidationError(t *testing.T) { }{ { Desc: "Repository.RelativePath is empty", - Req: &gitalypb.SSHReceivePackRequest{Repository: &gitalypb.Repository{StorageName: "default", RelativePath: ""}, GlId: "user-123"}, + Req: &gitalypb.SSHReceivePackRequest{Repository: &gitalypb.Repository{StorageName: cfg.Storages[0].Name, RelativePath: ""}, GlId: "user-123"}, Code: codes.InvalidArgument, }, { @@ -52,12 +54,12 @@ func TestFailedReceivePackRequestDueToValidationError(t *testing.T) { }, { Desc: "Empty GlId", - Req: &gitalypb.SSHReceivePackRequest{Repository: &gitalypb.Repository{StorageName: "default", RelativePath: testRepo.GetRelativePath()}, GlId: ""}, + Req: &gitalypb.SSHReceivePackRequest{Repository: &gitalypb.Repository{StorageName: cfg.Storages[0].Name, RelativePath: repos[0].GetRelativePath()}, GlId: ""}, Code: codes.InvalidArgument, }, { Desc: "Data exists on first request", - Req: &gitalypb.SSHReceivePackRequest{Repository: &gitalypb.Repository{StorageName: "default", RelativePath: testRepo.GetRelativePath()}, GlId: "user-123", Stdin: []byte("Fail")}, + Req: &gitalypb.SSHReceivePackRequest{Repository: &gitalypb.Repository{StorageName: cfg.Storages[0].Name, RelativePath: repos[0].GetRelativePath()}, GlId: "user-123", Stdin: []byte("Fail")}, Code: codes.InvalidArgument, }, } @@ -80,28 +82,29 @@ func TestFailedReceivePackRequestDueToValidationError(t *testing.T) { } func TestReceivePackPushSuccess(t *testing.T) { - defer func(dir string) { config.Config.GitlabShell.Dir = dir }(config.Config.GitlabShell.Dir) - config.Config.GitlabShell.Dir = "/foo/bar/gitlab-shell" + cfgBuilder := testcfg.NewGitalyCfgBuilder() + defer cfgBuilder.Cleanup() + cfg, repos := cfgBuilder.BuildWithRepoAt(t, t.Name()) + + cfg.GitlabShell.Dir = "/foo/bar/gitlab-shell" hookOutputFile, cleanup := gittest.CaptureHookEnv(t) defer cleanup() - serverSocketPath, stop := runSSHServer(t) + serverSocketPath, stop := runSSHServer(t, cfg) defer stop() glRepository := "project-456" glProjectPath := "project/path" - lHead, rHead, err := testCloneAndPush(t, serverSocketPath, pushParams{ + lHead, rHead, err := testCloneAndPush(t, cfg.Storages[0].Path, serverSocketPath, repos[0], pushParams{ storageName: testhelper.DefaultStorageName, glID: "123", glUsername: "user", glRepository: glRepository, glProjectPath: glProjectPath, }) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) require.Equal(t, lHead, rHead, "local and remote head not equal. push failed") envData, err := ioutil.ReadFile(hookOutputFile) @@ -113,7 +116,7 @@ func TestReceivePackPushSuccess(t *testing.T) { // Compare the repository up front so that we can use require.Equal for // the remaining values. testhelper.ProtoEqual(t, &gitalypb.Repository{ - StorageName: testhelper.DefaultStorageName, + StorageName: cfg.Storages[0].Name, RelativePath: "gitlab-test-ssh-receive-pack.git", GlProjectPath: glProjectPath, GlRepository: glRepository, @@ -127,10 +130,10 @@ func TestReceivePackPushSuccess(t *testing.T) { payload.Praefect = nil require.Equal(t, git.HooksPayload{ - BinDir: config.Config.BinDir, - GitPath: config.Config.Git.BinPath, - InternalSocket: config.Config.GitalyInternalSocketPath(), - InternalSocketToken: config.Config.Auth.Token, + BinDir: cfg.BinDir, + GitPath: cfg.Git.BinPath, + InternalSocket: cfg.GitalyInternalSocketPath(), + InternalSocketToken: cfg.Auth.Token, ReceiveHooksPayload: &git.ReceiveHooksPayload{ UserID: "123", Username: "user", @@ -141,15 +144,19 @@ func TestReceivePackPushSuccess(t *testing.T) { } func TestReceivePackPushSuccessWithGitProtocol(t *testing.T) { - defer func(old config.Cfg) { config.Config = old }(config.Config) - readProto, cfg, restore := gittest.EnableGitProtocolV2Support(t, config.Config) + cfgBuilder := testcfg.NewGitalyCfgBuilder() + defer cfgBuilder.Cleanup() + cfg, repos := cfgBuilder.BuildWithRepoAt(t, t.Name()) + + testhelper.ConfigureGitalyHooksBin(t, cfg) + + readProto, cfg, restore := gittest.EnableGitProtocolV2Support(t, cfg) defer restore() - config.Config = cfg - serverSocketPath, stop := runSSHServer(t) + serverSocketPath, stop := runSSHServer(t, cfg) defer stop() - lHead, rHead, err := testCloneAndPush(t, serverSocketPath, pushParams{ + lHead, rHead, err := testCloneAndPush(t, cfg.Storages[0].Path, serverSocketPath, repos[0], pushParams{ storageName: testhelper.DefaultStorageName, glRepository: "project-123", glID: "1", @@ -164,18 +171,26 @@ func TestReceivePackPushSuccessWithGitProtocol(t *testing.T) { } func TestReceivePackPushFailure(t *testing.T) { - serverSocketPath, stop := runSSHServer(t) + cfgBuilder := testcfg.NewGitalyCfgBuilder() + defer cfgBuilder.Cleanup() + cfg, repos := cfgBuilder.BuildWithRepoAt(t, t.Name()) + + serverSocketPath, stop := runSSHServer(t, cfg) defer stop() - _, _, err := testCloneAndPush(t, serverSocketPath, pushParams{storageName: "foobar", glID: "1"}) + _, _, err := testCloneAndPush(t, cfg.Storages[0].Path, serverSocketPath, repos[0], pushParams{storageName: "foobar", glID: "1"}) require.Error(t, err, "local and remote head equal. push did not fail") - _, _, err = testCloneAndPush(t, serverSocketPath, pushParams{storageName: testhelper.DefaultStorageName, glID: ""}) + _, _, err = testCloneAndPush(t, cfg.Storages[0].Path, serverSocketPath, repos[0], pushParams{storageName: cfg.Storages[0].Name, glID: ""}) require.Error(t, err, "local and remote head equal. push did not fail") } func TestReceivePackPushHookFailure(t *testing.T) { - serverSocketPath, stop := runSSHServer(t) + cfgBuilder := testcfg.NewGitalyCfgBuilder() + defer cfgBuilder.Cleanup() + cfg, repos := cfgBuilder.BuildWithRepoAt(t, t.Name()) + + serverSocketPath, stop := runSSHServer(t, cfg) defer stop() hookDir, cleanup := testhelper.TempDir(t) @@ -184,18 +199,25 @@ func TestReceivePackPushHookFailure(t *testing.T) { defer func(old string) { hooks.Override = old }(hooks.Override) hooks.Override = hookDir - require.NoError(t, os.MkdirAll(hooks.Path(config.Config), 0755)) + require.NoError(t, os.MkdirAll(hooks.Path(cfg), 0755)) hookContent := []byte("#!/bin/sh\nexit 1") - ioutil.WriteFile(filepath.Join(hooks.Path(config.Config), "pre-receive"), hookContent, 0755) + ioutil.WriteFile(filepath.Join(hooks.Path(cfg), "pre-receive"), hookContent, 0755) - _, _, err := testCloneAndPush(t, serverSocketPath, pushParams{storageName: testhelper.DefaultStorageName, glID: "1"}) + _, _, err := testCloneAndPush(t, cfg.Storages[0].Path, serverSocketPath, repos[0], pushParams{storageName: cfg.Storages[0].Name, glID: "1"}) require.Error(t, err) require.Contains(t, err.Error(), "(pre-receive hook declined)") } func TestObjectPoolRefAdvertisementHidingSSH(t *testing.T) { - serverSocketPath, stop := runSSHServer(t) + cfgBuilder := testcfg.NewGitalyCfgBuilder() + defer cfgBuilder.Cleanup() + cfg, repos := cfgBuilder.BuildWithRepoAt(t, t.Name()) + repo := repos[0] + + testhelper.ConfigureGitalyHooksBin(t, cfg) + + serverSocketPath, stop := runSSHServer(t, cfg) defer stop() client, conn := newSSHClient(t, serverSocketPath) @@ -207,10 +229,7 @@ func TestObjectPoolRefAdvertisementHidingSSH(t *testing.T) { stream, err := client.SSHReceivePack(ctx) require.NoError(t, err) - repo, _, cleanupFn := gittest.CloneRepo(t) - defer cleanupFn() - - pool, err := objectpool.NewObjectPool(config.Config, config.NewLocator(config.Config), git.NewExecCommandFactory(config.Config), repo.GetStorageName(), gittest.NewObjectPoolName(t)) + pool, err := objectpool.NewObjectPool(cfg, config.NewLocator(cfg), git.NewExecCommandFactory(cfg), repo.GetStorageName(), gittest.NewObjectPoolName(t)) require.NoError(t, err) require.NoError(t, pool.Create(ctx, repo)) @@ -222,7 +241,7 @@ func TestObjectPoolRefAdvertisementHidingSSH(t *testing.T) { // First request require.NoError(t, stream.Send(&gitalypb.SSHReceivePackRequest{ - Repository: &gitalypb.Repository{StorageName: "default", RelativePath: repo.GetRelativePath()}, GlId: "user-123", + Repository: &gitalypb.Repository{StorageName: cfg.Storages[0].Name, RelativePath: repo.GetRelativePath()}, GlId: "user-123", })) require.NoError(t, stream.Send(&gitalypb.SSHReceivePackRequest{Stdin: []byte("0000")})) @@ -240,28 +259,27 @@ func TestObjectPoolRefAdvertisementHidingSSH(t *testing.T) { } func TestSSHReceivePackToHooks(t *testing.T) { - secretToken := "secret token" - glRepository := "some_repo" - glID := "key-123" + cfgBuilder := testcfg.NewGitalyCfgBuilder() + defer cfgBuilder.Cleanup() + cfg, repos := cfgBuilder.BuildWithRepoAt(t, t.Name()) - defer func(old config.Cfg) { config.Config = old }(config.Config) - readProto, cfg, restore := gittest.EnableGitProtocolV2Support(t, config.Config) - defer restore() - config.Config = cfg + testhelper.ConfigureGitalyHooksBin(t, cfg) - serverSocketPath, stop := runSSHServer(t) - defer stop() + const ( + secretToken = "secret token" + glRepository = "some_repo" + glID = "key-123" + ) + + readProto, cfg, restore := gittest.EnableGitProtocolV2Support(t, cfg) + defer restore() tempGitlabShellDir, cleanup := testhelper.TempDir(t) defer cleanup() - defer func(gitlabShell config.GitlabShell) { - config.Config.GitlabShell = gitlabShell - }(config.Config.GitlabShell) + cfg.GitlabShell.Dir = tempGitlabShellDir - config.Config.GitlabShell.Dir = tempGitlabShellDir - - cloneDetails, cleanup := setupSSHClone(t) + cloneDetails, cleanup := setupSSHClone(t, cfg.Storages[0].Path, repos[0]) defer cleanup() serverURL, cleanup := testhelper.NewGitlabTestServer(t, testhelper.GitlabTestServerOptions{ @@ -278,14 +296,17 @@ func TestSSHReceivePackToHooks(t *testing.T) { testhelper.WriteShellSecretFile(t, tempGitlabShellDir, secretToken) - config.Config.Gitlab.URL = serverURL - config.Config.Gitlab.SecretFile = filepath.Join(tempGitlabShellDir, ".gitlab_shell_secret") + cfg.Gitlab.URL = serverURL + cfg.Gitlab.SecretFile = filepath.Join(tempGitlabShellDir, ".gitlab_shell_secret") - cleanup = gittest.WriteCheckNewObjectExistsHook(t, config.Config.Git.BinPath, cloneDetails.RemoteRepoPath) + cleanup = gittest.WriteCheckNewObjectExistsHook(t, cfg.Git.BinPath, cloneDetails.RemoteRepoPath) defer cleanup() + serverSocketPath, stop := runSSHServer(t, cfg) + defer stop() + lHead, rHead, err := sshPush(t, cloneDetails, serverSocketPath, pushParams{ - storageName: testhelper.DefaultStorageName, + storageName: cfg.Storages[0].Name, glID: glID, glRepository: glRepository, gitProtocol: git.ProtocolV2, @@ -305,11 +326,7 @@ type SSHCloneDetails struct { } // setupSSHClone sets up a test clone -func setupSSHClone(t *testing.T) (SSHCloneDetails, func()) { - testRepo, _, cleanup := gittest.CloneRepo(t) - defer cleanup() - - storagePath := testhelper.GitlabTestStoragePath() +func setupSSHClone(t *testing.T, storagePath string, testRepo *gitalypb.Repository) (SSHCloneDetails, func()) { tempRepo := "gitlab-test-ssh-receive-pack.git" testRepoPath := filepath.Join(storagePath, testRepo.GetRelativePath()) remoteRepoPath := filepath.Join(storagePath, tempRepo) @@ -359,7 +376,7 @@ func sshPush(t *testing.T, cloneDetails SSHCloneDetails, serverSocketPath string }) require.NoError(t, err) - cmd := exec.Command(config.Config.Git.BinPath, "-C", cloneDetails.LocalRepoPath, "push", "-v", "git@localhost:test/test.git", "master") + cmd := exec.Command("git", "-C", cloneDetails.LocalRepoPath, "push", "-v", "git@localhost:test/test.git", "master") cmd.Env = []string{ fmt.Sprintf("GITALY_PAYLOAD=%s", payload), fmt.Sprintf("GITALY_ADDRESS=%s", serverSocketPath), @@ -381,8 +398,8 @@ func sshPush(t *testing.T, cloneDetails SSHCloneDetails, serverSocketPath string return string(localHead), string(remoteHead), nil } -func testCloneAndPush(t *testing.T, serverSocketPath string, params pushParams) (string, string, error) { - cloneDetails, cleanup := setupSSHClone(t) +func testCloneAndPush(t *testing.T, storagePath, serverSocketPath string, testRepo *gitalypb.Repository, params pushParams) (string, string, error) { + cloneDetails, cleanup := setupSSHClone(t, storagePath, testRepo) defer cleanup() return sshPush(t, cloneDetails, serverSocketPath, params) diff --git a/internal/gitaly/service/ssh/testhelper_test.go b/internal/gitaly/service/ssh/testhelper_test.go index 5bf277a7b..1345991c5 100644 --- a/internal/gitaly/service/ssh/testhelper_test.go +++ b/internal/gitaly/service/ssh/testhelper_test.go @@ -40,15 +40,15 @@ func testMain(m *testing.M) int { return m.Run() } -func runSSHServer(t *testing.T, serverOpts ...ServerOpt) (string, func()) { - locator := config.NewLocator(config.Config) - txManager := transaction.NewManager(config.Config) - hookManager := hook.NewManager(locator, txManager, hook.GitlabAPIStub, config.Config) - gitCmdFactory := git.NewExecCommandFactory(config.Config) +func runSSHServer(t *testing.T, cfg config.Cfg, serverOpts ...ServerOpt) (string, func()) { + locator := config.NewLocator(cfg) + txManager := transaction.NewManager(cfg) + hookManager := hook.NewManager(locator, txManager, hook.GitlabAPIStub, cfg) + gitCmdFactory := git.NewExecCommandFactory(cfg) - srv := testhelper.NewServer(t, nil, nil, testhelper.WithInternalSocket(config.Config)) - gitalypb.RegisterSSHServiceServer(srv.GrpcServer(), NewServer(config.Config, locator, gitCmdFactory, serverOpts...)) - gitalypb.RegisterHookServiceServer(srv.GrpcServer(), hookservice.NewServer(config.Config, hookManager, gitCmdFactory)) + srv := testhelper.NewServer(t, nil, nil, testhelper.WithInternalSocket(cfg)) + gitalypb.RegisterSSHServiceServer(srv.GrpcServer(), NewServer(cfg, locator, gitCmdFactory, serverOpts...)) + gitalypb.RegisterHookServiceServer(srv.GrpcServer(), hookservice.NewServer(cfg, hookManager, gitCmdFactory)) srv.Start(t) return "unix://" + srv.Socket(), srv.Stop diff --git a/internal/gitaly/service/ssh/upload_archive_test.go b/internal/gitaly/service/ssh/upload_archive_test.go index b6c0e2379..edb7d25c5 100644 --- a/internal/gitaly/service/ssh/upload_archive_test.go +++ b/internal/gitaly/service/ssh/upload_archive_test.go @@ -17,7 +17,7 @@ import ( ) func TestFailedUploadArchiveRequestDueToTimeout(t *testing.T) { - serverSocketPath, stop := runSSHServer(t, WithArchiveRequestTimeout(100*time.Microsecond)) + serverSocketPath, stop := runSSHServer(t, config.Config, WithArchiveRequestTimeout(100*time.Microsecond)) defer stop() client, conn := newSSHClient(t, serverSocketPath) @@ -54,7 +54,7 @@ func TestFailedUploadArchiveRequestDueToTimeout(t *testing.T) { } func TestFailedUploadArchiveRequestDueToValidationError(t *testing.T) { - serverSocketPath, stop := runSSHServer(t) + serverSocketPath, stop := runSSHServer(t, config.Config) defer stop() client, conn := newSSHClient(t, serverSocketPath) @@ -103,10 +103,10 @@ func TestFailedUploadArchiveRequestDueToValidationError(t *testing.T) { } func TestUploadArchiveSuccess(t *testing.T) { - serverSocketPath, stop := runSSHServer(t) + serverSocketPath, stop := runSSHServer(t, config.Config) defer stop() - cmd := exec.Command(config.Config.Git.BinPath, "archive", "master", "--remote=git@localhost:test/test.git") + cmd := exec.Command("git", "archive", "master", "--remote=git@localhost:test/test.git") testRepo, _, cleanup := gittest.CloneRepo(t) defer cleanup() diff --git a/internal/gitaly/service/ssh/upload_pack_test.go b/internal/gitaly/service/ssh/upload_pack_test.go index c1cb0ada1..a54273158 100644 --- a/internal/gitaly/service/ssh/upload_pack_test.go +++ b/internal/gitaly/service/ssh/upload_pack_test.go @@ -15,6 +15,7 @@ import ( "github.com/prometheus/client_golang/prometheus" promtest "github.com/prometheus/client_golang/prometheus/testutil" "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitaly/internal/command" "gitlab.com/gitlab-org/gitaly/internal/git" "gitlab.com/gitlab-org/gitaly/internal/git/gittest" "gitlab.com/gitlab-org/gitaly/internal/git/pktline" @@ -22,6 +23,7 @@ import ( "gitlab.com/gitlab-org/gitaly/internal/helper/text" "gitlab.com/gitlab-org/gitaly/internal/metadata/featureflag" "gitlab.com/gitlab-org/gitaly/internal/testhelper" + "gitlab.com/gitlab-org/gitaly/internal/testhelper/testcfg" "gitlab.com/gitlab-org/gitaly/proto/go/gitalypb" "google.golang.org/grpc/codes" ) @@ -72,17 +74,17 @@ func (cmd cloneCommand) execute(t *testing.T) error { return nil } -func (cmd cloneCommand) test(t *testing.T, localRepoPath string) (string, string, string, string) { +func (cmd cloneCommand) test(t *testing.T, repoPath string, localRepoPath string) (string, string, string, string) { + t.Helper() + defer os.RemoveAll(localRepoPath) err := cmd.execute(t) require.NoError(t, err) - testRepo, _, cleanup := gittest.CloneRepo(t) - defer cleanup() - - storagePath := testhelper.GitlabTestStoragePath() - testRepoPath := filepath.Join(storagePath, testRepo.GetRelativePath()) + //testRepo := gittest.CloneRepoAtStorage(t, repoPath.Storages[0], t.Name()) + //testRepoPath := filepath.Join(repoPath.Storages[0].Path, testRepo.GetRelativePath()) + testRepoPath := repoPath remoteHead := text.ChompBytes(testhelper.MustRunCommand(t, nil, "git", "-C", testRepoPath, "rev-parse", "master")) localHead := text.ChompBytes(testhelper.MustRunCommand(t, nil, "git", "-C", localRepoPath, "rev-parse", "master")) @@ -94,7 +96,7 @@ func (cmd cloneCommand) test(t *testing.T, localRepoPath string) (string, string } func TestFailedUploadPackRequestDueToTimeout(t *testing.T) { - serverSocketPath, stop := runSSHServer(t, WithUploadPackRequestTimeout(10*time.Microsecond)) + serverSocketPath, stop := runSSHServer(t, config.Config, WithUploadPackRequestTimeout(10*time.Microsecond)) defer stop() client, conn := newSSHClient(t, serverSocketPath) @@ -152,7 +154,7 @@ func requireFailedSSHStream(t *testing.T, recv func() (int32, error)) { } func TestFailedUploadPackRequestDueToValidationError(t *testing.T) { - serverSocketPath, stop := runSSHServer(t) + serverSocketPath, stop := runSSHServer(t, config.Config) defer stop() client, conn := newSSHClient(t, serverSocketPath) @@ -201,10 +203,15 @@ func TestFailedUploadPackRequestDueToValidationError(t *testing.T) { } func TestUploadPackCloneSuccess(t *testing.T) { + cfgBuilder := testcfg.NewGitalyCfgBuilder(testcfg.WithBase(config.Config)) + defer cfgBuilder.Cleanup() + cfg, repos := cfgBuilder.BuildWithRepoAt(t, t.Name()) + repoPath := filepath.Join(cfg.Storages[0].Path, repos[0].RelativePath) + negotiationMetrics := prometheus.NewCounterVec(prometheus.CounterOpts{}, []string{"feature"}) serverSocketPath, stop := runSSHServer( - t, WithPackfileNegotiationMetrics(negotiationMetrics), + t, cfg, WithPackfileNegotiationMetrics(negotiationMetrics), ) defer stop() @@ -218,17 +225,17 @@ func TestUploadPackCloneSuccess(t *testing.T) { featureFlags []string }{ { - cmd: exec.Command(config.Config.Git.BinPath, "clone", "git@localhost:test/test.git", localRepoPath), + cmd: exec.Command(cfg.Git.BinPath, "clone", "git@localhost:test/test.git", localRepoPath), desc: "full clone", deepen: 0, }, { - cmd: exec.Command(config.Config.Git.BinPath, "clone", "--depth", "1", "git@localhost:test/test.git", localRepoPath), + cmd: exec.Command(cfg.Git.BinPath, "clone", "--depth", "1", "git@localhost:test/test.git", localRepoPath), desc: "shallow clone", deepen: 1, }, { - cmd: exec.Command(config.Config.Git.BinPath, "clone", "git@localhost:test/test.git", localRepoPath), + cmd: exec.Command(cfg.Git.BinPath, "clone", "git@localhost:test/test.git", localRepoPath), desc: "full clone with hook", deepen: 0, featureFlags: []string{ @@ -236,7 +243,7 @@ func TestUploadPackCloneSuccess(t *testing.T) { }, }, { - cmd: exec.Command(config.Config.Git.BinPath, "clone", "--depth", "1", "git@localhost:test/test.git", localRepoPath), + cmd: exec.Command(cfg.Git.BinPath, "clone", "--depth", "1", "git@localhost:test/test.git", localRepoPath), desc: "shallow clone with hook", deepen: 1, featureFlags: []string{ @@ -245,20 +252,17 @@ func TestUploadPackCloneSuccess(t *testing.T) { }, } - testRepo, _, cleanup := gittest.CloneRepo(t) - defer cleanup() - for _, tc := range tests { t.Run(tc.desc, func(t *testing.T) { negotiationMetrics.Reset() cmd := cloneCommand{ - repository: testRepo, + repository: repos[0], command: tc.cmd, featureFlags: tc.featureFlags, server: serverSocketPath, } - lHead, rHead, _, _ := cmd.test(t, localRepoPath) + lHead, rHead, _, _ := cmd.test(t, repoPath, localRepoPath) require.Equal(t, lHead, rHead, "local and remote head not equal") metric, err := negotiationMetrics.GetMetricWithLabelValues("deepen") @@ -288,7 +292,7 @@ func TestUploadPackWithPackObjectsHook(t *testing.T) { // cause the clone to fail with this error message. testhelper.WriteExecutable(t, filepath.Join(filterDir, "gitaly-hooks"), []byte(hookScript)) - serverSocketPath, stop := runSSHServer(t) + serverSocketPath, stop := runSSHServer(t, config.Config) defer stop() localRepoPath, cleanup := testhelper.TempDir(t) @@ -299,7 +303,7 @@ func TestUploadPackWithPackObjectsHook(t *testing.T) { err := cloneCommand{ repository: testRepo, - command: exec.Command(config.Config.Git.BinPath, "clone", "git@localhost:test/test.git", localRepoPath), + command: exec.Command("git", "clone", "git@localhost:test/test.git", localRepoPath), featureFlags: []string{ featureflag.UploadPackGitalyHooks.Name, }, @@ -311,7 +315,7 @@ func TestUploadPackWithPackObjectsHook(t *testing.T) { } func TestUploadPackWithoutSideband(t *testing.T) { - serverSocketPath, stop := runSSHServer(t) + serverSocketPath, stop := runSSHServer(t, config.Config) defer stop() // While Git knows the side-band-64 capability, some other clients don't. There is no way @@ -354,7 +358,11 @@ func TestUploadPackWithoutSideband(t *testing.T) { } func TestUploadPackCloneWithPartialCloneFilter(t *testing.T) { - serverSocketPath, stop := runSSHServer(t) + cfgBuilder := testcfg.NewGitalyCfgBuilder() + defer cfgBuilder.Cleanup() + cfg, repos := cfgBuilder.BuildWithRepoAt(t, t.Name()) + + serverSocketPath, stop := runSSHServer(t, cfg) defer stop() // Ruby file which is ~1kB in size and not present in HEAD @@ -370,22 +378,19 @@ func TestUploadPackCloneWithPartialCloneFilter(t *testing.T) { { desc: "full_clone", repoTest: func(t *testing.T, repoPath string) { - gittest.GitObjectMustExist(t, config.Config.Git.BinPath, repoPath, blobGreaterThanLimit) + gittest.GitObjectMustExist(t, cfg.Git.BinPath, repoPath, blobGreaterThanLimit) }, cloneArgs: []string{"clone", "git@localhost:test/test.git"}, }, { desc: "partial_clone", repoTest: func(t *testing.T, repoPath string) { - gittest.GitObjectMustNotExist(t, config.Config.Git.BinPath, repoPath, blobGreaterThanLimit) + gittest.GitObjectMustNotExist(t, cfg.Git.BinPath, repoPath, blobGreaterThanLimit) }, cloneArgs: []string{"clone", "--filter=blob:limit=2048", "git@localhost:test/test.git"}, }, } - testRepo, _, cleanup := gittest.CloneRepo(t) - defer cleanup() - for _, tc := range tests { t.Run(tc.desc, func(t *testing.T) { // Run the clone with filtering enabled in both runs. The only @@ -395,21 +400,26 @@ func TestUploadPackCloneWithPartialCloneFilter(t *testing.T) { defer cleanup() cmd := cloneCommand{ - repository: testRepo, - command: exec.Command(config.Config.Git.BinPath, append(tc.cloneArgs, localPath)...), + repository: repos[0], + command: exec.Command(cfg.Git.BinPath, append(tc.cloneArgs, localPath)...), server: serverSocketPath, } err := cmd.execute(t) defer os.RemoveAll(localPath) require.NoError(t, err, "clone failed") - gittest.GitObjectMustExist(t, config.Config.Git.BinPath, localPath, blobLessThanLimit) + gittest.GitObjectMustExist(t, cfg.Git.BinPath, localPath, blobLessThanLimit) tc.repoTest(t, localPath) }) } } func TestUploadPackCloneSuccessWithGitProtocol(t *testing.T) { + cfgBuilder := testcfg.NewGitalyCfgBuilder(testcfg.WithBase(config.Config)) + defer cfgBuilder.Cleanup() + cfg, repos := cfgBuilder.BuildWithRepoAt(t, t.Name()) + repoPath := filepath.Join(cfg.Storages[0].Path, repos[0].RelativePath) + localRepoPath, cleanup := testhelper.TempDir(t) defer cleanup() @@ -418,36 +428,31 @@ func TestUploadPackCloneSuccessWithGitProtocol(t *testing.T) { desc string }{ { - cmd: exec.Command(config.Config.Git.BinPath, "clone", "git@localhost:test/test.git", localRepoPath), + cmd: exec.Command(cfg.Git.BinPath, "clone", "git@localhost:test/test.git", localRepoPath), desc: "full clone", }, { - cmd: exec.Command(config.Config.Git.BinPath, "clone", "--depth", "1", "git@localhost:test/test.git", localRepoPath), + cmd: exec.Command(cfg.Git.BinPath, "clone", "--depth", "1", "git@localhost:test/test.git", localRepoPath), desc: "shallow clone", }, } - testRepo, _, cleanup := gittest.CloneRepo(t) - defer cleanup() - for _, tc := range tests { t.Run(tc.desc, func(t *testing.T) { - defer func(old config.Cfg) { config.Config = old }(config.Config) - readProto, cfg, restore := gittest.EnableGitProtocolV2Support(t, config.Config) + readProto, cfg, restore := gittest.EnableGitProtocolV2Support(t, cfg) defer restore() - config.Config = cfg - serverSocketPath, stop := runSSHServer(t) + serverSocketPath, stop := runSSHServer(t, cfg) defer stop() cmd := cloneCommand{ - repository: testRepo, + repository: repos[0], command: tc.cmd, server: serverSocketPath, gitProtocol: git.ProtocolV2, } - lHead, rHead, _, _ := cmd.test(t, localRepoPath) + lHead, rHead, _, _ := cmd.test(t, repoPath, localRepoPath) require.Equal(t, lHead, rHead, "local and remote head not equal") envData := readProto() @@ -457,22 +462,30 @@ func TestUploadPackCloneSuccessWithGitProtocol(t *testing.T) { } func TestUploadPackCloneHideTags(t *testing.T) { - serverSocketPath, stop := runSSHServer(t) - defer stop() + cfgTmpl := config.Config + cfgTmpl.Storages = nil - testRepo, _, cleanup := gittest.CloneRepo(t) - defer cleanup() + cfgBuilder := testcfg.NewGitalyCfgBuilder(testcfg.WithBase(cfgTmpl)) + defer cfgBuilder.Cleanup() + cfg, repos := cfgBuilder.BuildWithRepoAt(t, t.Name()) + repoPath := filepath.Join(cfg.Storages[0].Path, repos[0].RelativePath) + + serverSocketPath, stop := runSSHServer(t, cfg) + defer stop() localRepoPath, cleanup := testhelper.TempDir(t) defer cleanup() - cmd := cloneCommand{ - repository: testRepo, - command: exec.Command(config.Config.Git.BinPath, "clone", "--mirror", "git@localhost:test/test.git", localRepoPath), + cmd := exec.Command(cfg.Git.BinPath, "clone", "--mirror", "git@localhost:test/test.git", localRepoPath) + cmd.Env = os.Environ() + cmd.Env = append(command.GitEnv, cmd.Env...) + cloneCmd := cloneCommand{ + repository: repos[0], + command: cmd, server: serverSocketPath, gitConfig: "transfer.hideRefs=refs/tags", } - _, _, lTags, rTags := cmd.test(t, localRepoPath) + _, _, lTags, rTags := cloneCmd.test(t, repoPath, localRepoPath) if lTags == rTags { t.Fatalf("local and remote tags are equal. clone failed: %q != %q", lTags, rTags) @@ -483,7 +496,7 @@ func TestUploadPackCloneHideTags(t *testing.T) { } func TestUploadPackCloneFailure(t *testing.T) { - serverSocketPath, stop := runSSHServer(t) + serverSocketPath, stop := runSSHServer(t, config.Config) defer stop() testRepo, _, cleanup := gittest.CloneRepo(t) @@ -497,7 +510,7 @@ func TestUploadPackCloneFailure(t *testing.T) { StorageName: "foobar", RelativePath: testRepo.GetRelativePath(), }, - command: exec.Command(config.Config.Git.BinPath, "clone", "git@localhost:test/test.git", localRepoPath), + command: exec.Command("git", "clone", "git@localhost:test/test.git", localRepoPath), server: serverSocketPath, } err := cmd.execute(t) diff --git a/internal/testhelper/configure.go b/internal/testhelper/configure.go index 1d9eed9e6..873f45149 100644 --- a/internal/testhelper/configure.go +++ b/internal/testhelper/configure.go @@ -1,6 +1,7 @@ package testhelper import ( + "errors" "fmt" "io/ioutil" "os" @@ -9,8 +10,11 @@ import ( "runtime" "strings" "sync" + "testing" + "time" log "github.com/sirupsen/logrus" + "github.com/stretchr/testify/require" "gitlab.com/gitlab-org/gitaly/internal/gitaly/config" gitalylog "gitlab.com/gitlab-org/gitaly/internal/log" ) @@ -148,6 +152,53 @@ func ConfigureGitalyHooksBinary(outputDir string) { buildCommand(outputDir, "gitaly-hooks") } +func ConfigureGitalyHooksBin(t testing.TB, cfg config.Cfg) { + buildBinary(t, cfg.BinDir, "gitaly-hooks") +} + +func buildBinary(t testing.TB, dstDir, name string) { + binsPath := filepath.Join(testDirectory, "bins") + binPath := filepath.Join(binsPath, name) + lockPath := binPath + ".lock" + + defer func() { + if !t.Failed() { + require.NoError(t, os.MkdirAll(dstDir, os.ModePerm)) + MustRunCommand(t, nil, "cp", binPath, dstDir) + } + }() + + require.NoError(t, os.MkdirAll(binsPath, os.ModePerm)) + + lockFile, err := os.OpenFile(lockPath, os.O_CREATE|os.O_EXCL, 0600) + if err != nil { + if !errors.Is(err, os.ErrExist) { + require.NoError(t, err) + } + // another process is creating the binary at the moment, wait in total for 5 sec + for i := 0; i < 50; i++ { + if _, err := os.Stat(binPath); err != nil { + if !errors.Is(err, os.ErrExist) { + require.NoError(t, err) + } + time.Sleep(100 * time.Millisecond) + continue + } + break + } + require.FailNow(t, "another process is creating binary for too long") + } + defer func() { require.NoError(t, os.Remove(lockPath)) }() + require.NoError(t, lockFile.Close()) + + if _, err := os.Stat(binPath); err != nil { + if !errors.Is(err, os.ErrNotExist) { + require.NoError(t, err) + } + buildCommand(binsPath, name) + } +} + func buildCommand(outputDir, cmd string) { if outputDir == "" { log.Fatal("BinDir must be set") diff --git a/internal/testhelper/testcfg/gitaly_builder.go b/internal/testhelper/testcfg/gitaly_builder.go index f14f84a95..55d7e7f74 100644 --- a/internal/testhelper/testcfg/gitaly_builder.go +++ b/internal/testhelper/testcfg/gitaly_builder.go @@ -75,36 +75,52 @@ func (gc *GitalyCfgBuilder) Build(t testing.TB) config.Cfg { t.Helper() cfg := gc.cfg - cfg.SocketPath = "it is a stub to bypass Validate method" + if cfg.SocketPath == "" { + cfg.SocketPath = "it is a stub to bypass Validate method" + } root := gc.tempDir(t) - cfg.BinDir = filepath.Join(root, "bin.d") - require.NoError(t, os.Mkdir(cfg.BinDir, 0755)) - - cfg.Logging.Dir = filepath.Join(root, "log.d") - require.NoError(t, os.Mkdir(cfg.Logging.Dir, 0755)) + if cfg.BinDir == "" { + cfg.BinDir = filepath.Join(root, "bin.d") + require.NoError(t, os.Mkdir(cfg.BinDir, 0755)) + } - cfg.GitlabShell.Dir = filepath.Join(root, "shell.d") - require.NoError(t, os.Mkdir(cfg.GitlabShell.Dir, 0755)) + if cfg.Logging.Dir == "" { + cfg.Logging.Dir = filepath.Join(root, "log.d") + require.NoError(t, os.Mkdir(cfg.Logging.Dir, 0755)) + } - cfg.InternalSocketDir = filepath.Join(root, "internal_socks.d") - require.NoError(t, os.Mkdir(cfg.InternalSocketDir, 0755)) + if cfg.GitlabShell.Dir == "" { + cfg.GitlabShell.Dir = filepath.Join(root, "shell.d") + require.NoError(t, os.Mkdir(cfg.GitlabShell.Dir, 0755)) + } - storagesDir := filepath.Join(root, "storages.d") - require.NoError(t, os.Mkdir(storagesDir, 0755)) + if cfg.InternalSocketDir == "" { + cfg.InternalSocketDir = filepath.Join(root, "internal_socks.d") + require.NoError(t, os.Mkdir(cfg.InternalSocketDir, 0755)) + } - if len(gc.storages) == 0 { - gc.storages = []string{"default"} + if len(cfg.Storages) != 0 && len(gc.storages) != 0 { + require.FailNow(t, "invalid configuration build setup: fix storages configured") } - // creation of the required storages (empty storage directories) - cfg.Storages = make([]config.Storage, len(gc.storages)) - for i, storageName := range gc.storages { - storagePath := filepath.Join(storagesDir, storageName) - require.NoError(t, os.MkdirAll(storagePath, 0755)) - cfg.Storages[i].Name = storageName - cfg.Storages[i].Path = storagePath + if len(cfg.Storages) == 0 { + storagesDir := filepath.Join(root, "storages.d") + require.NoError(t, os.Mkdir(storagesDir, 0755)) + + if len(gc.storages) == 0 { + gc.storages = []string{"default"} + } + + // creation of the required storages (empty storage directories) + cfg.Storages = make([]config.Storage, len(gc.storages)) + for i, storageName := range gc.storages { + storagePath := filepath.Join(storagesDir, storageName) + require.NoError(t, os.MkdirAll(storagePath, 0755)) + cfg.Storages[i].Name = storageName + cfg.Storages[i].Path = storagePath + } } require.NoError(t, testhelper.ConfigureRuby(&cfg)) @@ -123,7 +139,7 @@ func (gc *GitalyCfgBuilder) BuildWithRepoAt(t testing.TB, relativePath string) ( // clone the test repo to the each storage repos := make([]*gitalypb.Repository, len(cfg.Storages)) for i, gitalyStorage := range cfg.Storages { - repos[i] = gittest.CloneRepoAtStorage(t, gitalyStorage, relativePath) + repos[i] = gittest.CloneRepoAtStorageRoot(t, gitalyStorage.Path, relativePath) repos[i].StorageName = gitalyStorage.Name } diff --git a/internal/testhelper/testserver.go b/internal/testhelper/testserver.go index 58b06afcb..434042858 100644 --- a/internal/testhelper/testserver.go +++ b/internal/testhelper/testserver.go @@ -915,11 +915,13 @@ func WriteTemporaryGitalyConfigFile(t testing.TB, tempDir, gitlabURL, user, pass } // WriteShellSecretFile writes a .gitlab_shell_secret file in the specified directory -func WriteShellSecretFile(t testing.TB, dir, secretToken string) { +func WriteShellSecretFile(t testing.TB, dir, secretToken string) string { t.Helper() require.NoError(t, os.MkdirAll(dir, os.ModeDir)) - require.NoError(t, ioutil.WriteFile(filepath.Join(dir, ".gitlab_shell_secret"), []byte(secretToken), 0644)) + filePath := filepath.Join(dir, ".gitlab_shell_secret") + require.NoError(t, ioutil.WriteFile(filePath, []byte(secretToken), 0644)) + return filePath } // HTTPSettings contains fields for http settings -- cgit v1.2.3