testing: do not crash when m.Run is called twice and -test.testlogfile is used

Tests exist that call m.Run in a loop‽
Now we have one too.

Fixes #23129.

Change-Id: I8cbecb724f239ae14ad45d75e67d12c80e41c994
Reviewed-on: https://go-review.googlesource.com/83956
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
Russ Cox 2017-12-13 21:46:03 -05:00
parent e28a0d397b
commit 94d7c884c3
4 changed files with 59 additions and 6 deletions

View file

@ -914,6 +914,8 @@ type M struct {
timer *time.Timer
afterOnce sync.Once
numRun int
}
// testDeps is an internal interface of functionality that is
@ -945,6 +947,12 @@ func MainStart(deps testDeps, tests []InternalTest, benchmarks []InternalBenchma
// Run runs the tests. It returns an exit code to pass to os.Exit.
func (m *M) Run() int {
// Count the number of calls to m.Run.
// We only ever expected 1, but we didn't enforce that,
// and now there are tests in the wild that call m.Run multiple times.
// Sigh. golang.org/issue/23129.
m.numRun++
// TestMain may have already called flag.Parse.
if !flag.Parsed() {
flag.Parse()
@ -1110,7 +1118,16 @@ func (m *M) before() {
if *testlog != "" {
// Note: Not using toOutputDir.
// This file is for use by cmd/go, not users.
f, err := os.Create(*testlog)
var f *os.File
var err error
if m.numRun == 1 {
f, err = os.Create(*testlog)
} else {
f, err = os.OpenFile(*testlog, os.O_WRONLY, 0)
if err == nil {
f.Seek(0, io.SeekEnd)
}
}
if err != nil {
fmt.Fprintf(os.Stderr, "testing: %s\n", err)
os.Exit(2)