aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/testing/testing.go
diff options
context:
space:
mode:
Diffstat (limited to 'libgo/go/testing/testing.go')
-rw-r--r--libgo/go/testing/testing.go32
1 files changed, 27 insertions, 5 deletions
diff --git a/libgo/go/testing/testing.go b/libgo/go/testing/testing.go
index 9ec3869768c..bcbe8f15c55 100644
--- a/libgo/go/testing/testing.go
+++ b/libgo/go/testing/testing.go
@@ -149,6 +149,7 @@ import (
"fmt"
"os"
"runtime"
+ "runtime/debug"
"runtime/pprof"
"strconv"
"strings"
@@ -281,9 +282,18 @@ var _ TB = (*B)(nil)
// T is a type passed to Test functions to manage test state and support formatted test logs.
// Logs are accumulated during execution and dumped to standard error when done.
+//
+// A test ends when its Test function returns or calls any of the methods
+// FailNow, Fatal, Fatalf, SkipNow, Skip, or Skipf. Those methods, as well as
+// the Parallel method, must be called only from the goroutine running the
+// Test function.
+//
+// The other reporting methods, such as the variations of Log and Error,
+// may be called simultaneously from multiple goroutines.
type T struct {
common
- name string // Name of test.
+ name string // Name of test.
+ isParallel bool
startParallel chan bool // Parallel tests will wait on this.
}
@@ -417,10 +427,17 @@ func (c *common) Skipped() bool {
// Parallel signals that this test is to be run in parallel with (and only with)
// other parallel tests.
func (t *T) Parallel() {
+ if t.isParallel {
+ panic("testing: t.Parallel called multiple times")
+ }
+ t.isParallel = true
+
+ // We don't want to include the time we spend waiting for serial tests
+ // in the test duration. Record the elapsed time thus far and reset the
+ // timer afterwards.
+ t.duration += time.Since(t.start)
t.signal <- (*T)(nil) // Release main testing loop
<-t.startParallel // Wait for serial tests to finish
- // Assuming Parallel is the first thing a test does, which is reasonable,
- // reinitialize the test's start time because it's actually starting now.
t.start = time.Now()
}
@@ -437,7 +454,7 @@ func tRunner(t *T, test *InternalTest) {
// a call to runtime.Goexit, record the duration and send
// a signal saying that the test is done.
defer func() {
- t.duration = time.Now().Sub(t.start)
+ t.duration += time.Now().Sub(t.start)
// If the test panicked, print any test output before dying.
err := recover()
if !t.finished && err == nil {
@@ -484,7 +501,11 @@ func MainStart(matchString func(pat, str string) (bool, error), tests []Internal
// Run runs the tests. It returns an exit code to pass to os.Exit.
func (m *M) Run() int {
- flag.Parse()
+ // TestMain may have already called flag.Parse.
+ if !flag.Parsed() {
+ flag.Parse()
+ }
+
parseCpuList()
before()
@@ -704,6 +725,7 @@ var timer *time.Timer
func startAlarm() {
if *timeout > 0 {
timer = time.AfterFunc(*timeout, func() {
+ debug.SetTraceback("all")
panic(fmt.Sprintf("test timed out after %v", *timeout))
})
}