You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flink.apache.org by sr...@apache.org on 2018/01/18 14:25:56 UTC
[5/9] flink git commit: [FLINK-7520][network] let our Buffer class
extend from netty's buffer class
http://git-wip-us.apache.org/repos/asf/flink/blob/85bea23a/flink-runtime/src/test/java/org/apache/flink/runtime/io/network/buffer/AbstractByteBufTest.java
----------------------------------------------------------------------
diff --git a/flink-runtime/src/test/java/org/apache/flink/runtime/io/network/buffer/AbstractByteBufTest.java b/flink-runtime/src/test/java/org/apache/flink/runtime/io/network/buffer/AbstractByteBufTest.java
new file mode 100644
index 0000000..8f19552
--- /dev/null
+++ b/flink-runtime/src/test/java/org/apache/flink/runtime/io/network/buffer/AbstractByteBufTest.java
@@ -0,0 +1,3077 @@
+/*
+ * Copyright 2012 The Netty Project
+ * Copy from netty 4.0.50.Final, changed to fit our use of netty 4.0.27.
+ *
+ * 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:
+ *
+ * http://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 org.apache.flink.runtime.io.network.buffer;
+
+import org.apache.flink.shaded.netty4.io.netty.buffer.ByteBuf;
+import org.apache.flink.shaded.netty4.io.netty.buffer.ByteBufProcessor;
+import org.apache.flink.shaded.netty4.io.netty.buffer.ByteBufUtil;
+import org.apache.flink.shaded.netty4.io.netty.util.CharsetUtil;
+import org.apache.flink.shaded.netty4.io.netty.util.IllegalReferenceCountException;
+import org.apache.flink.shaded.netty4.io.netty.util.internal.ThreadLocalRandom;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.ReadOnlyBufferException;
+import java.nio.channels.Channels;
+import java.nio.channels.GatheringByteChannel;
+import java.nio.channels.ScatteringByteChannel;
+import java.nio.channels.WritableByteChannel;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Random;
+import java.util.Set;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.CyclicBarrier;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicReference;
+
+import static org.apache.flink.shaded.netty4.io.netty.buffer.Unpooled.LITTLE_ENDIAN;
+import static org.apache.flink.shaded.netty4.io.netty.buffer.Unpooled.buffer;
+import static org.apache.flink.shaded.netty4.io.netty.buffer.Unpooled.copiedBuffer;
+import static org.apache.flink.shaded.netty4.io.netty.buffer.Unpooled.directBuffer;
+import static org.apache.flink.shaded.netty4.io.netty.buffer.Unpooled.wrappedBuffer;
+import static org.apache.flink.shaded.netty4.io.netty.util.internal.EmptyArrays.EMPTY_BYTES;
+import static org.hamcrest.CoreMatchers.is;
+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.assertThat;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeTrue;
+
+/**
+ * An abstract test class for channel buffers.
+ *
+ * Copied from netty 4.0.50 with some changes to fit our netty version 4.0.27.
+ */
+public abstract class AbstractByteBufTest {
+
+ private static final int CAPACITY = 4096; // Must be even
+ private static final int BLOCK_SIZE = 128;
+ private static final int JAVA_BYTEBUFFER_CONSISTENCY_ITERATIONS = 100;
+
+ private long seed;
+ private Random random;
+ private ByteBuf buffer;
+
+ protected final ByteBuf newBuffer(int capacity) {
+ return newBuffer(capacity, Integer.MAX_VALUE);
+ }
+
+ protected abstract ByteBuf newBuffer(int capacity, int maxCapacity);
+
+ protected boolean discardReadBytesDoesNotMoveWritableBytes() {
+ return true;
+ }
+
+ @Before
+ public void init() {
+ buffer = newBuffer(CAPACITY);
+ seed = System.currentTimeMillis();
+ random = new Random(seed);
+ }
+
+ @After
+ public void dispose() {
+ if (buffer != null) {
+ assertThat(buffer.release(), is(true));
+ assertThat(buffer.refCnt(), is(0));
+
+ try {
+ buffer.release();
+ } catch (Exception e) {
+ // Ignore.
+ }
+ buffer = null;
+ }
+ }
+
+ @Test
+ public void comparableInterfaceNotViolated() {
+ buffer.writerIndex(buffer.readerIndex());
+ assumeTrue(buffer.writableBytes() >= 4);
+
+ buffer.writeLong(0);
+ ByteBuf buffer2 = newBuffer(CAPACITY);
+ buffer2.writerIndex(buffer2.readerIndex());
+ // Write an unsigned integer that will cause buffer.getUnsignedInt() - buffer2.getUnsignedInt() to underflow the
+ // int type and wrap around on the negative side.
+ buffer2.writeLong(0xF0000000L);
+ assertTrue(buffer.compareTo(buffer2) < 0);
+ assertTrue(buffer2.compareTo(buffer) > 0);
+ buffer2.release();
+ }
+
+ @Test
+ public void initialState() {
+ assertEquals(CAPACITY, buffer.capacity());
+ assertEquals(0, buffer.readerIndex());
+ }
+
+ @Test(expected = IndexOutOfBoundsException.class)
+ public void readerIndexBoundaryCheck1() {
+ try {
+ buffer.writerIndex(0);
+ } catch (IndexOutOfBoundsException e) {
+ fail();
+ }
+ buffer.readerIndex(-1);
+ }
+
+ @Test(expected = IndexOutOfBoundsException.class)
+ public void readerIndexBoundaryCheck2() {
+ try {
+ buffer.writerIndex(buffer.capacity());
+ } catch (IndexOutOfBoundsException e) {
+ fail();
+ }
+ buffer.readerIndex(buffer.capacity() + 1);
+ }
+
+ @Test(expected = IndexOutOfBoundsException.class)
+ public void readerIndexBoundaryCheck3() {
+ try {
+ buffer.writerIndex(CAPACITY / 2);
+ } catch (IndexOutOfBoundsException e) {
+ fail();
+ }
+ buffer.readerIndex(CAPACITY * 3 / 2);
+ }
+
+ @Test
+ public void readerIndexBoundaryCheck4() {
+ buffer.writerIndex(0);
+ buffer.readerIndex(0);
+ buffer.writerIndex(buffer.capacity());
+ buffer.readerIndex(buffer.capacity());
+ }
+
+ @Test(expected = IndexOutOfBoundsException.class)
+ public void writerIndexBoundaryCheck1() {
+ buffer.writerIndex(-1);
+ }
+
+ @Test(expected = IndexOutOfBoundsException.class)
+ public void writerIndexBoundaryCheck2() {
+ try {
+ buffer.writerIndex(CAPACITY);
+ buffer.readerIndex(CAPACITY);
+ } catch (IndexOutOfBoundsException e) {
+ fail();
+ }
+ buffer.writerIndex(buffer.capacity() + 1);
+ }
+
+ @Test(expected = IndexOutOfBoundsException.class)
+ public void writerIndexBoundaryCheck3() {
+ try {
+ buffer.writerIndex(CAPACITY);
+ buffer.readerIndex(CAPACITY / 2);
+ } catch (IndexOutOfBoundsException e) {
+ fail();
+ }
+ buffer.writerIndex(CAPACITY / 4);
+ }
+
+ @Test
+ public void writerIndexBoundaryCheck4() {
+ buffer.writerIndex(0);
+ buffer.readerIndex(0);
+ buffer.writerIndex(CAPACITY);
+
+ buffer.writeBytes(ByteBuffer.wrap(EMPTY_BYTES));
+ }
+
+ @Test(expected = IndexOutOfBoundsException.class)
+ public void getBooleanBoundaryCheck1() {
+ buffer.getBoolean(-1);
+ }
+
+ @Test(expected = IndexOutOfBoundsException.class)
+ public void getBooleanBoundaryCheck2() {
+ buffer.getBoolean(buffer.capacity());
+ }
+
+ @Test(expected = IndexOutOfBoundsException.class)
+ public void getByteBoundaryCheck1() {
+ buffer.getByte(-1);
+ }
+
+ @Test(expected = IndexOutOfBoundsException.class)
+ public void getByteBoundaryCheck2() {
+ buffer.getByte(buffer.capacity());
+ }
+
+ @Test(expected = IndexOutOfBoundsException.class)
+ public void getShortBoundaryCheck1() {
+ buffer.getShort(-1);
+ }
+
+ @Test(expected = IndexOutOfBoundsException.class)
+ public void getShortBoundaryCheck2() {
+ buffer.getShort(buffer.capacity() - 1);
+ }
+
+ @Test(expected = IndexOutOfBoundsException.class)
+ public void getMediumBoundaryCheck1() {
+ buffer.getMedium(-1);
+ }
+
+ @Test(expected = IndexOutOfBoundsException.class)
+ public void getMediumBoundaryCheck2() {
+ buffer.getMedium(buffer.capacity() - 2);
+ }
+
+ @Test(expected = IndexOutOfBoundsException.class)
+ public void getIntBoundaryCheck1() {
+ buffer.getInt(-1);
+ }
+
+ @Test(expected = IndexOutOfBoundsException.class)
+ public void getIntBoundaryCheck2() {
+ buffer.getInt(buffer.capacity() - 3);
+ }
+
+ @Test(expected = IndexOutOfBoundsException.class)
+ public void getLongBoundaryCheck1() {
+ buffer.getLong(-1);
+ }
+
+ @Test(expected = IndexOutOfBoundsException.class)
+ public void getLongBoundaryCheck2() {
+ buffer.getLong(buffer.capacity() - 7);
+ }
+
+ @Test(expected = IndexOutOfBoundsException.class)
+ public void getByteArrayBoundaryCheck1() {
+ buffer.getBytes(-1, EMPTY_BYTES);
+ }
+
+ @Test(expected = IndexOutOfBoundsException.class)
+ public void getByteArrayBoundaryCheck2() {
+ 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
+ }
+
+ // No partial copy is expected.
+ assertEquals(0, dst[0]);
+ assertEquals(0, dst[1]);
+ assertEquals(0, dst[2]);
+ assertEquals(0, dst[3]);
+ }
+
+ @Test
+ public void getByteArrayBoundaryCheck4() {
+ byte[] dst = new byte[4];
+ buffer.setInt(0, 0x01020304);
+ try {
+ buffer.getBytes(0, dst, 1, 4);
+ fail();
+ } catch (IndexOutOfBoundsException e) {
+ // Success
+ }
+
+ // No partial copy is expected.
+ assertEquals(0, dst[0]);
+ assertEquals(0, dst[1]);
+ assertEquals(0, dst[2]);
+ assertEquals(0, dst[3]);
+ }
+
+ @Test(expected = IndexOutOfBoundsException.class)
+ public void getByteBufferBoundaryCheck() {
+ buffer.getBytes(-1, ByteBuffer.allocate(0));
+ }
+
+ @Test(expected = IndexOutOfBoundsException.class)
+ public void copyBoundaryCheck1() {
+ buffer.copy(-1, 0);
+ }
+
+ @Test(expected = IndexOutOfBoundsException.class)
+ public void copyBoundaryCheck2() {
+ buffer.copy(0, buffer.capacity() + 1);
+ }
+
+ @Test(expected = IndexOutOfBoundsException.class)
+ public void copyBoundaryCheck3() {
+ buffer.copy(buffer.capacity() + 1, 0);
+ }
+
+ @Test(expected = IndexOutOfBoundsException.class)
+ public void copyBoundaryCheck4() {
+ buffer.copy(buffer.capacity(), 1);
+ }
+
+ @Test(expected = IndexOutOfBoundsException.class)
+ public void setIndexBoundaryCheck1() {
+ buffer.setIndex(-1, CAPACITY);
+ }
+
+ @Test(expected = IndexOutOfBoundsException.class)
+ public void setIndexBoundaryCheck2() {
+ buffer.setIndex(CAPACITY / 2, CAPACITY / 4);
+ }
+
+ @Test(expected = IndexOutOfBoundsException.class)
+ public void setIndexBoundaryCheck3() {
+ buffer.setIndex(0, CAPACITY + 1);
+ }
+
+ @Test
+ public void getByteBufferState() {
+ ByteBuffer dst = ByteBuffer.allocate(4);
+ dst.position(1);
+ dst.limit(3);
+
+ buffer.setByte(0, (byte) 1);
+ buffer.setByte(1, (byte) 2);
+ buffer.setByte(2, (byte) 3);
+ buffer.setByte(3, (byte) 4);
+ buffer.getBytes(1, dst);
+
+ assertEquals(3, dst.position());
+ assertEquals(3, dst.limit());
+
+ dst.clear();
+ assertEquals(0, dst.get(0));
+ assertEquals(2, dst.get(1));
+ assertEquals(3, dst.get(2));
+ assertEquals(0, dst.get(3));
+ }
+
+ @Test(expected = IndexOutOfBoundsException.class)
+ public void getDirectByteBufferBoundaryCheck() {
+ buffer.getBytes(-1, ByteBuffer.allocateDirect(0));
+ }
+
+ @Test
+ public void getDirectByteBufferState() {
+ ByteBuffer dst = ByteBuffer.allocateDirect(4);
+ dst.position(1);
+ dst.limit(3);
+
+ buffer.setByte(0, (byte) 1);
+ buffer.setByte(1, (byte) 2);
+ buffer.setByte(2, (byte) 3);
+ buffer.setByte(3, (byte) 4);
+ buffer.getBytes(1, dst);
+
+ assertEquals(3, dst.position());
+ assertEquals(3, dst.limit());
+
+ dst.clear();
+ assertEquals(0, dst.get(0));
+ assertEquals(2, dst.get(1));
+ assertEquals(3, dst.get(2));
+ assertEquals(0, dst.get(3));
+ }
+
+ @Test
+ public void testRandomByteAccess() {
+ for (int i = 0; i < buffer.capacity(); i ++) {
+ byte value = (byte) random.nextInt();
+ buffer.setByte(i, value);
+ }
+
+ random.setSeed(seed);
+ for (int i = 0; i < buffer.capacity(); i ++) {
+ byte value = (byte) random.nextInt();
+ assertEquals(value, buffer.getByte(i));
+ }
+ }
+
+ @Test
+ public void testRandomUnsignedByteAccess() {
+ for (int i = 0; i < buffer.capacity(); i ++) {
+ byte value = (byte) random.nextInt();
+ buffer.setByte(i, value);
+ }
+
+ random.setSeed(seed);
+ for (int i = 0; i < buffer.capacity(); i ++) {
+ int value = random.nextInt() & 0xFF;
+ assertEquals(value, buffer.getUnsignedByte(i));
+ }
+ }
+
+ @Test
+ public void testRandomShortAccess() {
+ for (int i = 0; i < buffer.capacity() - 1; i += 2) {
+ short value = (short) random.nextInt();
+ buffer.setShort(i, value);
+ }
+
+ random.setSeed(seed);
+ for (int i = 0; i < buffer.capacity() - 1; i += 2) {
+ short value = (short) random.nextInt();
+ assertEquals(value, buffer.getShort(i));
+ }
+ }
+
+ @Test
+ public void testShortConsistentWithByteBuffer() {
+ testShortConsistentWithByteBuffer(true, true);
+ testShortConsistentWithByteBuffer(true, false);
+ testShortConsistentWithByteBuffer(false, true);
+ testShortConsistentWithByteBuffer(false, false);
+ }
+
+ private void testShortConsistentWithByteBuffer(boolean direct, boolean testBigEndian) {
+ for (int i = 0; i < JAVA_BYTEBUFFER_CONSISTENCY_ITERATIONS; ++i) {
+ ByteBuffer javaBuffer = direct ? ByteBuffer.allocateDirect(buffer.capacity())
+ : ByteBuffer.allocate(buffer.capacity());
+ if (!testBigEndian) {
+ javaBuffer = javaBuffer.order(ByteOrder.LITTLE_ENDIAN);
+ }
+
+ short expected = (short) (random.nextInt() & 0xFFFF);
+ javaBuffer.putShort(expected);
+
+ final int bufferIndex = buffer.capacity() - 2;
+ if (!testBigEndian) {
+ buffer = buffer.order(ByteOrder.LITTLE_ENDIAN);
+ }
+ buffer.setShort(bufferIndex, expected);
+ javaBuffer.flip();
+
+ short javaActual = javaBuffer.getShort();
+ assertEquals(expected, javaActual);
+ assertEquals(javaActual, buffer.getShort(bufferIndex));
+ }
+ }
+
+ @Test
+ public void testRandomUnsignedShortAccess() {
+ for (int i = 0; i < buffer.capacity() - 1; i += 2) {
+ short value = (short) random.nextInt();
+ buffer.setShort(i, value);
+ }
+
+ random.setSeed(seed);
+ for (int i = 0; i < buffer.capacity() - 1; i += 2) {
+ int value = random.nextInt() & 0xFFFF;
+ assertEquals(value, buffer.getUnsignedShort(i));
+ }
+ }
+
+ @Test
+ public void testRandomMediumAccess() {
+ for (int i = 0; i < buffer.capacity() - 2; i += 3) {
+ int value = random.nextInt();
+ buffer.setMedium(i, value);
+ }
+
+ random.setSeed(seed);
+ for (int i = 0; i < buffer.capacity() - 2; i += 3) {
+ int value = random.nextInt() << 8 >> 8;
+ assertEquals(value, buffer.getMedium(i));
+ }
+ }
+
+ @Test
+ public void testRandomUnsignedMediumAccess() {
+ for (int i = 0; i < buffer.capacity() - 2; i += 3) {
+ int value = random.nextInt();
+ buffer.setMedium(i, value);
+ }
+
+ random.setSeed(seed);
+ for (int i = 0; i < buffer.capacity() - 2; i += 3) {
+ int value = random.nextInt() & 0x00FFFFFF;
+ assertEquals(value, buffer.getUnsignedMedium(i));
+ }
+ }
+
+ @Test
+ public void testMediumConsistentWithByteBuffer() {
+ testMediumConsistentWithByteBuffer(true, true);
+ testMediumConsistentWithByteBuffer(true, false);
+ testMediumConsistentWithByteBuffer(false, true);
+ testMediumConsistentWithByteBuffer(false, false);
+ }
+
+ private void testMediumConsistentWithByteBuffer(boolean direct, boolean testBigEndian) {
+ for (int i = 0; i < JAVA_BYTEBUFFER_CONSISTENCY_ITERATIONS; ++i) {
+ ByteBuffer javaBuffer = direct ? ByteBuffer.allocateDirect(buffer.capacity())
+ : ByteBuffer.allocate(buffer.capacity());
+ if (!testBigEndian) {
+ javaBuffer = javaBuffer.order(ByteOrder.LITTLE_ENDIAN);
+ }
+
+ int expected = random.nextInt() & 0x00FFFFFF;
+ javaBuffer.putInt(expected);
+
+ final int bufferIndex = buffer.capacity() - 3;
+ if (testBigEndian) {
+ buffer = buffer.order(ByteOrder.LITTLE_ENDIAN);
+ }
+ buffer.setMedium(bufferIndex, expected);
+ javaBuffer.flip();
+
+ int javaActual = javaBuffer.getInt();
+ assertEquals(expected, javaActual);
+ assertEquals(javaActual, buffer.getUnsignedMedium(bufferIndex));
+ }
+ }
+
+ @Test
+ public void testRandomIntAccess() {
+ for (int i = 0; i < buffer.capacity() - 3; i += 4) {
+ int value = random.nextInt();
+ buffer.setInt(i, value);
+ }
+
+ random.setSeed(seed);
+ for (int i = 0; i < buffer.capacity() - 3; i += 4) {
+ int value = random.nextInt();
+ assertEquals(value, buffer.getInt(i));
+ }
+ }
+
+ @Test
+ public void testIntConsistentWithByteBuffer() {
+ testIntConsistentWithByteBuffer(true, true);
+ testIntConsistentWithByteBuffer(true, false);
+ testIntConsistentWithByteBuffer(false, true);
+ testIntConsistentWithByteBuffer(false, false);
+ }
+
+ private void testIntConsistentWithByteBuffer(boolean direct, boolean testBigEndian) {
+ for (int i = 0; i < JAVA_BYTEBUFFER_CONSISTENCY_ITERATIONS; ++i) {
+ ByteBuffer javaBuffer = direct ? ByteBuffer.allocateDirect(buffer.capacity())
+ : ByteBuffer.allocate(buffer.capacity());
+ if (!testBigEndian) {
+ javaBuffer = javaBuffer.order(ByteOrder.LITTLE_ENDIAN);
+ }
+
+ int expected = random.nextInt();
+ javaBuffer.putInt(expected);
+
+ final int bufferIndex = buffer.capacity() - 4;
+ if (testBigEndian) {
+ buffer = buffer.order(ByteOrder.LITTLE_ENDIAN);
+ }
+ buffer.setInt(bufferIndex, expected);
+ javaBuffer.flip();
+
+ int javaActual = javaBuffer.getInt();
+ assertEquals(expected, javaActual);
+ assertEquals(javaActual, buffer.getInt(bufferIndex));
+ }
+ }
+
+ @Test
+ public void testRandomUnsignedIntAccess() {
+ for (int i = 0; i < buffer.capacity() - 3; i += 4) {
+ int value = random.nextInt();
+ buffer.setInt(i, value);
+ }
+
+ random.setSeed(seed);
+ for (int i = 0; i < buffer.capacity() - 3; i += 4) {
+ long value = random.nextInt() & 0xFFFFFFFFL;
+ assertEquals(value, buffer.getUnsignedInt(i));
+ }
+ }
+
+ @Test
+ public void testRandomLongAccess() {
+ for (int i = 0; i < buffer.capacity() - 7; i += 8) {
+ long value = random.nextLong();
+ buffer.setLong(i, value);
+ }
+
+ random.setSeed(seed);
+ for (int i = 0; i < buffer.capacity() - 7; i += 8) {
+ long value = random.nextLong();
+ assertEquals(value, buffer.getLong(i));
+ }
+ }
+
+ @Test
+ public void testSetZero() {
+ buffer.clear();
+ while (buffer.isWritable()) {
+ buffer.writeByte((byte) 0xFF);
+ }
+
+ for (int i = 0; i < buffer.capacity();) {
+ int length = Math.min(buffer.capacity() - i, random.nextInt(32));
+ buffer.setZero(i, length);
+ i += length;
+ }
+
+ for (int i = 0; i < buffer.capacity(); i ++) {
+ assertEquals(0, buffer.getByte(i));
+ }
+ }
+
+ @Test
+ public void testSequentialByteAccess() {
+ buffer.writerIndex(0);
+ for (int i = 0; i < buffer.capacity(); i ++) {
+ byte value = (byte) random.nextInt();
+ assertEquals(i, buffer.writerIndex());
+ assertTrue(buffer.isWritable());
+ buffer.writeByte(value);
+ }
+
+ assertEquals(0, buffer.readerIndex());
+ assertEquals(buffer.capacity(), buffer.writerIndex());
+ assertFalse(buffer.isWritable());
+
+ random.setSeed(seed);
+ for (int i = 0; i < buffer.capacity(); i ++) {
+ byte value = (byte) random.nextInt();
+ assertEquals(i, buffer.readerIndex());
+ assertTrue(buffer.isReadable());
+ assertEquals(value, buffer.readByte());
+ }
+
+ assertEquals(buffer.capacity(), buffer.readerIndex());
+ assertEquals(buffer.capacity(), buffer.writerIndex());
+ assertFalse(buffer.isReadable());
+ assertFalse(buffer.isWritable());
+ }
+
+ @Test
+ public void testSequentialUnsignedByteAccess() {
+ buffer.writerIndex(0);
+ for (int i = 0; i < buffer.capacity(); i ++) {
+ byte value = (byte) random.nextInt();
+ assertEquals(i, buffer.writerIndex());
+ assertTrue(buffer.isWritable());
+ buffer.writeByte(value);
+ }
+
+ assertEquals(0, buffer.readerIndex());
+ assertEquals(buffer.capacity(), buffer.writerIndex());
+ assertFalse(buffer.isWritable());
+
+ random.setSeed(seed);
+ for (int i = 0; i < buffer.capacity(); i ++) {
+ int value = random.nextInt() & 0xFF;
+ assertEquals(i, buffer.readerIndex());
+ assertTrue(buffer.isReadable());
+ assertEquals(value, buffer.readUnsignedByte());
+ }
+
+ assertEquals(buffer.capacity(), buffer.readerIndex());
+ assertEquals(buffer.capacity(), buffer.writerIndex());
+ assertFalse(buffer.isReadable());
+ assertFalse(buffer.isWritable());
+ }
+
+ @Test
+ public void testSequentialShortAccess() {
+ buffer.writerIndex(0);
+ for (int i = 0; i < buffer.capacity(); i += 2) {
+ short value = (short) random.nextInt();
+ assertEquals(i, buffer.writerIndex());
+ assertTrue(buffer.isWritable());
+ buffer.writeShort(value);
+ }
+
+ assertEquals(0, buffer.readerIndex());
+ assertEquals(buffer.capacity(), buffer.writerIndex());
+ assertFalse(buffer.isWritable());
+
+ random.setSeed(seed);
+ for (int i = 0; i < buffer.capacity(); i += 2) {
+ short value = (short) random.nextInt();
+ assertEquals(i, buffer.readerIndex());
+ assertTrue(buffer.isReadable());
+ assertEquals(value, buffer.readShort());
+ }
+
+ assertEquals(buffer.capacity(), buffer.readerIndex());
+ assertEquals(buffer.capacity(), buffer.writerIndex());
+ assertFalse(buffer.isReadable());
+ assertFalse(buffer.isWritable());
+ }
+
+ @Test
+ public void testSequentialUnsignedShortAccess() {
+ buffer.writerIndex(0);
+ for (int i = 0; i < buffer.capacity(); i += 2) {
+ short value = (short) random.nextInt();
+ assertEquals(i, buffer.writerIndex());
+ assertTrue(buffer.isWritable());
+ buffer.writeShort(value);
+ }
+
+ assertEquals(0, buffer.readerIndex());
+ assertEquals(buffer.capacity(), buffer.writerIndex());
+ assertFalse(buffer.isWritable());
+
+ random.setSeed(seed);
+ for (int i = 0; i < buffer.capacity(); i += 2) {
+ int value = random.nextInt() & 0xFFFF;
+ assertEquals(i, buffer.readerIndex());
+ assertTrue(buffer.isReadable());
+ assertEquals(value, buffer.readUnsignedShort());
+ }
+
+ assertEquals(buffer.capacity(), buffer.readerIndex());
+ assertEquals(buffer.capacity(), buffer.writerIndex());
+ assertFalse(buffer.isReadable());
+ assertFalse(buffer.isWritable());
+ }
+
+ @Test
+ public void testSequentialMediumAccess() {
+ buffer.writerIndex(0);
+ for (int i = 0; i < buffer.capacity() / 3 * 3; i += 3) {
+ int value = random.nextInt();
+ assertEquals(i, buffer.writerIndex());
+ assertTrue(buffer.isWritable());
+ buffer.writeMedium(value);
+ }
+
+ assertEquals(0, buffer.readerIndex());
+ assertEquals(buffer.capacity() / 3 * 3, buffer.writerIndex());
+ assertEquals(buffer.capacity() % 3, buffer.writableBytes());
+
+ random.setSeed(seed);
+ for (int i = 0; i < buffer.capacity() / 3 * 3; i += 3) {
+ int value = random.nextInt() << 8 >> 8;
+ assertEquals(i, buffer.readerIndex());
+ assertTrue(buffer.isReadable());
+ assertEquals(value, buffer.readMedium());
+ }
+
+ assertEquals(buffer.capacity() / 3 * 3, buffer.readerIndex());
+ assertEquals(buffer.capacity() / 3 * 3, buffer.writerIndex());
+ assertEquals(0, buffer.readableBytes());
+ assertEquals(buffer.capacity() % 3, buffer.writableBytes());
+ }
+
+ @Test
+ public void testSequentialUnsignedMediumAccess() {
+ buffer.writerIndex(0);
+ for (int i = 0; i < buffer.capacity() / 3 * 3; i += 3) {
+ int value = random.nextInt() & 0x00FFFFFF;
+ assertEquals(i, buffer.writerIndex());
+ assertTrue(buffer.isWritable());
+ buffer.writeMedium(value);
+ }
+
+ assertEquals(0, buffer.readerIndex());
+ assertEquals(buffer.capacity() / 3 * 3, buffer.writerIndex());
+ assertEquals(buffer.capacity() % 3, buffer.writableBytes());
+
+ random.setSeed(seed);
+ for (int i = 0; i < buffer.capacity() / 3 * 3; i += 3) {
+ int value = random.nextInt() & 0x00FFFFFF;
+ assertEquals(i, buffer.readerIndex());
+ assertTrue(buffer.isReadable());
+ assertEquals(value, buffer.readUnsignedMedium());
+ }
+
+ assertEquals(buffer.capacity() / 3 * 3, buffer.readerIndex());
+ assertEquals(buffer.capacity() / 3 * 3, buffer.writerIndex());
+ assertEquals(0, buffer.readableBytes());
+ assertEquals(buffer.capacity() % 3, buffer.writableBytes());
+ }
+
+ @Test
+ public void testSequentialIntAccess() {
+ buffer.writerIndex(0);
+ for (int i = 0; i < buffer.capacity(); i += 4) {
+ int value = random.nextInt();
+ assertEquals(i, buffer.writerIndex());
+ assertTrue(buffer.isWritable());
+ buffer.writeInt(value);
+ }
+
+ assertEquals(0, buffer.readerIndex());
+ assertEquals(buffer.capacity(), buffer.writerIndex());
+ assertFalse(buffer.isWritable());
+
+ random.setSeed(seed);
+ for (int i = 0; i < buffer.capacity(); i += 4) {
+ int value = random.nextInt();
+ assertEquals(i, buffer.readerIndex());
+ assertTrue(buffer.isReadable());
+ assertEquals(value, buffer.readInt());
+ }
+
+ assertEquals(buffer.capacity(), buffer.readerIndex());
+ assertEquals(buffer.capacity(), buffer.writerIndex());
+ assertFalse(buffer.isReadable());
+ assertFalse(buffer.isWritable());
+ }
+
+ @Test
+ public void testSequentialUnsignedIntAccess() {
+ buffer.writerIndex(0);
+ for (int i = 0; i < buffer.capacity(); i += 4) {
+ int value = random.nextInt();
+ assertEquals(i, buffer.writerIndex());
+ assertTrue(buffer.isWritable());
+ buffer.writeInt(value);
+ }
+
+ assertEquals(0, buffer.readerIndex());
+ assertEquals(buffer.capacity(), buffer.writerIndex());
+ assertFalse(buffer.isWritable());
+
+ random.setSeed(seed);
+ for (int i = 0; i < buffer.capacity(); i += 4) {
+ long value = random.nextInt() & 0xFFFFFFFFL;
+ assertEquals(i, buffer.readerIndex());
+ assertTrue(buffer.isReadable());
+ assertEquals(value, buffer.readUnsignedInt());
+ }
+
+ assertEquals(buffer.capacity(), buffer.readerIndex());
+ assertEquals(buffer.capacity(), buffer.writerIndex());
+ assertFalse(buffer.isReadable());
+ assertFalse(buffer.isWritable());
+ }
+
+ @Test
+ public void testSequentialLongAccess() {
+ buffer.writerIndex(0);
+ for (int i = 0; i < buffer.capacity(); i += 8) {
+ long value = random.nextLong();
+ assertEquals(i, buffer.writerIndex());
+ assertTrue(buffer.isWritable());
+ buffer.writeLong(value);
+ }
+
+ assertEquals(0, buffer.readerIndex());
+ assertEquals(buffer.capacity(), buffer.writerIndex());
+ assertFalse(buffer.isWritable());
+
+ random.setSeed(seed);
+ for (int i = 0; i < buffer.capacity(); i += 8) {
+ long value = random.nextLong();
+ assertEquals(i, buffer.readerIndex());
+ assertTrue(buffer.isReadable());
+ assertEquals(value, buffer.readLong());
+ }
+
+ assertEquals(buffer.capacity(), buffer.readerIndex());
+ assertEquals(buffer.capacity(), buffer.writerIndex());
+ assertFalse(buffer.isReadable());
+ assertFalse(buffer.isWritable());
+ }
+
+ @Test
+ public void testByteArrayTransfer() {
+ byte[] value = new byte[BLOCK_SIZE * 2];
+ for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) {
+ random.nextBytes(value);
+ buffer.setBytes(i, value, random.nextInt(BLOCK_SIZE), BLOCK_SIZE);
+ }
+
+ random.setSeed(seed);
+ byte[] expectedValue = new byte[BLOCK_SIZE * 2];
+ for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) {
+ random.nextBytes(expectedValue);
+ int valueOffset = random.nextInt(BLOCK_SIZE);
+ buffer.getBytes(i, value, valueOffset, BLOCK_SIZE);
+ for (int j = valueOffset; j < valueOffset + BLOCK_SIZE; j ++) {
+ assertEquals(expectedValue[j], value[j]);
+ }
+ }
+ }
+
+ @Test
+ public void testRandomByteArrayTransfer1() {
+ byte[] value = new byte[BLOCK_SIZE];
+ for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) {
+ random.nextBytes(value);
+ buffer.setBytes(i, value);
+ }
+
+ random.setSeed(seed);
+ byte[] expectedValueContent = new byte[BLOCK_SIZE];
+ ByteBuf expectedValue = wrappedBuffer(expectedValueContent);
+ for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) {
+ random.nextBytes(expectedValueContent);
+ buffer.getBytes(i, value);
+ for (int j = 0; j < BLOCK_SIZE; j ++) {
+ assertEquals(expectedValue.getByte(j), value[j]);
+ }
+ }
+ }
+
+ @Test
+ public void testRandomByteArrayTransfer2() {
+ byte[] value = new byte[BLOCK_SIZE * 2];
+ for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) {
+ random.nextBytes(value);
+ buffer.setBytes(i, value, random.nextInt(BLOCK_SIZE), BLOCK_SIZE);
+ }
+
+ random.setSeed(seed);
+ byte[] expectedValueContent = new byte[BLOCK_SIZE * 2];
+ ByteBuf expectedValue = wrappedBuffer(expectedValueContent);
+ for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) {
+ random.nextBytes(expectedValueContent);
+ int valueOffset = random.nextInt(BLOCK_SIZE);
+ buffer.getBytes(i, value, valueOffset, BLOCK_SIZE);
+ for (int j = valueOffset; j < valueOffset + BLOCK_SIZE; j ++) {
+ assertEquals(expectedValue.getByte(j), value[j]);
+ }
+ }
+ }
+
+ @Test
+ public void testRandomHeapBufferTransfer1() {
+ byte[] valueContent = new byte[BLOCK_SIZE];
+ ByteBuf value = wrappedBuffer(valueContent);
+ for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) {
+ random.nextBytes(valueContent);
+ value.setIndex(0, BLOCK_SIZE);
+ buffer.setBytes(i, value);
+ assertEquals(BLOCK_SIZE, value.readerIndex());
+ assertEquals(BLOCK_SIZE, value.writerIndex());
+ }
+
+ random.setSeed(seed);
+ byte[] expectedValueContent = new byte[BLOCK_SIZE];
+ ByteBuf expectedValue = wrappedBuffer(expectedValueContent);
+ for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) {
+ random.nextBytes(expectedValueContent);
+ value.clear();
+ buffer.getBytes(i, value);
+ assertEquals(0, value.readerIndex());
+ assertEquals(BLOCK_SIZE, value.writerIndex());
+ for (int j = 0; j < BLOCK_SIZE; j ++) {
+ assertEquals(expectedValue.getByte(j), value.getByte(j));
+ }
+ }
+ }
+
+ @Test
+ public void testRandomHeapBufferTransfer2() {
+ byte[] valueContent = new byte[BLOCK_SIZE * 2];
+ ByteBuf value = wrappedBuffer(valueContent);
+ for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) {
+ random.nextBytes(valueContent);
+ buffer.setBytes(i, value, random.nextInt(BLOCK_SIZE), BLOCK_SIZE);
+ }
+
+ random.setSeed(seed);
+ byte[] expectedValueContent = new byte[BLOCK_SIZE * 2];
+ ByteBuf expectedValue = wrappedBuffer(expectedValueContent);
+ for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) {
+ random.nextBytes(expectedValueContent);
+ int valueOffset = random.nextInt(BLOCK_SIZE);
+ buffer.getBytes(i, value, valueOffset, BLOCK_SIZE);
+ for (int j = valueOffset; j < valueOffset + BLOCK_SIZE; j ++) {
+ assertEquals(expectedValue.getByte(j), value.getByte(j));
+ }
+ }
+ }
+
+ @Test
+ public void testRandomDirectBufferTransfer() {
+ byte[] tmp = new byte[BLOCK_SIZE * 2];
+ ByteBuf value = directBuffer(BLOCK_SIZE * 2);
+ for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) {
+ random.nextBytes(tmp);
+ value.setBytes(0, tmp, 0, value.capacity());
+ buffer.setBytes(i, value, random.nextInt(BLOCK_SIZE), BLOCK_SIZE);
+ }
+
+ random.setSeed(seed);
+ ByteBuf expectedValue = directBuffer(BLOCK_SIZE * 2);
+ for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) {
+ random.nextBytes(tmp);
+ expectedValue.setBytes(0, tmp, 0, expectedValue.capacity());
+ int valueOffset = random.nextInt(BLOCK_SIZE);
+ buffer.getBytes(i, value, valueOffset, BLOCK_SIZE);
+ for (int j = valueOffset; j < valueOffset + BLOCK_SIZE; j ++) {
+ assertEquals(expectedValue.getByte(j), value.getByte(j));
+ }
+ }
+ value.release();
+ expectedValue.release();
+ }
+
+ @Test
+ public void testRandomByteBufferTransfer() {
+ ByteBuffer value = ByteBuffer.allocate(BLOCK_SIZE * 2);
+ for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) {
+ random.nextBytes(value.array());
+ value.clear().position(random.nextInt(BLOCK_SIZE));
+ value.limit(value.position() + BLOCK_SIZE);
+ buffer.setBytes(i, value);
+ }
+
+ random.setSeed(seed);
+ ByteBuffer expectedValue = ByteBuffer.allocate(BLOCK_SIZE * 2);
+ for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) {
+ random.nextBytes(expectedValue.array());
+ int valueOffset = random.nextInt(BLOCK_SIZE);
+ value.clear().position(valueOffset).limit(valueOffset + BLOCK_SIZE);
+ buffer.getBytes(i, value);
+ assertEquals(valueOffset + BLOCK_SIZE, value.position());
+ for (int j = valueOffset; j < valueOffset + BLOCK_SIZE; j ++) {
+ assertEquals(expectedValue.get(j), value.get(j));
+ }
+ }
+ }
+
+ @Test
+ public void testSequentialByteArrayTransfer1() {
+ byte[] value = new byte[BLOCK_SIZE];
+ buffer.writerIndex(0);
+ for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) {
+ random.nextBytes(value);
+ assertEquals(0, buffer.readerIndex());
+ assertEquals(i, buffer.writerIndex());
+ buffer.writeBytes(value);
+ }
+
+ random.setSeed(seed);
+ byte[] expectedValue = new byte[BLOCK_SIZE];
+ for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) {
+ random.nextBytes(expectedValue);
+ assertEquals(i, buffer.readerIndex());
+ assertEquals(CAPACITY, buffer.writerIndex());
+ buffer.readBytes(value);
+ for (int j = 0; j < BLOCK_SIZE; j ++) {
+ assertEquals(expectedValue[j], value[j]);
+ }
+ }
+ }
+
+ @Test
+ public void testSequentialByteArrayTransfer2() {
+ byte[] value = new byte[BLOCK_SIZE * 2];
+ buffer.writerIndex(0);
+ for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) {
+ random.nextBytes(value);
+ assertEquals(0, buffer.readerIndex());
+ assertEquals(i, buffer.writerIndex());
+ int readerIndex = random.nextInt(BLOCK_SIZE);
+ buffer.writeBytes(value, readerIndex, BLOCK_SIZE);
+ }
+
+ random.setSeed(seed);
+ byte[] expectedValue = new byte[BLOCK_SIZE * 2];
+ for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) {
+ random.nextBytes(expectedValue);
+ int valueOffset = random.nextInt(BLOCK_SIZE);
+ assertEquals(i, buffer.readerIndex());
+ assertEquals(CAPACITY, buffer.writerIndex());
+ buffer.readBytes(value, valueOffset, BLOCK_SIZE);
+ for (int j = valueOffset; j < valueOffset + BLOCK_SIZE; j ++) {
+ assertEquals(expectedValue[j], value[j]);
+ }
+ }
+ }
+
+ @Test
+ public void testSequentialHeapBufferTransfer1() {
+ byte[] valueContent = new byte[BLOCK_SIZE * 2];
+ ByteBuf value = wrappedBuffer(valueContent);
+ buffer.writerIndex(0);
+ for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) {
+ random.nextBytes(valueContent);
+ assertEquals(0, buffer.readerIndex());
+ assertEquals(i, buffer.writerIndex());
+ buffer.writeBytes(value, random.nextInt(BLOCK_SIZE), BLOCK_SIZE);
+ assertEquals(0, value.readerIndex());
+ assertEquals(valueContent.length, value.writerIndex());
+ }
+
+ random.setSeed(seed);
+ byte[] expectedValueContent = new byte[BLOCK_SIZE * 2];
+ ByteBuf expectedValue = wrappedBuffer(expectedValueContent);
+ for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) {
+ random.nextBytes(expectedValueContent);
+ int valueOffset = random.nextInt(BLOCK_SIZE);
+ assertEquals(i, buffer.readerIndex());
+ assertEquals(CAPACITY, buffer.writerIndex());
+ buffer.readBytes(value, valueOffset, BLOCK_SIZE);
+ for (int j = valueOffset; j < valueOffset + BLOCK_SIZE; j ++) {
+ assertEquals(expectedValue.getByte(j), value.getByte(j));
+ }
+ assertEquals(0, value.readerIndex());
+ assertEquals(valueContent.length, value.writerIndex());
+ }
+ }
+
+ @Test
+ public void testSequentialHeapBufferTransfer2() {
+ byte[] valueContent = new byte[BLOCK_SIZE * 2];
+ ByteBuf value = wrappedBuffer(valueContent);
+ buffer.writerIndex(0);
+ for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) {
+ random.nextBytes(valueContent);
+ assertEquals(0, buffer.readerIndex());
+ assertEquals(i, buffer.writerIndex());
+ int readerIndex = random.nextInt(BLOCK_SIZE);
+ value.readerIndex(readerIndex);
+ value.writerIndex(readerIndex + BLOCK_SIZE);
+ buffer.writeBytes(value);
+ assertEquals(readerIndex + BLOCK_SIZE, value.writerIndex());
+ assertEquals(value.writerIndex(), value.readerIndex());
+ }
+
+ random.setSeed(seed);
+ byte[] expectedValueContent = new byte[BLOCK_SIZE * 2];
+ ByteBuf expectedValue = wrappedBuffer(expectedValueContent);
+ for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) {
+ random.nextBytes(expectedValueContent);
+ int valueOffset = random.nextInt(BLOCK_SIZE);
+ assertEquals(i, buffer.readerIndex());
+ assertEquals(CAPACITY, buffer.writerIndex());
+ value.readerIndex(valueOffset);
+ value.writerIndex(valueOffset);
+ buffer.readBytes(value, BLOCK_SIZE);
+ for (int j = valueOffset; j < valueOffset + BLOCK_SIZE; j ++) {
+ assertEquals(expectedValue.getByte(j), value.getByte(j));
+ }
+ assertEquals(valueOffset, value.readerIndex());
+ assertEquals(valueOffset + BLOCK_SIZE, value.writerIndex());
+ }
+ }
+
+ @Test
+ public void testSequentialDirectBufferTransfer1() {
+ byte[] valueContent = new byte[BLOCK_SIZE * 2];
+ ByteBuf value = directBuffer(BLOCK_SIZE * 2);
+ buffer.writerIndex(0);
+ for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) {
+ random.nextBytes(valueContent);
+ value.setBytes(0, valueContent);
+ assertEquals(0, buffer.readerIndex());
+ assertEquals(i, buffer.writerIndex());
+ buffer.writeBytes(value, random.nextInt(BLOCK_SIZE), BLOCK_SIZE);
+ assertEquals(0, value.readerIndex());
+ assertEquals(0, value.writerIndex());
+ }
+
+ random.setSeed(seed);
+ byte[] expectedValueContent = new byte[BLOCK_SIZE * 2];
+ ByteBuf expectedValue = wrappedBuffer(expectedValueContent);
+ for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) {
+ random.nextBytes(expectedValueContent);
+ int valueOffset = random.nextInt(BLOCK_SIZE);
+ value.setBytes(0, valueContent);
+ assertEquals(i, buffer.readerIndex());
+ assertEquals(CAPACITY, buffer.writerIndex());
+ buffer.readBytes(value, valueOffset, BLOCK_SIZE);
+ for (int j = valueOffset; j < valueOffset + BLOCK_SIZE; j ++) {
+ assertEquals(expectedValue.getByte(j), value.getByte(j));
+ }
+ assertEquals(0, value.readerIndex());
+ assertEquals(0, value.writerIndex());
+ }
+ value.release();
+ expectedValue.release();
+ }
+
+ @Test
+ public void testSequentialDirectBufferTransfer2() {
+ byte[] valueContent = new byte[BLOCK_SIZE * 2];
+ ByteBuf value = directBuffer(BLOCK_SIZE * 2);
+ buffer.writerIndex(0);
+ for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) {
+ random.nextBytes(valueContent);
+ value.setBytes(0, valueContent);
+ assertEquals(0, buffer.readerIndex());
+ assertEquals(i, buffer.writerIndex());
+ int readerIndex = random.nextInt(BLOCK_SIZE);
+ value.readerIndex(0);
+ value.writerIndex(readerIndex + BLOCK_SIZE);
+ value.readerIndex(readerIndex);
+ buffer.writeBytes(value);
+ assertEquals(readerIndex + BLOCK_SIZE, value.writerIndex());
+ assertEquals(value.writerIndex(), value.readerIndex());
+ }
+
+ random.setSeed(seed);
+ byte[] expectedValueContent = new byte[BLOCK_SIZE * 2];
+ ByteBuf expectedValue = wrappedBuffer(expectedValueContent);
+ for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) {
+ random.nextBytes(expectedValueContent);
+ value.setBytes(0, valueContent);
+ int valueOffset = random.nextInt(BLOCK_SIZE);
+ assertEquals(i, buffer.readerIndex());
+ assertEquals(CAPACITY, buffer.writerIndex());
+ value.readerIndex(valueOffset);
+ value.writerIndex(valueOffset);
+ buffer.readBytes(value, BLOCK_SIZE);
+ for (int j = valueOffset; j < valueOffset + BLOCK_SIZE; j ++) {
+ assertEquals(expectedValue.getByte(j), value.getByte(j));
+ }
+ assertEquals(valueOffset, value.readerIndex());
+ assertEquals(valueOffset + BLOCK_SIZE, value.writerIndex());
+ }
+ value.release();
+ expectedValue.release();
+ }
+
+ @Test
+ public void testSequentialByteBufferBackedHeapBufferTransfer1() {
+ byte[] valueContent = new byte[BLOCK_SIZE * 2];
+ ByteBuf value = wrappedBuffer(ByteBuffer.allocate(BLOCK_SIZE * 2));
+ value.writerIndex(0);
+ buffer.writerIndex(0);
+ for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) {
+ random.nextBytes(valueContent);
+ value.setBytes(0, valueContent);
+ assertEquals(0, buffer.readerIndex());
+ assertEquals(i, buffer.writerIndex());
+ buffer.writeBytes(value, random.nextInt(BLOCK_SIZE), BLOCK_SIZE);
+ assertEquals(0, value.readerIndex());
+ assertEquals(0, value.writerIndex());
+ }
+
+ random.setSeed(seed);
+ byte[] expectedValueContent = new byte[BLOCK_SIZE * 2];
+ ByteBuf expectedValue = wrappedBuffer(expectedValueContent);
+ for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) {
+ random.nextBytes(expectedValueContent);
+ int valueOffset = random.nextInt(BLOCK_SIZE);
+ value.setBytes(0, valueContent);
+ assertEquals(i, buffer.readerIndex());
+ assertEquals(CAPACITY, buffer.writerIndex());
+ buffer.readBytes(value, valueOffset, BLOCK_SIZE);
+ for (int j = valueOffset; j < valueOffset + BLOCK_SIZE; j ++) {
+ assertEquals(expectedValue.getByte(j), value.getByte(j));
+ }
+ assertEquals(0, value.readerIndex());
+ assertEquals(0, value.writerIndex());
+ }
+ }
+
+ @Test
+ public void testSequentialByteBufferBackedHeapBufferTransfer2() {
+ byte[] valueContent = new byte[BLOCK_SIZE * 2];
+ ByteBuf value = wrappedBuffer(ByteBuffer.allocate(BLOCK_SIZE * 2));
+ value.writerIndex(0);
+ buffer.writerIndex(0);
+ for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) {
+ random.nextBytes(valueContent);
+ value.setBytes(0, valueContent);
+ assertEquals(0, buffer.readerIndex());
+ assertEquals(i, buffer.writerIndex());
+ int readerIndex = random.nextInt(BLOCK_SIZE);
+ value.readerIndex(0);
+ value.writerIndex(readerIndex + BLOCK_SIZE);
+ value.readerIndex(readerIndex);
+ buffer.writeBytes(value);
+ assertEquals(readerIndex + BLOCK_SIZE, value.writerIndex());
+ assertEquals(value.writerIndex(), value.readerIndex());
+ }
+
+ random.setSeed(seed);
+ byte[] expectedValueContent = new byte[BLOCK_SIZE * 2];
+ ByteBuf expectedValue = wrappedBuffer(expectedValueContent);
+ for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) {
+ random.nextBytes(expectedValueContent);
+ value.setBytes(0, valueContent);
+ int valueOffset = random.nextInt(BLOCK_SIZE);
+ assertEquals(i, buffer.readerIndex());
+ assertEquals(CAPACITY, buffer.writerIndex());
+ value.readerIndex(valueOffset);
+ value.writerIndex(valueOffset);
+ buffer.readBytes(value, BLOCK_SIZE);
+ for (int j = valueOffset; j < valueOffset + BLOCK_SIZE; j ++) {
+ assertEquals(expectedValue.getByte(j), value.getByte(j));
+ }
+ assertEquals(valueOffset, value.readerIndex());
+ assertEquals(valueOffset + BLOCK_SIZE, value.writerIndex());
+ }
+ }
+
+ @Test
+ public void testSequentialByteBufferTransfer() {
+ buffer.writerIndex(0);
+ ByteBuffer value = ByteBuffer.allocate(BLOCK_SIZE * 2);
+ for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) {
+ random.nextBytes(value.array());
+ value.clear().position(random.nextInt(BLOCK_SIZE));
+ value.limit(value.position() + BLOCK_SIZE);
+ buffer.writeBytes(value);
+ }
+
+ random.setSeed(seed);
+ ByteBuffer expectedValue = ByteBuffer.allocate(BLOCK_SIZE * 2);
+ for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) {
+ random.nextBytes(expectedValue.array());
+ int valueOffset = random.nextInt(BLOCK_SIZE);
+ value.clear().position(valueOffset).limit(valueOffset + BLOCK_SIZE);
+ buffer.readBytes(value);
+ assertEquals(valueOffset + BLOCK_SIZE, value.position());
+ for (int j = valueOffset; j < valueOffset + BLOCK_SIZE; j ++) {
+ assertEquals(expectedValue.get(j), value.get(j));
+ }
+ }
+ }
+
+ @Test
+ public void testSequentialCopiedBufferTransfer1() {
+ buffer.writerIndex(0);
+ for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) {
+ byte[] value = new byte[BLOCK_SIZE];
+ random.nextBytes(value);
+ assertEquals(0, buffer.readerIndex());
+ assertEquals(i, buffer.writerIndex());
+ buffer.writeBytes(value);
+ }
+
+ random.setSeed(seed);
+ byte[] expectedValue = new byte[BLOCK_SIZE];
+ for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) {
+ random.nextBytes(expectedValue);
+ assertEquals(i, buffer.readerIndex());
+ assertEquals(CAPACITY, buffer.writerIndex());
+ ByteBuf actualValue = buffer.readBytes(BLOCK_SIZE);
+ assertEquals(wrappedBuffer(expectedValue), actualValue);
+
+ // Make sure if it is a copied buffer.
+ actualValue.setByte(0, (byte) (actualValue.getByte(0) + 1));
+ assertFalse(buffer.getByte(i) == actualValue.getByte(0));
+ actualValue.release();
+ }
+ }
+
+ @Test
+ public void testSequentialSlice1() {
+ buffer.writerIndex(0);
+ for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) {
+ byte[] value = new byte[BLOCK_SIZE];
+ random.nextBytes(value);
+ assertEquals(0, buffer.readerIndex());
+ assertEquals(i, buffer.writerIndex());
+ buffer.writeBytes(value);
+ }
+
+ random.setSeed(seed);
+ byte[] expectedValue = new byte[BLOCK_SIZE];
+ for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) {
+ random.nextBytes(expectedValue);
+ assertEquals(i, buffer.readerIndex());
+ assertEquals(CAPACITY, buffer.writerIndex());
+ ByteBuf actualValue = buffer.readSlice(BLOCK_SIZE);
+ assertEquals(buffer.order(), actualValue.order());
+ assertEquals(wrappedBuffer(expectedValue), actualValue);
+
+ // Make sure if it is a sliced buffer.
+ actualValue.setByte(0, (byte) (actualValue.getByte(0) + 1));
+ assertEquals(buffer.getByte(i), actualValue.getByte(0));
+ }
+ }
+
+ @Test
+ public void testWriteZero() {
+ try {
+ buffer.writeZero(-1);
+ fail();
+ } catch (IllegalArgumentException e) {
+ // Expected
+ }
+
+ buffer.clear();
+ while (buffer.isWritable()) {
+ buffer.writeByte((byte) 0xFF);
+ }
+
+ buffer.clear();
+ for (int i = 0; i < buffer.capacity();) {
+ int length = Math.min(buffer.capacity() - i, random.nextInt(32));
+ buffer.writeZero(length);
+ i += length;
+ }
+
+ assertEquals(0, buffer.readerIndex());
+ assertEquals(buffer.capacity(), buffer.writerIndex());
+
+ for (int i = 0; i < buffer.capacity(); i ++) {
+ assertEquals(0, buffer.getByte(i));
+ }
+ }
+
+ @Test
+ public void testDiscardReadBytes() {
+ buffer.writerIndex(0);
+ for (int i = 0; i < buffer.capacity(); i += 4) {
+ buffer.writeInt(i);
+ }
+ ByteBuf copy = copiedBuffer(buffer);
+
+ // Make sure there's no effect if called when readerIndex is 0.
+ buffer.readerIndex(CAPACITY / 4);
+ buffer.markReaderIndex();
+ buffer.writerIndex(CAPACITY / 3);
+ buffer.markWriterIndex();
+ buffer.readerIndex(0);
+ buffer.writerIndex(CAPACITY / 2);
+ buffer.discardReadBytes();
+
+ assertEquals(0, buffer.readerIndex());
+ assertEquals(CAPACITY / 2, buffer.writerIndex());
+ assertEquals(copy.slice(0, CAPACITY / 2), buffer.slice(0, CAPACITY / 2));
+ buffer.resetReaderIndex();
+ assertEquals(CAPACITY / 4, buffer.readerIndex());
+ buffer.resetWriterIndex();
+ assertEquals(CAPACITY / 3, buffer.writerIndex());
+
+ // Make sure bytes after writerIndex is not copied.
+ buffer.readerIndex(1);
+ buffer.writerIndex(CAPACITY / 2);
+ buffer.discardReadBytes();
+
+ assertEquals(0, buffer.readerIndex());
+ assertEquals(CAPACITY / 2 - 1, buffer.writerIndex());
+ assertEquals(copy.slice(1, CAPACITY / 2 - 1), buffer.slice(0, CAPACITY / 2 - 1));
+
+ if (discardReadBytesDoesNotMoveWritableBytes()) {
+ // If writable bytes were copied, the test should fail to avoid unnecessary memory bandwidth consumption.
+ assertFalse(copy.slice(CAPACITY / 2, CAPACITY / 2).equals(buffer.slice(CAPACITY / 2 - 1, CAPACITY / 2)));
+ } else {
+ assertEquals(copy.slice(CAPACITY / 2, CAPACITY / 2), buffer.slice(CAPACITY / 2 - 1, CAPACITY / 2));
+ }
+
+ // Marks also should be relocated.
+ buffer.resetReaderIndex();
+ assertEquals(CAPACITY / 4 - 1, buffer.readerIndex());
+ buffer.resetWriterIndex();
+ assertEquals(CAPACITY / 3 - 1, buffer.writerIndex());
+ copy.release();
+ }
+
+ /**
+ * The similar test case with {@link #testDiscardReadBytes()} but this one
+ * discards a large chunk at once.
+ */
+ @Test
+ public void testDiscardReadBytes2() {
+ buffer.writerIndex(0);
+ for (int i = 0; i < buffer.capacity(); i ++) {
+ buffer.writeByte((byte) i);
+ }
+ ByteBuf copy = copiedBuffer(buffer);
+
+ // Discard the first (CAPACITY / 2 - 1) bytes.
+ buffer.setIndex(CAPACITY / 2 - 1, CAPACITY - 1);
+ buffer.discardReadBytes();
+ assertEquals(0, buffer.readerIndex());
+ assertEquals(CAPACITY / 2, buffer.writerIndex());
+ for (int i = 0; i < CAPACITY / 2; i ++) {
+ assertEquals(copy.slice(CAPACITY / 2 - 1 + i, CAPACITY / 2 - i), buffer.slice(i, CAPACITY / 2 - i));
+ }
+ copy.release();
+ }
+
+ @Test
+ public void testStreamTransfer1() throws Exception {
+ byte[] expected = new byte[buffer.capacity()];
+ random.nextBytes(expected);
+
+ for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) {
+ ByteArrayInputStream in = new ByteArrayInputStream(expected, i, BLOCK_SIZE);
+ assertEquals(BLOCK_SIZE, buffer.setBytes(i, in, BLOCK_SIZE));
+ assertEquals(-1, buffer.setBytes(i, in, 0));
+ }
+
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) {
+ buffer.getBytes(i, out, BLOCK_SIZE);
+ }
+
+ assertTrue(Arrays.equals(expected, out.toByteArray()));
+ }
+
+ @Test
+ public void testStreamTransfer2() throws Exception {
+ byte[] expected = new byte[buffer.capacity()];
+ random.nextBytes(expected);
+ buffer.clear();
+
+ for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) {
+ ByteArrayInputStream in = new ByteArrayInputStream(expected, i, BLOCK_SIZE);
+ assertEquals(i, buffer.writerIndex());
+ buffer.writeBytes(in, BLOCK_SIZE);
+ assertEquals(i + BLOCK_SIZE, buffer.writerIndex());
+ }
+
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) {
+ assertEquals(i, buffer.readerIndex());
+ buffer.readBytes(out, BLOCK_SIZE);
+ assertEquals(i + BLOCK_SIZE, buffer.readerIndex());
+ }
+
+ assertTrue(Arrays.equals(expected, out.toByteArray()));
+ }
+
+ @Test
+ public void testCopy() {
+ for (int i = 0; i < buffer.capacity(); i ++) {
+ byte value = (byte) random.nextInt();
+ buffer.setByte(i, value);
+ }
+
+ final int readerIndex = CAPACITY / 3;
+ final int writerIndex = CAPACITY * 2 / 3;
+ buffer.setIndex(readerIndex, writerIndex);
+
+ // Make sure all properties are copied.
+ ByteBuf copy = buffer.copy();
+ assertEquals(0, copy.readerIndex());
+ assertEquals(buffer.readableBytes(), copy.writerIndex());
+ assertEquals(buffer.readableBytes(), copy.capacity());
+ assertSame(buffer.order(), copy.order());
+ for (int i = 0; i < copy.capacity(); i ++) {
+ assertEquals(buffer.getByte(i + readerIndex), copy.getByte(i));
+ }
+
+ // Make sure the buffer content is independent from each other.
+ buffer.setByte(readerIndex, (byte) (buffer.getByte(readerIndex) + 1));
+ assertTrue(buffer.getByte(readerIndex) != copy.getByte(0));
+ copy.setByte(1, (byte) (copy.getByte(1) + 1));
+ assertTrue(buffer.getByte(readerIndex + 1) != copy.getByte(1));
+ copy.release();
+ }
+
+ @Test
+ public void testDuplicate() {
+ for (int i = 0; i < buffer.capacity(); i ++) {
+ byte value = (byte) random.nextInt();
+ buffer.setByte(i, value);
+ }
+
+ final int readerIndex = CAPACITY / 3;
+ final int writerIndex = CAPACITY * 2 / 3;
+ buffer.setIndex(readerIndex, writerIndex);
+
+ // Make sure all properties are copied.
+ ByteBuf duplicate = buffer.duplicate();
+ assertSame(buffer.order(), duplicate.order());
+ assertEquals(buffer.readableBytes(), duplicate.readableBytes());
+ assertEquals(0, buffer.compareTo(duplicate));
+
+ // Make sure the buffer content is shared.
+ buffer.setByte(readerIndex, (byte) (buffer.getByte(readerIndex) + 1));
+ assertEquals(buffer.getByte(readerIndex), duplicate.getByte(duplicate.readerIndex()));
+ duplicate.setByte(duplicate.readerIndex(), (byte) (duplicate.getByte(duplicate.readerIndex()) + 1));
+ assertEquals(buffer.getByte(readerIndex), duplicate.getByte(duplicate.readerIndex()));
+ }
+
+ @Test
+ public void testSliceEndianness() throws Exception {
+ assertEquals(buffer.order(), buffer.slice(0, buffer.capacity()).order());
+ assertEquals(buffer.order(), buffer.slice(0, buffer.capacity() - 1).order());
+ assertEquals(buffer.order(), buffer.slice(1, buffer.capacity() - 1).order());
+ assertEquals(buffer.order(), buffer.slice(1, buffer.capacity() - 2).order());
+ }
+
+ @Test
+ public void testSliceIndex() throws Exception {
+ assertEquals(0, buffer.slice(0, buffer.capacity()).readerIndex());
+ assertEquals(0, buffer.slice(0, buffer.capacity() - 1).readerIndex());
+ assertEquals(0, buffer.slice(1, buffer.capacity() - 1).readerIndex());
+ assertEquals(0, buffer.slice(1, buffer.capacity() - 2).readerIndex());
+
+ assertEquals(buffer.capacity(), buffer.slice(0, buffer.capacity()).writerIndex());
+ assertEquals(buffer.capacity() - 1, buffer.slice(0, buffer.capacity() - 1).writerIndex());
+ assertEquals(buffer.capacity() - 1, buffer.slice(1, buffer.capacity() - 1).writerIndex());
+ assertEquals(buffer.capacity() - 2, buffer.slice(1, buffer.capacity() - 2).writerIndex());
+ }
+
+ @Test
+ @SuppressWarnings("ObjectEqualsNull")
+ public void testEquals() {
+ assertFalse(buffer.equals(null));
+ assertFalse(buffer.equals(new Object()));
+
+ byte[] value = new byte[32];
+ buffer.setIndex(0, value.length);
+ random.nextBytes(value);
+ buffer.setBytes(0, value);
+
+ assertEquals(buffer, wrappedBuffer(value));
+ assertEquals(buffer, wrappedBuffer(value).order(LITTLE_ENDIAN));
+
+ value[0] ++;
+ assertFalse(buffer.equals(wrappedBuffer(value)));
+ assertFalse(buffer.equals(wrappedBuffer(value).order(LITTLE_ENDIAN)));
+ }
+
+ @Test
+ public void testCompareTo() {
+ try {
+ buffer.compareTo(null);
+ fail();
+ } catch (NullPointerException e) {
+ // Expected
+ }
+
+ // Fill the random stuff
+ byte[] value = new byte[32];
+ random.nextBytes(value);
+ // Prevent overflow / underflow
+ if (value[0] == 0) {
+ value[0]++;
+ } else if (value[0] == -1) {
+ value[0]--;
+ }
+
+ buffer.setIndex(0, value.length);
+ buffer.setBytes(0, value);
+
+ assertEquals(0, buffer.compareTo(wrappedBuffer(value)));
+ assertEquals(0, buffer.compareTo(wrappedBuffer(value).order(LITTLE_ENDIAN)));
+
+ value[0]++;
+ assertTrue(buffer.compareTo(wrappedBuffer(value)) < 0);
+ assertTrue(buffer.compareTo(wrappedBuffer(value).order(LITTLE_ENDIAN)) < 0);
+ value[0] -= 2;
+ assertTrue(buffer.compareTo(wrappedBuffer(value)) > 0);
+ assertTrue(buffer.compareTo(wrappedBuffer(value).order(LITTLE_ENDIAN)) > 0);
+ value[0]++;
+
+ assertTrue(buffer.compareTo(wrappedBuffer(value, 0, 31)) > 0);
+ assertTrue(buffer.compareTo(wrappedBuffer(value, 0, 31).order(LITTLE_ENDIAN)) > 0);
+ assertTrue(buffer.slice(0, 31).compareTo(wrappedBuffer(value)) < 0);
+ assertTrue(buffer.slice(0, 31).compareTo(wrappedBuffer(value).order(LITTLE_ENDIAN)) < 0);
+ }
+
+ @Test
+ @Ignore("Behaviour was changed after 4.0.27, this test is newer but we should keep the old behaviour to be consistent with the netty version we use.")
+ public void testCompareTo2() {
+ byte[] bytes = {1, 2, 3, 4};
+ byte[] bytesReversed = {4, 3, 2, 1};
+
+ ByteBuf buf1 = newBuffer(4).clear().writeBytes(bytes).order(ByteOrder.LITTLE_ENDIAN);
+ ByteBuf buf2 = newBuffer(4).clear().writeBytes(bytesReversed).order(ByteOrder.LITTLE_ENDIAN);
+ ByteBuf buf3 = newBuffer(4).clear().writeBytes(bytes).order(ByteOrder.BIG_ENDIAN);
+ ByteBuf buf4 = newBuffer(4).clear().writeBytes(bytesReversed).order(ByteOrder.BIG_ENDIAN);
+ try {
+ assertEquals(buf1.compareTo(buf2), buf3.compareTo(buf4));
+ assertEquals(buf2.compareTo(buf1), buf4.compareTo(buf3));
+ assertEquals(buf1.compareTo(buf3), buf2.compareTo(buf4));
+ assertEquals(buf3.compareTo(buf1), buf4.compareTo(buf2));
+ } finally {
+ buf1.release();
+ buf2.release();
+ buf3.release();
+ buf4.release();
+ }
+ }
+
+ @Test
+ public void testToString() {
+ ByteBuf copied = copiedBuffer("Hello, World!", CharsetUtil.ISO_8859_1);
+ buffer.clear();
+ buffer.writeBytes(copied);
+ assertEquals("Hello, World!", buffer.toString(CharsetUtil.ISO_8859_1));
+ copied.release();
+ }
+
+ @Test
+ public void testIndexOf() {
+ buffer.clear();
+ buffer.writeByte((byte) 1);
+ buffer.writeByte((byte) 2);
+ buffer.writeByte((byte) 3);
+ buffer.writeByte((byte) 2);
+ buffer.writeByte((byte) 1);
+
+ assertEquals(-1, buffer.indexOf(1, 4, (byte) 1));
+ assertEquals(-1, buffer.indexOf(4, 1, (byte) 1));
+ assertEquals(1, buffer.indexOf(1, 4, (byte) 2));
+ assertEquals(3, buffer.indexOf(4, 1, (byte) 2));
+ }
+
+ @Test
+ public void testNioBuffer1() {
+ assumeTrue(buffer.nioBufferCount() == 1);
+
+ byte[] value = new byte[buffer.capacity()];
+ random.nextBytes(value);
+ buffer.clear();
+ buffer.writeBytes(value);
+
+ assertRemainingEquals(ByteBuffer.wrap(value), buffer.nioBuffer());
+ }
+
+ @Test
+ public void testToByteBuffer2() {
+ assumeTrue(buffer.nioBufferCount() == 1);
+
+ byte[] value = new byte[buffer.capacity()];
+ random.nextBytes(value);
+ buffer.clear();
+ buffer.writeBytes(value);
+
+ for (int i = 0; i < buffer.capacity() - BLOCK_SIZE + 1; i += BLOCK_SIZE) {
+ assertRemainingEquals(ByteBuffer.wrap(value, i, BLOCK_SIZE), buffer.nioBuffer(i, BLOCK_SIZE));
+ }
+ }
+
+ private static void assertRemainingEquals(ByteBuffer expected, ByteBuffer actual) {
+ int remaining = expected.remaining();
+ int remaining2 = actual.remaining();
+
+ assertEquals(remaining, remaining2);
+ byte[] array1 = new byte[remaining];
+ byte[] array2 = new byte[remaining2];
+ expected.get(array1);
+ actual.get(array2);
+ assertArrayEquals(array1, array2);
+ }
+
+ @Test
+ public void testToByteBuffer3() {
+ assumeTrue(buffer.nioBufferCount() == 1);
+
+ assertEquals(buffer.order(), buffer.nioBuffer().order());
+ }
+
+ @Test
+ public void testSkipBytes1() {
+ buffer.setIndex(CAPACITY / 4, CAPACITY / 2);
+
+ buffer.skipBytes(CAPACITY / 4);
+ assertEquals(CAPACITY / 4 * 2, buffer.readerIndex());
+
+ try {
+ buffer.skipBytes(CAPACITY / 4 + 1);
+ fail();
+ } catch (IndexOutOfBoundsException e) {
+ // Expected
+ }
+
+ // Should remain unchanged.
+ assertEquals(CAPACITY / 4 * 2, buffer.readerIndex());
+ }
+
+ @Test
+ public void testHashCode() {
+ ByteBuf elemA = buffer(15);
+ ByteBuf elemB = directBuffer(15);
+ elemA.writeBytes(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5 });
+ elemB.writeBytes(new byte[] { 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 9 });
+
+ Set<ByteBuf> set = new HashSet<ByteBuf>();
+ set.add(elemA);
+ set.add(elemB);
+
+ assertEquals(2, set.size());
+ ByteBuf elemACopy = elemA.copy();
+ assertTrue(set.contains(elemACopy));
+
+ ByteBuf elemBCopy = elemB.copy();
+ assertTrue(set.contains(elemBCopy));
+
+ buffer.clear();
+ buffer.writeBytes(elemA.duplicate());
+
+ assertTrue(set.remove(buffer));
+ assertFalse(set.contains(elemA));
+ assertEquals(1, set.size());
+
+ buffer.clear();
+ buffer.writeBytes(elemB.duplicate());
+ assertTrue(set.remove(buffer));
+ assertFalse(set.contains(elemB));
+ assertEquals(0, set.size());
+ elemA.release();
+ elemB.release();
+ elemACopy.release();
+ elemBCopy.release();
+ }
+
+ // Test case for https://github.com/netty/netty/issues/325
+ @Test
+ public void testDiscardAllReadBytes() {
+ buffer.writerIndex(buffer.capacity());
+ buffer.readerIndex(buffer.writerIndex());
+ buffer.discardReadBytes();
+ }
+
+ @Test
+ public void testForEachByte() {
+ buffer.clear();
+ for (int i = 0; i < CAPACITY; i ++) {
+ buffer.writeByte(i + 1);
+ }
+
+ final AtomicInteger lastIndex = new AtomicInteger();
+ buffer.setIndex(CAPACITY / 4, CAPACITY * 3 / 4);
+ assertThat(buffer.forEachByte(new ByteBufProcessor() {
+ int i = CAPACITY / 4;
+
+ @Override
+ public boolean process(byte value) throws Exception {
+ assertThat(value, is((byte) (i + 1)));
+ lastIndex.set(i);
+ i ++;
+ return true;
+ }
+ }), is(-1));
+
+ assertThat(lastIndex.get(), is(CAPACITY * 3 / 4 - 1));
+ }
+
+ @Test
+ public void testForEachByteAbort() {
+ buffer.clear();
+ for (int i = 0; i < CAPACITY; i ++) {
+ buffer.writeByte(i + 1);
+ }
+
+ final int stop = CAPACITY / 2;
+ assertThat(buffer.forEachByte(CAPACITY / 3, CAPACITY / 3, new ByteBufProcessor() {
+ int i = CAPACITY / 3;
+
+ @Override
+ public boolean process(byte value) throws Exception {
+ assertThat(value, is((byte) (i + 1)));
+ if (i == stop) {
+ return false;
+ }
+
+ i++;
+ return true;
+ }
+ }), is(stop));
+ }
+
+ @Test
+ public void testForEachByteDesc() {
+ buffer.clear();
+ for (int i = 0; i < CAPACITY; i ++) {
+ buffer.writeByte(i + 1);
+ }
+
+ final AtomicInteger lastIndex = new AtomicInteger();
+ assertThat(buffer.forEachByteDesc(CAPACITY / 4, CAPACITY * 2 / 4, new ByteBufProcessor() {
+ int i = CAPACITY * 3 / 4 - 1;
+
+ @Override
+ public boolean process(byte value) throws Exception {
+ assertThat(value, is((byte) (i + 1)));
+ lastIndex.set(i);
+ i --;
+ return true;
+ }
+ }), is(-1));
+
+ assertThat(lastIndex.get(), is(CAPACITY / 4));
+ }
+
+ @Test
+ public void testInternalNioBuffer() {
+ testInternalNioBuffer(128);
+ testInternalNioBuffer(1024);
+ testInternalNioBuffer(4 * 1024);
+ testInternalNioBuffer(64 * 1024);
+ testInternalNioBuffer(32 * 1024 * 1024);
+ testInternalNioBuffer(64 * 1024 * 1024);
+ }
+
+ private void testInternalNioBuffer(int a) {
+ ByteBuf buffer = newBuffer(2);
+ ByteBuffer buf = buffer.internalNioBuffer(buffer.readerIndex(), 1);
+ assertEquals(1, buf.remaining());
+
+ byte[] data = new byte[a];
+ ThreadLocalRandom.current().nextBytes(data);
+ buffer.writeBytes(data);
+
+ buf = buffer.internalNioBuffer(buffer.readerIndex(), a);
+ assertEquals(a, buf.remaining());
+
+ for (int i = 0; i < a; i++) {
+ assertEquals(data[i], buf.get());
+ }
+ assertFalse(buf.hasRemaining());
+ buffer.release();
+ }
+
+ @Test
+ public void testDuplicateReadGatheringByteChannelMultipleThreads() throws Exception {
+ testReadGatheringByteChannelMultipleThreads(false);
+ }
+
+ @Test
+ public void testSliceReadGatheringByteChannelMultipleThreads() throws Exception {
+ testReadGatheringByteChannelMultipleThreads(true);
+ }
+
+ private void testReadGatheringByteChannelMultipleThreads(final boolean slice) throws Exception {
+ final byte[] bytes = new byte[8];
+ random.nextBytes(bytes);
+
+ final ByteBuf buffer = newBuffer(8);
+ buffer.writeBytes(bytes);
+ final CountDownLatch latch = new CountDownLatch(60000);
+ final CyclicBarrier barrier = new CyclicBarrier(11);
+ for (int i = 0; i < 10; i++) {
+ new Thread(new Runnable() {
+ @Override
+ public void run() {
+ while (latch.getCount() > 0) {
+ ByteBuf buf;
+ if (slice) {
+ buf = buffer.slice();
+ } else {
+ buf = buffer.duplicate();
+ }
+ TestGatheringByteChannel channel = new TestGatheringByteChannel();
+
+ while (buf.isReadable()) {
+ try {
+ buf.readBytes(channel, buf.readableBytes());
+ } catch (IOException e) {
+ // Never happens
+ return;
+ }
+ }
+ assertArrayEquals(bytes, channel.writtenBytes());
+ latch.countDown();
+ }
+ try {
+ barrier.await();
+ } catch (Exception e) {
+ // ignore
+ }
+ }
+ }).start();
+ }
+ latch.await(10, TimeUnit.SECONDS);
+ barrier.await(5, TimeUnit.SECONDS);
+ buffer.release();
+ }
+
+ @Test
+ public void testDuplicateReadOutputStreamMultipleThreads() throws Exception {
+ testReadOutputStreamMultipleThreads(false);
+ }
+
+ @Test
+ public void testSliceReadOutputStreamMultipleThreads() throws Exception {
+ testReadOutputStreamMultipleThreads(true);
+ }
+
+ private void testReadOutputStreamMultipleThreads(final boolean slice) throws Exception {
+ final byte[] bytes = new byte[8];
+ random.nextBytes(bytes);
+
+ final ByteBuf buffer = newBuffer(8);
+ buffer.writeBytes(bytes);
+ final CountDownLatch latch = new CountDownLatch(60000);
+ final CyclicBarrier barrier = new CyclicBarrier(11);
+ for (int i = 0; i < 10; i++) {
+ new Thread(new Runnable() {
+ @Override
+ public void run() {
+ while (latch.getCount() > 0) {
+ ByteBuf buf;
+ if (slice) {
+ buf = buffer.slice();
+ } else {
+ buf = buffer.duplicate();
+ }
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+
+ while (buf.isReadable()) {
+ try {
+ buf.readBytes(out, buf.readableBytes());
+ } catch (IOException e) {
+ // Never happens
+ return;
+ }
+ }
+ assertArrayEquals(bytes, out.toByteArray());
+ latch.countDown();
+ }
+ try {
+ barrier.await();
+ } catch (Exception e) {
+ // ignore
+ }
+ }
+ }).start();
+ }
+ latch.await(10, TimeUnit.SECONDS);
+ barrier.await(5, TimeUnit.SECONDS);
+ buffer.release();
+ }
+
+ @Test
+ public void testDuplicateBytesInArrayMultipleThreads() throws Exception {
+ testBytesInArrayMultipleThreads(false);
+ }
+
+ @Test
+ public void testSliceBytesInArrayMultipleThreads() throws Exception {
+ testBytesInArrayMultipleThreads(true);
+ }
+
+ private void testBytesInArrayMultipleThreads(final boolean slice) throws Exception {
+ final byte[] bytes = new byte[8];
+ random.nextBytes(bytes);
+
+ final ByteBuf buffer = newBuffer(8);
+ buffer.writeBytes(bytes);
+ final AtomicReference<Throwable> cause = new AtomicReference<Throwable>();
+ final CountDownLatch latch = new CountDownLatch(60000);
+ final CyclicBarrier barrier = new CyclicBarrier(11);
+ for (int i = 0; i < 10; i++) {
+ new Thread(new Runnable() {
+ @Override
+ public void run() {
+ while (cause.get() == null && latch.getCount() > 0) {
+ ByteBuf buf;
+ if (slice) {
+ buf = buffer.slice();
+ } else {
+ buf = buffer.duplicate();
+ }
+
+ byte[] array = new byte[8];
+ buf.readBytes(array);
+
+ assertArrayEquals(bytes, array);
+
+ Arrays.fill(array, (byte) 0);
+ buf.getBytes(0, array);
+ assertArrayEquals(bytes, array);
+
+ latch.countDown();
+ }
+ try {
+ barrier.await();
+ } catch (Exception e) {
+ // ignore
+ }
+ }
+ }).start();
+ }
+ latch.await(10, TimeUnit.SECONDS);
+ barrier.await(5, TimeUnit.SECONDS);
+ assertNull(cause.get());
+ buffer.release();
+ }
+
+ @Test(expected = IndexOutOfBoundsException.class)
+ public void readByteThrowsIndexOutOfBoundsException() {
+ 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];
+ random.nextBytes(data);
+ buffer.writeBytes(data);
+
+ ByteBuffer nioBuf = buffer.nioBuffer(1, data.length - 2);
+ assertEquals(0, nioBuf.position());
+ assertEquals(6, nioBuf.remaining());
+
+ for (int i = 1; nioBuf.hasRemaining(); i++) {
+ assertEquals(data[i], nioBuf.get());
+ }
+ buffer.release();
+ }
+
+ @Test
+ public void ensureWritableWithForceDoesNotThrow() {
+ ensureWritableDoesNotThrow(true);
+ }
+
+ @Test
+ public void ensureWritableWithOutForceDoesNotThrow() {
+ ensureWritableDoesNotThrow(false);
+ }
+
+ private void ensureWritableDoesNotThrow(boolean force) {
+ final ByteBuf buffer = newBuffer(8);
+ buffer.writerIndex(buffer.capacity());
+ buffer.ensureWritable(8, force);
+ buffer.release();
+ }
+
+ // See:
+ // - https://github.com/netty/netty/issues/2587
+ // - https://github.com/netty/netty/issues/2580
+ @Test
+ public void testLittleEndianWithExpand() {
+ ByteBuf buffer = newBuffer(0).order(LITTLE_ENDIAN);
+ buffer.writeInt(0x12345678);
+ assertEquals("78563412", ByteBufUtil.hexDump(buffer));
+ buffer.release();
+ }
+
+ private ByteBuf releasedBuffer() {
+ ByteBuf buffer = newBuffer(8);
+ // Clear the buffer so we are sure the reader and writer indices are 0.
+ // This is important as we may return a slice from newBuffer(...).
+ buffer.clear();
+
+ assertTrue(buffer.release());
+ return buffer;
+ }
+
+ @Test(expected = IllegalReferenceCountException.class)
+ public void testDiscardReadBytesAfterRelease() {
+ releasedBuffer().discardReadBytes();
+ }
+
+ @Test(expected = IllegalReferenceCountException.class)
+ public void testDiscardSomeReadBytesAfterRelease() {
+ releasedBuffer().discardSomeReadBytes();
+ }
+
+ @Test(expected = IllegalReferenceCountException.class)
+ public void testEnsureWritableAfterRelease() {
+ releasedBuffer().ensureWritable(16);
+ }
+
+ @Test(expected = IllegalReferenceCountException.class)
+ public void testGetBooleanAfterRelease() {
+ releasedBuffer().getBoolean(0);
+ }
+
+ @Test(expected = IllegalReferenceCountException.class)
+ public void testGetByteAfterRelease() {
+ releasedBuffer().getByte(0);
+ }
+
+ @Test(expected = IllegalReferenceCountException.class)
+ public void testGetUnsignedByteAfterRelease() {
+ releasedBuffer().getUnsignedByte(0);
+ }
+
+ @Test(expected = IllegalReferenceCountException.class)
+ public void testGetShortAfterRelease() {
+ releasedBuffer().getShort(0);
+ }
+
+ @Test(expected = IllegalReferenceCountException.class)
+ public void testGetUnsignedShortAfterRelease() {
+ releasedBuffer().getUnsignedShort(0);
+ }
+
+ @Test(expected = IllegalReferenceCountException.class)
+ public void testGetMediumAfterRelease() {
+ releasedBuffer().getMedium(0);
+ }
+
+ @Test(expected = IllegalReferenceCountException.class)
+ public void testGetUnsignedMediumAfterRelease() {
+ releasedBuffer().getUnsignedMedium(0);
+ }
+
+ @Test(expected = IllegalReferenceCountException.class)
+ public void testGetIntAfterRelease() {
+ releasedBuffer().getInt(0);
+ }
+
+ @Test(expected = IllegalReferenceCountException.class)
+ public void testGetUnsignedIntAfterRelease() {
+ releasedBuffer().getUnsignedInt(0);
+ }
+
+ @Test(expected = IllegalReferenceCountException.class)
+ public void testGetLongAfterRelease() {
+ releasedBuffer().getLong(0);
+ }
+
+ @Test(expected = IllegalReferenceCountException.class)
+ public void testGetCharAfterRelease() {
+ releasedBuffer().getChar(0);
+ }
+
+ @Test(expected = IllegalReferenceCountException.class)
+ public void testGetFloatAfterRelease() {
+ releasedBuffer().getFloat(0);
+ }
+
+ @Test(expected = IllegalReferenceCountException.class)
+ public void testGetDoubleAfterRelease() {
+ releasedBuffer().getDouble(0);
+ }
+
+ @Test(expected = IllegalReferenceCountException.class)
+ public void testGetBytesAfterRelease() {
+ ByteBuf buffer = buffer(8);
+ try {
+ releasedBuffer().getBytes(0, buffer);
+ } finally {
+ buffer.release();
+ }
+ }
+
+ @Test(expected = IllegalReferenceCountException.class)
+ public void testGetBytesAfterRelease2() {
+ ByteBuf buffer = buffer();
+ try {
+ releasedBuffer().getBytes(0, buffer, 1);
+ } finally {
+ buffer.release();
+ }
+ }
+
+ @Test(expected = IllegalReferenceCountException.class)
+ public void testGetBytesAfterRelease3() {
+ ByteBuf buffer = buffer();
+ try {
+ releasedBuffer().getBytes(0, buffer, 0, 1);
+ } finally {
+ buffer.release();
+ }
+ }
+
+ @Test(expected = IllegalReferenceCountException.class)
+ public void testGetBytesAfterRelease4() {
+ releasedBuffer().getBytes(0, new byte[8]);
+ }
+
+ @Test(expected = IllegalReferenceCountException.class)
+ public void testGetBytesAfterRelease5() {
+ releasedBuffer().getBytes(0, new byte[8], 0, 1);
+ }
+
+ @Test(expected = IllegalReferenceCountException.class)
+ public void testGetBytesAfterRelease6() {
+ releasedBuffer().getBytes(0, ByteBuffer.allocate(8));
+ }
+
+ @Test(expected = IllegalReferenceCountException.class)
+ public void testGetBytesAfterRelease7() throws IOException {
+ releasedBuffer().getBytes(0, new ByteArrayOutputStream(), 1);
+ }
+
+ @Test(expected = IllegalReferenceCountException.class)
+ public void testGetBytesAfterRelease8() throws IOException {
+ releasedBuffer().getBytes(0, new DevNullGatheringByteChannel(), 1);
+ }
+
+ @Test(expected = IllegalReferenceCountException.class)
+ public void testSetBooleanAfterRelease() {
+ releasedBuffer().setBoolean(0, true);
+ }
+
+ @Test(expected = IllegalReferenceCountException.class)
+ public void testSetByteAfterRelease() {
+ releasedBuffer().setByte(0, 1);
+ }
+
+ @Test(expected = IllegalReferenceCountException.class)
+ public void testSetShortAfterRelease() {
+ releasedBuffer().setShort(0, 1);
+ }
+
+ @Test(expected = IllegalReferenceCountException.class)
+ public void testSetMediumAfterRelease() {
+ releasedBuffer().setMedium(0, 1);
+ }
+
+ @Test(expected = IllegalReferenceCountException.class)
+ public void testSetIntAfterRelease() {
+ releasedBuffer().setInt(0, 1);
+ }
+
+ @Test(expected = IllegalReferenceCountException.class)
+ public void testSetLongAfterRelease() {
+ releasedBuffer().setLong(0, 1);
+ }
+
+ @Test(expected = IllegalReferenceCountException.class)
+ public void testSetCharAfterRelease() {
+ releasedBuffer().setChar(0, 1);
+ }
+
+ @Test(expected = IllegalReferenceCountException.class)
+ public void testSetFloatAfterRelease() {
+ releasedBuffer().setFloat(0, 1);
+ }
+
+ @Test(expected = IllegalReferenceCountException.class)
+ public void testSetDoubleAfterRelease() {
+ releasedBuffer().setDouble(0, 1);
+ }
+
+ @Test(expected = IllegalReferenceCountException.class)
+ public void testSetBytesAfterRelease() {
+ ByteBuf buffer = buffer();
+ try {
+ releasedBuffer().setBytes(0, buffer);
+ } finally {
+ buffer.release();
+ }
+ }
+
+ @Test(expected = IllegalReferenceCountException.class)
+ public void testSetBytesAfterRelease2() {
+ ByteBuf buffer = buffer();
+ try {
+ releasedBuffer().setBytes(0, buffer, 1);
+ } finally {
+ buffer.release();
+ }
+ }
+
+ @Test(expected = IllegalReferenceCountException.class)
+ public void testSetBytesAfterRelease3() {
+ ByteBuf buffer = buffer();
+ try {
+ releasedBuffer().setBytes(0, buffer, 0, 1);
+ } finally {
+ buffer.release();
+ }
+ }
+
+ @Test(expected = IllegalReferenceCountException.class)
+ public void testSetBytesAfterRelease4() {
+ releasedBuffer().setBytes(0, new byte[8]);
+ }
+
+ @Test(expected = IllegalReferenceCountException.class)
+ public void testSetBytesAfterRelease5() {
+ releasedBuffer().setBytes(0, new byte[8], 0, 1);
+ }
+
+ @Test(expected = IllegalReferenceCountException.class)
+ public void testSetBytesAfterRelease6() {
+ releasedBuffer().setBytes(0, ByteBuffer.allocate(8));
+ }
+
+ @Test(expected = IllegalReferenceCountException.class)
+ public void testSetBytesAfterRelease7() throws IOException {
+ releasedBuffer().setBytes(0, new ByteArrayInputStream(new byte[8]), 1);
+ }
+
+ @Test(expected = IllegalReferenceCountException.class)
+ public void testSetBytesAfterRelease8() throws IOException {
+ releasedBuffer().setBytes(0, new TestScatteringByteChannel(), 1);
+ }
+
+ @Test(expected = IllegalReferenceCountException.class)
<TRUNCATED>