Skip to content

Commit a6dc233

Browse files
committed
Add more gitter test cases. Rename endpoints
1 parent fb1dfc7 commit a6dc233

2 files changed

Lines changed: 162 additions & 14 deletions

File tree

go/cmd/gitter/gitter.go

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,9 @@ import (
3030

3131
// API Endpoints
3232
var endpointHandlers = map[string]http.HandlerFunc{
33-
"GET /repo": gitHandler,
33+
"GET /git": gitHandler,
3434
"POST /cache": cacheHandler,
35-
"POST /affected-commits": affectCommitsHandler,
35+
"POST /affected-commits": affectedCommitsHandler,
3636
}
3737

3838
const defaultGitterWorkDir = "/work/gitter"
@@ -72,15 +72,15 @@ func runCmd(ctx context.Context, dir string, env []string, name string, args ...
7272
// Ensure it eventually dies if it ignores SIGINT
7373
cmd.WaitDelay = shutdownTimeout / 2
7474

75-
out, err := cmd.Output()
75+
out, err := cmd.CombinedOutput()
7676
if err != nil {
7777
if ctx.Err() != nil {
7878
// Log separately if cancelled
7979
logger.Warn("Command cancelled", slog.String("cmd", name), slog.Any("err", ctx.Err()))
8080
return nil, fmt.Errorf("command %s cancelled: %w", name, ctx.Err())
8181
}
8282

83-
return nil, fmt.Errorf("command %s failed, stdout: %s, stderr: %s", name, out, err)
83+
return nil, fmt.Errorf("command %s failed: %w, output: %s", name, err, out)
8484
}
8585

8686
return out, nil
@@ -388,12 +388,15 @@ func cacheHandler(w http.ResponseWriter, r *http.Request) {
388388
logger.Info("Received request: /cache", slog.String("url", url))
389389

390390
// Fetch repo if it's not fresh
391-
_, err, _ = gFetch.Do(url, func() (any, error) {
391+
if _, err, _ := gFetch.Do(url, func() (any, error) {
392392
return nil, fetchRepo(r.Context(), url)
393-
})
394-
if err != nil {
395-
logger.Error("Failed to update repo", slog.String("url", url), slog.Any("error", err))
396-
http.Error(w, fmt.Sprintf("Failed to update repo: %v", err), http.StatusInternalServerError)
393+
}); err != nil {
394+
logger.Error("Error fetching blob", slog.String("url", url), slog.Any("error", err))
395+
if isAuthError(err) {
396+
http.Error(w, fmt.Sprintf("Error fetching blob: %v", err), http.StatusForbidden)
397+
return
398+
}
399+
http.Error(w, fmt.Sprintf("Error fetching blob: %v", err), http.StatusInternalServerError)
397400
return
398401
}
399402

@@ -413,7 +416,7 @@ func cacheHandler(w http.ResponseWriter, r *http.Request) {
413416
logger.Info("Request completed successfully: /cache", slog.String("url", url), slog.Duration("duration", time.Since(start)))
414417
}
415418

416-
func affectCommitsHandler(w http.ResponseWriter, r *http.Request) {
419+
func affectedCommitsHandler(w http.ResponseWriter, r *http.Request) {
417420
start := time.Now()
418421
// POST requets body processing
419422
var body struct {
@@ -468,8 +471,12 @@ func affectCommitsHandler(w http.ResponseWriter, r *http.Request) {
468471
if _, err, _ := gFetch.Do(url, func() (any, error) {
469472
return nil, fetchRepo(r.Context(), url)
470473
}); err != nil {
471-
logger.Error("Failed to update repo", slog.String("url", url), slog.Any("error", err))
472-
http.Error(w, fmt.Sprintf("Failed to update repo: %v", err), http.StatusInternalServerError)
474+
logger.Error("Error fetching blob", slog.String("url", url), slog.Any("error", err))
475+
if isAuthError(err) {
476+
http.Error(w, fmt.Sprintf("Error fetching blob: %v", err), http.StatusForbidden)
477+
return
478+
}
479+
http.Error(w, fmt.Sprintf("Error fetching blob: %v", err), http.StatusInternalServerError)
473480
return
474481
}
475482

go/cmd/gitter/gitter_test.go

Lines changed: 143 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package main
22

33
import (
4+
"bytes"
5+
"encoding/json"
46
"errors"
57
"net/http"
68
"net/http/httptest"
@@ -62,7 +64,7 @@ func TestGitHandler_InvalidURL(t *testing.T) {
6264
}
6365

6466
for _, tt := range tests {
65-
req, err := http.NewRequest(http.MethodGet, "/getgit?url="+tt.url, nil)
67+
req, err := http.NewRequest(http.MethodGet, "/git?url="+tt.url, nil)
6668
if err != nil {
6769
t.Fatal(err)
6870
}
@@ -114,7 +116,7 @@ func TestGitHandler_Integration(t *testing.T) {
114116

115117
for _, tt := range tests {
116118
t.Run(tt.name, func(t *testing.T) {
117-
req, err := http.NewRequest(http.MethodGet, "/getgit?url="+tt.url, nil)
119+
req, err := http.NewRequest(http.MethodGet, "/git?url="+tt.url, nil)
118120
if err != nil {
119121
t.Fatal(err)
120122
}
@@ -128,3 +130,142 @@ func TestGitHandler_Integration(t *testing.T) {
128130
})
129131
}
130132
}
133+
134+
func TestCacheHandler(t *testing.T) {
135+
if testing.Short() {
136+
t.Skip("skipping integration test in short mode")
137+
}
138+
139+
// Setup valid workdir
140+
tmpDir := t.TempDir()
141+
142+
// Override global variables for test
143+
// Note: In a real app we might want to dependency inject these,
144+
// but for this simple script we modify package globals.
145+
gitStorePath = tmpDir
146+
fetchTimeout = time.Minute
147+
// Ensure lastFetch map is initialized
148+
if lastFetch == nil {
149+
loadLastFetchMap()
150+
}
151+
152+
tests := []struct {
153+
name string
154+
url string
155+
expectedCode int
156+
}{
157+
{
158+
name: "Valid public repo",
159+
url: "https://github.com/google/oss-fuzz-vulns.git", // Small repo
160+
expectedCode: http.StatusOK,
161+
},
162+
{
163+
name: "Non-existent repo",
164+
url: "https://github.com/google/this-repo-does-not-exist-12345.git",
165+
expectedCode: http.StatusForbidden,
166+
},
167+
}
168+
169+
for _, tt := range tests {
170+
t.Run(tt.name, func(t *testing.T) {
171+
body, _ := json.Marshal(map[string]string{"url": tt.url})
172+
req, err := http.NewRequest(http.MethodPost, "/cache", bytes.NewBuffer(body))
173+
if err != nil {
174+
t.Fatal(err)
175+
}
176+
rr := httptest.NewRecorder()
177+
cacheHandler(rr, req)
178+
179+
if status := rr.Code; status != tt.expectedCode {
180+
t.Errorf("handler returned wrong status code: got %v want %v",
181+
status, tt.expectedCode)
182+
}
183+
})
184+
}
185+
}
186+
187+
func TestAffectedCommitsHandler(t *testing.T) {
188+
if testing.Short() {
189+
t.Skip("skipping integration test in short mode")
190+
}
191+
192+
// Setup valid workdir
193+
tmpDir := t.TempDir()
194+
195+
// Override global variables for test
196+
// Note: In a real app we might want to dependency inject these,
197+
// but for this simple script we modify package globals.
198+
gitStorePath = tmpDir
199+
fetchTimeout = time.Minute
200+
// Ensure lastFetch map is initialized
201+
if lastFetch == nil {
202+
loadLastFetchMap()
203+
}
204+
205+
tests := []struct {
206+
name string
207+
url string
208+
introduced []string
209+
fixed []string
210+
lastAffected []string
211+
limit []string
212+
expectedCode int
213+
}{
214+
{
215+
name: "Valid range in public repo",
216+
url: "https://github.com/google/oss-fuzz-vulns.git",
217+
introduced: []string{"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"},
218+
fixed: []string{"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"},
219+
expectedCode: http.StatusOK,
220+
},
221+
{
222+
name: "Invalid mixed limit and fixed",
223+
url: "https://github.com/google/oss-fuzz-vulns.git",
224+
fixed: []string{"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"},
225+
limit: []string{"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"},
226+
expectedCode: http.StatusBadRequest,
227+
},
228+
{
229+
name: "Non-existent repo",
230+
url: "https://github.com/google/this-repo-does-not-exist-12345.git",
231+
introduced: []string{"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"},
232+
expectedCode: http.StatusForbidden,
233+
},
234+
}
235+
236+
for _, tt := range tests {
237+
t.Run(tt.name, func(t *testing.T) {
238+
var events []Event
239+
for _, h := range tt.introduced {
240+
events = append(events, Event{EventType: "introduced", Hash: h})
241+
}
242+
for _, h := range tt.fixed {
243+
events = append(events, Event{EventType: "fixed", Hash: h})
244+
}
245+
for _, h := range tt.lastAffected {
246+
events = append(events, Event{EventType: "last_affected", Hash: h})
247+
}
248+
for _, h := range tt.limit {
249+
events = append(events, Event{EventType: "limit", Hash: h})
250+
}
251+
252+
reqBody := map[string]interface{}{
253+
"url": tt.url,
254+
"events": events,
255+
}
256+
257+
body, _ := json.Marshal(reqBody)
258+
req, err := http.NewRequest(http.MethodPost, "/affected-commits", bytes.NewBuffer(body))
259+
if err != nil {
260+
t.Fatal(err)
261+
}
262+
rr := httptest.NewRecorder()
263+
affectedCommitsHandler(rr, req)
264+
265+
if status := rr.Code; status != tt.expectedCode {
266+
t.Errorf("handler returned wrong status code: got %v want %v",
267+
status, tt.expectedCode)
268+
}
269+
})
270+
}
271+
}

0 commit comments

Comments
 (0)