diff options
author | John Cai <jcai@gitlab.com> | 2020-03-16 20:05:35 +0300 |
---|---|---|
committer | John Cai <jcai@gitlab.com> | 2020-03-23 18:23:26 +0300 |
commit | 583746610c60102c4c9f0e123b3dff803a1433be (patch) | |
tree | 94c62dc8b8b19d01bca6e3c70bf606972c0a328d | |
parent | 4bd9b1536b4776ae369b8e43388a25941e18a19e (diff) |
Add test to ensure GIT_OBJECT_DIRECTORY and GIT_ALTERNATE_OBJECT_DIRECTORIES get passed from hook to API
-rw-r--r-- | cmd/gitaly-hooks/hooks_test.go | 27 | ||||
-rw-r--r-- | internal/service/smarthttp/receive_pack_test.go | 2 | ||||
-rw-r--r-- | internal/service/ssh/receive_pack_test.go | 2 | ||||
-rw-r--r-- | internal/testhelper/testhelper.go | 12 | ||||
-rw-r--r-- | internal/testhelper/testserver.go | 40 |
5 files changed, 77 insertions, 6 deletions
diff --git a/cmd/gitaly-hooks/hooks_test.go b/cmd/gitaly-hooks/hooks_test.go index 0d8a162d2..fd8bbe9ce 100644 --- a/cmd/gitaly-hooks/hooks_test.go +++ b/cmd/gitaly-hooks/hooks_test.go @@ -8,6 +8,7 @@ import ( "os" "os/exec" "path/filepath" + "regexp" "strings" "testing" @@ -46,6 +47,8 @@ func TestHooksPrePostReceive(t *testing.T) { changes := "abc" gitPushOptions := []string{"gitpushoption1", "gitpushoption2"} + gitObjectDir := filepath.Join(testRepoPath, "objects", "temp") + gitAlternateObjectDirs := []string{(filepath.Join(testRepoPath, "objects"))} c := testhelper.GitlabTestServerOptions{ User: "", @@ -57,6 +60,9 @@ func TestHooksPrePostReceive(t *testing.T) { PostReceiveCounterDecreased: true, Protocol: "ssh", GitPushOptions: gitPushOptions, + GitObjectDir: gitObjectDir, + GitAlternateObjectDirs: gitAlternateObjectDirs, + RepoPath: testRepoPath, } ts := testhelper.NewGitlabTestServer(t, c) @@ -71,6 +77,9 @@ func TestHooksPrePostReceive(t *testing.T) { testhelper.WriteTemporaryGitlabShellConfigFile(t, tempGitlabShellDir, testhelper.GitlabShellConfig{GitlabURL: ts.URL}) testhelper.WriteShellSecretFile(t, tempGitlabShellDir, secretToken) + gitObjectDirRegex := regexp.MustCompile(`(?m)^GIT_OBJECT_DIRECTORY=(.*)$`) + gitAlternateObjectDirRegex := regexp.MustCompile(`(?m)^GIT_ALTERNATE_OBJECT_DIRECTORIES=(.*)$`) + for _, hook := range []string{"pre-receive", "post-receive"} { t.Run(hook, func(t *testing.T) { customHookOutputPath, cleanup := testhelper.WriteEnvToCustomHook(t, testRepoPath, hook) @@ -88,10 +97,12 @@ func TestHooksPrePostReceive(t *testing.T) { t, tempGitlabShellDir, testhelper.GlHookValues{ - GLID: glID, - GLUsername: glUsername, - GLRepo: glRepository, - GLProtocol: glProtocol, + GLID: glID, + GLUsername: glUsername, + GLRepo: glRepository, + GLProtocol: glProtocol, + GitObjectDir: c.GitObjectDir, + GitAlternateObjectDirs: c.GitAlternateObjectDirs, }, gitPushOptions..., ) @@ -108,6 +119,14 @@ func TestHooksPrePostReceive(t *testing.T) { if hook != "pre-receive" { require.Contains(t, output, "GL_PROTOCOL="+glProtocol) } + + gitObjectDirMatches := gitObjectDirRegex.FindStringSubmatch(output) + require.Len(t, gitObjectDirMatches, 2) + require.Equal(t, gitObjectDir, gitObjectDirMatches[1]) + + gitAlternateObjectDirMatches := gitAlternateObjectDirRegex.FindStringSubmatch(output) + require.Len(t, gitAlternateObjectDirMatches, 2) + require.Equal(t, strings.Join(gitAlternateObjectDirs, ":"), gitAlternateObjectDirMatches[1]) }) } } diff --git a/internal/service/smarthttp/receive_pack_test.go b/internal/service/smarthttp/receive_pack_test.go index f1074ef06..3ef07c6b6 100644 --- a/internal/service/smarthttp/receive_pack_test.go +++ b/internal/service/smarthttp/receive_pack_test.go @@ -317,6 +317,8 @@ func TestPostReceivePackToHooks(t *testing.T) { testhelper.WriteTemporaryGitlabShellConfigFile(t, tempGitlabShellDir, testhelper.GitlabShellConfig{GitlabURL: ts.URL}) testhelper.WriteShellSecretFile(t, tempGitlabShellDir, secretToken) + testhelper.WriteCustomHook(testRepoPath, "pre-receive", []byte(testhelper.CheckNewObjectExists)) + defer func(override string) { hooks.Override = override }(hooks.Override) diff --git a/internal/service/ssh/receive_pack_test.go b/internal/service/ssh/receive_pack_test.go index 7e4ad6fb3..14f2bfdc2 100644 --- a/internal/service/ssh/receive_pack_test.go +++ b/internal/service/ssh/receive_pack_test.go @@ -244,6 +244,8 @@ func TestSSHReceivePackToHooks(t *testing.T) { testhelper.WriteTemporaryGitlabShellConfigFile(t, tempGitlabShellDir, testhelper.GitlabShellConfig{GitlabURL: ts.URL}) testhelper.WriteShellSecretFile(t, tempGitlabShellDir, secretToken) + testhelper.WriteCustomHook(cloneDetails.RemoteRepoPath, "pre-receive", []byte(testhelper.CheckNewObjectExists)) + defer func(override string) { hooks.Override = override }(hooks.Override) diff --git a/internal/testhelper/testhelper.go b/internal/testhelper/testhelper.go index 0ba640434..e03f39549 100644 --- a/internal/testhelper/testhelper.go +++ b/internal/testhelper/testhelper.go @@ -634,3 +634,15 @@ func WriteCustomHook(repoPath, name string, content []byte) (func(), error) { os.RemoveAll(fullpathDir) }, ioutil.WriteFile(fullPath, content, 0755) } + +// CheckNewObjectExists is a script meant to be used as a pre-receive custom hook. +// It only succeeds if it can find the object in the quarantine directory. +// if GIT_OBJECT_DIRECTORY and GIT_ALTERNATE_OBJECT_DIRECTORIES were not passed through correctly to the hooks, +// it will fail +const CheckNewObjectExists = `#!/usr/bin/env ruby +STDIN.each_line do |line| + new_object = line.split(' ')[1] + exit 1 unless new_object + exit 1 unless system(*%W[git cat-file -e #{new_object}]) +end +` diff --git a/internal/testhelper/testserver.go b/internal/testhelper/testserver.go index 38227789f..2d56935fd 100644 --- a/internal/testhelper/testserver.go +++ b/internal/testhelper/testserver.go @@ -2,6 +2,7 @@ package testhelper import ( "context" + "encoding/json" "errors" "fmt" "io/ioutil" @@ -293,6 +294,28 @@ func handleAllowed(t *testing.T, options GitlabTestServerOptions) func(w http.Re require.Regexp(t, changeLineRegex, line) } } + env := r.Form.Get("env") + require.NotEmpty(t, env) + + var gitVars struct { + GitAlternateObjectDirsRel []string `json:"GIT_ALTERNATE_OBJECT_DIRECTORIES_RELATIVE"` + GitObjectDirRel string `json:"GIT_OBJECT_DIRECTORY_RELATIVE"` + } + require.NoError(t, json.Unmarshal([]byte(env), &gitVars)) + + if options.GitObjectDir != "" { + relObjectDir, err := filepath.Rel(options.RepoPath, options.GitObjectDir) + require.NoError(t, err) + require.Equal(t, relObjectDir, gitVars.GitObjectDirRel) + } + if len(options.GitAlternateObjectDirs) > 0 { + require.Len(t, gitVars.GitAlternateObjectDirsRel, len(options.GitAlternateObjectDirs)) + for i, gitAlterateObjectDir := range options.GitAlternateObjectDirs { + relAltObjectDir, err := filepath.Rel(options.RepoPath, gitAlterateObjectDir) + require.NoError(t, err) + require.Equal(t, relAltObjectDir, gitVars.GitAlternateObjectDirsRel[i]) + } + } w.Header().Set("Content-Type", "application/json") if r.Form.Get("secret_token") == options.SecretToken { @@ -374,6 +397,9 @@ type GitlabTestServerOptions struct { PostReceiveCounterDecreased bool Protocol string GitPushOptions []string + GitObjectDir string + GitAlternateObjectDirs []string + RepoPath string } // NewGitlabTestServer returns a mock gitlab server that responds to the hook api endpoints @@ -427,7 +453,8 @@ func WriteTemporaryGitalyConfigFile(t *testing.T, tempDir string) (string, func( } type GlHookValues struct { - GLID, GLUsername, GLRepo, GLProtocol string + GLID, GLUsername, GLRepo, GLProtocol, GitObjectDir string + GitAlternateObjectDirs []string } // EnvForHooks generates a set of environment variables for gitaly hooks @@ -435,7 +462,7 @@ func EnvForHooks(t *testing.T, gitlabShellDir string, glHookValues GlHookValues, rubyDir, err := filepath.Abs("../../ruby") require.NoError(t, err) - return append(append([]string{ + env := append(append([]string{ fmt.Sprintf("GITALY_BIN_DIR=%s", config.Config.BinDir), fmt.Sprintf("GITALY_RUBY_DIR=%s", rubyDir), fmt.Sprintf("GL_ID=%s", glHookValues.GLID), @@ -447,6 +474,15 @@ func EnvForHooks(t *testing.T, gitlabShellDir string, glHookValues GlHookValues, "GITALY_LOG_LEVEL=info", "GITALY_LOG_FORMAT=json", }, os.Environ()...), hooks.GitPushOptions(gitPushOptions)...) + + if glHookValues.GitObjectDir != "" { + env = append(env, fmt.Sprintf("GIT_OBJECT_DIRECTORY=%s", glHookValues.GitObjectDir)) + } + if len(glHookValues.GitAlternateObjectDirs) > 0 { + env = append(env, fmt.Sprintf("GIT_ALTERNATE_OBJECT_DIRECTORIES=%s", strings.Join(glHookValues.GitAlternateObjectDirs, ":"))) + } + + return env } // WriteShellSecretFile writes a .gitlab_shell_secret file in the specified directory |