Increase code coverage.
This commit is contained in:
parent
e28b54abed
commit
bdbc806e85
@ -74,6 +74,7 @@ dependencies {
|
|||||||
testCompile "org.junit.jupiter:junit-jupiter-engine:5.2.0"
|
testCompile "org.junit.jupiter:junit-jupiter-engine:5.2.0"
|
||||||
testCompile "org.junit.platform:junit-platform-launcher:1.2.0"
|
testCompile "org.junit.platform:junit-platform-launcher:1.2.0"
|
||||||
testCompile "commons-io:commons-io:2.6"
|
testCompile "commons-io:commons-io:2.6"
|
||||||
|
testCompile "org.mockito:mockito-core:2.21.0"
|
||||||
}
|
}
|
||||||
|
|
||||||
test {
|
test {
|
||||||
|
@ -37,11 +37,15 @@ public abstract class AbstractChronicleStore<I, O> implements FluxStore<I, O> {
|
|||||||
private final RollCycle rollCycle;
|
private final RollCycle rollCycle;
|
||||||
|
|
||||||
protected AbstractChronicleStore(AbstractChronicleStoreBuilder<I> builder) {
|
protected AbstractChronicleStore(AbstractChronicleStoreBuilder<I> builder) {
|
||||||
String path = builder.path;
|
|
||||||
serializer = builder.serializer;
|
serializer = builder.serializer;
|
||||||
deserializer = builder.deserializer;
|
deserializer = builder.deserializer;
|
||||||
rollCycle = builder.rollCycle;
|
rollCycle = builder.rollCycle;
|
||||||
this.queue = SingleChronicleQueueBuilder.binary(path).rollCycle(rollCycle).build();
|
this.queue = createQueue(builder.path);
|
||||||
|
}
|
||||||
|
|
||||||
|
//package private for testing
|
||||||
|
SingleChronicleQueue createQueue(String path) {
|
||||||
|
return SingleChronicleQueueBuilder.binary(path).rollCycle(rollCycle).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
void close() {
|
void close() {
|
||||||
@ -84,7 +88,8 @@ public abstract class AbstractChronicleStore<I, O> implements FluxStore<I, O> {
|
|||||||
try {
|
try {
|
||||||
while (!sink.isCancelled()) {
|
while (!sink.isCancelled()) {
|
||||||
if (sink.requestedFromDownstream() > 0) {
|
if (sink.requestedFromDownstream() > 0) {
|
||||||
boolean present = tailer.readBytes(b -> sink.next(deserializeValue(b)));
|
boolean present = tailer.readBytes(b ->
|
||||||
|
sink.next(deserializeValue(b)));
|
||||||
if (!present) {
|
if (!present) {
|
||||||
if (readerType == ReaderType.ONLY_HISTORY) {
|
if (readerType == ReaderType.ONLY_HISTORY) {
|
||||||
sink.complete();
|
sink.complete();
|
||||||
|
@ -0,0 +1,136 @@
|
|||||||
|
package ch.streamly.chronicle.flux;
|
||||||
|
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||||
|
import static org.mockito.ArgumentMatchers.anyInt;
|
||||||
|
import static org.mockito.ArgumentMatchers.anyLong;
|
||||||
|
import static org.mockito.Mockito.timeout;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.time.Duration;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.DisplayName;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.mockito.ArgumentCaptor;
|
||||||
|
import org.mockito.Mockito;
|
||||||
|
|
||||||
|
import ch.streamly.chronicle.flux.AbstractChronicleStore.AbstractChronicleStoreBuilder;
|
||||||
|
import net.openhft.chronicle.bytes.Bytes;
|
||||||
|
import net.openhft.chronicle.bytes.BytesIn;
|
||||||
|
import net.openhft.chronicle.bytes.ReadBytesMarshallable;
|
||||||
|
import net.openhft.chronicle.queue.ExcerptTailer;
|
||||||
|
import net.openhft.chronicle.queue.RollCycle;
|
||||||
|
import net.openhft.chronicle.queue.impl.WireStore;
|
||||||
|
import net.openhft.chronicle.queue.impl.single.SingleChronicleQueue;
|
||||||
|
import reactor.core.Disposable;
|
||||||
|
import reactor.test.StepVerifier;
|
||||||
|
|
||||||
|
class AbstractChronicleStoreTest {
|
||||||
|
|
||||||
|
private static final String TEST_VALUE = "testValue";
|
||||||
|
private AbstractChronicleStore<String, String> store;
|
||||||
|
|
||||||
|
private File file;
|
||||||
|
private SingleChronicleQueue queue;
|
||||||
|
private ArgumentCaptor<ReadBytesMarshallable> reader;
|
||||||
|
private ExcerptTailer tailer;
|
||||||
|
private WireStore wireStore;
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void setUp() {
|
||||||
|
|
||||||
|
RollCycle rollCycle = Mockito.mock(RollCycle.class);
|
||||||
|
file = Mockito.mock(File.class);
|
||||||
|
queue = Mockito.mock(SingleChronicleQueue.class);
|
||||||
|
reader = ArgumentCaptor.forClass(ReadBytesMarshallable.class);
|
||||||
|
tailer = Mockito.mock(ExcerptTailer.class);
|
||||||
|
wireStore = Mockito.mock(WireStore.class);
|
||||||
|
|
||||||
|
when(queue.createTailer()).thenReturn(tailer);
|
||||||
|
when(tailer.readBytes(any(ReadBytesMarshallable.class))).thenReturn(true);
|
||||||
|
when(tailer.queue()).thenReturn(queue);
|
||||||
|
when(queue.file()).thenReturn(file);
|
||||||
|
when(file.getAbsolutePath()).thenReturn("");
|
||||||
|
when(rollCycle.toCycle(anyLong())).thenReturn(0).thenReturn(1);
|
||||||
|
when(queue.storeForCycle(anyInt(), anyLong(), anyBoolean())).thenReturn(wireStore);
|
||||||
|
when(wireStore.file()).thenReturn(file);
|
||||||
|
when(file.delete()).thenReturn(true);
|
||||||
|
|
||||||
|
AbstractChronicleStoreBuilder<String> builder = new AbstractChronicleStoreBuilder<String>() {
|
||||||
|
};
|
||||||
|
builder.rollCycle(rollCycle);
|
||||||
|
|
||||||
|
store = new AbstractChronicleStore<String, String>(builder) {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
SingleChronicleQueue createQueue(String path) {
|
||||||
|
return queue;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String deserializeValue(BytesIn rawData) {
|
||||||
|
return TEST_VALUE;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("tests that the file is deleted once it has rolled")
|
||||||
|
void shouldDeleteAfterRead() {
|
||||||
|
Disposable sub = store.retrieveAll(true).subscribe();
|
||||||
|
verify(file, timeout(100)).delete();
|
||||||
|
sub.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("tests that the an exception on file deletion is swallowed")
|
||||||
|
void shouldSwallowExceptionOnFileDelete() {
|
||||||
|
when(file.delete()).thenThrow(new RuntimeException("Simulated for unit test"));
|
||||||
|
Disposable sub = store.retrieveAll(true).subscribe();
|
||||||
|
verify(file, timeout(100)).delete();
|
||||||
|
sub.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("tests that failure of file deletion does not send an exception")
|
||||||
|
void shouldNotFailIfFileNotDeleted() {
|
||||||
|
when(file.delete()).thenReturn(false);
|
||||||
|
Disposable sub = store.retrieveAll(true).subscribe();
|
||||||
|
verify(file, timeout(100)).delete();
|
||||||
|
sub.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("tests that a null wirestore throws no exception")
|
||||||
|
void testNullWirestore() {
|
||||||
|
when(queue.storeForCycle(anyInt(), anyLong(), anyBoolean())).thenReturn(null);
|
||||||
|
subscribeToValues();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void subscribeToValues() {
|
||||||
|
StepVerifier.create(store.retrieveAll(true))
|
||||||
|
.expectSubscription()
|
||||||
|
.then(() -> {
|
||||||
|
verify(tailer, timeout(100).atLeastOnce()).readBytes(reader.capture());
|
||||||
|
reader.getValue().readMarshallable(Bytes.elasticByteBuffer());
|
||||||
|
reader.getValue().readMarshallable(Bytes.elasticByteBuffer());
|
||||||
|
reader.getValue().readMarshallable(Bytes.elasticByteBuffer());
|
||||||
|
})
|
||||||
|
.expectNext(TEST_VALUE)
|
||||||
|
.expectNext(TEST_VALUE)
|
||||||
|
.expectNext(TEST_VALUE)
|
||||||
|
.thenCancel()
|
||||||
|
.verify(Duration.ofMillis(500));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("tests that a null file throws no exception")
|
||||||
|
void testNullFile() {
|
||||||
|
when(queue.storeForCycle(anyInt(), anyLong(), anyBoolean())).thenReturn(wireStore);
|
||||||
|
when(wireStore.file()).thenReturn(null);
|
||||||
|
subscribeToValues();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1 @@
|
|||||||
|
mock-maker-inline
|
Loading…
Reference in New Issue
Block a user