diff options
Diffstat (limited to 'workhorse/gitaly_test.go')
-rw-r--r-- | workhorse/gitaly_test.go | 175 |
1 files changed, 175 insertions, 0 deletions
diff --git a/workhorse/gitaly_test.go b/workhorse/gitaly_test.go index 95d6907ac6a..d0e694bf8e7 100644 --- a/workhorse/gitaly_test.go +++ b/workhorse/gitaly_test.go @@ -9,6 +9,7 @@ import ( "math/rand" "net" "net/http" + "net/url" "os" "os/exec" "path" @@ -169,6 +170,62 @@ func TestGetInfoRefsProxiedToGitalyInterruptedStream(t *testing.T) { waitDone(t, done) } +func TestGetInfoRefsRouting(t *testing.T) { + gitalyServer, socketPath := startGitalyServer(t, codes.OK) + defer gitalyServer.GracefulStop() + + apiResponse := gitOkBody(t) + apiResponse.GitalyServer.Address = "unix:" + socketPath + ts := testAuthServer(t, nil, url.Values{"service": {"git-receive-pack"}}, 200, apiResponse) + defer ts.Close() + + ws := startWorkhorseServer(ts.URL) + defer ws.Close() + + testCases := []struct { + method string + path string + status int + }{ + // valid requests + {"GET", "/toplevel.git/info/refs?service=git-receive-pack", 200}, + {"GET", "/toplevel.wiki.git/info/refs?service=git-receive-pack", 200}, + {"GET", "/toplevel/child/project.git/info/refs?service=git-receive-pack", 200}, + {"GET", "/toplevel/child/project.wiki.git/info/refs?service=git-receive-pack", 200}, + {"GET", "/toplevel/child/project/snippets/123.git/info/refs?service=git-receive-pack", 200}, + {"GET", "/snippets/123.git/info/refs?service=git-receive-pack", 200}, + // failing due to missing service parameter + {"GET", "/foo/bar.git/info/refs", 403}, + // failing due to invalid service parameter + {"GET", "/foo/bar.git/info/refs?service=git-zzz-pack", 403}, + // failing due to invalid repository path + {"GET", "/.git/info/refs?service=git-receive-pack", 204}, + // failing due to invalid request method + {"POST", "/toplevel.git/info/refs?service=git-receive-pack", 204}, + } + + for _, tc := range testCases { + t.Run(tc.path, func(t *testing.T) { + req, err := http.NewRequest(tc.method, ws.URL+tc.path, nil) + require.NoError(t, err) + + resp, err := http.DefaultClient.Do(req) + require.NoError(t, err) + defer resp.Body.Close() + + body := string(testhelper.ReadAll(t, resp.Body)) + + if tc.status == 200 { + require.Equal(t, 200, resp.StatusCode) + require.Contains(t, body, "\x00", "expect response generated by test gitaly server") + } else { + require.Equal(t, tc.status, resp.StatusCode) + require.Empty(t, body, "normal request has empty response body") + } + }) + } +} + func waitDone(t *testing.T, done chan struct{}) { t.Helper() select { @@ -259,6 +316,65 @@ func TestPostReceivePackProxiedToGitalyInterrupted(t *testing.T) { waitDone(t, done) } +func TestPostReceivePackRouting(t *testing.T) { + gitalyServer, socketPath := startGitalyServer(t, codes.OK) + defer gitalyServer.GracefulStop() + + apiResponse := gitOkBody(t) + apiResponse.GitalyServer.Address = "unix:" + socketPath + ts := testAuthServer(t, nil, nil, 200, apiResponse) + defer ts.Close() + + ws := startWorkhorseServer(ts.URL) + defer ws.Close() + + testCases := []struct { + method string + path string + contentType string + match bool + }{ + {"POST", "/toplevel.git/git-receive-pack", "application/x-git-receive-pack-request", true}, + {"POST", "/toplevel.wiki.git/git-receive-pack", "application/x-git-receive-pack-request", true}, + {"POST", "/toplevel/child/project.git/git-receive-pack", "application/x-git-receive-pack-request", true}, + {"POST", "/toplevel/child/project.wiki.git/git-receive-pack", "application/x-git-receive-pack-request", true}, + {"POST", "/toplevel/child/project/snippets/123.git/git-receive-pack", "application/x-git-receive-pack-request", true}, + {"POST", "/snippets/123.git/git-receive-pack", "application/x-git-receive-pack-request", true}, + {"POST", "/foo/bar/git-receive-pack", "application/x-git-receive-pack-request", false}, + {"POST", "/foo/bar.git/git-zzz-pack", "application/x-git-receive-pack-request", false}, + {"POST", "/.git/git-receive-pack", "application/x-git-receive-pack-request", false}, + {"POST", "/toplevel.git/git-receive-pack", "application/x-git-upload-pack-request", false}, + {"GET", "/toplevel.git/git-receive-pack", "application/x-git-receive-pack-request", false}, + } + + for _, tc := range testCases { + t.Run(tc.path, func(t *testing.T) { + req, err := http.NewRequest( + tc.method, + ws.URL+tc.path, + bytes.NewReader(testhelper.GitalyReceivePackResponseMock), + ) + require.NoError(t, err) + + req.Header.Set("Content-Type", tc.contentType) + + resp, err := http.DefaultClient.Do(req) + require.NoError(t, err) + defer resp.Body.Close() + + body := string(testhelper.ReadAll(t, resp.Body)) + + if tc.match { + require.Equal(t, 200, resp.StatusCode) + require.Contains(t, body, "\x00", "expect response generated by test gitaly server") + } else { + require.Equal(t, 204, resp.StatusCode) + require.Empty(t, body, "normal request has empty response body") + } + }) + } +} + // ReaderFunc is an adapter to turn a conforming function into an io.Reader. type ReaderFunc func(b []byte) (int, error) @@ -376,6 +492,65 @@ func TestPostUploadPackProxiedToGitalyInterrupted(t *testing.T) { waitDone(t, done) } +func TestPostUploadPackRouting(t *testing.T) { + gitalyServer, socketPath := startGitalyServer(t, codes.OK) + defer gitalyServer.GracefulStop() + + apiResponse := gitOkBody(t) + apiResponse.GitalyServer.Address = "unix:" + socketPath + ts := testAuthServer(t, nil, nil, 200, apiResponse) + defer ts.Close() + + ws := startWorkhorseServer(ts.URL) + defer ws.Close() + + testCases := []struct { + method string + path string + contentType string + match bool + }{ + {"POST", "/toplevel.git/git-upload-pack", "application/x-git-upload-pack-request", true}, + {"POST", "/toplevel.wiki.git/git-upload-pack", "application/x-git-upload-pack-request", true}, + {"POST", "/toplevel/child/project.git/git-upload-pack", "application/x-git-upload-pack-request", true}, + {"POST", "/toplevel/child/project.wiki.git/git-upload-pack", "application/x-git-upload-pack-request", true}, + {"POST", "/toplevel/child/project/snippets/123.git/git-upload-pack", "application/x-git-upload-pack-request", true}, + {"POST", "/snippets/123.git/git-upload-pack", "application/x-git-upload-pack-request", true}, + {"POST", "/foo/bar/git-upload-pack", "application/x-git-upload-pack-request", false}, + {"POST", "/foo/bar.git/git-zzz-pack", "application/x-git-upload-pack-request", false}, + {"POST", "/.git/git-upload-pack", "application/x-git-upload-pack-request", false}, + {"POST", "/toplevel.git/git-upload-pack", "application/x-git-receive-pack-request", false}, + {"GET", "/toplevel.git/git-upload-pack", "application/x-git-upload-pack-request", false}, + } + + for _, tc := range testCases { + t.Run(tc.path, func(t *testing.T) { + req, err := http.NewRequest( + tc.method, + ws.URL+tc.path, + bytes.NewReader(testhelper.GitalyReceivePackResponseMock), + ) + require.NoError(t, err) + + req.Header.Set("Content-Type", tc.contentType) + + resp, err := http.DefaultClient.Do(req) + require.NoError(t, err) + defer resp.Body.Close() + + body := string(testhelper.ReadAll(t, resp.Body)) + + if tc.match { + require.Equal(t, 200, resp.StatusCode) + require.Contains(t, body, "\x00", "expect response generated by test gitaly server") + } else { + require.Equal(t, 204, resp.StatusCode) + require.Empty(t, body, "normal request has empty response body") + } + }) + } +} + func TestGetDiffProxiedToGitalySuccessfully(t *testing.T) { gitalyServer, socketPath := startGitalyServer(t, codes.OK) defer gitalyServer.GracefulStop() |