aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/dist/test.go
diff options
context:
space:
mode:
authorAustin Clements <austin@google.com>2023-05-19 09:32:22 -0400
committerGopher Robot <gobot@golang.org>2023-05-19 20:13:24 +0000
commit6333725d5fae3ceda830d3d1d65b1540d004b288 (patch)
tree3ef70b6acec6a4197d99811ae9a6e1b38e1f1eb3 /src/cmd/dist/test.go
parente6fb1905cb740b7d68b1c9676f058bf44266539d (diff)
downloadgo-6333725d5fae3ceda830d3d1d65b1540d004b288.tar.gz
go-6333725d5fae3ceda830d3d1d65b1540d004b288.zip
cmd/dist: flush incomplete lines in -json mode
Currently, if a test prints an incomplete line and then exits, in JSON mode, the filter we use to rewrite Package lines will keep the last incomplete line in an internal buffer and never print it. In theory this should never happen anyway because the test should only write JSON to stdout, but we try pretty hard to pass through any non-JSON, so it seems inconsistent to swallow incomplete lines. Fix this by adding a testJSONFilter.Flush method and calling it in the right places. Unfortunately this is a bit tricky because the filter is constructed pretty far from where we run the exec.Cmd, so we return the flush function through the various layers in order to route it to the place where we call Cmd.Run. Updates #37486. Change-Id: I38af67e8ad23458598a32fd428779bb0ec21ac3c Reviewed-on: https://go-review.googlesource.com/c/go/+/496516 Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Auto-Submit: Austin Clements <austin@google.com> Reviewed-by: Bryan Mills <bcmills@google.com>
Diffstat (limited to 'src/cmd/dist/test.go')
-rw-r--r--src/cmd/dist/test.go35
1 files changed, 24 insertions, 11 deletions
diff --git a/src/cmd/dist/test.go b/src/cmd/dist/test.go
index 65e4515e9a..046d279c98 100644
--- a/src/cmd/dist/test.go
+++ b/src/cmd/dist/test.go
@@ -86,6 +86,7 @@ type tester struct {
type work struct {
dt *distTest
cmd *exec.Cmd // Must write stdout/stderr to work.out
+ flush func() // If non-nil, called after cmd.Run
start chan bool
out bytes.Buffer
err error
@@ -326,9 +327,10 @@ type goTest struct {
testFlags []string // Additional flags accepted by this test
}
-// bgCommand returns a go test Cmd. The result will write its output to stdout
-// and stderr. If stdout==stderr, bgCommand ensures Writes are serialized.
-func (opts *goTest) bgCommand(t *tester, stdout, stderr io.Writer) *exec.Cmd {
+// bgCommand returns a go test Cmd and a post-Run flush function. The result
+// will write its output to stdout and stderr. If stdout==stderr, bgCommand
+// ensures Writes are serialized. The caller should call flush() after Cmd exits.
+func (opts *goTest) bgCommand(t *tester, stdout, stderr io.Writer) (cmd *exec.Cmd, flush func()) {
goCmd, build, run, pkgs, testFlags, setupCmd := opts.buildArgs(t)
// Combine the flags.
@@ -343,7 +345,7 @@ func (opts *goTest) bgCommand(t *tester, stdout, stderr io.Writer) *exec.Cmd {
args = append(args, testFlags...)
}
- cmd := exec.Command(goCmd, args...)
+ cmd = exec.Command(goCmd, args...)
setupCmd(cmd)
if t.json && opts.variant != "" && !opts.sharded {
// Rewrite Package in the JSON output to be pkg:variant. For sharded
@@ -364,22 +366,29 @@ func (opts *goTest) bgCommand(t *tester, stdout, stderr io.Writer) *exec.Cmd {
stdout = &lockedWriter{w: stdout}
stderr = stdout
}
- cmd.Stdout = &testJSONFilter{w: stdout, variant: opts.variant}
+ f := &testJSONFilter{w: stdout, variant: opts.variant}
+ cmd.Stdout = f
+ flush = f.Flush
} else {
cmd.Stdout = stdout
+ flush = func() {}
}
cmd.Stderr = stderr
- return cmd
+ return cmd, flush
}
-// command returns a go test Cmd intended to be run immediately.
-func (opts *goTest) command(t *tester) *exec.Cmd {
+// command returns a go test Cmd intended to be run immediately and a flush
+// function to call after it has run.
+func (opts *goTest) command(t *tester) (*exec.Cmd, func()) {
return opts.bgCommand(t, os.Stdout, os.Stderr)
}
func (opts *goTest) run(t *tester) error {
- return opts.command(t).Run()
+ cmd, flush := opts.command(t)
+ err := cmd.Run()
+ flush()
+ return err
}
// buildArgs is in internal helper for goTest that constructs the elements of
@@ -742,13 +751,14 @@ func (t *tester) registerTests() {
// Run `go test fmt` in the moved GOROOT, without explicitly setting
// GOROOT in the environment. The 'go' command should find itself.
- cmd := (&goTest{
+ cmd, flush := (&goTest{
variant: "moved_goroot",
goroot: moved,
pkg: "fmt",
}).command(t)
unsetEnv(cmd, "GOROOT")
err := cmd.Run()
+ flush()
if rerr := os.Rename(moved, goroot); rerr != nil {
fatalf("failed to restore GOROOT: %v", rerr)
@@ -936,7 +946,7 @@ func (t *tester) registerTest(name, heading string, test *goTest, opts ...regist
}
}
w := &work{dt: dt}
- w.cmd = test.bgCommand(t, &w.out, &w.out)
+ w.cmd, w.flush = test.bgCommand(t, &w.out, &w.out)
t.worklist = append(t.worklist, w)
return nil
})
@@ -1255,6 +1265,9 @@ func (t *tester) runPending(nextTest *distTest) {
} else {
timelog("start", w.dt.name)
w.err = w.cmd.Run()
+ if w.flush != nil {
+ w.flush()
+ }
if w.err != nil {
if isUnsupportedVMASize(w) {
timelog("skip", w.dt.name)