libgo: update to Go 1.11
[official-gcc.git] / libgo / go / cmd / test2json / main.go
blob0385d8f246c358a39185e3c8642c07ff2aa16184
1 // Copyright 2017 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
5 // Test2json converts go test output to a machine-readable JSON stream.
6 //
7 // Usage:
8 //
9 // go tool test2json [-p pkg] [-t] [./pkg.test -test.v]
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 // It writes a corresponding stream of JSON events to standard output.
14 // There is no unnecessary input or output buffering, so that
15 // the JSON stream can be read for “live updates” of test status.
17 // The -p flag sets the package reported in each test event.
19 // The -t flag requests that time stamps be added to each test event.
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.
25 // Output Format
27 // The JSON stream is a newline-separated sequence of TestEvent objects
28 // corresponding to the Go struct:
30 // type TestEvent struct {
31 // Time time.Time // encodes as an RFC3339-format string
32 // Action string
33 // Package string
34 // Test string
35 // Elapsed float64 // seconds
36 // Output string
37 // }
39 // The Time field holds the time the event happened.
40 // It is conventionally omitted for cached test results.
42 // The Action field is one of a fixed set of action descriptions:
44 // run - the test has started running
45 // pause - the test has been paused
46 // cont - the test has continued running
47 // pass - the test passed
48 // bench - the benchmark printed log output but did not fail
49 // fail - the test or benchmark failed
50 // output - the test printed output
51 // skip - the test was skipped or the package contained no tests
53 // The Package field, if present, specifies the package being tested.
54 // When the go command runs parallel tests in -json mode, events from
55 // different tests are interlaced; the Package field allows readers to
56 // separate them.
58 // The Test field, if present, specifies the test, example, or benchmark
59 // function that caused the event. Events for the overall package test
60 // do not set Test.
62 // The Elapsed field is set for "pass" and "fail" events. It gives the time
63 // elapsed for the specific test or the overall package test that passed or failed.
65 // The Output field is set for Action == "output" and is a portion of the test's output
66 // (standard output and standard error merged together). The output is
67 // unmodified except that invalid UTF-8 output from a test is coerced
68 // into valid UTF-8 by use of replacement characters. With that one exception,
69 // the concatenation of the Output fields of all output events is the exact
70 // output of the test execution.
72 // When a benchmark runs, it typically produces a single line of output
73 // giving timing results. That line is reported in an event with Action == "output"
74 // and no Test field. If a benchmark logs output or reports a failure
75 // (for example, by using b.Log or b.Error), that extra output is reported
76 // as a sequence of events with Test set to the benchmark name, terminated
77 // by a final event with Action == "bench" or "fail".
78 // Benchmarks have no events with Action == "run", "pause", or "cont".
80 package main
82 import (
83 "flag"
84 "fmt"
85 "io"
86 "os"
87 "os/exec"
89 "cmd/internal/test2json"
92 var (
93 flagP = flag.String("p", "", "report `pkg` as the package being tested in each event")
94 flagT = flag.Bool("t", false, "include timestamps in events")
97 func usage() {
98 fmt.Fprintf(os.Stderr, "usage: go tool test2json [-p pkg] [-t] [./pkg.test -test.v]\n")
99 os.Exit(2)
102 func main() {
103 flag.Usage = usage
104 flag.Parse()
106 var mode test2json.Mode
107 if *flagT {
108 mode |= test2json.Timestamp
110 c := test2json.NewConverter(os.Stdout, *flagP, mode)
111 defer c.Close()
113 if flag.NArg() == 0 {
114 io.Copy(c, os.Stdin)
115 } else {
116 args := flag.Args()
117 cmd := exec.Command(args[0], args[1:]...)
118 w := &countWriter{0, c}
119 cmd.Stdout = w
120 cmd.Stderr = w
121 if err := cmd.Run(); err != nil {
122 if w.n > 0 {
123 // Assume command printed why it failed.
124 } else {
125 fmt.Fprintf(c, "test2json: %v\n", err)
127 c.Close()
128 os.Exit(1)
133 type countWriter struct {
134 n int64
135 w io.Writer
138 func (w *countWriter) Write(b []byte) (int, error) {
139 w.n += int64(len(b))
140 return w.w.Write(b)