aboutsummaryrefslogtreecommitdiffstats
path: root/syz-ci/manager_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'syz-ci/manager_test.go')
-rw-r--r--syz-ci/manager_test.go137
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
+}