google.golang.org/grpc@v1.72.2/test/goaway_test.go (about)

     1  /*
     2   *
     3   * Copyright 2019 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 test
    20  
    21  import (
    22  	"context"
    23  	"fmt"
    24  	"io"
    25  	"net"
    26  	"strings"
    27  	"testing"
    28  	"time"
    29  
    30  	"golang.org/x/net/http2"
    31  	"google.golang.org/grpc"
    32  	"google.golang.org/grpc/codes"
    33  	"google.golang.org/grpc/connectivity"
    34  	"google.golang.org/grpc/credentials/insecure"
    35  	"google.golang.org/grpc/internal"
    36  	"google.golang.org/grpc/internal/grpcsync"
    37  	"google.golang.org/grpc/internal/grpctest"
    38  	"google.golang.org/grpc/internal/stubserver"
    39  	"google.golang.org/grpc/internal/testutils"
    40  	"google.golang.org/grpc/keepalive"
    41  	"google.golang.org/grpc/resolver"
    42  	"google.golang.org/grpc/resolver/manual"
    43  	"google.golang.org/grpc/status"
    44  
    45  	testgrpc "google.golang.org/grpc/interop/grpc_testing"
    46  	testpb "google.golang.org/grpc/interop/grpc_testing"
    47  )
    48  
    49  // TestGracefulClientOnGoAway attempts to ensure that when the server sends a
    50  // GOAWAY (in this test, by configuring max connection age on the server), a
    51  // client will never see an error.  This requires that the client is appraised
    52  // of the GOAWAY and updates its state accordingly before the transport stops
    53  // accepting new streams.  If a subconn is chosen by a picker and receives the
    54  // goaway before creating the stream, an error will occur, but upon transparent
    55  // retry, the clientconn will ensure a ready subconn is chosen.
    56  func (s) TestGracefulClientOnGoAway(t *testing.T) {
    57  	const maxConnAge = 100 * time.Millisecond
    58  	const testTime = maxConnAge * 10
    59  	lis, err := testutils.LocalTCPListener()
    60  	if err != nil {
    61  		t.Fatalf("Failed to create listener: %v", err)
    62  	}
    63  	ss := &stubserver.StubServer{
    64  		Listener: lis,
    65  		EmptyCallF: func(context.Context, *testpb.Empty) (*testpb.Empty, error) {
    66  			return &testpb.Empty{}, nil
    67  		},
    68  		S: grpc.NewServer(grpc.KeepaliveParams(keepalive.ServerParameters{MaxConnectionAge: maxConnAge})),
    69  	}
    70  	stubserver.StartTestService(t, ss)
    71  	defer ss.S.Stop()
    72  
    73  	cc, err := grpc.NewClient(lis.Addr().String(), grpc.WithTransportCredentials(insecure.NewCredentials()))
    74  	if err != nil {
    75  		t.Fatalf("Failed to dial server: %v", err)
    76  	}
    77  	defer cc.Close()
    78  	c := testgrpc.NewTestServiceClient(cc)
    79  
    80  	ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
    81  	defer cancel()
    82  	endTime := time.Now().Add(testTime)
    83  	for time.Now().Before(endTime) {
    84  		if _, err := c.EmptyCall(ctx, &testpb.Empty{}); err != nil {
    85  			t.Fatalf("EmptyCall(_, _) = _, %v; want _, <nil>", err)
    86  		}
    87  	}
    88  }
    89  
    90  func (s) TestDetailedGoAwayErrorOnGracefulClosePropagatesToRPCError(t *testing.T) {
    91  	rpcDoneOnClient := make(chan struct{})
    92  	ss := &stubserver.StubServer{
    93  		FullDuplexCallF: func(testgrpc.TestService_FullDuplexCallServer) error {
    94  			<-rpcDoneOnClient
    95  			return status.Error(codes.Internal, "arbitrary status")
    96  		},
    97  	}
    98  	sopts := []grpc.ServerOption{
    99  		grpc.KeepaliveParams(keepalive.ServerParameters{
   100  			MaxConnectionAge:      time.Millisecond * 100,
   101  			MaxConnectionAgeGrace: time.Nanosecond, // ~instantaneously, but non-zero to avoid default
   102  		}),
   103  	}
   104  	if err := ss.Start(sopts); err != nil {
   105  		t.Fatalf("Error starting endpoint server: %v", err)
   106  	}
   107  	defer ss.Stop()
   108  
   109  	ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
   110  	defer cancel()
   111  	stream, err := ss.Client.FullDuplexCall(ctx)
   112  	if err != nil {
   113  		t.Fatalf("%v.FullDuplexCall = _, %v, want _, <nil>", ss.Client, err)
   114  	}
   115  	const expectedErrorMessageSubstring = "received prior goaway: code: NO_ERROR"
   116  	_, err = stream.Recv()
   117  	close(rpcDoneOnClient)
   118  	if err == nil || !strings.Contains(err.Error(), expectedErrorMessageSubstring) {
   119  		t.Fatalf("%v.Recv() = _, %v, want _, rpc error containing substring: %q", stream, err, expectedErrorMessageSubstring)
   120  	}
   121  }
   122  
   123  func (s) TestDetailedGoAwayErrorOnAbruptClosePropagatesToRPCError(t *testing.T) {
   124  	grpctest.TLogger.ExpectError("Client received GoAway with error code ENHANCE_YOUR_CALM and debug data equal to ASCII \"too_many_pings\"")
   125  	// set the min keepalive time very low so that this test can take
   126  	// a reasonable amount of time
   127  	prev := internal.KeepaliveMinPingTime
   128  	internal.KeepaliveMinPingTime = time.Millisecond
   129  	defer func() { internal.KeepaliveMinPingTime = prev }()
   130  
   131  	rpcDoneOnClient := make(chan struct{})
   132  	ss := &stubserver.StubServer{
   133  		FullDuplexCallF: func(testgrpc.TestService_FullDuplexCallServer) error {
   134  			<-rpcDoneOnClient
   135  			return status.Error(codes.Internal, "arbitrary status")
   136  		},
   137  	}
   138  	sopts := []grpc.ServerOption{
   139  		grpc.KeepaliveEnforcementPolicy(keepalive.EnforcementPolicy{
   140  			MinTime: time.Second * 1000, /* arbitrary, large value */
   141  		}),
   142  	}
   143  	dopts := []grpc.DialOption{
   144  		grpc.WithKeepaliveParams(keepalive.ClientParameters{
   145  			Time:                time.Millisecond,   /* should trigger "too many pings" error quickly */
   146  			Timeout:             time.Second * 1000, /* arbitrary, large value */
   147  			PermitWithoutStream: false,
   148  		}),
   149  	}
   150  	if err := ss.Start(sopts, dopts...); err != nil {
   151  		t.Fatalf("Error starting endpoint server: %v", err)
   152  	}
   153  	defer ss.Stop()
   154  
   155  	ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
   156  	defer cancel()
   157  	stream, err := ss.Client.FullDuplexCall(ctx)
   158  	if err != nil {
   159  		t.Fatalf("%v.FullDuplexCall = _, %v, want _, <nil>", ss.Client, err)
   160  	}
   161  	const expectedErrorMessageSubstring = `received prior goaway: code: ENHANCE_YOUR_CALM, debug data: "too_many_pings"`
   162  	_, err = stream.Recv()
   163  	close(rpcDoneOnClient)
   164  	if err == nil || !strings.Contains(err.Error(), expectedErrorMessageSubstring) {
   165  		t.Fatalf("%v.Recv() = _, %v, want _, rpc error containing substring: |%v|", stream, err, expectedErrorMessageSubstring)
   166  	}
   167  }
   168  
   169  func (s) TestClientConnCloseAfterGoAwayWithActiveStream(t *testing.T) {
   170  	for _, e := range listTestEnv() {
   171  		if e.name == "handler-tls" {
   172  			continue
   173  		}
   174  		testClientConnCloseAfterGoAwayWithActiveStream(t, e)
   175  	}
   176  }
   177  
   178  func testClientConnCloseAfterGoAwayWithActiveStream(t *testing.T, e env) {
   179  	te := newTest(t, e)
   180  	te.startServer(&testServer{security: e.security})
   181  	defer te.tearDown()
   182  	cc := te.clientConn()
   183  	tc := testgrpc.NewTestServiceClient(cc)
   184  
   185  	ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
   186  	defer cancel()
   187  	if _, err := tc.FullDuplexCall(ctx); err != nil {
   188  		t.Fatalf("%v.FullDuplexCall(_) = _, %v, want _, <nil>", tc, err)
   189  	}
   190  	done := make(chan struct{})
   191  	go func() {
   192  		te.srv.GracefulStop()
   193  		close(done)
   194  	}()
   195  	time.Sleep(50 * time.Millisecond)
   196  	cc.Close()
   197  	timeout := time.NewTimer(time.Second)
   198  	select {
   199  	case <-done:
   200  	case <-timeout.C:
   201  		t.Fatalf("Test timed-out.")
   202  	}
   203  }
   204  
   205  func (s) TestServerGoAway(t *testing.T) {
   206  	for _, e := range listTestEnv() {
   207  		if e.name == "handler-tls" {
   208  			continue
   209  		}
   210  		testServerGoAway(t, e)
   211  	}
   212  }
   213  
   214  func testServerGoAway(t *testing.T, e env) {
   215  	te := newTest(t, e)
   216  	te.userAgent = testAppUA
   217  	te.startServer(&testServer{security: e.security})
   218  	defer te.tearDown()
   219  
   220  	cc := te.clientConn()
   221  	tc := testgrpc.NewTestServiceClient(cc)
   222  	// Finish an RPC to make sure the connection is good.
   223  	ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
   224  	defer cancel()
   225  	if _, err := tc.EmptyCall(ctx, &testpb.Empty{}, grpc.WaitForReady(true)); err != nil {
   226  		t.Fatalf("TestService/EmptyCall(_, _) = _, %v, want _, <nil>", err)
   227  	}
   228  	ch := make(chan struct{})
   229  	go func() {
   230  		te.srv.GracefulStop()
   231  		close(ch)
   232  	}()
   233  	// Loop until the server side GoAway signal is propagated to the client.
   234  	for {
   235  		ctx, cancel := context.WithTimeout(context.Background(), defaultTestShortTimeout)
   236  		if _, err := tc.EmptyCall(ctx, &testpb.Empty{}); err != nil && status.Code(err) != codes.DeadlineExceeded {
   237  			cancel()
   238  			break
   239  		}
   240  		cancel()
   241  	}
   242  	// A new RPC should fail.
   243  	ctx, cancel = context.WithTimeout(context.Background(), defaultTestTimeout)
   244  	defer cancel()
   245  	if _, err := tc.EmptyCall(ctx, &testpb.Empty{}); status.Code(err) != codes.Unavailable && status.Code(err) != codes.Internal {
   246  		t.Fatalf("TestService/EmptyCall(_, _) = _, %v, want _, %s or %s", err, codes.Unavailable, codes.Internal)
   247  	}
   248  	<-ch
   249  	awaitNewConnLogOutput()
   250  }
   251  
   252  func (s) TestServerGoAwayPendingRPC(t *testing.T) {
   253  	for _, e := range listTestEnv() {
   254  		if e.name == "handler-tls" {
   255  			continue
   256  		}
   257  		testServerGoAwayPendingRPC(t, e)
   258  	}
   259  }
   260  
   261  func testServerGoAwayPendingRPC(t *testing.T, e env) {
   262  	te := newTest(t, e)
   263  	te.userAgent = testAppUA
   264  	te.declareLogNoise(
   265  		"transport: http2Client.notifyError got notified that the client transport was broken EOF",
   266  		"grpc: addrConn.transportMonitor exits due to: grpc: the connection is closing",
   267  		"grpc: addrConn.resetTransport failed to create client transport: connection error",
   268  	)
   269  	te.startServer(&testServer{security: e.security})
   270  	defer te.tearDown()
   271  
   272  	cc := te.clientConn()
   273  	tc := testgrpc.NewTestServiceClient(cc)
   274  	ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
   275  	stream, err := tc.FullDuplexCall(ctx, grpc.WaitForReady(true))
   276  	if err != nil {
   277  		t.Fatalf("%v.FullDuplexCall(_) = _, %v, want <nil>", tc, err)
   278  	}
   279  	// Finish an RPC to make sure the connection is good.
   280  	if _, err := tc.EmptyCall(ctx, &testpb.Empty{}, grpc.WaitForReady(true)); err != nil {
   281  		t.Fatalf("%v.EmptyCall(_, _, _) = _, %v, want _, <nil>", tc, err)
   282  	}
   283  	ch := make(chan struct{})
   284  	go func() {
   285  		te.srv.GracefulStop()
   286  		close(ch)
   287  	}()
   288  	// Loop until the server side GoAway signal is propagated to the client.
   289  	start := time.Now()
   290  	errored := false
   291  	for time.Since(start) < time.Second {
   292  		ctx, cancel := context.WithTimeout(context.Background(), defaultTestShortTimeout)
   293  		_, err := tc.EmptyCall(ctx, &testpb.Empty{}, grpc.WaitForReady(true))
   294  		cancel()
   295  		if err != nil {
   296  			errored = true
   297  			break
   298  		}
   299  	}
   300  	if !errored {
   301  		t.Fatalf("GoAway never received by client")
   302  	}
   303  	respParam := []*testpb.ResponseParameters{{Size: 1}}
   304  	payload, err := newPayload(testpb.PayloadType_COMPRESSABLE, int32(100))
   305  	if err != nil {
   306  		t.Fatal(err)
   307  	}
   308  	req := &testpb.StreamingOutputCallRequest{
   309  		ResponseType:       testpb.PayloadType_COMPRESSABLE,
   310  		ResponseParameters: respParam,
   311  		Payload:            payload,
   312  	}
   313  	// The existing RPC should be still good to proceed.
   314  	if err := stream.Send(req); err != nil {
   315  		t.Fatalf("%v.Send(_) = %v, want <nil>", stream, err)
   316  	}
   317  	if _, err := stream.Recv(); err != nil {
   318  		t.Fatalf("%v.Recv() = _, %v, want _, <nil>", stream, err)
   319  	}
   320  	// The RPC will run until canceled.
   321  	cancel()
   322  	<-ch
   323  	awaitNewConnLogOutput()
   324  }
   325  
   326  func (s) TestServerMultipleGoAwayPendingRPC(t *testing.T) {
   327  	for _, e := range listTestEnv() {
   328  		if e.name == "handler-tls" {
   329  			continue
   330  		}
   331  		testServerMultipleGoAwayPendingRPC(t, e)
   332  	}
   333  }
   334  
   335  func testServerMultipleGoAwayPendingRPC(t *testing.T, e env) {
   336  	te := newTest(t, e)
   337  	te.userAgent = testAppUA
   338  	te.declareLogNoise(
   339  		"transport: http2Client.notifyError got notified that the client transport was broken EOF",
   340  		"grpc: addrConn.transportMonitor exits due to: grpc: the connection is closing",
   341  		"grpc: addrConn.resetTransport failed to create client transport: connection error",
   342  	)
   343  	te.startServer(&testServer{security: e.security})
   344  	defer te.tearDown()
   345  
   346  	cc := te.clientConn()
   347  	tc := testgrpc.NewTestServiceClient(cc)
   348  	ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
   349  	stream, err := tc.FullDuplexCall(ctx, grpc.WaitForReady(true))
   350  	if err != nil {
   351  		t.Fatalf("%v.FullDuplexCall(_) = _, %v, want <nil>", tc, err)
   352  	}
   353  	// Finish an RPC to make sure the connection is good.
   354  	if _, err := tc.EmptyCall(ctx, &testpb.Empty{}, grpc.WaitForReady(true)); err != nil {
   355  		t.Fatalf("%v.EmptyCall(_, _, _) = _, %v, want _, <nil>", tc, err)
   356  	}
   357  	ch1 := make(chan struct{})
   358  	go func() {
   359  		te.srv.GracefulStop()
   360  		close(ch1)
   361  	}()
   362  	ch2 := make(chan struct{})
   363  	go func() {
   364  		te.srv.GracefulStop()
   365  		close(ch2)
   366  	}()
   367  	// Loop until the server side GoAway signal is propagated to the client.
   368  
   369  	for {
   370  		ctx, cancel := context.WithTimeout(context.Background(), defaultTestShortTimeout)
   371  		if _, err := tc.EmptyCall(ctx, &testpb.Empty{}, grpc.WaitForReady(true)); err != nil {
   372  			cancel()
   373  			break
   374  		}
   375  		cancel()
   376  	}
   377  	select {
   378  	case <-ch1:
   379  		t.Fatal("GracefulStop() terminated early")
   380  	case <-ch2:
   381  		t.Fatal("GracefulStop() terminated early")
   382  	default:
   383  	}
   384  	respParam := []*testpb.ResponseParameters{
   385  		{
   386  			Size: 1,
   387  		},
   388  	}
   389  	payload, err := newPayload(testpb.PayloadType_COMPRESSABLE, int32(100))
   390  	if err != nil {
   391  		t.Fatal(err)
   392  	}
   393  	req := &testpb.StreamingOutputCallRequest{
   394  		ResponseType:       testpb.PayloadType_COMPRESSABLE,
   395  		ResponseParameters: respParam,
   396  		Payload:            payload,
   397  	}
   398  	// The existing RPC should be still good to proceed.
   399  	if err := stream.Send(req); err != nil {
   400  		t.Fatalf("%v.Send(%v) = %v, want <nil>", stream, req, err)
   401  	}
   402  	if _, err := stream.Recv(); err != nil {
   403  		t.Fatalf("%v.Recv() = _, %v, want _, <nil>", stream, err)
   404  	}
   405  	if err := stream.CloseSend(); err != nil {
   406  		t.Fatalf("%v.CloseSend() = %v, want <nil>", stream, err)
   407  	}
   408  
   409  	<-ch1
   410  	<-ch2
   411  	cancel()
   412  	awaitNewConnLogOutput()
   413  }
   414  
   415  func (s) TestConcurrentClientConnCloseAndServerGoAway(t *testing.T) {
   416  	for _, e := range listTestEnv() {
   417  		if e.name == "handler-tls" {
   418  			continue
   419  		}
   420  		testConcurrentClientConnCloseAndServerGoAway(t, e)
   421  	}
   422  }
   423  
   424  func testConcurrentClientConnCloseAndServerGoAway(t *testing.T, e env) {
   425  	te := newTest(t, e)
   426  	te.userAgent = testAppUA
   427  	te.declareLogNoise(
   428  		"transport: http2Client.notifyError got notified that the client transport was broken EOF",
   429  		"grpc: addrConn.transportMonitor exits due to: grpc: the connection is closing",
   430  		"grpc: addrConn.resetTransport failed to create client transport: connection error",
   431  	)
   432  	te.startServer(&testServer{security: e.security})
   433  	defer te.tearDown()
   434  
   435  	cc := te.clientConn()
   436  	tc := testgrpc.NewTestServiceClient(cc)
   437  	ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
   438  	defer cancel()
   439  	if _, err := tc.EmptyCall(ctx, &testpb.Empty{}, grpc.WaitForReady(true)); err != nil {
   440  		t.Fatalf("%v.EmptyCall(_, _, _) = _, %v, want _, <nil>", tc, err)
   441  	}
   442  	ch := make(chan struct{})
   443  	// Close ClientConn and Server concurrently.
   444  	go func() {
   445  		te.srv.GracefulStop()
   446  		close(ch)
   447  	}()
   448  	go func() {
   449  		cc.Close()
   450  	}()
   451  	<-ch
   452  }
   453  
   454  func (s) TestConcurrentServerStopAndGoAway(t *testing.T) {
   455  	for _, e := range listTestEnv() {
   456  		if e.name == "handler-tls" {
   457  			continue
   458  		}
   459  		testConcurrentServerStopAndGoAway(t, e)
   460  	}
   461  }
   462  
   463  func testConcurrentServerStopAndGoAway(t *testing.T, e env) {
   464  	te := newTest(t, e)
   465  	te.userAgent = testAppUA
   466  	te.declareLogNoise(
   467  		"transport: http2Client.notifyError got notified that the client transport was broken EOF",
   468  		"grpc: addrConn.transportMonitor exits due to: grpc: the connection is closing",
   469  		"grpc: addrConn.resetTransport failed to create client transport: connection error",
   470  	)
   471  	te.startServer(&testServer{security: e.security})
   472  	defer te.tearDown()
   473  
   474  	cc := te.clientConn()
   475  	tc := testgrpc.NewTestServiceClient(cc)
   476  	ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
   477  	defer cancel()
   478  	stream, err := tc.FullDuplexCall(ctx, grpc.WaitForReady(true))
   479  	if err != nil {
   480  		t.Fatalf("%v.FullDuplexCall(_) = _, %v, want <nil>", tc, err)
   481  	}
   482  
   483  	// Finish an RPC to make sure the connection is good.
   484  	if _, err := tc.EmptyCall(ctx, &testpb.Empty{}, grpc.WaitForReady(true)); err != nil {
   485  		t.Fatalf("%v.EmptyCall(_, _, _) = _, %v, want _, <nil>", tc, err)
   486  	}
   487  
   488  	ch := make(chan struct{})
   489  	go func() {
   490  		te.srv.GracefulStop()
   491  		close(ch)
   492  	}()
   493  	// Loop until the server side GoAway signal is propagated to the client.
   494  	for {
   495  		ctx, cancel := context.WithTimeout(context.Background(), defaultTestShortTimeout)
   496  		if _, err := tc.EmptyCall(ctx, &testpb.Empty{}, grpc.WaitForReady(true)); err != nil {
   497  			cancel()
   498  			break
   499  		}
   500  		cancel()
   501  	}
   502  	// Stop the server and close all the connections.
   503  	te.srv.Stop()
   504  	respParam := []*testpb.ResponseParameters{
   505  		{
   506  			Size: 1,
   507  		},
   508  	}
   509  	payload, err := newPayload(testpb.PayloadType_COMPRESSABLE, int32(100))
   510  	if err != nil {
   511  		t.Fatal(err)
   512  	}
   513  	req := &testpb.StreamingOutputCallRequest{
   514  		ResponseType:       testpb.PayloadType_COMPRESSABLE,
   515  		ResponseParameters: respParam,
   516  		Payload:            payload,
   517  	}
   518  	sendStart := time.Now()
   519  	for {
   520  		if err := stream.Send(req); err == io.EOF {
   521  			// stream.Send should eventually send io.EOF
   522  			break
   523  		} else if err != nil {
   524  			// Send should never return a transport-level error.
   525  			t.Fatalf("stream.Send(%v) = %v; want <nil or io.EOF>", req, err)
   526  		}
   527  		if time.Since(sendStart) > 2*time.Second {
   528  			t.Fatalf("stream.Send(_) did not return io.EOF after 2s")
   529  		}
   530  		time.Sleep(time.Millisecond)
   531  	}
   532  	if _, err := stream.Recv(); err == nil || err == io.EOF {
   533  		t.Fatalf("%v.Recv() = _, %v, want _, <non-nil, non-EOF>", stream, err)
   534  	}
   535  	<-ch
   536  	awaitNewConnLogOutput()
   537  }
   538  
   539  // Proxies typically send GO_AWAY followed by connection closure a minute or so later. This
   540  // test ensures that the connection is re-created after GO_AWAY and not affected by the
   541  // subsequent (old) connection closure.
   542  func (s) TestGoAwayThenClose(t *testing.T) {
   543  	ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
   544  	defer cancel()
   545  
   546  	lis1, err := testutils.LocalTCPListener()
   547  	if err != nil {
   548  		t.Fatalf("Error while listening. Err: %v", err)
   549  	}
   550  
   551  	unaryCallF := func(context.Context, *testpb.SimpleRequest) (*testpb.SimpleResponse, error) {
   552  		return &testpb.SimpleResponse{}, nil
   553  	}
   554  	fullDuplexCallF := func(stream testgrpc.TestService_FullDuplexCallServer) error {
   555  		if err := stream.Send(&testpb.StreamingOutputCallResponse{}); err != nil {
   556  			t.Errorf("Unexpected error from send: %v", err)
   557  			return err
   558  		}
   559  		// Wait until a message is received from client
   560  		_, err := stream.Recv()
   561  		if err == nil {
   562  			t.Error("Expected to never receive any message")
   563  		}
   564  		return err
   565  	}
   566  	ss1 := &stubserver.StubServer{
   567  		Listener:        lis1,
   568  		UnaryCallF:      unaryCallF,
   569  		FullDuplexCallF: fullDuplexCallF,
   570  		S:               grpc.NewServer(),
   571  	}
   572  	stubserver.StartTestService(t, ss1)
   573  	defer ss1.S.Stop()
   574  
   575  	conn2Established := grpcsync.NewEvent()
   576  	lis2, err := listenWithNotifyingListener("tcp", "localhost:0", conn2Established)
   577  	if err != nil {
   578  		t.Fatalf("Error while listening. Err: %v", err)
   579  	}
   580  	ss2 := &stubserver.StubServer{
   581  		Listener:        lis2,
   582  		UnaryCallF:      unaryCallF,
   583  		FullDuplexCallF: fullDuplexCallF,
   584  		S:               grpc.NewServer(),
   585  	}
   586  	stubserver.StartTestService(t, ss2)
   587  	defer ss2.S.Stop()
   588  
   589  	r := manual.NewBuilderWithScheme("whatever")
   590  	r.InitialState(resolver.State{Addresses: []resolver.Address{
   591  		{Addr: lis1.Addr().String()},
   592  		{Addr: lis2.Addr().String()},
   593  	}})
   594  	cc, err := grpc.NewClient(r.Scheme()+":///", grpc.WithResolvers(r), grpc.WithTransportCredentials(insecure.NewCredentials()))
   595  	if err != nil {
   596  		t.Fatalf("Error creating client: %v", err)
   597  	}
   598  	defer cc.Close()
   599  
   600  	client := testgrpc.NewTestServiceClient(cc)
   601  
   602  	// We make a streaming RPC and do an one-message-round-trip to make sure
   603  	// it's created on connection 1.
   604  	//
   605  	// We use a long-lived RPC because it will cause GracefulStop to send
   606  	// GO_AWAY, but the connection won't get closed until the server stops and
   607  	// the client receives the error.
   608  	t.Log("Creating first streaming RPC to server 1.")
   609  	stream, err := client.FullDuplexCall(ctx)
   610  	if err != nil {
   611  		t.Fatalf("FullDuplexCall(_) = _, %v; want _, nil", err)
   612  	}
   613  	if _, err = stream.Recv(); err != nil {
   614  		t.Fatalf("unexpected error from first recv: %v", err)
   615  	}
   616  
   617  	t.Log("Gracefully stopping server 1.")
   618  	go ss1.S.GracefulStop()
   619  
   620  	t.Log("Waiting for the ClientConn to enter IDLE state.")
   621  	testutils.AwaitState(ctx, t, cc, connectivity.Idle)
   622  
   623  	t.Log("Performing another RPC to create a connection to server 2.")
   624  	if _, err := client.UnaryCall(ctx, &testpb.SimpleRequest{}); err != nil {
   625  		t.Fatalf("UnaryCall(_) = _, %v; want _, nil", err)
   626  	}
   627  
   628  	t.Log("Waiting for a connection to server 2.")
   629  	select {
   630  	case <-conn2Established.Done():
   631  	case <-ctx.Done():
   632  		t.Fatalf("timed out waiting for connection 2 to be established")
   633  	}
   634  
   635  	// Close the listener for server2 to prevent it from allowing new connections.
   636  	lis2.Close()
   637  
   638  	t.Log("Hard closing connection 1.")
   639  	ss1.S.Stop()
   640  
   641  	t.Log("Waiting for the first stream to error.")
   642  	if _, err = stream.Recv(); err == nil {
   643  		t.Fatal("expected the stream to die, but got a successful Recv")
   644  	}
   645  
   646  	t.Log("Ensuring connection 2 is stable.")
   647  	for i := 0; i < 10; i++ {
   648  		if _, err := client.UnaryCall(ctx, &testpb.SimpleRequest{}); err != nil {
   649  			t.Fatalf("UnaryCall(_) = _, %v; want _, nil", err)
   650  		}
   651  	}
   652  }
   653  
   654  // TestGoAwayStreamIDSmallerThanCreatedStreams tests the scenario where a server
   655  // sends a goaway with a stream id that is smaller than some created streams on
   656  // the client, while the client is simultaneously creating new streams. This
   657  // should not induce a deadlock.
   658  func (s) TestGoAwayStreamIDSmallerThanCreatedStreams(t *testing.T) {
   659  	lis, err := net.Listen("tcp", "localhost:0")
   660  	if err != nil {
   661  		t.Fatalf("error listening: %v", err)
   662  	}
   663  
   664  	ctCh := testutils.NewChannel()
   665  	go func() {
   666  		conn, err := lis.Accept()
   667  		if err != nil {
   668  			t.Errorf("error in lis.Accept(): %v", err)
   669  		}
   670  		ct := newClientTester(t, conn)
   671  		ctCh.Send(ct)
   672  	}()
   673  
   674  	cc, err := grpc.NewClient(lis.Addr().String(), grpc.WithTransportCredentials(insecure.NewCredentials()))
   675  	if err != nil {
   676  		t.Fatalf("grpc.NewClient(%q) = %v", lis.Addr().String(), err)
   677  	}
   678  	defer cc.Close()
   679  	cc.Connect()
   680  
   681  	ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
   682  	defer cancel()
   683  
   684  	val, err := ctCh.Receive(ctx)
   685  	if err != nil {
   686  		t.Fatalf("timeout waiting for client transport (should be given after http2 creation)")
   687  	}
   688  	ct := val.(*clientTester)
   689  
   690  	tc := testgrpc.NewTestServiceClient(cc)
   691  	someStreamsCreated := grpcsync.NewEvent()
   692  	goAwayWritten := grpcsync.NewEvent()
   693  	go func() {
   694  		for i := 0; i < 20; i++ {
   695  			if i == 10 {
   696  				<-goAwayWritten.Done()
   697  			}
   698  			tc.FullDuplexCall(ctx)
   699  			if i == 4 {
   700  				someStreamsCreated.Fire()
   701  			}
   702  		}
   703  	}()
   704  
   705  	<-someStreamsCreated.Done()
   706  	ct.writeGoAway(1, http2.ErrCodeNo, []byte{})
   707  	goAwayWritten.Fire()
   708  }
   709  
   710  // TestTwoGoAwayPingFrames tests the scenario where you get two go away ping
   711  // frames from the client during graceful shutdown. This should not crash the
   712  // server.
   713  func (s) TestTwoGoAwayPingFrames(t *testing.T) {
   714  	lis, err := net.Listen("tcp", "localhost:0")
   715  	if err != nil {
   716  		t.Fatalf("Failed to listen: %v", err)
   717  	}
   718  	defer lis.Close()
   719  	s := grpc.NewServer()
   720  	defer s.Stop()
   721  	go s.Serve(lis)
   722  
   723  	conn, err := net.DialTimeout("tcp", lis.Addr().String(), defaultTestTimeout)
   724  	if err != nil {
   725  		t.Fatalf("Failed to dial: %v", err)
   726  	}
   727  
   728  	st := newServerTesterFromConn(t, conn)
   729  	st.greet()
   730  	pingReceivedClientSide := testutils.NewChannel()
   731  	go func() {
   732  		for {
   733  			f, err := st.readFrame()
   734  			if err != nil {
   735  				return
   736  			}
   737  			switch f.(type) {
   738  			case *http2.GoAwayFrame:
   739  			case *http2.PingFrame:
   740  				pingReceivedClientSide.Send(nil)
   741  			default:
   742  				t.Errorf("server tester received unexpected frame type %T", f)
   743  			}
   744  		}
   745  	}()
   746  	gsDone := testutils.NewChannel()
   747  	go func() {
   748  		s.GracefulStop()
   749  		gsDone.Send(nil)
   750  	}()
   751  	ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
   752  	defer cancel()
   753  	if _, err := pingReceivedClientSide.Receive(ctx); err != nil {
   754  		t.Fatalf("Error waiting for ping frame client side from graceful shutdown: %v", err)
   755  	}
   756  	// Write two goaway pings here.
   757  	st.writePing(true, [8]byte{1, 6, 1, 8, 0, 3, 3, 9})
   758  	st.writePing(true, [8]byte{1, 6, 1, 8, 0, 3, 3, 9})
   759  	// Close the conn to finish up the Graceful Shutdown process.
   760  	conn.Close()
   761  	if _, err := gsDone.Receive(ctx); err != nil {
   762  		t.Fatalf("Error waiting for graceful shutdown of the server: %v", err)
   763  	}
   764  }
   765  
   766  // TestClientSendsAGoAway tests the scenario where you get a go away ping
   767  // frames from the client during graceful shutdown.
   768  func (s) TestClientSendsAGoAway(t *testing.T) {
   769  	lis, err := net.Listen("tcp", "localhost:0")
   770  	if err != nil {
   771  		t.Fatalf("error listening: %v", err)
   772  	}
   773  	defer lis.Close()
   774  	goAwayReceived := make(chan struct{})
   775  	errCh := make(chan error)
   776  	go func() {
   777  		conn, err := lis.Accept()
   778  		if err != nil {
   779  			t.Errorf("error in lis.Accept(): %v", err)
   780  		}
   781  		ct := newClientTester(t, conn)
   782  		defer ct.conn.Close()
   783  		for {
   784  			f, err := ct.fr.ReadFrame()
   785  			if err != nil {
   786  				errCh <- fmt.Errorf("error reading frame: %v", err)
   787  				return
   788  			}
   789  			switch fr := f.(type) {
   790  			case *http2.GoAwayFrame:
   791  				fr = f.(*http2.GoAwayFrame)
   792  				if fr.ErrCode == http2.ErrCodeNo {
   793  					t.Logf("GoAway received from client")
   794  					close(goAwayReceived)
   795  					return
   796  				}
   797  			default:
   798  				t.Errorf("server tester received unexpected frame type %T", f)
   799  				errCh <- fmt.Errorf("server tester received unexpected frame type %T", f)
   800  				close(errCh)
   801  			}
   802  		}
   803  	}()
   804  
   805  	cc, err := grpc.NewClient(lis.Addr().String(), grpc.WithTransportCredentials(insecure.NewCredentials()))
   806  	if err != nil {
   807  		t.Fatalf("error dialing: %v", err)
   808  	}
   809  	cc.Connect()
   810  
   811  	ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
   812  	defer cancel()
   813  
   814  	testutils.AwaitState(ctx, t, cc, connectivity.Ready)
   815  	cc.Close()
   816  	select {
   817  	case <-goAwayReceived:
   818  	case err := <-errCh:
   819  		t.Errorf("Error receiving the goAway: %v", err)
   820  	case <-ctx.Done():
   821  		t.Errorf("Context timed out")
   822  	}
   823  }