Skip to content

Commit 7684fe0

Browse files
committed
cmd/test2json: add ability to run test binary
Also be clear that go test output is not suitable for piping into test2json. Fixes #22710. Fixes #22789. Change-Id: I3d850c8a2288be7f9a27d638bbf847cb8707dcce Reviewed-on: https://go-review.googlesource.com/81555 Run-TryBot: Russ Cox <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Ian Lance Taylor <[email protected]>
1 parent 7ef9f72 commit 7684fe0

File tree

2 files changed

+44
-9
lines changed

2 files changed

+44
-9
lines changed

src/cmd/go/go_test.go

+5
Original file line numberDiff line numberDiff line change
@@ -5251,6 +5251,11 @@ func TestGoTestJSON(t *testing.T) {
52515251
tg.grepStdout(`"Package":"errors"`, "did not see JSON output")
52525252
tg.grepStdout(`"Action":"run"`, "did not see JSON output")
52535253

5254+
tg.run("test", "-o", filepath.Join(tg.tempdir, "errors.test.exe"), "-c", "errors")
5255+
tg.run("tool", "test2json", "-p", "errors", filepath.Join(tg.tempdir, "errors.test.exe"), "-test.v", "-test.short")
5256+
tg.grepStdout(`"Package":"errors"`, "did not see JSON output")
5257+
tg.grepStdout(`"Action":"run"`, "did not see JSON output")
5258+
tg.grepStdout(`\{"Action":"pass","Package":"errors"\}`, "did not see final pass")
52545259
}
52555260

52565261
func TestFailFast(t *testing.T) {

src/cmd/test2json/main.go

+39-9
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@
66
//
77
// Usage:
88
//
9-
// go test ... | go tool test2json [-p pkg] [-t]
10-
// ./test.out 2>&1 | go tool test2json [-p pkg] [-t]
9+
// go tool test2json [-p pkg] [-t] [./pkg.test -test.v]
1110
//
12-
// Test2json expects to read go test output from standard input.
11+
// Test2json runs the given test command and converts its output to JSON;
12+
// with no command specified, test2json expects test output on standard input.
1313
// It writes a corresponding stream of JSON events to standard output.
1414
// There is no unnecessary input or output buffering, so that
1515
// the JSON stream can be read for “live updates” of test status.
@@ -18,6 +18,10 @@
1818
//
1919
// The -t flag requests that time stamps be added to each test event.
2020
//
21+
// Note that test2json is only intended for converting a single test
22+
// binary's output. To convert the output of a "go test" command,
23+
// use "go test -json" instead of invoking test2json directly.
24+
//
2125
// Output Format
2226
//
2327
// The JSON stream is a newline-separated sequence of TestEvent objects
@@ -56,7 +60,7 @@
5660
// The Elapsed field is set for "pass" and "fail" events. It gives the time
5761
// elapsed for the specific test or the overall package test that passed or failed.
5862
//
59-
// The Output field is set for Event == "output" and is a portion of the test's output
63+
// The Output field is set for Action == "output" and is a portion of the test's output
6064
// (standard output and standard error merged together). The output is
6165
// unmodified except that invalid UTF-8 output from a test is coerced
6266
// into valid UTF-8 by use of replacement characters. With that one exception,
@@ -70,6 +74,7 @@ import (
7074
"fmt"
7175
"io"
7276
"os"
77+
"os/exec"
7378

7479
"cmd/internal/test2json"
7580
)
@@ -80,22 +85,47 @@ var (
8085
)
8186

8287
func usage() {
83-
fmt.Fprintf(os.Stderr, "usage: go test ... | go tool test2json [-p pkg] [-t]\n")
88+
fmt.Fprintf(os.Stderr, "usage: go tool test2json [-p pkg] [-t] [./pkg.test -test.v]\n")
8489
os.Exit(2)
8590
}
8691

8792
func main() {
8893
flag.Usage = usage
8994
flag.Parse()
90-
if flag.NArg() > 0 {
91-
usage()
92-
}
9395

9496
var mode test2json.Mode
9597
if *flagT {
9698
mode |= test2json.Timestamp
9799
}
98100
c := test2json.NewConverter(os.Stdout, *flagP, mode)
99101
defer c.Close()
100-
io.Copy(c, os.Stdin)
102+
103+
if flag.NArg() == 0 {
104+
io.Copy(c, os.Stdin)
105+
} else {
106+
args := flag.Args()
107+
cmd := exec.Command(args[0], args[1:]...)
108+
w := &countWriter{0, c}
109+
cmd.Stdout = w
110+
cmd.Stderr = w
111+
if err := cmd.Run(); err != nil {
112+
if w.n > 0 {
113+
// Assume command printed why it failed.
114+
} else {
115+
fmt.Fprintf(c, "test2json: %v\n", err)
116+
}
117+
c.Close()
118+
os.Exit(1)
119+
}
120+
}
121+
}
122+
123+
type countWriter struct {
124+
n int64
125+
w io.Writer
126+
}
127+
128+
func (w *countWriter) Write(b []byte) (int, error) {
129+
w.n += int64(len(b))
130+
return w.w.Write(b)
101131
}

0 commit comments

Comments
 (0)