use of io.pravega.common.TimeoutTimer in project pravega by pravega.
the class TableBucketReaderTests method testFindKey.
/**
* Tests the ability to locate Table Keys in a Table Bucket using {@link TableBucketReader#key}.
*/
@Test
public void testFindKey() throws Exception {
val segment = new SegmentMock(executorService());
// Generate our test data and append it to the segment.
val data = generateData();
segment.append(new ByteArraySegment(data.serialization), null, TIMEOUT).join();
val reader = TableBucketReader.key(segment, (s, offset, timeout) -> CompletableFuture.completedFuture(data.getBackpointer(offset)), executorService());
// Check a valid result.
val validKey = data.entries.get(1).getKey();
val validResult = reader.find(validKey.getKey(), data.getBucketOffset(), new TimeoutTimer(TIMEOUT)).get(TIMEOUT.toMillis(), TimeUnit.MILLISECONDS);
Assert.assertEquals("Unexpected version from valid key.", data.getEntryOffset(1), validResult.getVersion());
Assert.assertEquals("Unexpected 'valid' key returned.", validKey.getKey(), validResult.getKey());
// Check a key that does not exist.
val invalidKey = data.unlinkedEntry.getKey();
val invalidResult = reader.find(invalidKey.getKey(), data.getBucketOffset(), new TimeoutTimer(TIMEOUT)).get(TIMEOUT.toMillis(), TimeUnit.MILLISECONDS);
Assert.assertNull("Not expecting any result for key that does not exist.", invalidResult);
}
use of io.pravega.common.TimeoutTimer in project pravega by pravega.
the class AsyncTableEntryReaderTests method testReadEntryResultTooShort.
/**
* Tests the ability to handle a case where the key could not be read before the read result was done.
*/
@Test
public void testReadEntryResultTooShort() {
val testItems = generateTestItems();
for (val e : testItems) {
// Start a new reader & processor for this key-serialization pair.
val entryReader = AsyncTableEntryReader.readEntry(new ByteArraySegment(e.key), 0L, SERIALIZER, new TimeoutTimer(TIMEOUT));
@Cleanup val rr = new ReadResultMock(e.serialization, e.serialization.length - 1, 1);
AsyncReadResultProcessor.process(rr, entryReader, executorService());
AssertExtensions.assertThrows("Unexpected behavior for shorter read result..", () -> entryReader.getResult().get(BASE_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS), ex -> ex instanceof SerializationException);
}
}
use of io.pravega.common.TimeoutTimer in project pravega by pravega.
the class AsyncTableEntryReaderTests method testReadEmptyKey.
/**
* Tests the ability to read an empty key (this should result in an exception).
*/
@Test
public void testReadEmptyKey() {
val testItem = generateTestItem(new byte[0], new byte[0], false, false);
// Start a new reader & processor for this key-serialization pair.
val keyReader = AsyncTableEntryReader.readKey(1L, SERIALIZER, new TimeoutTimer(TIMEOUT));
@Cleanup val rr = new ReadResultMock(testItem.serialization, testItem.serialization.length, 1);
AsyncReadResultProcessor.process(rr, keyReader, executorService());
AssertExtensions.assertThrows("Unexpected behavior for empty key.", () -> keyReader.getResult().get(BASE_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS), ex -> ex instanceof SerializationException);
// When the result is done, whether with error or not, this should be set to 0.
Assert.assertEquals("Unexpected final suggested read length.", 0, keyReader.getMaxReadAtOnce());
}
use of io.pravega.common.TimeoutTimer in project pravega by pravega.
the class AsyncTableEntryReaderTests method testReadEntry.
// endregion
// region Reading Entries
/**
* Tests the ability to read a Table Entry for a matching key.
*/
@Test
public void testReadEntry() throws Exception {
long keyVersion = 1L;
val testItems = generateTestItems();
for (val item : testItems) {
// Start a new reader & processor for this key-serialization pair.
val entryReader = AsyncTableEntryReader.readEntry(new ByteArraySegment(item.key), keyVersion, SERIALIZER, new TimeoutTimer(TIMEOUT));
Assert.assertEquals("Unexpected initial suggested read length.", AsyncTableEntryReader.INITIAL_READ_LENGTH, entryReader.getMaxReadAtOnce());
@Cleanup val rr = new ReadResultMock(item.serialization, item.serialization.length, 1);
AsyncReadResultProcessor.process(rr, entryReader, executorService());
Assert.assertEquals(Math.min(rr.getMaxResultLength(), entryReader.getMaxReadAtOnce()), rr.getMaxReadAtOnce());
val result = entryReader.getResult().get(BASE_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
Assert.assertNotNull("Expecting a result.", result);
Assert.assertEquals("Unexpected suggested read length after reading whole entry.", 0, entryReader.getMaxReadAtOnce());
// Check key.
val resultKey = result.getKey().getKey();
Assert.assertEquals("Unexpected result key length.", item.key.length, resultKey.getLength());
Assert.assertEquals("Unexpected result key.", new ByteArraySegment(item.key), resultKey);
if (item.isRemoval) {
// Verify there is no value and that the key has been properly set.
Assert.assertEquals("Unexpected key version for non existing key.", TableKey.NOT_EXISTS, result.getKey().getVersion());
Assert.assertNull("Not expecting a value for a removal.", result.getValue());
} else {
// Verify we have a value and that it matches.
if (item.explicitVersion == TableKey.NO_VERSION) {
Assert.assertEquals("Unexpected key version for existing key.", keyVersion, result.getKey().getVersion());
} else {
Assert.assertEquals("Unexpected (explicit) key version for existing key.", item.explicitVersion, result.getKey().getVersion());
}
Assert.assertNotNull("Expecting a value for non removal.", result.getValue());
val resultValue = result.getValue();
Assert.assertEquals("Unexpected value length.", item.value.length, resultValue.getLength());
Assert.assertEquals("Unexpected result value", new ByteArraySegment(item.value), resultValue);
}
keyVersion++;
}
}
use of io.pravega.common.TimeoutTimer in project pravega by pravega.
the class SegmentAggregator method flushNormally.
/**
* Repeatedly flushes the contents of the Aggregator to the Storage as long as something immediate needs to be flushed,
* such as a Seal or Merge operation.
*
* @param force Whether to force everything out.
* @param timer Timer for the operation.
* @return A CompletableFuture that, when completed, will contain the result from the flush operation.
*/
private CompletableFuture<WriterFlushResult> flushNormally(boolean force, TimeoutTimer timer) {
assert this.state.get() == AggregatorState.Writing : "flushNormally cannot be called if state == " + this.state;
long traceId = LoggerHelpers.traceEnterWithContext(log, this.traceObjectId, "flushNormally", force, this.operations.size());
WriterFlushResult result = new WriterFlushResult();
AtomicBoolean canContinue = new AtomicBoolean(true);
return Futures.loop(canContinue::get, () -> flushOnce(force, timer), partialResult -> {
canContinue.set(partialResult.getFlushedBytes() + partialResult.getMergedBytes() > 0);
result.withFlushResult(partialResult);
}, this.executor).thenApply(v -> {
LoggerHelpers.traceLeave(log, this.traceObjectId, "flushNormally", traceId, result);
return result;
});
}
Aggregations