1
0
mirror of https://github.com/golang/go synced 2024-11-20 05:04:43 -07:00

context: adjust tests to avoid importing "testing" in package context

So that testing can use context in its public API.

For #16221.

Change-Id: I6263fa7266c336c9490f20164ce79336df44a57e
Reviewed-on: https://go-review.googlesource.com/32648
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
This commit is contained in:
Russ Cox 2016-11-03 15:01:30 -04:00
parent 2b59b15f6b
commit 606f81eef3
3 changed files with 112 additions and 56 deletions

View File

@ -0,0 +1,44 @@
// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package context_test
import (
. "context"
"fmt"
"testing"
)
func BenchmarkContextCancelTree(b *testing.B) {
depths := []int{1, 10, 100, 1000}
for _, d := range depths {
b.Run(fmt.Sprintf("depth=%d", d), func(b *testing.B) {
b.Run("Root=Background", func(b *testing.B) {
for i := 0; i < b.N; i++ {
buildContextTree(Background(), d)
}
})
b.Run("Root=OpenCanceler", func(b *testing.B) {
for i := 0; i < b.N; i++ {
ctx, cancel := WithCancel(Background())
buildContextTree(ctx, d)
cancel()
}
})
b.Run("Root=ClosedCanceler", func(b *testing.B) {
for i := 0; i < b.N; i++ {
ctx, cancel := WithCancel(Background())
cancel()
buildContextTree(ctx, d)
}
})
})
}
}
func buildContextTree(root Context, depth int) {
for d := 0; d < depth; d++ {
root, _ = WithCancel(root)
}
}

View File

