mirror of https://github.com/grpc/grpc-go.git
Move leak check into a separate leakcheck package (#1445)
This commit is contained in:
parent
3a378f9deb
commit
e67952ee26
|
|
@ -33,7 +33,6 @@ import (
|
|||
"os"
|
||||
"reflect"
|
||||
"runtime"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
"syscall"
|
||||
|
|
@ -59,6 +58,7 @@ import (
|
|||
"google.golang.org/grpc/status"
|
||||
"google.golang.org/grpc/tap"
|
||||
testpb "google.golang.org/grpc/test/grpc_testing"
|
||||
"google.golang.org/grpc/test/leakcheck"
|
||||
"google.golang.org/grpc/testdata"
|
||||
)
|
||||
|
||||
|
|
@ -673,7 +673,7 @@ func (te *test) withServerTester(fn func(st *serverTester)) {
|
|||
}
|
||||
|
||||
func TestTimeoutOnDeadServer(t *testing.T) {
|
||||
defer leakCheck(t)()
|
||||
defer leakcheck.Check(t)
|
||||
for _, e := range listTestEnv() {
|
||||
testTimeoutOnDeadServer(t, e)
|
||||
}
|
||||
|
|
@ -708,7 +708,7 @@ func testTimeoutOnDeadServer(t *testing.T, e env) {
|
|||
}
|
||||
|
||||
func TestServerGracefulStopIdempotent(t *testing.T) {
|
||||
defer leakCheck(t)()
|
||||
defer leakcheck.Check(t)
|
||||
for _, e := range listTestEnv() {
|
||||
if e.name == "handler-tls" {
|
||||
continue
|
||||
|
|
@ -729,7 +729,7 @@ func testServerGracefulStopIdempotent(t *testing.T, e env) {
|
|||
}
|
||||
|
||||
func TestServerGoAway(t *testing.T) {
|
||||
defer leakCheck(t)()
|
||||
defer leakcheck.Check(t)
|
||||
for _, e := range listTestEnv() {
|
||||
if e.name == "handler-tls" {
|
||||
continue
|
||||
|
|
@ -773,7 +773,7 @@ func testServerGoAway(t *testing.T, e env) {
|
|||
}
|
||||
|
||||
func TestServerGoAwayPendingRPC(t *testing.T) {
|
||||
defer leakCheck(t)()
|
||||
defer leakcheck.Check(t)
|
||||
for _, e := range listTestEnv() {
|
||||
if e.name == "handler-tls" {
|
||||
continue
|
||||
|
|
@ -845,7 +845,7 @@ func testServerGoAwayPendingRPC(t *testing.T, e env) {
|
|||
}
|
||||
|
||||
func TestServerMultipleGoAwayPendingRPC(t *testing.T) {
|
||||
defer leakCheck(t)()
|
||||
defer leakcheck.Check(t)
|
||||
for _, e := range listTestEnv() {
|
||||
if e.name == "handler-tls" {
|
||||
continue
|
||||
|
|
@ -933,7 +933,7 @@ func testServerMultipleGoAwayPendingRPC(t *testing.T, e env) {
|
|||
}
|
||||
|
||||
func TestConcurrentClientConnCloseAndServerGoAway(t *testing.T) {
|
||||
defer leakCheck(t)()
|
||||
defer leakcheck.Check(t)
|
||||
for _, e := range listTestEnv() {
|
||||
if e.name == "handler-tls" {
|
||||
continue
|
||||
|
|
@ -971,7 +971,7 @@ func testConcurrentClientConnCloseAndServerGoAway(t *testing.T, e env) {
|
|||
}
|
||||
|
||||
func TestConcurrentServerStopAndGoAway(t *testing.T) {
|
||||
defer leakCheck(t)()
|
||||
defer leakcheck.Check(t)
|
||||
for _, e := range listTestEnv() {
|
||||
if e.name == "handler-tls" {
|
||||
continue
|
||||
|
|
@ -1041,7 +1041,7 @@ func testConcurrentServerStopAndGoAway(t *testing.T, e env) {
|
|||
}
|
||||
|
||||
func TestClientConnCloseAfterGoAwayWithActiveStream(t *testing.T) {
|
||||
defer leakCheck(t)()
|
||||
defer leakcheck.Check(t)
|
||||
for _, e := range listTestEnv() {
|
||||
if e.name == "handler-tls" {
|
||||
continue
|
||||
|
|
@ -1076,7 +1076,7 @@ func testClientConnCloseAfterGoAwayWithActiveStream(t *testing.T, e env) {
|
|||
}
|
||||
|
||||
func TestFailFast(t *testing.T) {
|
||||
defer leakCheck(t)()
|
||||
defer leakcheck.Check(t)
|
||||
for _, e := range listTestEnv() {
|
||||
testFailFast(t, e)
|
||||
}
|
||||
|
|
@ -1150,7 +1150,7 @@ func newDuration(b time.Duration) (a *time.Duration) {
|
|||
}
|
||||
|
||||
func TestServiceConfigGetMethodConfig(t *testing.T) {
|
||||
defer leakCheck(t)()
|
||||
defer leakcheck.Check(t)
|
||||
for _, e := range listTestEnv() {
|
||||
testGetMethodConfig(t, e)
|
||||
}
|
||||
|
|
@ -1201,7 +1201,7 @@ func testGetMethodConfig(t *testing.T, e env) {
|
|||
}
|
||||
|
||||
func TestServiceConfigWaitForReady(t *testing.T) {
|
||||
defer leakCheck(t)()
|
||||
defer leakcheck.Check(t)
|
||||
for _, e := range listTestEnv() {
|
||||
testServiceConfigWaitForReady(t, e)
|
||||
}
|
||||
|
|
@ -1265,7 +1265,7 @@ func testServiceConfigWaitForReady(t *testing.T, e env) {
|
|||
}
|
||||
|
||||
func TestServiceConfigTimeout(t *testing.T) {
|
||||
defer leakCheck(t)()
|
||||
defer leakcheck.Check(t)
|
||||
for _, e := range listTestEnv() {
|
||||
testServiceConfigTimeout(t, e)
|
||||
}
|
||||
|
|
@ -1337,7 +1337,7 @@ func testServiceConfigTimeout(t *testing.T, e env) {
|
|||
}
|
||||
|
||||
func TestServiceConfigMaxMsgSize(t *testing.T) {
|
||||
defer leakCheck(t)()
|
||||
defer leakcheck.Check(t)
|
||||
for _, e := range listTestEnv() {
|
||||
testServiceConfigMaxMsgSize(t, e)
|
||||
}
|
||||
|
|
@ -1555,7 +1555,7 @@ func testServiceConfigMaxMsgSize(t *testing.T, e env) {
|
|||
}
|
||||
|
||||
func TestMaxMsgSizeClientDefault(t *testing.T) {
|
||||
defer leakCheck(t)()
|
||||
defer leakcheck.Check(t)
|
||||
for _, e := range listTestEnv() {
|
||||
testMaxMsgSizeClientDefault(t, e)
|
||||
}
|
||||
|
|
@ -1616,7 +1616,7 @@ func testMaxMsgSizeClientDefault(t *testing.T, e env) {
|
|||
}
|
||||
|
||||
func TestMaxMsgSizeClientAPI(t *testing.T) {
|
||||
defer leakCheck(t)()
|
||||
defer leakcheck.Check(t)
|
||||
for _, e := range listTestEnv() {
|
||||
testMaxMsgSizeClientAPI(t, e)
|
||||
}
|
||||
|
|
@ -1704,7 +1704,7 @@ func testMaxMsgSizeClientAPI(t *testing.T, e env) {
|
|||
}
|
||||
|
||||
func TestMaxMsgSizeServerAPI(t *testing.T) {
|
||||
defer leakCheck(t)()
|
||||
defer leakcheck.Check(t)
|
||||
for _, e := range listTestEnv() {
|
||||
testMaxMsgSizeServerAPI(t, e)
|
||||
}
|
||||
|
|
@ -1793,7 +1793,7 @@ func testMaxMsgSizeServerAPI(t *testing.T, e env) {
|
|||
}
|
||||
|
||||
func TestTap(t *testing.T) {
|
||||
defer leakCheck(t)()
|
||||
defer leakcheck.Check(t)
|
||||
for _, e := range listTestEnv() {
|
||||
if e.name == "handler-tls" {
|
||||
continue
|
||||
|
|
@ -1865,7 +1865,7 @@ func healthCheck(d time.Duration, cc *grpc.ClientConn, serviceName string) (*hea
|
|||
}
|
||||
|
||||
func TestHealthCheckOnSuccess(t *testing.T) {
|
||||
defer leakCheck(t)()
|
||||
defer leakcheck.Check(t)
|
||||
for _, e := range listTestEnv() {
|
||||
testHealthCheckOnSuccess(t, e)
|
||||
}
|
||||
|
|
@ -1886,14 +1886,14 @@ func testHealthCheckOnSuccess(t *testing.T, e env) {
|
|||
}
|
||||
|
||||
func TestHealthCheckOnFailure(t *testing.T) {
|
||||
defer leakCheck(t)()
|
||||
defer leakcheck.Check(t)
|
||||
for _, e := range listTestEnv() {
|
||||
testHealthCheckOnFailure(t, e)
|
||||
}
|
||||
}
|
||||
|
||||
func testHealthCheckOnFailure(t *testing.T, e env) {
|
||||
defer leakCheck(t)()
|
||||
defer leakcheck.Check(t)
|
||||
te := newTest(t, e)
|
||||
te.declareLogNoise(
|
||||
"Failed to dial ",
|
||||
|
|
@ -1914,7 +1914,7 @@ func testHealthCheckOnFailure(t *testing.T, e env) {
|
|||
}
|
||||
|
||||
func TestHealthCheckOff(t *testing.T) {
|
||||
defer leakCheck(t)()
|
||||
defer leakcheck.Check(t)
|
||||
for _, e := range listTestEnv() {
|
||||
// TODO(bradfitz): Temporarily skip this env due to #619.
|
||||
if e.name == "handler-tls" {
|
||||
|
|
@ -1935,7 +1935,7 @@ func testHealthCheckOff(t *testing.T, e env) {
|
|||
}
|
||||
|
||||
func TestUnknownHandler(t *testing.T) {
|
||||
defer leakCheck(t)()
|
||||
defer leakcheck.Check(t)
|
||||
// An example unknownHandler that returns a different code and a different method, making sure that we do not
|
||||
// expose what methods are implemented to a client that is not authenticated.
|
||||
unknownHandler := func(srv interface{}, stream grpc.ServerStream) error {
|
||||
|
|
@ -1962,7 +1962,7 @@ func testUnknownHandler(t *testing.T, e env, unknownHandler grpc.StreamHandler)
|
|||
}
|
||||
|
||||
func TestHealthCheckServingStatus(t *testing.T) {
|
||||
defer leakCheck(t)()
|
||||
defer leakcheck.Check(t)
|
||||
for _, e := range listTestEnv() {
|
||||
testHealthCheckServingStatus(t, e)
|
||||
}
|
||||
|
|
@ -2007,7 +2007,7 @@ func testHealthCheckServingStatus(t *testing.T, e env) {
|
|||
}
|
||||
|
||||
func TestErrorChanNoIO(t *testing.T) {
|
||||
defer leakCheck(t)()
|
||||
defer leakcheck.Check(t)
|
||||
for _, e := range listTestEnv() {
|
||||
testErrorChanNoIO(t, e)
|
||||
}
|
||||
|
|
@ -2025,7 +2025,7 @@ func testErrorChanNoIO(t *testing.T, e env) {
|
|||
}
|
||||
|
||||
func TestEmptyUnaryWithUserAgent(t *testing.T) {
|
||||
defer leakCheck(t)()
|
||||
defer leakcheck.Check(t)
|
||||
for _, e := range listTestEnv() {
|
||||
testEmptyUnaryWithUserAgent(t, e)
|
||||
}
|
||||
|
|
@ -2052,7 +2052,7 @@ func testEmptyUnaryWithUserAgent(t *testing.T, e env) {
|
|||
}
|
||||
|
||||
func TestFailedEmptyUnary(t *testing.T) {
|
||||
defer leakCheck(t)()
|
||||
defer leakcheck.Check(t)
|
||||
for _, e := range listTestEnv() {
|
||||
if e.name == "handler-tls" {
|
||||
// This test covers status details, but
|
||||
|
|
@ -2078,7 +2078,7 @@ func testFailedEmptyUnary(t *testing.T, e env) {
|
|||
}
|
||||
|
||||
func TestLargeUnary(t *testing.T) {
|
||||
defer leakCheck(t)()
|
||||
defer leakcheck.Check(t)
|
||||
for _, e := range listTestEnv() {
|
||||
testLargeUnary(t, e)
|
||||
}
|
||||
|
|
@ -2116,7 +2116,7 @@ func testLargeUnary(t *testing.T, e env) {
|
|||
|
||||
// Test backward-compatability API for setting msg size limit.
|
||||
func TestExceedMsgLimit(t *testing.T) {
|
||||
defer leakCheck(t)()
|
||||
defer leakcheck.Check(t)
|
||||
for _, e := range listTestEnv() {
|
||||
testExceedMsgLimit(t, e)
|
||||
}
|
||||
|
|
@ -2202,7 +2202,7 @@ func testExceedMsgLimit(t *testing.T, e env) {
|
|||
}
|
||||
|
||||
func TestPeerClientSide(t *testing.T) {
|
||||
defer leakCheck(t)()
|
||||
defer leakcheck.Check(t)
|
||||
for _, e := range listTestEnv() {
|
||||
testPeerClientSide(t, e)
|
||||
}
|
||||
|
|
@ -2242,7 +2242,7 @@ func testPeerClientSide(t *testing.T, e env) {
|
|||
// doesn't cause a segmentation fault.
|
||||
// issue#1141 https://github.com/grpc/grpc-go/issues/1141
|
||||
func TestPeerNegative(t *testing.T) {
|
||||
defer leakCheck(t)()
|
||||
defer leakcheck.Check(t)
|
||||
for _, e := range listTestEnv() {
|
||||
testPeerNegative(t, e)
|
||||
}
|
||||
|
|
@ -2262,7 +2262,7 @@ func testPeerNegative(t *testing.T, e env) {
|
|||
}
|
||||
|
||||
func TestPeerFailedRPC(t *testing.T) {
|
||||
defer leakCheck(t)()
|
||||
defer leakcheck.Check(t)
|
||||
for _, e := range listTestEnv() {
|
||||
testPeerFailedRPC(t, e)
|
||||
}
|
||||
|
|
@ -2318,7 +2318,7 @@ func testPeerFailedRPC(t *testing.T, e env) {
|
|||
}
|
||||
|
||||
func TestMetadataUnaryRPC(t *testing.T) {
|
||||
defer leakCheck(t)()
|
||||
defer leakcheck.Check(t)
|
||||
for _, e := range listTestEnv() {
|
||||
testMetadataUnaryRPC(t, e)
|
||||
}
|
||||
|
|
@ -2363,7 +2363,7 @@ func testMetadataUnaryRPC(t *testing.T, e env) {
|
|||
}
|
||||
|
||||
func TestMultipleSetTrailerUnaryRPC(t *testing.T) {
|
||||
defer leakCheck(t)()
|
||||
defer leakcheck.Check(t)
|
||||
for _, e := range listTestEnv() {
|
||||
testMultipleSetTrailerUnaryRPC(t, e)
|
||||
}
|
||||
|
|
@ -2401,7 +2401,7 @@ func testMultipleSetTrailerUnaryRPC(t *testing.T, e env) {
|
|||
}
|
||||
|
||||
func TestMultipleSetTrailerStreamingRPC(t *testing.T) {
|
||||
defer leakCheck(t)()
|
||||
defer leakcheck.Check(t)
|
||||
for _, e := range listTestEnv() {
|
||||
testMultipleSetTrailerStreamingRPC(t, e)
|
||||
}
|
||||
|
|
@ -2433,7 +2433,7 @@ func testMultipleSetTrailerStreamingRPC(t *testing.T, e env) {
|
|||
}
|
||||
|
||||
func TestSetAndSendHeaderUnaryRPC(t *testing.T) {
|
||||
defer leakCheck(t)()
|
||||
defer leakcheck.Check(t)
|
||||
for _, e := range listTestEnv() {
|
||||
if e.name == "handler-tls" {
|
||||
continue
|
||||
|
|
@ -2476,7 +2476,7 @@ func testSetAndSendHeaderUnaryRPC(t *testing.T, e env) {
|
|||
}
|
||||
|
||||
func TestMultipleSetHeaderUnaryRPC(t *testing.T) {
|
||||
defer leakCheck(t)()
|
||||
defer leakcheck.Check(t)
|
||||
for _, e := range listTestEnv() {
|
||||
if e.name == "handler-tls" {
|
||||
continue
|
||||
|
|
@ -2520,7 +2520,7 @@ func testMultipleSetHeaderUnaryRPC(t *testing.T, e env) {
|
|||
}
|
||||
|
||||
func TestMultipleSetHeaderUnaryRPCError(t *testing.T) {
|
||||
defer leakCheck(t)()
|
||||
defer leakcheck.Check(t)
|
||||
for _, e := range listTestEnv() {
|
||||
if e.name == "handler-tls" {
|
||||
continue
|
||||
|
|
@ -2563,7 +2563,7 @@ func testMultipleSetHeaderUnaryRPCError(t *testing.T, e env) {
|
|||
}
|
||||
|
||||
func TestSetAndSendHeaderStreamingRPC(t *testing.T) {
|
||||
defer leakCheck(t)()
|
||||
defer leakcheck.Check(t)
|
||||
for _, e := range listTestEnv() {
|
||||
if e.name == "handler-tls" {
|
||||
continue
|
||||
|
|
@ -2607,7 +2607,7 @@ func testSetAndSendHeaderStreamingRPC(t *testing.T, e env) {
|
|||
}
|
||||
|
||||
func TestMultipleSetHeaderStreamingRPC(t *testing.T) {
|
||||
defer leakCheck(t)()
|
||||
defer leakcheck.Check(t)
|
||||
for _, e := range listTestEnv() {
|
||||
if e.name == "handler-tls" {
|
||||
continue
|
||||
|
|
@ -2671,7 +2671,7 @@ func testMultipleSetHeaderStreamingRPC(t *testing.T, e env) {
|
|||
}
|
||||
|
||||
func TestMultipleSetHeaderStreamingRPCError(t *testing.T) {
|
||||
defer leakCheck(t)()
|
||||
defer leakcheck.Check(t)
|
||||
for _, e := range listTestEnv() {
|
||||
if e.name == "handler-tls" {
|
||||
continue
|
||||
|
|
@ -2734,7 +2734,7 @@ func testMultipleSetHeaderStreamingRPCError(t *testing.T, e env) {
|
|||
// TestMalformedHTTP2Metedata verfies the returned error when the client
|
||||
// sends an illegal metadata.
|
||||
func TestMalformedHTTP2Metadata(t *testing.T) {
|
||||
defer leakCheck(t)()
|
||||
defer leakcheck.Check(t)
|
||||
for _, e := range listTestEnv() {
|
||||
if e.name == "handler-tls" {
|
||||
// Failed with "server stops accepting new RPCs".
|
||||
|
|
@ -2797,7 +2797,7 @@ func performOneRPC(t *testing.T, tc testpb.TestServiceClient, wg *sync.WaitGroup
|
|||
}
|
||||
|
||||
func TestRetry(t *testing.T) {
|
||||
defer leakCheck(t)()
|
||||
defer leakcheck.Check(t)
|
||||
for _, e := range listTestEnv() {
|
||||
if e.name == "handler-tls" {
|
||||
// In race mode, with go1.6, the test never returns with handler_server.
|
||||
|
|
@ -2853,7 +2853,7 @@ func testRetry(t *testing.T, e env) {
|
|||
}
|
||||
|
||||
func TestRPCTimeout(t *testing.T) {
|
||||
defer leakCheck(t)()
|
||||
defer leakcheck.Check(t)
|
||||
for _, e := range listTestEnv() {
|
||||
testRPCTimeout(t, e)
|
||||
}
|
||||
|
|
@ -2891,7 +2891,7 @@ func testRPCTimeout(t *testing.T, e env) {
|
|||
}
|
||||
|
||||
func TestCancel(t *testing.T) {
|
||||
defer leakCheck(t)()
|
||||
defer leakcheck.Check(t)
|
||||
for _, e := range listTestEnv() {
|
||||
testCancel(t, e)
|
||||
}
|
||||
|
|
@ -2928,7 +2928,7 @@ func testCancel(t *testing.T, e env) {
|
|||
}
|
||||
|
||||
func TestCancelNoIO(t *testing.T) {
|
||||
defer leakCheck(t)()
|
||||
defer leakcheck.Check(t)
|
||||
for _, e := range listTestEnv() {
|
||||
testCancelNoIO(t, e)
|
||||
}
|
||||
|
|
@ -3000,7 +3000,7 @@ var (
|
|||
)
|
||||
|
||||
func TestNoService(t *testing.T) {
|
||||
defer leakCheck(t)()
|
||||
defer leakcheck.Check(t)
|
||||
for _, e := range listTestEnv() {
|
||||
testNoService(t, e)
|
||||
}
|
||||
|
|
@ -3024,7 +3024,7 @@ func testNoService(t *testing.T, e env) {
|
|||
}
|
||||
|
||||
func TestPingPong(t *testing.T) {
|
||||
defer leakCheck(t)()
|
||||
defer leakcheck.Check(t)
|
||||
for _, e := range listTestEnv() {
|
||||
testPingPong(t, e)
|
||||
}
|
||||
|
|
@ -3084,7 +3084,7 @@ func testPingPong(t *testing.T, e env) {
|
|||
}
|
||||
|
||||
func TestMetadataStreamingRPC(t *testing.T) {
|
||||
defer leakCheck(t)()
|
||||
defer leakcheck.Check(t)
|
||||
for _, e := range listTestEnv() {
|
||||
testMetadataStreamingRPC(t, e)
|
||||
}
|
||||
|
|
@ -3160,7 +3160,7 @@ func testMetadataStreamingRPC(t *testing.T, e env) {
|
|||
}
|
||||
|
||||
func TestServerStreaming(t *testing.T) {
|
||||
defer leakCheck(t)()
|
||||
defer leakcheck.Check(t)
|
||||
for _, e := range listTestEnv() {
|
||||
testServerStreaming(t, e)
|
||||
}
|
||||
|
|
@ -3215,7 +3215,7 @@ func testServerStreaming(t *testing.T, e env) {
|
|||
}
|
||||
|
||||
func TestFailedServerStreaming(t *testing.T) {
|
||||
defer leakCheck(t)()
|
||||
defer leakcheck.Check(t)
|
||||
for _, e := range listTestEnv() {
|
||||
testFailedServerStreaming(t, e)
|
||||
}
|
||||
|
|
@ -3272,7 +3272,7 @@ func (s concurrentSendServer) StreamingOutputCall(args *testpb.StreamingOutputCa
|
|||
|
||||
// Tests doing a bunch of concurrent streaming output calls.
|
||||
func TestServerStreamingConcurrent(t *testing.T) {
|
||||
defer leakCheck(t)()
|
||||
defer leakcheck.Check(t)
|
||||
for _, e := range listTestEnv() {
|
||||
testServerStreamingConcurrent(t, e)
|
||||
}
|
||||
|
|
@ -3352,7 +3352,7 @@ func generatePayloadSizes() [][]int {
|
|||
}
|
||||
|
||||
func TestClientStreaming(t *testing.T) {
|
||||
defer leakCheck(t)()
|
||||
defer leakcheck.Check(t)
|
||||
for _, s := range generatePayloadSizes() {
|
||||
for _, e := range listTestEnv() {
|
||||
testClientStreaming(t, e, s)
|
||||
|
|
@ -3398,7 +3398,7 @@ func testClientStreaming(t *testing.T, e env, sizes []int) {
|
|||
}
|
||||
|
||||
func TestClientStreamingError(t *testing.T) {
|
||||
defer leakCheck(t)()
|
||||
defer leakcheck.Check(t)
|
||||
for _, e := range listTestEnv() {
|
||||
if e.name == "handler-tls" {
|
||||
continue
|
||||
|
|
@ -3441,7 +3441,7 @@ func testClientStreamingError(t *testing.T, e env) {
|
|||
}
|
||||
|
||||
func TestExceedMaxStreamsLimit(t *testing.T) {
|
||||
defer leakCheck(t)()
|
||||
defer leakcheck.Check(t)
|
||||
for _, e := range listTestEnv() {
|
||||
testExceedMaxStreamsLimit(t, e)
|
||||
}
|
||||
|
|
@ -3484,7 +3484,7 @@ func testExceedMaxStreamsLimit(t *testing.T, e env) {
|
|||
const defaultMaxStreamsClient = 100
|
||||
|
||||
func TestExceedDefaultMaxStreamsLimit(t *testing.T) {
|
||||
defer leakCheck(t)()
|
||||
defer leakcheck.Check(t)
|
||||
for _, e := range listTestEnv() {
|
||||
if e.name == "handler-tls" {
|
||||
// The default max stream limit in handler_server is not 100?
|
||||
|
|
@ -3528,7 +3528,7 @@ func testExceedDefaultMaxStreamsLimit(t *testing.T, e env) {
|
|||
}
|
||||
|
||||
func TestStreamsQuotaRecovery(t *testing.T) {
|
||||
defer leakCheck(t)()
|
||||
defer leakcheck.Check(t)
|
||||
for _, e := range listTestEnv() {
|
||||
testStreamsQuotaRecovery(t, e)
|
||||
}
|
||||
|
|
@ -3592,7 +3592,7 @@ func testStreamsQuotaRecovery(t *testing.T, e env) {
|
|||
}
|
||||
|
||||
func TestCompressServerHasNoSupport(t *testing.T) {
|
||||
defer leakCheck(t)()
|
||||
defer leakcheck.Check(t)
|
||||
for _, e := range listTestEnv() {
|
||||
testCompressServerHasNoSupport(t, e)
|
||||
}
|
||||
|
|
@ -3648,7 +3648,7 @@ func testCompressServerHasNoSupport(t *testing.T, e env) {
|
|||
}
|
||||
|
||||
func TestCompressOK(t *testing.T) {
|
||||
defer leakCheck(t)()
|
||||
defer leakcheck.Check(t)
|
||||
for _, e := range listTestEnv() {
|
||||
testCompressOK(t, e)
|
||||
}
|
||||
|
|
@ -3708,7 +3708,7 @@ func testCompressOK(t *testing.T, e env) {
|
|||
}
|
||||
|
||||
func TestUnaryClientInterceptor(t *testing.T) {
|
||||
defer leakCheck(t)()
|
||||
defer leakcheck.Check(t)
|
||||
for _, e := range listTestEnv() {
|
||||
testUnaryClientInterceptor(t, e)
|
||||
}
|
||||
|
|
@ -3736,7 +3736,7 @@ func testUnaryClientInterceptor(t *testing.T, e env) {
|
|||
}
|
||||
|
||||
func TestStreamClientInterceptor(t *testing.T) {
|
||||
defer leakCheck(t)()
|
||||
defer leakcheck.Check(t)
|
||||
for _, e := range listTestEnv() {
|
||||
testStreamClientInterceptor(t, e)
|
||||
}
|
||||
|
|
@ -3777,7 +3777,7 @@ func testStreamClientInterceptor(t *testing.T, e env) {
|
|||
}
|
||||
|
||||
func TestUnaryServerInterceptor(t *testing.T) {
|
||||
defer leakCheck(t)()
|
||||
defer leakcheck.Check(t)
|
||||
for _, e := range listTestEnv() {
|
||||
testUnaryServerInterceptor(t, e)
|
||||
}
|
||||
|
|
@ -3800,7 +3800,7 @@ func testUnaryServerInterceptor(t *testing.T, e env) {
|
|||
}
|
||||
|
||||
func TestStreamServerInterceptor(t *testing.T) {
|
||||
defer leakCheck(t)()
|
||||
defer leakcheck.Check(t)
|
||||
for _, e := range listTestEnv() {
|
||||
// TODO(bradfitz): Temporarily skip this env due to #619.
|
||||
if e.name == "handler-tls" {
|
||||
|
|
@ -3877,7 +3877,7 @@ func (s *funcServer) StreamingInputCall(stream testpb.TestService_StreamingInput
|
|||
}
|
||||
|
||||
func TestClientRequestBodyErrorUnexpectedEOF(t *testing.T) {
|
||||
defer leakCheck(t)()
|
||||
defer leakcheck.Check(t)
|
||||
for _, e := range listTestEnv() {
|
||||
testClientRequestBodyErrorUnexpectedEOF(t, e)
|
||||
}
|
||||
|
|
@ -3901,7 +3901,7 @@ func testClientRequestBodyErrorUnexpectedEOF(t *testing.T, e env) {
|
|||
}
|
||||
|
||||
func TestClientRequestBodyErrorCloseAfterLength(t *testing.T) {
|
||||
defer leakCheck(t)()
|
||||
defer leakcheck.Check(t)
|
||||
for _, e := range listTestEnv() {
|
||||
testClientRequestBodyErrorCloseAfterLength(t, e)
|
||||
}
|
||||
|
|
@ -3926,7 +3926,7 @@ func testClientRequestBodyErrorCloseAfterLength(t *testing.T, e env) {
|
|||
}
|
||||
|
||||
func TestClientRequestBodyErrorCancel(t *testing.T) {
|
||||
defer leakCheck(t)()
|
||||
defer leakcheck.Check(t)
|
||||
for _, e := range listTestEnv() {
|
||||
testClientRequestBodyErrorCancel(t, e)
|
||||
}
|
||||
|
|
@ -3963,7 +3963,7 @@ func testClientRequestBodyErrorCancel(t *testing.T, e env) {
|
|||
}
|
||||
|
||||
func TestClientRequestBodyErrorCancelStreamingInput(t *testing.T) {
|
||||
defer leakCheck(t)()
|
||||
defer leakcheck.Check(t)
|
||||
for _, e := range listTestEnv() {
|
||||
testClientRequestBodyErrorCancelStreamingInput(t, e)
|
||||
}
|
||||
|
|
@ -4167,7 +4167,7 @@ func TestFlowControlLogicalRace(t *testing.T) {
|
|||
// Test for a regression of https://github.com/grpc/grpc-go/issues/632,
|
||||
// and other flow control bugs.
|
||||
|
||||
defer leakCheck(t)()
|
||||
defer leakcheck.Check(t)
|
||||
|
||||
const (
|
||||
itemCount = 100
|
||||
|
|
@ -4274,78 +4274,6 @@ func (s *flowControlLogicalRaceServer) StreamingOutputCall(req *testpb.Streaming
|
|||
return nil
|
||||
}
|
||||
|
||||
// interestingGoroutines returns all goroutines we care about for the purpose
|
||||
// of leak checking. It excludes testing or runtime ones.
|
||||
func interestingGoroutines() (gs []string) {
|
||||
buf := make([]byte, 2<<20)
|
||||
buf = buf[:runtime.Stack(buf, true)]
|
||||
for _, g := range strings.Split(string(buf), "\n\n") {
|
||||
sl := strings.SplitN(g, "\n", 2)
|
||||
if len(sl) != 2 {
|
||||
continue
|
||||
}
|
||||
stack := strings.TrimSpace(sl[1])
|
||||
if strings.HasPrefix(stack, "testing.RunTests") {
|
||||
continue
|
||||
}
|
||||
|
||||
if stack == "" ||
|
||||
strings.Contains(stack, "testing.Main(") ||
|
||||
strings.Contains(stack, "testing.tRunner(") ||
|
||||
strings.Contains(stack, "testing.(*M).") ||
|
||||
strings.Contains(stack, "runtime.goexit") ||
|
||||
strings.Contains(stack, "created by runtime.gc") ||
|
||||
strings.Contains(stack, "created by runtime/trace.Start") ||
|
||||
strings.Contains(stack, "created by google3/base/go/log.init") ||
|
||||
strings.Contains(stack, "interestingGoroutines") ||
|
||||
strings.Contains(stack, "runtime.MHeap_Scavenger") ||
|
||||
strings.Contains(stack, "signal.signal_recv") ||
|
||||
strings.Contains(stack, "sigterm.handler") ||
|
||||
strings.Contains(stack, "runtime_mcall") ||
|
||||
strings.Contains(stack, "(*loggingT).flushDaemon") ||
|
||||
strings.Contains(stack, "goroutine in C code") {
|
||||
continue
|
||||
}
|
||||
gs = append(gs, g)
|
||||
}
|
||||
sort.Strings(gs)
|
||||
return
|
||||
}
|
||||
|
||||
// leakCheck snapshots the currently-running goroutines and returns a
|
||||
// function to be run at the end of tests to see whether any
|
||||
// goroutines leaked.
|
||||
func leakCheck(t testing.TB) func() {
|
||||
orig := map[string]bool{}
|
||||
for _, g := range interestingGoroutines() {
|
||||
orig[g] = true
|
||||
}
|
||||
return func() {
|
||||
// Loop, waiting for goroutines to shut down.
|
||||
// Wait up to 10 seconds, but finish as quickly as possible.
|
||||
deadline := time.Now().Add(10 * time.Second)
|
||||
for {
|
||||
var leaked []string
|
||||
for _, g := range interestingGoroutines() {
|
||||
if !orig[g] {
|
||||
leaked = append(leaked, g)
|
||||
}
|
||||
}
|
||||
if len(leaked) == 0 {
|
||||
return
|
||||
}
|
||||
if time.Now().Before(deadline) {
|
||||
time.Sleep(50 * time.Millisecond)
|
||||
continue
|
||||
}
|
||||
for _, g := range leaked {
|
||||
t.Errorf("Leaked goroutine: %v", g)
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type lockingWriter struct {
|
||||
mu sync.Mutex
|
||||
w io.Writer
|
||||
|
|
@ -4735,7 +4663,7 @@ func max(a, b int32) int32 {
|
|||
}
|
||||
|
||||
func TestConfigurableWindowSizeWithLargeWindow(t *testing.T) {
|
||||
defer leakCheck(t)()
|
||||
defer leakcheck.Check(t)
|
||||
wc := windowSizeConfig{
|
||||
serverStream: 8 * 1024 * 1024,
|
||||
serverConn: 12 * 1024 * 1024,
|
||||
|
|
@ -4748,7 +4676,7 @@ func TestConfigurableWindowSizeWithLargeWindow(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestConfigurableWindowSizeWithSmallWindow(t *testing.T) {
|
||||
defer leakCheck(t)()
|
||||
defer leakcheck.Check(t)
|
||||
wc := windowSizeConfig{
|
||||
serverStream: 1,
|
||||
serverConn: 1,
|
||||
|
|
@ -4843,7 +4771,7 @@ func authHandle(ctx context.Context, info *tap.Info) (context.Context, error) {
|
|||
}
|
||||
|
||||
func TestPerRPCCredentialsViaDialOptions(t *testing.T) {
|
||||
defer leakCheck(t)()
|
||||
defer leakcheck.Check(t)
|
||||
for _, e := range listTestEnv() {
|
||||
testPerRPCCredentialsViaDialOptions(t, e)
|
||||
}
|
||||
|
|
@ -4864,7 +4792,7 @@ func testPerRPCCredentialsViaDialOptions(t *testing.T, e env) {
|
|||
}
|
||||
|
||||
func TestPerRPCCredentialsViaCallOptions(t *testing.T) {
|
||||
defer leakCheck(t)()
|
||||
defer leakcheck.Check(t)
|
||||
for _, e := range listTestEnv() {
|
||||
testPerRPCCredentialsViaCallOptions(t, e)
|
||||
}
|
||||
|
|
@ -4884,7 +4812,7 @@ func testPerRPCCredentialsViaCallOptions(t *testing.T, e env) {
|
|||
}
|
||||
|
||||
func TestPerRPCCredentialsViaDialOptionsAndCallOptions(t *testing.T) {
|
||||
defer leakCheck(t)()
|
||||
defer leakcheck.Check(t)
|
||||
for _, e := range listTestEnv() {
|
||||
testPerRPCCredentialsViaDialOptionsAndCallOptions(t, e)
|
||||
}
|
||||
|
|
@ -4925,7 +4853,7 @@ func testPerRPCCredentialsViaDialOptionsAndCallOptions(t *testing.T, e env) {
|
|||
}
|
||||
|
||||
func TestWaitForReadyConnection(t *testing.T) {
|
||||
defer leakCheck(t)()
|
||||
defer leakcheck.Check(t)
|
||||
for _, e := range listTestEnv() {
|
||||
testWaitForReadyConnection(t, e)
|
||||
}
|
||||
|
|
@ -4977,7 +4905,7 @@ func (c *errCodec) String() string {
|
|||
}
|
||||
|
||||
func TestEncodeDoesntPanic(t *testing.T) {
|
||||
defer leakCheck(t)()
|
||||
defer leakcheck.Check(t)
|
||||
for _, e := range listTestEnv() {
|
||||
testEncodeDoesntPanic(t, e)
|
||||
}
|
||||
|
|
@ -5001,7 +4929,7 @@ func testEncodeDoesntPanic(t *testing.T, e env) {
|
|||
}
|
||||
|
||||
func TestSvrWriteStatusEarlyWrite(t *testing.T) {
|
||||
defer leakCheck(t)()
|
||||
defer leakcheck.Check(t)
|
||||
for _, e := range listTestEnv() {
|
||||
testSvrWriteStatusEarlyWrite(t, e)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
*
|
||||
* Copyright 2017 gRPC authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
// Package leakcheck contains functions to check leaked goroutines.
|
||||
//
|
||||
// Call "defer leakcheck.Check(t)" at the beginning of tests.
|
||||
package leakcheck
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// interestingGoroutines returns all goroutines we care about for the purpose of
|
||||
// leak checking. It excludes testing or runtime ones.
|
||||
func interestingGoroutines() (gs []string) {
|
||||
buf := make([]byte, 2<<20)
|
||||
buf = buf[:runtime.Stack(buf, true)]
|
||||
for _, g := range strings.Split(string(buf), "\n\n") {
|
||||
sl := strings.SplitN(g, "\n", 2)
|
||||
if len(sl) != 2 {
|
||||
continue
|
||||
}
|
||||
stack := strings.TrimSpace(sl[1])
|
||||
if strings.HasPrefix(stack, "testing.RunTests") {
|
||||
continue
|
||||
}
|
||||
|
||||
if stack == "" ||
|
||||
strings.Contains(stack, "testing.Main(") ||
|
||||
strings.Contains(stack, "testing.tRunner(") ||
|
||||
strings.Contains(stack, "testing.(*M).") ||
|
||||
strings.Contains(stack, "runtime.goexit") ||
|
||||
strings.Contains(stack, "created by runtime.gc") ||
|
||||
strings.Contains(stack, "created by runtime/trace.Start") ||
|
||||
strings.Contains(stack, "created by google3/base/go/log.init") ||
|
||||
strings.Contains(stack, "interestingGoroutines") ||
|
||||
strings.Contains(stack, "runtime.MHeap_Scavenger") ||
|
||||
strings.Contains(stack, "signal.signal_recv") ||
|
||||
strings.Contains(stack, "sigterm.handler") ||
|
||||
strings.Contains(stack, "runtime_mcall") ||
|
||||
strings.Contains(stack, "(*loggingT).flushDaemon") ||
|
||||
strings.Contains(stack, "goroutine in C code") {
|
||||
continue
|
||||
}
|
||||
gs = append(gs, g)
|
||||
}
|
||||
sort.Strings(gs)
|
||||
return
|
||||
}
|
||||
|
||||
// Errorfer is the interface that wraps the Errorf method. It's a subset of
|
||||
// testing.TB to make it easy to use Check.
|
||||
type Errorfer interface {
|
||||
Errorf(format string, args ...interface{})
|
||||
}
|
||||
|
||||
func check(efer Errorfer, timeout time.Duration) {
|
||||
// Loop, waiting for goroutines to shut down.
|
||||
// Wait up to timeout, but finish as quickly as possible.
|
||||
deadline := time.Now().Add(timeout)
|
||||
var leaked []string
|
||||
for time.Now().Before(deadline) {
|
||||
if leaked = interestingGoroutines(); len(leaked) == 0 {
|
||||
return
|
||||
}
|
||||
time.Sleep(50 * time.Millisecond)
|
||||
}
|
||||
for _, g := range leaked {
|
||||
efer.Errorf("Leaked goroutine: %v", g)
|
||||
}
|
||||
}
|
||||
|
||||
// Check looks at the currently-running goroutines and checks if there are any
|
||||
// interestring (created by gRPC) goroutines leaked. It waits up to 10 seconds
|
||||
// in the error cases.
|
||||
func Check(efer Errorfer) {
|
||||
check(efer, 10*time.Second)
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
*
|
||||
* Copyright 2017 gRPC authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package leakcheck
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
type testErrorfer struct {
|
||||
errorCount int
|
||||
}
|
||||
|
||||
func (e *testErrorfer) Errorf(format string, args ...interface{}) {
|
||||
e.errorCount++
|
||||
}
|
||||
|
||||
func TestCheck(t *testing.T) {
|
||||
const leakCount = 3
|
||||
for i := 0; i < leakCount; i++ {
|
||||
go func() { time.Sleep(2 * time.Second) }()
|
||||
}
|
||||
if ig := interestingGoroutines(); len(ig) == 0 {
|
||||
t.Error("blah")
|
||||
}
|
||||
e := &testErrorfer{}
|
||||
check(e, time.Second)
|
||||
if e.errorCount != leakCount {
|
||||
t.Errorf("check found %v leaks, want %v leaks", e.errorCount, leakCount)
|
||||
}
|
||||
check(t, 3*time.Second)
|
||||
}
|
||||
Loading…
Reference in New Issue