[Test] make sure we test writeTo(Channel) in BytesReference

also introduce proper randomization of content in the bytes
This commit is contained in:
Shay Banon 2014-05-26 13:32:52 +02:00
parent 15ff3df243
commit cd94af2c9e
1 changed files with 76 additions and 45 deletions

View File

@ -19,20 +19,26 @@
package org.elasticsearch.common.bytes; package org.elasticsearch.common.bytes;
import com.carrotsearch.randomizedtesting.annotations.Repeat;
import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.BytesRef;
import org.elasticsearch.common.io.Streams;
import org.elasticsearch.common.io.stream.BytesStreamOutput; import org.elasticsearch.common.io.stream.BytesStreamOutput;
import org.elasticsearch.common.io.stream.ReleasableBytesStreamOutput;
import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.settings.ImmutableSettings; import org.elasticsearch.common.settings.ImmutableSettings;
import org.elasticsearch.common.util.BigArrays; import org.elasticsearch.common.util.BigArrays;
import org.elasticsearch.common.util.ByteArray; import org.elasticsearch.common.util.ByteArray;
import org.elasticsearch.test.ElasticsearchTestCase; import org.elasticsearch.test.ElasticsearchTestCase;
import org.hamcrest.Matchers;
import org.jboss.netty.buffer.ChannelBuffer; import org.jboss.netty.buffer.ChannelBuffer;
import org.junit.After; import org.junit.After;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import java.io.EOFException; import java.io.EOFException;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.Arrays; import java.util.Arrays;
public class PagedBytesReferenceTest extends ElasticsearchTestCase { public class PagedBytesReferenceTest extends ElasticsearchTestCase {
@ -82,13 +88,11 @@ public class PagedBytesReferenceTest extends ElasticsearchTestCase {
if (slice.hasArray()) { if (slice.hasArray()) {
assertEquals(sliceOffset, slice.arrayOffset()); assertEquals(sliceOffset, slice.arrayOffset());
} } else {
else {
try { try {
slice.arrayOffset(); slice.arrayOffset();
fail("expected IllegalStateException"); fail("expected IllegalStateException");
} } catch (IllegalStateException ise) {
catch (IllegalStateException ise) {
// expected // expected
} }
} }
@ -119,7 +123,7 @@ public class PagedBytesReferenceTest extends ElasticsearchTestCase {
si.reset(); si.reset();
// read a few few bytes as ints // read a few few bytes as ints
int bytesToRead = randomIntBetween(1, length/2); int bytesToRead = randomIntBetween(1, length / 2);
for (int i = 0; i < bytesToRead; i++) { for (int i = 0; i < bytesToRead; i++) {
int b = si.read(); int b = si.read();
assertEquals(pbr.get(i), b); assertEquals(pbr.get(i), b);
@ -134,8 +138,7 @@ public class PagedBytesReferenceTest extends ElasticsearchTestCase {
try { try {
si.readByte(); si.readByte();
fail("expected EOF"); fail("expected EOF");
} } catch (EOFException eof) {
catch (EOFException eof) {
// yay // yay
} }
@ -144,8 +147,7 @@ public class PagedBytesReferenceTest extends ElasticsearchTestCase {
try { try {
si.readBytes(targetBuf, 0, length * 2); si.readBytes(targetBuf, 0, length * 2);
fail("expected IndexOutOfBoundsException: le > stream.length"); fail("expected IndexOutOfBoundsException: le > stream.length");
} } catch (IndexOutOfBoundsException ioob) {
catch (IndexOutOfBoundsException ioob) {
// expected // expected
} }
} }
@ -158,7 +160,7 @@ public class PagedBytesReferenceTest extends ElasticsearchTestCase {
// read a bunch of single bytes one by one // read a bunch of single bytes one by one
int offset = randomIntBetween(1, length / 2); int offset = randomIntBetween(1, length / 2);
for (int i = 0; i < offset ; i++) { for (int i = 0; i < offset; i++) {
assertEquals(pbr.get(i), si.readByte()); assertEquals(pbr.get(i), si.readByte());
} }
@ -180,11 +182,11 @@ public class PagedBytesReferenceTest extends ElasticsearchTestCase {
BytesReference pbr = getRandomizedPagedBytesReference(length); BytesReference pbr = getRandomizedPagedBytesReference(length);
StreamInput streamInput = pbr.streamInput(); StreamInput streamInput = pbr.streamInput();
BytesRef target = new BytesRef(); BytesRef target = new BytesRef();
while(target.length < pbr.length()) { while (target.length < pbr.length()) {
switch (randomIntBetween(0, 10)) { switch (randomIntBetween(0, 10)) {
case 6: case 6:
case 5: case 5:
target.append(new BytesRef(new byte[] {streamInput.readByte()})); target.append(new BytesRef(new byte[]{streamInput.readByte()}));
break; break;
case 4: case 4:
case 3: case 3:
@ -236,13 +238,13 @@ public class PagedBytesReferenceTest extends ElasticsearchTestCase {
sliceInput.reset(); sliceInput.reset();
byte[] buffer = new byte[sliceLength + scaledRandomIntBetween(1, 100)]; byte[] buffer = new byte[sliceLength + scaledRandomIntBetween(1, 100)];
int offset = scaledRandomIntBetween(0, Math.max(1, buffer.length - sliceLength - 1)); int offset = scaledRandomIntBetween(0, Math.max(1, buffer.length - sliceLength - 1));
int read = sliceInput.read(buffer, offset, sliceLength / 2); int read = sliceInput.read(buffer, offset, sliceLength / 2);
sliceInput.read(buffer, offset + read, sliceLength); sliceInput.read(buffer, offset + read, sliceLength);
assertArrayEquals(sliceBytes, Arrays.copyOfRange(buffer, offset, offset + sliceLength)); assertArrayEquals(sliceBytes, Arrays.copyOfRange(buffer, offset, offset + sliceLength));
} }
public void testWriteTo() throws IOException { public void testWriteToOutputStream() throws IOException {
int length = randomIntBetween(10, PAGE_SIZE * 4); int length = randomIntBetween(10, PAGE_SIZE * 4);
BytesReference pbr = getRandomizedPagedBytesReference(length); BytesReference pbr = getRandomizedPagedBytesReference(length);
BytesStreamOutput out = new BytesStreamOutput(); BytesStreamOutput out = new BytesStreamOutput();
@ -252,8 +254,18 @@ public class PagedBytesReferenceTest extends ElasticsearchTestCase {
out.close(); out.close();
} }
public void testSliceWriteTo() throws IOException { public void testWriteToChannel() throws IOException {
int length = randomIntBetween(10, PAGE_SIZE * randomIntBetween(2,5)); int length = randomIntBetween(10, PAGE_SIZE * 4);
BytesReference pbr = getRandomizedPagedBytesReference(length);
File tFile = newTempFile();
RandomAccessFile file = new RandomAccessFile(tFile, "rw");
pbr.writeTo(file.getChannel());
assertEquals(pbr.length(), file.length());
assertArrayEquals(pbr.toBytes(), Streams.copyToByteArray(tFile));
}
public void testSliceWriteToOutputStream() throws IOException {
int length = randomIntBetween(10, PAGE_SIZE * randomIntBetween(2, 5));
BytesReference pbr = getRandomizedPagedBytesReference(length); BytesReference pbr = getRandomizedPagedBytesReference(length);
int sliceOffset = randomIntBetween(1, length / 2); int sliceOffset = randomIntBetween(1, length / 2);
int sliceLength = length - sliceOffset; int sliceLength = length - sliceOffset;
@ -265,8 +277,21 @@ public class PagedBytesReferenceTest extends ElasticsearchTestCase {
sliceOut.close(); sliceOut.close();
} }
public void testSliceWriteToChannel() throws IOException {
int length = randomIntBetween(10, PAGE_SIZE * randomIntBetween(2, 5));
BytesReference pbr = getRandomizedPagedBytesReference(length);
int sliceOffset = randomIntBetween(1, length / 2);
int sliceLength = length - sliceOffset;
BytesReference slice = pbr.slice(sliceOffset, sliceLength);
File tFile = newTempFile();
RandomAccessFile file = new RandomAccessFile(tFile, "rw");
slice.writeTo(file.getChannel());
assertEquals(slice.length(), file.length());
assertArrayEquals(slice.toBytes(), Streams.copyToByteArray(tFile));
}
public void testToBytes() { public void testToBytes() {
int[] sizes = {0, randomInt(PAGE_SIZE), PAGE_SIZE, randomIntBetween(2, PAGE_SIZE * randomIntBetween(2,5))}; int[] sizes = {0, randomInt(PAGE_SIZE), PAGE_SIZE, randomIntBetween(2, PAGE_SIZE * randomIntBetween(2, 5))};
for (int i = 0; i < sizes.length; i++) { for (int i = 0; i < sizes.length; i++) {
BytesReference pbr = getRandomizedPagedBytesReference(sizes[i]); BytesReference pbr = getRandomizedPagedBytesReference(sizes[i]);
@ -275,8 +300,7 @@ public class PagedBytesReferenceTest extends ElasticsearchTestCase {
// verify that toBytes() is cheap for small payloads // verify that toBytes() is cheap for small payloads
if (sizes[i] <= PAGE_SIZE) { if (sizes[i] <= PAGE_SIZE) {
assertSame(bytes, pbr.toBytes()); assertSame(bytes, pbr.toBytes());
} } else {
else {
assertNotSame(bytes, pbr.toBytes()); assertNotSame(bytes, pbr.toBytes());
} }
} }
@ -299,7 +323,7 @@ public class PagedBytesReferenceTest extends ElasticsearchTestCase {
// we need a length != (n * pagesize) to avoid page sharing at boundaries // we need a length != (n * pagesize) to avoid page sharing at boundaries
int length = 0; int length = 0;
while ((length % PAGE_SIZE) == 0) { while ((length % PAGE_SIZE) == 0) {
length = randomIntBetween(PAGE_SIZE, PAGE_SIZE * randomIntBetween(2,5)); length = randomIntBetween(PAGE_SIZE, PAGE_SIZE * randomIntBetween(2, 5));
} }
BytesReference pbr = getRandomizedPagedBytesReference(length); BytesReference pbr = getRandomizedPagedBytesReference(length);
BytesArray ba = pbr.toBytesArray(); BytesArray ba = pbr.toBytesArray();
@ -324,7 +348,7 @@ public class PagedBytesReferenceTest extends ElasticsearchTestCase {
} }
public void testSliceCopyBytesArray() { public void testSliceCopyBytesArray() {
int length = randomIntBetween(10, PAGE_SIZE * randomIntBetween(2,8)); int length = randomIntBetween(10, PAGE_SIZE * randomIntBetween(2, 8));
BytesReference pbr = getRandomizedPagedBytesReference(length); BytesReference pbr = getRandomizedPagedBytesReference(length);
int sliceOffset = randomIntBetween(0, pbr.length()); int sliceOffset = randomIntBetween(0, pbr.length());
int sliceLength = randomIntBetween(pbr.length() - sliceOffset, pbr.length() - sliceOffset); int sliceLength = randomIntBetween(pbr.length() - sliceOffset, pbr.length() - sliceOffset);
@ -341,7 +365,7 @@ public class PagedBytesReferenceTest extends ElasticsearchTestCase {
} }
public void testToChannelBuffer() { public void testToChannelBuffer() {
int length = randomIntBetween(10, PAGE_SIZE * randomIntBetween(2,8)); int length = randomIntBetween(10, PAGE_SIZE * randomIntBetween(2, 8));
BytesReference pbr = getRandomizedPagedBytesReference(length); BytesReference pbr = getRandomizedPagedBytesReference(length);
ChannelBuffer cb = pbr.toChannelBuffer(); ChannelBuffer cb = pbr.toChannelBuffer();
assertNotNull(cb); assertNotNull(cb);
@ -359,7 +383,7 @@ public class PagedBytesReferenceTest extends ElasticsearchTestCase {
} }
public void testSliceToChannelBuffer() { public void testSliceToChannelBuffer() {
int length = randomIntBetween(10, PAGE_SIZE * randomIntBetween(2,8)); int length = randomIntBetween(10, PAGE_SIZE * randomIntBetween(2, 8));
BytesReference pbr = getRandomizedPagedBytesReference(length); BytesReference pbr = getRandomizedPagedBytesReference(length);
int sliceOffset = randomIntBetween(0, pbr.length()); int sliceOffset = randomIntBetween(0, pbr.length());
int sliceLength = randomIntBetween(pbr.length() - sliceOffset, pbr.length() - sliceOffset); int sliceLength = randomIntBetween(pbr.length() - sliceOffset, pbr.length() - sliceOffset);
@ -372,14 +396,14 @@ public class PagedBytesReferenceTest extends ElasticsearchTestCase {
} }
public void testHasArray() { public void testHasArray() {
int length = randomIntBetween(10, PAGE_SIZE * randomIntBetween(1,3)); int length = randomIntBetween(10, PAGE_SIZE * randomIntBetween(1, 3));
BytesReference pbr = getRandomizedPagedBytesReference(length); BytesReference pbr = getRandomizedPagedBytesReference(length);
// must return true for <= pagesize // must return true for <= pagesize
assertEquals(length <= PAGE_SIZE, pbr.hasArray()); assertEquals(length <= PAGE_SIZE, pbr.hasArray());
} }
public void testArray() { public void testArray() {
int[] sizes = {0, randomInt(PAGE_SIZE), PAGE_SIZE, randomIntBetween(2, PAGE_SIZE * randomIntBetween(2,5))}; int[] sizes = {0, randomInt(PAGE_SIZE), PAGE_SIZE, randomIntBetween(2, PAGE_SIZE * randomIntBetween(2, 5))};
for (int i = 0; i < sizes.length; i++) { for (int i = 0; i < sizes.length; i++) {
BytesReference pbr = getRandomizedPagedBytesReference(sizes[i]); BytesReference pbr = getRandomizedPagedBytesReference(sizes[i]);
@ -389,13 +413,11 @@ public class PagedBytesReferenceTest extends ElasticsearchTestCase {
assertNotNull(array); assertNotNull(array);
assertEquals(sizes[i], array.length); assertEquals(sizes[i], array.length);
assertSame(array, pbr.array()); assertSame(array, pbr.array());
} } else {
else {
try { try {
pbr.array(); pbr.array();
fail("expected IllegalStateException"); fail("expected IllegalStateException");
} } catch (IllegalStateException isx) {
catch (IllegalStateException isx) {
// expected // expected
} }
} }
@ -403,37 +425,33 @@ public class PagedBytesReferenceTest extends ElasticsearchTestCase {
} }
public void testArrayOffset() { public void testArrayOffset() {
int length = randomInt(PAGE_SIZE * randomIntBetween(2,5)); int length = randomInt(PAGE_SIZE * randomIntBetween(2, 5));
BytesReference pbr = getRandomizedPagedBytesReference(length); BytesReference pbr = getRandomizedPagedBytesReference(length);
if (pbr.hasArray()) { if (pbr.hasArray()) {
assertEquals(0, pbr.arrayOffset()); assertEquals(0, pbr.arrayOffset());
} } else {
else {
try { try {
pbr.arrayOffset(); pbr.arrayOffset();
fail("expected IllegalStateException"); fail("expected IllegalStateException");
} } catch (IllegalStateException ise) {
catch (IllegalStateException ise) {
// expected // expected
} }
} }
} }
public void testSliceArrayOffset() { public void testSliceArrayOffset() {
int length = randomInt(PAGE_SIZE * randomIntBetween(2,5)); int length = randomInt(PAGE_SIZE * randomIntBetween(2, 5));
BytesReference pbr = getRandomizedPagedBytesReference(length); BytesReference pbr = getRandomizedPagedBytesReference(length);
int sliceOffset = randomIntBetween(0, pbr.length()); int sliceOffset = randomIntBetween(0, pbr.length());
int sliceLength = randomIntBetween(pbr.length() - sliceOffset, pbr.length() - sliceOffset); int sliceLength = randomIntBetween(pbr.length() - sliceOffset, pbr.length() - sliceOffset);
BytesReference slice = pbr.slice(sliceOffset, sliceLength); BytesReference slice = pbr.slice(sliceOffset, sliceLength);
if (slice.hasArray()) { if (slice.hasArray()) {
assertEquals(sliceOffset, slice.arrayOffset()); assertEquals(sliceOffset, slice.arrayOffset());
} } else {
else {
try { try {
slice.arrayOffset(); slice.arrayOffset();
fail("expected IllegalStateException"); fail("expected IllegalStateException");
} } catch (IllegalStateException ise) {
catch (IllegalStateException ise) {
// expected // expected
} }
} }
@ -468,7 +486,7 @@ public class PagedBytesReferenceTest extends ElasticsearchTestCase {
} }
public void testCopyBytesRef() { public void testCopyBytesRef() {
int length = randomIntBetween(0, PAGE_SIZE * randomIntBetween(2,5)); int length = randomIntBetween(0, PAGE_SIZE * randomIntBetween(2, 5));
BytesReference pbr = getRandomizedPagedBytesReference(length); BytesReference pbr = getRandomizedPagedBytesReference(length);
BytesRef ref = pbr.copyBytesRef(); BytesRef ref = pbr.copyBytesRef();
assertNotNull(ref); assertNotNull(ref);
@ -481,7 +499,7 @@ public class PagedBytesReferenceTest extends ElasticsearchTestCase {
assertEquals(Arrays.hashCode(BytesRef.EMPTY_BYTES), pbr.hashCode()); assertEquals(Arrays.hashCode(BytesRef.EMPTY_BYTES), pbr.hashCode());
// test with content // test with content
pbr = getRandomizedPagedBytesReference(randomIntBetween(0, PAGE_SIZE * randomIntBetween(2,5))); pbr = getRandomizedPagedBytesReference(randomIntBetween(0, PAGE_SIZE * randomIntBetween(2, 5)));
int jdkHash = Arrays.hashCode(pbr.toBytes()); int jdkHash = Arrays.hashCode(pbr.toBytes());
int pbrHash = pbr.hashCode(); int pbrHash = pbr.hashCode();
assertEquals(jdkHash, pbrHash); assertEquals(jdkHash, pbrHash);
@ -496,7 +514,7 @@ public class PagedBytesReferenceTest extends ElasticsearchTestCase {
} }
public void testEquals() { public void testEquals() {
int length = randomIntBetween(100, PAGE_SIZE * randomIntBetween(2,5)); int length = randomIntBetween(100, PAGE_SIZE * randomIntBetween(2, 5));
ByteArray ba1 = bigarrays.newByteArray(length, false); ByteArray ba1 = bigarrays.newByteArray(length, false);
ByteArray ba2 = bigarrays.newByteArray(length, false); ByteArray ba2 = bigarrays.newByteArray(length, false);
@ -512,14 +530,14 @@ public class PagedBytesReferenceTest extends ElasticsearchTestCase {
} }
public void testEqualsPeerClass() { public void testEqualsPeerClass() {
int length = randomIntBetween(100, PAGE_SIZE * randomIntBetween(2,5)); int length = randomIntBetween(100, PAGE_SIZE * randomIntBetween(2, 5));
BytesReference pbr = getRandomizedPagedBytesReference(length); BytesReference pbr = getRandomizedPagedBytesReference(length);
BytesReference ba = new BytesArray(pbr.toBytes()); BytesReference ba = new BytesArray(pbr.toBytes());
assertEquals(pbr, ba); assertEquals(pbr, ba);
} }
public void testSliceEquals() { public void testSliceEquals() {
int length = randomIntBetween(100, PAGE_SIZE * randomIntBetween(2,5)); int length = randomIntBetween(100, PAGE_SIZE * randomIntBetween(2, 5));
ByteArray ba1 = bigarrays.newByteArray(length, false); ByteArray ba1 = bigarrays.newByteArray(length, false);
BytesReference pbr = new PagedBytesReference(bigarrays, ba1, length); BytesReference pbr = new PagedBytesReference(bigarrays, ba1, length);
@ -539,7 +557,20 @@ public class PagedBytesReferenceTest extends ElasticsearchTestCase {
} }
private BytesReference getRandomizedPagedBytesReference(int length) { private BytesReference getRandomizedPagedBytesReference(int length) {
return new PagedBytesReference(bigarrays, bigarrays.newByteArray(length, false), length); // we know bytes stream output always creates a paged bytes reference, we use it to create randomized content
ReleasableBytesStreamOutput out = new ReleasableBytesStreamOutput(length, bigarrays);
try {
for (int i = 0; i < length; i++) {
out.writeByte((byte) getRandom().nextInt(1 << 8));
}
} catch (IOException e) {
fail("should not happen " + e.getMessage());
}
assertThat(out.size(), Matchers.equalTo(length));
BytesReference ref = out.bytes();
assertThat(ref.length(), Matchers.equalTo(length));
assertThat(ref, Matchers.instanceOf(PagedBytesReference.class));
return ref;
} }
} }