Skip to content

Commit

Permalink
add coverage Compact
Browse files Browse the repository at this point in the history
  • Loading branch information
xhd2015 committed May 11, 2024
1 parent 478508a commit bceecf1
Show file tree
Hide file tree
Showing 14 changed files with 206 additions and 99 deletions.
7 changes: 1 addition & 6 deletions cmd/trace/main.go
Original file line number Diff line number Diff line change
@@ -1,17 +1,12 @@
package main

import (
"fmt"
"os"

"github.com/xhd2015/xgo/cmd/xgo/trace"
)

func main() {
args := os.Args[1:]
err := trace.Main(args)
if err != nil {
fmt.Fprintf(os.Stderr, "%v\n", err)
os.Exit(1)
}
trace.Main(args)
}
48 changes: 0 additions & 48 deletions cmd/trace/stack_export.go

This file was deleted.

1 change: 1 addition & 0 deletions cmd/xgo/coverage/help.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ Usage:
The commands are:
merge merge coverage profiles
compact compact profile
help show help message
Options for merge:
Expand Down
38 changes: 29 additions & 9 deletions cmd/xgo/coverage/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ func Main(args []string) {
fmt.Print(strings.TrimPrefix(help, "\n"))
return
}
if cmd != "merge" && cmd != "compact" {
fmt.Fprintf(os.Stderr, "unrecognized cmd: %s\n", cmd)
return
}
args = args[1:]

var remainArgs []string
Expand Down Expand Up @@ -82,35 +86,51 @@ func Main(args []string) {
fmt.Fprintf(os.Stderr, "%v\n", err)
os.Exit(1)
}
case "compact":
if len(remainArgs) == 0 {
fmt.Fprintf(os.Stderr, "requires file\n")
os.Exit(1)
}
if len(remainArgs) != 1 {
fmt.Fprintf(os.Stderr, "compact requires exactly 1, found: %v\n", remainArgs)
os.Exit(1)
}
// compact is a special case of merge
err := mergeCover(remainArgs, outFile, excludePrefix)
if err != nil {
fmt.Fprintf(os.Stderr, "%v\n", err)
os.Exit(1)
}
default:
fmt.Fprintf(os.Stderr, "unrecognized cmd: %s\n", cmd)
os.Exit(1)
}
}

