aboutsummaryrefslogtreecommitdiff
path: root/infra/base-images/base-runner/gocoverage/gocovsum/gocovsum.go
diff options
context:
space:
mode:
authorElliott Hughes <enh@google.com>2021-04-02 19:51:01 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2021-04-02 19:51:01 +0000
commit75c8dcf71ca8652f671b4ca5fea780a558c86e08 (patch)
tree328e6c9629b196cec1de3a94ee804d9fee3a0524 /infra/base-images/base-runner/gocoverage/gocovsum/gocovsum.go
parent378a8d19d33a5a62afbbe33b7f7b87b67db47236 (diff)
parent235e96b2f8ab4e43316158a2e6fa69e75a219e23 (diff)
downloadoss-fuzz-75c8dcf71ca8652f671b4ca5fea780a558c86e08.tar.gz
Original change: https://android-review.googlesource.com/c/platform/external/oss-fuzz/+/1662261 Change-Id: Ib7b7a79b38e1261c1d5fb4ccb1a5dfd106588996
Diffstat (limited to 'infra/base-images/base-runner/gocoverage/gocovsum/gocovsum.go')
-rw-r--r--infra/base-images/base-runner/gocoverage/gocovsum/gocovsum.go147
1 files changed, 147 insertions, 0 deletions
diff --git a/infra/base-images/base-runner/gocoverage/gocovsum/gocovsum.go b/infra/base-images/base-runner/gocoverage/gocovsum/gocovsum.go
new file mode 100644
index 000000000..973b7ae92
--- /dev/null
+++ b/infra/base-images/base-runner/gocoverage/gocovsum/gocovsum.go
@@ -0,0 +1,147 @@
+package main
+
+import (
+ "encoding/json"
+ "flag"
+ "fmt"
+ "log"
+
+ "go/ast"
+ "go/parser"
+ "go/token"
+
+ "golang.org/x/tools/cover"
+)
+
+type CoverageTotal struct {
+ Count int `json:"count"`
+ Covered int `json:"covered"`
+ Uncovered int `json:"notcovered"`
+ Percent float64 `json:"percent"`
+}
+
+type CoverageTotals struct {
+ Functions CoverageTotal `json:"functions,omitempty"`
+ Lines CoverageTotal `json:"lines,omitempty"`
+ Regions CoverageTotal `json:"regions,omitempty"`
+ Instantiations CoverageTotal `json:"instantiations,omitempty"`
+ Branches CoverageTotal `json:"branches,omitempty"`
+}
+
+type CoverageFile struct {
+ Summary CoverageTotals `json:"summary,omitempty"`
+ Filename string `json:"filename,omitempty"`
+}
+
+type CoverageData struct {
+ Totals CoverageTotals `json:"totals,omitempty"`
+ Files []CoverageFile `json:"files,omitempty"`
+}
+
+type PositionInterval struct {
+ start token.Position
+ end token.Position
+}
+
+type CoverageSummary struct {
+ Data []CoverageData `json:"data,omitempty"`
+ Type string `json:"type,omitempty"`
+ Version string `json:"version,omitempty"`
+}
+
+func isFunctionCovered(s token.Position, e token.Position, blocks []cover.ProfileBlock) bool {
+ for _, b := range blocks {
+ if b.StartLine >= s.Line && b.StartLine <= e.Line && b.EndLine >= s.Line && b.EndLine <= e.Line {
+ if b.Count > 0 {
+ return true
+ }
+ }
+ }
+ return false
+}
+
+func computePercent(s *CoverageTotals) {
+ s.Regions.Percent = float64(100*s.Regions.Covered) / float64(s.Regions.Count)
+ s.Lines.Percent = float64(100*s.Lines.Covered) / float64(s.Lines.Count)
+ s.Functions.Percent = float64(100*s.Functions.Covered) / float64(s.Functions.Count)
+}
+
+func main() {
+ flag.Parse()
+
+ if len(flag.Args()) != 1 {
+ log.Fatalf("needs exactly one argument")
+ }
+ profiles, err := cover.ParseProfiles(flag.Args()[0])
+ if err != nil {
+ log.Fatalf("failed to parse profiles: %v", err)
+ }
+ r := CoverageSummary{}
+ r.Type = "oss-fuzz.go.coverage.json.export"
+ r.Version = "2.0.1"
+ r.Data = make([]CoverageData, 1)
+ for _, p := range profiles {
+ fset := token.NewFileSet() // positions are relative to fset
+ f, err := parser.ParseFile(fset, p.FileName, nil, 0)
+ if err != nil {
+ panic(err)
+ }
+ fileCov := CoverageFile{}
+ fileCov.Filename = p.FileName
+ ast.Inspect(f, func(n ast.Node) bool {
+ switch x := n.(type) {
+ case *ast.FuncLit:
+ startf := fset.Position(x.Pos())
+ endf := fset.Position(x.End())
+ fileCov.Summary.Functions.Count++
+ if isFunctionCovered(startf, endf, p.Blocks) {
+ fileCov.Summary.Functions.Covered++
+ } else {
+ fileCov.Summary.Functions.Uncovered++
+ }
+ case *ast.FuncDecl:
+ startf := fset.Position(x.Pos())
+ endf := fset.Position(x.End())
+ fileCov.Summary.Functions.Count++
+ if isFunctionCovered(startf, endf, p.Blocks) {
+ fileCov.Summary.Functions.Covered++
+ } else {
+ fileCov.Summary.Functions.Uncovered++
+ }
+ }
+ return true
+ })
+
+ for _, b := range p.Blocks {
+ fileCov.Summary.Regions.Count++
+ if b.Count > 0 {
+ fileCov.Summary.Regions.Covered++
+ } else {
+ fileCov.Summary.Regions.Uncovered++
+ }
+
+ fileCov.Summary.Lines.Count += b.NumStmt
+ if b.Count > 0 {
+ fileCov.Summary.Lines.Covered += b.NumStmt
+ } else {
+ fileCov.Summary.Lines.Uncovered += b.NumStmt
+ }
+ }
+ r.Data[0].Totals.Regions.Count += fileCov.Summary.Regions.Count
+ r.Data[0].Totals.Regions.Covered += fileCov.Summary.Regions.Covered
+ r.Data[0].Totals.Regions.Uncovered += fileCov.Summary.Regions.Uncovered
+ r.Data[0].Totals.Lines.Count += fileCov.Summary.Lines.Count
+ r.Data[0].Totals.Lines.Covered += fileCov.Summary.Lines.Covered
+ r.Data[0].Totals.Lines.Uncovered += fileCov.Summary.Lines.Uncovered
+ r.Data[0].Totals.Functions.Count += fileCov.Summary.Functions.Count
+ r.Data[0].Totals.Functions.Covered += fileCov.Summary.Functions.Covered
+ r.Data[0].Totals.Functions.Uncovered += fileCov.Summary.Functions.Uncovered
+
+ computePercent(&fileCov.Summary)
+ r.Data[0].Files = append(r.Data[0].Files, fileCov)
+ }
+
+ computePercent(&r.Data[0].Totals)
+ o, _ := json.Marshal(r)
+ fmt.Printf(string(o))
+}