package rocks.inspectit.shared.all.storage.nio.stream;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.Random;
import org.mockito.Matchers;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import rocks.inspectit.shared.all.storage.nio.ByteBufferProvider;
/**
* Tests the {@link ExtendedByteBufferOutputStream}.
*
* @author Ivan Senic
*
*/
@SuppressWarnings("PMD")
public class ExtendedByteBufferOutputStreamTest {
/**
* Size of buffers {@link ByteBufferProvider} will return.
*/
private final int bufferSize = 1024;
/**
* Mocked {@link ByteBufferProvider}.
*/
@Mock
private ByteBufferProvider byteBufferProvider;
/**
* To be tested.
*/
private ExtendedByteBufferOutputStream extendedByteBufferOutputStream;
/**
* Init mocks.
*/
@BeforeMethod
public void init() throws IOException {
MockitoAnnotations.initMocks(this);
Mockito.when(byteBufferProvider.acquireByteBuffer()).thenAnswer(new Answer<ByteBuffer>() {
@Override
public ByteBuffer answer(InvocationOnMock invocation) throws Throwable {
return ByteBuffer.allocate(bufferSize);
}
});
extendedByteBufferOutputStream = new ExtendedByteBufferOutputStream();
extendedByteBufferOutputStream.byteBufferProvider = byteBufferProvider;
extendedByteBufferOutputStream.prepare();
}
/**
* Test the write of the write can fit into one buffer.
*
* @throws IOException
* If {@link IOException} occurs.
*/
@Test(invocationCount = 5)
public void writeLessThanBufferSize() throws IOException {
Random random = new Random();
int writeCount = random.nextInt(bufferSize);
byte[] array = new byte[writeCount];
random.nextBytes(array);
extendedByteBufferOutputStream.write(array);
assertThat(extendedByteBufferOutputStream.getTotalWriteSize(), is((long) writeCount));
extendedByteBufferOutputStream.flush(false);
assertThat(extendedByteBufferOutputStream.getTotalWriteSize(), is((long) writeCount));
Mockito.verify(byteBufferProvider, Mockito.times(1)).acquireByteBuffer();
assertThat(extendedByteBufferOutputStream.getBuffersCount(), is(equalTo(1)));
ByteBuffer buffer = extendedByteBufferOutputStream.getAllByteBuffers().get(0);
byte[] actual = new byte[buffer.limit() - buffer.position()];
buffer.get(actual);
assertThat(actual, is(equalTo(array)));
extendedByteBufferOutputStream.close();
Mockito.verify(byteBufferProvider, Mockito.times(1)).releaseByteBuffer((ByteBuffer) Matchers.any());
}
/**
* Test the write of the write can fit into one buffer.
*
* @throws IOException
* If {@link IOException} occurs.
*/
@Test(invocationCount = 5)
public void writeMoreThanBufferSize() throws IOException {
Random random = new Random();
int writeCount = random.nextInt(bufferSize * 5);
byte[] array = new byte[writeCount];
random.nextBytes(array);
int buffersUsed = writeCount / bufferSize;
if ((writeCount % bufferSize) > 0) {
buffersUsed++;
}
extendedByteBufferOutputStream.write(array);
assertThat(extendedByteBufferOutputStream.getTotalWriteSize(), is((long) writeCount));
extendedByteBufferOutputStream.flush(false);
assertThat(extendedByteBufferOutputStream.getTotalWriteSize(), is((long) writeCount));
Mockito.verify(byteBufferProvider, Mockito.times(buffersUsed)).acquireByteBuffer();
assertThat(extendedByteBufferOutputStream.getBuffersCount(), is(equalTo(buffersUsed)));
byte[] actual = new byte[writeCount];
int position = 0;
for (ByteBuffer byteBuffer : extendedByteBufferOutputStream.getAllByteBuffers()) {
int length = byteBuffer.limit() - byteBuffer.position();
byteBuffer.get(actual, position, length);
position += length;
}
assertThat(actual, is(equalTo(array)));
extendedByteBufferOutputStream.close();
Mockito.verify(byteBufferProvider, Mockito.times(buffersUsed)).releaseByteBuffer((ByteBuffer) Matchers.any());
}
}