@ -10,10 +10,26 @@ import (
"runtime" "runtime"
"strings" "strings"
"sync" "sync"
"testing"
"time" "time"
) )
type testingT interface {
Error(args ...interface{})
Errorf(format string, args ...interface{})
Fail()
FailNow()
Failed() bool
Fatal(args ...interface{})
Fatalf(format string, args ...interface{})
Log(args ...interface{})
Logf(format string, args ...interface{})
Name() string
Skip(args ...interface{})
SkipNow()
Skipf(format string, args ...interface{})
Skipped() bool
}
// otherContext is a Context that's not one of the types defined in context.go. // otherContext is a Context that's not one of the types defined in context.go.
// This lets us test code paths that differ based on the underlying type of the // This lets us test code paths that differ based on the underlying type of the
// Context. // Context.
@ -21,7 +37,7 @@ type otherContext struct {
Context Context
} }
func TestBackground(t *testing.T) { func XTestBackground(t testingT) {
c := Background() c := Background()
if c == nil { if c == nil {
t.Fatalf("Background returned nil") t.Fatalf("Background returned nil")
@ -36,7 +52,7 @@ func TestBackground(t *testing.T) {
} }
} }
func TestTODO(t *testing.T) { func XTestTODO(t testingT) {
c := TODO() c := TODO()
if c == nil { if c == nil {
t.Fatalf("TODO returned nil") t.Fatalf("TODO returned nil")
@ -51,7 +67,7 @@ func TestTODO(t *testing.T) {
} }
} }
func TestWithCancel(t *testing.T) { func XTestWithCancel(t testingT) {
c1, cancel := WithCancel(Background()) c1, cancel := WithCancel(Background())
if got, want := fmt.Sprint(c1), "context.Background.WithCancel"; got != want { if got, want := fmt.Sprint(c1), "context.Background.WithCancel"; got != want {
@ -97,7 +113,7 @@ func contains(m map[canceler]struct{}, key canceler) bool {
return ret return ret
} }
func TestParentFinishesChild(t *testing.T) { func XTestParentFinishesChild(t testingT) {
// Context tree: // Context tree:
// parent -> cancelChild // parent -> cancelChild
// parent -> valueChild -> timerChild // parent -> valueChild -> timerChild
@ -174,7 +190,7 @@ func TestParentFinishesChild(t *testing.T) {
} }
} }
func TestChildFinishesFirst(t *testing.T) { func XTestChildFinishesFirst(t testingT) {
cancelable, stop := WithCancel(Background()) cancelable, stop := WithCancel(Background())
defer stop() defer stop()
for _, parent := range []Context{Background(), cancelable} { for _, parent := range []Context{Background(), cancelable} {
@ -234,7 +250,7 @@ func TestChildFinishesFirst(t *testing.T) {
} }
} }
func testDeadline(c Context, name string, failAfter time.Duration, t *testing.T) { func testDeadline(c Context, name string, failAfter time.Duration, t testingT) {
select { select {
case <-time.After(failAfter): case <-time.After(failAfter):
t.Fatalf("%s: context should have timed out", name) t.Fatalf("%s: context should have timed out", name)
@ -245,7 +261,7 @@ func testDeadline(c Context, name string, failAfter time.Duration, t *testing.T)
} }
} }
func TestDeadline(t *testing.T) { func XTestDeadline(t testingT) {
c, _ := WithDeadline(Background(), time.Now().Add(50*time.Millisecond)) c, _ := WithDeadline(Background(), time.Now().Add(50*time.Millisecond))
if got, prefix := fmt.Sprint(c), "context.Background.WithDeadline("; !strings.HasPrefix(got, prefix) { if got, prefix := fmt.Sprint(c), "context.Background.WithDeadline("; !strings.HasPrefix(got, prefix) {
t.Errorf("c.String() = %q want prefix %q", got, prefix) t.Errorf("c.String() = %q want prefix %q", got, prefix)
@ -268,7 +284,7 @@ func TestDeadline(t *testing.T) {
testDeadline(c, "WithDeadline+now", time.Second, t) testDeadline(c, "WithDeadline+now", time.Second, t)
} }
func TestTimeout(t *testing.T) { func XTestTimeout(t testingT) {
c, _ := WithTimeout(Background(), 50*time.Millisecond) c, _ := WithTimeout(Background(), 50*time.Millisecond)
if got, prefix := fmt.Sprint(c), "context.Background.WithDeadline("; !strings.HasPrefix(got, prefix) { if got, prefix := fmt.Sprint(c), "context.Background.WithDeadline("; !strings.HasPrefix(got, prefix) {
t.Errorf("c.String() = %q want prefix %q", got, prefix) t.Errorf("c.String() = %q want prefix %q", got, prefix)
@ -285,7 +301,7 @@ func TestTimeout(t *testing.T) {
testDeadline(c, "WithTimeout+otherContext+WithTimeout", 2*time.Second, t) testDeadline(c, "WithTimeout+otherContext+WithTimeout", 2*time.Second, t)
} }
func TestCanceledTimeout(t *testing.T) { func XTestCanceledTimeout(t testingT) {
c, _ := WithTimeout(Background(), time.Second) c, _ := WithTimeout(Background(), time.Second)
o := otherContext{c} o := otherContext{c}
c, cancel := WithTimeout(o, 2*time.Second) c, cancel := WithTimeout(o, 2*time.Second)
@ -308,7 +324,7 @@ var k1 = key1(1)
var k2 = key2(1) // same int as k1, different type var k2 = key2(1) // same int as k1, different type
var k3 = key2(3) // same type as k2, different int var k3 = key2(3) // same type as k2, different int
func TestValues(t *testing.T) { func XTestValues(t testingT) {
check := func(c Context, nm, v1, v2, v3 string) { check := func(c Context, nm, v1, v2, v3 string) {
if v, ok := c.Value(k1).(string); ok == (len(v1) == 0) || v != v1 { if v, ok := c.Value(k1).(string); ok == (len(v1) == 0) || v != v1 {
t.Errorf(`%s.Value(k1).(string) = %q, %t want %q, %t`, nm, v, ok, v1, len(v1) != 0) t.Errorf(`%s.Value(k1).(string) = %q, %t want %q, %t`, nm, v, ok, v1, len(v1) != 0)
@ -356,7 +372,7 @@ func TestValues(t *testing.T) {
check(o4, "o4", "", "c2k2", "") check(o4, "o4", "", "c2k2", "")
} }
func TestAllocs(t *testing.T) { func XTestAllocs(t testingT, testingShort func() bool, testingAllocsPerRun func(int, func()) float64) {
bg := Background() bg := Background()
for _, test := range []struct { for _, test := range []struct {
desc string desc string
@ -416,16 +432,16 @@ func TestAllocs(t *testing.T) {
limit = test.gccgoLimit limit = test.gccgoLimit
} }
numRuns := 100 numRuns := 100
if testing.Short() { if testingShort() {
numRuns = 10 numRuns = 10
} }
if n := testing.AllocsPerRun(numRuns, test.f); n > limit { if n := testingAllocsPerRun(numRuns, test.f); n > limit {
t.Errorf("%s allocs = %f want %d", test.desc, n, int(limit)) t.Errorf("%s allocs = %f want %d", test.desc, n, int(limit))
} }
} }
} }
func TestSimultaneousCancels(t *testing.T) { func XTestSimultaneousCancels(t testingT) {
root, cancel := WithCancel(Background()) root, cancel := WithCancel(Background())
m := map[Context]CancelFunc{root: cancel} m := map[Context]CancelFunc{root: cancel}
q := []Context{root} q := []Context{root}
@ -473,7 +489,7 @@ func TestSimultaneousCancels(t *testing.T) {
} }
} }
func TestInterlockedCancels(t *testing.T) { func XTestInterlockedCancels(t testingT) {
parent, cancelParent := WithCancel(Background()) parent, cancelParent := WithCancel(Background())
child, cancelChild := WithCancel(parent) child, cancelChild := WithCancel(parent)
go func() { go func() {
@ -490,15 +506,15 @@ func TestInterlockedCancels(t *testing.T) {
} }
} }
func TestLayersCancel(t *testing.T) { func XTestLayersCancel(t testingT) {
testLayers(t, time.Now().UnixNano(), false) testLayers(t, time.Now().UnixNano(), false)
} }
func TestLayersTimeout(t *testing.T) { func XTestLayersTimeout(t testingT) {
testLayers(t, time.Now().UnixNano(), true) testLayers(t, time.Now().UnixNano(), true)
} }
func testLayers(t *testing.T, seed int64, testTimeout bool) { func testLayers(t testingT, seed int64, testTimeout bool) {
rand.Seed(seed) rand.Seed(seed)
errorf := func(format string, a ...interface{}) { errorf := func(format string, a ...interface{}) {
t.Errorf(fmt.Sprintf("seed=%d: %s", seed, format), a...) t.Errorf(fmt.Sprintf("seed=%d: %s", seed, format), a...)
@ -567,7 +583,7 @@ func testLayers(t *testing.T, seed int64, testTimeout bool) {
} }
} }
func TestCancelRemoves(t *testing.T) { func XTestCancelRemoves(t testingT) {
checkChildren := func(when string, ctx Context, want int) { checkChildren := func(when string, ctx Context, want int) {
if got := len(ctx.(*cancelCtx).children); got != want { if got := len(ctx.(*cancelCtx).children); got != want {
t.Errorf("%s: context has %d children, want %d", when, got, want) t.Errorf("%s: context has %d children, want %d", when, got, want)
@ -589,7 +605,7 @@ func TestCancelRemoves(t *testing.T) {
checkChildren("after cancelling WithTimeout child", ctx, 0) checkChildren("after cancelling WithTimeout child", ctx, 0)
} }
func TestWithCancelCanceledParent(t *testing.T) { func XTestWithCancelCanceledParent(t testingT) {
parent, pcancel := WithCancel(Background()) parent, pcancel := WithCancel(Background())
pcancel() pcancel()
@ -604,7 +620,7 @@ func TestWithCancelCanceledParent(t *testing.T) {
} }
} }
func TestWithValueChecksKey(t *testing.T) { func XTestWithValueChecksKey(t testingT) {
panicVal := recoveredValue(func() { WithValue(Background(), []byte("foo"), "bar") }) panicVal := recoveredValue(func() { WithValue(Background(), []byte("foo"), "bar") })
if panicVal == nil { if panicVal == nil {
t.Error("expected panic") t.Error("expected panic")
@ -621,7 +637,7 @@ func recoveredValue(fn func()) (v interface{}) {
return return
} }
func TestDeadlineExceededSupportsTimeout(t *testing.T) { func XTestDeadlineExceededSupportsTimeout(t testingT) {
i, ok := DeadlineExceeded.(interface { i, ok := DeadlineExceeded.(interface {
Timeout() bool Timeout() bool
}) })
@ -632,36 +648,3 @@ func TestDeadlineExceededSupportsTimeout(t *testing.T) {
t.Fatal("wrong value for timeout") t.Fatal("wrong value for timeout")
} }
} }
func BenchmarkContextCancelTree(b *testing.B) {
depths := []int{1, 10, 100, 1000}
for _, d := range depths {
b.Run(fmt.Sprintf("depth=%d", d), func(b *testing.B) {
b.Run("Root=Background", func(b *testing.B) {
for i := 0; i < b.N; i++ {
buildContextTree(Background(), d)
}
})
b.Run("Root=OpenCanceler", func(b *testing.B) {
for i := 0; i < b.N; i++ {
ctx, cancel := WithCancel(Background())
buildContextTree(ctx, d)
cancel()
}
})
b.Run("Root=ClosedCanceler", func(b *testing.B) {
for i := 0; i < b.N; i++ {
ctx, cancel := WithCancel(Background())
cancel()
buildContextTree(ctx, d)
}
})
})
}
}
func buildContextTree(root Context, depth int) {
for d := 0; d < depth; d++ {
root, _ = WithCancel(root)
}
}

29
src/context/x_test.go Normal file
View File

@ -0,0 +1,29 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package context_test
import (
. "context"
"testing"
)
func TestBackground(t *testing.T) { XTestBackground(t) }
func TestTODO(t *testing.T) { XTestTODO(t) }
func TestWithCancel(t *testing.T) { XTestWithCancel(t) }
func TestParentFinishesChild(t *testing.T) { XTestParentFinishesChild(t) }
func TestChildFinishesFirst(t *testing.T) { XTestChildFinishesFirst(t) }
func TestDeadline(t *testing.T) { XTestDeadline(t) }
func TestTimeout(t *testing.T) { XTestTimeout(t) }
func TestCanceledTimeout(t *testing.T) { XTestCanceledTimeout(t) }
func TestValues(t *testing.T) { XTestValues(t) }
func TestAllocs(t *testing.T) { XTestAllocs(t, testing.Short, testing.AllocsPerRun) }
func TestSimultaneousCancels(t *testing.T) { XTestSimultaneousCancels(t) }
func TestInterlockedCancels(t *testing.T) { XTestInterlockedCancels(t) }
func TestLayersCancel(t *testing.T) { XTestLayersCancel(t) }
func TestLayersTimeout(t *testing.T) { XTestLayersTimeout(t) }
func TestCancelRemoves(t *testing.T) { XTestCancelRemoves(t) }
func TestWithCancelCanceledParent(t *testing.T) { XTestWithCancelCanceledParent(t) }
func TestWithValueChecksKey(t *testing.T) { XTestWithValueChecksKey(t) }
func TestDeadlineExceededSupportsTimeout(t *testing.T) { XTestDeadlineExceededSupportsTimeout(t) }