Test that in the event of a graceful client transport shutdown, i.e., clientTransport.Close(), client sends a goaway to the server with the correct error code and debug data.
(t *testing.T)
| 3059 | // clientTransport.Close(), client sends a goaway to the server with the correct |
| 3060 | // error code and debug data. |
| 3061 | func (s) TestClientSendsAGoAwayFrame(t *testing.T) { |
| 3062 | // Create a server. |
| 3063 | lis, err := net.Listen("tcp", "localhost:0") |
| 3064 | if err != nil { |
| 3065 | t.Fatalf("Error while listening: %v", err) |
| 3066 | } |
| 3067 | defer lis.Close() |
| 3068 | // greetDone is used to notify when server is done greeting the client. |
| 3069 | greetDone := make(chan struct{}) |
| 3070 | // errorCh verifies that desired GOAWAY not received by server |
| 3071 | errorCh := make(chan error) |
| 3072 | ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout) |
| 3073 | defer cancel() |
| 3074 | // Launch the server. |
| 3075 | go func() { |
| 3076 | sconn, err := lis.Accept() |
| 3077 | if err != nil { |
| 3078 | t.Errorf("Error while accepting: %v", err) |
| 3079 | } |
| 3080 | defer sconn.Close() |
| 3081 | if _, err := io.ReadFull(sconn, make([]byte, len(clientPreface))); err != nil { |
| 3082 | t.Errorf("Error while writing settings ack: %v", err) |
| 3083 | return |
| 3084 | } |
| 3085 | sfr := http2.NewFramer(sconn, sconn) |
| 3086 | if err := sfr.WriteSettings(); err != nil { |
| 3087 | t.Errorf("Error while writing settings %v", err) |
| 3088 | return |
| 3089 | } |
| 3090 | fr, _ := sfr.ReadFrame() |
| 3091 | if _, ok := fr.(*http2.SettingsFrame); !ok { |
| 3092 | t.Errorf("Expected settings frame, got %v", fr) |
| 3093 | } |
| 3094 | fr, _ = sfr.ReadFrame() |
| 3095 | if fr, ok := fr.(*http2.SettingsFrame); !ok || !fr.IsAck() { |
| 3096 | t.Errorf("Expected settings ACK frame, got %v", fr) |
| 3097 | } |
| 3098 | fr, _ = sfr.ReadFrame() |
| 3099 | if fr, ok := fr.(*http2.HeadersFrame); !ok || !fr.Flags.Has(http2.FlagHeadersEndHeaders) { |
| 3100 | t.Errorf("Expected Headers frame with END_HEADERS frame, got %v", fr) |
| 3101 | } |
| 3102 | close(greetDone) |
| 3103 | |
| 3104 | frame, err := sfr.ReadFrame() |
| 3105 | if err != nil { |
| 3106 | return |
| 3107 | } |
| 3108 | switch fr := frame.(type) { |
| 3109 | case *http2.GoAwayFrame: |
| 3110 | // Records that the server successfully received a GOAWAY frame. |
| 3111 | goAwayFrame := fr |
| 3112 | if goAwayFrame.ErrCode == http2.ErrCodeNo { |
| 3113 | t.Logf("Received goAway frame from client") |
| 3114 | close(errorCh) |
| 3115 | } else { |
| 3116 | errorCh <- fmt.Errorf("received unexpected goAway frame: %v", err) |
| 3117 | close(errorCh) |
| 3118 | } |
nothing calls this directly
no test coverage detected