1212
1313import io .netty .bootstrap .Bootstrap ;
1414import io .netty .buffer .ByteBuf ;
15- import io .netty .channel .Channel ;
16- import io .netty .channel .ChannelFuture ;
17- import io .netty .channel .ChannelHandlerContext ;
18- import io .netty .channel .ChannelInitializer ;
15+ import io .netty .channel .*;
1916import io .netty .channel .nio .NioEventLoopGroup ;
2017import io .netty .channel .socket .nio .NioSocketChannel ;
2118import io .netty .handler .codec .http2 .AbstractHttp2ConnectionHandlerBuilder ;
4037import io .netty .handler .codec .http2 .Http2Settings ;
4138import org .junit .Test ;
4239
40+ import java .io .IOException ;
4341import java .net .InetSocketAddress ;
4442import java .util .concurrent .CompletableFuture ;
4543import java .util .concurrent .TimeUnit ;
@@ -68,7 +66,7 @@ public void testMYR() throws Exception {
6866 AtomicInteger inflightRequests = new AtomicInteger ();
6967 AtomicInteger maxInflightRequests = new AtomicInteger ();
7068 AtomicInteger receivedRstFrames = new AtomicInteger ();
71- CompletableFuture <Void > goAway = new CompletableFuture <>();
69+ CompletableFuture <Boolean > goAway = new CompletableFuture <>();
7270
7371 server .requestHandler (req -> {
7472 int val = inflightRequests .incrementAndGet ();
@@ -140,7 +138,7 @@ public void onSettingsRead(ChannelHandlerContext ctx, Http2Settings settings) th
140138
141139 @ Override
142140 public void onGoAwayRead (ChannelHandlerContext ctx , int lastStreamId , long errorCode , ByteBuf debugData ) throws Http2Exception {
143- goAway .complete (null );
141+ goAway .complete (true );
144142 }
145143 });
146144 return super .build ();
@@ -150,6 +148,16 @@ public void onGoAwayRead(ChannelHandlerContext ctx, int lastStreamId, long error
150148 Builder clientHandlerBuilder = new Builder ();
151149 Http2ConnectionHandler clientHandler = clientHandlerBuilder .build ();
152150 ch .pipeline ().addLast (clientHandler );
151+ ch .pipeline ().addLast (new ChannelDuplexHandler () {
152+ @ Override
153+ public void exceptionCaught (ChannelHandlerContext ctx , Throwable cause ) throws Exception {
154+ if (cause instanceof IOException && cause .getMessage ().startsWith ("Connection reset" )) {
155+ goAway .complete (false );
156+ } else {
157+ goAway .completeExceptionally (cause );
158+ }
159+ }
160+ });
153161 }
154162 };
155163 }
@@ -178,10 +186,14 @@ public ChannelFuture connect(int port, String host, BiConsumer<ChannelHandlerCon
178186 chctx .flush ();
179187 }).sync ();
180188
181- goAway .get (10 , TimeUnit .SECONDS );
182-
183189 // Check the number of rst frame received before getting a go away
184- assertEquals (receivedRstFrames .get (), maxRstFramePerWindow + 1 );
185- assertEquals (maxInflightRequests .get (), maxRstFramePerWindow + 1 );
190+ if (goAway .get (20 , TimeUnit .SECONDS )) {
191+ assertEquals (receivedRstFrames .get (), maxRstFramePerWindow + 1 );
192+ } else {
193+ // Mitigate CI behavior
194+ assertTrue (receivedRstFrames .get () < maxRstFramePerWindow + 1 );
195+ }
196+
197+ assertTrue (maxInflightRequests .get () <= 2 * maxRstFramePerWindow );
186198 }
187199}
0 commit comments