diff -r 9ac141d2f527 libgo/go/testing/testing.go --- a/libgo/go/testing/testing.go Fri Dec 12 16:49:18 2014 -0800 +++ b/libgo/go/testing/testing.go Fri Dec 12 16:57:00 2014 -0800 @@ -117,6 +117,26 @@ // The entire test file is presented as the example when it contains a single // example function, at least one other function, type, variable, or constant // declaration, and no test or benchmark functions. +// +// Main +// +// It is sometimes necessary for a test program to do extra setup or teardown +// before or after testing. It is also sometimes necessary for a test to control +// which code runs on the main thread. To support these and other cases, +// if a test file contains a function: +// +// func TestMain(m *testing.M) +// +// then the generated test will call TestMain(m) instead of running the tests +// directly. TestMain runs in the main goroutine and can do whatever setup +// and teardown is necessary around a call to m.Run. It should then call +// os.Exit with the result of m.Run. +// +// The minimal implementation of TestMain is: +// +// func TestMain(m *testing.M) { os.Exit(m.Run()) } +// +// In effect, that is the implementation used when no TestMain is explicitly defined. package testing import ( @@ -426,23 +446,49 @@ // An internal function but exported because it is cross-package; part of the implementation // of the "go test" command. func Main(matchString func(pat, str string) (bool, error), tests []InternalTest, benchmarks []InternalBenchmark, examples []InternalExample) { + os.Exit(MainStart(matchString, tests, benchmarks, examples).Run()) +} + +// M is a type passed to a TestMain function to run the actual tests. +type M struct { + matchString func(pat, str string) (bool, error) + tests []InternalTest + benchmarks []InternalBenchmark + examples []InternalExample +} + +// MainStart is meant for use by tests generated by 'go test'. +// It is not meant to be called directly and is not subject to the Go 1 compatibility document. +// It may change signature from release to release. +func MainStart(matchString func(pat, str string) (bool, error), tests []InternalTest, benchmarks []InternalBenchmark, examples []InternalExample) *M { + return &M{ + matchString: matchString, + tests: tests, + benchmarks: benchmarks, + examples: examples, + } +} + +// Run runs the tests. It returns an exit code to pass to os.Exit. +func (m *M) Run() int { flag.Parse() parseCpuList() before() startAlarm() - haveExamples = len(examples) > 0 - testOk := RunTests(matchString, tests) - exampleOk := RunExamples(matchString, examples) + haveExamples = len(m.examples) > 0 + testOk := RunTests(m.matchString, m.tests) + exampleOk := RunExamples(m.matchString, m.examples) stopAlarm() if !testOk || !exampleOk { fmt.Println("FAIL") after() - os.Exit(1) + return 1 } fmt.Println("PASS") - RunBenchmarks(matchString, benchmarks) + RunBenchmarks(m.matchString, m.benchmarks) after() + return 0 } func (t *T) report() {