38
38
import io .grpc .internal .WritableBuffer ;
39
39
import io .netty .buffer .ByteBuf ;
40
40
import io .netty .buffer .ByteBufAllocator ;
41
- import io .netty .buffer .ByteBufUtil ;
42
41
import io .netty .buffer .CompositeByteBuf ;
43
42
import io .netty .buffer .Unpooled ;
44
43
import io .netty .buffer .UnpooledByteBufAllocator ;
68
67
import java .nio .ByteBuffer ;
69
68
import java .util .concurrent .Delayed ;
70
69
import java .util .concurrent .TimeUnit ;
70
+ import org .junit .After ;
71
71
import org .junit .Assert ;
72
72
import org .junit .Test ;
73
73
import org .junit .runner .RunWith ;
84
84
public abstract class NettyHandlerTestBase <T extends Http2ConnectionHandler > {
85
85
86
86
protected static final int STREAM_ID = 3 ;
87
- private ByteBuf content ;
88
87
89
88
private EmbeddedChannel channel ;
90
89
@@ -106,18 +105,24 @@ protected void manualSetUp() throws Exception {}
106
105
protected final TransportTracer transportTracer = new TransportTracer ();
107
106
protected int flowControlWindow = DEFAULT_WINDOW_SIZE ;
108
107
protected boolean autoFlowControl = false ;
109
-
110
108
private final FakeClock fakeClock = new FakeClock ();
111
109
112
110
FakeClock fakeClock () {
113
111
return fakeClock ;
114
112
}
115
113
114
+ @ After
115
+ public void tearDown () throws Exception {
116
+ if (channel () != null ) {
117
+ channel ().releaseInbound ();
118
+ channel ().releaseOutbound ();
119
+ }
120
+ }
121
+
116
122
/**
117
123
* Must be called by subclasses to initialize the handler and channel.
118
124
*/
119
125
protected final void initChannel (Http2HeadersDecoder headersDecoder ) throws Exception {
120
- content = Unpooled .copiedBuffer ("hello world" , UTF_8 );
121
126
frameWriter = mock (Http2FrameWriter .class , delegatesTo (new DefaultHttp2FrameWriter ()));
122
127
frameReader = new DefaultHttp2FrameReader (headersDecoder );
123
128
@@ -233,11 +238,11 @@ protected final Http2FrameReader frameReader() {
233
238
}
234
239
235
240
protected final ByteBuf content () {
236
- return content ;
241
+ return Unpooled . copiedBuffer ( contentAsArray ()) ;
237
242
}
238
243
239
244
protected final byte [] contentAsArray () {
240
- return ByteBufUtil .getBytes (content () );
245
+ return " \000 \000 \000 \000 \r hello world" .getBytes (UTF_8 );
241
246
}
242
247
243
248
protected final Http2FrameWriter verifyWrite () {
@@ -252,8 +257,8 @@ protected final void channelRead(Object obj) throws Exception {
252
257
channel .writeInbound (obj );
253
258
}
254
259
255
- protected ByteBuf grpcDataFrame ( int streamId , boolean endStream , byte [] content ) {
256
- final ByteBuf compressionFrame = Unpooled .buffer (content .length );
260
+ protected ByteBuf grpcFrame ( byte [] message ) {
261
+ final ByteBuf compressionFrame = Unpooled .buffer (message .length );
257
262
MessageFramer framer = new MessageFramer (
258
263
new MessageFramer .Sink () {
259
264
@ Override
@@ -262,23 +267,22 @@ public void deliverFrame(
262
267
if (frame != null ) {
263
268
ByteBuf bytebuf = ((NettyWritableBuffer ) frame ).bytebuf ();
264
269
compressionFrame .writeBytes (bytebuf );
270
+ bytebuf .release ();
265
271
}
266
272
}
267
273
},
268
274
new NettyWritableBufferAllocator (ByteBufAllocator .DEFAULT ),
269
275
StatsTraceContext .NOOP );
270
- framer .writePayload (new ByteArrayInputStream (content ));
271
- framer .flush ();
272
- ChannelHandlerContext ctx = newMockContext ();
273
- new DefaultHttp2FrameWriter ().writeData (ctx , streamId , compressionFrame , 0 , endStream ,
274
- newPromise ());
275
- return captureWrite (ctx );
276
+ framer .writePayload (new ByteArrayInputStream (message ));
277
+ framer .close ();
278
+ return compressionFrame ;
276
279
}
277
280
278
- protected final ByteBuf dataFrame (int streamId , boolean endStream , ByteBuf content ) {
279
- // Need to retain the content since the frameWriter releases it.
280
- content . retain ();
281
+ protected final ByteBuf grpcDataFrame (int streamId , boolean endStream , byte [] content ) {
282
+ return dataFrame ( streamId , endStream , grpcFrame ( content ));
283
+ }
281
284
285
+ protected final ByteBuf dataFrame (int streamId , boolean endStream , ByteBuf content ) {
282
286
ChannelHandlerContext ctx = newMockContext ();
283
287
new DefaultHttp2FrameWriter ().writeData (ctx , streamId , content , 0 , endStream , newPromise ());
284
288
return captureWrite (ctx );
@@ -410,6 +414,7 @@ public void dataSizeSincePingAccumulates() throws Exception {
410
414
channelRead (dataFrame (3 , false , buff .copy ()));
411
415
412
416
assertEquals (length * 3 , handler .flowControlPing ().getDataSincePing ());
417
+ buff .release ();
413
418
}
414
419
415
420
@ Test
@@ -608,12 +613,14 @@ public void bdpPingWindowResizing() throws Exception {
608
613
609
614
private void readPingAck (long pingData ) throws Exception {
610
615
channelRead (pingFrame (true , pingData ));
616
+ channel ().releaseOutbound ();
611
617
}
612
618
613
619
private void readXCopies (int copies , byte [] data ) throws Exception {
614
620
for (int i = 0 ; i < copies ; i ++) {
615
621
channelRead (grpcDataFrame (STREAM_ID , false , data )); // buffer it
616
622
stream ().request (1 ); // consume it
623
+ channel ().releaseOutbound ();
617
624
}
618
625
}
619
626
0 commit comments