6
6
//
7
7
// Usage:
8
8
//
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]
11
10
//
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.
13
13
// It writes a corresponding stream of JSON events to standard output.
14
14
// There is no unnecessary input or output buffering, so that
15
15
// the JSON stream can be read for “live updates” of test status.
18
18
//
19
19
// The -t flag requests that time stamps be added to each test event.
20
20
//
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
+ //
21
25
// Output Format
22
26
//
23
27
// The JSON stream is a newline-separated sequence of TestEvent objects
56
60
// The Elapsed field is set for "pass" and "fail" events. It gives the time
57
61
// elapsed for the specific test or the overall package test that passed or failed.
58
62
//
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
60
64
// (standard output and standard error merged together). The output is
61
65
// unmodified except that invalid UTF-8 output from a test is coerced
62
66
// into valid UTF-8 by use of replacement characters. With that one exception,
@@ -70,6 +74,7 @@ import (
70
74
"fmt"
71
75
"io"
72
76
"os"
77
+ "os/exec"
73
78
74
79
"cmd/internal/test2json"
75
80
)
@@ -80,22 +85,47 @@ var (
80
85
)
81
86
82
87
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 " )
84
89
os .Exit (2 )
85
90
}
86
91
87
92
func main () {
88
93
flag .Usage = usage
89
94
flag .Parse ()
90
- if flag .NArg () > 0 {
91
- usage ()
92
- }
93
95
94
96
var mode test2json.Mode
95
97
if * flagT {
96
98
mode |= test2json .Timestamp
97
99
}
98
100
c := test2json .NewConverter (os .Stdout , * flagP , mode )
99
101
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 )
101
131
}
0 commit comments