diff options
Diffstat (limited to 'syz-ci/manager_test.go')
| -rw-r--r-- | syz-ci/manager_test.go | 137 |
1 files changed, 137 insertions, 0 deletions
diff --git a/syz-ci/manager_test.go b/syz-ci/manager_test.go index d8366102b..42282711d 100644 --- a/syz-ci/manager_test.go +++ b/syz-ci/manager_test.go @@ -4,10 +4,21 @@ package main import ( + "bytes" + "compress/gzip" + "encoding/json" "fmt" + "io" + "net/http" + "net/http/httptest" + "strings" "testing" + "time" "github.com/google/syzkaller/dashboard/dashapi" + "github.com/google/syzkaller/pkg/cover" + gcsmocks "github.com/google/syzkaller/pkg/gcs/mocks" + "github.com/google/syzkaller/pkg/mgrconfig" "github.com/google/syzkaller/pkg/vcs" "github.com/google/syzkaller/sys/targets" "github.com/stretchr/testify/assert" @@ -106,3 +117,129 @@ Reported-by: foo+abcd000@bar.com`, assert.Equal(t, commit.Title, "title with fix") assert.ElementsMatch(t, commit.BugIDs, []string{"abcd000"}) } + +func TestUploadCoverJSONLToGCS(t *testing.T) { + tests := []struct { + name string + + inputJSONL string + inputTime time.Time + + inputCompress bool + inputPublish bool + + wantGCSFileName string + wantGCSFileContent string + wantCompressed bool + wantPublish bool + wantError string + }{ + { + name: "upload single object", + inputJSONL: "{}", + inputTime: time.Time{}, + wantGCSFileName: "test-bucket/test-namespace/mgr-name-0001-01-01-0-0.jsonl", + wantGCSFileContent: "{}\n", + }, + { + name: "upload single object, compress", + inputJSONL: "{}", + inputTime: time.Time{}, + inputCompress: true, + wantGCSFileName: "test-bucket/test-namespace/mgr-name-0001-01-01-0-0.jsonl", + wantGCSFileContent: "{}\n", + wantCompressed: true, + }, + { + name: "upload single object, publish", + inputJSONL: "{}", + inputTime: time.Time{}, + inputPublish: true, + wantGCSFileName: "test-bucket/test-namespace/mgr-name-0001-01-01-0-0.jsonl", + wantGCSFileContent: "{}\n", + wantPublish: true, + }, + { + name: "upload single object, error", + inputJSONL: "{", + inputTime: time.Time{}, + wantGCSFileName: "test-bucket/test-namespace/mgr-name-0001-01-01-0-0.jsonl", + wantError: "callback: cover.ProgramCoverage: unexpected EOF", + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + httpServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { + w.Write([]byte(test.inputJSONL)) + })) + defer httpServer.Close() + + testSetverAddrPort, _ := strings.CutPrefix(httpServer.URL, "http://") + mgr := Manager{ + name: "mgr-name", + managercfg: &mgrconfig.Config{ + HTTP: testSetverAddrPort, + Cover: true, + }, + mgrcfg: &ManagerConfig{ + DashboardClient: "test-namespace", + }, + } + + gcsMock := gcsmocks.NewClient(t) + gotBytes := mockWriteCloser{} + + gcsMock.On("FileWriter", test.wantGCSFileName, "", ""). + Return(&gotBytes, nil).Once() + gcsMock.On("Close").Return(nil).Once() + if test.wantPublish { + gcsMock.On("Publish", test.wantGCSFileName). + Return(nil).Once() + } + err := mgr.uploadCoverJSONLToGCS(gcsMock, + "/teststream&jsonl=1", + "gs://test-bucket", + time.Time{}, test.inputPublish, test.inputCompress, func(w io.Writer, dec *json.Decoder) error { + var v any + if err := dec.Decode(&v); err != nil { + return fmt.Errorf("cover.ProgramCoverage: %w", err) + } + if err := cover.WriteJSLine(w, &v); err != nil { + return fmt.Errorf("cover.WriteJSLine: %w", err) + } + return nil + }) + if test.wantError != "" { + assert.Equal(t, test.wantError, err.Error()) + } else { + assert.NoError(t, err) + } + assert.Equal(t, 1, gotBytes.closedTimes) + if test.wantCompressed { + gzReader, err := gzip.NewReader(&gotBytes.buf) + assert.NoError(t, err) + defer gzReader.Close() + plainBytes := mockWriteCloser{} + _, err = io.Copy(&plainBytes, gzReader) + assert.NoError(t, err) + gotBytes = plainBytes + } + assert.Equal(t, test.wantGCSFileContent, gotBytes.buf.String()) + }) + } +} + +type mockWriteCloser struct { + buf bytes.Buffer + closedTimes int +} + +func (m *mockWriteCloser) Write(p []byte) (n int, err error) { + return m.buf.Write(p) +} + +func (m *mockWriteCloser) Close() error { + m.closedTimes++ + return nil +} |
