Add common tests for ByteBufAllocator / AbstractByteBufAllocator implementations.

Motivation:

We not had tests for ByteBufAllocator implementations in general.

Modifications:

Added ByteBufAllocatorTest, AbstractByteBufAllocatorTest and UnpooledByteBufAllocatorTest

Result:

More tests for allocator implementations.
This commit is contained in:
Norman Maurer 2017-01-26 12:15:10 +01:00
parent 0f9b739508
commit 756b78b7df
7 changed files with 336 additions and 11 deletions

View File

@ -25,8 +25,10 @@ import io.netty.util.internal.StringUtil;
* Skeletal {@link ByteBufAllocator} implementation to extend. * Skeletal {@link ByteBufAllocator} implementation to extend.
*/ */
public abstract class AbstractByteBufAllocator implements ByteBufAllocator { public abstract class AbstractByteBufAllocator implements ByteBufAllocator {
private static final int DEFAULT_INITIAL_CAPACITY = 256; static final int DEFAULT_INITIAL_CAPACITY = 256;
static final int DEFAULT_MAX_CAPACITY = Integer.MAX_VALUE;
static final int DEFAULT_MAX_COMPONENTS = 16; static final int DEFAULT_MAX_COMPONENTS = 16;
static final int CALCULATE_THRESHOLD = 1048576 * 4; // 4 MiB page
protected static ByteBuf toLeakAwareBuffer(ByteBuf buf) { protected static ByteBuf toLeakAwareBuffer(ByteBuf buf) {
ResourceLeakTracker<ByteBuf> leak; ResourceLeakTracker<ByteBuf> leak;
@ -143,12 +145,12 @@ public abstract class AbstractByteBufAllocator implements ByteBufAllocator {
@Override @Override
public ByteBuf heapBuffer() { public ByteBuf heapBuffer() {
return heapBuffer(DEFAULT_INITIAL_CAPACITY, Integer.MAX_VALUE); return heapBuffer(DEFAULT_INITIAL_CAPACITY, DEFAULT_MAX_CAPACITY);
} }
@Override @Override
public ByteBuf heapBuffer(int initialCapacity) { public ByteBuf heapBuffer(int initialCapacity) {
return heapBuffer(initialCapacity, Integer.MAX_VALUE); return heapBuffer(initialCapacity, DEFAULT_MAX_CAPACITY);
} }
@Override @Override
@ -162,12 +164,12 @@ public abstract class AbstractByteBufAllocator implements ByteBufAllocator {
@Override @Override
public ByteBuf directBuffer() { public ByteBuf directBuffer() {
return directBuffer(DEFAULT_INITIAL_CAPACITY, Integer.MAX_VALUE); return directBuffer(DEFAULT_INITIAL_CAPACITY, DEFAULT_MAX_CAPACITY);
} }
@Override @Override
public ByteBuf directBuffer(int initialCapacity) { public ByteBuf directBuffer(int initialCapacity) {
return directBuffer(initialCapacity, Integer.MAX_VALUE); return directBuffer(initialCapacity, DEFAULT_MAX_CAPACITY);
} }
@Override @Override
@ -251,7 +253,7 @@ public abstract class AbstractByteBufAllocator implements ByteBufAllocator {
"minNewCapacity: %d (expected: not greater than maxCapacity(%d)", "minNewCapacity: %d (expected: not greater than maxCapacity(%d)",
minNewCapacity, maxCapacity)); minNewCapacity, maxCapacity));
} }
final int threshold = 1048576 * 4; // 4 MiB page final int threshold = CALCULATE_THRESHOLD; // 4 MiB page
if (minNewCapacity == threshold) { if (minNewCapacity == threshold) {
return threshold; return threshold;

View File

@ -54,7 +54,7 @@ public class CompositeByteBuf extends AbstractReferenceCountedByteBuf implements
private boolean freed; private boolean freed;
public CompositeByteBuf(ByteBufAllocator alloc, boolean direct, int maxNumComponents) { public CompositeByteBuf(ByteBufAllocator alloc, boolean direct, int maxNumComponents) {
super(Integer.MAX_VALUE); super(AbstractByteBufAllocator.DEFAULT_MAX_CAPACITY);
if (alloc == null) { if (alloc == null) {
throw new NullPointerException("alloc"); throw new NullPointerException("alloc");
} }
@ -70,7 +70,7 @@ public class CompositeByteBuf extends AbstractReferenceCountedByteBuf implements
CompositeByteBuf( CompositeByteBuf(
ByteBufAllocator alloc, boolean direct, int maxNumComponents, ByteBuf[] buffers, int offset, int len) { ByteBufAllocator alloc, boolean direct, int maxNumComponents, ByteBuf[] buffers, int offset, int len) {
super(Integer.MAX_VALUE); super(AbstractByteBufAllocator.DEFAULT_MAX_CAPACITY);
if (alloc == null) { if (alloc == null) {
throw new NullPointerException("alloc"); throw new NullPointerException("alloc");
} }
@ -91,7 +91,7 @@ public class CompositeByteBuf extends AbstractReferenceCountedByteBuf implements
public CompositeByteBuf( public CompositeByteBuf(
ByteBufAllocator alloc, boolean direct, int maxNumComponents, Iterable<ByteBuf> buffers) { ByteBufAllocator alloc, boolean direct, int maxNumComponents, Iterable<ByteBuf> buffers) {
super(Integer.MAX_VALUE); super(AbstractByteBufAllocator.DEFAULT_MAX_CAPACITY);
if (alloc == null) { if (alloc == null) {
throw new NullPointerException("alloc"); throw new NullPointerException("alloc");
} }

View File

@ -43,7 +43,7 @@ final class FixedCompositeByteBuf extends AbstractReferenceCountedByteBuf {
private final boolean direct; private final boolean direct;
FixedCompositeByteBuf(ByteBufAllocator allocator, ByteBuf... buffers) { FixedCompositeByteBuf(ByteBufAllocator allocator, ByteBuf... buffers) {
super(Integer.MAX_VALUE); super(AbstractByteBufAllocator.DEFAULT_MAX_CAPACITY);
if (buffers.length == 0) { if (buffers.length == 0) {
this.buffers = EMPTY; this.buffers = EMPTY;
order = ByteOrder.BIG_ENDIAN; order = ByteOrder.BIG_ENDIAN;

View File

@ -0,0 +1,69 @@
/*
* Copyright 2017 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:
*
* 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 io.netty.buffer;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
public abstract class AbstractByteBufAllocatorTest extends ByteBufAllocatorTest {
@Override
protected abstract AbstractByteBufAllocator newAllocator(boolean preferDirect);
@Override
protected final int defaultMaxCapacity() {
return AbstractByteBufAllocator.DEFAULT_MAX_CAPACITY;
}
@Override
protected final int defaultMaxComponents() {
return AbstractByteBufAllocator.DEFAULT_MAX_COMPONENTS;
}
@Test
public void testCalculateNewCapacity() {
testCalculateNewCapacity(true);
testCalculateNewCapacity(false);
}
private void testCalculateNewCapacity(boolean preferDirect) {
ByteBufAllocator allocator = newAllocator(preferDirect);
assertEquals(8, allocator.calculateNewCapacity(1, 8));
assertEquals(7, allocator.calculateNewCapacity(1, 7));
assertEquals(64, allocator.calculateNewCapacity(1, 129));
assertEquals(AbstractByteBufAllocator.CALCULATE_THRESHOLD,
allocator.calculateNewCapacity(AbstractByteBufAllocator.CALCULATE_THRESHOLD,
AbstractByteBufAllocator.CALCULATE_THRESHOLD + 1));
assertEquals(AbstractByteBufAllocator.CALCULATE_THRESHOLD * 2,
allocator.calculateNewCapacity(AbstractByteBufAllocator.CALCULATE_THRESHOLD + 1,
AbstractByteBufAllocator.CALCULATE_THRESHOLD * 4));
try {
allocator.calculateNewCapacity(8, 7);
fail();
} catch (IllegalArgumentException e) {
// expected
}
try {
allocator.calculateNewCapacity(-1, 8);
fail();
} catch (IllegalArgumentException e) {
// expected
}
}
}

View File

@ -0,0 +1,225 @@
/*
* Copyright 2017 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:
*
* 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 io.netty.buffer;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
public abstract class ByteBufAllocatorTest {
protected abstract int defaultMaxCapacity();
protected abstract int defaultMaxComponents();
protected abstract ByteBufAllocator newAllocator(boolean preferDirect);
@Test
public void testBuffer() {
testBuffer(true);
testBuffer(false);
}
private void testBuffer(boolean preferDirect) {
ByteBufAllocator allocator = newAllocator(preferDirect);
ByteBuf buffer = allocator.buffer(1);
try {
assertBuffer(buffer, preferDirect, 1, defaultMaxCapacity());
} finally {
buffer.release();
}
}
@Test
public void testBufferWithCapacity() {
testBufferWithCapacity(true, 8);
testBufferWithCapacity(false, 8);
}
private void testBufferWithCapacity(boolean preferDirect, int maxCapacity) {
ByteBufAllocator allocator = newAllocator(preferDirect);
ByteBuf buffer = allocator.buffer(1, maxCapacity);
try {
assertBuffer(buffer, preferDirect, 1, maxCapacity);
} finally {
buffer.release();
}
}
@Test
public void testHeapBuffer() {
testHeapBuffer(true);
testHeapBuffer(false);
}
private void testHeapBuffer(boolean preferDirect) {
ByteBufAllocator allocator = newAllocator(preferDirect);
ByteBuf buffer = allocator.heapBuffer(1);
try {
assertBuffer(buffer, false, 1, defaultMaxCapacity());
} finally {
buffer.release();
}
}
@Test
public void testHeapBufferMaxCapacity() {
testHeapBuffer(true, 8);
testHeapBuffer(false, 8);
}
private void testHeapBuffer(boolean preferDirect, int maxCapacity) {
ByteBufAllocator allocator = newAllocator(preferDirect);
ByteBuf buffer = allocator.heapBuffer(1, maxCapacity);
try {
assertBuffer(buffer, false, 1, maxCapacity);
} finally {
buffer.release();
}
}
@Test
public void testDirectBuffer() {
testDirectBuffer(true);
testDirectBuffer(false);
}
private void testDirectBuffer(boolean preferDirect) {
ByteBufAllocator allocator = newAllocator(preferDirect);
ByteBuf buffer = allocator.directBuffer(1);
try {
assertBuffer(buffer, true, 1, defaultMaxCapacity());
} finally {
buffer.release();
}
}
@Test
public void testDirectBufferMaxCapacity() {
testDirectBuffer(true, 8);
testDirectBuffer(false, 8);
}
private void testDirectBuffer(boolean preferDirect, int maxCapacity) {
ByteBufAllocator allocator = newAllocator(preferDirect);
ByteBuf buffer = allocator.directBuffer(1, maxCapacity);
try {
assertBuffer(buffer, true, 1, maxCapacity);
} finally {
buffer.release();
}
}
@Test
public void testCompositeBuffer() {
testCompositeBuffer(true);
testCompositeBuffer(false);
}
private void testCompositeBuffer(boolean preferDirect) {
ByteBufAllocator allocator = newAllocator(preferDirect);
CompositeByteBuf buffer = allocator.compositeBuffer();
try {
assertCompositeByteBuf(buffer, defaultMaxComponents());
} finally {
buffer.release();
}
}
@Test
public void testCompositeBufferWithCapacity() {
testCompositeHeapBufferWithCapacity(true, 8);
testCompositeHeapBufferWithCapacity(false, 8);
}
@Test
public void testCompositeHeapBuffer() {
testCompositeHeapBuffer(true);
testCompositeHeapBuffer(false);
}
private void testCompositeHeapBuffer(boolean preferDirect) {
ByteBufAllocator allocator = newAllocator(preferDirect);
CompositeByteBuf buffer = allocator.compositeHeapBuffer();
try {
assertCompositeByteBuf(buffer, defaultMaxComponents());
} finally {
buffer.release();
}
}
@Test
public void testCompositeHeapBufferWithCapacity() {
testCompositeHeapBufferWithCapacity(true, 8);
testCompositeHeapBufferWithCapacity(false, 8);
}
private void testCompositeHeapBufferWithCapacity(boolean preferDirect, int maxNumComponents) {
ByteBufAllocator allocator = newAllocator(preferDirect);
CompositeByteBuf buffer = allocator.compositeHeapBuffer(maxNumComponents);
try {
assertCompositeByteBuf(buffer, maxNumComponents);
} finally {
buffer.release();
}
}
@Test
public void testCompositeDirectBuffer() {
testCompositeDirectBuffer(true);
testCompositeDirectBuffer(false);
}
private void testCompositeDirectBuffer(boolean preferDirect) {
ByteBufAllocator allocator = newAllocator(preferDirect);
CompositeByteBuf buffer = allocator.compositeDirectBuffer();
try {
assertCompositeByteBuf(buffer, defaultMaxComponents());
} finally {
buffer.release();
}
}
@Test
public void testCompositeDirectBufferWithCapacity() {
testCompositeDirectBufferWithCapacity(true, 8);
testCompositeDirectBufferWithCapacity(false, 8);
}
private void testCompositeDirectBufferWithCapacity(boolean preferDirect, int maxNumComponents) {
ByteBufAllocator allocator = newAllocator(preferDirect);
CompositeByteBuf buffer = allocator.compositeDirectBuffer(maxNumComponents);
try {
assertCompositeByteBuf(buffer, maxNumComponents);
} finally {
buffer.release();
}
}
private static void assertBuffer(
ByteBuf buffer, boolean expectedDirect, int expectedCapacity, int expectedMaxCapacity) {
assertEquals(expectedDirect, buffer.isDirect());
assertEquals(expectedCapacity, buffer.capacity());
assertEquals(expectedMaxCapacity, buffer.maxCapacity());
}
private void assertCompositeByteBuf(
CompositeByteBuf buffer, int expectedMaxNumComponents) {
assertEquals(0, buffer.numComponents());
assertEquals(expectedMaxNumComponents, buffer.maxNumComponents());
assertBuffer(buffer, false, 0, defaultMaxCapacity());
}
}

View File

@ -35,7 +35,12 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
public class PooledByteBufAllocatorTest { public class PooledByteBufAllocatorTest extends AbstractByteBufAllocatorTest {
@Override
protected AbstractByteBufAllocator newAllocator(boolean preferDirect) {
return new PooledByteBufAllocator(preferDirect);
}
@Test @Test
public void testArenaMetricsNoCache() { public void testArenaMetricsNoCache() {

View File

@ -0,0 +1,24 @@
/*
* Copyright 2017 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:
*
* 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 io.netty.buffer;
public class UnpooledByteBufAllocatorTest extends AbstractByteBufAllocatorTest {
@Override
protected AbstractByteBufAllocator newAllocator(boolean preferDirect) {
return new UnpooledByteBufAllocator(preferDirect);
}
}