aboutsummaryrefslogtreecommitdiffstats
path: root/pkg
diff options
context:
space:
mode:
authorTaras Madan <tarasmadan@google.com>2024-03-20 15:36:37 +0100
committerTaras Madan <tarasmadan@google.com>2024-03-21 16:38:22 +0000
commit0a84219ec0829db2fb2d804eb0a9cbc0c5e6b4b1 (patch)
tree586e697f7e99058baf4bc7f3b25d5ae208a94817 /pkg
parentc2b3b7068cafe4a798f6cf1d9e65bf105b7e33fc (diff)
syz-ci, pkg/cover: stream coverage from manager to gcs
Diffstat (limited to 'pkg')
-rw-r--r--pkg/cover/html.go6
-rw-r--r--pkg/cover/manager_to_ci.go51
-rw-r--r--pkg/cover/manager_to_ci_test.go47
-rw-r--r--pkg/cover/report_test.go8
4 files changed, 104 insertions, 8 deletions
diff --git a/pkg/cover/html.go b/pkg/cover/html.go
index bba3dc07b..6e266ebce 100644
--- a/pkg/cover/html.go
+++ b/pkg/cover/html.go
@@ -211,8 +211,7 @@ func (rg *ReportGenerator) DoRawCoverFiles(w io.Writer, params CoverHandlerParam
return nil
}
-type coverageInfo struct {
- Version int `json:"version"`
+type CoverageInfo struct {
FilePath string `json:"file_path"`
FuncName string `json:"func_name"`
StartLine int `json:"sl"`
@@ -245,8 +244,7 @@ func (rg *ReportGenerator) DoCoverJSONL(w io.Writer, params CoverHandlerParams)
}
pcProgCount := FileByFrame(fm, &frame).lines[frame.StartLine].pcProgCount
hitCount := pcProgCount[frame.PC]
- covInfo := &coverageInfo{
- Version: 1,
+ covInfo := &CoverageInfo{
FilePath: frame.Name,
FuncName: frame.FuncName,
StartLine: frame.Range.StartLine,
diff --git a/pkg/cover/manager_to_ci.go b/pkg/cover/manager_to_ci.go
new file mode 100644
index 000000000..4b6f1d9ef
--- /dev/null
+++ b/pkg/cover/manager_to_ci.go
@@ -0,0 +1,51 @@
+// Copyright 2024 syzkaller project authors. All rights reserved.
+// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
+
+package cover
+
+import (
+ "encoding/json"
+ "fmt"
+ "io"
+)
+
+// CIDetails fields will be added to every CSV line.
+type CIDetails struct {
+ Version int `json:"version"`
+ Timestamp string `json:"timestamp"`
+ FuzzingMinutes int `json:"fuzzing_minutes"`
+ Arch string `json:"arch"`
+ BuildID string `json:"build_id"`
+ Manager string `json:"manager"`
+ KernelRepo string `json:"kernel_repo"`
+ KernelBranch string `json:"kernel_branch"`
+ KernelCommit string `json:"kernel_commit"`
+}
+
+type dbCoverageRecord struct {
+ CIDetails
+ CoverageInfo
+}
+
+func writeJSLine(w io.Writer, covInfo dbCoverageRecord) error {
+ bs, err := json.Marshal(covInfo)
+ if err != nil {
+ return fmt.Errorf("failed to marshal covInfo: %w", err)
+ }
+ bs = append(bs, '\n')
+ if _, err = w.Write(bs); err != nil {
+ return fmt.Errorf("failed to write js data: %w", err)
+ }
+ return nil
+}
+
+func WriteCIJSONLine(w io.Writer, managerCover CoverageInfo, ciDetails CIDetails) error {
+ dbLine := dbCoverageRecord{
+ CIDetails: ciDetails,
+ CoverageInfo: managerCover,
+ }
+ if err := writeJSLine(w, dbLine); err != nil {
+ return fmt.Errorf("failed to serialize func line: %w", err)
+ }
+ return nil
+}
diff --git a/pkg/cover/manager_to_ci_test.go b/pkg/cover/manager_to_ci_test.go
new file mode 100644
index 000000000..3bb26beca
--- /dev/null
+++ b/pkg/cover/manager_to_ci_test.go
@@ -0,0 +1,47 @@
+// Copyright 2024 syzkaller project authors. All rights reserved.
+// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
+
+package cover
+
+import (
+ "bytes"
+ "encoding/json"
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestWriteCIJSONLine(t *testing.T) {
+ expectedJSON :=
+ `{"version":1,` +
+ `"timestamp":"2014-04-14 00:00:00.000",` +
+ `"fuzzing_minutes":360,` +
+ `"arch":"x86",` +
+ `"build_id":"sample_buildid",` +
+ `"manager":"sample_manager",` +
+ `"kernel_repo":"sample_repo_path",` +
+ `"kernel_branch":"",` +
+ `"kernel_commit":"",` +
+ `"file_path":"main.c",` +
+ `"func_name":"main",` +
+ `"sl":1,"sc":0,"el":1,"ec":-1,` +
+ `"hit_count":1,` +
+ `"inline":false,` +
+ `"pc":12345}
+`
+
+ covInfo := CoverageInfo{}
+ assert.NoError(t, json.Unmarshal(sampleCoverJSON, &covInfo))
+
+ buf := new(bytes.Buffer)
+ assert.NoError(t, WriteCIJSONLine(buf, covInfo, CIDetails{
+ Version: 1,
+ Timestamp: "2014-04-14 00:00:00.000",
+ FuzzingMinutes: 360,
+ Arch: "x86",
+ BuildID: "sample_buildid",
+ Manager: "sample_manager",
+ KernelRepo: "sample_repo_path",
+ }))
+ assert.Equal(t, expectedJSON, buf.String())
+}
diff --git a/pkg/cover/report_test.go b/pkg/cover/report_test.go
index e9b224fa5..43769cf46 100644
--- a/pkg/cover/report_test.go
+++ b/pkg/cover/report_test.go
@@ -429,13 +429,13 @@ func checkCSVReport(t *testing.T, CSVReport []byte) {
}
}
+var sampleCoverJSON = []byte(`{"file_path":"main.c","func_name":"main",` +
+ `"sl":1,"sc":0,"el":1,"ec":-1,"hit_count":1,"inline":false,"pc":12345}`)
+
// nolint:lll
func checkJSONLReport(t *testing.T, r []byte) {
- expected := []byte(`{"version":1,"file_path":"main.c","func_name":"main",` +
- `"sl":1,"sc":0,"el":1,"ec":-1,"hit_count":1,"inline":false,"pc":12345}`)
-
compacted := new(bytes.Buffer)
- if err := json.Compact(compacted, expected); err != nil {
+ if err := json.Compact(compacted, sampleCoverJSON); err != nil {
t.Errorf("failed to prepare compacted json: %v", err)
}
compacted.Write([]byte("\n"))