MCPcopy
hub / github.com/grpc/grpc-go / TestGracefulStop

Method TestGracefulStop

test/gracefulstop_test.go:103–162  ·  view source on GitHub ↗

TestGracefulStop ensures GracefulStop causes new connections to fail. Steps of this test: 1. Start Server 2. GracefulStop() Server after listener's Accept is called, but don't allow Accept() to exit when Close() is called on it. 3. Create a new connection to the server after listener.Close() is cal

(t *testing.T)

Source from the content-addressed store, hash-verified

101// 4. Send an RPC on the new connection. Should see Unavailable error
102// because the ClientConn is in transient failure.
103func (s) TestGracefulStop(t *testing.T) {
104 lis, err := net.Listen("tcp", "localhost:0")
105 if err != nil {
106 t.Fatalf("Error listenening: %v", err)
107 }
108 dlis := &delayListener{
109 Listener: lis,
110 acceptCalled: make(chan struct{}),
111 closeCalled: make(chan struct{}),
112 allowCloseCh: make(chan struct{}),
113 }
114
115 ss := &stubserver.StubServer{
116 Listener: dlis,
117 FullDuplexCallF: func(stream testgrpc.TestService_FullDuplexCallServer) error {
118 if _, err := stream.Recv(); err != nil {
119 return err
120 }
121 return stream.Send(&testpb.StreamingOutputCallResponse{})
122 },
123 S: grpc.NewServer(),
124 }
125 // 1. Start Server and start serving by calling Serve().
126 stubserver.StartTestService(t, ss)
127
128 // 2. Call GracefulStop from a goroutine. It will trigger Close on the
129 // listener, but the listener will not actually close until a connection
130 // is accepted.
131 gracefulStopDone := make(chan struct{})
132 <-dlis.acceptCalled
133 go func() {
134 ss.S.GracefulStop()
135 close(gracefulStopDone)
136 }()
137
138 // 3. Create a new connection to the server after listener.Close() is called.
139 // Server should close this connection immediately, before handshaking.
140
141 <-dlis.closeCalled // Block until GracefulStop calls dlis.Close()
142
143 dialer := func(ctx context.Context, _ string) (net.Conn, error) { return dlis.Dial(ctx) }
144 cc, err := grpc.NewClient("passthrough:///", grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithContextDialer(dialer))
145 if err != nil {
146 t.Fatalf("grpc.NewClient(%q) = %v", lis.Addr().String(), err)
147 }
148 client := testgrpc.NewTestServiceClient(cc)
149 defer cc.Close()
150
151 // 4. Make an RPC.
152 // The server would send a GOAWAY first, but we are delaying the server's
153 // writes for now until the client writes more than the preface.
154 // This will cause a connection to be accepted. This will
155 // also unblock the Close method.
156 ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
157 if _, err = client.FullDuplexCall(ctx); err == nil || status.Code(err) != codes.Unavailable {
158 t.Fatalf("FullDuplexCall= _, %v; want _, <status code Unavailable>", err)
159 }
160 cancel()

Callers

nothing calls this directly

Calls 15

DialMethod · 0.95
FullDuplexCallMethod · 0.95
NewServerFunction · 0.92
StartTestServiceFunction · 0.92
NewClientFunction · 0.92
WithTransportCredentialsFunction · 0.92
NewCredentialsFunction · 0.92
WithContextDialerFunction · 0.92
CodeFunction · 0.92
FatalfMethod · 0.65
RecvMethod · 0.65
SendMethod · 0.65

Tested by

no test coverage detected