aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobbert van Ginkel <robbert@uber.com>2021-05-07 16:38:23 -0700
committerGitHub <noreply@github.com>2021-05-08 07:38:23 +0800
commit71042b949a84ae275660f45b8da9499a5877bb9c (patch)
tree6e2ae2f2df65224761043c6762fdab2323e77338
parent707c634bf8f7ca5b57c2a923bec16fa62ced1fc7 (diff)
downloadbazelbuild-rules_go-71042b949a84ae275660f45b8da9499a5877bb9c.tar.gz
Update test2json.go (#2873)
There have been some updates to test2json.go since d47526ed777958aa4a2542382e931eb7b3c4c6a9, most notably a fix for https://github.com/golang/go/issues/40132 that was important enough to recevie a backport. Update rules_go's copy of test2json.go to the latest.
-rw-r--r--go/tools/bzltestutil/test2json.go67
1 files changed, 46 insertions, 21 deletions
diff --git a/go/tools/bzltestutil/test2json.go b/go/tools/bzltestutil/test2json.go
index 92375d57..331773d0 100644
--- a/go/tools/bzltestutil/test2json.go
+++ b/go/tools/bzltestutil/test2json.go
@@ -9,7 +9,7 @@
//
// The file test2json.go was copied from upstream go at
// src/cmd/internal/test2json/test2json.go, revision
-// d47526ed777958aa4a2542382e931eb7b3c4c6a9. At the time of writing this was
+// 1b86bdbdc3991c13c6ed156100a5f4918fdd9c6b. At the time of writing this was
// deemed the best way of depending on this code that is otherwise not exposed
// outside of the go toolchain. These files should be kept in sync.
@@ -52,10 +52,10 @@ type textBytes []byte
func (b textBytes) MarshalText() ([]byte, error) { return b, nil }
-// A converter holds the state of a test-to-JSON conversion.
+// A Converter holds the state of a test-to-JSON conversion.
// It implements io.WriteCloser; the caller writes test output in,
// and the converter writes JSON output to w.
-type converter struct {
+type Converter struct {
w io.Writer // JSON output stream
pkg string // package to name in events
mode Mode // mode bits
@@ -107,9 +107,9 @@ var (
//
// The pkg string, if present, specifies the import path to
// report in the JSON stream.
-func NewConverter(w io.Writer, pkg string, mode Mode) io.WriteCloser {
- c := new(converter)
- *c = converter{
+func NewConverter(w io.Writer, pkg string, mode Mode) *Converter {
+ c := new(Converter)
+ *c = Converter{
w: w,
pkg: pkg,
mode: mode,
@@ -129,15 +129,31 @@ func NewConverter(w io.Writer, pkg string, mode Mode) io.WriteCloser {
}
// Write writes the test input to the converter.
-func (c *converter) Write(b []byte) (int, error) {
+func (c *Converter) Write(b []byte) (int, error) {
c.input.write(b)
return len(b), nil
}
+// Exited marks the test process as having exited with the given error.
+func (c *Converter) Exited(err error) {
+ if err == nil {
+ c.result = "pass"
+ } else {
+ c.result = "fail"
+ }
+}
+
var (
+ // printed by test on successful run.
bigPass = []byte("PASS\n")
+
+ // printed by test after a normal test failure.
bigFail = []byte("FAIL\n")
+ // printed by 'go test' along with an error if the test binary terminates
+ // with an error.
+ bigFailErrorPrefix = []byte("FAIL\t")
+
updates = [][]byte{
[]byte("=== RUN "),
[]byte("=== PAUSE "),
@@ -160,9 +176,9 @@ var (
// handleInputLine handles a single whole test output line.
// It must write the line to c.output but may choose to do so
// before or after emitting other events.
-func (c *converter) handleInputLine(line []byte) {
+func (c *Converter) handleInputLine(line []byte) {
// Final PASS or FAIL.
- if bytes.Equal(line, bigPass) || bytes.Equal(line, bigFail) {
+ if bytes.Equal(line, bigPass) || bytes.Equal(line, bigFail) || bytes.HasPrefix(line, bigFailErrorPrefix) {
c.flushReport(0)
c.output.write(line)
if bytes.Equal(line, bigPass) {
@@ -211,8 +227,18 @@ func (c *converter) handleInputLine(line []byte) {
}
}
+ // Not a special test output line.
if !ok {
- // Not a special test output line.
+ // Lookup the name of the test which produced the output using the
+ // indentation of the output as an index into the stack of the current
+ // subtests.
+ // If the indentation is greater than the number of current subtests
+ // then the output must have included extra indentation. We can't
+ // determine which subtest produced this output, so we default to the
+ // old behaviour of assuming the most recently run subtest produced it.
+ if indent > 0 && indent <= len(c.report) {
+ c.testName = c.report[indent-1].Test
+ }
c.output.write(origLine)
return
}
@@ -276,7 +302,7 @@ func (c *converter) handleInputLine(line []byte) {
}
// flushReport flushes all pending PASS/FAIL reports at levels >= depth.
-func (c *converter) flushReport(depth int) {
+func (c *Converter) flushReport(depth int) {
c.testName = ""
for len(c.report) > depth {
e := c.report[len(c.report)-1]
@@ -288,23 +314,22 @@ func (c *converter) flushReport(depth int) {
// Close marks the end of the go test output.
// It flushes any pending input and then output (only partial lines at this point)
// and then emits the final overall package-level pass/fail event.
-func (c *converter) Close() error {
+func (c *Converter) Close() error {
c.input.flush()
c.output.flush()
- e := &event{Action: "pass"}
if c.result != "" {
- e.Action = c.result
- }
- if c.mode&Timestamp != 0 {
- dt := time.Since(c.start).Round(1 * time.Millisecond).Seconds()
- e.Elapsed = &dt
+ e := &event{Action: c.result}
+ if c.mode&Timestamp != 0 {
+ dt := time.Since(c.start).Round(1 * time.Millisecond).Seconds()
+ e.Elapsed = &dt
+ }
+ c.writeEvent(e)
}
- c.writeEvent(e)
return nil
}
// writeOutputEvent writes a single output event with the given bytes.
-func (c *converter) writeOutputEvent(out []byte) {
+func (c *Converter) writeOutputEvent(out []byte) {
c.writeEvent(&event{
Action: "output",
Output: (*textBytes)(&out),
@@ -313,7 +338,7 @@ func (c *converter) writeOutputEvent(out []byte) {
// writeEvent writes a single event.
// It adds the package, time (if requested), and test name (if needed).
-func (c *converter) writeEvent(e *event) {
+func (c *Converter) writeEvent(e *event) {
e.Package = c.pkg
if c.mode&Timestamp != 0 {
t := time.Now()