Repository: grpc/grpc-go
File: test/goaway_test.go (Go)

Code before:
		},
		FullDuplexCallF: func(stream testgrpc.TestService_FullDuplexCallServer) error {
			if err := stream.Send(&testpb.StreamingOutputCallResponse{}); err != nil {
				t.Errorf("unexpected error from send: %v", err)
				return err
			}
			// Wait until a message is received from client
			_, err := stream.Recv()
			if err == nil {
				t.Error("expected to never receive any message")
			}
			return err
		},
		S: grpc.NewServer(),
	}
	stubserver.StartTestService(t, ss1)
	defer ss1.S.Stop()

	conn2Established := grpcsync.NewEvent()
	lis2, err := listenWithNotifyingListener("tcp", "localhost:0", conn2Established)
	if err != nil {
		t.Fatalf("Error while listening. Err: %v", err)
	}
	ss2 := &stubserver.StubServer{
		Listener: lis2,
		UnaryCallF: func(context.Context, *testpb.SimpleRequest) (*testpb.SimpleResponse, error) {
			return &testpb.SimpleResponse{}, nil
		},
		FullDuplexCallF: func(stream testgrpc.TestService_FullDuplexCallServer) error {
			if err := stream.Send(&testpb.StreamingOutputCallResponse{}); err != nil {
				t.Errorf("unexpected error from send: %v", err)
				return err
			}
			// Wait until a message is received from client
			_, err := stream.Recv()
			if err == nil {
				t.Error("expected to never receive any message")
			}
			return err
		},
		S: grpc.NewServer(),
	}
	stubserver.StartTestService(t, ss2)
	defer ss2.S.Stop()

	r := manual.NewBuilderWithScheme("whatever")
	r.InitialState(resolver.State{Addresses: []resolver.Address{
		{Addr: lis1.Addr().String()},
		{Addr: lis2.Addr().String()},
	}})
	cc, err := grpc.DialContext(ctx, r.Scheme()+":///", grpc.WithResolvers(r), grpc.WithTransportCredentials(insecure.NewCredentials()))

Review comment (suggestion):
Would it make sense to declare local variables here:

```golang
unaryCallF := func(context.Context, *testpb.SimpleRequest) (*testpb.SimpleResponse, error) {
	return &testpb.SimpleResponse{}, nil
}
fullDuplexCallF := func(stream testgrpc.TestService_FullDuplexCallServer) error {
	if err := stream.Send(&testpb.StreamingOutputCallResponse{}); err != nil {
		t.Errorf("unexpected error from send: %v", err)
		return err
	}
	// Wait until a message is received from client
	_, err := stream.Recv()
	if err == nil {
		t.Error("expected to never receive any message")
	}
	return err
}
```

So, that both the stub server implementations can use the local variable and we can avoid some code duplication (since they seem to be the same)
```golang
	ss(1|2) := &stubserver.StubServer{
		Listener: lis2,
		UnaryCallF: unaryCallF,
		FullDuplexCallF: fullDuplexCallF
	}
```

Code after:
			return err
		}
		// Wait until a message is received from client
		_, err := stream.Recv()
		if err == nil {
			t.Error("Expected to never receive any message")
		}
		return err
	}
	ss1 := &stubserver.StubServer{
		Listener:        lis1,
		UnaryCallF:      unaryCallF,
		FullDuplexCallF: fullDuplexCallF,
		S:               grpc.NewServer(),
	}
	stubserver.StartTestService(t, ss1)
	defer ss1.S.Stop()

	conn2Established := grpcsync.NewEvent()
	lis2, err := listenWithNotifyingListener("tcp", "localhost:0", conn2Established)
	if err != nil {
		t.Fatalf("Error while listening. Err: %v", err)
	}
	ss2 := &stubserver.StubServer{
		Listener:        lis2,
		UnaryCallF:      unaryCallF,
		FullDuplexCallF: fullDuplexCallF,
		S:               grpc.NewServer(),
	}
	stubserver.StartTestService(t, ss2)
	defer ss2.S.Stop()

	r := manual.NewBuilderWithScheme("whatever")
	r.InitialState(resolver.State{Addresses: []resolver.Address{
		{Addr: lis1.Addr().String()},
		{Addr: lis2.Addr().String()},
	}})
	cc, err := grpc.DialContext(ctx, r.Scheme()+":///", grpc.WithResolvers(r), grpc.WithTransportCredentials(insecure.NewCredentials()))
	if err != nil {
		t.Fatalf("Error creating client: %v", err)
	}
	defer cc.Close()

	client := testgrpc.NewTestServiceClient(cc)

	t.Log("Waiting for the ClientConn to enter READY state.")
	testutils.AwaitState(ctx, t, cc, connectivity.Ready)

	// We make a streaming RPC and do an one-message-round-trip to make sure
	// it's created on connection 1.
	//