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"
|
"os"
|
||||||
"reflect"
|
"reflect"
|
||||||
"runtime"
|
"runtime"
|
||||||
"sort"
|
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
@ -59,6 +58,7 @@ import (
|
||||||
"google.golang.org/grpc/status"
|
"google.golang.org/grpc/status"
|
||||||
"google.golang.org/grpc/tap"
|
"google.golang.org/grpc/tap"
|
||||||
testpb "google.golang.org/grpc/test/grpc_testing"
|
testpb "google.golang.org/grpc/test/grpc_testing"
|
||||||
|
"google.golang.org/grpc/test/leakcheck"
|
||||||
"google.golang.org/grpc/testdata"
|
"google.golang.org/grpc/testdata"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -673,7 +673,7 @@ func (te *test) withServerTester(fn func(st *serverTester)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTimeoutOnDeadServer(t *testing.T) {
|
func TestTimeoutOnDeadServer(t *testing.T) {
|
||||||
defer leakCheck(t)()
|
defer leakcheck.Check(t)
|
||||||
for _, e := range listTestEnv() {
|
for _, e := range listTestEnv() {
|
||||||
testTimeoutOnDeadServer(t, e)
|
testTimeoutOnDeadServer(t, e)
|
||||||
}
|
}
|
||||||
|
|
@ -708,7 +708,7 @@ func testTimeoutOnDeadServer(t *testing.T, e env) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestServerGracefulStopIdempotent(t *testing.T) {
|
func TestServerGracefulStopIdempotent(t *testing.T) {
|
||||||
defer leakCheck(t)()
|
defer leakcheck.Check(t)
|
||||||
for _, e := range listTestEnv() {
|
for _, e := range listTestEnv() {
|
||||||
if e.name == "handler-tls" {
|
if e.name == "handler-tls" {
|
||||||
continue
|
continue
|
||||||
|
|
@ -729,7 +729,7 @@ func testServerGracefulStopIdempotent(t *testing.T, e env) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestServerGoAway(t *testing.T) {
|
func TestServerGoAway(t *testing.T) {
|
||||||
defer leakCheck(t)()
|
defer leakcheck.Check(t)
|
||||||
for _, e := range listTestEnv() {
|
for _, e := range listTestEnv() {
|
||||||
if e.name == "handler-tls" {
|
if e.name == "handler-tls" {
|
||||||
continue
|
continue
|
||||||
|
|
@ -773,7 +773,7 @@ func testServerGoAway(t *testing.T, e env) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestServerGoAwayPendingRPC(t *testing.T) {
|
func TestServerGoAwayPendingRPC(t *testing.T) {
|
||||||
defer leakCheck(t)()
|
defer leakcheck.Check(t)
|
||||||
for _, e := range listTestEnv() {
|
for _, e := range listTestEnv() {
|
||||||
if e.name == "handler-tls" {
|
if e.name == "handler-tls" {
|
||||||
continue
|
continue
|
||||||
|
|
@ -845,7 +845,7 @@ func testServerGoAwayPendingRPC(t *testing.T, e env) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestServerMultipleGoAwayPendingRPC(t *testing.T) {
|
func TestServerMultipleGoAwayPendingRPC(t *testing.T) {
|
||||||
defer leakCheck(t)()
|
defer leakcheck.Check(t)
|
||||||
for _, e := range listTestEnv() {
|
for _, e := range listTestEnv() {
|
||||||
if e.name == "handler-tls" {
|
if e.name == "handler-tls" {
|
||||||
continue
|
continue
|
||||||
|
|
@ -933,7 +933,7 @@ func testServerMultipleGoAwayPendingRPC(t *testing.T, e env) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestConcurrentClientConnCloseAndServerGoAway(t *testing.T) {
|
func TestConcurrentClientConnCloseAndServerGoAway(t *testing.T) {
|
||||||
defer leakCheck(t)()
|
defer leakcheck.Check(t)
|
||||||
for _, e := range listTestEnv() {
|
for _, e := range listTestEnv() {
|
||||||
if e.name == "handler-tls" {
|
if e.name == "handler-tls" {
|
||||||
continue
|
continue
|
||||||
|
|
@ -971,7 +971,7 @@ func testConcurrentClientConnCloseAndServerGoAway(t *testing.T, e env) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestConcurrentServerStopAndGoAway(t *testing.T) {
|
func TestConcurrentServerStopAndGoAway(t *testing.T) {
|
||||||
defer leakCheck(t)()
|
defer leakcheck.Check(t)
|
||||||
for _, e := range listTestEnv() {
|
for _, e := range listTestEnv() {
|
||||||
if e.name == "handler-tls" {
|
if e.name == "handler-tls" {
|
||||||
continue
|
continue
|
||||||
|
|
@ -1041,7 +1041,7 @@ func testConcurrentServerStopAndGoAway(t *testing.T, e env) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestClientConnCloseAfterGoAwayWithActiveStream(t *testing.T) {
|
func TestClientConnCloseAfterGoAwayWithActiveStream(t *testing.T) {
|
||||||
defer leakCheck(t)()
|
defer leakcheck.Check(t)
|
||||||
for _, e := range listTestEnv() {
|
for _, e := range listTestEnv() {
|
||||||
if e.name == "handler-tls" {
|
if e.name == "handler-tls" {
|
||||||
continue
|
continue
|
||||||
|
|
@ -1076,7 +1076,7 @@ func testClientConnCloseAfterGoAwayWithActiveStream(t *testing.T, e env) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFailFast(t *testing.T) {
|
func TestFailFast(t *testing.T) {
|
||||||
defer leakCheck(t)()
|
defer leakcheck.Check(t)
|
||||||
for _, e := range listTestEnv() {
|
for _, e := range listTestEnv() {
|
||||||
testFailFast(t, e)
|
testFailFast(t, e)
|
||||||
}
|
}
|
||||||
|
|
@ -1150,7 +1150,7 @@ func newDuration(b time.Duration) (a *time.Duration) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestServiceConfigGetMethodConfig(t *testing.T) {
|
func TestServiceConfigGetMethodConfig(t *testing.T) {
|
||||||
defer leakCheck(t)()
|
defer leakcheck.Check(t)
|
||||||
for _, e := range listTestEnv() {
|
for _, e := range listTestEnv() {
|
||||||
testGetMethodConfig(t, e)
|
testGetMethodConfig(t, e)
|
||||||
}
|
}
|
||||||
|
|
@ -1201,7 +1201,7 @@ func testGetMethodConfig(t *testing.T, e env) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestServiceConfigWaitForReady(t *testing.T) {
|
func TestServiceConfigWaitForReady(t *testing.T) {
|
||||||
defer leakCheck(t)()
|
defer leakcheck.Check(t)
|
||||||
for _, e := range listTestEnv() {
|
for _, e := range listTestEnv() {
|
||||||
testServiceConfigWaitForReady(t, e)
|
testServiceConfigWaitForReady(t, e)
|
||||||
}
|
}
|
||||||
|
|
@ -1265,7 +1265,7 @@ func testServiceConfigWaitForReady(t *testing.T, e env) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestServiceConfigTimeout(t *testing.T) {
|
func TestServiceConfigTimeout(t *testing.T) {
|
||||||
defer leakCheck(t)()
|
defer leakcheck.Check(t)
|
||||||
for _, e := range listTestEnv() {
|
for _, e := range listTestEnv() {
|
||||||
testServiceConfigTimeout(t, e)
|
testServiceConfigTimeout(t, e)
|
||||||
}
|
}
|
||||||
|
|
@ -1337,7 +1337,7 @@ func testServiceConfigTimeout(t *testing.T, e env) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestServiceConfigMaxMsgSize(t *testing.T) {
|
func TestServiceConfigMaxMsgSize(t *testing.T) {
|
||||||
defer leakCheck(t)()
|
defer leakcheck.Check(t)
|
||||||
for _, e := range listTestEnv() {
|
for _, e := range listTestEnv() {
|
||||||
testServiceConfigMaxMsgSize(t, e)
|
testServiceConfigMaxMsgSize(t, e)
|
||||||
}
|
}
|
||||||
|
|
@ -1555,7 +1555,7 @@ func testServiceConfigMaxMsgSize(t *testing.T, e env) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMaxMsgSizeClientDefault(t *testing.T) {
|
func TestMaxMsgSizeClientDefault(t *testing.T) {
|
||||||
defer leakCheck(t)()
|
defer leakcheck.Check(t)
|
||||||
for _, e := range listTestEnv() {
|
for _, e := range listTestEnv() {
|
||||||
testMaxMsgSizeClientDefault(t, e)
|
testMaxMsgSizeClientDefault(t, e)
|
||||||
}
|
}
|
||||||
|
|
@ -1616,7 +1616,7 @@ func testMaxMsgSizeClientDefault(t *testing.T, e env) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMaxMsgSizeClientAPI(t *testing.T) {
|
func TestMaxMsgSizeClientAPI(t *testing.T) {
|
||||||
defer leakCheck(t)()
|
defer leakcheck.Check(t)
|
||||||
for _, e := range listTestEnv() {
|
for _, e := range listTestEnv() {
|
||||||
testMaxMsgSizeClientAPI(t, e)
|
testMaxMsgSizeClientAPI(t, e)
|
||||||
}
|
}
|
||||||
|
|
@ -1704,7 +1704,7 @@ func testMaxMsgSizeClientAPI(t *testing.T, e env) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMaxMsgSizeServerAPI(t *testing.T) {
|
func TestMaxMsgSizeServerAPI(t *testing.T) {
|
||||||
defer leakCheck(t)()
|
defer leakcheck.Check(t)
|
||||||
for _, e := range listTestEnv() {
|
for _, e := range listTestEnv() {
|
||||||
testMaxMsgSizeServerAPI(t, e)
|
testMaxMsgSizeServerAPI(t, e)
|
||||||
}
|
}
|
||||||
|
|
@ -1793,7 +1793,7 @@ func testMaxMsgSizeServerAPI(t *testing.T, e env) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTap(t *testing.T) {
|
func TestTap(t *testing.T) {
|
||||||
defer leakCheck(t)()
|
defer leakcheck.Check(t)
|
||||||
for _, e := range listTestEnv() {
|
for _, e := range listTestEnv() {
|
||||||
if e.name == "handler-tls" {
|
if e.name == "handler-tls" {
|
||||||
continue
|
continue
|
||||||
|
|
@ -1865,7 +1865,7 @@ func healthCheck(d time.Duration, cc *grpc.ClientConn, serviceName string) (*hea
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestHealthCheckOnSuccess(t *testing.T) {
|
func TestHealthCheckOnSuccess(t *testing.T) {
|
||||||
defer leakCheck(t)()
|
defer leakcheck.Check(t)
|
||||||
for _, e := range listTestEnv() {
|
for _, e := range listTestEnv() {
|
||||||
testHealthCheckOnSuccess(t, e)
|
testHealthCheckOnSuccess(t, e)
|
||||||
}
|
}
|
||||||
|
|
@ -1886,14 +1886,14 @@ func testHealthCheckOnSuccess(t *testing.T, e env) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestHealthCheckOnFailure(t *testing.T) {
|
func TestHealthCheckOnFailure(t *testing.T) {
|
||||||
defer leakCheck(t)()
|
defer leakcheck.Check(t)
|
||||||
for _, e := range listTestEnv() {
|
for _, e := range listTestEnv() {
|
||||||
testHealthCheckOnFailure(t, e)
|
testHealthCheckOnFailure(t, e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func testHealthCheckOnFailure(t *testing.T, e env) {
|
func testHealthCheckOnFailure(t *testing.T, e env) {
|
||||||
defer leakCheck(t)()
|
defer leakcheck.Check(t)
|
||||||
te := newTest(t, e)
|
te := newTest(t, e)
|
||||||
te.declareLogNoise(
|
te.declareLogNoise(
|
||||||
"Failed to dial ",
|
"Failed to dial ",
|
||||||
|
|
@ -1914,7 +1914,7 @@ func testHealthCheckOnFailure(t *testing.T, e env) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestHealthCheckOff(t *testing.T) {
|
func TestHealthCheckOff(t *testing.T) {
|
||||||
defer leakCheck(t)()
|
defer leakcheck.Check(t)
|
||||||
for _, e := range listTestEnv() {
|
for _, e := range listTestEnv() {
|
||||||
// TODO(bradfitz): Temporarily skip this env due to #619.
|
// TODO(bradfitz): Temporarily skip this env due to #619.
|
||||||
if e.name == "handler-tls" {
|
if e.name == "handler-tls" {
|
||||||
|
|
@ -1935,7 +1935,7 @@ func testHealthCheckOff(t *testing.T, e env) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestUnknownHandler(t *testing.T) {
|
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
|
// 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.
|
// expose what methods are implemented to a client that is not authenticated.
|
||||||
unknownHandler := func(srv interface{}, stream grpc.ServerStream) error {
|
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) {
|
func TestHealthCheckServingStatus(t *testing.T) {
|
||||||
defer leakCheck(t)()
|
defer leakcheck.Check(t)
|
||||||
for _, e := range listTestEnv() {
|
for _, e := range listTestEnv() {
|
||||||
testHealthCheckServingStatus(t, e)
|
testHealthCheckServingStatus(t, e)
|
||||||
}
|
}
|
||||||
|
|
@ -2007,7 +2007,7 @@ func testHealthCheckServingStatus(t *testing.T, e env) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestErrorChanNoIO(t *testing.T) {
|
func TestErrorChanNoIO(t *testing.T) {
|
||||||
defer leakCheck(t)()
|
defer leakcheck.Check(t)
|
||||||
for _, e := range listTestEnv() {
|
for _, e := range listTestEnv() {
|
||||||
testErrorChanNoIO(t, e)
|
testErrorChanNoIO(t, e)
|
||||||
}
|
}
|
||||||
|
|
@ -2025,7 +2025,7 @@ func testErrorChanNoIO(t *testing.T, e env) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestEmptyUnaryWithUserAgent(t *testing.T) {
|
func TestEmptyUnaryWithUserAgent(t *testing.T) {
|
||||||
defer leakCheck(t)()
|
defer leakcheck.Check(t)
|
||||||
for _, e := range listTestEnv() {
|
for _, e := range listTestEnv() {
|
||||||
testEmptyUnaryWithUserAgent(t, e)
|
testEmptyUnaryWithUserAgent(t, e)
|
||||||
}
|
}
|
||||||
|
|
@ -2052,7 +2052,7 @@ func testEmptyUnaryWithUserAgent(t *testing.T, e env) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFailedEmptyUnary(t *testing.T) {
|
func TestFailedEmptyUnary(t *testing.T) {
|
||||||
defer leakCheck(t)()
|
defer leakcheck.Check(t)
|
||||||
for _, e := range listTestEnv() {
|
for _, e := range listTestEnv() {
|
||||||
if e.name == "handler-tls" {
|
if e.name == "handler-tls" {
|
||||||
// This test covers status details, but
|
// This test covers status details, but
|
||||||
|
|
@ -2078,7 +2078,7 @@ func testFailedEmptyUnary(t *testing.T, e env) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestLargeUnary(t *testing.T) {
|
func TestLargeUnary(t *testing.T) {
|
||||||
defer leakCheck(t)()
|
defer leakcheck.Check(t)
|
||||||
for _, e := range listTestEnv() {
|
for _, e := range listTestEnv() {
|
||||||
testLargeUnary(t, e)
|
testLargeUnary(t, e)
|
||||||
}
|
}
|
||||||
|
|
@ -2116,7 +2116,7 @@ func testLargeUnary(t *testing.T, e env) {
|
||||||
|
|
||||||
// Test backward-compatability API for setting msg size limit.
|
// Test backward-compatability API for setting msg size limit.
|
||||||
func TestExceedMsgLimit(t *testing.T) {
|
func TestExceedMsgLimit(t *testing.T) {
|
||||||
defer leakCheck(t)()
|
defer leakcheck.Check(t)
|
||||||
for _, e := range listTestEnv() {
|
for _, e := range listTestEnv() {
|
||||||
testExceedMsgLimit(t, e)
|
testExceedMsgLimit(t, e)
|
||||||
}
|
}
|
||||||
|
|
@ -2202,7 +2202,7 @@ func testExceedMsgLimit(t *testing.T, e env) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPeerClientSide(t *testing.T) {
|
func TestPeerClientSide(t *testing.T) {
|
||||||
defer leakCheck(t)()
|
defer leakcheck.Check(t)
|
||||||
for _, e := range listTestEnv() {
|
for _, e := range listTestEnv() {
|
||||||
testPeerClientSide(t, e)
|
testPeerClientSide(t, e)
|
||||||
}
|
}
|
||||||
|
|
@ -2242,7 +2242,7 @@ func testPeerClientSide(t *testing.T, e env) {
|
||||||
// doesn't cause a segmentation fault.
|
// doesn't cause a segmentation fault.
|
||||||
// issue#1141 https://github.com/grpc/grpc-go/issues/1141
|
// issue#1141 https://github.com/grpc/grpc-go/issues/1141
|
||||||
func TestPeerNegative(t *testing.T) {
|
func TestPeerNegative(t *testing.T) {
|
||||||
defer leakCheck(t)()
|
defer leakcheck.Check(t)
|
||||||
for _, e := range listTestEnv() {
|
for _, e := range listTestEnv() {
|
||||||
testPeerNegative(t, e)
|
testPeerNegative(t, e)
|
||||||
}
|
}
|
||||||
|
|
@ -2262,7 +2262,7 @@ func testPeerNegative(t *testing.T, e env) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPeerFailedRPC(t *testing.T) {
|
func TestPeerFailedRPC(t *testing.T) {
|
||||||
defer leakCheck(t)()
|
defer leakcheck.Check(t)
|
||||||
for _, e := range listTestEnv() {
|
for _, e := range listTestEnv() {
|
||||||
testPeerFailedRPC(t, e)
|
testPeerFailedRPC(t, e)
|
||||||
}
|
}
|
||||||
|
|
@ -2318,7 +2318,7 @@ func testPeerFailedRPC(t *testing.T, e env) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMetadataUnaryRPC(t *testing.T) {
|
func TestMetadataUnaryRPC(t *testing.T) {
|
||||||
defer leakCheck(t)()
|
defer leakcheck.Check(t)
|
||||||
for _, e := range listTestEnv() {
|
for _, e := range listTestEnv() {
|
||||||
testMetadataUnaryRPC(t, e)
|
testMetadataUnaryRPC(t, e)
|
||||||
}
|
}
|
||||||
|
|
@ -2363,7 +2363,7 @@ func testMetadataUnaryRPC(t *testing.T, e env) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMultipleSetTrailerUnaryRPC(t *testing.T) {
|
func TestMultipleSetTrailerUnaryRPC(t *testing.T) {
|
||||||
defer leakCheck(t)()
|
defer leakcheck.Check(t)
|
||||||
for _, e := range listTestEnv() {
|
for _, e := range listTestEnv() {
|
||||||
testMultipleSetTrailerUnaryRPC(t, e)
|
testMultipleSetTrailerUnaryRPC(t, e)
|
||||||
}
|
}
|
||||||
|
|
@ -2401,7 +2401,7 @@ func testMultipleSetTrailerUnaryRPC(t *testing.T, e env) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMultipleSetTrailerStreamingRPC(t *testing.T) {
|
func TestMultipleSetTrailerStreamingRPC(t *testing.T) {
|
||||||
defer leakCheck(t)()
|
defer leakcheck.Check(t)
|
||||||
for _, e := range listTestEnv() {
|
for _, e := range listTestEnv() {
|
||||||
testMultipleSetTrailerStreamingRPC(t, e)
|
testMultipleSetTrailerStreamingRPC(t, e)
|
||||||
}
|
}
|
||||||
|
|
@ -2433,7 +2433,7 @@ func testMultipleSetTrailerStreamingRPC(t *testing.T, e env) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSetAndSendHeaderUnaryRPC(t *testing.T) {
|
func TestSetAndSendHeaderUnaryRPC(t *testing.T) {
|
||||||
defer leakCheck(t)()
|
defer leakcheck.Check(t)
|
||||||
for _, e := range listTestEnv() {
|
for _, e := range listTestEnv() {
|
||||||
if e.name == "handler-tls" {
|
if e.name == "handler-tls" {
|
||||||
continue
|
continue
|
||||||
|
|
@ -2476,7 +2476,7 @@ func testSetAndSendHeaderUnaryRPC(t *testing.T, e env) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMultipleSetHeaderUnaryRPC(t *testing.T) {
|
func TestMultipleSetHeaderUnaryRPC(t *testing.T) {
|
||||||
defer leakCheck(t)()
|
defer leakcheck.Check(t)
|
||||||
for _, e := range listTestEnv() {
|
for _, e := range listTestEnv() {
|
||||||
if e.name == "handler-tls" {
|
if e.name == "handler-tls" {
|
||||||
continue
|
continue
|
||||||
|
|
@ -2520,7 +2520,7 @@ func testMultipleSetHeaderUnaryRPC(t *testing.T, e env) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMultipleSetHeaderUnaryRPCError(t *testing.T) {
|
func TestMultipleSetHeaderUnaryRPCError(t *testing.T) {
|
||||||
defer leakCheck(t)()
|
defer leakcheck.Check(t)
|
||||||
for _, e := range listTestEnv() {
|
for _, e := range listTestEnv() {
|
||||||
if e.name == "handler-tls" {
|
if e.name == "handler-tls" {
|
||||||
continue
|
continue
|
||||||
|
|
@ -2563,7 +2563,7 @@ func testMultipleSetHeaderUnaryRPCError(t *testing.T, e env) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSetAndSendHeaderStreamingRPC(t *testing.T) {
|
func TestSetAndSendHeaderStreamingRPC(t *testing.T) {
|
||||||
defer leakCheck(t)()
|
defer leakcheck.Check(t)
|
||||||
for _, e := range listTestEnv() {
|
for _, e := range listTestEnv() {
|
||||||
if e.name == "handler-tls" {
|
if e.name == "handler-tls" {
|
||||||
continue
|
continue
|
||||||
|
|
@ -2607,7 +2607,7 @@ func testSetAndSendHeaderStreamingRPC(t *testing.T, e env) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMultipleSetHeaderStreamingRPC(t *testing.T) {
|
func TestMultipleSetHeaderStreamingRPC(t *testing.T) {
|
||||||
defer leakCheck(t)()
|
defer leakcheck.Check(t)
|
||||||
for _, e := range listTestEnv() {
|
for _, e := range listTestEnv() {
|
||||||
if e.name == "handler-tls" {
|
if e.name == "handler-tls" {
|
||||||
continue
|
continue
|
||||||
|
|
@ -2671,7 +2671,7 @@ func testMultipleSetHeaderStreamingRPC(t *testing.T, e env) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMultipleSetHeaderStreamingRPCError(t *testing.T) {
|
func TestMultipleSetHeaderStreamingRPCError(t *testing.T) {
|
||||||
defer leakCheck(t)()
|
defer leakcheck.Check(t)
|
||||||
for _, e := range listTestEnv() {
|
for _, e := range listTestEnv() {
|
||||||
if e.name == "handler-tls" {
|
if e.name == "handler-tls" {
|
||||||
continue
|
continue
|
||||||
|
|
@ -2734,7 +2734,7 @@ func testMultipleSetHeaderStreamingRPCError(t *testing.T, e env) {
|
||||||
// TestMalformedHTTP2Metedata verfies the returned error when the client
|
// TestMalformedHTTP2Metedata verfies the returned error when the client
|
||||||
// sends an illegal metadata.
|
// sends an illegal metadata.
|
||||||
func TestMalformedHTTP2Metadata(t *testing.T) {
|
func TestMalformedHTTP2Metadata(t *testing.T) {
|
||||||
defer leakCheck(t)()
|
defer leakcheck.Check(t)
|
||||||
for _, e := range listTestEnv() {
|
for _, e := range listTestEnv() {
|
||||||
if e.name == "handler-tls" {
|
if e.name == "handler-tls" {
|
||||||
// Failed with "server stops accepting new RPCs".
|
// 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) {
|
func TestRetry(t *testing.T) {
|
||||||
defer leakCheck(t)()
|
defer leakcheck.Check(t)
|
||||||
for _, e := range listTestEnv() {
|
for _, e := range listTestEnv() {
|
||||||
if e.name == "handler-tls" {
|
if e.name == "handler-tls" {
|
||||||
// In race mode, with go1.6, the test never returns with handler_server.
|
// 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) {
|
func TestRPCTimeout(t *testing.T) {
|
||||||
defer leakCheck(t)()
|
defer leakcheck.Check(t)
|
||||||
for _, e := range listTestEnv() {
|
for _, e := range listTestEnv() {
|
||||||
testRPCTimeout(t, e)
|
testRPCTimeout(t, e)
|
||||||
}
|
}
|
||||||
|
|
@ -2891,7 +2891,7 @@ func testRPCTimeout(t *testing.T, e env) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCancel(t *testing.T) {
|
func TestCancel(t *testing.T) {
|
||||||
defer leakCheck(t)()
|
defer leakcheck.Check(t)
|
||||||
for _, e := range listTestEnv() {
|
for _, e := range listTestEnv() {
|
||||||
testCancel(t, e)
|
testCancel(t, e)
|
||||||
}
|
}
|
||||||
|
|
@ -2928,7 +2928,7 @@ func testCancel(t *testing.T, e env) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCancelNoIO(t *testing.T) {
|
func TestCancelNoIO(t *testing.T) {
|
||||||
defer leakCheck(t)()
|
defer leakcheck.Check(t)
|
||||||
for _, e := range listTestEnv() {
|
for _, e := range listTestEnv() {
|
||||||
testCancelNoIO(t, e)
|
testCancelNoIO(t, e)
|
||||||
}
|
}
|
||||||
|
|
@ -3000,7 +3000,7 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestNoService(t *testing.T) {
|
func TestNoService(t *testing.T) {
|
||||||
defer leakCheck(t)()
|
defer leakcheck.Check(t)
|
||||||
for _, e := range listTestEnv() {
|
for _, e := range listTestEnv() {
|
||||||
testNoService(t, e)
|
testNoService(t, e)
|
||||||
}
|
}
|
||||||
|
|
@ -3024,7 +3024,7 @@ func testNoService(t *testing.T, e env) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPingPong(t *testing.T) {
|
func TestPingPong(t *testing.T) {
|
||||||
defer leakCheck(t)()
|
defer leakcheck.Check(t)
|
||||||
for _, e := range listTestEnv() {
|
for _, e := range listTestEnv() {
|
||||||
testPingPong(t, e)
|
testPingPong(t, e)
|
||||||
}
|
}
|
||||||
|
|
@ -3084,7 +3084,7 @@ func testPingPong(t *testing.T, e env) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMetadataStreamingRPC(t *testing.T) {
|
func TestMetadataStreamingRPC(t *testing.T) {
|
||||||
defer leakCheck(t)()
|
defer leakcheck.Check(t)
|
||||||
for _, e := range listTestEnv() {
|
for _, e := range listTestEnv() {
|
||||||
testMetadataStreamingRPC(t, e)
|
testMetadataStreamingRPC(t, e)
|
||||||
}
|
}
|
||||||
|
|
@ -3160,7 +3160,7 @@ func testMetadataStreamingRPC(t *testing.T, e env) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestServerStreaming(t *testing.T) {
|
func TestServerStreaming(t *testing.T) {
|
||||||
defer leakCheck(t)()
|
defer leakcheck.Check(t)
|
||||||
for _, e := range listTestEnv() {
|
for _, e := range listTestEnv() {
|
||||||
testServerStreaming(t, e)
|
testServerStreaming(t, e)
|
||||||
}
|
}
|
||||||
|
|
@ -3215,7 +3215,7 @@ func testServerStreaming(t *testing.T, e env) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFailedServerStreaming(t *testing.T) {
|
func TestFailedServerStreaming(t *testing.T) {
|
||||||
defer leakCheck(t)()
|
defer leakcheck.Check(t)
|
||||||
for _, e := range listTestEnv() {
|
for _, e := range listTestEnv() {
|
||||||
testFailedServerStreaming(t, e)
|
testFailedServerStreaming(t, e)
|
||||||
}
|
}
|
||||||
|
|
@ -3272,7 +3272,7 @@ func (s concurrentSendServer) StreamingOutputCall(args *testpb.StreamingOutputCa
|
||||||
|
|
||||||
// Tests doing a bunch of concurrent streaming output calls.
|
// Tests doing a bunch of concurrent streaming output calls.
|
||||||
func TestServerStreamingConcurrent(t *testing.T) {
|
func TestServerStreamingConcurrent(t *testing.T) {
|
||||||
defer leakCheck(t)()
|
defer leakcheck.Check(t)
|
||||||
for _, e := range listTestEnv() {
|
for _, e := range listTestEnv() {
|
||||||
testServerStreamingConcurrent(t, e)
|
testServerStreamingConcurrent(t, e)
|
||||||
}
|
}
|
||||||
|
|
@ -3352,7 +3352,7 @@ func generatePayloadSizes() [][]int {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestClientStreaming(t *testing.T) {
|
func TestClientStreaming(t *testing.T) {
|
||||||
defer leakCheck(t)()
|
defer leakcheck.Check(t)
|
||||||
for _, s := range generatePayloadSizes() {
|
for _, s := range generatePayloadSizes() {
|
||||||
for _, e := range listTestEnv() {
|
for _, e := range listTestEnv() {
|
||||||
testClientStreaming(t, e, s)
|
testClientStreaming(t, e, s)
|
||||||
|
|
@ -3398,7 +3398,7 @@ func testClientStreaming(t *testing.T, e env, sizes []int) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestClientStreamingError(t *testing.T) {
|
func TestClientStreamingError(t *testing.T) {
|
||||||
defer leakCheck(t)()
|
defer leakcheck.Check(t)
|
||||||
for _, e := range listTestEnv() {
|
for _, e := range listTestEnv() {
|
||||||
if e.name == "handler-tls" {
|
if e.name == "handler-tls" {
|
||||||
continue
|
continue
|
||||||
|
|
@ -3441,7 +3441,7 @@ func testClientStreamingError(t *testing.T, e env) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestExceedMaxStreamsLimit(t *testing.T) {
|
func TestExceedMaxStreamsLimit(t *testing.T) {
|
||||||
defer leakCheck(t)()
|
defer leakcheck.Check(t)
|
||||||
for _, e := range listTestEnv() {
|
for _, e := range listTestEnv() {
|
||||||
testExceedMaxStreamsLimit(t, e)
|
testExceedMaxStreamsLimit(t, e)
|
||||||
}
|
}
|
||||||
|
|
@ -3484,7 +3484,7 @@ func testExceedMaxStreamsLimit(t *testing.T, e env) {
|
||||||
const defaultMaxStreamsClient = 100
|
const defaultMaxStreamsClient = 100
|
||||||
|
|
||||||
func TestExceedDefaultMaxStreamsLimit(t *testing.T) {
|
func TestExceedDefaultMaxStreamsLimit(t *testing.T) {
|
||||||
defer leakCheck(t)()
|
defer leakcheck.Check(t)
|
||||||
for _, e := range listTestEnv() {
|
for _, e := range listTestEnv() {
|
||||||
if e.name == "handler-tls" {
|
if e.name == "handler-tls" {
|
||||||
// The default max stream limit in handler_server is not 100?
|
// 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) {
|
func TestStreamsQuotaRecovery(t *testing.T) {
|
||||||
defer leakCheck(t)()
|
defer leakcheck.Check(t)
|
||||||
for _, e := range listTestEnv() {
|
for _, e := range listTestEnv() {
|
||||||
testStreamsQuotaRecovery(t, e)
|
testStreamsQuotaRecovery(t, e)
|
||||||
}
|
}
|
||||||
|
|
@ -3592,7 +3592,7 @@ func testStreamsQuotaRecovery(t *testing.T, e env) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCompressServerHasNoSupport(t *testing.T) {
|
func TestCompressServerHasNoSupport(t *testing.T) {
|
||||||
defer leakCheck(t)()
|
defer leakcheck.Check(t)
|
||||||
for _, e := range listTestEnv() {
|
for _, e := range listTestEnv() {
|
||||||
testCompressServerHasNoSupport(t, e)
|
testCompressServerHasNoSupport(t, e)
|
||||||
}
|
}
|
||||||
|
|
@ -3648,7 +3648,7 @@ func testCompressServerHasNoSupport(t *testing.T, e env) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCompressOK(t *testing.T) {
|
func TestCompressOK(t *testing.T) {
|
||||||
defer leakCheck(t)()
|
defer leakcheck.Check(t)
|
||||||
for _, e := range listTestEnv() {
|
for _, e := range listTestEnv() {
|
||||||
testCompressOK(t, e)
|
testCompressOK(t, e)
|
||||||
}
|
}
|
||||||
|
|
@ -3708,7 +3708,7 @@ func testCompressOK(t *testing.T, e env) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestUnaryClientInterceptor(t *testing.T) {
|
func TestUnaryClientInterceptor(t *testing.T) {
|
||||||
defer leakCheck(t)()
|
defer leakcheck.Check(t)
|
||||||
for _, e := range listTestEnv() {
|
for _, e := range listTestEnv() {
|
||||||
testUnaryClientInterceptor(t, e)
|
testUnaryClientInterceptor(t, e)
|
||||||
}
|
}
|
||||||
|
|
@ -3736,7 +3736,7 @@ func testUnaryClientInterceptor(t *testing.T, e env) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestStreamClientInterceptor(t *testing.T) {
|
func TestStreamClientInterceptor(t *testing.T) {
|
||||||
defer leakCheck(t)()
|
defer leakcheck.Check(t)
|
||||||
for _, e := range listTestEnv() {
|
for _, e := range listTestEnv() {
|
||||||
testStreamClientInterceptor(t, e)
|
testStreamClientInterceptor(t, e)
|
||||||
}
|
}
|
||||||
|
|
@ -3777,7 +3777,7 @@ func testStreamClientInterceptor(t *testing.T, e env) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestUnaryServerInterceptor(t *testing.T) {
|
func TestUnaryServerInterceptor(t *testing.T) {
|
||||||
defer leakCheck(t)()
|
defer leakcheck.Check(t)
|
||||||
for _, e := range listTestEnv() {
|
for _, e := range listTestEnv() {
|
||||||
testUnaryServerInterceptor(t, e)
|
testUnaryServerInterceptor(t, e)
|
||||||
}
|
}
|
||||||
|
|
@ -3800,7 +3800,7 @@ func testUnaryServerInterceptor(t *testing.T, e env) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestStreamServerInterceptor(t *testing.T) {
|
func TestStreamServerInterceptor(t *testing.T) {
|
||||||
defer leakCheck(t)()
|
defer leakcheck.Check(t)
|
||||||
for _, e := range listTestEnv() {
|
for _, e := range listTestEnv() {
|
||||||
// TODO(bradfitz): Temporarily skip this env due to #619.
|
// TODO(bradfitz): Temporarily skip this env due to #619.
|
||||||
if e.name == "handler-tls" {
|
if e.name == "handler-tls" {
|
||||||
|
|
@ -3877,7 +3877,7 @@ func (s *funcServer) StreamingInputCall(stream testpb.TestService_StreamingInput
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestClientRequestBodyErrorUnexpectedEOF(t *testing.T) {
|
func TestClientRequestBodyErrorUnexpectedEOF(t *testing.T) {
|
||||||
defer leakCheck(t)()
|
defer leakcheck.Check(t)
|
||||||
for _, e := range listTestEnv() {
|
for _, e := range listTestEnv() {
|
||||||
testClientRequestBodyErrorUnexpectedEOF(t, e)
|
testClientRequestBodyErrorUnexpectedEOF(t, e)
|
||||||
}
|
}
|
||||||
|
|
@ -3901,7 +3901,7 @@ func testClientRequestBodyErrorUnexpectedEOF(t *testing.T, e env) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestClientRequestBodyErrorCloseAfterLength(t *testing.T) {
|
func TestClientRequestBodyErrorCloseAfterLength(t *testing.T) {
|
||||||
defer leakCheck(t)()
|
defer leakcheck.Check(t)
|
||||||
for _, e := range listTestEnv() {
|
for _, e := range listTestEnv() {
|
||||||
testClientRequestBodyErrorCloseAfterLength(t, e)
|
testClientRequestBodyErrorCloseAfterLength(t, e)
|
||||||
}
|
}
|
||||||
|
|
@ -3926,7 +3926,7 @@ func testClientRequestBodyErrorCloseAfterLength(t *testing.T, e env) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestClientRequestBodyErrorCancel(t *testing.T) {
|
func TestClientRequestBodyErrorCancel(t *testing.T) {
|
||||||
defer leakCheck(t)()
|
defer leakcheck.Check(t)
|
||||||
for _, e := range listTestEnv() {
|
for _, e := range listTestEnv() {
|
||||||
testClientRequestBodyErrorCancel(t, e)
|
testClientRequestBodyErrorCancel(t, e)
|
||||||
}
|
}
|
||||||
|
|
@ -3963,7 +3963,7 @@ func testClientRequestBodyErrorCancel(t *testing.T, e env) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestClientRequestBodyErrorCancelStreamingInput(t *testing.T) {
|
func TestClientRequestBodyErrorCancelStreamingInput(t *testing.T) {
|
||||||
defer leakCheck(t)()
|
defer leakcheck.Check(t)
|
||||||
for _, e := range listTestEnv() {
|
for _, e := range listTestEnv() {
|
||||||
testClientRequestBodyErrorCancelStreamingInput(t, e)
|
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,
|
// Test for a regression of https://github.com/grpc/grpc-go/issues/632,
|
||||||
// and other flow control bugs.
|
// and other flow control bugs.
|
||||||
|
|
||||||
defer leakCheck(t)()
|
defer leakcheck.Check(t)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
itemCount = 100
|
itemCount = 100
|
||||||
|
|
@ -4274,78 +4274,6 @@ func (s *flowControlLogicalRaceServer) StreamingOutputCall(req *testpb.Streaming
|
||||||
return nil
|
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 {
|
type lockingWriter struct {
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
w io.Writer
|
w io.Writer
|
||||||
|
|
@ -4735,7 +4663,7 @@ func max(a, b int32) int32 {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestConfigurableWindowSizeWithLargeWindow(t *testing.T) {
|
func TestConfigurableWindowSizeWithLargeWindow(t *testing.T) {
|
||||||
defer leakCheck(t)()
|
defer leakcheck.Check(t)
|
||||||
wc := windowSizeConfig{
|
wc := windowSizeConfig{
|
||||||
serverStream: 8 * 1024 * 1024,
|
serverStream: 8 * 1024 * 1024,
|
||||||
serverConn: 12 * 1024 * 1024,
|
serverConn: 12 * 1024 * 1024,
|
||||||
|
|
@ -4748,7 +4676,7 @@ func TestConfigurableWindowSizeWithLargeWindow(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestConfigurableWindowSizeWithSmallWindow(t *testing.T) {
|
func TestConfigurableWindowSizeWithSmallWindow(t *testing.T) {
|
||||||
defer leakCheck(t)()
|
defer leakcheck.Check(t)
|
||||||
wc := windowSizeConfig{
|
wc := windowSizeConfig{
|
||||||
serverStream: 1,
|
serverStream: 1,
|
||||||
serverConn: 1,
|
serverConn: 1,
|
||||||
|
|
@ -4843,7 +4771,7 @@ func authHandle(ctx context.Context, info *tap.Info) (context.Context, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPerRPCCredentialsViaDialOptions(t *testing.T) {
|
func TestPerRPCCredentialsViaDialOptions(t *testing.T) {
|
||||||
defer leakCheck(t)()
|
defer leakcheck.Check(t)
|
||||||
for _, e := range listTestEnv() {
|
for _, e := range listTestEnv() {
|
||||||
testPerRPCCredentialsViaDialOptions(t, e)
|
testPerRPCCredentialsViaDialOptions(t, e)
|
||||||
}
|
}
|
||||||
|
|
@ -4864,7 +4792,7 @@ func testPerRPCCredentialsViaDialOptions(t *testing.T, e env) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPerRPCCredentialsViaCallOptions(t *testing.T) {
|
func TestPerRPCCredentialsViaCallOptions(t *testing.T) {
|
||||||
defer leakCheck(t)()
|
defer leakcheck.Check(t)
|
||||||
for _, e := range listTestEnv() {
|
for _, e := range listTestEnv() {
|
||||||
testPerRPCCredentialsViaCallOptions(t, e)
|
testPerRPCCredentialsViaCallOptions(t, e)
|
||||||
}
|
}
|
||||||
|
|
@ -4884,7 +4812,7 @@ func testPerRPCCredentialsViaCallOptions(t *testing.T, e env) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPerRPCCredentialsViaDialOptionsAndCallOptions(t *testing.T) {
|
func TestPerRPCCredentialsViaDialOptionsAndCallOptions(t *testing.T) {
|
||||||
defer leakCheck(t)()
|
defer leakcheck.Check(t)
|
||||||
for _, e := range listTestEnv() {
|
for _, e := range listTestEnv() {
|
||||||
testPerRPCCredentialsViaDialOptionsAndCallOptions(t, e)
|
testPerRPCCredentialsViaDialOptionsAndCallOptions(t, e)
|
||||||
}
|
}
|
||||||
|
|
@ -4925,7 +4853,7 @@ func testPerRPCCredentialsViaDialOptionsAndCallOptions(t *testing.T, e env) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestWaitForReadyConnection(t *testing.T) {
|
func TestWaitForReadyConnection(t *testing.T) {
|
||||||
defer leakCheck(t)()
|
defer leakcheck.Check(t)
|
||||||
for _, e := range listTestEnv() {
|
for _, e := range listTestEnv() {
|
||||||
testWaitForReadyConnection(t, e)
|
testWaitForReadyConnection(t, e)
|
||||||
}
|
}
|
||||||
|
|
@ -4977,7 +4905,7 @@ func (c *errCodec) String() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestEncodeDoesntPanic(t *testing.T) {
|
func TestEncodeDoesntPanic(t *testing.T) {
|
||||||
defer leakCheck(t)()
|
defer leakcheck.Check(t)
|
||||||
for _, e := range listTestEnv() {
|
for _, e := range listTestEnv() {
|
||||||
testEncodeDoesntPanic(t, e)
|
testEncodeDoesntPanic(t, e)
|
||||||
}
|
}
|
||||||
|
|
@ -5001,7 +4929,7 @@ func testEncodeDoesntPanic(t *testing.T, e env) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSvrWriteStatusEarlyWrite(t *testing.T) {
|
func TestSvrWriteStatusEarlyWrite(t *testing.T) {
|
||||||
defer leakCheck(t)()
|
defer leakcheck.Check(t)
|
||||||
for _, e := range listTestEnv() {
|
for _, e := range listTestEnv() {
|
||||||
testSvrWriteStatusEarlyWrite(t, e)
|
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