Fix test race: Atomically access minConnecTimout in testing environment. (#1897)

This commit is contained in:
mmukhi 2018-03-07 10:36:17 -08:00 committed by GitHub
parent 3ae2a613bc
commit 207e2760fd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 25 additions and 6 deletions

View File

@ -45,6 +45,11 @@ import (
"google.golang.org/grpc/transport" "google.golang.org/grpc/transport"
) )
const (
// minimum time to give a connection to complete
minConnectTimeout = 20 * time.Second
)
var ( var (
// ErrClientConnClosing indicates that the operation is illegal because // ErrClientConnClosing indicates that the operation is illegal because
// the ClientConn is closing. // the ClientConn is closing.
@ -60,8 +65,11 @@ var (
errConnUnavailable = errors.New("grpc: the connection is unavailable") errConnUnavailable = errors.New("grpc: the connection is unavailable")
// errBalancerClosed indicates that the balancer is closed. // errBalancerClosed indicates that the balancer is closed.
errBalancerClosed = errors.New("grpc: balancer is closed") errBalancerClosed = errors.New("grpc: balancer is closed")
// minimum time to give a connection to complete // We use an accessor so that minConnectTimeout can be
minConnectTimeout = 20 * time.Second // atomically read and updated while testing.
getMinConnectTimeout = func() time.Duration {
return minConnectTimeout
}
) )
// The following errors are returned from Dial and DialContext // The following errors are returned from Dial and DialContext
@ -1055,7 +1063,7 @@ func (ac *addrConn) resetTransport() error {
// connection. // connection.
backoffFor := ac.dopts.bs.backoff(connectRetryNum) // time.Duration. backoffFor := ac.dopts.bs.backoff(connectRetryNum) // time.Duration.
// This will be the duration that dial gets to finish. // This will be the duration that dial gets to finish.
dialDuration := minConnectTimeout dialDuration := getMinConnectTimeout()
if backoffFor > dialDuration { if backoffFor > dialDuration {
// Give dial more time as we keep failing to connect. // Give dial more time as we keep failing to connect.
dialDuration = backoffFor dialDuration = backoffFor

View File

@ -39,6 +39,16 @@ import (
"google.golang.org/grpc/testdata" "google.golang.org/grpc/testdata"
) )
var (
mutableMinConnectTimeout = time.Second * 20
)
func init() {
getMinConnectTimeout = func() time.Duration {
return time.Duration(atomic.LoadInt64((*int64)(&mutableMinConnectTimeout)))
}
}
func assertState(wantState connectivity.State, cc *ClientConn) (connectivity.State, bool) { func assertState(wantState connectivity.State, cc *ClientConn) (connectivity.State, bool) {
ctx, cancel := context.WithTimeout(context.Background(), time.Second) ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel() defer cancel()
@ -169,13 +179,14 @@ func TestDialWaitsForServerSettings(t *testing.T) {
} }
func TestCloseConnectionWhenServerPrefaceNotReceived(t *testing.T) { func TestCloseConnectionWhenServerPrefaceNotReceived(t *testing.T) {
mctBkp := minConnectTimeout mctBkp := getMinConnectTimeout()
// Call this only after transportMonitor goroutine has ended. // Call this only after transportMonitor goroutine has ended.
defer func() { defer func() {
minConnectTimeout = mctBkp atomic.StoreInt64((*int64)(&mutableMinConnectTimeout), int64(mctBkp))
}() }()
defer leakcheck.Check(t) defer leakcheck.Check(t)
minConnectTimeout = time.Millisecond * 500 atomic.StoreInt64((*int64)(&mutableMinConnectTimeout), int64(time.Millisecond)*500)
lis, err := net.Listen("tcp", "localhost:0") lis, err := net.Listen("tcp", "localhost:0")
if err != nil { if err != nil {
t.Fatalf("Error while listening. Err: %v", err) t.Fatalf("Error while listening. Err: %v", err)