use of io.pravega.segmentstore.storage.StorageNotPrimaryException in project pravega by pravega.
the class ChunkedSegmentStorageTests method testTruncateWithFailover.
@Test
public void testTruncateWithFailover() throws Exception {
@Cleanup CleanupHelper cleanupHelper = new CleanupHelper();
String testSegmentName = "foo";
val config = ChunkedSegmentStorageConfig.DEFAULT_CONFIG.toBuilder().garbageCollectionDelay(Duration.ZERO).indexBlockSize(3).build();
TestContext testContext = getTestContext(config);
cleanupHelper.add(testContext);
// Create
testContext.chunkedSegmentStorage.create(testSegmentName, null).get();
// Write some data.
long offset = 0;
int i = 2;
long epoch = testContext.chunkedSegmentStorage.getEpoch();
SegmentHandle hWrite = testContext.chunkedSegmentStorage.openWrite(testSegmentName).get();
// Create a new test context and initialize with new epoch.
testContext.chunkedSegmentStorage.write(hWrite, offset, new ByteArrayInputStream(new byte[i]), i, null).join();
TestUtils.checkSegmentBounds(testContext.metadataStore, testSegmentName, offset, offset + i);
TestUtils.checkReadIndexEntries(testContext.chunkedSegmentStorage, testContext.metadataStore, testSegmentName, offset, offset + i, true);
checkDataRead(testSegmentName, testContext, offset, i);
offset += i;
// Fork the context.
testContext = testContext.fork(++epoch);
cleanupHelper.add(testContext);
val oldTestCotext = testContext;
val newTestContext = oldTestCotext.fork(++epoch);
cleanupHelper.add(newTestContext);
// Fence out old store.
oldTestCotext.metadataStore.markFenced();
// Truncate and Read in new epoch.
// Make sure to open segment with new instance before writing garbage to old instance.
hWrite = newTestContext.chunkedSegmentStorage.openWrite(testSegmentName).get();
newTestContext.chunkedSegmentStorage.truncate(hWrite, offset, null).get();
TestUtils.checkSegmentBounds(newTestContext.metadataStore, testSegmentName, offset, offset);
TestUtils.checkReadIndexEntries(newTestContext.chunkedSegmentStorage, newTestContext.metadataStore, testSegmentName, offset, offset, false);
AssertExtensions.assertFutureThrows("openWrite() allowed after fencing", oldTestCotext.chunkedSegmentStorage.openWrite(testSegmentName), ex -> ex instanceof StorageNotPrimaryException);
AssertExtensions.assertFutureThrows("openRead() allowed after fencing", oldTestCotext.chunkedSegmentStorage.openRead(testSegmentName), ex -> ex instanceof StorageNotPrimaryException);
}
use of io.pravega.segmentstore.storage.StorageNotPrimaryException in project pravega by pravega.
the class ChunkedSegmentStorageTests method testReadWriteWithMultipleFailoversWithGarbage.
/**
* Test read and write with multiple failovers.
*
* @throws Exception Exception if any.
*/
@Test
public void testReadWriteWithMultipleFailoversWithGarbage() throws Exception {
@Cleanup CleanupHelper cleanupHelper = new CleanupHelper();
String testSegmentName = "foo";
@Cleanup TestContext testContext = getTestContext();
cleanupHelper.add(testContext);
// Create
testContext.chunkedSegmentStorage.create(testSegmentName, null).get();
// Write some data.
long writeAt = 0;
long epoch = CONTAINER_ID;
SegmentHandle hWrite = testContext.chunkedSegmentStorage.openWrite(testSegmentName).get();
ArrayList<Long> lengths = new ArrayList<>();
for (int i = 1; i < 5; i++) {
// Create a new test context and initialize with new epoch.
testContext.chunkedSegmentStorage.write(hWrite, writeAt, new ByteArrayInputStream(new byte[i]), i, null).join();
writeAt += i;
lengths.add((long) i);
// Read in same epoch.
checkDataRead(testSegmentName, testContext, 0, writeAt);
val lengthsArray = Longs.toArray(lengths);
TestUtils.checkSegmentLayout(testContext.metadataStore, testSegmentName, lengthsArray);
TestUtils.checkReadIndexEntries(testContext.chunkedSegmentStorage, testContext.metadataStore, testSegmentName, 0, Arrays.stream(lengthsArray).sum(), false);
// Fork the context.
val oldTestCotext = testContext;
testContext = oldTestCotext.fork(epoch++);
cleanupHelper.add(testContext);
TestUtils.checkSegmentLayout(testContext.metadataStore, testSegmentName, Longs.toArray(lengths));
// Make sure to open segment with new instance before writing garbage to old instance.
hWrite = testContext.chunkedSegmentStorage.openWrite(testSegmentName).get();
// Write some garbage
oldTestCotext.chunkedSegmentStorage.write(hWrite, writeAt, new ByteArrayInputStream(new byte[10]), 10, null).join();
// Fence out old store.
oldTestCotext.metadataStore.markFenced();
AssertExtensions.assertFutureThrows("write() allowed after fencing", oldTestCotext.chunkedSegmentStorage.write(hWrite, writeAt + 10, new ByteArrayInputStream(new byte[10]), 10, null), ex -> ex instanceof StorageNotPrimaryException);
// Read in new epoch.
checkDataRead(testSegmentName, testContext, 0, writeAt);
}
int total = 10;
// Create a new test context and initialize with new epoch.
testContext = testContext.fork(epoch++);
cleanupHelper.add(testContext);
checkDataRead(testSegmentName, testContext, 0, total);
}
use of io.pravega.segmentstore.storage.StorageNotPrimaryException in project pravega by pravega.
the class ChunkedSegmentStorageTests method testStorageNotPrimaryException.
/**
* Test scenarios when storage is no more primary.
*/
@Test
public void testStorageNotPrimaryException() throws Exception {
String testSegmentName = "foo";
@Cleanup TestContext testContext = getTestContext();
testContext.chunkedSegmentStorage.initialize(2);
int maxRollingLength = 1;
int ownerEpoch = OWNER_EPOCH;
testContext.insertMetadata(testSegmentName, maxRollingLength, ownerEpoch);
// These operations should always succeed.
testContext.chunkedSegmentStorage.getStreamSegmentInfo(testSegmentName, null).join();
val h = testContext.chunkedSegmentStorage.openRead(testSegmentName).join();
testContext.chunkedSegmentStorage.read(h, 0, new byte[0], 0, 0, null);
// These operations should never succeed.
AssertExtensions.assertFutureThrows("Seal succeeded on segment not owned.", testContext.chunkedSegmentStorage.seal(SegmentStorageHandle.writeHandle(testSegmentName), null), ex -> ex instanceof StorageNotPrimaryException);
AssertExtensions.assertFutureThrows("openWrite succeeded on segment not owned.", testContext.chunkedSegmentStorage.openWrite(testSegmentName), ex -> ex instanceof StorageNotPrimaryException);
AssertExtensions.assertFutureThrows("delete succeeded on segment not owned.", testContext.chunkedSegmentStorage.delete(SegmentStorageHandle.writeHandle(testSegmentName), null), ex -> ex instanceof StorageNotPrimaryException);
AssertExtensions.assertFutureThrows("write succeeded on segment not owned.", testContext.chunkedSegmentStorage.write(SegmentStorageHandle.writeHandle(testSegmentName), 0, new ByteArrayInputStream(new byte[10]), 10, null), ex -> ex instanceof StorageNotPrimaryException);
AssertExtensions.assertFutureThrows("truncate succeeded on segment not owned.", testContext.chunkedSegmentStorage.truncate(SegmentStorageHandle.writeHandle(testSegmentName), 0, null), ex -> ex instanceof StorageNotPrimaryException);
testContext.insertMetadata("source", maxRollingLength, 1);
testContext.chunkedSegmentStorage.seal(SegmentStorageHandle.writeHandle("source"), null).join();
AssertExtensions.assertFutureThrows("concat succeeded on segment not owned.", testContext.chunkedSegmentStorage.concat(SegmentStorageHandle.writeHandle(testSegmentName), 0, "source", null), ex -> ex instanceof StorageNotPrimaryException);
}
use of io.pravega.segmentstore.storage.StorageNotPrimaryException in project pravega by pravega.
the class RollingStorage method updateHandle.
private void updateHandle(RollingSegmentHandle handle, byte[] data) throws StreamSegmentException {
try {
this.headerStorage.write(handle.getHeaderHandle(), handle.getHeaderLength(), new ByteArrayInputStream(data), data.length);
handle.increaseHeaderLength(data.length);
log.debug("Header for '{}' updated with {} bytes for a length of {}.", handle.getSegmentName(), data.length, handle.getHeaderLength());
} catch (BadOffsetException ex) {
// If we get BadOffsetException when writing the Handle, it means it was modified externally.
throw new StorageNotPrimaryException(handle.getSegmentName(), ex);
}
}
Aggregations