Skip to content

Commit

Permalink
cmd/test2json: emit Benchmark name output early
Browse files Browse the repository at this point in the history
When benchmarks run, they print lines like:

  BenchmarkGenericNoMatch-8   3000000 385 ns/op

The first field, padded by spaces and followed by a tab,
is printed when the benchmark begins running.
The rest of the line is printed when the benchmark ends.
Tools and people can watch the timing of these prints
to see which benchmark is running.

To allow tools consuming json output to continue to be
able to see which benchmark is running, this CL adds a
special case to the usual "line at a time" behavior to flush
the benchmark name if it is observed separately from the
rest of the line.

Fixes golang#23352.

Change-Id: I7b6410698d78034eec18745d7f57b7d8e9575dbb
Reviewed-on: https://go-review.googlesource.com/86695
Run-TryBot: Russ Cox <[email protected]>
TryBot-Result: Gobot Gobot <[email protected]>
Reviewed-by: Ian Lance Taylor <[email protected]>
  • Loading branch information
rsc committed Jan 9, 2018
1 parent a99deed commit 9044f01
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 0 deletions.
25 changes: 25 additions & 0 deletions src/cmd/internal/test2json/test2json.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"strconv"
"strings"
"time"
"unicode"
"unicode/utf8"
)

Expand Down Expand Up @@ -349,6 +350,15 @@ func (l *lineBuffer) write(b []byte) {
for i < len(l.b) {
j := bytes.IndexByte(l.b[i:], '\n')
if j < 0 {
if !l.mid {
if j := bytes.IndexByte(l.b[i:], '\t'); j >= 0 {
if isBenchmarkName(bytes.TrimRight(l.b[i:i+j], " ")) {
l.part(l.b[i : i+j+1])
l.mid = true
i += j + 1
}
}
}
break
}
e := i + j + 1
Expand Down Expand Up @@ -390,6 +400,21 @@ func (l *lineBuffer) flush() {
}
}

var benchmark = []byte("Benchmark")

// isBenchmarkName reports whether b is a valid benchmark name
// that might appear as the first field in a benchmark result line.
func isBenchmarkName(b []byte) bool {
if !bytes.HasPrefix(b, benchmark) {
return false
}
if len(b) == len(benchmark) { // just "Benchmark"
return true
}
r, _ := utf8.DecodeRune(b[len(benchmark):])
return !unicode.IsLower(r)
}

// trimUTF8 returns a length t as close to len(b) as possible such that b[:t]
// does not end in the middle of a possibly-valid UTF-8 sequence.
//
Expand Down
7 changes: 7 additions & 0 deletions src/cmd/internal/test2json/testdata/benchshort.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{"Action":"output","Output":"# This file ends in an early EOF to trigger the Benchmark prefix test,\n"}
{"Action":"output","Output":"# which only happens when a benchmark prefix is seen ahead of the \\n.\n"}
{"Action":"output","Output":"# Normally that's due to the benchmark running and the \\n coming later,\n"}
{"Action":"output","Output":"# but to avoid questions of timing, we just use a file with no \\n at all.\n"}
{"Action":"output","Output":"BenchmarkFoo \t"}
{"Action":"output","Output":"10000 early EOF"}
{"Action":"fail"}
5 changes: 5 additions & 0 deletions src/cmd/internal/test2json/testdata/benchshort.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# This file ends in an early EOF to trigger the Benchmark prefix test,
# which only happens when a benchmark prefix is seen ahead of the \n.
# Normally that's due to the benchmark running and the \n coming later,
# but to avoid questions of timing, we just use a file with no \n at all.
BenchmarkFoo 10000 early EOF

0 comments on commit 9044f01

Please sign in to comment.