use of io.pravega.segmentstore.contracts.StreamSegmentNotExistsException in project pravega by pravega.
the class RollingStorage method getHeaderInfo.
private SegmentProperties getHeaderInfo(String segmentName) throws StreamSegmentException {
String headerSegment = StreamSegmentNameUtils.getHeaderSegmentName(segmentName);
val headerInfo = this.baseStorage.getStreamSegmentInfo(headerSegment);
if (headerInfo.getLength() == 0) {
// We treat empty header files as inexistent segments.
throw new StreamSegmentNotExistsException(segmentName);
}
return headerInfo;
}
use of io.pravega.segmentstore.contracts.StreamSegmentNotExistsException in project pravega by pravega.
the class StorageTestBase method testConcat.
/**
* Tests the concat() method.
*
* @throws Exception if an unexpected error occurred.
*/
@Test
public void testConcat() throws Exception {
final String context = "Concat";
try (Storage s = createStorage()) {
s.initialize(DEFAULT_EPOCH);
HashMap<String, ByteArrayOutputStream> appendData = populate(s, context);
// Check invalid segment name.
val firstSegmentName = getSegmentName(0, context);
val firstSegmentHandle = s.openWrite(firstSegmentName).join();
val sealedSegmentName = "SealedSegment";
createSegment(sealedSegmentName, s);
val sealedSegmentHandle = s.openWrite(sealedSegmentName).join();
s.write(sealedSegmentHandle, 0, new ByteArrayInputStream(new byte[1]), 1, TIMEOUT).join();
s.seal(sealedSegmentHandle, TIMEOUT).join();
AtomicLong firstSegmentLength = new AtomicLong(s.getStreamSegmentInfo(firstSegmentName, TIMEOUT).join().getLength());
assertThrows("concat() did not throw for non-existent target segment name.", () -> s.concat(createInexistentSegmentHandle(s, false), 0, sealedSegmentName, TIMEOUT), ex -> ex instanceof StreamSegmentNotExistsException);
assertThrows("concat() did not throw for invalid source StreamSegment name.", () -> s.concat(firstSegmentHandle, firstSegmentLength.get(), "foo2", TIMEOUT), ex -> ex instanceof StreamSegmentNotExistsException);
ArrayList<String> concatOrder = new ArrayList<>();
concatOrder.add(firstSegmentName);
for (String sourceSegment : appendData.keySet()) {
if (sourceSegment.equals(firstSegmentName)) {
// FirstSegment is where we'll be concatenating to.
continue;
}
assertThrows("Concat allowed when source segment is not sealed.", () -> s.concat(firstSegmentHandle, firstSegmentLength.get(), sourceSegment, TIMEOUT), ex -> ex instanceof IllegalStateException);
// Seal the source segment and then re-try the concat
val sourceWriteHandle = s.openWrite(sourceSegment).join();
s.seal(sourceWriteHandle, TIMEOUT).join();
SegmentProperties preConcatTargetProps = s.getStreamSegmentInfo(firstSegmentName, TIMEOUT).join();
SegmentProperties sourceProps = s.getStreamSegmentInfo(sourceSegment, TIMEOUT).join();
s.concat(firstSegmentHandle, firstSegmentLength.get(), sourceSegment, TIMEOUT).join();
concatOrder.add(sourceSegment);
SegmentProperties postConcatTargetProps = s.getStreamSegmentInfo(firstSegmentName, TIMEOUT).join();
Assert.assertFalse("concat() did not delete source segment", s.exists(sourceSegment, TIMEOUT).join());
// Only check lengths here; we'll check the contents at the end.
Assert.assertEquals("Unexpected target StreamSegment.length after concatenation.", preConcatTargetProps.getLength() + sourceProps.getLength(), postConcatTargetProps.getLength());
firstSegmentLength.set(postConcatTargetProps.getLength());
}
// Check the contents of the first StreamSegment. We already validated that the length is correct.
SegmentProperties segmentProperties = s.getStreamSegmentInfo(firstSegmentName, TIMEOUT).join();
byte[] readBuffer = new byte[(int) segmentProperties.getLength()];
// Read the entire StreamSegment.
int bytesRead = s.read(firstSegmentHandle, 0, readBuffer, 0, readBuffer.length, TIMEOUT).join();
Assert.assertEquals("Unexpected number of bytes read.", readBuffer.length, bytesRead);
// Check, concat-by-concat, that the final data is correct.
int offset = 0;
for (String segmentName : concatOrder) {
byte[] concatData = appendData.get(segmentName).toByteArray();
AssertExtensions.assertArrayEquals("Unexpected concat data.", concatData, 0, readBuffer, offset, concatData.length);
offset += concatData.length;
}
Assert.assertEquals("Concat included more bytes than expected.", offset, readBuffer.length);
}
}
use of io.pravega.segmentstore.contracts.StreamSegmentNotExistsException in project pravega by pravega.
the class StorageTestBase method testSeal.
/**
* Tests the seal() method.
*
* @throws Exception if an unexpected error occurred.
*/
@Test
public void testSeal() throws Exception {
final String context = "Seal";
try (Storage s = createStorage()) {
s.initialize(DEFAULT_EPOCH);
// Check segment not exists.
assertThrows("seal() did not throw for non-existent segment name.", () -> s.seal(createInexistentSegmentHandle(s, false), TIMEOUT), ex -> ex instanceof StreamSegmentNotExistsException);
HashMap<String, ByteArrayOutputStream> appendData = populate(s, context);
int deleteCount = 0;
for (String segmentName : appendData.keySet()) {
val readHandle = s.openRead(segmentName).join();
assertThrows("seal() did not throw for read-only handle.", () -> s.seal(readHandle, TIMEOUT), ex -> ex instanceof IllegalArgumentException);
val writeHandle = s.openWrite(segmentName).join();
s.seal(writeHandle, TIMEOUT).join();
// Seal is idempotent. Resealing an already sealed segment should work.
s.seal(writeHandle, TIMEOUT).join();
assertThrows("write() did not throw for a sealed StreamSegment.", () -> s.write(writeHandle, s.getStreamSegmentInfo(segmentName, TIMEOUT).join().getLength(), new ByteArrayInputStream("g".getBytes()), 1, TIMEOUT), ex -> ex instanceof StreamSegmentSealedException);
// Check post-delete seal. Half of the segments use the existing handle, and half will re-acquire it.
// We want to reacquire it because OpenWrite will return a read-only handle for sealed segments.
boolean reacquireHandle = (deleteCount++) % 2 == 0;
SegmentHandle deleteHandle = writeHandle;
if (reacquireHandle) {
deleteHandle = s.openWrite(segmentName).join();
}
s.delete(deleteHandle, TIMEOUT).join();
assertThrows("seal() did not throw for a deleted StreamSegment.", () -> s.seal(writeHandle, TIMEOUT), ex -> ex instanceof StreamSegmentNotExistsException);
}
}
}
use of io.pravega.segmentstore.contracts.StreamSegmentNotExistsException in project pravega by pravega.
the class StorageTestBase method testRead.
/**
* Tests the read() method.
*
* @throws Exception if an unexpected error occurred.
*/
@Test
public void testRead() throws Exception {
final String context = "Read";
try (Storage s = createStorage()) {
s.initialize(DEFAULT_EPOCH);
// Check invalid segment name.
assertThrows("read() did not throw for invalid segment name.", () -> s.read(createInexistentSegmentHandle(s, true), 0, new byte[1], 0, 1, TIMEOUT), ex -> ex instanceof StreamSegmentNotExistsException);
HashMap<String, ByteArrayOutputStream> appendData = populate(s, context);
// Do some reading.
for (Entry<String, ByteArrayOutputStream> entry : appendData.entrySet()) {
String segmentName = entry.getKey();
val readHandle = s.openRead(segmentName).join();
byte[] expectedData = entry.getValue().toByteArray();
for (int offset = 0; offset < expectedData.length / 2; offset++) {
int length = expectedData.length - 2 * offset;
byte[] readBuffer = new byte[length];
int bytesRead = s.read(readHandle, offset, readBuffer, 0, readBuffer.length, TIMEOUT).join();
Assert.assertEquals(String.format("Unexpected number of bytes read from offset %d.", offset), length, bytesRead);
AssertExtensions.assertArrayEquals(String.format("Unexpected read result from offset %d.", offset), expectedData, offset, readBuffer, 0, bytesRead);
}
}
// Test bad parameters.
val testSegment = getSegmentName(0, context);
val testSegmentHandle = s.openRead(testSegment).join();
byte[] testReadBuffer = new byte[10];
assertThrows("read() allowed reading with negative read offset.", () -> s.read(testSegmentHandle, -1, testReadBuffer, 0, testReadBuffer.length, TIMEOUT), ex -> ex instanceof IllegalArgumentException || ex instanceof ArrayIndexOutOfBoundsException);
assertThrows("read() allowed reading with offset beyond Segment length.", () -> s.read(testSegmentHandle, s.getStreamSegmentInfo(testSegment, TIMEOUT).join().getLength() + 1, testReadBuffer, 0, testReadBuffer.length, TIMEOUT), ex -> ex instanceof IllegalArgumentException || ex instanceof ArrayIndexOutOfBoundsException);
assertThrows("read() allowed reading with negative read buffer offset.", () -> s.read(testSegmentHandle, 0, testReadBuffer, -1, testReadBuffer.length, TIMEOUT), ex -> ex instanceof IllegalArgumentException || ex instanceof ArrayIndexOutOfBoundsException);
assertThrows("read() allowed reading with invalid read buffer length.", () -> s.read(testSegmentHandle, 0, testReadBuffer, 1, testReadBuffer.length, TIMEOUT), ex -> ex instanceof IllegalArgumentException || ex instanceof ArrayIndexOutOfBoundsException);
assertThrows("read() allowed reading with invalid read length.", () -> s.read(testSegmentHandle, 0, testReadBuffer, 0, testReadBuffer.length + 1, TIMEOUT), ex -> ex instanceof IllegalArgumentException || ex instanceof ArrayIndexOutOfBoundsException);
// Check post-delete read.
s.delete(s.openWrite(testSegment).join(), TIMEOUT).join();
assertThrows("read() did not throw for a deleted StreamSegment.", () -> s.read(testSegmentHandle, 0, new byte[1], 0, 1, TIMEOUT), ex -> ex instanceof StreamSegmentNotExistsException);
}
}
use of io.pravega.segmentstore.contracts.StreamSegmentNotExistsException in project pravega by pravega.
the class StreamSegmentMapperTests method testGetStreamSegmentInfo.
/**
* Tests GetStreamSegmentInfo with various scenarios.
*/
@Test
public void testGetStreamSegmentInfo() {
final String segmentName = "segment";
final long segmentId = 1;
@Cleanup TestContext context = new TestContext();
HashSet<String> storageSegments = new HashSet<>();
// Segment not exists in Metadata or Storage.
setupStorageGetHandler(context, storageSegments, sn -> {
throw new CompletionException(new StreamSegmentNotExistsException(sn));
});
setSavedState(segmentName, segmentId, 0, ATTRIBUTE_COUNT, context);
val segmentState = context.stateStore.get(segmentName, TIMEOUT).join();
Map<UUID, Long> expectedAttributes = segmentState == null ? null : segmentState.getAttributes();
AssertExtensions.assertThrows("getStreamSegmentInfo did not throw correct exception when segment does not exist in Metadata or Storage.", () -> context.mapper.getStreamSegmentInfo(segmentName, TIMEOUT), ex -> ex instanceof StreamSegmentNotExistsException);
// Segment does not exist in Metadata, but does so in Storage.
// Since we do not setup an OperationLog, we guarantee that there is no attempt to map this in the metadata.
val segmentInfo = StreamSegmentInformation.builder().name(segmentName).length(123).sealed(true).build();
storageSegments.add(segmentName);
setupStorageGetHandler(context, storageSegments, sn -> segmentInfo);
val inStorageInfo = context.mapper.getStreamSegmentInfo(segmentName, TIMEOUT).join();
assertEquals("Unexpected SegmentInfo when Segment exists in Storage.", segmentInfo, inStorageInfo);
SegmentMetadataComparer.assertSameAttributes("Unexpected attributes when Segment exists in Storage", expectedAttributes, inStorageInfo);
Assert.assertEquals("Not expecting any segments to be mapped.", 0, context.metadata.getAllStreamSegmentIds().size());
// Segment exists in Metadata (and in Storage too) - here, we set different values in the Metadata to verify that
// the info is fetched from there.
val sm = context.metadata.mapStreamSegmentId(segmentName, segmentId);
sm.setLength(segmentInfo.getLength() + 1);
sm.updateAttributes(Collections.singletonMap(UUID.randomUUID(), 12345L));
val inMetadataInfo = context.mapper.getStreamSegmentInfo(segmentName, TIMEOUT).join();
assertEquals("Unexpected SegmentInfo when Segment exists in Metadata.", sm, inMetadataInfo);
SegmentMetadataComparer.assertSameAttributes("Unexpected attributes when Segment exists in Metadata.", sm.getAttributes(), inMetadataInfo);
// Segment exists in Metadata, but is marked as deleted.
sm.markDeleted();
AssertExtensions.assertThrows("getStreamSegmentInfo did not throw correct exception when segment is marked as Deleted in metadata.", () -> context.mapper.getStreamSegmentInfo(segmentName, TIMEOUT), ex -> ex instanceof StreamSegmentNotExistsException);
}
Aggregations