|
| 1 | +package githttp |
| 2 | + |
| 3 | +import ( |
| 4 | + "bytes" |
| 5 | + "context" |
| 6 | + "io" |
| 7 | + "net/http" |
| 8 | + "strings" |
| 9 | + "testing" |
| 10 | + |
| 11 | + "github.com/stretchr/testify/require" |
| 12 | + |
| 13 | + "gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver" |
| 14 | + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/command/readwriter" |
| 15 | + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/config" |
| 16 | + "gitlab.com/gitlab-org/gitlab-shell/v14/internal/gitlabnet/accessverifier" |
| 17 | +) |
| 18 | + |
| 19 | +var ( |
| 20 | + flush = "0000" |
| 21 | + infoRefsWithoutPrefix = "00c4e56497bb5f03a90a51293fc6d516788730953899 refs/heads/'test'report-status " + |
| 22 | + "report-status-v2 delete-refs side-band-64k quiet atomic ofs-delta push-options object-format=sha1 " + |
| 23 | + "agent=git/2.38.3.gl200\n" + flush |
| 24 | +) |
| 25 | + |
| 26 | +func TestExecute(t *testing.T) { |
| 27 | + url, input := setup(t, http.StatusOK) |
| 28 | + output := &bytes.Buffer{} |
| 29 | + |
| 30 | + cmd := &PushCommand{ |
| 31 | + Config: &config.Config{GitlabUrl: url}, |
| 32 | + ReadWriter: &readwriter.ReadWriter{Out: output, In: input}, |
| 33 | + Response: &accessverifier.Response{ |
| 34 | + Payload: accessverifier.CustomPayload{ |
| 35 | + Data: accessverifier.CustomPayloadData{PrimaryRepo: url}, |
| 36 | + }, |
| 37 | + }, |
| 38 | + } |
| 39 | + |
| 40 | + require.NoError(t, cmd.Execute(context.Background())) |
| 41 | + require.Equal(t, infoRefsWithoutPrefix, output.String()) |
| 42 | +} |
| 43 | + |
| 44 | +func TestExecuteWithFailedInfoRefs(t *testing.T) { |
| 45 | + testCases := []struct { |
| 46 | + desc string |
| 47 | + statusCode int |
| 48 | + responseContent string |
| 49 | + expectedErr string |
| 50 | + }{ |
| 51 | + { |
| 52 | + desc: "request failed", |
| 53 | + statusCode: http.StatusForbidden, |
| 54 | + expectedErr: "Internal API error (403)", |
| 55 | + }, { |
| 56 | + desc: "unexpected response", |
| 57 | + statusCode: http.StatusOK, |
| 58 | + responseContent: "unexpected response", |
| 59 | + expectedErr: "Unexpected git-receive-pack response", |
| 60 | + }, |
| 61 | + } |
| 62 | + |
| 63 | + for _, tc := range testCases { |
| 64 | + t.Run(tc.desc, func(t *testing.T) { |
| 65 | + requests := []testserver.TestRequestHandler{ |
| 66 | + { |
| 67 | + Path: "/info/refs", |
| 68 | + Handler: func(w http.ResponseWriter, r *http.Request) { |
| 69 | + require.Equal(t, "git-receive-pack", r.URL.Query().Get("service")) |
| 70 | + |
| 71 | + w.WriteHeader(tc.statusCode) |
| 72 | + w.Write([]byte(tc.responseContent)) |
| 73 | + }, |
| 74 | + }, |
| 75 | + } |
| 76 | + |
| 77 | + url := testserver.StartHttpServer(t, requests) |
| 78 | + |
| 79 | + cmd := &PushCommand{ |
| 80 | + Config: &config.Config{GitlabUrl: url}, |
| 81 | + Response: &accessverifier.Response{ |
| 82 | + Payload: accessverifier.CustomPayload{ |
| 83 | + Data: accessverifier.CustomPayloadData{PrimaryRepo: url}, |
| 84 | + }, |
| 85 | + }, |
| 86 | + } |
| 87 | + |
| 88 | + err := cmd.Execute(context.Background()) |
| 89 | + require.Error(t, err) |
| 90 | + require.Equal(t, tc.expectedErr, err.Error()) |
| 91 | + }) |
| 92 | + } |
| 93 | +} |
| 94 | + |
| 95 | +func TestExecuteWithFailedReceivePack(t *testing.T) { |
| 96 | + url, input := setup(t, http.StatusForbidden) |
| 97 | + output := &bytes.Buffer{} |
| 98 | + |
| 99 | + cmd := &PushCommand{ |
| 100 | + Config: &config.Config{GitlabUrl: url}, |
| 101 | + ReadWriter: &readwriter.ReadWriter{Out: output, In: input}, |
| 102 | + Response: &accessverifier.Response{ |
| 103 | + Payload: accessverifier.CustomPayload{ |
| 104 | + Data: accessverifier.CustomPayloadData{PrimaryRepo: url}, |
| 105 | + }, |
| 106 | + }, |
| 107 | + } |
| 108 | + |
| 109 | + err := cmd.Execute(context.Background()) |
| 110 | + require.Error(t, err) |
| 111 | + require.Equal(t, "Internal API error (403)", err.Error()) |
| 112 | +} |
| 113 | + |
| 114 | +func setup(t *testing.T, receivePackStatusCode int) (string, io.Reader) { |
| 115 | + infoRefs := "001f# service=git-receive-pack\n" + flush + infoRefsWithoutPrefix |
| 116 | + receivePackPrefix := "00ab4c9d98d7750fa65db8ddcc60a89ef919f7a179f9 df505c066e4e63a801268a84627d7e8f7e033c7a " + |
| 117 | + "refs/heads/main123 report-status-v2 side-band-64k object-format=sha1 agent=git/2.39.1" |
| 118 | + receivePackData := "PACK some data" |
| 119 | + |
| 120 | + // Imitate sending data via multiple packets |
| 121 | + input := io.MultiReader( |
| 122 | + strings.NewReader(receivePackPrefix), |
| 123 | + strings.NewReader(flush), |
| 124 | + strings.NewReader(receivePackData), |
| 125 | + ) |
| 126 | + |
| 127 | + requests := []testserver.TestRequestHandler{ |
| 128 | + { |
| 129 | + Path: "/info/refs", |
| 130 | + Handler: func(w http.ResponseWriter, r *http.Request) { |
| 131 | + require.Equal(t, "git-receive-pack", r.URL.Query().Get("service")) |
| 132 | + |
| 133 | + w.Write([]byte(infoRefs)) |
| 134 | + }, |
| 135 | + }, |
| 136 | + { |
| 137 | + Path: "/git-receive-pack", |
| 138 | + Handler: func(w http.ResponseWriter, r *http.Request) { |
| 139 | + body, err := io.ReadAll(r.Body) |
| 140 | + require.NoError(t, err) |
| 141 | + defer r.Body.Close() |
| 142 | + |
| 143 | + require.Equal(t, receivePackPrefix+flush+receivePackData, string(body)) |
| 144 | + w.WriteHeader(receivePackStatusCode) |
| 145 | + }, |
| 146 | + }, |
| 147 | + } |
| 148 | + |
| 149 | + return testserver.StartHttpServer(t, requests), input |
| 150 | +} |
0 commit comments