@@ -59,6 +59,8 @@ func Test(t *testing.T) {
59
59
grpctest .RunSubTests (t , s {})
60
60
}
61
61
62
+ const goAwayFrameSize = 42
63
+
62
64
var (
63
65
expectedRequest = []byte ("ping" )
64
66
expectedResponse = []byte ("pong" )
@@ -2759,18 +2761,20 @@ type hangingConn struct {
2759
2761
2760
2762
func (hc * hangingConn ) Write (b []byte ) (n int , err error ) {
2761
2763
n , err = hc .Conn .Write (b )
2762
- if hc .startHanging .Load () == true {
2763
- // Hang the Write for more than goAwayLoopyWriterTimeout
2764
- timer := time .NewTimer (time .Millisecond * 5 )
2765
- defer timer .Stop ()
2766
- select {
2767
- case <- hc .hangConn :
2768
- case <- timer .C :
2769
- }
2764
+ if n == goAwayFrameSize { // hang the conn after the goAway is received
2765
+ <- hc .hangConn
2770
2766
}
2771
2767
return n , err
2772
2768
}
2773
2769
2770
+ func hangingDialer (_ context.Context , addr string ) (net.Conn , error ) {
2771
+ conn , err := net .Dial ("tcp" , addr )
2772
+ if err != nil {
2773
+ return nil , err
2774
+ }
2775
+ return & hangingConn {Conn : conn , hangConn : make (chan struct {})}, nil
2776
+ }
2777
+
2774
2778
// Tests the scenario where a client transport is closed and writing of the
2775
2779
// GOAWAY frame as part of the close does not complete because of a network
2776
2780
// hang. The test verifies that the client transport is closed without waiting
@@ -2786,28 +2790,7 @@ func (s) TestClientCloseReturnsEarlyWhenGoAwayWriteHangs(t *testing.T) {
2786
2790
}()
2787
2791
2788
2792
// Create the server set up.
2789
- connectCtx , cancel := context .WithDeadline (context .Background (), time .Now ().Add (2 * time .Second ))
2790
- server := setUpServerOnly (t , 0 , & ServerConfig {}, normal )
2791
- addr := resolver.Address {Addr : "localhost:" + server .port }
2792
- isGreetingDone := & atomic.Bool {}
2793
- dialer := func (_ context.Context , addr string ) (net.Conn , error ) {
2794
- conn , err := net .Dial ("tcp" , addr )
2795
- if err != nil {
2796
- return nil , err
2797
- }
2798
- return & hangingConn {Conn : conn , hangConn : make (chan struct {}), startHanging : isGreetingDone }, nil
2799
- }
2800
- copts := ConnectOptions {Dialer : dialer }
2801
- copts .ChannelzParent = channelzSubChannel (t )
2802
-
2803
- // Create client transport with custom dialer
2804
- ct , connErr := NewClientTransport (connectCtx , context .Background (), addr , copts , func (GoAwayReason ) {})
2805
- if connErr != nil {
2806
- cancel () // Do not cancel in success path.
2807
- t .Fatalf ("failed to create transport: %v" , connErr )
2808
- }
2809
- isGreetingDone .Store (true )
2810
-
2793
+ server , ct , cancel := setUpWithOptions (t , 0 , & ServerConfig {}, normal , ConnectOptions {Dialer : hangingDialer })
2811
2794
defer cancel ()
2812
2795
defer server .stop ()
2813
2796
@@ -2816,6 +2799,5 @@ func (s) TestClientCloseReturnsEarlyWhenGoAwayWriteHangs(t *testing.T) {
2816
2799
if _ , err := ct .NewStream (ctx , & CallHdr {}); err != nil {
2817
2800
t .Fatalf ("Failed to open stream: %v" , err )
2818
2801
}
2819
-
2820
2802
ct .Close (errors .New ("manually closed by client" ))
2821
2803
}
0 commit comments