Skip to content

Commit c633030

Browse files
author
OlegDokuka
committed
improves leak tracker
Signed-off-by: Oleh Dokuka <[email protected]> Signed-off-by: Oleh Dokuka <[email protected]> Signed-off-by: OlegDokuka <[email protected]>
1 parent 5ed16d9 commit c633030

File tree

3 files changed

+64
-33
lines changed

3 files changed

+64
-33
lines changed

rsocket-core/src/test/java/io/rsocket/buffer/LeaksTrackingByteBufAllocator.java

Lines changed: 31 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,25 @@
55
import io.netty.buffer.ByteBuf;
66
import io.netty.buffer.ByteBufAllocator;
77
import io.netty.buffer.CompositeByteBuf;
8+
import io.netty.util.IllegalReferenceCountException;
89
import io.netty.util.ResourceLeakDetector;
910
import java.lang.reflect.Field;
1011
import java.time.Duration;
1112
import java.util.ArrayList;
1213
import java.util.Collections;
14+
import java.util.HashSet;
1315
import java.util.Set;
1416
import java.util.concurrent.ConcurrentLinkedQueue;
1517
import 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
*/
2125
public 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,6 +88,7 @@ public LeaksTrackingByteBufAllocator assertHasNoLeaks() {
8388
return this;
8489
}
8590

91+
LOGGER.debug(tag + " await buffers to be released");
8692
for (int i = 0; i < 100; i++) {
8793
System.gc();
8894
parkNanos(1000);
@@ -91,22 +97,31 @@ public LeaksTrackingByteBufAllocator assertHasNoLeaks() {
9197
}
9298
}
9399

94-
Assertions.assertThat(unreleased)
95-
.allMatch(
96-
bb -> {
97-
final boolean checkResult = bb.refCnt() == 0;
98-
99-
if (!checkResult) {
100-
try {
101-
System.out.println(tag + " " + resolveTrackingInfo(bb));
102-
} catch (Exception e) {
103-
e.printStackTrace();
104-
}
105-
}
106-
107-
return checkResult;
108-
},
109-
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();
110125
} finally {
111126
tracker.clear();
112127
}

rsocket-test/build.gradle

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ dependencies {
2828
implementation 'io.projectreactor:reactor-test'
2929
implementation 'org.assertj:assertj-core'
3030
implementation 'org.mockito:mockito-core'
31+
implementation 'org.awaitility:awaitility'
32+
implementation 'org.slf4j:slf4j-api'
3133
}
3234

3335
jar {

rsocket-test/src/main/java/io/rsocket/test/LeaksTrackingByteBufAllocator.java

Lines changed: 31 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,25 @@
55
import io.netty.buffer.ByteBuf;
66
import io.netty.buffer.ByteBufAllocator;
77
import io.netty.buffer.CompositeByteBuf;
8+
import io.netty.util.IllegalReferenceCountException;
89
import io.netty.util.ResourceLeakDetector;
910
import java.lang.reflect.Field;
1011
import java.time.Duration;
1112
import java.util.ArrayList;
1213
import java.util.Collections;
14+
import java.util.HashSet;
1315
import java.util.Set;
1416
import java.util.concurrent.ConcurrentLinkedQueue;
1517
import 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
*/
2125
public 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

Comments
 (0)