gitee.com/ks-custle/core-gm@v0.0.0-20230922171213-b83bdd97b62c/grpc/clientconn_test.go (about)

     1  /*
     2   *
     3   * Copyright 2014 gRPC authors.
     4   *
     5   * Licensed under the Apache License, Version 2.0 (the "License");
     6   * you may not use this file except in compliance with the License.
     7   * You may obtain a copy of the License at
     8   *
     9   *     http://www.apache.org/licenses/LICENSE-2.0
    10   *
    11   * Unless required by applicable law or agreed to in writing, software
    12   * distributed under the License is distributed on an "AS IS" BASIS,
    13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14   * See the License for the specific language governing permissions and
    15   * limitations under the License.
    16   *
    17   */
    18  
    19  package grpc
    20  
    21  import (
    22  	"context"
    23  	"errors"
    24  	"fmt"
    25  	"math"
    26  	"net"
    27  	"strings"
    28  	"sync/atomic"
    29  	"testing"
    30  	"time"
    31  
    32  	"gitee.com/ks-custle/core-gm/grpc/backoff"
    33  	"gitee.com/ks-custle/core-gm/grpc/connectivity"
    34  	"gitee.com/ks-custle/core-gm/grpc/credentials"
    35  	internalbackoff "gitee.com/ks-custle/core-gm/grpc/internal/backoff"
    36  	"gitee.com/ks-custle/core-gm/grpc/internal/grpcsync"
    37  	"gitee.com/ks-custle/core-gm/grpc/internal/transport"
    38  	"gitee.com/ks-custle/core-gm/grpc/keepalive"
    39  	"gitee.com/ks-custle/core-gm/grpc/resolver"
    40  	"gitee.com/ks-custle/core-gm/grpc/resolver/manual"
    41  	"gitee.com/ks-custle/core-gm/grpc/testdata"
    42  	"gitee.com/ks-custle/core-gm/net/http2"
    43  )
    44  
    45  func (s) TestDialWithTimeout(t *testing.T) {
    46  	lis, err := net.Listen("tcp", "localhost:0")
    47  	if err != nil {
    48  		t.Fatalf("Error while listening. Err: %v", err)
    49  	}
    50  	defer lis.Close()
    51  	lisAddr := resolver.Address{Addr: lis.Addr().String()}
    52  	lisDone := make(chan struct{})
    53  	dialDone := make(chan struct{})
    54  	// 1st listener accepts the connection and then does nothing
    55  	go func() {
    56  		defer close(lisDone)
    57  		conn, err := lis.Accept()
    58  		if err != nil {
    59  			t.Errorf("Error while accepting. Err: %v", err)
    60  			return
    61  		}
    62  		framer := http2.NewFramer(conn, conn)
    63  		if err := framer.WriteSettings(http2.Setting{}); err != nil {
    64  			t.Errorf("Error while writing settings. Err: %v", err)
    65  			return
    66  		}
    67  		<-dialDone // Close conn only after dial returns.
    68  	}()
    69  
    70  	r := manual.NewBuilderWithScheme("whatever")
    71  	r.InitialState(resolver.State{Addresses: []resolver.Address{lisAddr}})
    72  	client, err := Dial(r.Scheme()+":///test.server", WithInsecure(), WithResolvers(r), WithTimeout(5*time.Second))
    73  	close(dialDone)
    74  	if err != nil {
    75  		t.Fatalf("Dial failed. Err: %v", err)
    76  	}
    77  	defer client.Close()
    78  	timeout := time.After(1 * time.Second)
    79  	select {
    80  	case <-timeout:
    81  		t.Fatal("timed out waiting for server to finish")
    82  	case <-lisDone:
    83  	}
    84  }
    85  
    86  func (s) TestDialWithMultipleBackendsNotSendingServerPreface(t *testing.T) {
    87  	lis1, err := net.Listen("tcp", "localhost:0")
    88  	if err != nil {
    89  		t.Fatalf("Error while listening. Err: %v", err)
    90  	}
    91  	defer lis1.Close()
    92  	lis1Addr := resolver.Address{Addr: lis1.Addr().String()}
    93  	lis1Done := make(chan struct{})
    94  	// 1st listener accepts the connection and immediately closes it.
    95  	go func() {
    96  		defer close(lis1Done)
    97  		conn, err := lis1.Accept()
    98  		if err != nil {
    99  			t.Errorf("Error while accepting. Err: %v", err)
   100  			return
   101  		}
   102  		conn.Close()
   103  	}()
   104  
   105  	lis2, err := net.Listen("tcp", "localhost:0")
   106  	if err != nil {
   107  		t.Fatalf("Error while listening. Err: %v", err)
   108  	}
   109  	defer lis2.Close()
   110  	lis2Done := make(chan struct{})
   111  	lis2Addr := resolver.Address{Addr: lis2.Addr().String()}
   112  	// 2nd listener should get a connection attempt since the first one failed.
   113  	go func() {
   114  		defer close(lis2Done)
   115  		_, err := lis2.Accept() // Closing the client will clean up this conn.
   116  		if err != nil {
   117  			t.Errorf("Error while accepting. Err: %v", err)
   118  			return
   119  		}
   120  	}()
   121  
   122  	r := manual.NewBuilderWithScheme("whatever")
   123  	r.InitialState(resolver.State{Addresses: []resolver.Address{lis1Addr, lis2Addr}})
   124  	client, err := Dial(r.Scheme()+":///test.server", WithInsecure(), WithResolvers(r))
   125  	if err != nil {
   126  		t.Fatalf("Dial failed. Err: %v", err)
   127  	}
   128  	defer client.Close()
   129  	timeout := time.After(5 * time.Second)
   130  	select {
   131  	case <-timeout:
   132  		t.Fatal("timed out waiting for server 1 to finish")
   133  	case <-lis1Done:
   134  	}
   135  	select {
   136  	case <-timeout:
   137  		t.Fatal("timed out waiting for server 2 to finish")
   138  	case <-lis2Done:
   139  	}
   140  }
   141  
   142  func (s) TestDialWaitsForServerSettings(t *testing.T) {
   143  	lis, err := net.Listen("tcp", "localhost:0")
   144  	if err != nil {
   145  		t.Fatalf("Error while listening. Err: %v", err)
   146  	}
   147  	defer lis.Close()
   148  	done := make(chan struct{})
   149  	sent := make(chan struct{})
   150  	dialDone := make(chan struct{})
   151  	go func() { // Launch the server.
   152  		defer func() {
   153  			close(done)
   154  		}()
   155  		conn, err := lis.Accept()
   156  		if err != nil {
   157  			t.Errorf("Error while accepting. Err: %v", err)
   158  			return
   159  		}
   160  		defer conn.Close()
   161  		// Sleep for a little bit to make sure that Dial on client
   162  		// side blocks until settings are received.
   163  		time.Sleep(100 * time.Millisecond)
   164  		framer := http2.NewFramer(conn, conn)
   165  		close(sent)
   166  		if err := framer.WriteSettings(http2.Setting{}); err != nil {
   167  			t.Errorf("Error while writing settings. Err: %v", err)
   168  			return
   169  		}
   170  		<-dialDone // Close conn only after dial returns.
   171  	}()
   172  	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
   173  	defer cancel()
   174  	client, err := DialContext(ctx, lis.Addr().String(), WithInsecure(), WithBlock())
   175  	close(dialDone)
   176  	if err != nil {
   177  		t.Fatalf("Error while dialing. Err: %v", err)
   178  	}
   179  	defer client.Close()
   180  	select {
   181  	case <-sent:
   182  	default:
   183  		t.Fatalf("Dial returned before server settings were sent")
   184  	}
   185  	<-done
   186  }
   187  
   188  func (s) TestDialWaitsForServerSettingsAndFails(t *testing.T) {
   189  	lis, err := net.Listen("tcp", "localhost:0")
   190  	if err != nil {
   191  		t.Fatalf("Error while listening. Err: %v", err)
   192  	}
   193  	done := make(chan struct{})
   194  	numConns := 0
   195  	go func() { // Launch the server.
   196  		defer func() {
   197  			close(done)
   198  		}()
   199  		for {
   200  			conn, err := lis.Accept()
   201  			if err != nil {
   202  				break
   203  			}
   204  			numConns++
   205  			defer conn.Close()
   206  		}
   207  	}()
   208  	ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
   209  	defer cancel()
   210  	client, err := DialContext(ctx,
   211  		lis.Addr().String(),
   212  		WithInsecure(),
   213  		WithReturnConnectionError(),
   214  		withBackoff(noBackoff{}),
   215  		withMinConnectDeadline(func() time.Duration { return time.Second / 4 }))
   216  	lis.Close()
   217  	if err == nil {
   218  		client.Close()
   219  		t.Fatalf("Unexpected success (err=nil) while dialing")
   220  	}
   221  	expectedMsg := "server preface"
   222  	if !strings.Contains(err.Error(), context.DeadlineExceeded.Error()) || !strings.Contains(err.Error(), expectedMsg) {
   223  		t.Fatalf("DialContext(_) = %v; want a message that includes both %q and %q", err, context.DeadlineExceeded.Error(), expectedMsg)
   224  	}
   225  	<-done
   226  	if numConns < 2 {
   227  		t.Fatalf("dial attempts: %v; want > 1", numConns)
   228  	}
   229  }
   230  
   231  // 1. Client connects to a server that doesn't send preface.
   232  // 2. After minConnectTimeout(500 ms here), client disconnects and retries.
   233  // 3. The new server sends its preface.
   234  // 4. Client doesn't kill the connection this time.
   235  func (s) TestCloseConnectionWhenServerPrefaceNotReceived(t *testing.T) {
   236  	lis, err := net.Listen("tcp", "localhost:0")
   237  	if err != nil {
   238  		t.Fatalf("Error while listening. Err: %v", err)
   239  	}
   240  	var (
   241  		conn2 net.Conn
   242  		over  uint32
   243  	)
   244  	defer func() {
   245  		lis.Close()
   246  		// conn2 shouldn't be closed until the client has
   247  		// observed a successful test.
   248  		if conn2 != nil {
   249  			conn2.Close()
   250  		}
   251  	}()
   252  	done := make(chan struct{})
   253  	accepted := make(chan struct{})
   254  	go func() { // Launch the server.
   255  		defer close(done)
   256  		conn1, err := lis.Accept()
   257  		if err != nil {
   258  			t.Errorf("Error while accepting. Err: %v", err)
   259  			return
   260  		}
   261  		defer conn1.Close()
   262  		// Don't send server settings and the client should close the connection and try again.
   263  		conn2, err = lis.Accept() // Accept a reconnection request from client.
   264  		if err != nil {
   265  			t.Errorf("Error while accepting. Err: %v", err)
   266  			return
   267  		}
   268  		close(accepted)
   269  		framer := http2.NewFramer(conn2, conn2)
   270  		if err = framer.WriteSettings(http2.Setting{}); err != nil {
   271  			t.Errorf("Error while writing settings. Err: %v", err)
   272  			return
   273  		}
   274  		b := make([]byte, 8)
   275  		for {
   276  			_, err = conn2.Read(b)
   277  			if err == nil {
   278  				continue
   279  			}
   280  			if atomic.LoadUint32(&over) == 1 {
   281  				// The connection stayed alive for the timer.
   282  				// Success.
   283  				return
   284  			}
   285  			t.Errorf("Unexpected error while reading. Err: %v, want timeout error", err)
   286  			break
   287  		}
   288  	}()
   289  	client, err := Dial(lis.Addr().String(), WithInsecure(), withMinConnectDeadline(func() time.Duration { return time.Millisecond * 500 }))
   290  	if err != nil {
   291  		t.Fatalf("Error while dialing. Err: %v", err)
   292  	}
   293  
   294  	go stayConnected(client)
   295  
   296  	// wait for connection to be accepted on the server.
   297  	timer := time.NewTimer(time.Second * 10)
   298  	select {
   299  	case <-accepted:
   300  	case <-timer.C:
   301  		t.Fatalf("Client didn't make another connection request in time.")
   302  	}
   303  	// Make sure the connection stays alive for sometime.
   304  	time.Sleep(time.Second)
   305  	atomic.StoreUint32(&over, 1)
   306  	client.Close()
   307  	<-done
   308  }
   309  
   310  func (s) TestBackoffWhenNoServerPrefaceReceived(t *testing.T) {
   311  	lis, err := net.Listen("tcp", "localhost:0")
   312  	if err != nil {
   313  		t.Fatalf("Error while listening. Err: %v", err)
   314  	}
   315  	defer lis.Close()
   316  	done := make(chan struct{})
   317  	go func() { // Launch the server.
   318  		defer close(done)
   319  		conn, err := lis.Accept() // Accept the connection only to close it immediately.
   320  		if err != nil {
   321  			t.Errorf("Error while accepting. Err: %v", err)
   322  			return
   323  		}
   324  		prevAt := time.Now()
   325  		conn.Close()
   326  		var prevDuration time.Duration
   327  		// Make sure the retry attempts are backed off properly.
   328  		for i := 0; i < 3; i++ {
   329  			conn, err := lis.Accept()
   330  			if err != nil {
   331  				t.Errorf("Error while accepting. Err: %v", err)
   332  				return
   333  			}
   334  			meow := time.Now()
   335  			conn.Close()
   336  			dr := meow.Sub(prevAt)
   337  			if dr <= prevDuration {
   338  				t.Errorf("Client backoff did not increase with retries. Previous duration: %v, current duration: %v", prevDuration, dr)
   339  				return
   340  			}
   341  			prevDuration = dr
   342  			prevAt = meow
   343  		}
   344  	}()
   345  	cc, err := Dial(lis.Addr().String(), WithInsecure())
   346  	if err != nil {
   347  		t.Fatalf("Error while dialing. Err: %v", err)
   348  	}
   349  	defer cc.Close()
   350  	go stayConnected(cc)
   351  	<-done
   352  }
   353  
   354  func (s) TestWithTimeout(t *testing.T) {
   355  	conn, err := Dial("passthrough:///Non-Existent.Server:80", WithTimeout(time.Millisecond), WithBlock(), WithInsecure())
   356  	if err == nil {
   357  		conn.Close()
   358  	}
   359  	if err != context.DeadlineExceeded {
   360  		t.Fatalf("Dial(_, _) = %v, %v, want %v", conn, err, context.DeadlineExceeded)
   361  	}
   362  }
   363  
   364  func (s) TestWithTransportCredentialsTLS(t *testing.T) {
   365  	ctx, cancel := context.WithTimeout(context.Background(), time.Millisecond)
   366  	defer cancel()
   367  	creds, err := credentials.NewClientTLSFromFile(testdata.Path("x509/server_ca_cert.pem"), "x.test.example.com")
   368  	if err != nil {
   369  		t.Fatalf("Failed to create credentials %v", err)
   370  	}
   371  	conn, err := DialContext(ctx, "passthrough:///Non-Existent.Server:80", WithTransportCredentials(creds), WithBlock())
   372  	if err == nil {
   373  		conn.Close()
   374  	}
   375  	if err != context.DeadlineExceeded {
   376  		t.Fatalf("Dial(_, _) = %v, %v, want %v", conn, err, context.DeadlineExceeded)
   377  	}
   378  }
   379  
   380  // When creating a transport configured with n addresses, only calculate the
   381  // backoff once per "round" of attempts instead of once per address (n times
   382  // per "round" of attempts).
   383  func (s) TestDial_OneBackoffPerRetryGroup(t *testing.T) {
   384  	var attempts uint32
   385  	getMinConnectTimeout := func() time.Duration {
   386  		if atomic.AddUint32(&attempts, 1) == 1 {
   387  			// Once all addresses are exhausted, hang around and wait for the
   388  			// client.Close to happen rather than re-starting a new round of
   389  			// attempts.
   390  			return time.Hour
   391  		}
   392  		t.Error("only one attempt backoff calculation, but got more")
   393  		return 0
   394  	}
   395  
   396  	ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
   397  	defer cancel()
   398  
   399  	lis1, err := net.Listen("tcp", "localhost:0")
   400  	if err != nil {
   401  		t.Fatalf("Error while listening. Err: %v", err)
   402  	}
   403  	defer lis1.Close()
   404  
   405  	lis2, err := net.Listen("tcp", "localhost:0")
   406  	if err != nil {
   407  		t.Fatalf("Error while listening. Err: %v", err)
   408  	}
   409  	defer lis2.Close()
   410  
   411  	server1Done := make(chan struct{})
   412  	server2Done := make(chan struct{})
   413  
   414  	// Launch server 1.
   415  	go func() {
   416  		conn, err := lis1.Accept()
   417  		if err != nil {
   418  			t.Error(err)
   419  			return
   420  		}
   421  
   422  		conn.Close()
   423  		close(server1Done)
   424  	}()
   425  	// Launch server 2.
   426  	go func() {
   427  		conn, err := lis2.Accept()
   428  		if err != nil {
   429  			t.Error(err)
   430  			return
   431  		}
   432  		conn.Close()
   433  		close(server2Done)
   434  	}()
   435  
   436  	rb := manual.NewBuilderWithScheme("whatever")
   437  	rb.InitialState(resolver.State{Addresses: []resolver.Address{
   438  		{Addr: lis1.Addr().String()},
   439  		{Addr: lis2.Addr().String()},
   440  	}})
   441  	client, err := DialContext(ctx, "whatever:///this-gets-overwritten",
   442  		WithInsecure(),
   443  		WithBalancerName(stateRecordingBalancerName),
   444  		WithResolvers(rb),
   445  		withMinConnectDeadline(getMinConnectTimeout))
   446  	if err != nil {
   447  		t.Fatal(err)
   448  	}
   449  	defer client.Close()
   450  
   451  	timeout := time.After(15 * time.Second)
   452  
   453  	select {
   454  	case <-timeout:
   455  		t.Fatal("timed out waiting for test to finish")
   456  	case <-server1Done:
   457  	}
   458  
   459  	select {
   460  	case <-timeout:
   461  		t.Fatal("timed out waiting for test to finish")
   462  	case <-server2Done:
   463  	}
   464  }
   465  
   466  func (s) TestDialContextCancel(t *testing.T) {
   467  	ctx, cancel := context.WithCancel(context.Background())
   468  	cancel()
   469  	if _, err := DialContext(ctx, "Non-Existent.Server:80", WithBlock(), WithInsecure()); err != context.Canceled {
   470  		t.Fatalf("DialContext(%v, _) = _, %v, want _, %v", ctx, err, context.Canceled)
   471  	}
   472  }
   473  
   474  type failFastError struct{}
   475  
   476  func (failFastError) Error() string   { return "failfast" }
   477  func (failFastError) Temporary() bool { return false }
   478  
   479  func (s) TestDialContextFailFast(t *testing.T) {
   480  	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
   481  	defer cancel()
   482  	failErr := failFastError{}
   483  	dialer := func(string, time.Duration) (net.Conn, error) {
   484  		return nil, failErr
   485  	}
   486  
   487  	_, err := DialContext(ctx, "Non-Existent.Server:80", WithBlock(), WithInsecure(), WithDialer(dialer), FailOnNonTempDialError(true))
   488  	if terr, ok := err.(transport.ConnectionError); !ok || terr.Origin() != failErr {
   489  		t.Fatalf("DialContext() = _, %v, want _, %v", err, failErr)
   490  	}
   491  }
   492  
   493  // securePerRPCCredentials always requires transport security.
   494  type securePerRPCCredentials struct {
   495  	credentials.PerRPCCredentials
   496  }
   497  
   498  func (c securePerRPCCredentials) RequireTransportSecurity() bool {
   499  	return true
   500  }
   501  
   502  type fakeBundleCreds struct {
   503  	credentials.Bundle
   504  	transportCreds credentials.TransportCredentials
   505  }
   506  
   507  func (b *fakeBundleCreds) TransportCredentials() credentials.TransportCredentials {
   508  	return b.transportCreds
   509  }
   510  
   511  func (s) TestCredentialsMisuse(t *testing.T) {
   512  	// Use of no transport creds and no creds bundle must fail.
   513  	if _, err := Dial("passthrough:///Non-Existent.Server:80"); err != errNoTransportSecurity {
   514  		t.Fatalf("Dial(_, _) = _, %v, want _, %v", err, errNoTransportSecurity)
   515  	}
   516  
   517  	// Use of both transport creds and creds bundle must fail.
   518  	creds, err := credentials.NewClientTLSFromFile(testdata.Path("x509/server_ca_cert.pem"), "x.test.example.com")
   519  	if err != nil {
   520  		t.Fatalf("Failed to create authenticator %v", err)
   521  	}
   522  	dopts := []DialOption{
   523  		WithTransportCredentials(creds),
   524  		WithCredentialsBundle(&fakeBundleCreds{transportCreds: creds}),
   525  	}
   526  	if _, err := Dial("passthrough:///Non-Existent.Server:80", dopts...); err != errTransportCredsAndBundle {
   527  		t.Fatalf("Dial(_, _) = _, %v, want _, %v", err, errTransportCredsAndBundle)
   528  	}
   529  
   530  	// Use of perRPC creds requiring transport security over an insecure
   531  	// transport must fail.
   532  	if _, err := Dial("passthrough:///Non-Existent.Server:80", WithPerRPCCredentials(securePerRPCCredentials{}), WithInsecure()); err != errTransportCredentialsMissing {
   533  		t.Fatalf("Dial(_, _) = _, %v, want _, %v", err, errTransportCredentialsMissing)
   534  	}
   535  
   536  	// Use of a creds bundle with nil transport credentials must fail.
   537  	if _, err := Dial("passthrough:///Non-Existent.Server:80", WithCredentialsBundle(&fakeBundleCreds{})); err != errNoTransportCredsInBundle {
   538  		t.Fatalf("Dial(_, _) = _, %v, want _, %v", err, errTransportCredsAndBundle)
   539  	}
   540  }
   541  
   542  func (s) TestWithBackoffConfigDefault(t *testing.T) {
   543  	testBackoffConfigSet(t, internalbackoff.DefaultExponential)
   544  }
   545  
   546  func (s) TestWithBackoffConfig(t *testing.T) {
   547  	b := BackoffConfig{MaxDelay: DefaultBackoffConfig.MaxDelay / 2}
   548  	bc := backoff.DefaultConfig
   549  	bc.MaxDelay = b.MaxDelay
   550  	wantBackoff := internalbackoff.Exponential{Config: bc}
   551  	testBackoffConfigSet(t, wantBackoff, WithBackoffConfig(b))
   552  }
   553  
   554  func (s) TestWithBackoffMaxDelay(t *testing.T) {
   555  	md := DefaultBackoffConfig.MaxDelay / 2
   556  	bc := backoff.DefaultConfig
   557  	bc.MaxDelay = md
   558  	wantBackoff := internalbackoff.Exponential{Config: bc}
   559  	testBackoffConfigSet(t, wantBackoff, WithBackoffMaxDelay(md))
   560  }
   561  
   562  func (s) TestWithConnectParams(t *testing.T) {
   563  	bd := 2 * time.Second
   564  	mltpr := 2.0
   565  	jitter := 0.0
   566  	bc := backoff.Config{BaseDelay: bd, Multiplier: mltpr, Jitter: jitter}
   567  
   568  	crt := ConnectParams{Backoff: bc}
   569  	// MaxDelay is not set in the ConnectParams. So it should not be set on
   570  	// internalbackoff.Exponential as well.
   571  	wantBackoff := internalbackoff.Exponential{Config: bc}
   572  	testBackoffConfigSet(t, wantBackoff, WithConnectParams(crt))
   573  }
   574  
   575  func testBackoffConfigSet(t *testing.T, wantBackoff internalbackoff.Exponential, opts ...DialOption) {
   576  	opts = append(opts, WithInsecure())
   577  	conn, err := Dial("passthrough:///foo:80", opts...)
   578  	if err != nil {
   579  		t.Fatalf("unexpected error dialing connection: %v", err)
   580  	}
   581  	defer conn.Close()
   582  
   583  	if conn.dopts.bs == nil {
   584  		t.Fatalf("backoff config not set")
   585  	}
   586  
   587  	gotBackoff, ok := conn.dopts.bs.(internalbackoff.Exponential)
   588  	if !ok {
   589  		t.Fatalf("unexpected type of backoff config: %#v", conn.dopts.bs)
   590  	}
   591  
   592  	if gotBackoff != wantBackoff {
   593  		t.Fatalf("unexpected backoff config on connection: %v, want %v", gotBackoff, wantBackoff)
   594  	}
   595  }
   596  
   597  func (s) TestConnectParamsWithMinConnectTimeout(t *testing.T) {
   598  	// Default value specified for minConnectTimeout in the spec is 20 seconds.
   599  	mct := 1 * time.Minute
   600  	conn, err := Dial("passthrough:///foo:80", WithInsecure(), WithConnectParams(ConnectParams{MinConnectTimeout: mct}))
   601  	if err != nil {
   602  		t.Fatalf("unexpected error dialing connection: %v", err)
   603  	}
   604  	defer conn.Close()
   605  
   606  	if got := conn.dopts.minConnectTimeout(); got != mct {
   607  		t.Errorf("unexpect minConnectTimeout on the connection: %v, want %v", got, mct)
   608  	}
   609  }
   610  
   611  func (s) TestResolverServiceConfigBeforeAddressNotPanic(t *testing.T) {
   612  	r := manual.NewBuilderWithScheme("whatever")
   613  
   614  	cc, err := Dial(r.Scheme()+":///test.server", WithInsecure(), WithResolvers(r))
   615  	if err != nil {
   616  		t.Fatalf("failed to dial: %v", err)
   617  	}
   618  	defer cc.Close()
   619  
   620  	// SwitchBalancer before NewAddress. There was no balancer created, this
   621  	// makes sure we don't call close on nil balancerWrapper.
   622  	r.UpdateState(resolver.State{ServiceConfig: parseCfg(r, `{"loadBalancingPolicy": "round_robin"}`)}) // This should not panic.
   623  
   624  	time.Sleep(time.Second) // Sleep to make sure the service config is handled by ClientConn.
   625  }
   626  
   627  func (s) TestResolverServiceConfigWhileClosingNotPanic(t *testing.T) {
   628  	for i := 0; i < 10; i++ { // Run this multiple times to make sure it doesn't panic.
   629  		r := manual.NewBuilderWithScheme(fmt.Sprintf("whatever-%d", i))
   630  
   631  		cc, err := Dial(r.Scheme()+":///test.server", WithInsecure(), WithResolvers(r))
   632  		if err != nil {
   633  			t.Fatalf("failed to dial: %v", err)
   634  		}
   635  		// Send a new service config while closing the ClientConn.
   636  		go cc.Close()
   637  		go r.UpdateState(resolver.State{ServiceConfig: parseCfg(r, `{"loadBalancingPolicy": "round_robin"}`)}) // This should not panic.
   638  	}
   639  }
   640  
   641  func (s) TestResolverEmptyUpdateNotPanic(t *testing.T) {
   642  	r := manual.NewBuilderWithScheme("whatever")
   643  
   644  	cc, err := Dial(r.Scheme()+":///test.server", WithInsecure(), WithResolvers(r))
   645  	if err != nil {
   646  		t.Fatalf("failed to dial: %v", err)
   647  	}
   648  	defer cc.Close()
   649  
   650  	// This make sure we don't create addrConn with empty address list.
   651  	r.UpdateState(resolver.State{}) // This should not panic.
   652  
   653  	time.Sleep(time.Second) // Sleep to make sure the service config is handled by ClientConn.
   654  }
   655  
   656  func (s) TestClientUpdatesParamsAfterGoAway(t *testing.T) {
   657  	lis, err := net.Listen("tcp", "localhost:0")
   658  	if err != nil {
   659  		t.Fatalf("Failed to listen. Err: %v", err)
   660  	}
   661  	defer lis.Close()
   662  	connected := grpcsync.NewEvent()
   663  	defer connected.Fire()
   664  	go func() {
   665  		conn, err := lis.Accept()
   666  		if err != nil {
   667  			t.Errorf("error accepting connection: %v", err)
   668  			return
   669  		}
   670  		defer conn.Close()
   671  		f := http2.NewFramer(conn, conn)
   672  		// Start a goroutine to read from the conn to prevent the client from
   673  		// blocking after it writes its preface.
   674  		go func() {
   675  			for {
   676  				if _, err := f.ReadFrame(); err != nil {
   677  					return
   678  				}
   679  			}
   680  		}()
   681  		if err := f.WriteSettings(http2.Setting{}); err != nil {
   682  			t.Errorf("error writing settings: %v", err)
   683  			return
   684  		}
   685  		<-connected.Done()
   686  		if err := f.WriteGoAway(0, http2.ErrCodeEnhanceYourCalm, []byte("too_many_pings")); err != nil {
   687  			t.Errorf("error writing GOAWAY: %v", err)
   688  			return
   689  		}
   690  	}()
   691  	addr := lis.Addr().String()
   692  	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
   693  	defer cancel()
   694  	cc, err := DialContext(ctx, addr, WithBlock(), WithInsecure(), WithKeepaliveParams(keepalive.ClientParameters{
   695  		Time:                10 * time.Second,
   696  		Timeout:             100 * time.Millisecond,
   697  		PermitWithoutStream: true,
   698  	}))
   699  	if err != nil {
   700  		t.Fatalf("Dial(%s, _) = _, %v, want _, <nil>", addr, err)
   701  	}
   702  	defer cc.Close()
   703  	connected.Fire()
   704  	for {
   705  		time.Sleep(10 * time.Millisecond)
   706  		cc.mu.RLock()
   707  		v := cc.mkp.Time
   708  		cc.mu.RUnlock()
   709  		if v == 20*time.Second {
   710  			// Success
   711  			return
   712  		}
   713  		if ctx.Err() != nil {
   714  			// Timeout
   715  			t.Fatalf("cc.dopts.copts.Keepalive.Time = %v , want 20s", v)
   716  		}
   717  	}
   718  }
   719  
   720  func (s) TestDisableServiceConfigOption(t *testing.T) {
   721  	r := manual.NewBuilderWithScheme("whatever")
   722  	addr := r.Scheme() + ":///non.existent"
   723  	cc, err := Dial(addr, WithInsecure(), WithResolvers(r), WithDisableServiceConfig())
   724  	if err != nil {
   725  		t.Fatalf("Dial(%s, _) = _, %v, want _, <nil>", addr, err)
   726  	}
   727  	defer cc.Close()
   728  	r.UpdateState(resolver.State{ServiceConfig: parseCfg(r, `{
   729      "methodConfig": [
   730          {
   731              "name": [
   732                  {
   733                      "service": "foo",
   734                      "method": "Bar"
   735                  }
   736              ],
   737              "waitForReady": true
   738          }
   739      ]
   740  }`)})
   741  	time.Sleep(1 * time.Second)
   742  	m := cc.GetMethodConfig("/foo/Bar")
   743  	if m.WaitForReady != nil {
   744  		t.Fatalf("want: method (\"/foo/bar/\") config to be empty, got: %+v", m)
   745  	}
   746  }
   747  
   748  func (s) TestMethodConfigDefaultService(t *testing.T) {
   749  	addr := "nonexist:///non.existent"
   750  	cc, err := Dial(addr, WithInsecure(), WithDefaultServiceConfig(`{
   751    "methodConfig": [{
   752      "name": [
   753        {
   754          "service": ""
   755        }
   756      ],
   757      "waitForReady": true
   758    }]
   759  }`))
   760  	if err != nil {
   761  		t.Fatalf("Dial(%s, _) = _, %v, want _, <nil>", addr, err)
   762  	}
   763  	defer cc.Close()
   764  
   765  	m := cc.GetMethodConfig("/foo/Bar")
   766  	if m.WaitForReady == nil {
   767  		t.Fatalf("want: method (%q) config to fallback to the default service", "/foo/Bar")
   768  	}
   769  }
   770  
   771  func (s) TestGetClientConnTarget(t *testing.T) {
   772  	addr := "nonexist:///non.existent"
   773  	cc, err := Dial(addr, WithInsecure())
   774  	if err != nil {
   775  		t.Fatalf("Dial(%s, _) = _, %v, want _, <nil>", addr, err)
   776  	}
   777  	defer cc.Close()
   778  	if cc.Target() != addr {
   779  		t.Fatalf("Target() = %s, want %s", cc.Target(), addr)
   780  	}
   781  }
   782  
   783  type backoffForever struct{}
   784  
   785  func (b backoffForever) Backoff(int) time.Duration { return time.Duration(math.MaxInt64) }
   786  
   787  func (s) TestResetConnectBackoff(t *testing.T) {
   788  	dials := make(chan struct{})
   789  	defer func() { // If we fail, let the http2client break out of dialing.
   790  		select {
   791  		case <-dials:
   792  		default:
   793  		}
   794  	}()
   795  	dialer := func(string, time.Duration) (net.Conn, error) {
   796  		dials <- struct{}{}
   797  		return nil, errors.New("failed to fake dial")
   798  	}
   799  	cc, err := Dial("any", WithInsecure(), WithDialer(dialer), withBackoff(backoffForever{}))
   800  	if err != nil {
   801  		t.Fatalf("Dial() = _, %v; want _, nil", err)
   802  	}
   803  	defer cc.Close()
   804  	go stayConnected(cc)
   805  	select {
   806  	case <-dials:
   807  	case <-time.NewTimer(10 * time.Second).C:
   808  		t.Fatal("Failed to call dial within 10s")
   809  	}
   810  
   811  	select {
   812  	case <-dials:
   813  		t.Fatal("Dial called unexpectedly before resetting backoff")
   814  	case <-time.NewTimer(100 * time.Millisecond).C:
   815  	}
   816  
   817  	cc.ResetConnectBackoff()
   818  
   819  	select {
   820  	case <-dials:
   821  	case <-time.NewTimer(10 * time.Second).C:
   822  		t.Fatal("Failed to call dial within 10s after resetting backoff")
   823  	}
   824  }
   825  
   826  func (s) TestBackoffCancel(t *testing.T) {
   827  	dialStrCh := make(chan string)
   828  	cc, err := Dial("any", WithInsecure(), WithDialer(func(t string, _ time.Duration) (net.Conn, error) {
   829  		dialStrCh <- t
   830  		return nil, fmt.Errorf("test dialer, always error")
   831  	}))
   832  	if err != nil {
   833  		t.Fatalf("Failed to create ClientConn: %v", err)
   834  	}
   835  	<-dialStrCh
   836  	cc.Close()
   837  	// Should not leak. May need -count 5000 to exercise.
   838  }
   839  
   840  // UpdateAddresses should cause the next reconnect to begin from the top of the
   841  // list if the connection is not READY.
   842  func (s) TestUpdateAddresses_RetryFromFirstAddr(t *testing.T) {
   843  	lis1, err := net.Listen("tcp", "localhost:0")
   844  	if err != nil {
   845  		t.Fatalf("Error while listening. Err: %v", err)
   846  	}
   847  	defer lis1.Close()
   848  
   849  	lis2, err := net.Listen("tcp", "localhost:0")
   850  	if err != nil {
   851  		t.Fatalf("Error while listening. Err: %v", err)
   852  	}
   853  	defer lis2.Close()
   854  
   855  	lis3, err := net.Listen("tcp", "localhost:0")
   856  	if err != nil {
   857  		t.Fatalf("Error while listening. Err: %v", err)
   858  	}
   859  	defer lis3.Close()
   860  
   861  	closeServer2 := make(chan struct{})
   862  	exitCh := make(chan struct{})
   863  	server1ContactedFirstTime := make(chan struct{})
   864  	server1ContactedSecondTime := make(chan struct{})
   865  	server2ContactedFirstTime := make(chan struct{})
   866  	server2ContactedSecondTime := make(chan struct{})
   867  	server3Contacted := make(chan struct{})
   868  
   869  	defer close(exitCh)
   870  
   871  	// Launch server 1.
   872  	go func() {
   873  		// First, let's allow the initial connection to go READY. We need to do
   874  		// this because tryUpdateAddrs only works after there's some non-nil
   875  		// address on the ac, and curAddress is only set after READY.
   876  		conn1, err := lis1.Accept()
   877  		if err != nil {
   878  			t.Error(err)
   879  			return
   880  		}
   881  		go keepReading(conn1)
   882  
   883  		framer := http2.NewFramer(conn1, conn1)
   884  		if err := framer.WriteSettings(http2.Setting{}); err != nil {
   885  			t.Errorf("Error while writing settings frame. %v", err)
   886  			return
   887  		}
   888  
   889  		// nextStateNotifier() is updated after balancerBuilder.Build(), which is
   890  		// called by grpc.Dial. It's safe to do it here because lis1.Accept blocks
   891  		// until balancer is built to process the addresses.
   892  		stateNotifications := testBalancerBuilder.nextStateNotifier()
   893  		// Wait for the transport to become ready.
   894  		for {
   895  			select {
   896  			case st := <-stateNotifications:
   897  				if st == connectivity.Ready {
   898  					goto ready
   899  				}
   900  			case <-exitCh:
   901  				return
   902  			}
   903  		}
   904  
   905  	ready:
   906  		// Once it's ready, curAddress has been set. So let's close this
   907  		// connection prompting the first reconnect cycle.
   908  		conn1.Close()
   909  
   910  		// Accept and immediately close, causing it to go to server2.
   911  		conn2, err := lis1.Accept()
   912  		if err != nil {
   913  			t.Error(err)
   914  			return
   915  		}
   916  		close(server1ContactedFirstTime)
   917  		conn2.Close()
   918  
   919  		// Hopefully it picks this server after tryUpdateAddrs.
   920  		lis1.Accept()
   921  		close(server1ContactedSecondTime)
   922  	}()
   923  	// Launch server 2.
   924  	go func() {
   925  		// Accept and then hang waiting for the test call tryUpdateAddrs and
   926  		// then signal to this server to close. After this server closes, it
   927  		// should start from the top instead of trying server2 or continuing
   928  		// to server3.
   929  		conn, err := lis2.Accept()
   930  		if err != nil {
   931  			t.Error(err)
   932  			return
   933  		}
   934  
   935  		close(server2ContactedFirstTime)
   936  		<-closeServer2
   937  		conn.Close()
   938  
   939  		// After tryUpdateAddrs, it should NOT try server2.
   940  		lis2.Accept()
   941  		close(server2ContactedSecondTime)
   942  	}()
   943  	// Launch server 3.
   944  	go func() {
   945  		// After tryUpdateAddrs, it should NOT try server3. (or any other time)
   946  		lis3.Accept()
   947  		close(server3Contacted)
   948  	}()
   949  
   950  	addrsList := []resolver.Address{
   951  		{Addr: lis1.Addr().String()},
   952  		{Addr: lis2.Addr().String()},
   953  		{Addr: lis3.Addr().String()},
   954  	}
   955  	rb := manual.NewBuilderWithScheme("whatever")
   956  	rb.InitialState(resolver.State{Addresses: addrsList})
   957  
   958  	client, err := Dial("whatever:///this-gets-overwritten",
   959  		WithInsecure(),
   960  		WithResolvers(rb),
   961  		withBackoff(noBackoff{}),
   962  		WithBalancerName(stateRecordingBalancerName),
   963  		withMinConnectDeadline(func() time.Duration { return time.Hour }))
   964  	if err != nil {
   965  		t.Fatal(err)
   966  	}
   967  	defer client.Close()
   968  	go stayConnected(client)
   969  
   970  	timeout := time.After(5 * time.Second)
   971  
   972  	// Wait for server1 to be contacted (which will immediately fail), then
   973  	// server2 (which will hang waiting for our signal).
   974  	select {
   975  	case <-server1ContactedFirstTime:
   976  	case <-timeout:
   977  		t.Fatal("timed out waiting for server1 to be contacted")
   978  	}
   979  	select {
   980  	case <-server2ContactedFirstTime:
   981  	case <-timeout:
   982  		t.Fatal("timed out waiting for server2 to be contacted")
   983  	}
   984  
   985  	// Grab the addrConn and call tryUpdateAddrs.
   986  	var ac *addrConn
   987  	client.mu.Lock()
   988  	for clientAC := range client.conns {
   989  		ac = clientAC
   990  		break
   991  	}
   992  	client.mu.Unlock()
   993  
   994  	ac.acbw.UpdateAddresses(addrsList)
   995  
   996  	// We've called tryUpdateAddrs - now let's make server2 close the
   997  	// connection and check that it goes back to server1 instead of continuing
   998  	// to server3 or trying server2 again.
   999  	close(closeServer2)
  1000  
  1001  	select {
  1002  	case <-server1ContactedSecondTime:
  1003  	case <-server2ContactedSecondTime:
  1004  		t.Fatal("server2 was contacted a second time, but it after tryUpdateAddrs it should have re-started the list and tried server1")
  1005  	case <-server3Contacted:
  1006  		t.Fatal("server3 was contacted, but after tryUpdateAddrs it should have re-started the list and tried server1")
  1007  	case <-timeout:
  1008  		t.Fatal("timed out waiting for any server to be contacted after tryUpdateAddrs")
  1009  	}
  1010  }
  1011  
  1012  func (s) TestDefaultServiceConfig(t *testing.T) {
  1013  	r := manual.NewBuilderWithScheme("whatever")
  1014  	addr := r.Scheme() + ":///non.existent"
  1015  	js := `{
  1016      "methodConfig": [
  1017          {
  1018              "name": [
  1019                  {
  1020                      "service": "foo",
  1021                      "method": "bar"
  1022                  }
  1023              ],
  1024              "waitForReady": true
  1025          }
  1026      ]
  1027  }`
  1028  	testInvalidDefaultServiceConfig(t)
  1029  	testDefaultServiceConfigWhenResolverServiceConfigDisabled(t, r, addr, js)
  1030  	testDefaultServiceConfigWhenResolverDoesNotReturnServiceConfig(t, r, addr, js)
  1031  	testDefaultServiceConfigWhenResolverReturnInvalidServiceConfig(t, r, addr, js)
  1032  }
  1033  
  1034  func verifyWaitForReadyEqualsTrue(cc *ClientConn) bool {
  1035  	var i int
  1036  	for i = 0; i < 10; i++ {
  1037  		mc := cc.GetMethodConfig("/foo/bar")
  1038  		if mc.WaitForReady != nil && *mc.WaitForReady == true {
  1039  			break
  1040  		}
  1041  		time.Sleep(100 * time.Millisecond)
  1042  	}
  1043  	return i != 10
  1044  }
  1045  
  1046  func testInvalidDefaultServiceConfig(t *testing.T) {
  1047  	_, err := Dial("fake.com", WithInsecure(), WithDefaultServiceConfig(""))
  1048  	if !strings.Contains(err.Error(), invalidDefaultServiceConfigErrPrefix) {
  1049  		t.Fatalf("Dial got err: %v, want err contains: %v", err, invalidDefaultServiceConfigErrPrefix)
  1050  	}
  1051  }
  1052  
  1053  func testDefaultServiceConfigWhenResolverServiceConfigDisabled(t *testing.T, r *manual.Resolver, addr string, js string) {
  1054  	cc, err := Dial(addr, WithInsecure(), WithDisableServiceConfig(), WithResolvers(r), WithDefaultServiceConfig(js))
  1055  	if err != nil {
  1056  		t.Fatalf("Dial(%s, _) = _, %v, want _, <nil>", addr, err)
  1057  	}
  1058  	defer cc.Close()
  1059  	// Resolver service config gets ignored since resolver service config is disabled.
  1060  	r.UpdateState(resolver.State{
  1061  		Addresses:     []resolver.Address{{Addr: addr}},
  1062  		ServiceConfig: parseCfg(r, "{}"),
  1063  	})
  1064  	if !verifyWaitForReadyEqualsTrue(cc) {
  1065  		t.Fatal("default service config failed to be applied after 1s")
  1066  	}
  1067  }
  1068  
  1069  func testDefaultServiceConfigWhenResolverDoesNotReturnServiceConfig(t *testing.T, r *manual.Resolver, addr string, js string) {
  1070  	cc, err := Dial(addr, WithInsecure(), WithResolvers(r), WithDefaultServiceConfig(js))
  1071  	if err != nil {
  1072  		t.Fatalf("Dial(%s, _) = _, %v, want _, <nil>", addr, err)
  1073  	}
  1074  	defer cc.Close()
  1075  	r.UpdateState(resolver.State{
  1076  		Addresses: []resolver.Address{{Addr: addr}},
  1077  	})
  1078  	if !verifyWaitForReadyEqualsTrue(cc) {
  1079  		t.Fatal("default service config failed to be applied after 1s")
  1080  	}
  1081  }
  1082  
  1083  func testDefaultServiceConfigWhenResolverReturnInvalidServiceConfig(t *testing.T, r *manual.Resolver, addr string, js string) {
  1084  	cc, err := Dial(addr, WithInsecure(), WithResolvers(r), WithDefaultServiceConfig(js))
  1085  	if err != nil {
  1086  		t.Fatalf("Dial(%s, _) = _, %v, want _, <nil>", addr, err)
  1087  	}
  1088  	defer cc.Close()
  1089  	r.UpdateState(resolver.State{
  1090  		Addresses: []resolver.Address{{Addr: addr}},
  1091  	})
  1092  	if !verifyWaitForReadyEqualsTrue(cc) {
  1093  		t.Fatal("default service config failed to be applied after 1s")
  1094  	}
  1095  }
  1096  
  1097  // stayConnected makes cc stay connected by repeatedly calling cc.Connect()
  1098  // until the state becomes Shutdown or until 10 seconds elapses.
  1099  func stayConnected(cc *ClientConn) {
  1100  	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
  1101  	defer cancel()
  1102  
  1103  	for {
  1104  		state := cc.GetState()
  1105  		switch state {
  1106  		case connectivity.Idle:
  1107  			cc.Connect()
  1108  		case connectivity.Shutdown:
  1109  			return
  1110  		}
  1111  		if !cc.WaitForStateChange(ctx, state) {
  1112  			return
  1113  		}
  1114  	}
  1115  }