diff --git a/src/cmd/go/internal/test/test.go b/src/cmd/go/internal/test/test.go index 50e6d5201b0d6e..f2d2290dbbf320 100644 --- a/src/cmd/go/internal/test/test.go +++ b/src/cmd/go/internal/test/test.go @@ -1261,7 +1261,11 @@ func (c *runCache) builderRunTest(b *work.Builder, ctx context.Context, a *work. return nil } - var stdout io.Writer = os.Stdout + // The os/exec package treats an *os.File differently to an io.Writer. + // Embed os.Stdout in an io.Writer struct so that we get the same + // behavior regardless of whether we wrap it below. + // See golang.org/issue/24050 + var stdout io.Writer = struct{ io.Writer }{os.Stdout} var err error if testJSON { json := test2json.NewConverter(lockedStdout{}, a.Package.ImportPath, test2json.Timestamp) diff --git a/src/cmd/go/testdata/script/test_output_wait.txt b/src/cmd/go/testdata/script/test_output_wait.txt new file mode 100644 index 00000000000000..878b108612de20 --- /dev/null +++ b/src/cmd/go/testdata/script/test_output_wait.txt @@ -0,0 +1,35 @@ +# Wait for test output from sub-processes whether or not the package name is +# provided on the command-line. +go test -v +stdout 'PASS\s+WAIT\s+ok' +go test -v . +stdout 'PASS\s+WAIT\s+ok' + +-- go.mod -- +module x + +-- x_test.go -- +package x + +import ( + "os" + "os/exec" + "testing" +) + +func TestMain(m *testing.M) { + if os.Getenv("WAIT") == "true" { + os.Stdout.Write([]byte("WAIT\n")) + return + } + m.Run() +} + +func TestWait(t *testing.T) { + cmd := exec.Command(os.Args[0]) + cmd.Env = []string{"WAIT=true"} + cmd.Stdout = os.Stdout + if err := cmd.Start(); err != nil { + t.Fatal(err) + } +}