google.golang.org/grpc@v1.72.2/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"
    29  	"sync/atomic"
    30  	"testing"
    31  	"time"
    32  
    33  	"golang.org/x/net/http2"
    34  	"google.golang.org/grpc/backoff"
    35  	"google.golang.org/grpc/balancer"
    36  	"google.golang.org/grpc/connectivity"
    37  	"google.golang.org/grpc/credentials"
    38  	"google.golang.org/grpc/credentials/insecure"
    39  	internalbackoff "google.golang.org/grpc/internal/backoff"
    40  	"google.golang.org/grpc/internal/envconfig"
    41  	"google.golang.org/grpc/internal/grpcsync"
    42  	"google.golang.org/grpc/internal/grpctest"
    43  	"google.golang.org/grpc/internal/transport"
    44  	"google.golang.org/grpc/keepalive"
    45  	"google.golang.org/grpc/resolver"
    46  	"google.golang.org/grpc/resolver/manual"
    47  	"google.golang.org/grpc/serviceconfig"
    48  	"google.golang.org/grpc/testdata"
    49  )
    50  
    51  const (
    52  	defaultTestTimeout         = 10 * time.Second
    53  	defaultTestShortTimeout    = 10 * time.Millisecond
    54  	stateRecordingBalancerName = "state_recording_balancer"
    55  	grpclbServiceConfig        = `{"loadBalancingConfig": [{"grpclb": {}}]}`
    56  	rrServiceConfig            = `{"loadBalancingPolicy": [{"round_robin": {}}]}`
    57  )
    58  
    59  var testBalancerBuilder = newStateRecordingBalancerBuilder()
    60  
    61  func init() {
    62  	balancer.Register(testBalancerBuilder)
    63  }
    64  
    65  func parseCfg(r *manual.Resolver, s string) *serviceconfig.ParseResult {
    66  	scpr := r.CC().ParseServiceConfig(s)
    67  	if scpr.Err != nil {
    68  		panic(fmt.Sprintf("Error parsing config %q: %v", s, scpr.Err))
    69  	}
    70  	return scpr
    71  }
    72  
    73  func (s) TestDialWithTimeout(t *testing.T) {
    74  	lis, err := net.Listen("tcp", "localhost:0")
    75  	if err != nil {
    76  		t.Fatalf("Error while listening. Err: %v", err)
    77  	}
    78  	defer lis.Close()
    79  	lisAddr := resolver.Address{Addr: lis.Addr().String()}
    80  	lisDone := make(chan struct{})
    81  	dialDone := make(chan struct{})
    82  	// 1st listener accepts the connection and then does nothing
    83  	go func() {
    84  		defer close(lisDone)
    85  		conn, err := lis.Accept()
    86  		if err != nil {
    87  			t.Errorf("Error while accepting. Err: %v", err)
    88  			return
    89  		}
    90  		framer := http2.NewFramer(conn, conn)
    91  		if err := framer.WriteSettings(http2.Setting{}); err != nil {
    92  			t.Errorf("Error while writing settings. Err: %v", err)
    93  			return
    94  		}
    95  		<-dialDone // Close conn only after dial returns.
    96  	}()
    97  
    98  	r := manual.NewBuilderWithScheme("whatever")
    99  	r.InitialState(resolver.State{Addresses: []resolver.Address{lisAddr}})
   100  	client, err := Dial(r.Scheme()+":///test.server", WithTransportCredentials(insecure.NewCredentials()), WithResolvers(r), WithTimeout(5*time.Second))
   101  	close(dialDone)
   102  	if err != nil {
   103  		t.Fatalf("Dial failed. Err: %v", err)
   104  	}
   105  	defer client.Close()
   106  	timeout := time.After(1 * time.Second)
   107  	select {
   108  	case <-timeout:
   109  		t.Fatal("timed out waiting for server to finish")
   110  	case <-lisDone:
   111  	}
   112  }
   113  
   114  func (s) TestNewClientWithMultipleBackendsNotSendingServerPreface(t *testing.T) {
   115  	lis1, err := net.Listen("tcp", "localhost:0")
   116  	if err != nil {
   117  		t.Fatalf("Error while listening. Err: %v", err)
   118  	}
   119  	defer lis1.Close()
   120  	lis1Addr := resolver.Address{Addr: lis1.Addr().String()}
   121  	lis1Done := make(chan struct{})
   122  	// 1st listener accepts the connection and immediately closes it.
   123  	go func() {
   124  		defer close(lis1Done)
   125  		conn, err := lis1.Accept()
   126  		if err != nil {
   127  			t.Errorf("Error while accepting. Err: %v", err)
   128  			return
   129  		}
   130  		conn.Close()
   131  	}()
   132  
   133  	lis2, err := net.Listen("tcp", "localhost:0")
   134  	if err != nil {
   135  		t.Fatalf("Error while listening. Err: %v", err)
   136  	}
   137  	defer lis2.Close()
   138  	lis2Done := make(chan struct{})
   139  	lis2Addr := resolver.Address{Addr: lis2.Addr().String()}
   140  	// 2nd listener should get a connection attempt since the first one failed.
   141  	go func() {
   142  		defer close(lis2Done)
   143  		_, err := lis2.Accept() // Closing the client will clean up this conn.
   144  		if err != nil {
   145  			t.Errorf("Error while accepting. Err: %v", err)
   146  			return
   147  		}
   148  	}()
   149  
   150  	r := manual.NewBuilderWithScheme("whatever")
   151  	r.InitialState(resolver.State{Addresses: []resolver.Address{lis1Addr, lis2Addr}})
   152  	client, err := NewClient(r.Scheme()+":///test.server", WithTransportCredentials(insecure.NewCredentials()), WithResolvers(r))
   153  	if err != nil {
   154  		t.Fatalf("grpc.NewClient() failed: %v", err)
   155  	}
   156  	client.Connect()
   157  	defer client.Close()
   158  	timeout := time.After(5 * time.Second)
   159  	select {
   160  	case <-timeout:
   161  		t.Fatal("timed out waiting for server 1 to finish")
   162  	case <-lis1Done:
   163  	}
   164  	select {
   165  	case <-timeout:
   166  		t.Fatal("timed out waiting for server 2 to finish")
   167  	case <-lis2Done:
   168  	}
   169  }
   170  
   171  func (s) TestDialWaitsForServerSettings(t *testing.T) {
   172  	lis, err := net.Listen("tcp", "localhost:0")
   173  	if err != nil {
   174  		t.Fatalf("Error while listening. Err: %v", err)
   175  	}
   176  	defer lis.Close()
   177  	done := make(chan struct{})
   178  	sent := make(chan struct{})
   179  	dialDone := make(chan struct{})
   180  	go func() { // Launch the server.
   181  		defer func() {
   182  			close(done)
   183  		}()
   184  		conn, err := lis.Accept()
   185  		if err != nil {
   186  			t.Errorf("Error while accepting. Err: %v", err)
   187  			return
   188  		}
   189  		defer conn.Close()
   190  		// Sleep for a little bit to make sure that Dial on client
   191  		// side blocks until settings are received.
   192  		time.Sleep(100 * time.Millisecond)
   193  		framer := http2.NewFramer(conn, conn)
   194  		close(sent)
   195  		if err := framer.WriteSettings(http2.Setting{}); err != nil {
   196  			t.Errorf("Error while writing settings. Err: %v", err)
   197  			return
   198  		}
   199  		<-dialDone // Close conn only after dial returns.
   200  	}()
   201  	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
   202  	defer cancel()
   203  	client, err := DialContext(ctx, lis.Addr().String(), WithTransportCredentials(insecure.NewCredentials()), WithBlock())
   204  	close(dialDone)
   205  	if err != nil {
   206  		t.Fatalf("Error while dialing. Err: %v", err)
   207  	}
   208  	defer client.Close()
   209  	select {
   210  	case <-sent:
   211  	default:
   212  		t.Fatalf("Dial returned before server settings were sent")
   213  	}
   214  	<-done
   215  }
   216  
   217  func (s) TestDialWaitsForServerSettingsAndFails(t *testing.T) {
   218  	lis, err := net.Listen("tcp", "localhost:0")
   219  	if err != nil {
   220  		t.Fatalf("Error while listening. Err: %v", err)
   221  	}
   222  	done := make(chan struct{})
   223  	numConns := 0
   224  	go func() { // Launch the server.
   225  		defer func() {
   226  			close(done)
   227  		}()
   228  		for {
   229  			conn, err := lis.Accept()
   230  			if err != nil {
   231  				break
   232  			}
   233  			numConns++
   234  			defer conn.Close()
   235  		}
   236  	}()
   237  	ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
   238  	defer cancel()
   239  	client, err := DialContext(ctx,
   240  		lis.Addr().String(),
   241  		WithTransportCredentials(insecure.NewCredentials()),
   242  		WithReturnConnectionError(),
   243  		WithConnectParams(ConnectParams{
   244  			Backoff:           backoff.Config{},
   245  			MinConnectTimeout: 250 * time.Millisecond,
   246  		}))
   247  	lis.Close()
   248  	if err == nil {
   249  		client.Close()
   250  		t.Fatalf("Unexpected success (err=nil) while dialing")
   251  	}
   252  	expectedMsg := "server preface"
   253  	if !strings.Contains(err.Error(), context.DeadlineExceeded.Error()) || !strings.Contains(err.Error(), expectedMsg) {
   254  		t.Fatalf("DialContext(_) = %v; want a message that includes both %q and %q", err, context.DeadlineExceeded.Error(), expectedMsg)
   255  	}
   256  	<-done
   257  	if numConns < 2 {
   258  		t.Fatalf("dial attempts: %v; want > 1", numConns)
   259  	}
   260  }
   261  
   262  // 1. Client connects to a server that doesn't send preface.
   263  // 2. After minConnectTimeout(500 ms here), client disconnects and retries.
   264  // 3. The new server sends its preface.
   265  // 4. Client doesn't kill the connection this time.
   266  func (s) TestCloseConnectionWhenServerPrefaceNotReceived(t *testing.T) {
   267  	lis, err := net.Listen("tcp", "localhost:0")
   268  	if err != nil {
   269  		t.Fatalf("Error while listening. Err: %v", err)
   270  	}
   271  	var (
   272  		conn2 net.Conn
   273  		over  uint32
   274  	)
   275  	defer func() {
   276  		lis.Close()
   277  		// conn2 shouldn't be closed until the client has
   278  		// observed a successful test.
   279  		if conn2 != nil {
   280  			conn2.Close()
   281  		}
   282  	}()
   283  	done := make(chan struct{})
   284  	accepted := make(chan struct{})
   285  	go func() { // Launch the server.
   286  		defer close(done)
   287  		conn1, err := lis.Accept()
   288  		if err != nil {
   289  			t.Errorf("Error while accepting. Err: %v", err)
   290  			return
   291  		}
   292  		defer conn1.Close()
   293  		// Don't send server settings and the client should close the connection and try again.
   294  		conn2, err = lis.Accept() // Accept a reconnection request from client.
   295  		if err != nil {
   296  			t.Errorf("Error while accepting. Err: %v", err)
   297  			return
   298  		}
   299  		close(accepted)
   300  		framer := http2.NewFramer(conn2, conn2)
   301  		if err = framer.WriteSettings(http2.Setting{}); err != nil {
   302  			t.Errorf("Error while writing settings. Err: %v", err)
   303  			return
   304  		}
   305  		b := make([]byte, 8)
   306  		for {
   307  			_, err = conn2.Read(b)
   308  			if err == nil {
   309  				continue
   310  			}
   311  			if atomic.LoadUint32(&over) == 1 {
   312  				// The connection stayed alive for the timer.
   313  				// Success.
   314  				return
   315  			}
   316  			t.Errorf("Unexpected error while reading. Err: %v, want timeout error", err)
   317  			break
   318  		}
   319  	}()
   320  	client, err := NewClient(lis.Addr().String(), WithTransportCredentials(insecure.NewCredentials()), withMinConnectDeadline(func() time.Duration { return time.Millisecond * 500 }))
   321  	if err != nil {
   322  		t.Fatalf("grpc.NewClient(%q) = %v", lis.Addr().String(), err)
   323  	}
   324  
   325  	go stayConnected(client)
   326  
   327  	// wait for connection to be accepted on the server.
   328  	timer := time.NewTimer(time.Second * 10)
   329  	select {
   330  	case <-accepted:
   331  	case <-timer.C:
   332  		t.Fatalf("Client didn't make another connection request in time.")
   333  	}
   334  	// Make sure the connection stays alive for some time.
   335  	time.Sleep(time.Second)
   336  	atomic.StoreUint32(&over, 1)
   337  	client.Close()
   338  	<-done
   339  }
   340  
   341  func (s) TestBackoffWhenNoServerPrefaceReceived(t *testing.T) {
   342  	lis, err := net.Listen("tcp", "localhost:0")
   343  	if err != nil {
   344  		t.Fatalf("Unexpected error from net.Listen(%q, %q): %v", "tcp", "localhost:0", err)
   345  	}
   346  	defer lis.Close()
   347  	done := make(chan struct{})
   348  	go func() { // Launch the server.
   349  		defer close(done)
   350  		conn, err := lis.Accept() // Accept the connection only to close it immediately.
   351  		if err != nil {
   352  			t.Errorf("Error while accepting. Err: %v", err)
   353  			return
   354  		}
   355  		prevAt := time.Now()
   356  		conn.Close()
   357  		var prevDuration time.Duration
   358  		// Make sure the retry attempts are backed off properly.
   359  		for i := 0; i < 3; i++ {
   360  			conn, err := lis.Accept()
   361  			if err != nil {
   362  				t.Errorf("Error while accepting. Err: %v", err)
   363  				return
   364  			}
   365  			meow := time.Now()
   366  			conn.Close()
   367  			dr := meow.Sub(prevAt)
   368  			if dr <= prevDuration {
   369  				t.Errorf("Client backoff did not increase with retries. Previous duration: %v, current duration: %v", prevDuration, dr)
   370  				return
   371  			}
   372  			prevDuration = dr
   373  			prevAt = meow
   374  		}
   375  	}()
   376  	bc := backoff.Config{
   377  		BaseDelay:  200 * time.Millisecond,
   378  		Multiplier: 2.0,
   379  		Jitter:     0,
   380  		MaxDelay:   120 * time.Second,
   381  	}
   382  	cp := ConnectParams{
   383  		Backoff:           bc,
   384  		MinConnectTimeout: 1 * time.Second,
   385  	}
   386  	cc, err := NewClient(lis.Addr().String(), WithTransportCredentials(insecure.NewCredentials()), WithConnectParams(cp))
   387  	if err != nil {
   388  		t.Fatalf("grpc.NewClient(%q) = %v", lis.Addr().String(), err)
   389  	}
   390  	defer cc.Close()
   391  	go stayConnected(cc)
   392  	<-done
   393  }
   394  
   395  func (s) TestWithTimeout(t *testing.T) {
   396  	conn, err := Dial("passthrough:///Non-Existent.Server:80",
   397  		WithTimeout(time.Millisecond),
   398  		WithBlock(),
   399  		WithTransportCredentials(insecure.NewCredentials()))
   400  	if err == nil {
   401  		conn.Close()
   402  	}
   403  	if err != context.DeadlineExceeded {
   404  		t.Fatalf("Dial(_, _) = %v, %v, want %v", conn, err, context.DeadlineExceeded)
   405  	}
   406  }
   407  
   408  func (s) TestWithTransportCredentialsTLS(t *testing.T) {
   409  	ctx, cancel := context.WithTimeout(context.Background(), time.Millisecond)
   410  	defer cancel()
   411  	creds, err := credentials.NewClientTLSFromFile(testdata.Path("x509/server_ca_cert.pem"), "x.test.example.com")
   412  	if err != nil {
   413  		t.Fatalf("Failed to create credentials %v", err)
   414  	}
   415  	conn, err := DialContext(ctx, "passthrough:///Non-Existent.Server:80", WithTransportCredentials(creds), WithBlock())
   416  	if err == nil {
   417  		conn.Close()
   418  	}
   419  	if err != context.DeadlineExceeded {
   420  		t.Fatalf("Dial(_, _) = %v, %v, want %v", conn, err, context.DeadlineExceeded)
   421  	}
   422  }
   423  
   424  // When creating a transport configured with n addresses, only calculate the
   425  // backoff once per "round" of attempts instead of once per address (n times
   426  // per "round" of attempts) for old pickfirst and once per address for new pickfirst.
   427  func (s) TestNewClient_BackoffCountPerRetryGroup(t *testing.T) {
   428  	var attempts uint32
   429  	wantBackoffs := uint32(1)
   430  	if envconfig.NewPickFirstEnabled {
   431  		wantBackoffs = 2
   432  	}
   433  	getMinConnectTimeout := func() time.Duration {
   434  		if atomic.AddUint32(&attempts, 1) <= wantBackoffs {
   435  			// Once all addresses are exhausted, hang around and wait for the
   436  			// client.Close to happen rather than re-starting a new round of
   437  			// attempts.
   438  			return time.Hour
   439  		}
   440  		t.Errorf("only %d attempt backoff calculation, but got more", wantBackoffs)
   441  		return 0
   442  	}
   443  
   444  	lis1, err := net.Listen("tcp", "localhost:0")
   445  	if err != nil {
   446  		t.Fatalf("Error while listening. Err: %v", err)
   447  	}
   448  	defer lis1.Close()
   449  
   450  	lis2, err := net.Listen("tcp", "localhost:0")
   451  	if err != nil {
   452  		t.Fatalf("Error while listening. Err: %v", err)
   453  	}
   454  	defer lis2.Close()
   455  
   456  	server1Done := make(chan struct{})
   457  	server2Done := make(chan struct{})
   458  
   459  	// Launch server 1.
   460  	go func() {
   461  		conn, err := lis1.Accept()
   462  		if err != nil {
   463  			t.Error(err)
   464  			return
   465  		}
   466  
   467  		conn.Close()
   468  		close(server1Done)
   469  	}()
   470  	// Launch server 2.
   471  	go func() {
   472  		conn, err := lis2.Accept()
   473  		if err != nil {
   474  			t.Error(err)
   475  			return
   476  		}
   477  		conn.Close()
   478  		close(server2Done)
   479  	}()
   480  
   481  	rb := manual.NewBuilderWithScheme("whatever")
   482  	rb.InitialState(resolver.State{Addresses: []resolver.Address{
   483  		{Addr: lis1.Addr().String()},
   484  		{Addr: lis2.Addr().String()},
   485  	}})
   486  	client, err := NewClient("whatever:///this-gets-overwritten",
   487  		WithTransportCredentials(insecure.NewCredentials()),
   488  		WithResolvers(rb),
   489  		withMinConnectDeadline(getMinConnectTimeout))
   490  	if err != nil {
   491  		t.Fatal(err)
   492  	}
   493  	defer client.Close()
   494  	client.Connect()
   495  	timeout := time.After(15 * time.Second)
   496  
   497  	select {
   498  	case <-timeout:
   499  		t.Fatal("timed out waiting for test to finish")
   500  	case <-server1Done:
   501  	}
   502  
   503  	select {
   504  	case <-timeout:
   505  		t.Fatal("timed out waiting for test to finish")
   506  	case <-server2Done:
   507  	}
   508  
   509  	if got, want := atomic.LoadUint32(&attempts), wantBackoffs; got != want {
   510  		t.Errorf("attempts = %d, want %d", got, want)
   511  	}
   512  }
   513  
   514  func (s) TestDialContextCancel(t *testing.T) {
   515  	ctx, cancel := context.WithCancel(context.Background())
   516  	cancel()
   517  	if _, err := DialContext(ctx, "Non-Existent.Server:80", WithBlock(), WithTransportCredentials(insecure.NewCredentials())); err != context.Canceled {
   518  		t.Fatalf("DialContext(%v, _) = _, %v, want _, %v", ctx, err, context.Canceled)
   519  	}
   520  }
   521  
   522  type failFastError struct{}
   523  
   524  func (failFastError) Error() string   { return "failfast" }
   525  func (failFastError) Temporary() bool { return false }
   526  
   527  func (s) TestDialContextFailFast(t *testing.T) {
   528  	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
   529  	defer cancel()
   530  	failErr := failFastError{}
   531  	dialer := func(string, time.Duration) (net.Conn, error) {
   532  		return nil, failErr
   533  	}
   534  
   535  	_, err := DialContext(ctx, "Non-Existent.Server:80", WithBlock(), WithTransportCredentials(insecure.NewCredentials()), WithDialer(dialer), FailOnNonTempDialError(true))
   536  	if terr, ok := err.(transport.ConnectionError); !ok || terr.Origin() != failErr {
   537  		t.Fatalf("DialContext() = _, %v, want _, %v", err, failErr)
   538  	}
   539  }
   540  
   541  // securePerRPCCredentials always requires transport security.
   542  type securePerRPCCredentials struct {
   543  	credentials.PerRPCCredentials
   544  }
   545  
   546  func (c securePerRPCCredentials) RequireTransportSecurity() bool {
   547  	return true
   548  }
   549  
   550  type fakeBundleCreds struct {
   551  	credentials.Bundle
   552  	transportCreds credentials.TransportCredentials
   553  }
   554  
   555  func (b *fakeBundleCreds) TransportCredentials() credentials.TransportCredentials {
   556  	return b.transportCreds
   557  }
   558  
   559  func (s) TestCredentialsMisuse(t *testing.T) {
   560  	// Use of no transport creds and no creds bundle must fail.
   561  	if _, err := NewClient("passthrough:///Non-Existent.Server:80"); err != errNoTransportSecurity {
   562  		t.Fatalf("grpc.NewClient() failed with error: %v, want: %v", err, errNoTransportSecurity)
   563  	}
   564  
   565  	// Use of both transport creds and creds bundle must fail.
   566  	creds, err := credentials.NewClientTLSFromFile(testdata.Path("x509/server_ca_cert.pem"), "x.test.example.com")
   567  	if err != nil {
   568  		t.Fatalf("Failed to create authenticator %v", err)
   569  	}
   570  	dopts := []DialOption{
   571  		WithTransportCredentials(creds),
   572  		WithCredentialsBundle(&fakeBundleCreds{transportCreds: creds}),
   573  	}
   574  	if _, err := NewClient("passthrough:///Non-Existent.Server:80", dopts...); err != errTransportCredsAndBundle {
   575  		t.Fatalf("grpc.NewClient() failed with error: %v, want: %v", err, errTransportCredsAndBundle)
   576  	}
   577  
   578  	// Use of perRPC creds requiring transport security over an insecure
   579  	// transport must fail.
   580  	if _, err := NewClient("passthrough:///Non-Existent.Server:80", WithPerRPCCredentials(securePerRPCCredentials{}), WithTransportCredentials(insecure.NewCredentials())); err != errTransportCredentialsMissing {
   581  		t.Fatalf("grpc.NewClient() failed with error: %v, want: %v", err, errTransportCredentialsMissing)
   582  	}
   583  
   584  	// Use of a creds bundle with nil transport credentials must fail.
   585  	if _, err := NewClient("passthrough:///Non-Existent.Server:80", WithCredentialsBundle(&fakeBundleCreds{})); err != errNoTransportCredsInBundle {
   586  		t.Fatalf("grpc.NewClient() failed with error: %v, want: %v", err, errTransportCredsAndBundle)
   587  	}
   588  }
   589  
   590  func (s) TestWithBackoffConfigDefault(t *testing.T) {
   591  	testBackoffConfigSet(t, internalbackoff.DefaultExponential)
   592  }
   593  
   594  func (s) TestWithBackoffConfig(t *testing.T) {
   595  	b := BackoffConfig{MaxDelay: DefaultBackoffConfig.MaxDelay / 2}
   596  	bc := backoff.DefaultConfig
   597  	bc.MaxDelay = b.MaxDelay
   598  	wantBackoff := internalbackoff.Exponential{Config: bc}
   599  	testBackoffConfigSet(t, wantBackoff, WithBackoffConfig(b))
   600  }
   601  
   602  func (s) TestWithBackoffMaxDelay(t *testing.T) {
   603  	md := DefaultBackoffConfig.MaxDelay / 2
   604  	bc := backoff.DefaultConfig
   605  	bc.MaxDelay = md
   606  	wantBackoff := internalbackoff.Exponential{Config: bc}
   607  	testBackoffConfigSet(t, wantBackoff, WithBackoffMaxDelay(md))
   608  }
   609  
   610  func (s) TestWithConnectParams(t *testing.T) {
   611  	bd := 2 * time.Second
   612  	mltpr := 2.0
   613  	jitter := 0.0
   614  	bc := backoff.Config{BaseDelay: bd, Multiplier: mltpr, Jitter: jitter}
   615  
   616  	crt := ConnectParams{Backoff: bc}
   617  	// MaxDelay is not set in the ConnectParams. So it should not be set on
   618  	// internalbackoff.Exponential as well.
   619  	wantBackoff := internalbackoff.Exponential{Config: bc}
   620  	testBackoffConfigSet(t, wantBackoff, WithConnectParams(crt))
   621  }
   622  
   623  func testBackoffConfigSet(t *testing.T, wantBackoff internalbackoff.Exponential, opts ...DialOption) {
   624  	opts = append(opts, WithTransportCredentials(insecure.NewCredentials()))
   625  	conn, err := NewClient("passthrough:///foo:80", opts...)
   626  	if err != nil {
   627  		t.Fatalf("grpc.NewClient() failed: %v", err)
   628  	}
   629  	defer conn.Close()
   630  
   631  	if conn.dopts.bs == nil {
   632  		t.Fatalf("backoff config not set")
   633  	}
   634  
   635  	gotBackoff, ok := conn.dopts.bs.(internalbackoff.Exponential)
   636  	if !ok {
   637  		t.Fatalf("unexpected type of backoff config: %#v", conn.dopts.bs)
   638  	}
   639  
   640  	if gotBackoff != wantBackoff {
   641  		t.Fatalf("unexpected backoff config on connection: %v, want %v", gotBackoff, wantBackoff)
   642  	}
   643  }
   644  
   645  func (s) TestConnectParamsWithMinConnectTimeout(t *testing.T) {
   646  	// Default value specified for minConnectTimeout in the spec is 20 seconds.
   647  	mct := 1 * time.Minute
   648  	conn, err := NewClient("passthrough:///foo:80", WithTransportCredentials(insecure.NewCredentials()), WithConnectParams(ConnectParams{MinConnectTimeout: mct}))
   649  	if err != nil {
   650  		t.Fatalf("grpc.NewClient() failed: %v", err)
   651  	}
   652  	defer conn.Close()
   653  
   654  	if got := conn.dopts.minConnectTimeout(); got != mct {
   655  		t.Errorf("unexpected minConnectTimeout on the connection: %v, want %v", got, mct)
   656  	}
   657  }
   658  
   659  func (s) TestResolverServiceConfigBeforeAddressNotPanic(t *testing.T) {
   660  	r := manual.NewBuilderWithScheme("whatever")
   661  
   662  	cc, err := NewClient(r.Scheme()+":///test.server", WithTransportCredentials(insecure.NewCredentials()), WithResolvers(r))
   663  	if err != nil {
   664  		t.Fatalf("grpc.NewClient() failed: %v", err)
   665  	}
   666  	defer cc.Close()
   667  	cc.Connect()
   668  	// SwitchBalancer before NewAddress. There was no balancer created, this
   669  	// makes sure we don't call close on nil balancerWrapper.
   670  	r.UpdateState(resolver.State{ServiceConfig: r.CC().ParseServiceConfig(grpclbServiceConfig)}) // This should not panic.
   671  
   672  	time.Sleep(time.Second) // Sleep to make sure the service config is handled by ClientConn.
   673  }
   674  
   675  func (s) TestResolverServiceConfigWhileClosingNotPanic(t *testing.T) {
   676  	for i := 0; i < 10; i++ { // Run this multiple times to make sure it doesn't panic.
   677  		r := manual.NewBuilderWithScheme(fmt.Sprintf("whatever-%d", i))
   678  		cc, err := NewClient(r.Scheme()+":///test.server", WithTransportCredentials(insecure.NewCredentials()), WithResolvers(r))
   679  		if err != nil {
   680  			t.Fatalf("grpc.NewClient() failed: %v", err)
   681  		}
   682  		cc.Connect()
   683  		// Send a new service config while closing the ClientConn.
   684  		go cc.Close()
   685  		go r.UpdateState(resolver.State{ServiceConfig: r.CC().ParseServiceConfig(rrServiceConfig)}) // This should not panic.
   686  	}
   687  }
   688  
   689  func (s) TestResolverEmptyUpdateNotPanic(t *testing.T) {
   690  	r := manual.NewBuilderWithScheme("whatever")
   691  
   692  	cc, err := NewClient(r.Scheme()+":///test.server", WithTransportCredentials(insecure.NewCredentials()), WithResolvers(r))
   693  	if err != nil {
   694  		t.Fatalf("grpc.NewClient() failed: %v", err)
   695  	}
   696  	defer cc.Close()
   697  	cc.Connect()
   698  	// This make sure we don't create addrConn with empty address list.
   699  	r.UpdateState(resolver.State{}) // This should not panic.
   700  
   701  	time.Sleep(time.Second) // Sleep to make sure the service config is handled by ClientConn.
   702  }
   703  
   704  func (s) TestClientUpdatesParamsAfterGoAway(t *testing.T) {
   705  	grpctest.TLogger.ExpectError("Client received GoAway with error code ENHANCE_YOUR_CALM and debug data equal to ASCII \"too_many_pings\"")
   706  
   707  	lis, err := net.Listen("tcp", "localhost:0")
   708  	if err != nil {
   709  		t.Fatalf("Failed to listen. Err: %v", err)
   710  	}
   711  	defer lis.Close()
   712  	connected := grpcsync.NewEvent()
   713  	defer connected.Fire()
   714  	go func() {
   715  		conn, err := lis.Accept()
   716  		if err != nil {
   717  			t.Errorf("error accepting connection: %v", err)
   718  			return
   719  		}
   720  		defer conn.Close()
   721  		f := http2.NewFramer(conn, conn)
   722  		// Start a goroutine to read from the conn to prevent the client from
   723  		// blocking after it writes its preface.
   724  		go func() {
   725  			for {
   726  				if _, err := f.ReadFrame(); err != nil {
   727  					return
   728  				}
   729  			}
   730  		}()
   731  		if err := f.WriteSettings(http2.Setting{}); err != nil {
   732  			t.Errorf("error writing settings: %v", err)
   733  			return
   734  		}
   735  		<-connected.Done()
   736  		if err := f.WriteGoAway(0, http2.ErrCodeEnhanceYourCalm, []byte("too_many_pings")); err != nil {
   737  			t.Errorf("error writing GOAWAY: %v", err)
   738  			return
   739  		}
   740  	}()
   741  	addr := lis.Addr().String()
   742  	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
   743  	defer cancel()
   744  	cc, err := DialContext(ctx, addr, WithBlock(), WithTransportCredentials(insecure.NewCredentials()), WithKeepaliveParams(keepalive.ClientParameters{
   745  		Time:                10 * time.Second,
   746  		Timeout:             100 * time.Millisecond,
   747  		PermitWithoutStream: true,
   748  	}))
   749  	if err != nil {
   750  		t.Fatalf("DialContext(%s) failed: %v, want: nil", addr, err)
   751  	}
   752  	defer cc.Close()
   753  	connected.Fire()
   754  	for {
   755  		time.Sleep(10 * time.Millisecond)
   756  		cc.mu.RLock()
   757  		v := cc.keepaliveParams.Time
   758  		cc.mu.RUnlock()
   759  		if v == 20*time.Second {
   760  			// Success
   761  			return
   762  		}
   763  		if ctx.Err() != nil {
   764  			// Timeout
   765  			t.Fatalf("cc.dopts.copts.Keepalive.Time = %v , want 20s", v)
   766  		}
   767  	}
   768  }
   769  
   770  func (s) TestDisableServiceConfigOption(t *testing.T) {
   771  	r := manual.NewBuilderWithScheme("whatever")
   772  	addr := r.Scheme() + ":///non.existent"
   773  	cc, err := NewClient(addr, WithTransportCredentials(insecure.NewCredentials()), WithResolvers(r), WithDisableServiceConfig())
   774  	if err != nil {
   775  		t.Fatalf("grpc.NewClient(%s) failed: %v, want: nil", addr, err)
   776  	}
   777  	defer cc.Close()
   778  	cc.Connect()
   779  	r.UpdateState(resolver.State{ServiceConfig: r.CC().ParseServiceConfig(`{
   780      "methodConfig": [
   781          {
   782              "name": [
   783                  {
   784                      "service": "foo",
   785                      "method": "Bar"
   786                  }
   787              ],
   788              "waitForReady": true
   789          }
   790      ]
   791  }`)})
   792  	time.Sleep(1 * time.Second)
   793  	m := cc.GetMethodConfig("/foo/Bar")
   794  	if m.WaitForReady != nil {
   795  		t.Fatalf("want: method (\"/foo/bar/\") config to be empty, got: %+v", m)
   796  	}
   797  }
   798  
   799  func (s) TestMethodConfigDefaultService(t *testing.T) {
   800  	addr := "passthrough:///non.existent"
   801  	cc, err := NewClient(addr, WithTransportCredentials(insecure.NewCredentials()), WithDefaultServiceConfig(`{
   802    "methodConfig": [{
   803      "name": [
   804        {
   805          "service": ""
   806        }
   807      ],
   808      "waitForReady": true
   809    }]
   810  }`))
   811  	if err != nil {
   812  		t.Fatalf("grpc.NewClient(%s) failed: %v, want: nil", addr, err)
   813  	}
   814  	cc.Connect()
   815  	defer cc.Close()
   816  
   817  	m := cc.GetMethodConfig("/foo/Bar")
   818  	if m.WaitForReady == nil {
   819  		t.Fatalf("want: method (%q) config to fallback to the default service", "/foo/Bar")
   820  	}
   821  }
   822  
   823  func (s) TestClientConnCanonicalTarget(t *testing.T) {
   824  	tests := []struct {
   825  		name                string
   826  		addr                string
   827  		canonicalTargetWant string
   828  	}{
   829  		{
   830  			name:                "normal-case",
   831  			addr:                "dns://a.server.com/google.com",
   832  			canonicalTargetWant: "dns://a.server.com/google.com",
   833  		},
   834  		{
   835  			name:                "canonical-target-not-specified",
   836  			addr:                "no.scheme",
   837  			canonicalTargetWant: "dns:///no.scheme",
   838  		},
   839  		{
   840  			name:                "canonical-target-nonexistent",
   841  			addr:                "nonexist:///non.existent",
   842  			canonicalTargetWant: "dns:///nonexist:///non.existent",
   843  		},
   844  		{
   845  			name:                "canonical-target-add-colon-slash",
   846  			addr:                "dns:hostname:port",
   847  			canonicalTargetWant: "dns:///hostname:port",
   848  		},
   849  	}
   850  	for _, test := range tests {
   851  		t.Run(test.name, func(t *testing.T) {
   852  			cc, err := NewClient(test.addr, WithTransportCredentials(insecure.NewCredentials()))
   853  			if err != nil {
   854  				t.Fatalf("grpc.NewClient(%s) failed: %v, want: nil", test.addr, err)
   855  			}
   856  			defer cc.Close()
   857  			if cc.Target() != test.addr {
   858  				t.Fatalf("Target() = %s, want %s", cc.Target(), test.addr)
   859  			}
   860  			if cc.CanonicalTarget() != test.canonicalTargetWant {
   861  				t.Fatalf("CanonicalTarget() = %s, want %s", cc.CanonicalTarget(), test.canonicalTargetWant)
   862  			}
   863  		})
   864  	}
   865  }
   866  
   867  type backoffForever struct{}
   868  
   869  func (b backoffForever) Backoff(int) time.Duration { return time.Duration(math.MaxInt64) }
   870  
   871  func (s) TestResetConnectBackoff(t *testing.T) {
   872  	dials := make(chan struct{})
   873  	defer func() { // If we fail, let the http2client break out of dialing.
   874  		select {
   875  		case <-dials:
   876  		default:
   877  		}
   878  	}()
   879  	dialer := func(string, time.Duration) (net.Conn, error) {
   880  		dials <- struct{}{}
   881  		return nil, errors.New("failed to fake dial")
   882  	}
   883  	cc, err := NewClient("passthrough:///", WithTransportCredentials(insecure.NewCredentials()), WithDialer(dialer), withBackoff(backoffForever{}))
   884  	if err != nil {
   885  		t.Fatalf("grpc.NewClient() failed with error: %v, want: nil", err)
   886  	}
   887  	defer cc.Close()
   888  	go stayConnected(cc)
   889  	select {
   890  	case <-dials:
   891  	case <-time.NewTimer(10 * time.Second).C:
   892  		t.Fatal("Failed to call dial within 10s")
   893  	}
   894  
   895  	select {
   896  	case <-dials:
   897  		t.Fatal("Dial called unexpectedly before resetting backoff")
   898  	case <-time.NewTimer(100 * time.Millisecond).C:
   899  	}
   900  
   901  	cc.ResetConnectBackoff()
   902  
   903  	select {
   904  	case <-dials:
   905  	case <-time.NewTimer(10 * time.Second).C:
   906  		t.Fatal("Failed to call dial within 10s after resetting backoff")
   907  	}
   908  }
   909  
   910  func (s) TestBackoffCancel(t *testing.T) {
   911  	dialStrCh := make(chan string)
   912  	cc, err := NewClient("passthrough:///", WithTransportCredentials(insecure.NewCredentials()), WithDialer(func(t string, _ time.Duration) (net.Conn, error) {
   913  		dialStrCh <- t
   914  		return nil, fmt.Errorf("test dialer, always error")
   915  	}))
   916  	if err != nil {
   917  		t.Fatalf("grpc.NewClient() failed: %v", err)
   918  	}
   919  	cc.Connect()
   920  	defer cc.Close()
   921  
   922  	select {
   923  	case <-time.After(defaultTestTimeout):
   924  		t.Fatal("Timeout when waiting for custom dialer to be invoked during Connect()")
   925  	case <-dialStrCh:
   926  	}
   927  }
   928  
   929  // TestUpdateAddresses_NoopIfCalledWithSameAddresses tests that UpdateAddresses
   930  // should be noop if UpdateAddresses is called with the same list of addresses,
   931  // even when the SubConn is in Connecting and doesn't have a current address.
   932  func (s) TestUpdateAddresses_NoopIfCalledWithSameAddresses(t *testing.T) {
   933  	lis1, err := net.Listen("tcp", "localhost:0")
   934  	if err != nil {
   935  		t.Fatalf("Error while listening. Err: %v", err)
   936  	}
   937  	defer lis1.Close()
   938  
   939  	lis2, err := net.Listen("tcp", "localhost:0")
   940  	if err != nil {
   941  		t.Fatalf("Error while listening. Err: %v", err)
   942  	}
   943  	defer lis2.Close()
   944  
   945  	lis3, err := net.Listen("tcp", "localhost:0")
   946  	if err != nil {
   947  		t.Fatalf("Error while listening. Err: %v", err)
   948  	}
   949  	defer lis3.Close()
   950  
   951  	closeServer2 := make(chan struct{})
   952  	exitCh := make(chan struct{})
   953  	server1ContactedFirstTime := make(chan struct{})
   954  	server1ContactedSecondTime := make(chan struct{})
   955  	server2ContactedFirstTime := make(chan struct{})
   956  	server2ContactedSecondTime := make(chan struct{})
   957  	server3Contacted := make(chan struct{})
   958  
   959  	defer close(exitCh)
   960  
   961  	// Launch server 1.
   962  	go func() {
   963  		// First, let's allow the initial connection to go READY. We need to do
   964  		// this because tryUpdateAddrs only works after there's some non-nil
   965  		// address on the ac, and curAddress is only set after READY.
   966  		conn1, err := lis1.Accept()
   967  		if err != nil {
   968  			t.Error(err)
   969  			return
   970  		}
   971  		go keepReading(conn1)
   972  
   973  		framer := http2.NewFramer(conn1, conn1)
   974  		if err := framer.WriteSettings(http2.Setting{}); err != nil {
   975  			t.Errorf("Error while writing settings frame. %v", err)
   976  			return
   977  		}
   978  
   979  		// nextStateNotifier() is updated after balancerBuilder.Build(), which
   980  		// is called by ClientConn.Connect in stayConnected. It's safe to do it
   981  		// here because lis1.Accept blocks until ClientConn.Connect is called
   982  		// and the balancer is built to process the addresses.
   983  		stateNotifications := testBalancerBuilder.nextStateNotifier()
   984  		// Wait for the transport to become ready.
   985  		for {
   986  			select {
   987  			case st := <-stateNotifications:
   988  				if st == connectivity.Ready {
   989  					goto ready
   990  				}
   991  			case <-exitCh:
   992  				return
   993  			}
   994  		}
   995  
   996  	ready:
   997  		// Once it's ready, curAddress has been set. So let's close this
   998  		// connection prompting the first reconnect cycle.
   999  		conn1.Close()
  1000  
  1001  		// Accept and immediately close, causing it to go to server2.
  1002  		conn2, err := lis1.Accept()
  1003  		if err != nil {
  1004  			t.Error(err)
  1005  			return
  1006  		}
  1007  		close(server1ContactedFirstTime)
  1008  		conn2.Close()
  1009  
  1010  		// Hopefully it picks this server after tryUpdateAddrs.
  1011  		lis1.Accept()
  1012  		close(server1ContactedSecondTime)
  1013  	}()
  1014  	// Launch server 2.
  1015  	go func() {
  1016  		// Accept and then hang waiting for the test call tryUpdateAddrs and
  1017  		// then signal to this server to close. After this server closes, it
  1018  		// should start from the top instead of trying server2 or continuing
  1019  		// to server3.
  1020  		conn, err := lis2.Accept()
  1021  		if err != nil {
  1022  			t.Error(err)
  1023  			return
  1024  		}
  1025  
  1026  		close(server2ContactedFirstTime)
  1027  		<-closeServer2
  1028  		conn.Close()
  1029  
  1030  		// After tryUpdateAddrs, it should NOT try server2.
  1031  		lis2.Accept()
  1032  		close(server2ContactedSecondTime)
  1033  	}()
  1034  	// Launch server 3.
  1035  	go func() {
  1036  		// After tryUpdateAddrs, it should NOT try server3. (or any other time)
  1037  		lis3.Accept()
  1038  		close(server3Contacted)
  1039  	}()
  1040  
  1041  	addrsList := []resolver.Address{
  1042  		{Addr: lis1.Addr().String()},
  1043  		{Addr: lis2.Addr().String()},
  1044  		{Addr: lis3.Addr().String()},
  1045  	}
  1046  	rb := manual.NewBuilderWithScheme("whatever")
  1047  	rb.InitialState(resolver.State{Addresses: addrsList})
  1048  
  1049  	client, err := NewClient("whatever:///this-gets-overwritten",
  1050  		WithTransportCredentials(insecure.NewCredentials()),
  1051  		WithResolvers(rb),
  1052  		WithConnectParams(ConnectParams{
  1053  			Backoff:           backoff.Config{},
  1054  			MinConnectTimeout: time.Hour,
  1055  		}),
  1056  		WithDefaultServiceConfig(fmt.Sprintf(`{"loadBalancingConfig": [{"%s":{}}]}`, stateRecordingBalancerName)))
  1057  	if err != nil {
  1058  		t.Fatal(err)
  1059  	}
  1060  	defer client.Close()
  1061  	go stayConnected(client)
  1062  
  1063  	timeout := time.After(5 * time.Second)
  1064  
  1065  	// Wait for server1 to be contacted (which will immediately fail), then
  1066  	// server2 (which will hang waiting for our signal).
  1067  	select {
  1068  	case <-server1ContactedFirstTime:
  1069  	case <-timeout:
  1070  		t.Fatal("timed out waiting for server1 to be contacted")
  1071  	}
  1072  	select {
  1073  	case <-server2ContactedFirstTime:
  1074  	case <-timeout:
  1075  		t.Fatal("timed out waiting for server2 to be contacted")
  1076  	}
  1077  
  1078  	// Grab the addrConn and call tryUpdateAddrs.
  1079  	client.mu.Lock()
  1080  	for clientAC := range client.conns {
  1081  		// Call UpdateAddresses with the same list of addresses, it should be a noop
  1082  		// (even when the SubConn is Connecting, and doesn't have a curAddr).
  1083  		clientAC.acbw.UpdateAddresses(clientAC.addrs)
  1084  	}
  1085  	client.mu.Unlock()
  1086  
  1087  	// We've called tryUpdateAddrs - now let's make server2 close the
  1088  	// connection and check that it continues to server3.
  1089  	close(closeServer2)
  1090  
  1091  	select {
  1092  	case <-server1ContactedSecondTime:
  1093  		t.Fatal("server1 was contacted a second time, but it should have continued to server 3")
  1094  	case <-server2ContactedSecondTime:
  1095  		t.Fatal("server2 was contacted a second time, but it should have continued to server 3")
  1096  	case <-server3Contacted:
  1097  	case <-timeout:
  1098  		t.Fatal("timed out waiting for any server to be contacted after tryUpdateAddrs")
  1099  	}
  1100  }
  1101  
  1102  func (s) TestDefaultServiceConfig(t *testing.T) {
  1103  	const defaultSC = `
  1104  {
  1105      "methodConfig": [
  1106          {
  1107              "name": [
  1108                  {
  1109                      "service": "foo",
  1110                      "method": "bar"
  1111                  }
  1112              ],
  1113              "waitForReady": true
  1114          }
  1115      ]
  1116  }`
  1117  	tests := []struct {
  1118  		name  string
  1119  		testF func(t *testing.T, r *manual.Resolver, addr, sc string)
  1120  		sc    string
  1121  	}{
  1122  		{
  1123  			name:  "invalid-service-config",
  1124  			testF: testInvalidDefaultServiceConfig,
  1125  			sc:    "",
  1126  		},
  1127  		{
  1128  			name:  "resolver-service-config-disabled",
  1129  			testF: testDefaultServiceConfigWhenResolverServiceConfigDisabled,
  1130  			sc:    defaultSC,
  1131  		},
  1132  		{
  1133  			name:  "resolver-does-not-return-service-config",
  1134  			testF: testDefaultServiceConfigWhenResolverDoesNotReturnServiceConfig,
  1135  			sc:    defaultSC,
  1136  		},
  1137  		{
  1138  			name:  "resolver-returns-invalid-service-config",
  1139  			testF: testDefaultServiceConfigWhenResolverReturnInvalidServiceConfig,
  1140  			sc:    defaultSC,
  1141  		},
  1142  	}
  1143  
  1144  	for _, test := range tests {
  1145  		t.Run(test.name, func(t *testing.T) {
  1146  			r := manual.NewBuilderWithScheme(test.name)
  1147  			addr := r.Scheme() + ":///non.existent"
  1148  			test.testF(t, r, addr, test.sc)
  1149  		})
  1150  	}
  1151  }
  1152  
  1153  func verifyWaitForReadyEqualsTrue(cc *ClientConn) bool {
  1154  	var i int
  1155  	for i = 0; i < 10; i++ {
  1156  		mc := cc.GetMethodConfig("/foo/bar")
  1157  		if mc.WaitForReady != nil && *mc.WaitForReady == true {
  1158  			break
  1159  		}
  1160  		time.Sleep(100 * time.Millisecond)
  1161  	}
  1162  	return i != 10
  1163  }
  1164  
  1165  func testInvalidDefaultServiceConfig(t *testing.T, r *manual.Resolver, addr, sc string) {
  1166  	_, err := NewClient(addr, WithTransportCredentials(insecure.NewCredentials()), WithResolvers(r), WithDefaultServiceConfig(sc))
  1167  	if !strings.Contains(err.Error(), invalidDefaultServiceConfigErrPrefix) {
  1168  		t.Fatalf("grpc.NewClient() got err: %v, want err contains: %v", err, invalidDefaultServiceConfigErrPrefix)
  1169  	}
  1170  }
  1171  
  1172  func testDefaultServiceConfigWhenResolverServiceConfigDisabled(t *testing.T, r *manual.Resolver, addr string, js string) {
  1173  	cc, err := NewClient(addr, WithTransportCredentials(insecure.NewCredentials()), WithDisableServiceConfig(), WithResolvers(r), WithDefaultServiceConfig(js))
  1174  	if err != nil {
  1175  		t.Fatalf("grpc.NewClient(%s) failed: %v, want: nil", addr, err)
  1176  	}
  1177  	cc.Connect()
  1178  	defer cc.Close()
  1179  	// Resolver service config gets ignored since resolver service config is disabled.
  1180  	r.UpdateState(resolver.State{
  1181  		Addresses:     []resolver.Address{{Addr: addr}},
  1182  		ServiceConfig: parseCfg(r, "{}"),
  1183  	})
  1184  	if !verifyWaitForReadyEqualsTrue(cc) {
  1185  		t.Fatal("default service config failed to be applied after 1s")
  1186  	}
  1187  }
  1188  
  1189  func testDefaultServiceConfigWhenResolverDoesNotReturnServiceConfig(t *testing.T, r *manual.Resolver, addr string, js string) {
  1190  	cc, err := NewClient(addr, WithTransportCredentials(insecure.NewCredentials()), WithResolvers(r), WithDefaultServiceConfig(js))
  1191  	if err != nil {
  1192  		t.Fatalf("grpc.NewClient(%s) failed: %v, want: nil", addr, err)
  1193  	}
  1194  	cc.Connect()
  1195  	defer cc.Close()
  1196  	r.UpdateState(resolver.State{
  1197  		Addresses: []resolver.Address{{Addr: addr}},
  1198  	})
  1199  	if !verifyWaitForReadyEqualsTrue(cc) {
  1200  		t.Fatal("default service config failed to be applied after 1s")
  1201  	}
  1202  }
  1203  
  1204  func testDefaultServiceConfigWhenResolverReturnInvalidServiceConfig(t *testing.T, r *manual.Resolver, addr string, js string) {
  1205  	cc, err := NewClient(addr, WithTransportCredentials(insecure.NewCredentials()), WithResolvers(r), WithDefaultServiceConfig(js))
  1206  	if err != nil {
  1207  		t.Fatalf("grpc.NewClient(%s) failed: %v, want: nil", addr, err)
  1208  	}
  1209  	cc.Connect()
  1210  	defer cc.Close()
  1211  	r.UpdateState(resolver.State{
  1212  		Addresses: []resolver.Address{{Addr: addr}},
  1213  	})
  1214  	if !verifyWaitForReadyEqualsTrue(cc) {
  1215  		t.Fatal("default service config failed to be applied after 1s")
  1216  	}
  1217  }
  1218  
  1219  type stateRecordingBalancer struct {
  1220  	balancer.Balancer
  1221  }
  1222  
  1223  func (b *stateRecordingBalancer) UpdateSubConnState(sc balancer.SubConn, s balancer.SubConnState) {
  1224  	panic(fmt.Sprintf("UpdateSubConnState(%v, %+v) called unexpectedly", sc, s))
  1225  }
  1226  
  1227  func (b *stateRecordingBalancer) Close() {
  1228  	b.Balancer.Close()
  1229  }
  1230  
  1231  type stateRecordingBalancerBuilder struct {
  1232  	mu       sync.Mutex
  1233  	notifier chan connectivity.State // The notifier used in the last Balancer.
  1234  }
  1235  
  1236  func newStateRecordingBalancerBuilder() *stateRecordingBalancerBuilder {
  1237  	return &stateRecordingBalancerBuilder{}
  1238  }
  1239  
  1240  func (b *stateRecordingBalancerBuilder) Name() string {
  1241  	return stateRecordingBalancerName
  1242  }
  1243  
  1244  func (b *stateRecordingBalancerBuilder) Build(cc balancer.ClientConn, opts balancer.BuildOptions) balancer.Balancer {
  1245  	stateNotifications := make(chan connectivity.State, 10)
  1246  	b.mu.Lock()
  1247  	b.notifier = stateNotifications
  1248  	b.mu.Unlock()
  1249  	return &stateRecordingBalancer{
  1250  		Balancer: balancer.Get("pick_first").Build(&stateRecordingCCWrapper{cc, stateNotifications}, opts),
  1251  	}
  1252  }
  1253  
  1254  func (b *stateRecordingBalancerBuilder) nextStateNotifier() <-chan connectivity.State {
  1255  	b.mu.Lock()
  1256  	defer b.mu.Unlock()
  1257  	ret := b.notifier
  1258  	b.notifier = nil
  1259  	return ret
  1260  }
  1261  
  1262  type stateRecordingCCWrapper struct {
  1263  	balancer.ClientConn
  1264  	notifier chan<- connectivity.State
  1265  }
  1266  
  1267  func (ccw *stateRecordingCCWrapper) NewSubConn(addrs []resolver.Address, opts balancer.NewSubConnOptions) (balancer.SubConn, error) {
  1268  	oldListener := opts.StateListener
  1269  	opts.StateListener = func(s balancer.SubConnState) {
  1270  		ccw.notifier <- s.ConnectivityState
  1271  		oldListener(s)
  1272  	}
  1273  	return ccw.ClientConn.NewSubConn(addrs, opts)
  1274  }
  1275  
  1276  // Keep reading until something causes the connection to die (EOF, server
  1277  // closed, etc). Useful as a tool for mindlessly keeping the connection
  1278  // healthy, since the client will error if things like client prefaces are not
  1279  // accepted in a timely fashion.
  1280  func keepReading(conn net.Conn) {
  1281  	buf := make([]byte, 1024)
  1282  	for _, err := conn.Read(buf); err == nil; _, err = conn.Read(buf) {
  1283  	}
  1284  }
  1285  
  1286  // stayConnected makes cc stay connected by repeatedly calling cc.Connect()
  1287  // until the state becomes Shutdown or until 10 seconds elapses.
  1288  func stayConnected(cc *ClientConn) {
  1289  	ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
  1290  	defer cancel()
  1291  
  1292  	for {
  1293  		state := cc.GetState()
  1294  		switch state {
  1295  		case connectivity.Idle:
  1296  			cc.Connect()
  1297  		case connectivity.Shutdown:
  1298  			return
  1299  		}
  1300  		if !cc.WaitForStateChange(ctx, state) {
  1301  			return
  1302  		}
  1303  	}
  1304  }
  1305  
  1306  func (s) TestURLAuthorityEscape(t *testing.T) {
  1307  	tests := []struct {
  1308  		name      string
  1309  		authority string
  1310  		want      string
  1311  	}{
  1312  		{
  1313  			name:      "ipv6_authority",
  1314  			authority: "[::1]",
  1315  			want:      "[::1]",
  1316  		},
  1317  		{
  1318  			name:      "with_user_and_host",
  1319  			authority: "userinfo@host:10001",
  1320  			want:      "userinfo@host:10001",
  1321  		},
  1322  		{
  1323  			name:      "with_multiple_slashes",
  1324  			authority: "projects/123/network/abc/service",
  1325  			want:      "projects%2F123%2Fnetwork%2Fabc%2Fservice",
  1326  		},
  1327  		{
  1328  			name:      "all_possible_allowed_chars",
  1329  			authority: "abc123-._~!$&'()*+,;=@:[]",
  1330  			want:      "abc123-._~!$&'()*+,;=@:[]",
  1331  		},
  1332  	}
  1333  
  1334  	for _, test := range tests {
  1335  		t.Run(test.name, func(t *testing.T) {
  1336  			if got, want := encodeAuthority(test.authority), test.want; got != want {
  1337  				t.Errorf("encodeAuthority(%s) = %s, want %s", test.authority, got, test.want)
  1338  			}
  1339  		})
  1340  	}
  1341  }