use of io.pravega.segmentstore.contracts.SegmentProperties in project pravega by pravega.
the class StreamSegmentContainerTests method checkStorage.
private static void checkStorage(HashMap<String, ByteArrayOutputStream> segmentContents, HashMap<String, Long> lengths, TestContext context) {
for (String segmentName : segmentContents.keySet()) {
// 1. Deletion status
SegmentProperties sp = null;
try {
sp = context.container.getStreamSegmentInfo(segmentName, false, TIMEOUT).join();
} catch (Exception ex) {
if (!(Exceptions.unwrap(ex) instanceof StreamSegmentNotExistsException)) {
throw ex;
}
}
if (sp == null) {
Assert.assertFalse("Segment is marked as deleted in metadata but was not deleted in Storage " + segmentName, context.storage.exists(segmentName, TIMEOUT).join());
// No need to do other checks.
continue;
}
// 2. Seal Status
SegmentProperties storageProps = context.storage.getStreamSegmentInfo(segmentName, TIMEOUT).join();
Assert.assertEquals("Segment seal status disagree between Metadata and Storage for segment " + segmentName, sp.isSealed(), storageProps.isSealed());
// 3. Contents.
long expectedLength = lengths.get(segmentName);
Assert.assertEquals("Unexpected Storage length for segment " + segmentName, expectedLength, storageProps.getLength());
byte[] expectedData = segmentContents.get(segmentName).toByteArray();
byte[] actualData = new byte[expectedData.length];
val readHandle = context.storage.openRead(segmentName).join();
int actualLength = context.storage.read(readHandle, 0, actualData, 0, actualData.length, TIMEOUT).join();
Assert.assertEquals("Unexpected number of bytes read from Storage for segment " + segmentName, expectedLength, actualLength);
Assert.assertArrayEquals("Unexpected data written to storage for segment " + segmentName, expectedData, actualData);
}
}
use of io.pravega.segmentstore.contracts.SegmentProperties in project pravega by pravega.
the class StreamSegmentContainerTests method waitForSegmentsInStorage.
private CompletableFuture<Void> waitForSegmentsInStorage(Collection<String> segmentNames, TestContext context) {
ArrayList<CompletableFuture<Void>> segmentsCompletion = new ArrayList<>();
for (String segmentName : segmentNames) {
SegmentProperties sp = context.container.getStreamSegmentInfo(segmentName, false, TIMEOUT).join();
segmentsCompletion.add(waitForSegmentInStorage(sp, context));
}
return Futures.allOf(segmentsCompletion);
}
use of io.pravega.segmentstore.contracts.SegmentProperties in project pravega by pravega.
the class StreamSegmentContainerTests method tryActivate.
/**
* Attempts to activate the targetSegment in the given Container. Since we do not have access to the internals of the
* Container, we need to trigger this somehow, hence the need for this complex code. We need to trigger a truncation,
* so we need an 'appendSegment' to which we continuously append so that the DurableDataLog is truncated. After truncation,
* the Metadata should have enough leeway in making room for new activation.
*
* @return A Future that will complete either with an exception (failure) or SegmentProperties for the targetSegment.
*/
private CompletableFuture<SegmentProperties> tryActivate(MetadataCleanupContainer localContainer, String targetSegment, String appendSegment) {
CompletableFuture<SegmentProperties> successfulMap = new CompletableFuture<>();
// Append continuously to an existing segment in order to trigger truncations (these are necessary for forced evictions).
val appendFuture = localContainer.appendRandomly(appendSegment, false, () -> !successfulMap.isDone());
Futures.exceptionListener(appendFuture, successfulMap::completeExceptionally);
// Repeatedly try to get info on 'segment1' (activate it), until we succeed or time out.
TimeoutTimer remaining = new TimeoutTimer(TIMEOUT);
Futures.loop(() -> !successfulMap.isDone(), () -> Futures.delayedFuture(Duration.ofMillis(250), executorService()).thenCompose(v -> localContainer.getStreamSegmentInfo(targetSegment, false, TIMEOUT)).thenAccept(successfulMap::complete).exceptionally(ex -> {
if (!(Exceptions.unwrap(ex) instanceof TooManyActiveSegmentsException)) {
// Some other error.
successfulMap.completeExceptionally(ex);
} else if (!remaining.hasRemaining()) {
// Waited too long.
successfulMap.completeExceptionally(new TimeoutException("No successful activation could be done in the allotted time."));
}
// Try again.
return null;
}), executorService());
return successfulMap;
}
use of io.pravega.segmentstore.contracts.SegmentProperties in project pravega by pravega.
the class StreamSegmentContainerTests method checkActiveSegments.
private void checkActiveSegments(SegmentContainer container, int expectedCount) {
val initialActiveSegments = container.getActiveSegments();
Assert.assertEquals("Unexpected result from getActiveSegments with freshly created segments.", expectedCount, initialActiveSegments.size());
for (SegmentProperties sp : initialActiveSegments) {
val expectedSp = container.getStreamSegmentInfo(sp.getName(), false, TIMEOUT).join();
Assert.assertEquals("Unexpected length (from getActiveSegments) for segment " + sp.getName(), expectedSp.getLength(), sp.getLength());
Assert.assertEquals("Unexpected sealed (from getActiveSegments) for segment " + sp.getName(), expectedSp.isSealed(), sp.isSealed());
Assert.assertEquals("Unexpected deleted (from getActiveSegments) for segment " + sp.getName(), expectedSp.isDeleted(), sp.isDeleted());
SegmentMetadataComparer.assertSameAttributes("Unexpected attributes (from getActiveSegments) for segment " + sp.getName(), expectedSp.getAttributes(), sp);
}
}
use of io.pravega.segmentstore.contracts.SegmentProperties in project pravega by pravega.
the class StreamSegmentContainerTests method testSegmentDelete.
/**
* Tests the ability to delete StreamSegments.
*/
@Test
public void testSegmentDelete() throws Exception {
final int appendsPerSegment = 1;
@Cleanup TestContext context = new TestContext();
context.container.startAsync().awaitRunning();
// 1. Create the StreamSegments.
ArrayList<String> segmentNames = createSegments(context);
HashMap<String, ArrayList<String>> transactionsBySegment = createTransactions(segmentNames, context);
// 2. Add some appends.
ArrayList<CompletableFuture<Void>> appendFutures = new ArrayList<>();
for (int i = 0; i < appendsPerSegment; i++) {
for (String segmentName : segmentNames) {
appendFutures.add(context.container.append(segmentName, getAppendData(segmentName, i), null, TIMEOUT));
for (String transactionName : transactionsBySegment.get(segmentName)) {
appendFutures.add(context.container.append(transactionName, getAppendData(transactionName, i), null, TIMEOUT));
}
}
}
Futures.allOf(appendFutures).get(TIMEOUT.toMillis(), TimeUnit.MILLISECONDS);
// 3. Delete the first half of the segments.
ArrayList<CompletableFuture<Void>> deleteFutures = new ArrayList<>();
for (int i = 0; i < segmentNames.size() / 2; i++) {
String segmentName = segmentNames.get(i);
deleteFutures.add(context.container.deleteStreamSegment(segmentName, TIMEOUT));
}
Futures.allOf(deleteFutures).get(TIMEOUT.toMillis(), TimeUnit.MILLISECONDS);
// 4. Verify that only the first half of the segments (and their Transactions) were deleted, and not the others.
for (int i = 0; i < segmentNames.size(); i++) {
ArrayList<String> toCheck = new ArrayList<>();
toCheck.add(segmentNames.get(i));
toCheck.addAll(transactionsBySegment.get(segmentNames.get(i)));
boolean expectedDeleted = i < segmentNames.size() / 2;
if (expectedDeleted) {
// Verify the segments and their Transactions are not there anymore.
for (String sn : toCheck) {
AssertExtensions.assertThrows("getStreamSegmentInfo did not throw expected exception when called on a deleted StreamSegment.", context.container.getStreamSegmentInfo(sn, false, TIMEOUT)::join, ex -> ex instanceof StreamSegmentNotExistsException);
AssertExtensions.assertThrows("append did not throw expected exception when called on a deleted StreamSegment.", context.container.append(sn, "foo".getBytes(), null, TIMEOUT)::join, ex -> ex instanceof StreamSegmentNotExistsException);
AssertExtensions.assertThrows("read did not throw expected exception when called on a deleted StreamSegment.", context.container.read(sn, 0, 1, TIMEOUT)::join, ex -> ex instanceof StreamSegmentNotExistsException);
Assert.assertFalse("Segment not deleted in storage.", context.storage.exists(sn, TIMEOUT).join());
}
} else {
// Verify the segments and their Transactions are still there.
for (String sn : toCheck) {
SegmentProperties props = context.container.getStreamSegmentInfo(sn, false, TIMEOUT).join();
Assert.assertFalse("Not-deleted segment (or one of its Transactions) was marked as deleted in metadata.", props.isDeleted());
// Verify we can still append and read from this segment.
context.container.append(sn, "foo".getBytes(), null, TIMEOUT).join();
@Cleanup ReadResult rr = context.container.read(sn, 0, 1, TIMEOUT).join();
// Verify the segment still exists in storage.
context.storage.getStreamSegmentInfo(sn, TIMEOUT).join();
}
}
}
context.container.stopAsync().awaitTerminated();
}
Aggregations