mirror of
https://github.com/jstemmer/go-junit-report.git
synced 2025-04-06 13:38:07 -05:00
Adds multi-package benchmark support, simplifies merge benchmark averaging. Addressing code review comments.
This commit is contained in:
parent
260b47cabe
commit
1c2c0a00fe
@ -32,7 +32,7 @@ go-junit-report reads the `go test` verbose output from standard in and writes
|
|||||||
junit compatible XML to standard out.
|
junit compatible XML to standard out.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
go test -v 2>&1 | go-junit-report > report.xml
|
go test -v -count 5 2>&1 | go-junit-report > report.xml
|
||||||
```
|
```
|
||||||
|
|
||||||
Note that it also can parse benchmark output with `-bench` flag:
|
Note that it also can parse benchmark output with `-bench` flag:
|
||||||
@ -40,11 +40,6 @@ Note that it also can parse benchmark output with `-bench` flag:
|
|||||||
go test -v -bench . 2>&1 | ./go-junit-report > report.xml
|
go test -v -bench . 2>&1 | ./go-junit-report > report.xml
|
||||||
```
|
```
|
||||||
|
|
||||||
or using the optional -count parameter:
|
|
||||||
```bash
|
|
||||||
go test -v -bench . -count 5 2>&1 | ./go-junit-report > report.xml
|
|
||||||
```
|
|
||||||
|
|
||||||
[travis-badge]: https://travis-ci.org/jstemmer/go-junit-report.svg
|
[travis-badge]: https://travis-ci.org/jstemmer/go-junit-report.svg
|
||||||
[travis-link]: https://travis-ci.org/jstemmer/go-junit-report
|
[travis-link]: https://travis-ci.org/jstemmer/go-junit-report
|
||||||
[report-badge]: https://goreportcard.com/badge/github.com/jstemmer/go-junit-report
|
[report-badge]: https://goreportcard.com/badge/github.com/jstemmer/go-junit-report
|
||||||
|
@ -65,6 +65,7 @@ func JUnitReportXML(report *parser.Report, noXMLHeader bool, goVersion string, w
|
|||||||
|
|
||||||
// convert Report to JUnit test suites
|
// convert Report to JUnit test suites
|
||||||
for _, pkg := range report.Packages {
|
for _, pkg := range report.Packages {
|
||||||
|
pkg.Benchmarks = mergeBenchmarks(pkg.Benchmarks)
|
||||||
ts := JUnitTestSuite{
|
ts := JUnitTestSuite{
|
||||||
Tests: len(pkg.Tests) + len(pkg.Benchmarks),
|
Tests: len(pkg.Tests) + len(pkg.Benchmarks),
|
||||||
Failures: 0,
|
Failures: 0,
|
||||||
@ -115,7 +116,7 @@ func JUnitReportXML(report *parser.Report, noXMLHeader bool, goVersion string, w
|
|||||||
}
|
}
|
||||||
|
|
||||||
// individual benchmarks
|
// individual benchmarks
|
||||||
for _, benchmark := range mergeBenchmarks(pkg.Benchmarks) {
|
for _, benchmark := range pkg.Benchmarks {
|
||||||
benchmarkCase := JUnitTestCase{
|
benchmarkCase := JUnitTestCase{
|
||||||
Classname: classname,
|
Classname: classname,
|
||||||
Name: benchmark.Name,
|
Name: benchmark.Name,
|
||||||
@ -149,38 +150,25 @@ func JUnitReportXML(report *parser.Report, noXMLHeader bool, goVersion string, w
|
|||||||
}
|
}
|
||||||
|
|
||||||
func mergeBenchmarks(benchmarks []*parser.Benchmark) []*parser.Benchmark {
|
func mergeBenchmarks(benchmarks []*parser.Benchmark) []*parser.Benchmark {
|
||||||
// calculate the cumulative moving average CMA for each benchmark.
|
|
||||||
// CMA(n + 1) = val(n+1) + n*CMA/(n+1)
|
|
||||||
alloc := "Allocs"
|
|
||||||
bytes := "Bytes"
|
|
||||||
dur := "Duration"
|
|
||||||
n := 1
|
|
||||||
var merged []*parser.Benchmark
|
var merged []*parser.Benchmark
|
||||||
averages := make(map[string] /*bench name*/ map[string] /* type */ int)
|
benchmap := make(map[string][]*parser.Benchmark)
|
||||||
for _, b := range benchmarks {
|
for _, bm := range benchmarks {
|
||||||
if avg, found := averages[b.Name]; found {
|
if _, ok := benchmap[bm.Name]; !ok {
|
||||||
// calculate CMAs
|
merged = append(merged, &parser.Benchmark{Name: bm.Name})
|
||||||
averages[b.Name][alloc] = (b.Allocs + n*averages[b.Name][alloc]) / (n + 1)
|
|
||||||
averages[b.Name][bytes] = (b.Bytes + n*avg[bytes]) / (n + 1)
|
|
||||||
averages[b.Name][dur] = (int(b.Duration.Nanoseconds()) + n*avg[dur]) / (n + 1)
|
|
||||||
|
|
||||||
n++
|
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
n = 1 // reset duplicate counter
|
benchmap[bm.Name] = append(benchmap[bm.Name], bm)
|
||||||
merged = append(merged, &parser.Benchmark{Name: b.Name})
|
|
||||||
averages[b.Name] = make(map[string]int)
|
|
||||||
averages[b.Name][alloc] = b.Allocs
|
|
||||||
averages[b.Name][bytes] = b.Bytes
|
|
||||||
averages[b.Name][dur] = int(b.Duration.Nanoseconds())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// fill out benchmarks
|
for _, bm := range merged {
|
||||||
for i := range merged {
|
for _, b := range benchmap[bm.Name] {
|
||||||
avgVals := averages[merged[i].Name]
|
bm.Allocs += b.Allocs
|
||||||
merged[i].Allocs = avgVals[alloc]
|
bm.Bytes += b.Bytes
|
||||||
merged[i].Bytes = avgVals[bytes]
|
bm.Duration += b.Duration
|
||||||
merged[i].Duration = time.Duration(avgVals[dur])
|
}
|
||||||
|
n := len(benchmap[bm.Name])
|
||||||
|
bm.Allocs /= n
|
||||||
|
bm.Bytes /= n
|
||||||
|
bm.Duration /= time.Duration(n)
|
||||||
}
|
}
|
||||||
|
|
||||||
return merged
|
return merged
|
||||||
|
@ -1107,101 +1107,40 @@ var testCases = []TestCase{
|
|||||||
report: &parser.Report{
|
report: &parser.Report{
|
||||||
Packages: []parser.Package{
|
Packages: []parser.Package{
|
||||||
{
|
{
|
||||||
Name: "multiple/repeating",
|
Name: "mycode/common",
|
||||||
Duration: 14211 * time.Millisecond,
|
Duration: 7267 * time.Millisecond,
|
||||||
Time: 14211,
|
Time: 7267,
|
||||||
Tests: []*parser.Test{
|
|
||||||
{
|
|
||||||
Name: "TestRepeat",
|
|
||||||
Duration: 0,
|
|
||||||
Time: 0,
|
|
||||||
Result: parser.PASS,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "TestRepeat",
|
|
||||||
Duration: 0,
|
|
||||||
Time: 0,
|
|
||||||
Result: parser.PASS,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "TestRepeat",
|
|
||||||
Duration: 0,
|
|
||||||
Time: 0,
|
|
||||||
Result: parser.PASS,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "TestRepeat",
|
|
||||||
Duration: 0,
|
|
||||||
Time: 0,
|
|
||||||
Result: parser.PASS,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "TestRepeat",
|
|
||||||
Duration: 0,
|
|
||||||
Time: 0,
|
|
||||||
Result: parser.PASS,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Benchmarks: []*parser.Benchmark{
|
Benchmarks: []*parser.Benchmark{
|
||||||
{
|
{
|
||||||
Name: "BenchmarkNew",
|
Name: "BenchmarkParse",
|
||||||
Duration: 350 * time.Nanosecond,
|
Duration: 1591 * time.Nanosecond,
|
||||||
Bytes: 80,
|
|
||||||
Allocs: 3,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "BenchmarkNew",
|
Name: "BenchmarkNewTask",
|
||||||
Duration: 357 * time.Nanosecond,
|
Duration: 391 * time.Nanosecond,
|
||||||
Bytes: 80,
|
},
|
||||||
Allocs: 3,
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "BenchmarkNew",
|
Name: "mycode/benchmarks/channels",
|
||||||
Duration: 354 * time.Nanosecond,
|
Duration: 47084 * time.Millisecond,
|
||||||
Bytes: 80,
|
Time: 47084,
|
||||||
Allocs: 3,
|
Benchmarks: []*parser.Benchmark{
|
||||||
|
{
|
||||||
|
Name: "BenchmarkFanout/Channel/10",
|
||||||
|
Duration: 4673 * time.Nanosecond,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "BenchmarkNew",
|
Name: "BenchmarkFanout/Channel/100",
|
||||||
Duration: 358 * time.Nanosecond,
|
Duration: 24965 * time.Nanosecond,
|
||||||
Bytes: 80,
|
|
||||||
Allocs: 3,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "BenchmarkNew",
|
Name: "BenchmarkFanout/Channel/1000",
|
||||||
Duration: 345 * time.Nanosecond,
|
Duration: 195672 * time.Nanosecond,
|
||||||
Bytes: 80,
|
|
||||||
Allocs: 3,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "BenchmarkFew",
|
Name: "BenchmarkFanout/Channel/10000",
|
||||||
Duration: 100 * time.Nanosecond,
|
Duration: 2410200 * time.Nanosecond,
|
||||||
Bytes: 20,
|
|
||||||
Allocs: 1,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "BenchmarkFew",
|
|
||||||
Duration: 105 * time.Nanosecond,
|
|
||||||
Bytes: 20,
|
|
||||||
Allocs: 1,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "BenchmarkFew",
|
|
||||||
Duration: 102 * time.Nanosecond,
|
|
||||||
Bytes: 20,
|
|
||||||
Allocs: 1,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "BenchmarkFew",
|
|
||||||
Duration: 102 * time.Nanosecond,
|
|
||||||
Bytes: 20,
|
|
||||||
Allocs: 1,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "BenchmarkFew",
|
|
||||||
Duration: 102 * time.Nanosecond,
|
|
||||||
Bytes: 20,
|
|
||||||
Allocs: 1,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -177,6 +177,7 @@ func Parse(r io.Reader, pkgName string) (*Report, error) {
|
|||||||
|
|
||||||
buffers[cur] = buffers[cur][0:0]
|
buffers[cur] = buffers[cur][0:0]
|
||||||
tests = make([]*Test, 0)
|
tests = make([]*Test, 0)
|
||||||
|
benchmarks = make([]*Benchmark, 0)
|
||||||
coveragePct = ""
|
coveragePct = ""
|
||||||
cur = ""
|
cur = ""
|
||||||
testsTime = 0
|
testsTime = 0
|
||||||
|
2
testdata/25-report.xml
vendored
2
testdata/25-report.xml
vendored
@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<testsuites>
|
<testsuites>
|
||||||
<testsuite tests="10" failures="0" time="14.211" name="pkg/count">
|
<testsuite tests="2" failures="0" time="14.211" name="pkg/count">
|
||||||
<properties>
|
<properties>
|
||||||
<property name="go.version" value="1.0"></property>
|
<property name="go.version" value="1.0"></property>
|
||||||
</properties>
|
</properties>
|
||||||
|
20
testdata/26-report.xml
vendored
20
testdata/26-report.xml
vendored
@ -1,15 +1,19 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<testsuites>
|
<testsuites>
|
||||||
<testsuite tests="15" failures="0" time="14.211" name="multiple/repeating">
|
<testsuite tests="2" failures="0" time="7.267" name="mycode/common">
|
||||||
<properties>
|
<properties>
|
||||||
<property name="go.version" value="1.0"></property>
|
<property name="go.version" value="1.0"></property>
|
||||||
</properties>
|
</properties>
|
||||||
<testcase classname="repeating" name="TestRepeat" time="0.000"></testcase>
|
<testcase classname="common" name="BenchmarkParse" time="0.000001591"></testcase>
|
||||||
<testcase classname="repeating" name="TestRepeat" time="0.000"></testcase>
|
<testcase classname="common" name="BenchmarkNewTask" time="0.000000391"></testcase>
|
||||||
<testcase classname="repeating" name="TestRepeat" time="0.000"></testcase>
|
</testsuite>
|
||||||
<testcase classname="repeating" name="TestRepeat" time="0.000"></testcase>
|
<testsuite tests="4" failures="0" time="47.084" name="mycode/benchmarks/channels">
|
||||||
<testcase classname="repeating" name="TestRepeat" time="0.000"></testcase>
|
<properties>
|
||||||
<testcase classname="repeating" name="BenchmarkNew" time="0.000000352"></testcase>
|
<property name="go.version" value="1.0"></property>
|
||||||
<testcase classname="repeating" name="BenchmarkFew" time="0.000000102"></testcase>
|
</properties>
|
||||||
|
<testcase classname="channels" name="BenchmarkFanout/Channel/10" time="0.000004673"></testcase>
|
||||||
|
<testcase classname="channels" name="BenchmarkFanout/Channel/100" time="0.000024965"></testcase>
|
||||||
|
<testcase classname="channels" name="BenchmarkFanout/Channel/1000" time="0.000195672"></testcase>
|
||||||
|
<testcase classname="channels" name="BenchmarkFanout/Channel/10000" time="0.002410200"></testcase>
|
||||||
</testsuite>
|
</testsuite>
|
||||||
</testsuites>
|
</testsuites>
|
||||||
|
33
testdata/26-testbenchmultiple.txt
vendored
33
testdata/26-testbenchmultiple.txt
vendored
@ -1,23 +1,12 @@
|
|||||||
=== RUN TestRepeat
|
pkg: mycode/common
|
||||||
--- PASS: TestRepeat (0.00s)
|
BenchmarkParse-8 1000000 1591 ns/op
|
||||||
=== RUN TestRepeat
|
BenchmarkNewTask-8 3000000 391 ns/op
|
||||||
--- PASS: TestRepeat (0.00s)
|
|
||||||
=== RUN TestRepeat
|
|
||||||
--- PASS: TestRepeat (0.00s)
|
|
||||||
=== RUN TestRepeat
|
|
||||||
--- PASS: TestRepeat (0.00s)
|
|
||||||
=== RUN TestRepeat
|
|
||||||
--- PASS: TestRepeat (0.00s)
|
|
||||||
pkg: multiple/repeating
|
|
||||||
BenchmarkNew-8 5000000 350 ns/op 80 B/op 3 allocs/op
|
|
||||||
BenchmarkNew-8 5000000 357 ns/op 80 B/op 3 allocs/op
|
|
||||||
BenchmarkNew-8 5000000 354 ns/op 80 B/op 3 allocs/op
|
|
||||||
BenchmarkNew-8 5000000 358 ns/op 80 B/op 3 allocs/op
|
|
||||||
BenchmarkNew-8 5000000 345 ns/op 80 B/op 3 allocs/op
|
|
||||||
BenchmarkFew-8 5000000 100 ns/op 20 B/op 1 allocs/op
|
|
||||||
BenchmarkFew-8 5000000 105 ns/op 20 B/op 1 allocs/op
|
|
||||||
BenchmarkFew-8 5000000 102 ns/op 20 B/op 1 allocs/op
|
|
||||||
BenchmarkFew-8 5000000 102 ns/op 20 B/op 1 allocs/op
|
|
||||||
BenchmarkFew-8 5000000 102 ns/op 20 B/op 1 allocs/op
|
|
||||||
PASS
|
PASS
|
||||||
ok multiple/repeating 14.211s
|
ok mycode/common 7.267s
|
||||||
|
pkg: mycode/benchmarks/channels
|
||||||
|
BenchmarkFanout/Channel/10-8 500000 4673 ns/op
|
||||||
|
BenchmarkFanout/Channel/100-8 50000 24965 ns/op
|
||||||
|
BenchmarkFanout/Channel/1000-8 10000 195672 ns/op
|
||||||
|
BenchmarkFanout/Channel/10000-8 500 2410200 ns/op
|
||||||
|
PASS
|
||||||
|
ok mycode/benchmarks/channels 47.084s
|
Loading…
x
Reference in New Issue
Block a user