From af119de4a73dcd7a84363877165810679a94ac67 Mon Sep 17 00:00:00 2001 From: Chris Vest Date: Fri, 28 May 2021 11:51:13 +0200 Subject: [PATCH 1/6] Implement BufferIntegratable for Nio- and UnsafeBuffer --- .../io/netty/buffer/api/MemoryManagers.java | 30 +++++++++ .../bytebuffer/ByteBufferMemoryManagers.java | 5 ++ .../buffer/api/bytebuffer/NioBuffer.java | 63 ++++++++++++++++++- .../MemoryManagersOverride.java | 9 +-- .../netty/buffer/api/unsafe/UnsafeBuffer.java | 62 +++++++++++++++++- .../api/unsafe/UnsafeMemoryManagers.java | 5 ++ .../api/memseg/SegmentMemoryManagers.java | 5 ++ .../api/tests/adaptor/ByteBufAdaptorTest.java | 18 ++++-- .../adaptor/MemSegByteBufAdaptorTest.java | 25 ++++++++ .../tests/adaptor/NioByteBufAdaptorTest.java | 25 ++++++++ .../adaptor/UnsafeByteBufAdaptorTest.java | 25 ++++++++ 11 files changed, 261 insertions(+), 11 deletions(-) rename buffer-api/src/main/java/io/netty/buffer/api/{ => internal}/MemoryManagersOverride.java (86%) create mode 100644 buffer-tests/src/test/java/io/netty/buffer/api/tests/adaptor/MemSegByteBufAdaptorTest.java create mode 100644 buffer-tests/src/test/java/io/netty/buffer/api/tests/adaptor/NioByteBufAdaptorTest.java create mode 100644 buffer-tests/src/test/java/io/netty/buffer/api/tests/adaptor/UnsafeByteBufAdaptorTest.java diff --git a/buffer-api/src/main/java/io/netty/buffer/api/MemoryManagers.java b/buffer-api/src/main/java/io/netty/buffer/api/MemoryManagers.java index f0f9d12..262af5b 100644 --- a/buffer-api/src/main/java/io/netty/buffer/api/MemoryManagers.java +++ b/buffer-api/src/main/java/io/netty/buffer/api/MemoryManagers.java @@ -15,6 +15,9 @@ */ package io.netty.buffer.api; +import io.netty.buffer.api.internal.MemoryManagersOverride; + +import java.util.Optional; import java.util.ServiceLoader; import java.util.function.Supplier; import java.util.stream.Stream; @@ -59,6 +62,25 @@ public interface MemoryManagers { return loader.stream(); } + /** + * Find a {@link MemoryManagers} implementation by its {@linkplain #implementationName() implementation name}. + * + * @param implementationName The named implementation to look for. + * @return A {@link MemoryManagers} implementation, if any was found. + */ + static Optional lookupImplementation(String implementationName) { + return getAllManagers() + .flatMap(provider -> { + try { + return Stream.ofNullable(provider.get()); + } catch (Exception e) { + return Stream.empty(); + } + }) + .filter(impl -> implementationName.equals(impl.implementationName())) + .findFirst(); + } + /** * Get a {@link MemoryManager} instance that is suitable for allocating on-heap {@link Buffer} instances. * @@ -72,4 +94,12 @@ public interface MemoryManagers { * @return An off-heap {@link MemoryManager}. */ MemoryManager getNativeMemoryManager(); + + /** + * Get the name for this implementation, which can be used for finding this particular implementation via the + * {@link #lookupImplementation(String)} method. + * + * @return The name of this memory managers implementation. + */ + String implementationName(); } diff --git a/buffer-api/src/main/java/io/netty/buffer/api/bytebuffer/ByteBufferMemoryManagers.java b/buffer-api/src/main/java/io/netty/buffer/api/bytebuffer/ByteBufferMemoryManagers.java index 8eca2fc..cb33511 100644 --- a/buffer-api/src/main/java/io/netty/buffer/api/bytebuffer/ByteBufferMemoryManagers.java +++ b/buffer-api/src/main/java/io/netty/buffer/api/bytebuffer/ByteBufferMemoryManagers.java @@ -29,6 +29,11 @@ public class ByteBufferMemoryManagers implements MemoryManagers { return new ByteBufferMemoryManager(true); } + @Override + public String implementationName() { + return "ByteBuffer"; + } + @Override public String toString() { return "BB"; diff --git a/buffer-api/src/main/java/io/netty/buffer/api/bytebuffer/NioBuffer.java b/buffer-api/src/main/java/io/netty/buffer/api/bytebuffer/NioBuffer.java index 8fa5a7e..329b347 100644 --- a/buffer-api/src/main/java/io/netty/buffer/api/bytebuffer/NioBuffer.java +++ b/buffer-api/src/main/java/io/netty/buffer/api/bytebuffer/NioBuffer.java @@ -15,12 +15,16 @@ */ package io.netty.buffer.api.bytebuffer; +import io.netty.buffer.ByteBuf; import io.netty.buffer.api.AllocatorControl; import io.netty.buffer.api.Buffer; import io.netty.buffer.api.BufferAllocator; import io.netty.buffer.api.ByteCursor; import io.netty.buffer.api.Drop; import io.netty.buffer.api.Owned; +import io.netty.buffer.api.adaptor.BufferIntegratable; +import io.netty.buffer.api.adaptor.ByteBufAdaptor; +import io.netty.buffer.api.adaptor.ByteBufAllocatorAdaptor; import io.netty.buffer.api.internal.ResourceSupport; import io.netty.buffer.api.ReadableComponent; import io.netty.buffer.api.ReadableComponentProcessor; @@ -28,6 +32,7 @@ import io.netty.buffer.api.WritableComponent; import io.netty.buffer.api.WritableComponentProcessor; import io.netty.buffer.api.internal.ArcDrop; import io.netty.buffer.api.internal.Statics; +import io.netty.util.ReferenceCounted; import io.netty.util.internal.PlatformDependent; import java.nio.ByteBuffer; @@ -39,7 +44,8 @@ import static io.netty.buffer.api.internal.Statics.bbslice; import static io.netty.buffer.api.internal.Statics.bufferIsClosed; import static io.netty.buffer.api.internal.Statics.bufferIsReadOnly; -class NioBuffer extends ResourceSupport implements Buffer, ReadableComponent, WritableComponent { +class NioBuffer extends ResourceSupport implements Buffer, ReadableComponent, WritableComponent, + BufferIntegratable { private static final ByteBuffer CLOSED_BUFFER = ByteBuffer.allocate(0); private final AllocatorControl control; @@ -1190,4 +1196,59 @@ class NioBuffer extends ResourceSupport implements Buffer, Re ByteBuffer recoverable() { return base; } + + // + private ByteBufAdaptor adaptor; + @Override + public ByteBuf asByteBuf() { + ByteBufAdaptor bba = adaptor; + if (bba == null) { + ByteBufAllocatorAdaptor alloc = new ByteBufAllocatorAdaptor( + BufferAllocator.heap(), BufferAllocator.direct()); + return adaptor = new ByteBufAdaptor(alloc, this); + } + return bba; + } + + @Override + public int refCnt() { + return isAccessible()? 1 + countBorrows() : 0; + } + + @Override + public ReferenceCounted retain() { + return retain(1); + } + + @Override + public ReferenceCounted retain(int increment) { + for (int i = 0; i < increment; i++) { + acquire(); + } + return this; + } + + @Override + public ReferenceCounted touch() { + return this; + } + + @Override + public ReferenceCounted touch(Object hint) { + return this; + } + + @Override + public boolean release() { + return release(1); + } + + @Override + public boolean release(int decrement) { + for (int i = 0; i < decrement; i++) { + close(); + } + return !isAccessible(); + } + // } diff --git a/buffer-api/src/main/java/io/netty/buffer/api/MemoryManagersOverride.java b/buffer-api/src/main/java/io/netty/buffer/api/internal/MemoryManagersOverride.java similarity index 86% rename from buffer-api/src/main/java/io/netty/buffer/api/MemoryManagersOverride.java rename to buffer-api/src/main/java/io/netty/buffer/api/internal/MemoryManagersOverride.java index c59125b..e4b0255 100644 --- a/buffer-api/src/main/java/io/netty/buffer/api/MemoryManagersOverride.java +++ b/buffer-api/src/main/java/io/netty/buffer/api/internal/MemoryManagersOverride.java @@ -13,8 +13,9 @@ * License for the specific language governing permissions and limitations * under the License. */ -package io.netty.buffer.api; +package io.netty.buffer.api.internal; +import io.netty.buffer.api.MemoryManagers; import io.netty.buffer.api.bytebuffer.ByteBufferMemoryManagers; import java.util.Collections; @@ -23,7 +24,7 @@ import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Supplier; -final class MemoryManagersOverride { +public final class MemoryManagersOverride { private static final MemoryManagers DEFAULT = new ByteBufferMemoryManagers(); private static final AtomicInteger OVERRIDES_AVAILABLE = new AtomicInteger(); private static final Map OVERRIDES = Collections.synchronizedMap(new IdentityHashMap<>()); @@ -31,14 +32,14 @@ final class MemoryManagersOverride { private MemoryManagersOverride() { } - static MemoryManagers getManagers() { + public static MemoryManagers getManagers() { if (OVERRIDES_AVAILABLE.get() > 0) { return OVERRIDES.getOrDefault(Thread.currentThread(), DEFAULT); } return DEFAULT; } - static T using(MemoryManagers managers, Supplier supplier) { + public static T using(MemoryManagers managers, Supplier supplier) { Thread thread = Thread.currentThread(); OVERRIDES.put(thread, managers); OVERRIDES_AVAILABLE.incrementAndGet(); diff --git a/buffer-api/src/main/java/io/netty/buffer/api/unsafe/UnsafeBuffer.java b/buffer-api/src/main/java/io/netty/buffer/api/unsafe/UnsafeBuffer.java index 8f875f0..793688b 100644 --- a/buffer-api/src/main/java/io/netty/buffer/api/unsafe/UnsafeBuffer.java +++ b/buffer-api/src/main/java/io/netty/buffer/api/unsafe/UnsafeBuffer.java @@ -15,12 +15,16 @@ */ package io.netty.buffer.api.unsafe; +import io.netty.buffer.ByteBuf; import io.netty.buffer.api.BufferAllocator; import io.netty.buffer.api.AllocatorControl; import io.netty.buffer.api.Buffer; import io.netty.buffer.api.ByteCursor; import io.netty.buffer.api.Drop; import io.netty.buffer.api.Owned; +import io.netty.buffer.api.adaptor.BufferIntegratable; +import io.netty.buffer.api.adaptor.ByteBufAdaptor; +import io.netty.buffer.api.adaptor.ByteBufAllocatorAdaptor; import io.netty.buffer.api.internal.ResourceSupport; import io.netty.buffer.api.ReadableComponent; import io.netty.buffer.api.ReadableComponentProcessor; @@ -28,6 +32,7 @@ import io.netty.buffer.api.WritableComponent; import io.netty.buffer.api.WritableComponentProcessor; import io.netty.buffer.api.internal.ArcDrop; import io.netty.buffer.api.internal.Statics; +import io.netty.util.ReferenceCounted; import io.netty.util.internal.PlatformDependent; import java.lang.ref.Reference; @@ -40,7 +45,7 @@ import static io.netty.buffer.api.internal.Statics.bufferIsReadOnly; import static io.netty.util.internal.PlatformDependent.BIG_ENDIAN_NATIVE_ORDER; class UnsafeBuffer extends ResourceSupport implements Buffer, ReadableComponent, - WritableComponent { + WritableComponent, BufferIntegratable { private static final int CLOSED_SIZE = -1; private static final boolean ACCESS_UNALIGNED = PlatformDependent.isUnaligned(); private UnsafeMemory memory; // The memory liveness; monitored by Cleaner. @@ -1606,4 +1611,59 @@ class UnsafeBuffer extends ResourceSupport implements Buff Object recover() { return memory; } + + // + private ByteBufAdaptor adaptor; + @Override + public ByteBuf asByteBuf() { + ByteBufAdaptor bba = adaptor; + if (bba == null) { + ByteBufAllocatorAdaptor alloc = new ByteBufAllocatorAdaptor( + BufferAllocator.heap(), BufferAllocator.direct()); + return adaptor = new ByteBufAdaptor(alloc, this); + } + return bba; + } + + @Override + public int refCnt() { + return isAccessible()? 1 + countBorrows() : 0; + } + + @Override + public ReferenceCounted retain() { + return retain(1); + } + + @Override + public ReferenceCounted retain(int increment) { + for (int i = 0; i < increment; i++) { + acquire(); + } + return this; + } + + @Override + public ReferenceCounted touch() { + return this; + } + + @Override + public ReferenceCounted touch(Object hint) { + return this; + } + + @Override + public boolean release() { + return release(1); + } + + @Override + public boolean release(int decrement) { + for (int i = 0; i < decrement; i++) { + close(); + } + return !isAccessible(); + } + // } diff --git a/buffer-api/src/main/java/io/netty/buffer/api/unsafe/UnsafeMemoryManagers.java b/buffer-api/src/main/java/io/netty/buffer/api/unsafe/UnsafeMemoryManagers.java index e1f0ed3..0c4ef5c 100644 --- a/buffer-api/src/main/java/io/netty/buffer/api/unsafe/UnsafeMemoryManagers.java +++ b/buffer-api/src/main/java/io/netty/buffer/api/unsafe/UnsafeMemoryManagers.java @@ -39,6 +39,11 @@ public class UnsafeMemoryManagers implements MemoryManagers { return new UnsafeMemoryManager(true); } + @Override + public String implementationName() { + return "Unsafe"; + } + @Override public String toString() { return "US"; diff --git a/buffer-memseg/src/main/java/io/netty/buffer/api/memseg/SegmentMemoryManagers.java b/buffer-memseg/src/main/java/io/netty/buffer/api/memseg/SegmentMemoryManagers.java index c004270..e28561f 100644 --- a/buffer-memseg/src/main/java/io/netty/buffer/api/memseg/SegmentMemoryManagers.java +++ b/buffer-memseg/src/main/java/io/netty/buffer/api/memseg/SegmentMemoryManagers.java @@ -29,6 +29,11 @@ public class SegmentMemoryManagers implements MemoryManagers { return new NativeMemorySegmentManager(); } + @Override + public String implementationName() { + return "MemorySegment"; + } + @Override public String toString() { return "MS"; diff --git a/buffer-tests/src/test/java/io/netty/buffer/api/tests/adaptor/ByteBufAdaptorTest.java b/buffer-tests/src/test/java/io/netty/buffer/api/tests/adaptor/ByteBufAdaptorTest.java index 34df8ff..743d32d 100644 --- a/buffer-tests/src/test/java/io/netty/buffer/api/tests/adaptor/ByteBufAdaptorTest.java +++ b/buffer-tests/src/test/java/io/netty/buffer/api/tests/adaptor/ByteBufAdaptorTest.java @@ -16,17 +16,25 @@ package io.netty.buffer.api.tests.adaptor; import io.netty.buffer.ByteBuf; +import io.netty.buffer.api.BufferAllocator; +import io.netty.buffer.api.MemoryManagers; import io.netty.buffer.api.adaptor.ByteBufAllocatorAdaptor; import org.junit.AfterClass; -import org.junit.BeforeClass; import org.junit.Ignore; -public class ByteBufAdaptorTest extends AbstractByteBufTest { +import java.util.Optional; + +import static org.junit.jupiter.api.Assumptions.assumeTrue; + +public abstract class ByteBufAdaptorTest extends AbstractByteBufTest { static ByteBufAllocatorAdaptor alloc; - @BeforeClass - public static void setUpAllocator() { - alloc = new ByteBufAllocatorAdaptor(); + static void setUpAllocator(String name) { + Optional managers = MemoryManagers.lookupImplementation(name); + assumeTrue(managers.isPresent()); + BufferAllocator onheap = MemoryManagers.using(managers.get(), BufferAllocator::pooledHeap); + BufferAllocator offheap = MemoryManagers.using(managers.get(), BufferAllocator::pooledHeap); + alloc = new ByteBufAllocatorAdaptor(onheap, offheap); } @AfterClass diff --git a/buffer-tests/src/test/java/io/netty/buffer/api/tests/adaptor/MemSegByteBufAdaptorTest.java b/buffer-tests/src/test/java/io/netty/buffer/api/tests/adaptor/MemSegByteBufAdaptorTest.java new file mode 100644 index 0000000..ebd34d7 --- /dev/null +++ b/buffer-tests/src/test/java/io/netty/buffer/api/tests/adaptor/MemSegByteBufAdaptorTest.java @@ -0,0 +1,25 @@ +/* + * Copyright 2021 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package io.netty.buffer.api.tests.adaptor; + +import org.junit.BeforeClass; + +public class MemSegByteBufAdaptorTest extends ByteBufAdaptorTest { + @BeforeClass + public static void setUpAllocator() { + setUpAllocator("MemorySegment"); + } +} diff --git a/buffer-tests/src/test/java/io/netty/buffer/api/tests/adaptor/NioByteBufAdaptorTest.java b/buffer-tests/src/test/java/io/netty/buffer/api/tests/adaptor/NioByteBufAdaptorTest.java new file mode 100644 index 0000000..34d5637 --- /dev/null +++ b/buffer-tests/src/test/java/io/netty/buffer/api/tests/adaptor/NioByteBufAdaptorTest.java @@ -0,0 +1,25 @@ +/* + * Copyright 2021 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package io.netty.buffer.api.tests.adaptor; + +import org.junit.BeforeClass; + +public class NioByteBufAdaptorTest extends ByteBufAdaptorTest { + @BeforeClass + public static void setUpAllocator() { + setUpAllocator("ByteBuffer"); + } +} diff --git a/buffer-tests/src/test/java/io/netty/buffer/api/tests/adaptor/UnsafeByteBufAdaptorTest.java b/buffer-tests/src/test/java/io/netty/buffer/api/tests/adaptor/UnsafeByteBufAdaptorTest.java new file mode 100644 index 0000000..f7535c3 --- /dev/null +++ b/buffer-tests/src/test/java/io/netty/buffer/api/tests/adaptor/UnsafeByteBufAdaptorTest.java @@ -0,0 +1,25 @@ +/* + * Copyright 2021 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +package io.netty.buffer.api.tests.adaptor; + +import org.junit.BeforeClass; + +public class UnsafeByteBufAdaptorTest extends ByteBufAdaptorTest { + @BeforeClass + public static void setUpAllocator() { + setUpAllocator("Unsafe"); + } +} From ecbd2476e14c80fdf594278612aa1541a25e651b Mon Sep 17 00:00:00 2001 From: Chris Vest Date: Fri, 28 May 2021 14:07:31 +0200 Subject: [PATCH 2/6] Use correct assume function for JUnit4 tests --- .../io/netty/buffer/api/tests/adaptor/ByteBufAdaptorTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buffer-tests/src/test/java/io/netty/buffer/api/tests/adaptor/ByteBufAdaptorTest.java b/buffer-tests/src/test/java/io/netty/buffer/api/tests/adaptor/ByteBufAdaptorTest.java index 743d32d..3cc8d9d 100644 --- a/buffer-tests/src/test/java/io/netty/buffer/api/tests/adaptor/ByteBufAdaptorTest.java +++ b/buffer-tests/src/test/java/io/netty/buffer/api/tests/adaptor/ByteBufAdaptorTest.java @@ -24,7 +24,7 @@ import org.junit.Ignore; import java.util.Optional; -import static org.junit.jupiter.api.Assumptions.assumeTrue; +import static org.junit.Assume.assumeTrue; public abstract class ByteBufAdaptorTest extends AbstractByteBufTest { static ByteBufAllocatorAdaptor alloc; From 78b30a1b37b162545385453bae71995456760fa8 Mon Sep 17 00:00:00 2001 From: Chris Vest Date: Fri, 28 May 2021 15:13:47 +0200 Subject: [PATCH 3/6] Convert ByteBufAdaptorTests to JUnit 5, and fix the MemSeg test skipping for Java 11 --- .../tests/adaptor/AbstractByteBufTest.java | 1186 ++++++++--------- .../api/tests/adaptor/ByteBufAdaptorTest.java | 32 +- .../adaptor/MemSegByteBufAdaptorTest.java | 4 +- .../tests/adaptor/NioByteBufAdaptorTest.java | 4 +- .../adaptor/UnsafeByteBufAdaptorTest.java | 4 +- 5 files changed, 587 insertions(+), 643 deletions(-) diff --git a/buffer-tests/src/test/java/io/netty/buffer/api/tests/adaptor/AbstractByteBufTest.java b/buffer-tests/src/test/java/io/netty/buffer/api/tests/adaptor/AbstractByteBufTest.java index a6b58cd..fe3bab3 100644 --- a/buffer-tests/src/test/java/io/netty/buffer/api/tests/adaptor/AbstractByteBufTest.java +++ b/buffer-tests/src/test/java/io/netty/buffer/api/tests/adaptor/AbstractByteBufTest.java @@ -21,9 +21,9 @@ import io.netty.util.ByteProcessor; import io.netty.util.CharsetUtil; import io.netty.util.IllegalReferenceCountException; import io.netty.util.internal.PlatformDependent; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -40,6 +40,7 @@ import java.nio.channels.GatheringByteChannel; import java.nio.channels.ScatteringByteChannel; import java.nio.channels.WritableByteChannel; import java.nio.charset.Charset; +import java.time.Duration; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; @@ -60,15 +61,18 @@ import static io.netty.buffer.Unpooled.directBuffer; import static io.netty.buffer.Unpooled.unreleasableBuffer; import static io.netty.buffer.Unpooled.wrappedBuffer; import static io.netty.util.internal.EmptyArrays.EMPTY_BYTES; -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertSame; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import static org.junit.Assume.assumeFalse; -import static org.junit.Assume.assumeTrue; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTimeoutPreemptively; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; +import static org.junit.jupiter.api.Assumptions.assumeFalse; +import static org.junit.jupiter.api.Assumptions.assumeTrue; /** * An abstract test class for channel buffers @@ -93,14 +97,14 @@ public abstract class AbstractByteBufTest { return true; } - @Before + @BeforeEach public void init() { buffer = newBuffer(CAPACITY); seed = System.currentTimeMillis(); random = new Random(seed); } - @After + @AfterEach public void dispose() { if (buffer != null) { assertTrue(buffer.release()); @@ -139,34 +143,22 @@ public abstract class AbstractByteBufTest { assertEquals(0, buffer.readerIndex()); } - @Test(expected = IndexOutOfBoundsException.class) + @Test public void readerIndexBoundaryCheck1() { - try { - buffer.writerIndex(0); - } catch (IndexOutOfBoundsException e) { - fail(); - } - buffer.readerIndex(-1); + buffer.writerIndex(0); + assertThrows(IndexOutOfBoundsException.class, () -> buffer.readerIndex(-1)); } - @Test(expected = IndexOutOfBoundsException.class) + @Test public void readerIndexBoundaryCheck2() { - try { - buffer.writerIndex(buffer.capacity()); - } catch (IndexOutOfBoundsException e) { - fail(); - } - buffer.readerIndex(buffer.capacity() + 1); + buffer.writerIndex(buffer.capacity()); + assertThrows(IndexOutOfBoundsException.class, () -> buffer.readerIndex(buffer.capacity() + 1)); } - @Test(expected = IndexOutOfBoundsException.class) + @Test public void readerIndexBoundaryCheck3() { - try { - buffer.writerIndex(CAPACITY / 2); - } catch (IndexOutOfBoundsException e) { - fail(); - } - buffer.readerIndex(CAPACITY * 3 / 2); + buffer.writerIndex(CAPACITY / 2); + assertThrows(IndexOutOfBoundsException.class, () -> buffer.readerIndex(CAPACITY * 3 / 2)); } @Test @@ -177,31 +169,23 @@ public abstract class AbstractByteBufTest { buffer.readerIndex(buffer.capacity()); } - @Test(expected = IndexOutOfBoundsException.class) + @Test public void writerIndexBoundaryCheck1() { - buffer.writerIndex(-1); + assertThrows(IndexOutOfBoundsException.class, () -> buffer.writerIndex(-1)); } - @Test(expected = IndexOutOfBoundsException.class) + @Test public void writerIndexBoundaryCheck2() { - try { - buffer.writerIndex(CAPACITY); - buffer.readerIndex(CAPACITY); - } catch (IndexOutOfBoundsException e) { - fail(); - } - buffer.writerIndex(buffer.capacity() + 1); + buffer.writerIndex(CAPACITY); + buffer.readerIndex(CAPACITY); + assertThrows(IndexOutOfBoundsException.class, () -> buffer.writerIndex(buffer.capacity() + 1)); } - @Test(expected = IndexOutOfBoundsException.class) + @Test public void writerIndexBoundaryCheck3() { - try { - buffer.writerIndex(CAPACITY); - buffer.readerIndex(CAPACITY / 2); - } catch (IndexOutOfBoundsException e) { - fail(); - } - buffer.writerIndex(CAPACITY / 4); + buffer.writerIndex(CAPACITY); + buffer.readerIndex(CAPACITY / 2); + assertThrows(IndexOutOfBoundsException.class, () -> buffer.writerIndex(CAPACITY / 4)); } @Test @@ -213,86 +197,81 @@ public abstract class AbstractByteBufTest { buffer.writeBytes(ByteBuffer.wrap(EMPTY_BYTES)); } - @Test(expected = IndexOutOfBoundsException.class) + @Test public void getBooleanBoundaryCheck1() { - buffer.getBoolean(-1); + assertThrows(IndexOutOfBoundsException.class, () -> buffer.getBoolean(-1)); } - @Test(expected = IndexOutOfBoundsException.class) + @Test public void getBooleanBoundaryCheck2() { - buffer.getBoolean(buffer.capacity()); + assertThrows(IndexOutOfBoundsException.class, () -> buffer.getBoolean(buffer.capacity())); } - @Test(expected = IndexOutOfBoundsException.class) + @Test public void getByteBoundaryCheck1() { - buffer.getByte(-1); + assertThrows(IndexOutOfBoundsException.class, () -> buffer.getByte(-1)); } - @Test(expected = IndexOutOfBoundsException.class) + @Test public void getByteBoundaryCheck2() { - buffer.getByte(buffer.capacity()); + assertThrows(IndexOutOfBoundsException.class, () -> buffer.getByte(buffer.capacity())); } - @Test(expected = IndexOutOfBoundsException.class) + @Test public void getShortBoundaryCheck1() { - buffer.getShort(-1); + assertThrows(IndexOutOfBoundsException.class, () -> buffer.getShort(-1)); } - @Test(expected = IndexOutOfBoundsException.class) + @Test public void getShortBoundaryCheck2() { - buffer.getShort(buffer.capacity() - 1); + assertThrows(IndexOutOfBoundsException.class, () -> buffer.getShort(buffer.capacity() - 1)); } - @Test(expected = IndexOutOfBoundsException.class) + @Test public void getMediumBoundaryCheck1() { - buffer.getMedium(-1); + assertThrows(IndexOutOfBoundsException.class, () -> buffer.getMedium(-1)); } - @Test(expected = IndexOutOfBoundsException.class) + @Test public void getMediumBoundaryCheck2() { - buffer.getMedium(buffer.capacity() - 2); + assertThrows(IndexOutOfBoundsException.class, () -> buffer.getMedium(buffer.capacity() - 2)); } - @Test(expected = IndexOutOfBoundsException.class) + @Test public void getIntBoundaryCheck1() { - buffer.getInt(-1); + assertThrows(IndexOutOfBoundsException.class, () -> buffer.getInt(-1)); } - @Test(expected = IndexOutOfBoundsException.class) + @Test public void getIntBoundaryCheck2() { - buffer.getInt(buffer.capacity() - 3); + assertThrows(IndexOutOfBoundsException.class, () -> buffer.getInt(buffer.capacity() - 3)); } - @Test(expected = IndexOutOfBoundsException.class) + @Test public void getLongBoundaryCheck1() { - buffer.getLong(-1); + assertThrows(IndexOutOfBoundsException.class, () -> buffer.getLong(-1)); } - @Test(expected = IndexOutOfBoundsException.class) + @Test public void getLongBoundaryCheck2() { - buffer.getLong(buffer.capacity() - 7); + assertThrows(IndexOutOfBoundsException.class, () -> buffer.getLong(buffer.capacity() - 7)); } - @Test(expected = IndexOutOfBoundsException.class) + @Test public void getByteArrayBoundaryCheck1() { - buffer.getBytes(-1, EMPTY_BYTES); + assertThrows(IndexOutOfBoundsException.class, () -> buffer.getBytes(-1, EMPTY_BYTES)); } - @Test(expected = IndexOutOfBoundsException.class) + @Test public void getByteArrayBoundaryCheck2() { - buffer.getBytes(-1, EMPTY_BYTES, 0, 0); + assertThrows(IndexOutOfBoundsException.class, () -> buffer.getBytes(-1, EMPTY_BYTES, 0, 0)); } @Test public void getByteArrayBoundaryCheck3() { byte[] dst = new byte[4]; buffer.setInt(0, 0x01020304); - try { - buffer.getBytes(0, dst, -1, 4); - fail(); - } catch (IndexOutOfBoundsException e) { - // Success - } + assertThrows(IndexOutOfBoundsException.class, () -> buffer.getBytes(0, dst, -1, 4)); // No partial copy is expected. assertEquals(0, dst[0]); @@ -305,12 +284,7 @@ public abstract class AbstractByteBufTest { public void getByteArrayBoundaryCheck4() { byte[] dst = new byte[4]; buffer.setInt(0, 0x01020304); - try { - buffer.getBytes(0, dst, 1, 4); - fail(); - } catch (IndexOutOfBoundsException e) { - // Success - } + assertThrows(IndexOutOfBoundsException.class, () -> buffer.getBytes(0, dst, 1, 4)); // No partial copy is expected. assertEquals(0, dst[0]); @@ -319,44 +293,44 @@ public abstract class AbstractByteBufTest { assertEquals(0, dst[3]); } - @Test(expected = IndexOutOfBoundsException.class) + @Test public void getByteBufferBoundaryCheck() { - buffer.getBytes(-1, ByteBuffer.allocate(0)); + assertThrows(IndexOutOfBoundsException.class, () -> buffer.getBytes(-1, ByteBuffer.allocate(0))); } - @Test(expected = IndexOutOfBoundsException.class) + @Test public void copyBoundaryCheck1() { - buffer.copy(-1, 0); + assertThrows(IndexOutOfBoundsException.class, () -> buffer.copy(-1, 0)); } - @Test(expected = IndexOutOfBoundsException.class) + @Test public void copyBoundaryCheck2() { - buffer.copy(0, buffer.capacity() + 1); + assertThrows(IndexOutOfBoundsException.class, () -> buffer.copy(0, buffer.capacity() + 1)); } - @Test(expected = IndexOutOfBoundsException.class) + @Test public void copyBoundaryCheck3() { - buffer.copy(buffer.capacity() + 1, 0); + assertThrows(IndexOutOfBoundsException.class, () -> buffer.copy(buffer.capacity() + 1, 0)); } - @Test(expected = IndexOutOfBoundsException.class) + @Test public void copyBoundaryCheck4() { - buffer.copy(buffer.capacity(), 1); + assertThrows(IndexOutOfBoundsException.class, () -> buffer.copy(buffer.capacity(), 1)); } - @Test(expected = IndexOutOfBoundsException.class) + @Test public void setIndexBoundaryCheck1() { - buffer.setIndex(-1, CAPACITY); + assertThrows(IndexOutOfBoundsException.class, () -> buffer.setIndex(-1, CAPACITY)); } - @Test(expected = IndexOutOfBoundsException.class) + @Test public void setIndexBoundaryCheck2() { - buffer.setIndex(CAPACITY / 2, CAPACITY / 4); + assertThrows(IndexOutOfBoundsException.class, () -> buffer.setIndex(CAPACITY / 2, CAPACITY / 4)); } - @Test(expected = IndexOutOfBoundsException.class) + @Test public void setIndexBoundaryCheck3() { - buffer.setIndex(0, CAPACITY + 1); + assertThrows(IndexOutOfBoundsException.class, () -> buffer.setIndex(0, CAPACITY + 1)); } @Test @@ -381,9 +355,9 @@ public abstract class AbstractByteBufTest { assertEquals(0, dst.get(3)); } - @Test(expected = IndexOutOfBoundsException.class) + @Test public void getDirectByteBufferBoundaryCheck() { - buffer.getBytes(-1, ByteBuffer.allocateDirect(0)); + assertThrows(IndexOutOfBoundsException.class, () -> buffer.getBytes(-1, ByteBuffer.allocateDirect(0))); } @Test @@ -1739,12 +1713,7 @@ public abstract class AbstractByteBufTest { @Test public void testWriteZero() { - try { - buffer.writeZero(-1); - fail(); - } catch (IllegalArgumentException e) { - // Expected - } + assertThrows(IllegalArgumentException.class, () -> buffer.writeZero(-1)); buffer.clear(); while (buffer.isWritable()) { @@ -1999,18 +1968,13 @@ public abstract class AbstractByteBufTest { assertEquals(buffer, wrappedBuffer(value).order(LITTLE_ENDIAN)); value[0] ++; - assertFalse(buffer.equals(wrappedBuffer(value))); - assertFalse(buffer.equals(wrappedBuffer(value).order(LITTLE_ENDIAN))); + assertNotEquals(buffer, wrappedBuffer(value)); + assertNotEquals(buffer, wrappedBuffer(value).order(LITTLE_ENDIAN)); } @Test public void testCompareTo() { - try { - buffer.compareTo(null); - fail(); - } catch (NullPointerException e) { - // Expected - } + assertThrows(NullPointerException.class, () -> buffer.compareTo(null)); // Fill the random stuff byte[] value = new byte[32]; @@ -2081,7 +2045,7 @@ public abstract class AbstractByteBufTest { copied.release(); } - @Test(timeout = 10000) + @Test public void testToStringMultipleThreads() throws Throwable { buffer.clear(); buffer.writeBytes("Hello, World!".getBytes(CharsetUtil.ISO_8859_1)); @@ -2105,9 +2069,11 @@ public abstract class AbstractByteBufTest { thread.start(); } - for (Thread thread : threads) { - thread.join(); - } + assertTimeoutPreemptively(Duration.ofSeconds(10), () -> { + for (Thread thread : threads) { + thread.join(); + } + }); Throwable error = errorRef.get(); if (error != null) { @@ -2162,19 +2128,8 @@ public abstract class AbstractByteBufTest { assertEquals(1, buffer.indexOf(1, 4, (byte) 2)); assertEquals(3, buffer.indexOf(4, 1, (byte) 2)); - try { - buffer.indexOf(0, buffer.capacity() + 1, (byte) 0); - fail(); - } catch (IndexOutOfBoundsException expected) { - // expected - } - - try { - buffer.indexOf(buffer.capacity(), -1, (byte) 0); - fail(); - } catch (IndexOutOfBoundsException expected) { - // expected - } + assertThrows(IndexOutOfBoundsException.class, () -> buffer.indexOf(0, buffer.capacity() + 1, (byte) 0)); + assertThrows(IndexOutOfBoundsException.class, () -> buffer.indexOf(buffer.capacity(), -1, (byte) 0)); assertEquals(4, buffer.indexOf(buffer.capacity() + 1, 0, (byte) 1)); assertEquals(0, buffer.indexOf(-1, buffer.capacity(), (byte) 1)); @@ -2184,12 +2139,7 @@ public abstract class AbstractByteBufTest { public void testIndexOfReleaseBuffer() { ByteBuf buffer = releasedBuffer(); if (buffer.capacity() != 0) { - try { - buffer.indexOf(0, 1, (byte) 1); - fail(); - } catch (IllegalReferenceCountException expected) { - // expected - } + assertThrows(IllegalReferenceCountException.class, () -> buffer.indexOf(0, 1, (byte) 1)); } else { assertEquals(-1, buffer.indexOf(0, 1, (byte) 1)); } @@ -2247,12 +2197,7 @@ public abstract class AbstractByteBufTest { buffer.skipBytes(CAPACITY / 4); assertEquals(CAPACITY / 4 * 2, buffer.readerIndex()); - try { - buffer.skipBytes(CAPACITY / 4 + 1); - fail(); - } catch (IndexOutOfBoundsException e) { - // Expected - } + assertThrows(IndexOutOfBoundsException.class, () -> buffer.skipBytes(CAPACITY / 4 + 1)); // Should remain unchanged. assertEquals(CAPACITY / 4 * 2, buffer.readerIndex()); @@ -2559,20 +2504,21 @@ public abstract class AbstractByteBufTest { buffer.release(); } - @Test(expected = IndexOutOfBoundsException.class) + @Test public void readByteThrowsIndexOutOfBoundsException() { - final ByteBuf buffer = newBuffer(8); - try { - buffer.writeByte(0); - assertEquals((byte) 0, buffer.readByte()); - buffer.readByte(); - } finally { - buffer.release(); - } + assertThrows(IndexOutOfBoundsException.class, () -> { + final ByteBuf buffer = newBuffer(8); + try { + buffer.writeByte(0); + assertEquals((byte) 0, buffer.readByte()); + buffer.readByte(); + } finally { + buffer.release(); + } + }); } @Test - @SuppressWarnings("ForLoopThatDoesntUseLoopVariable") public void testNioBufferExposeOnlyRegion() { final ByteBuf buffer = newBuffer(8); byte[] data = new byte[8]; @@ -2626,730 +2572,751 @@ public abstract class AbstractByteBufTest { return buffer; } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testDiscardReadBytesAfterRelease() { - releasedBuffer().discardReadBytes(); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().discardReadBytes()); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testDiscardSomeReadBytesAfterRelease() { - releasedBuffer().discardSomeReadBytes(); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().discardSomeReadBytes()); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testEnsureWritableAfterRelease() { - releasedBuffer().ensureWritable(16); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().ensureWritable(16)); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testGetBooleanAfterRelease() { - releasedBuffer().getBoolean(0); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().getBoolean(0)); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testGetByteAfterRelease() { - releasedBuffer().getByte(0); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().getByte(0)); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testGetUnsignedByteAfterRelease() { - releasedBuffer().getUnsignedByte(0); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().getUnsignedByte(0)); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testGetShortAfterRelease() { - releasedBuffer().getShort(0); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().getShort(0)); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testGetShortLEAfterRelease() { - releasedBuffer().getShortLE(0); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().getShortLE(0)); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testGetUnsignedShortAfterRelease() { - releasedBuffer().getUnsignedShort(0); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().getUnsignedShort(0)); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testGetUnsignedShortLEAfterRelease() { - releasedBuffer().getUnsignedShortLE(0); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().getUnsignedShortLE(0)); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testGetMediumAfterRelease() { - releasedBuffer().getMedium(0); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().getMedium(0)); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testGetMediumLEAfterRelease() { - releasedBuffer().getMediumLE(0); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().getMediumLE(0)); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testGetUnsignedMediumAfterRelease() { - releasedBuffer().getUnsignedMedium(0); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().getUnsignedMedium(0)); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testGetIntAfterRelease() { - releasedBuffer().getInt(0); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().getInt(0)); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testGetIntLEAfterRelease() { - releasedBuffer().getIntLE(0); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().getIntLE(0)); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testGetUnsignedIntAfterRelease() { - releasedBuffer().getUnsignedInt(0); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().getUnsignedInt(0)); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testGetUnsignedIntLEAfterRelease() { - releasedBuffer().getUnsignedIntLE(0); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().getUnsignedIntLE(0)); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testGetLongAfterRelease() { - releasedBuffer().getLong(0); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().getLong(0)); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testGetLongLEAfterRelease() { - releasedBuffer().getLongLE(0); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().getLongLE(0)); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testGetCharAfterRelease() { - releasedBuffer().getChar(0); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().getChar(0)); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testGetFloatAfterRelease() { - releasedBuffer().getFloat(0); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().getFloat(0)); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testGetFloatLEAfterRelease() { - releasedBuffer().getFloatLE(0); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().getFloatLE(0)); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testGetDoubleAfterRelease() { - releasedBuffer().getDouble(0); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().getDouble(0)); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testGetDoubleLEAfterRelease() { - releasedBuffer().getDoubleLE(0); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().getDoubleLE(0)); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testGetBytesAfterRelease() { - ByteBuf buffer = buffer(8); - try { - releasedBuffer().getBytes(0, buffer); - } finally { - buffer.release(); - } + assertThrows(IllegalReferenceCountException.class, () -> { + ByteBuf buffer = buffer(8); + try { + releasedBuffer().getBytes(0, buffer); + } finally { + buffer.release(); + } + }); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testGetBytesAfterRelease2() { - ByteBuf buffer = buffer(); - try { - releasedBuffer().getBytes(0, buffer, 1); - } finally { - buffer.release(); - } + assertThrows(IllegalReferenceCountException.class, () -> { + ByteBuf buffer = buffer(); + try { + releasedBuffer().getBytes(0, buffer, 1); + } finally { + buffer.release(); + } + }); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testGetBytesAfterRelease3() { - ByteBuf buffer = buffer(); - try { - releasedBuffer().getBytes(0, buffer, 0, 1); - } finally { - buffer.release(); - } + assertThrows(IllegalReferenceCountException.class, () -> { + ByteBuf buffer = buffer(); + try { + releasedBuffer().getBytes(0, buffer, 0, 1); + } finally { + buffer.release(); + } + }); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testGetBytesAfterRelease4() { - releasedBuffer().getBytes(0, new byte[8]); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().getBytes(0, new byte[8])); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testGetBytesAfterRelease5() { - releasedBuffer().getBytes(0, new byte[8], 0, 1); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().getBytes(0, new byte[8], 0, 1)); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testGetBytesAfterRelease6() { - releasedBuffer().getBytes(0, ByteBuffer.allocate(8)); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().getBytes(0, ByteBuffer.allocate(8))); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testGetBytesAfterRelease7() throws IOException { - releasedBuffer().getBytes(0, new ByteArrayOutputStream(), 1); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().getBytes(0, new ByteArrayOutputStream(), 1)); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testGetBytesAfterRelease8() throws IOException { - releasedBuffer().getBytes(0, new DevNullGatheringByteChannel(), 1); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().getBytes(0, new DevNullGatheringByteChannel(), 1)); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testSetBooleanAfterRelease() { - releasedBuffer().setBoolean(0, true); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().setBoolean(0, true)); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testSetByteAfterRelease() { - releasedBuffer().setByte(0, 1); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().setByte(0, 1)); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testSetShortAfterRelease() { - releasedBuffer().setShort(0, 1); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().setShort(0, 1)); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testSetShortLEAfterRelease() { - releasedBuffer().setShortLE(0, 1); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().setShortLE(0, 1)); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testSetMediumAfterRelease() { - releasedBuffer().setMedium(0, 1); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().setMedium(0, 1)); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testSetMediumLEAfterRelease() { - releasedBuffer().setMediumLE(0, 1); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().setMediumLE(0, 1)); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testSetIntAfterRelease() { - releasedBuffer().setInt(0, 1); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().setInt(0, 1)); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testSetIntLEAfterRelease() { - releasedBuffer().setIntLE(0, 1); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().setIntLE(0, 1)); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testSetLongAfterRelease() { - releasedBuffer().setLong(0, 1); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().setLong(0, 1)); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testSetLongLEAfterRelease() { - releasedBuffer().setLongLE(0, 1); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().setLongLE(0, 1)); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testSetCharAfterRelease() { - releasedBuffer().setChar(0, 1); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().setChar(0, 1)); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testSetFloatAfterRelease() { - releasedBuffer().setFloat(0, 1); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().setFloat(0, 1)); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testSetDoubleAfterRelease() { - releasedBuffer().setDouble(0, 1); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().setDouble(0, 1)); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testSetBytesAfterRelease() { - ByteBuf buffer = buffer(); - try { - releasedBuffer().setBytes(0, buffer); - } finally { - buffer.release(); - } + assertThrows(IllegalReferenceCountException.class, () -> { + ByteBuf buffer = buffer(); + try { + releasedBuffer().setBytes(0, buffer); + } finally { + buffer.release(); + } + }); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testSetBytesAfterRelease2() { - ByteBuf buffer = buffer(); - try { - releasedBuffer().setBytes(0, buffer, 1); - } finally { - buffer.release(); - } + assertThrows(IllegalReferenceCountException.class, () -> { + ByteBuf buffer = buffer(); + try { + releasedBuffer().setBytes(0, buffer, 1); + } finally { + buffer.release(); + } + }); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testSetBytesAfterRelease3() { - ByteBuf buffer = buffer(); - try { - releasedBuffer().setBytes(0, buffer, 0, 1); - } finally { - buffer.release(); - } + assertThrows(IllegalReferenceCountException.class, () -> { + ByteBuf buffer = buffer(); + try { + releasedBuffer().setBytes(0, buffer, 0, 1); + } finally { + buffer.release(); + } + }); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testSetUsAsciiCharSequenceAfterRelease() { - testSetCharSequenceAfterRelease0(CharsetUtil.US_ASCII); + assertThrows(IllegalReferenceCountException.class, () -> testSetCharSequenceAfterRelease0(CharsetUtil.US_ASCII)); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testSetIso88591CharSequenceAfterRelease() { - testSetCharSequenceAfterRelease0(CharsetUtil.ISO_8859_1); + assertThrows(IllegalReferenceCountException.class, () -> testSetCharSequenceAfterRelease0(CharsetUtil.ISO_8859_1)); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testSetUtf8CharSequenceAfterRelease() { - testSetCharSequenceAfterRelease0(CharsetUtil.UTF_8); + assertThrows(IllegalReferenceCountException.class, () -> testSetCharSequenceAfterRelease0(CharsetUtil.UTF_8)); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testSetUtf16CharSequenceAfterRelease() { - testSetCharSequenceAfterRelease0(CharsetUtil.UTF_16); + assertThrows(IllegalReferenceCountException.class, () -> testSetCharSequenceAfterRelease0(CharsetUtil.UTF_16)); } private void testSetCharSequenceAfterRelease0(Charset charset) { releasedBuffer().setCharSequence(0, "x", charset); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testSetBytesAfterRelease4() { - releasedBuffer().setBytes(0, new byte[8]); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().setBytes(0, new byte[8])); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testSetBytesAfterRelease5() { - releasedBuffer().setBytes(0, new byte[8], 0, 1); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().setBytes(0, new byte[8], 0, 1)); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testSetBytesAfterRelease6() { - releasedBuffer().setBytes(0, ByteBuffer.allocate(8)); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().setBytes(0, ByteBuffer.allocate(8))); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testSetBytesAfterRelease7() throws IOException { - releasedBuffer().setBytes(0, new ByteArrayInputStream(new byte[8]), 1); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().setBytes(0, new ByteArrayInputStream(new byte[8]), 1)); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testSetBytesAfterRelease8() throws IOException { - releasedBuffer().setBytes(0, new TestScatteringByteChannel(), 1); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().setBytes(0, new TestScatteringByteChannel(), 1)); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testSetZeroAfterRelease() { - releasedBuffer().setZero(0, 1); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().setZero(0, 1)); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testReadBooleanAfterRelease() { - releasedBuffer().readBoolean(); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().readBoolean()); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testReadByteAfterRelease() { - releasedBuffer().readByte(); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().readByte()); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testReadUnsignedByteAfterRelease() { - releasedBuffer().readUnsignedByte(); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().readUnsignedByte()); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testReadShortAfterRelease() { - releasedBuffer().readShort(); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().readShort()); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testReadShortLEAfterRelease() { - releasedBuffer().readShortLE(); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().readShortLE()); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testReadUnsignedShortAfterRelease() { - releasedBuffer().readUnsignedShort(); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().readUnsignedShort()); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testReadUnsignedShortLEAfterRelease() { - releasedBuffer().readUnsignedShortLE(); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().readUnsignedShortLE()); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testReadMediumAfterRelease() { - releasedBuffer().readMedium(); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().readMedium()); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testReadMediumLEAfterRelease() { - releasedBuffer().readMediumLE(); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().readMediumLE()); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testReadUnsignedMediumAfterRelease() { - releasedBuffer().readUnsignedMedium(); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().readUnsignedMedium()); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testReadUnsignedMediumLEAfterRelease() { - releasedBuffer().readUnsignedMediumLE(); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().readUnsignedMediumLE()); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testReadIntAfterRelease() { - releasedBuffer().readInt(); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().readInt()); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testReadIntLEAfterRelease() { - releasedBuffer().readIntLE(); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().readIntLE()); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testReadUnsignedIntAfterRelease() { - releasedBuffer().readUnsignedInt(); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().readUnsignedInt()); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testReadUnsignedIntLEAfterRelease() { - releasedBuffer().readUnsignedIntLE(); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().readUnsignedIntLE()); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testReadLongAfterRelease() { - releasedBuffer().readLong(); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().readLong()); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testReadLongLEAfterRelease() { - releasedBuffer().readLongLE(); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().readLongLE()); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testReadCharAfterRelease() { - releasedBuffer().readChar(); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().readChar()); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testReadFloatAfterRelease() { - releasedBuffer().readFloat(); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().readFloat()); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testReadFloatLEAfterRelease() { - releasedBuffer().readFloatLE(); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().readFloatLE()); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testReadDoubleAfterRelease() { - releasedBuffer().readDouble(); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().readDouble()); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testReadDoubleLEAfterRelease() { - releasedBuffer().readDoubleLE(); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().readDoubleLE()); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testReadBytesAfterRelease() { - releasedBuffer().readBytes(1); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().readBytes(1)); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testReadBytesAfterRelease2() { - ByteBuf buffer = buffer(8); - try { - releasedBuffer().readBytes(buffer); - } finally { - buffer.release(); - } + assertThrows(IllegalReferenceCountException.class, () -> { + ByteBuf buffer = buffer(8); + try { + releasedBuffer().readBytes(buffer); + } finally { + buffer.release(); + } + }); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testReadBytesAfterRelease3() { - ByteBuf buffer = buffer(8); - try { - releasedBuffer().readBytes(buffer); - } finally { - buffer.release(); - } + assertThrows(IllegalReferenceCountException.class, () -> { + ByteBuf buffer = buffer(8); + try { + releasedBuffer().readBytes(buffer); + } finally { + buffer.release(); + } + }); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testReadBytesAfterRelease4() { - ByteBuf buffer = buffer(8); - try { - releasedBuffer().readBytes(buffer, 0, 1); - } finally { - buffer.release(); - } + assertThrows(IllegalReferenceCountException.class, () -> { + ByteBuf buffer = buffer(8); + try { + releasedBuffer().readBytes(buffer, 0, 1); + } finally { + buffer.release(); + } + }); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testReadBytesAfterRelease5() { - releasedBuffer().readBytes(new byte[8]); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().readBytes(new byte[8])); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testReadBytesAfterRelease6() { - releasedBuffer().readBytes(new byte[8], 0, 1); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().readBytes(new byte[8], 0, 1)); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testReadBytesAfterRelease7() { - releasedBuffer().readBytes(ByteBuffer.allocate(8)); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().readBytes(ByteBuffer.allocate(8))); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testReadBytesAfterRelease8() throws IOException { - releasedBuffer().readBytes(new ByteArrayOutputStream(), 1); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().readBytes(new ByteArrayOutputStream(), 1)); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testReadBytesAfterRelease9() throws IOException { - releasedBuffer().readBytes(new ByteArrayOutputStream(), 1); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().readBytes(new ByteArrayOutputStream(), 1)); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testReadBytesAfterRelease10() throws IOException { - releasedBuffer().readBytes(new DevNullGatheringByteChannel(), 1); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().readBytes(new DevNullGatheringByteChannel(), 1)); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testWriteBooleanAfterRelease() { - releasedBuffer().writeBoolean(true); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().writeBoolean(true)); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testWriteByteAfterRelease() { - releasedBuffer().writeByte(1); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().writeByte(1)); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testWriteShortAfterRelease() { - releasedBuffer().writeShort(1); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().writeShort(1)); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testWriteShortLEAfterRelease() { - releasedBuffer().writeShortLE(1); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().writeShortLE(1)); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testWriteMediumAfterRelease() { - releasedBuffer().writeMedium(1); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().writeMedium(1)); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testWriteMediumLEAfterRelease() { - releasedBuffer().writeMediumLE(1); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().writeMediumLE(1)); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testWriteIntAfterRelease() { - releasedBuffer().writeInt(1); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().writeInt(1)); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testWriteIntLEAfterRelease() { - releasedBuffer().writeIntLE(1); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().writeIntLE(1)); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testWriteLongAfterRelease() { - releasedBuffer().writeLong(1); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().writeLong(1)); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testWriteLongLEAfterRelease() { - releasedBuffer().writeLongLE(1); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().writeLongLE(1)); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testWriteCharAfterRelease() { - releasedBuffer().writeChar(1); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().writeChar(1)); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testWriteFloatAfterRelease() { - releasedBuffer().writeFloat(1); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().writeFloat(1)); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testWriteFloatLEAfterRelease() { - releasedBuffer().writeFloatLE(1); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().writeFloatLE(1)); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testWriteDoubleAfterRelease() { - releasedBuffer().writeDouble(1); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().writeDouble(1)); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testWriteDoubleLEAfterRelease() { - releasedBuffer().writeDoubleLE(1); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().writeDoubleLE(1)); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testWriteBytesAfterRelease() { - ByteBuf buffer = buffer(8); - try { - releasedBuffer().writeBytes(buffer); - } finally { - buffer.release(); - } + assertThrows(IllegalReferenceCountException.class, () -> { + ByteBuf buffer = buffer(8); + try { + releasedBuffer().writeBytes(buffer); + } finally { + buffer.release(); + } + }); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testWriteBytesAfterRelease2() { - ByteBuf buffer = copiedBuffer(new byte[8]); - try { - releasedBuffer().writeBytes(buffer, 1); - } finally { - buffer.release(); - } + assertThrows(IllegalReferenceCountException.class, () -> { + ByteBuf buffer = copiedBuffer(new byte[8]); + try { + releasedBuffer().writeBytes(buffer, 1); + } finally { + buffer.release(); + } + }); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testWriteBytesAfterRelease3() { - ByteBuf buffer = buffer(8); - try { - releasedBuffer().writeBytes(buffer, 0, 1); - } finally { - buffer.release(); - } + assertThrows(IllegalReferenceCountException.class, () -> { + ByteBuf buffer = buffer(8); + try { + releasedBuffer().writeBytes(buffer, 0, 1); + } finally { + buffer.release(); + } + }); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testWriteBytesAfterRelease4() { - releasedBuffer().writeBytes(new byte[8]); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().writeBytes(new byte[8])); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testWriteBytesAfterRelease5() { - releasedBuffer().writeBytes(new byte[8], 0 , 1); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().writeBytes(new byte[8], 0 , 1)); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testWriteBytesAfterRelease6() { - releasedBuffer().writeBytes(ByteBuffer.allocate(8)); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().writeBytes(ByteBuffer.allocate(8))); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testWriteBytesAfterRelease7() throws IOException { - releasedBuffer().writeBytes(new ByteArrayInputStream(new byte[8]), 1); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().writeBytes(new ByteArrayInputStream(new byte[8]), 1)); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testWriteBytesAfterRelease8() throws IOException { - releasedBuffer().writeBytes(new TestScatteringByteChannel(), 1); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().writeBytes(new TestScatteringByteChannel(), 1)); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testWriteZeroAfterRelease() throws IOException { - releasedBuffer().writeZero(1); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().writeZero(1)); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testWriteUsAsciiCharSequenceAfterRelease() { - testWriteCharSequenceAfterRelease0(CharsetUtil.US_ASCII); + assertThrows(IllegalReferenceCountException.class, () -> testWriteCharSequenceAfterRelease0(CharsetUtil.US_ASCII)); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testWriteIso88591CharSequenceAfterRelease() { - testWriteCharSequenceAfterRelease0(CharsetUtil.ISO_8859_1); + assertThrows(IllegalReferenceCountException.class, () -> testWriteCharSequenceAfterRelease0(CharsetUtil.ISO_8859_1)); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testWriteUtf8CharSequenceAfterRelease() { - testWriteCharSequenceAfterRelease0(CharsetUtil.UTF_8); + assertThrows(IllegalReferenceCountException.class, () -> testWriteCharSequenceAfterRelease0(CharsetUtil.UTF_8)); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testWriteUtf16CharSequenceAfterRelease() { - testWriteCharSequenceAfterRelease0(CharsetUtil.UTF_16); + assertThrows(IllegalReferenceCountException.class, () -> testWriteCharSequenceAfterRelease0(CharsetUtil.UTF_16)); } private void testWriteCharSequenceAfterRelease0(Charset charset) { releasedBuffer().writeCharSequence("x", charset); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testForEachByteAfterRelease() { - releasedBuffer().forEachByte(new TestByteProcessor()); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().forEachByte(new TestByteProcessor())); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testForEachByteAfterRelease1() { - releasedBuffer().forEachByte(0, 1, new TestByteProcessor()); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().forEachByte(0, 1, new TestByteProcessor())); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testForEachByteDescAfterRelease() { - releasedBuffer().forEachByteDesc(new TestByteProcessor()); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().forEachByteDesc(new TestByteProcessor())); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testForEachByteDescAfterRelease1() { - releasedBuffer().forEachByteDesc(0, 1, new TestByteProcessor()); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().forEachByteDesc(0, 1, new TestByteProcessor())); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testCopyAfterRelease() { - releasedBuffer().copy(); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().copy()); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testCopyAfterRelease1() { - releasedBuffer().copy(); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().copy()); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testNioBufferAfterRelease() { - releasedBuffer().nioBuffer(); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().nioBuffer()); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testNioBufferAfterRelease1() { - releasedBuffer().nioBuffer(0, 1); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().nioBuffer(0, 1)); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testInternalNioBufferAfterRelease() { - ByteBuf releasedBuffer = releasedBuffer(); - releasedBuffer.internalNioBuffer(releasedBuffer.readerIndex(), 1); + assertThrows(IllegalReferenceCountException.class, () -> { + ByteBuf releasedBuffer = releasedBuffer(); + releasedBuffer.internalNioBuffer(releasedBuffer.readerIndex(), 1); + }); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testNioBuffersAfterRelease() { - releasedBuffer().nioBuffers(); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().nioBuffers()); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testNioBuffersAfterRelease2() { - releasedBuffer().nioBuffers(0, 1); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().nioBuffers(0, 1)); } @Test public void testArrayAfterRelease() { ByteBuf buf = releasedBuffer(); if (buf.hasArray()) { - try { - buf.array(); - fail(); - } catch (IllegalReferenceCountException e) { - // expected - } + assertThrows(IllegalReferenceCountException.class, () -> buf.array()); } } @@ -3357,23 +3324,18 @@ public abstract class AbstractByteBufTest { public void testMemoryAddressAfterRelease() { ByteBuf buf = releasedBuffer(); if (buf.hasMemoryAddress()) { - try { - buf.memoryAddress(); - fail(); - } catch (IllegalReferenceCountException e) { - // expected - } + assertThrows(IllegalReferenceCountException.class, () -> buf.memoryAddress()); } } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testSliceAfterRelease() { - releasedBuffer().slice(); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().slice()); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testSliceAfterRelease2() { - releasedBuffer().slice(0, 1); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().slice(0, 1)); } private static void assertSliceFailAfterRelease(ByteBuf... bufs) { @@ -3383,13 +3345,8 @@ public abstract class AbstractByteBufTest { } } for (ByteBuf buf : bufs) { - try { - assertEquals(0, buf.refCnt()); - buf.slice(); - fail(); - } catch (IllegalReferenceCountException ignored) { - // as expected - } + assertEquals(0, buf.refCnt()); + assertThrows(IllegalReferenceCountException.class, () -> buf.slice()); } } @@ -3431,14 +3388,14 @@ public abstract class AbstractByteBufTest { assertSliceFailAfterRelease(buf, buf2, buf3); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testRetainedSliceAfterRelease() { - releasedBuffer().retainedSlice(); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().retainedSlice()); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testRetainedSliceAfterRelease2() { - releasedBuffer().retainedSlice(0, 1); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().retainedSlice(0, 1)); } private static void assertRetainedSliceFailAfterRelease(ByteBuf... bufs) { @@ -3448,13 +3405,8 @@ public abstract class AbstractByteBufTest { } } for (ByteBuf buf : bufs) { - try { - assertEquals(0, buf.refCnt()); - buf.retainedSlice(); - fail(); - } catch (IllegalReferenceCountException ignored) { - // as expected - } + assertEquals(0, buf.refCnt()); + assertThrows(IllegalReferenceCountException.class, () -> buf.retainedSlice()); } } @@ -3496,14 +3448,14 @@ public abstract class AbstractByteBufTest { assertRetainedSliceFailAfterRelease(buf, buf2, buf3); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testDuplicateAfterRelease() { - releasedBuffer().duplicate(); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().duplicate()); } - @Test(expected = IllegalReferenceCountException.class) + @Test public void testRetainedDuplicateAfterRelease() { - releasedBuffer().retainedDuplicate(); + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().retainedDuplicate()); } private static void assertDuplicateFailAfterRelease(ByteBuf... bufs) { @@ -3513,13 +3465,8 @@ public abstract class AbstractByteBufTest { } } for (ByteBuf buf : bufs) { - try { - assertEquals(0, buf.refCnt()); - buf.duplicate(); - fail(); - } catch (IllegalReferenceCountException ignored) { - // as expected - } + assertEquals(0, buf.refCnt()); + assertThrows(IllegalReferenceCountException.class, () -> buf.duplicate()); } } @@ -3553,13 +3500,8 @@ public abstract class AbstractByteBufTest { } } for (ByteBuf buf : bufs) { - try { - assertEquals(0, buf.refCnt()); - buf.retainedDuplicate(); - fail(); - } catch (IllegalReferenceCountException ignored) { - // as expected - } + assertEquals(0, buf.refCnt()); + assertThrows(IllegalReferenceCountException.class, () -> buf.retainedDuplicate()); } } @@ -3592,14 +3534,14 @@ public abstract class AbstractByteBufTest { assertEquals(0, buf.refCnt()); } - @Test(expected = IndexOutOfBoundsException.class) + @Test public void testReadSliceOutOfBounds() { - testReadSliceOutOfBounds(false); + assertThrows(IndexOutOfBoundsException.class, () -> testReadSliceOutOfBounds(false)); } - @Test(expected = IndexOutOfBoundsException.class) + @Test public void testReadRetainedSliceOutOfBounds() { - testReadSliceOutOfBounds(true); + assertThrows(IndexOutOfBoundsException.class, () -> testReadSliceOutOfBounds(true)); } private void testReadSliceOutOfBounds(boolean retainedSlice) { @@ -3648,24 +3590,24 @@ public abstract class AbstractByteBufTest { } } - @Test(expected = IndexOutOfBoundsException.class) + @Test public void testSetUsAsciiCharSequenceNoExpand() { - testSetCharSequenceNoExpand(CharsetUtil.US_ASCII); + assertThrows(IndexOutOfBoundsException.class, () -> testSetCharSequenceNoExpand(CharsetUtil.US_ASCII)); } - @Test(expected = IndexOutOfBoundsException.class) + @Test public void testSetUtf8CharSequenceNoExpand() { - testSetCharSequenceNoExpand(CharsetUtil.UTF_8); + assertThrows(IndexOutOfBoundsException.class, () -> testSetCharSequenceNoExpand(CharsetUtil.UTF_8)); } - @Test(expected = IndexOutOfBoundsException.class) + @Test public void testSetIso88591CharSequenceNoExpand() { - testSetCharSequenceNoExpand(CharsetUtil.ISO_8859_1); + assertThrows(IndexOutOfBoundsException.class, () -> testSetCharSequenceNoExpand(CharsetUtil.ISO_8859_1)); } - @Test(expected = IndexOutOfBoundsException.class) + @Test public void testSetUtf16CharSequenceNoExpand() { - testSetCharSequenceNoExpand(CharsetUtil.UTF_16); + assertThrows(IndexOutOfBoundsException.class, () -> testSetCharSequenceNoExpand(CharsetUtil.UTF_16)); } private void testSetCharSequenceNoExpand(Charset charset) { @@ -3748,44 +3690,44 @@ public abstract class AbstractByteBufTest { buf.release(); } - @Test(expected = IndexOutOfBoundsException.class) + @Test public void testRetainedSliceIndexOutOfBounds() { - testSliceOutOfBounds(true, true, true); + assertThrows(IndexOutOfBoundsException.class, () -> testSliceOutOfBounds(true, true, true)); } - @Test(expected = IndexOutOfBoundsException.class) + @Test public void testRetainedSliceLengthOutOfBounds() { - testSliceOutOfBounds(true, true, false); + assertThrows(IndexOutOfBoundsException.class, () -> testSliceOutOfBounds(true, true, false)); } - @Test(expected = IndexOutOfBoundsException.class) + @Test public void testMixedSliceAIndexOutOfBounds() { - testSliceOutOfBounds(true, false, true); + assertThrows(IndexOutOfBoundsException.class, () -> testSliceOutOfBounds(true, false, true)); } - @Test(expected = IndexOutOfBoundsException.class) + @Test public void testMixedSliceALengthOutOfBounds() { - testSliceOutOfBounds(true, false, false); + assertThrows(IndexOutOfBoundsException.class, () -> testSliceOutOfBounds(true, false, false)); } - @Test(expected = IndexOutOfBoundsException.class) + @Test public void testMixedSliceBIndexOutOfBounds() { - testSliceOutOfBounds(false, true, true); + assertThrows(IndexOutOfBoundsException.class, () -> testSliceOutOfBounds(false, true, true)); } - @Test(expected = IndexOutOfBoundsException.class) + @Test public void testMixedSliceBLengthOutOfBounds() { - testSliceOutOfBounds(false, true, false); + assertThrows(IndexOutOfBoundsException.class, () -> testSliceOutOfBounds(false, true, false)); } - @Test(expected = IndexOutOfBoundsException.class) + @Test public void testSliceIndexOutOfBounds() { - testSliceOutOfBounds(false, false, true); + assertThrows(IndexOutOfBoundsException.class, () -> testSliceOutOfBounds(false, false, true)); } - @Test(expected = IndexOutOfBoundsException.class) + @Test public void testSliceLengthOutOfBounds() { - testSliceOutOfBounds(false, false, false); + assertThrows(IndexOutOfBoundsException.class, () -> testSliceOutOfBounds(false, false, false)); } @Test @@ -4041,14 +3983,14 @@ public abstract class AbstractByteBufTest { testDuplicateCapacityChange(true); } - @Test(expected = UnsupportedOperationException.class) + @Test public void testSliceCapacityChange() { - testSliceCapacityChange(false); + assertThrows(UnsupportedOperationException.class, () -> testSliceCapacityChange(false)); } - @Test(expected = UnsupportedOperationException.class) + @Test public void testRetainedSliceCapacityChange() { - testSliceCapacityChange(true); + assertThrows(UnsupportedOperationException.class, () -> testSliceCapacityChange(true)); } @Test @@ -4523,12 +4465,7 @@ public abstract class AbstractByteBufTest { ByteBuffer dst = direct ? ByteBuffer.allocateDirect(bytes.length) : ByteBuffer.allocate(bytes.length); ByteBuffer readOnlyDst = dst.asReadOnlyBuffer(); - try { - buffer.getBytes(0, readOnlyDst); - fail(); - } catch (ReadOnlyBufferException e) { - // expected - } + assertThrows(ReadOnlyBufferException.class, () -> buffer.getBytes(0, readOnlyDst)); assertEquals(0, readOnlyDst.position()); buffer.release(); } @@ -4674,18 +4611,20 @@ public abstract class AbstractByteBufTest { } } - @Test(expected = IndexOutOfBoundsException.class) + @Test public void testGetBytesByteBuffer() { - byte[] bytes = {'a', 'b', 'c', 'd', 'e', 'f', 'g'}; - // Ensure destination buffer is bigger then what is in the ByteBuf. - ByteBuffer nioBuffer = ByteBuffer.allocate(bytes.length + 1); - ByteBuf buffer = newBuffer(bytes.length); - try { - buffer.writeBytes(bytes); - buffer.getBytes(buffer.readerIndex(), nioBuffer); - } finally { - buffer.release(); - } + assertThrows(IndexOutOfBoundsException.class, () -> { + byte[] bytes = {'a', 'b', 'c', 'd', 'e', 'f', 'g'}; + // Ensure destination buffer is bigger then what is in the ByteBuf. + ByteBuffer nioBuffer = ByteBuffer.allocate(bytes.length + 1); + ByteBuf buffer = newBuffer(bytes.length); + try { + buffer.writeBytes(bytes); + buffer.getBytes(buffer.readerIndex(), nioBuffer); + } finally { + buffer.release(); + } + }); } private void testRefCnt0(final boolean parameter) throws Exception { @@ -4840,28 +4779,32 @@ public abstract class AbstractByteBufTest { } } - @Test(expected = IllegalArgumentException.class) + @Test public void testCapacityEnforceMaxCapacity() { - ByteBuf buffer = newBuffer(3, 13); - assertEquals(13, buffer.maxCapacity()); - assertEquals(3, buffer.capacity()); - try { - buffer.capacity(14); - } finally { - buffer.release(); - } + assertThrows(IllegalArgumentException.class, () -> { + ByteBuf buffer = newBuffer(3, 13); + assertEquals(13, buffer.maxCapacity()); + assertEquals(3, buffer.capacity()); + try { + buffer.capacity(14); + } finally { + buffer.release(); + } + }); } - @Test(expected = IllegalArgumentException.class) + @Test public void testCapacityNegative() { - ByteBuf buffer = newBuffer(3, 13); - assertEquals(13, buffer.maxCapacity()); - assertEquals(3, buffer.capacity()); - try { - buffer.capacity(-1); - } finally { - buffer.release(); - } + assertThrows(IllegalArgumentException.class, () -> { + ByteBuf buffer = newBuffer(3, 13); + assertEquals(13, buffer.maxCapacity()); + assertEquals(3, buffer.capacity()); + try { + buffer.capacity(-1); + } finally { + buffer.release(); + } + }); } @Test @@ -4892,24 +4835,26 @@ public abstract class AbstractByteBufTest { } } - @Test(expected = IndexOutOfBoundsException.class) + @Test public void testReaderIndexLargerThanWriterIndex() { - String content1 = "hello"; - String content2 = "world"; - int length = content1.length() + content2.length(); - ByteBuf buffer = newBuffer(length); - buffer.setIndex(0, 0); - buffer.writeCharSequence(content1, CharsetUtil.US_ASCII); - buffer.skipBytes(content1.length()); - buffer.writeCharSequence(content2, CharsetUtil.US_ASCII); - buffer.skipBytes(content2.length()); - assertTrue(buffer.readerIndex() <= buffer.writerIndex()); + assertThrows(IndexOutOfBoundsException.class, () -> { + String content1 = "hello"; + String content2 = "world"; + int length = content1.length() + content2.length(); + ByteBuf buffer = newBuffer(length); + buffer.setIndex(0, 0); + buffer.writeCharSequence(content1, CharsetUtil.US_ASCII); + buffer.skipBytes(content1.length()); + buffer.writeCharSequence(content2, CharsetUtil.US_ASCII); + buffer.skipBytes(content2.length()); + assertTrue(buffer.readerIndex() <= buffer.writerIndex()); - try { - buffer.readerIndex(buffer.writerIndex() + 1); - } finally { - buffer.release(); - } + try { + buffer.readerIndex(buffer.writerIndex() + 1); + } finally { + buffer.release(); + } + }); } @Test @@ -4930,10 +4875,7 @@ public abstract class AbstractByteBufTest { buffer.writerIndex(buffer.readerIndex()); buffer.writeByte(1); try { - buffer.ensureWritable(Integer.MAX_VALUE); - fail(); - } catch (IndexOutOfBoundsException e) { - // expected + assertThrows(IndexOutOfBoundsException.class, () -> buffer.ensureWritable(Integer.MAX_VALUE)); } finally { buffer.release(); } diff --git a/buffer-tests/src/test/java/io/netty/buffer/api/tests/adaptor/ByteBufAdaptorTest.java b/buffer-tests/src/test/java/io/netty/buffer/api/tests/adaptor/ByteBufAdaptorTest.java index 3cc8d9d..6b83159 100644 --- a/buffer-tests/src/test/java/io/netty/buffer/api/tests/adaptor/ByteBufAdaptorTest.java +++ b/buffer-tests/src/test/java/io/netty/buffer/api/tests/adaptor/ByteBufAdaptorTest.java @@ -19,27 +19,29 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.api.BufferAllocator; import io.netty.buffer.api.MemoryManagers; import io.netty.buffer.api.adaptor.ByteBufAllocatorAdaptor; -import org.junit.AfterClass; -import org.junit.Ignore; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.Disabled; import java.util.Optional; -import static org.junit.Assume.assumeTrue; +import static org.junit.jupiter.api.Assumptions.assumeTrue; public abstract class ByteBufAdaptorTest extends AbstractByteBufTest { static ByteBufAllocatorAdaptor alloc; static void setUpAllocator(String name) { Optional managers = MemoryManagers.lookupImplementation(name); - assumeTrue(managers.isPresent()); + assumeTrue(managers.isPresent(), () -> "Memory implementation '" + name + "' not found."); BufferAllocator onheap = MemoryManagers.using(managers.get(), BufferAllocator::pooledHeap); BufferAllocator offheap = MemoryManagers.using(managers.get(), BufferAllocator::pooledHeap); alloc = new ByteBufAllocatorAdaptor(onheap, offheap); } - @AfterClass + @AfterAll public static void tearDownAllocator() throws Exception { - alloc.close(); + if (alloc != null) { + alloc.close(); + } } @Override @@ -47,50 +49,50 @@ public abstract class ByteBufAdaptorTest extends AbstractByteBufTest { return alloc.buffer(capacity, capacity); } - @Ignore("This test codifies that asking to reading 0 bytes from an empty but unclosed stream should return -1, " + + @Disabled("This test codifies that asking to reading 0 bytes from an empty but unclosed stream should return -1, " + "which is just weird.") @Override public void testStreamTransfer1() throws Exception { } - @Ignore("Relies on capacity and max capacity being separate things.") + @Disabled("Relies on capacity and max capacity being separate things.") @Override public void testCapacityIncrease() { } - @Ignore("Decreasing capacity not supported in new API.") + @Disabled("Decreasing capacity not supported in new API.") @Override public void testCapacityDecrease() { } - @Ignore("Decreasing capacity not supported in new API.") + @Disabled("Decreasing capacity not supported in new API.") @Override public void testCapacityNegative() { throw new IllegalArgumentException(); // Can't ignore tests annotated with throws expectation? } - @Ignore("Decreasing capacity not supported in new API.") + @Disabled("Decreasing capacity not supported in new API.") @Override public void testCapacityEnforceMaxCapacity() { throw new IllegalArgumentException(); // Can't ignore tests annotated with throws expectation? } - @Ignore("Decreasing capacity not supported in new API.") + @Disabled("Decreasing capacity not supported in new API.") @Override public void testMaxFastWritableBytes() { } - @Ignore("Impossible to expose entire memory as a ByteBuffer using new API.") + @Disabled("Impossible to expose entire memory as a ByteBuffer using new API.") @Override public void testNioBufferExposeOnlyRegion() { } - @Ignore("Impossible to expose entire memory as a ByteBuffer using new API.") + @Disabled("Impossible to expose entire memory as a ByteBuffer using new API.") @Override public void testToByteBuffer2() { } - @Ignore("No longer allowed to allocate 0 sized buffers, except for composite buffers with no components.") + @Disabled("No longer allowed to allocate 0 sized buffers, except for composite buffers with no components.") @Override public void testLittleEndianWithExpand() { } diff --git a/buffer-tests/src/test/java/io/netty/buffer/api/tests/adaptor/MemSegByteBufAdaptorTest.java b/buffer-tests/src/test/java/io/netty/buffer/api/tests/adaptor/MemSegByteBufAdaptorTest.java index ebd34d7..78468d1 100644 --- a/buffer-tests/src/test/java/io/netty/buffer/api/tests/adaptor/MemSegByteBufAdaptorTest.java +++ b/buffer-tests/src/test/java/io/netty/buffer/api/tests/adaptor/MemSegByteBufAdaptorTest.java @@ -15,10 +15,10 @@ */ package io.netty.buffer.api.tests.adaptor; -import org.junit.BeforeClass; +import org.junit.jupiter.api.BeforeAll; public class MemSegByteBufAdaptorTest extends ByteBufAdaptorTest { - @BeforeClass + @BeforeAll public static void setUpAllocator() { setUpAllocator("MemorySegment"); } diff --git a/buffer-tests/src/test/java/io/netty/buffer/api/tests/adaptor/NioByteBufAdaptorTest.java b/buffer-tests/src/test/java/io/netty/buffer/api/tests/adaptor/NioByteBufAdaptorTest.java index 34d5637..de0f4e1 100644 --- a/buffer-tests/src/test/java/io/netty/buffer/api/tests/adaptor/NioByteBufAdaptorTest.java +++ b/buffer-tests/src/test/java/io/netty/buffer/api/tests/adaptor/NioByteBufAdaptorTest.java @@ -15,10 +15,10 @@ */ package io.netty.buffer.api.tests.adaptor; -import org.junit.BeforeClass; +import org.junit.jupiter.api.BeforeAll; public class NioByteBufAdaptorTest extends ByteBufAdaptorTest { - @BeforeClass + @BeforeAll public static void setUpAllocator() { setUpAllocator("ByteBuffer"); } diff --git a/buffer-tests/src/test/java/io/netty/buffer/api/tests/adaptor/UnsafeByteBufAdaptorTest.java b/buffer-tests/src/test/java/io/netty/buffer/api/tests/adaptor/UnsafeByteBufAdaptorTest.java index f7535c3..ae56013 100644 --- a/buffer-tests/src/test/java/io/netty/buffer/api/tests/adaptor/UnsafeByteBufAdaptorTest.java +++ b/buffer-tests/src/test/java/io/netty/buffer/api/tests/adaptor/UnsafeByteBufAdaptorTest.java @@ -15,10 +15,10 @@ */ package io.netty.buffer.api.tests.adaptor; -import org.junit.BeforeClass; +import org.junit.jupiter.api.BeforeAll; public class UnsafeByteBufAdaptorTest extends ByteBufAdaptorTest { - @BeforeClass + @BeforeAll public static void setUpAllocator() { setUpAllocator("Unsafe"); } From 53a8d71c64990c6a34295c0697c156579deee50d Mon Sep 17 00:00:00 2001 From: Chris Vest Date: Fri, 28 May 2021 16:23:35 +0200 Subject: [PATCH 4/6] Fix numerous review comments - Mostly javadocs have been fixed or added. - A couple of small code changes in ByteBufAdaptor to better cope with unlikely exceptions. --- .../main/java/io/netty/buffer/api/Buffer.java | 10 ++--- .../io/netty/buffer/api/BufferHolder.java | 6 ++- .../io/netty/buffer/api/MemoryManagers.java | 5 +++ .../java/io/netty/buffer/api/Resource.java | 15 ++++++++ .../buffer/api/adaptor/ByteBufAdaptor.java | 9 ++++- .../buffer/api/internal/ResourceSupport.java | 38 +++++++++++++++++++ .../io/netty/buffer/api/internal/Statics.java | 3 +- .../tests/adaptor/AbstractByteBufTest.java | 5 +++ 8 files changed, 81 insertions(+), 10 deletions(-) diff --git a/buffer-api/src/main/java/io/netty/buffer/api/Buffer.java b/buffer-api/src/main/java/io/netty/buffer/api/Buffer.java index 63985c7..88cba0b 100644 --- a/buffer-api/src/main/java/io/netty/buffer/api/Buffer.java +++ b/buffer-api/src/main/java/io/netty/buffer/api/Buffer.java @@ -76,7 +76,7 @@ import java.nio.ByteOrder; * *

Splitting buffers

* - * The {@link #split()} method break a buffer into two. + * The {@link #split()} method breaks a buffer into two. * The two buffers will share the underlying memory, but their regions will not overlap, ensuring that the memory is * safely shared between the two. *

@@ -86,7 +86,7 @@ import java.nio.ByteOrder; * further processing, as split buffer regions, once their data has been received in its entirety. * * If you instead wish to temporarily share a region of a buffer, you will have to pass offset and length along with the - * buffer, or you will have to make a copy of the region in a new buffer. + * buffer, or you will have to make a copy of the region. * *

Buffers as constants

* @@ -377,7 +377,7 @@ public interface Buffer extends Resource, BufferAccessors { * {@code false}. * * @param size The requested number of bytes of space that should be available for writing. - * @throws IllegalStateException if this buffer is not in a bad state, or is {@linkplain #readOnly() read-only}. + * @throws IllegalStateException if this buffer is in a bad state, or is {@linkplain #readOnly() read-only}. */ default void ensureWritable(int size) { ensureWritable(size, 1, true); @@ -418,7 +418,7 @@ public interface Buffer extends Resource, BufferAccessors { * @param allowCompaction {@code true} if the method is allowed to modify the * {@linkplain #readerOffset() reader offset} and * {@linkplain #writerOffset() writer offset}, otherwise {@code false}. - * @throws IllegalStateException if this buffer is not in a bad state, or is {@linkplain #readOnly() read-only}. + * @throws IllegalStateException if this buffer is in a bad state, or is {@linkplain #readOnly() read-only}. */ void ensureWritable(int size, int minimumGrowth, boolean allowCompaction); @@ -553,7 +553,7 @@ public interface Buffer extends Resource, BufferAccessors { /** * Discards the read bytes, and moves the buffer contents to the beginning of the buffer. * - * @throws IllegalStateException if this buffer is not in a bad state, or is {@linkplain #readOnly() read-only}. + * @throws IllegalStateException if this buffer is in a bad state, or is {@linkplain #readOnly() read-only}. */ void compact(); diff --git a/buffer-api/src/main/java/io/netty/buffer/api/BufferHolder.java b/buffer-api/src/main/java/io/netty/buffer/api/BufferHolder.java index eadd4da..751f43a 100644 --- a/buffer-api/src/main/java/io/netty/buffer/api/BufferHolder.java +++ b/buffer-api/src/main/java/io/netty/buffer/api/BufferHolder.java @@ -97,8 +97,9 @@ public abstract class BufferHolder> implements Resourc * @param send The new {@link Buffer} instance that is replacing the currently held buffer. */ protected final void replaceBuffer(Send send) { + Buffer received = send.receive(); buf.close(); - buf = send.receive(); + buf = received; } /** @@ -114,7 +115,8 @@ public abstract class BufferHolder> implements Resourc * @param send The {@link Send} with the new {@link Buffer} instance that is replacing the currently held buffer. */ protected final void replaceBufferVolatile(Send send) { - var prev = (Buffer) BUF.getAndSet(this, send.receive()); + Buffer received = send.receive(); + var prev = (Buffer) BUF.getAndSet(this, received); prev.close(); } diff --git a/buffer-api/src/main/java/io/netty/buffer/api/MemoryManagers.java b/buffer-api/src/main/java/io/netty/buffer/api/MemoryManagers.java index 262af5b..92322bf 100644 --- a/buffer-api/src/main/java/io/netty/buffer/api/MemoryManagers.java +++ b/buffer-api/src/main/java/io/netty/buffer/api/MemoryManagers.java @@ -54,6 +54,8 @@ public interface MemoryManagers { /** * Get a lazy-loading stream of all available memory managers. + *

+ * Note: All available {@link MemoryManagers} instances are service loaded and instantiated on every call. * * @return A stream of providers of memory managers instances. */ @@ -64,6 +66,9 @@ public interface MemoryManagers { /** * Find a {@link MemoryManagers} implementation by its {@linkplain #implementationName() implementation name}. + *

+ * Note: All available {@link MemoryManagers} instances are service loaded and instantiated every time this + * method is called. * * @param implementationName The named implementation to look for. * @return A {@link MemoryManagers} implementation, if any was found. diff --git a/buffer-api/src/main/java/io/netty/buffer/api/Resource.java b/buffer-api/src/main/java/io/netty/buffer/api/Resource.java index 8fa18a9..73604ec 100644 --- a/buffer-api/src/main/java/io/netty/buffer/api/Resource.java +++ b/buffer-api/src/main/java/io/netty/buffer/api/Resource.java @@ -1,3 +1,18 @@ +/* + * Copyright 2021 The Netty Project + * + * The Netty Project licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ package io.netty.buffer.api; /** diff --git a/buffer-api/src/main/java/io/netty/buffer/api/adaptor/ByteBufAdaptor.java b/buffer-api/src/main/java/io/netty/buffer/api/adaptor/ByteBufAdaptor.java index fcb545b..5b65400 100644 --- a/buffer-api/src/main/java/io/netty/buffer/api/adaptor/ByteBufAdaptor.java +++ b/buffer-api/src/main/java/io/netty/buffer/api/adaptor/ByteBufAdaptor.java @@ -1419,8 +1419,9 @@ public final class ByteBufAdaptor extends ByteBuf { @Override public ByteBuf retainedSlice(int index, int length) { checkAccess(); + Slice slice = new Slice(this, index, length); retain(); - return new Slice(this, index, length); + return slice; } private static final class Slice extends SlicedByteBuf { @@ -1678,7 +1679,11 @@ public final class ByteBufAdaptor extends ByteBuf { @Override public boolean release(int decrement) { for (int i = 0; i < decrement; i++) { - buffer.close(); + try { + buffer.close(); + } catch (IllegalStateException e) { + throw new IllegalReferenceCountException(e); + } } return !buffer.isAccessible(); } diff --git a/buffer-api/src/main/java/io/netty/buffer/api/internal/ResourceSupport.java b/buffer-api/src/main/java/io/netty/buffer/api/internal/ResourceSupport.java index 1d8dbc9..1af1bc4 100644 --- a/buffer-api/src/main/java/io/netty/buffer/api/internal/ResourceSupport.java +++ b/buffer-api/src/main/java/io/netty/buffer/api/internal/ResourceSupport.java @@ -38,6 +38,17 @@ public abstract class ResourceSupport, T extends ResourceS tracer = LifecycleTracer.get(); } + /** + * Encapsulation bypass for calling {@link #acquire()} on the given object. + *

+ * Note: this {@code acquire} method does not check the type of the return value from acquire at compile time. + * The type is instead checked at runtime, and will cause a {@link ClassCastException} to be thrown if done + * incorrectly. + * + * @param obj The object we wish to acquire (increment reference count) on. + * @param The type of the acquired object, given by target-typing. + * @return The acquired object. + */ @SuppressWarnings("unchecked") static T acquire(ResourceSupport obj) { return (T) obj.acquire(); @@ -103,6 +114,13 @@ public abstract class ResourceSupport, T extends ResourceS return new TransferSend(owned, drop, getClass()); } + /** + * Attach a trace of the life-cycle of this object as suppressed exceptions to the given throwable. + * + * @param throwable The throwable to attach a life-cycle trace to. + * @param The concrete exception type. + * @return The given exception, which can then be thrown. + */ protected E attachTrace(E throwable) { return tracer.attachTrace(throwable); } @@ -117,14 +135,34 @@ public abstract class ResourceSupport, T extends ResourceS "Cannot send() a reference counted object with " + countBorrows() + " borrows: " + this + '.'); } + /** + * Encapsulation bypass to call {@link #isOwned()} on the given object. + * + * @param obj The object to query the ownership state on. + * @return {@code true} if the given object is owned, otherwise {@code false}. + */ static boolean isOwned(ResourceSupport obj) { return obj.isOwned(); } + /** + * Query if this object is in an "owned" state, which means no other references have been + * {@linkplain #acquire() acquired} to it. + * + * This would usually be the case, since there are no public methods for acquiring references to these objects. + * + * @return {@code true} if this object is in an owned state, otherwise {@code false}. + */ protected boolean isOwned() { return acquires == 0; } + /** + * Encapsulation bypass to call {@link #countBorrows()} on the given object. + * + * @param obj The object to count borrows on. + * @return The number of borrows, or outstanding {@linkplain #acquire() acquires}, if any, of the given object. + */ static int countBorrows(ResourceSupport obj) { return obj.countBorrows(); } diff --git a/buffer-api/src/main/java/io/netty/buffer/api/internal/Statics.java b/buffer-api/src/main/java/io/netty/buffer/api/internal/Statics.java index de58053..f9e9a11 100644 --- a/buffer-api/src/main/java/io/netty/buffer/api/internal/Statics.java +++ b/buffer-api/src/main/java/io/netty/buffer/api/internal/Statics.java @@ -54,6 +54,7 @@ public interface Statics { } } + @SuppressWarnings("JavaLangInvokeHandleSignature") static MethodHandle getByteBufferPutOffsetsMethodHandle() { try { Lookup lookup = MethodHandles.lookup(); @@ -64,7 +65,7 @@ public interface Statics { } } - @SuppressWarnings("unchecked") + @SuppressWarnings({"unchecked", "unused"}) static Drop noOpDrop() { return (Drop) NO_OP_DROP; } diff --git a/buffer-tests/src/test/java/io/netty/buffer/api/tests/adaptor/AbstractByteBufTest.java b/buffer-tests/src/test/java/io/netty/buffer/api/tests/adaptor/AbstractByteBufTest.java index fe3bab3..8f27894 100644 --- a/buffer-tests/src/test/java/io/netty/buffer/api/tests/adaptor/AbstractByteBufTest.java +++ b/buffer-tests/src/test/java/io/netty/buffer/api/tests/adaptor/AbstractByteBufTest.java @@ -3458,6 +3458,11 @@ public abstract class AbstractByteBufTest { assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().retainedDuplicate()); } + @Test + public void testReleaseAfterRelease() { + assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().release()); + } + private static void assertDuplicateFailAfterRelease(ByteBuf... bufs) { for (ByteBuf buf : bufs) { if (buf.refCnt() > 0) { From db7ac9969924a91986a85ac6f4d7a8b48ab5a14f Mon Sep 17 00:00:00 2001 From: Chris Vest Date: Fri, 28 May 2021 17:10:46 +0200 Subject: [PATCH 5/6] Fix more review comments --- .../main/java/io/netty/buffer/api/MemoryManagers.java | 6 +++--- .../io/netty/buffer/api/adaptor/ByteBufAdaptor.java | 3 +++ .../api/bytebuffer/ByteBufferMemoryManagers.java | 2 +- .../java/io/netty/buffer/api/bytebuffer/NioBuffer.java | 4 ++++ .../java/io/netty/buffer/api/unsafe/UnsafeBuffer.java | 4 ++++ .../netty/buffer/api/unsafe/UnsafeMemoryManagers.java | 2 +- .../java/io/netty/buffer/api/memseg/MemSegBuffer.java | 4 ++++ .../netty/buffer/api/memseg/SegmentMemoryManagers.java | 2 +- .../buffer/api/tests/adaptor/AbstractByteBufTest.java | 10 ++++++++++ 9 files changed, 31 insertions(+), 6 deletions(-) diff --git a/buffer-api/src/main/java/io/netty/buffer/api/MemoryManagers.java b/buffer-api/src/main/java/io/netty/buffer/api/MemoryManagers.java index 92322bf..c9a4af4 100644 --- a/buffer-api/src/main/java/io/netty/buffer/api/MemoryManagers.java +++ b/buffer-api/src/main/java/io/netty/buffer/api/MemoryManagers.java @@ -65,7 +65,7 @@ public interface MemoryManagers { } /** - * Find a {@link MemoryManagers} implementation by its {@linkplain #implementationName() implementation name}. + * Find a {@link MemoryManagers} implementation by its {@linkplain #getImplementationName() implementation name}. *

* Note: All available {@link MemoryManagers} instances are service loaded and instantiated every time this * method is called. @@ -82,7 +82,7 @@ public interface MemoryManagers { return Stream.empty(); } }) - .filter(impl -> implementationName.equals(impl.implementationName())) + .filter(impl -> implementationName.equals(impl.getImplementationName())) .findFirst(); } @@ -106,5 +106,5 @@ public interface MemoryManagers { * * @return The name of this memory managers implementation. */ - String implementationName(); + String getImplementationName(); } diff --git a/buffer-api/src/main/java/io/netty/buffer/api/adaptor/ByteBufAdaptor.java b/buffer-api/src/main/java/io/netty/buffer/api/adaptor/ByteBufAdaptor.java index 5b65400..0d95e23 100644 --- a/buffer-api/src/main/java/io/netty/buffer/api/adaptor/ByteBufAdaptor.java +++ b/buffer-api/src/main/java/io/netty/buffer/api/adaptor/ByteBufAdaptor.java @@ -1678,6 +1678,9 @@ public final class ByteBufAdaptor extends ByteBuf { @Override public boolean release(int decrement) { + if (!buffer.isAccessible() || decrement > 1 + Statics.countBorrows((ResourceSupport) buffer)) { + throw new IllegalReferenceCountException(); + } for (int i = 0; i < decrement; i++) { try { buffer.close(); diff --git a/buffer-api/src/main/java/io/netty/buffer/api/bytebuffer/ByteBufferMemoryManagers.java b/buffer-api/src/main/java/io/netty/buffer/api/bytebuffer/ByteBufferMemoryManagers.java index cb33511..56e731f 100644 --- a/buffer-api/src/main/java/io/netty/buffer/api/bytebuffer/ByteBufferMemoryManagers.java +++ b/buffer-api/src/main/java/io/netty/buffer/api/bytebuffer/ByteBufferMemoryManagers.java @@ -30,7 +30,7 @@ public class ByteBufferMemoryManagers implements MemoryManagers { } @Override - public String implementationName() { + public String getImplementationName() { return "ByteBuffer"; } diff --git a/buffer-api/src/main/java/io/netty/buffer/api/bytebuffer/NioBuffer.java b/buffer-api/src/main/java/io/netty/buffer/api/bytebuffer/NioBuffer.java index 329b347..7bbdda2 100644 --- a/buffer-api/src/main/java/io/netty/buffer/api/bytebuffer/NioBuffer.java +++ b/buffer-api/src/main/java/io/netty/buffer/api/bytebuffer/NioBuffer.java @@ -32,6 +32,7 @@ import io.netty.buffer.api.WritableComponent; import io.netty.buffer.api.WritableComponentProcessor; import io.netty.buffer.api.internal.ArcDrop; import io.netty.buffer.api.internal.Statics; +import io.netty.util.IllegalReferenceCountException; import io.netty.util.ReferenceCounted; import io.netty.util.internal.PlatformDependent; @@ -1245,6 +1246,9 @@ class NioBuffer extends ResourceSupport implements Buffer, Re @Override public boolean release(int decrement) { + if (!isAccessible() || decrement > 1 + countBorrows()) { + throw new IllegalReferenceCountException(); + } for (int i = 0; i < decrement; i++) { close(); } diff --git a/buffer-api/src/main/java/io/netty/buffer/api/unsafe/UnsafeBuffer.java b/buffer-api/src/main/java/io/netty/buffer/api/unsafe/UnsafeBuffer.java index 793688b..8490a4f 100644 --- a/buffer-api/src/main/java/io/netty/buffer/api/unsafe/UnsafeBuffer.java +++ b/buffer-api/src/main/java/io/netty/buffer/api/unsafe/UnsafeBuffer.java @@ -32,6 +32,7 @@ import io.netty.buffer.api.WritableComponent; import io.netty.buffer.api.WritableComponentProcessor; import io.netty.buffer.api.internal.ArcDrop; import io.netty.buffer.api.internal.Statics; +import io.netty.util.IllegalReferenceCountException; import io.netty.util.ReferenceCounted; import io.netty.util.internal.PlatformDependent; @@ -1660,6 +1661,9 @@ class UnsafeBuffer extends ResourceSupport implements Buff @Override public boolean release(int decrement) { + if (!isAccessible() || decrement > 1 + countBorrows()) { + throw new IllegalReferenceCountException(); + } for (int i = 0; i < decrement; i++) { close(); } diff --git a/buffer-api/src/main/java/io/netty/buffer/api/unsafe/UnsafeMemoryManagers.java b/buffer-api/src/main/java/io/netty/buffer/api/unsafe/UnsafeMemoryManagers.java index 0c4ef5c..41a11ae 100644 --- a/buffer-api/src/main/java/io/netty/buffer/api/unsafe/UnsafeMemoryManagers.java +++ b/buffer-api/src/main/java/io/netty/buffer/api/unsafe/UnsafeMemoryManagers.java @@ -40,7 +40,7 @@ public class UnsafeMemoryManagers implements MemoryManagers { } @Override - public String implementationName() { + public String getImplementationName() { return "Unsafe"; } diff --git a/buffer-memseg/src/main/java/io/netty/buffer/api/memseg/MemSegBuffer.java b/buffer-memseg/src/main/java/io/netty/buffer/api/memseg/MemSegBuffer.java index 07b6b2f..b63e526 100644 --- a/buffer-memseg/src/main/java/io/netty/buffer/api/memseg/MemSegBuffer.java +++ b/buffer-memseg/src/main/java/io/netty/buffer/api/memseg/MemSegBuffer.java @@ -32,6 +32,7 @@ import io.netty.buffer.api.WritableComponentProcessor; import io.netty.buffer.api.Drop; import io.netty.buffer.api.Owned; import io.netty.buffer.api.internal.ResourceSupport; +import io.netty.util.IllegalReferenceCountException; import jdk.incubator.foreign.MemorySegment; import jdk.incubator.foreign.ResourceScope; @@ -1266,6 +1267,9 @@ class MemSegBuffer extends ResourceSupport implements Buff @Override public boolean release(int decrement) { + if (!isAccessible() || decrement > 1 + countBorrows()) { + throw new IllegalReferenceCountException(); + } for (int i = 0; i < decrement; i++) { close(); } diff --git a/buffer-memseg/src/main/java/io/netty/buffer/api/memseg/SegmentMemoryManagers.java b/buffer-memseg/src/main/java/io/netty/buffer/api/memseg/SegmentMemoryManagers.java index e28561f..9d1d6dc 100644 --- a/buffer-memseg/src/main/java/io/netty/buffer/api/memseg/SegmentMemoryManagers.java +++ b/buffer-memseg/src/main/java/io/netty/buffer/api/memseg/SegmentMemoryManagers.java @@ -30,7 +30,7 @@ public class SegmentMemoryManagers implements MemoryManagers { } @Override - public String implementationName() { + public String getImplementationName() { return "MemorySegment"; } diff --git a/buffer-tests/src/test/java/io/netty/buffer/api/tests/adaptor/AbstractByteBufTest.java b/buffer-tests/src/test/java/io/netty/buffer/api/tests/adaptor/AbstractByteBufTest.java index 8f27894..b445cb2 100644 --- a/buffer-tests/src/test/java/io/netty/buffer/api/tests/adaptor/AbstractByteBufTest.java +++ b/buffer-tests/src/test/java/io/netty/buffer/api/tests/adaptor/AbstractByteBufTest.java @@ -61,6 +61,7 @@ import static io.netty.buffer.Unpooled.directBuffer; import static io.netty.buffer.Unpooled.unreleasableBuffer; import static io.netty.buffer.Unpooled.wrappedBuffer; import static io.netty.util.internal.EmptyArrays.EMPTY_BYTES; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; @@ -3463,6 +3464,15 @@ public abstract class AbstractByteBufTest { assertThrows(IllegalReferenceCountException.class, () -> releasedBuffer().release()); } + @Test + public void overReleasingMustNotCloseBuffer() { + ByteBuf buf = newBuffer(1); + assertThrows(IllegalReferenceCountException.class, () -> buf.release(10)); + assertThrows(IllegalReferenceCountException.class, () -> buf.release(2)); + assertThat(buf.refCnt()).isNotZero(); + assertTrue(buf.release()); + } + private static void assertDuplicateFailAfterRelease(ByteBuf... bufs) { for (ByteBuf buf : bufs) { if (buf.refCnt() > 0) { From a48a12794d60ce71894e3d03cf2aff9f5db60d0c Mon Sep 17 00:00:00 2001 From: Chris Vest Date: Mon, 31 May 2021 15:06:48 +0200 Subject: [PATCH 6/6] Make `release(int)` methods handle errors better Exception types and error messages are now unified and more descriptive. --- .../io/netty/buffer/api/adaptor/ByteBufAdaptor.java | 7 ++++--- .../io/netty/buffer/api/bytebuffer/NioBuffer.java | 11 ++++++++--- .../java/io/netty/buffer/api/unsafe/UnsafeBuffer.java | 11 ++++++++--- .../java/io/netty/buffer/api/memseg/MemSegBuffer.java | 11 ++++++++--- 4 files changed, 28 insertions(+), 12 deletions(-) diff --git a/buffer-api/src/main/java/io/netty/buffer/api/adaptor/ByteBufAdaptor.java b/buffer-api/src/main/java/io/netty/buffer/api/adaptor/ByteBufAdaptor.java index 0d95e23..b9ceb21 100644 --- a/buffer-api/src/main/java/io/netty/buffer/api/adaptor/ByteBufAdaptor.java +++ b/buffer-api/src/main/java/io/netty/buffer/api/adaptor/ByteBufAdaptor.java @@ -1678,13 +1678,14 @@ public final class ByteBufAdaptor extends ByteBuf { @Override public boolean release(int decrement) { - if (!buffer.isAccessible() || decrement > 1 + Statics.countBorrows((ResourceSupport) buffer)) { - throw new IllegalReferenceCountException(); + int refCount = 1 + Statics.countBorrows((ResourceSupport) buffer); + if (!buffer.isAccessible() || decrement > refCount) { + throw new IllegalReferenceCountException(refCount, -decrement); } for (int i = 0; i < decrement; i++) { try { buffer.close(); - } catch (IllegalStateException e) { + } catch (RuntimeException e) { throw new IllegalReferenceCountException(e); } } diff --git a/buffer-api/src/main/java/io/netty/buffer/api/bytebuffer/NioBuffer.java b/buffer-api/src/main/java/io/netty/buffer/api/bytebuffer/NioBuffer.java index 7bbdda2..acaf4a1 100644 --- a/buffer-api/src/main/java/io/netty/buffer/api/bytebuffer/NioBuffer.java +++ b/buffer-api/src/main/java/io/netty/buffer/api/bytebuffer/NioBuffer.java @@ -1246,11 +1246,16 @@ class NioBuffer extends ResourceSupport implements Buffer, Re @Override public boolean release(int decrement) { - if (!isAccessible() || decrement > 1 + countBorrows()) { - throw new IllegalReferenceCountException(); + int refCount = 1 + countBorrows(); + if (!isAccessible() || decrement > refCount) { + throw new IllegalReferenceCountException(refCount, -decrement); } for (int i = 0; i < decrement; i++) { - close(); + try { + close(); + } catch (RuntimeException e) { + throw new IllegalReferenceCountException(e); + } } return !isAccessible(); } diff --git a/buffer-api/src/main/java/io/netty/buffer/api/unsafe/UnsafeBuffer.java b/buffer-api/src/main/java/io/netty/buffer/api/unsafe/UnsafeBuffer.java index 8490a4f..32ed0d4 100644 --- a/buffer-api/src/main/java/io/netty/buffer/api/unsafe/UnsafeBuffer.java +++ b/buffer-api/src/main/java/io/netty/buffer/api/unsafe/UnsafeBuffer.java @@ -1661,11 +1661,16 @@ class UnsafeBuffer extends ResourceSupport implements Buff @Override public boolean release(int decrement) { - if (!isAccessible() || decrement > 1 + countBorrows()) { - throw new IllegalReferenceCountException(); + int refCount = 1 + countBorrows(); + if (!isAccessible() || decrement > refCount) { + throw new IllegalReferenceCountException(refCount, -decrement); } for (int i = 0; i < decrement; i++) { - close(); + try { + close(); + } catch (RuntimeException e) { + throw new IllegalReferenceCountException(e); + } } return !isAccessible(); } diff --git a/buffer-memseg/src/main/java/io/netty/buffer/api/memseg/MemSegBuffer.java b/buffer-memseg/src/main/java/io/netty/buffer/api/memseg/MemSegBuffer.java index b63e526..234fe26 100644 --- a/buffer-memseg/src/main/java/io/netty/buffer/api/memseg/MemSegBuffer.java +++ b/buffer-memseg/src/main/java/io/netty/buffer/api/memseg/MemSegBuffer.java @@ -1267,11 +1267,16 @@ class MemSegBuffer extends ResourceSupport implements Buff @Override public boolean release(int decrement) { - if (!isAccessible() || decrement > 1 + countBorrows()) { - throw new IllegalReferenceCountException(); + int refCount = 1 + countBorrows(); + if (!isAccessible() || decrement > refCount) { + throw new IllegalReferenceCountException(refCount, -decrement); } for (int i = 0; i < decrement; i++) { - close(); + try { + close(); + } catch (RuntimeException e) { + throw new IllegalReferenceCountException(e); + } } return !isAccessible(); }