func mergeCover(files []string, outFile string, excludePrefix []string) error {
var mode string
// var mode string
covs := make([][]*coverage.CovLine, 0, len(files))
for _, file := range files {
content, err := os.ReadFile(file)
if err != nil {
return err
}
covMode, cov := coverage.Parse(string(content))
_, cov := coverage.Parse(string(content))
covs = append(covs, cov)
if mode == "" {
mode = covMode
}
// if mode == "" {
// mode = covMode
// }
}
res := coverage.Merge(covs...)
res = coverage.Filter(res, func(line *coverage.CovLine) bool {
return !hasAnyPrefix(line.Prefix, excludePrefix)
})

if mode == "" {
mode = "set"
}
mergedCov := coverage.Format(mode, res)
// if mode == "" {
// mode = "set"
// }
// always set mode to count
mergedCov := coverage.Format("count", res)

var out io.Writer = os.Stdout
if outFile != "" {
Expand Down
4 changes: 2 additions & 2 deletions cmd/xgo/runtime_gen/core/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import (
)

const VERSION = "1.0.31"
const REVISION = "771bf0c6ea6525f6c02faada38c18c5d4870fbd9+1"
const NUMBER = 211
const REVISION = "2de7323b90b0a735fedb48da16ff42b5ab455545+1"
const NUMBER = 212

// these fields will be filled by compiler
const XGO_VERSION = ""
Expand Down
34 changes: 22 additions & 12 deletions cmd/xgo/trace/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,22 +89,14 @@ func serveFile(file string) {
}

for {
// open url after 500ms, waiting for port openning to check if error

Check warning on line 92 in cmd/xgo/trace/main.go

View workflow job for this annotation

GitHub Actions / build

"openning" should be "opening".
portErr := make(chan struct{})
go func() {
select {
case <-time.After(500 * time.Millisecond):
case <-portErr:
return
}
go watchSignalWithinTimeout(500*time.Millisecond, portErr, func() {
url := fmt.Sprintf("http://localhost:%s", portStr)
fmt.Printf("Server listen at %s\n", url)

openCmd := "open"
if runtime.GOOS == "windows" {
openCmd = "explorer"
}
cmd.Run(openCmd, url)
}()
openURL(url)
})
err := http.ListenAndServe(fmt.Sprintf(":%s", portStr), server)
if err == nil {
break
Expand All @@ -120,6 +112,24 @@ func serveFile(file string) {
}
}

// executing action
func watchSignalWithinTimeout(timeout time.Duration, errSignal chan struct{}, action func()) {
select {
case <-time.After(timeout):
case <-errSignal:
return
}
action()
}

func openURL(url string) {
openCmd := "open"
if runtime.GOOS == "windows" {
openCmd = "explorer"
}
cmd.Run(openCmd, url)
}

//go:embed style.css
var styles string

Expand Down
2 changes: 1 addition & 1 deletion cmd/xgo/trace/stack_export.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions cmd/xgo/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ package main
import "fmt"

const VERSION = "1.0.31"
const REVISION = "771bf0c6ea6525f6c02faada38c18c5d4870fbd9+1"
const NUMBER = 211
const REVISION = "2de7323b90b0a735fedb48da16ff42b5ab455545+1"
const NUMBER = 212

func getRevision() string {
revSuffix := ""
Expand Down
4 changes: 2 additions & 2 deletions runtime/core/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import (
)

const VERSION = "1.0.31"
const REVISION = "771bf0c6ea6525f6c02faada38c18c5d4870fbd9+1"
const NUMBER = 211
const REVISION = "2de7323b90b0a735fedb48da16ff42b5ab455545+1"
const NUMBER = 212

// these fields will be filled by compiler
const XGO_VERSION = ""
Expand Down
2 changes: 1 addition & 1 deletion script/generate/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ func generate(rootDir string, subGens SubGens) error {
if subGens.Has(GenernateType_StackTraceDef) {
err := copyTraceExport(
filepath.Join(rootDir, "runtime", "trace", "stack_export.go"),
filepath.Join(rootDir, "cmd", "trace", "stack_export.go"),
filepath.Join(rootDir, "cmd", "xgo", "trace", "stack_export.go"),
)
if err != nil {
return err
Expand Down
39 changes: 23 additions & 16 deletions support/coverage/merge.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
package coverage

// Merge profiles
// the result will be compacted
func Merge(covs ...[]*CovLine) []*CovLine {
if len(covs) == 0 {
return nil
}
if len(covs) == 1 {
return covs[0]
return Compact(covs[0])
}
result := covs[0]
lineByPrefix := make(map[string]*CovLine, len(result))
result = compact(lineByPrefix, result)
for i := 1; i < len(covs); i++ {
result = doMerge(result, covs[i])
result = doMerge(lineByPrefix, result, covs[i])
}
return result
}
Expand All @@ -26,21 +30,24 @@ func Filter(covs []*CovLine, check func(line *CovLine) bool) []*CovLine {
return covs[:j]
}

func doMerge(linesA []*CovLine, linesB []*CovLine) []*CovLine {
for _, line := range linesB {
idx := -1
for i := 0; i < len(linesA); i++ {
if linesA[i].Prefix == line.Prefix {
idx = i
break
}
func doMerge(lineByPrefix map[string]*CovLine, dst []*CovLine, src []*CovLine) []*CovLine {
for _, line := range src {
prevLine, ok := lineByPrefix[line.Prefix]
if ok {
prevLine.Count += line.Count
continue
}
if idx < 0 {
linesA = append(linesA, line)
} else {
// fmt.Printf("add %s %d %d\n", a[idx].prefix, a[idx].count, line.count)
linesA[idx].Count += line.Count
lineByPrefix[line.Prefix] = line
dst = append(dst, line)
}
return dst
}

func findByPrefix(linesA []*CovLine, prefix string) int {
for i := 0; i < len(linesA); i++ {
if linesA[i].Prefix == prefix {
return i
}
}
return linesA
return -1
}
67 changes: 67 additions & 0 deletions support/coverage/merge_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package coverage

import (
"testing"
)

func mergeAndFormat(list ...string) string {
var covList [][]*CovLine
for _, content := range list {
_, lines := Parse(content)
covList = append(covList, lines)
}
lines := Merge(covList...)
return Format("set", lines)
}

func TestMerge(t *testing.T) {
tests := []struct {
name string
covs []string
want string
}{
{
name: "empty",
want: "mode: set",
},
{
name: "single",
covs: []string{`mode: set
github.com/xhd2015/xgo/runtime/core/func.go:44.41,45.22 1 0`},
want: `mode: set
github.com/xhd2015/xgo/runtime/core/func.go:44.41,45.22 1 0`,
},
{
name: "single_compact",
covs: []string{`mode: set
github.com/xhd2015/xgo/runtime/core/func.go:44.41,45.22 1 1
github.com/xhd2015/xgo/runtime/core/func1.go:44.41,45.22 1 0
github.com/xhd2015/xgo/runtime/core/func.go:44.41,45.22 1 4`},
want: `mode: set
github.com/xhd2015/xgo/runtime/core/func.go:44.41,45.22 1 5
github.com/xhd2015/xgo/runtime/core/func1.go:44.41,45.22 1 0`,
},
{
name: "multiple_compact",
covs: []string{`mode: set
github.com/xhd2015/xgo/runtime/core/func.go:44.41,45.22 1 1
github.com/xhd2015/xgo/runtime/core/func1.go:44.41,45.22 1 0
github.com/xhd2015/xgo/runtime/core/func.go:44.41,45.22 1 4`,
`mode: set
github.com/xhd2015/xgo/runtime/core/func.go:44.41,45.22 1 0
github.com/xhd2015/xgo/runtime/core/func1.go:44.41,45.22 1 1
github.com/xhd2015/xgo/runtime/core/func.go:44.41,45.22 1 8`},
want: `mode: set
github.com/xhd2015/xgo/runtime/core/func.go:44.41,45.22 1 13
github.com/xhd2015/xgo/runtime/core/func1.go:44.41,45.22 1 1`,
},
}
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
if got := mergeAndFormat(tt.covs...); got != tt.want {
t.Errorf("Merge() = %v, want %v", got, tt.want)
}
})
}
}
Loading

0 comments on commit bceecf1

Please sign in to comment.