]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/test2json: add ability to run test binary
authorRuss Cox <rsc@golang.org>
Fri, 1 Dec 2017 18:54:15 +0000 (13:54 -0500)
committerRuss Cox <rsc@golang.org>
Fri, 1 Dec 2017 21:06:36 +0000 (21:06 +0000)
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 <rsc@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
src/cmd/go/go_test.go
src/cmd/test2json/main.go

index 4551193b88bb32cf7e2c89bdb92774e8dbf288be..5694b58f7a3d59f7756ad9bddc867051b15c0391 100644 (file)
@@ -5251,6 +5251,11 @@ func TestGoTestJSON(t *testing.T) {
        tg.grepStdout(`"Package":"errors"`, "did not see JSON output")
        tg.grepStdout(`"Action":"run"`, "did not see JSON output")
 
+       tg.run("test", "-o", filepath.Join(tg.tempdir, "errors.test.exe"), "-c", "errors")
+       tg.run("tool", "test2json", "-p", "errors", filepath.Join(tg.tempdir, "errors.test.exe"), "-test.v", "-test.short")
+       tg.grepStdout(`"Package":"errors"`, "did not see JSON output")
+       tg.grepStdout(`"Action":"run"`, "did not see JSON output")
+       tg.grepStdout(`\{"Action":"pass","Package":"errors"\}`, "did not see final pass")
 }
 
 func TestFailFast(t *testing.T) {
index 14004977f5568b2d5c871b8e0c396215328c4be8..7bdc867bbe5a55e37099afce5d9a388959d18ed5 100644 (file)
@@ -6,10 +6,10 @@
 //
 // Usage:
 //
-//     go test ... | go tool test2json [-p pkg] [-t]
-//     ./test.out 2>&1 | go tool test2json [-p pkg] [-t]
+//     go tool test2json [-p pkg] [-t] [./pkg.test -test.v]
 //
-// Test2json expects to read go test output from standard input.
+// Test2json runs the given test command and converts its output to JSON;
+// with no command specified, test2json expects test output on standard input.
 // It writes a corresponding stream of JSON events to standard output.
 // There is no unnecessary input or output buffering, so that
 // the JSON stream can be read for “live updates” of test status.
 //
 // The -t flag requests that time stamps be added to each test event.
 //
+// Note that test2json is only intended for converting a single test
+// binary's output. To convert the output of a "go test" command,
+// use "go test -json" instead of invoking test2json directly.
+//
 // Output Format
 //
 // The JSON stream is a newline-separated sequence of TestEvent objects
@@ -56,7 +60,7 @@
 // The Elapsed field is set for "pass" and "fail" events. It gives the time
 // elapsed for the specific test or the overall package test that passed or failed.
 //
-// The Output field is set for Event == "output" and is a portion of the test's output
+// The Output field is set for Action == "output" and is a portion of the test's output
 // (standard output and standard error merged together). The output is
 // unmodified except that invalid UTF-8 output from a test is coerced
 // into valid UTF-8 by use of replacement characters. With that one exception,
@@ -70,6 +74,7 @@ import (
        "fmt"
        "io"
        "os"
+       "os/exec"
 
        "cmd/internal/test2json"
 )
@@ -80,16 +85,13 @@ var (
 )
 
 func usage() {
-       fmt.Fprintf(os.Stderr, "usage: go test ... | go tool test2json [-p pkg] [-t]\n")
+       fmt.Fprintf(os.Stderr, "usage: go tool test2json [-p pkg] [-t] [./pkg.test -test.v]\n")
        os.Exit(2)
 }
 
 func main() {
        flag.Usage = usage
        flag.Parse()
-       if flag.NArg() > 0 {
-               usage()
-       }
 
        var mode test2json.Mode
        if *flagT {
@@ -97,5 +99,33 @@ func main() {
        }
        c := test2json.NewConverter(os.Stdout, *flagP, mode)
        defer c.Close()
-       io.Copy(c, os.Stdin)
+
+       if flag.NArg() == 0 {
+               io.Copy(c, os.Stdin)
+       } else {
+               args := flag.Args()
+               cmd := exec.Command(args[0], args[1:]...)
+               w := &countWriter{0, c}
+               cmd.Stdout = w
+               cmd.Stderr = w
+               if err := cmd.Run(); err != nil {
+                       if w.n > 0 {
+                               // Assume command printed why it failed.
+                       } else {
+                               fmt.Fprintf(c, "test2json: %v\n", err)
+                       }
+                       c.Close()
+                       os.Exit(1)
+               }
+       }
+}
+
+type countWriter struct {
+       n int64
+       w io.Writer
+}
+
+func (w *countWriter) Write(b []byte) (int, error) {
+       w.n += int64(len(b))
+       return w.w.Write(b)
 }