Commit 4bf7d1e7 authored by Joe Tsai's avatar Joe Tsai Committed by Brad Fitzpatrick

Revert "testing: add T.Context method"

This reverts commit 26827bc2.

Fixes #18199

Change-Id: I42e292cb4e3d740a4fbb5d0380c6ee15ac742092
Reviewed-on: https://go-review.googlesource.com/34141Reviewed-by: 's avatarBrad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent e12ce1e4
...@@ -179,7 +179,7 @@ var pkgDeps = map[string][]string{ ...@@ -179,7 +179,7 @@ var pkgDeps = map[string][]string{
"runtime/trace": {"L0"}, "runtime/trace": {"L0"},
"text/tabwriter": {"L2"}, "text/tabwriter": {"L2"},
"testing": {"L2", "context", "flag", "fmt", "internal/race", "os", "runtime/debug", "runtime/pprof", "runtime/trace", "time"}, "testing": {"L2", "flag", "fmt", "internal/race", "os", "runtime/debug", "runtime/pprof", "runtime/trace", "time"},
"testing/iotest": {"L2", "log"}, "testing/iotest": {"L2", "log"},
"testing/quick": {"L2", "flag", "fmt", "reflect"}, "testing/quick": {"L2", "flag", "fmt", "reflect"},
"internal/testenv": {"L2", "OS", "flag", "testing", "syscall"}, "internal/testenv": {"L2", "OS", "flag", "testing", "syscall"},
......
...@@ -5,7 +5,6 @@ ...@@ -5,7 +5,6 @@
package testing package testing
import ( import (
"context"
"flag" "flag"
"fmt" "fmt"
"internal/race" "internal/race"
...@@ -128,9 +127,6 @@ func (b *B) nsPerOp() int64 { ...@@ -128,9 +127,6 @@ func (b *B) nsPerOp() int64 {
// runN runs a single benchmark for the specified number of iterations. // runN runs a single benchmark for the specified number of iterations.
func (b *B) runN(n int) { func (b *B) runN(n int) {
b.ctx, b.cancel = context.WithCancel(b.parentContext())
defer b.cancel()
benchmarkLock.Lock() benchmarkLock.Lock()
defer benchmarkLock.Unlock() defer benchmarkLock.Unlock()
// Try to get a comparable environment for each run // Try to get a comparable environment for each run
......
...@@ -6,7 +6,6 @@ package testing ...@@ -6,7 +6,6 @@ package testing
import ( import (
"bytes" "bytes"
"context"
"regexp" "regexp"
"strings" "strings"
"sync/atomic" "sync/atomic"
...@@ -278,33 +277,28 @@ func TestTRun(t *T) { ...@@ -278,33 +277,28 @@ func TestTRun(t *T) {
ok: true, ok: true,
maxPar: 4, maxPar: 4,
f: func(t *T) { f: func(t *T) {
// t.Parallel doesn't work in the pseudo-T we start with: t.Parallel()
// it leaks a goroutine. for i := 0; i < 12; i++ {
// Call t.Run to get a real one. t.Run("a", func(t *T) {
t.Run("X", func(t *T) { t.Parallel()
t.Parallel() time.Sleep(time.Nanosecond)
for i := 0; i < 12; i++ { for i := 0; i < 12; i++ {
t.Run("a", func(t *T) { t.Run("b", func(t *T) {
t.Parallel() time.Sleep(time.Nanosecond)
time.Sleep(time.Nanosecond) for i := 0; i < 12; i++ {
for i := 0; i < 12; i++ { t.Run("c", func(t *T) {
t.Run("b", func(t *T) { t.Parallel()
time.Sleep(time.Nanosecond) time.Sleep(time.Nanosecond)
for i := 0; i < 12; i++ { t.Run("d1", func(t *T) {})
t.Run("c", func(t *T) { t.Run("d2", func(t *T) {})
t.Parallel() t.Run("d3", func(t *T) {})
time.Sleep(time.Nanosecond) t.Run("d4", func(t *T) {})
t.Run("d1", func(t *T) {}) })
t.Run("d2", func(t *T) {}) }
t.Run("d3", func(t *T) {}) })
t.Run("d4", func(t *T) {}) }
}) })
} }
})
}
})
}
})
}, },
}, { }, {
desc: "skip output", desc: "skip output",
...@@ -347,7 +341,6 @@ func TestTRun(t *T) { ...@@ -347,7 +341,6 @@ func TestTRun(t *T) {
}, },
context: ctx, context: ctx,
} }
root.ctx, root.cancel = context.WithCancel(context.Background())
ok := root.Run(tc.desc, tc.f) ok := root.Run(tc.desc, tc.f)
ctx.release() ctx.release()
......
...@@ -204,7 +204,6 @@ package testing ...@@ -204,7 +204,6 @@ package testing
import ( import (
"bytes" "bytes"
"context"
"errors" "errors"
"flag" "flag"
"fmt" "fmt"
...@@ -262,14 +261,12 @@ type common struct { ...@@ -262,14 +261,12 @@ type common struct {
mu sync.RWMutex // guards output, failed, and done. mu sync.RWMutex // guards output, failed, and done.
output []byte // Output generated by test or benchmark. output []byte // Output generated by test or benchmark.
w io.Writer // For flushToParent. w io.Writer // For flushToParent.
ctx context.Context chatty bool // A copy of the chatty flag.
cancel context.CancelFunc ran bool // Test or benchmark (or one of its subtests) was executed.
chatty bool // A copy of the chatty flag. failed bool // Test or benchmark has failed.
ran bool // Test or benchmark (or one of its subtests) was executed. skipped bool // Test of benchmark has been skipped.
failed bool // Test or benchmark has failed. finished bool // Test function has completed.
skipped bool // Test of benchmark has been skipped. done bool // Test is finished and all subtests have completed.
finished bool // Test function has completed.
done bool // Test is finished and all subtests have completed.
hasSub bool hasSub bool
raceErrors int // number of races detected during test raceErrors int // number of races detected during test
...@@ -283,13 +280,6 @@ type common struct { ...@@ -283,13 +280,6 @@ type common struct {
sub []*T // Queue of subtests to be run in parallel. sub []*T // Queue of subtests to be run in parallel.
} }
func (c *common) parentContext() context.Context {
if c == nil || c.parent == nil || c.parent.ctx == nil {
return context.Background()
}
return c.parent.ctx
}
// Short reports whether the -test.short flag is set. // Short reports whether the -test.short flag is set.
func Short() bool { func Short() bool {
return *short return *short
...@@ -386,7 +376,6 @@ func fmtDuration(d time.Duration) string { ...@@ -386,7 +376,6 @@ func fmtDuration(d time.Duration) string {
// TB is the interface common to T and B. // TB is the interface common to T and B.
type TB interface { type TB interface {
Context() context.Context
Error(args ...interface{}) Error(args ...interface{})
Errorf(format string, args ...interface{}) Errorf(format string, args ...interface{})
Fail() Fail()
...@@ -434,15 +423,6 @@ func (c *common) Name() string { ...@@ -434,15 +423,6 @@ func (c *common) Name() string {
return c.name return c.name
} }
// Context returns the context for the current test or benchmark.
// The context is cancelled when the test or benchmark finishes.
// A goroutine started during a test or benchmark can wait for the
// context's Done channel to become readable as a signal that the
// test or benchmark is over, so that the goroutine can exit.
func (c *common) Context() context.Context {
return c.ctx
}
func (c *common) setRan() { func (c *common) setRan() {
if c.parent != nil { if c.parent != nil {
c.parent.setRan() c.parent.setRan()
...@@ -619,9 +599,6 @@ type InternalTest struct { ...@@ -619,9 +599,6 @@ type InternalTest struct {
} }
func tRunner(t *T, fn func(t *T)) { func tRunner(t *T, fn func(t *T)) {
t.ctx, t.cancel = context.WithCancel(t.parentContext())
defer t.cancel()
// When this goroutine is done, either because fn(t) // When this goroutine is done, either because fn(t)
// returned normally or because a test failure triggered // returned normally or because a test failure triggered
// a call to runtime.Goexit, record the duration and send // a call to runtime.Goexit, record the duration and send
......
...@@ -5,42 +5,14 @@ ...@@ -5,42 +5,14 @@
package testing_test package testing_test
import ( import (
"fmt"
"os" "os"
"runtime"
"testing" "testing"
"time"
) )
func TestMain(m *testing.M) { // This is exactly what a test would do without a TestMain.
g0 := runtime.NumGoroutine() // It's here only so that there is at least one package in the
// standard library with a TestMain, so that code is executed.
code := m.Run()
if code != 0 {
os.Exit(code)
}
// Check that there are no goroutines left behind. func TestMain(m *testing.M) {
t0 := time.Now() os.Exit(m.Run())
stacks := make([]byte, 1<<20)
for {
g1 := runtime.NumGoroutine()
if g1 == g0 {
return
}
stacks = stacks[:runtime.Stack(stacks, true)]
time.Sleep(50 * time.Millisecond)
if time.Since(t0) > 2*time.Second {
fmt.Fprintf(os.Stderr, "Unexpected leftover goroutines detected: %v -> %v\n%s\n", g0, g1, stacks)
os.Exit(1)
}
}
}
func TestContextCancel(t *testing.T) {
ctx := t.Context()
// Tests we don't leak this goroutine:
go func() {
<-ctx.Done()
}()
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment