TestServeHTTP_GracefulStop verifies that calling GracefulStop on a server using ServeHTTP returns properly.
(t *testing.T)
| 304 | // TestServeHTTP_GracefulStop verifies that calling GracefulStop on a server |
| 305 | // using ServeHTTP returns properly. |
| 306 | func (s) TestServeHTTP_GracefulStop(t *testing.T) { |
| 307 | gs := grpc.NewServer() |
| 308 | defer gs.Stop() |
| 309 | |
| 310 | ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout) |
| 311 | defer cancel() |
| 312 | |
| 313 | // Register a service that blocks until context is done to make sure the |
| 314 | // server is active when GracefulStop is called. |
| 315 | callStarted := make(chan struct{}) |
| 316 | testgrpc.RegisterTestServiceServer(gs, &stubserver.StubServer{ |
| 317 | FullDuplexCallF: func(testgrpc.TestService_FullDuplexCallServer) error { |
| 318 | close(callStarted) |
| 319 | <-ctx.Done() |
| 320 | return nil |
| 321 | }, |
| 322 | }) |
| 323 | |
| 324 | // Create a handler that delegates to ServeHTTP and signals when it returns. |
| 325 | serveHTTPDone := make(chan struct{}) |
| 326 | handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { |
| 327 | gs.ServeHTTP(w, r) |
| 328 | close(serveHTTPDone) |
| 329 | }) |
| 330 | |
| 331 | // Start an HTTP/2 server with the wrapped handler. |
| 332 | ts := httptest.NewUnstartedServer(handler) |
| 333 | ts.EnableHTTP2 = true |
| 334 | ts.StartTLS() |
| 335 | defer ts.Close() |
| 336 | |
| 337 | // Make a new request to the gRPC server via HTTP/2 to ensure HandleStreams is called. |
| 338 | req, err := http.NewRequest("POST", ts.URL+"/grpc.testing.TestService/FullDuplexCall", nil) |
| 339 | if err != nil { |
| 340 | t.Fatal(err) |
| 341 | } |
| 342 | req.Header.Set("Content-Type", "application/grpc") |
| 343 | |
| 344 | client := ts.Client() |
| 345 | // Send the request in a goroutine. |
| 346 | go func() { |
| 347 | resp, err := client.Do(req) |
| 348 | if err != nil { |
| 349 | return |
| 350 | } |
| 351 | resp.Body.Close() |
| 352 | }() |
| 353 | |
| 354 | <-callStarted |
| 355 | // Call GracefulStop in a goroutine to avoid blocking the main thread until the RPC is done. |
| 356 | go gs.GracefulStop() |
| 357 | |
| 358 | // Verify that ServeHTTP returned because GracefulStop is called and ensure it doesn't panic. |
| 359 | select { |
| 360 | case <-serveHTTPDone: |
| 361 | case <-ctx.Done(): |
| 362 | t.Fatal("Context timed out waiting for ServeHTTP to return after GracefulStop") |
| 363 | } |