diff mbox

libgo patch committed: Add testing.MainStart

Message ID CAOyqgcWmdz1QLAYWqXm3UBT25qsfuY4V7vRNBH6Wge9ERmD78Q@mail.gmail.com
State New
Headers show

Commit Message

Ian Lance Taylor Dec. 13, 2014, 1:01 a.m. UTC
In Go 1.4 the "go test" command uses the new function
testing.MainStart.  That function will be normally brought into libgo
when we upgrade it to the 1.4 library.  However, for convenience for
people using gccgo with the Go 1.4 gc release, I've committed this
patch to bring it into gccgo now.  Bootstrapped and ran Go testsuite
on x86_64-unknown-linux-gnu.  Committed to mainline.

Ian
diff mbox

Patch

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() {