55import io .netty .buffer .ByteBuf ;
66import io .netty .buffer .ByteBufAllocator ;
77import io .netty .buffer .CompositeByteBuf ;
8+ import io .netty .util .IllegalReferenceCountException ;
89import io .netty .util .ResourceLeakDetector ;
910import java .lang .reflect .Field ;
1011import java .time .Duration ;
1112import java .util .ArrayList ;
1213import java .util .Collections ;
14+ import java .util .HashSet ;
1315import java .util .Set ;
1416import java .util .concurrent .ConcurrentLinkedQueue ;
1517import org .assertj .core .api .Assertions ;
18+ import org .slf4j .Logger ;
19+ import org .slf4j .LoggerFactory ;
1620
1721/**
1822 * Additional Utils which allows to decorate a ByteBufAllocator and track/assertOnLeaks all created
1923 * ByteBuffs
2024 */
2125public class LeaksTrackingByteBufAllocator implements ByteBufAllocator {
26+ static final Logger LOGGER = LoggerFactory .getLogger (LeaksTrackingByteBufAllocator .class );
2227
2328 /**
2429 * Allows to instrument any given the instance of ByteBufAllocator
@@ -83,7 +88,7 @@ public LeaksTrackingByteBufAllocator assertHasNoLeaks() {
8388 return this ;
8489 }
8590
86- System . out . println (tag + " await buffers to be released" );
91+ LOGGER . debug (tag + " await buffers to be released" );
8792 for (int i = 0 ; i < 100 ; i ++) {
8893 System .gc ();
8994 parkNanos (1000 );
@@ -92,22 +97,31 @@ public LeaksTrackingByteBufAllocator assertHasNoLeaks() {
9297 }
9398 }
9499
95- Assertions .assertThat (unreleased )
96- .allMatch (
97- bb -> {
98- final boolean checkResult = bb .refCnt () == 0 ;
99-
100- if (!checkResult ) {
101- try {
102- System .out .println (tag + " " + resolveTrackingInfo (bb ));
103- } catch (Exception e ) {
104- e .printStackTrace ();
105- }
106- }
107-
108- return checkResult ;
109- },
110- tag );
100+ Set <ByteBuf > collected = new HashSet <>();
101+ for (ByteBuf buf : unreleased ) {
102+ if (buf .refCnt () != 0 ) {
103+ try {
104+ collected .add (buf );
105+ } catch (IllegalReferenceCountException ignored ) {
106+ // fine to ignore if throws because of refCnt
107+ }
108+ }
109+ }
110+
111+ Assertions .assertThat (
112+ collected
113+ .stream ()
114+ .filter (bb -> bb .refCnt () != 0 )
115+ .peek (
116+ bb -> {
117+ try {
118+ LOGGER .debug (tag + " " + resolveTrackingInfo (bb ));
119+ } catch (Exception e ) {
120+ e .printStackTrace ();
121+ }
122+ }))
123+ .describedAs ("[" + tag + "] all buffers expected to be released but got " )
124+ .isEmpty ();
111125 } finally {
112126 tracker .clear ();
113127 }
0 commit comments