use of io.pravega.segmentstore.contracts.BadOffsetException in project pravega by pravega.
the class IdempotentStorageTestBase method testParallelWriteTwoHosts.
// endregion
// region synchronization unit tests
/**
* This test case simulates two hosts writing at the same offset at the same time.
*/
@Test(timeout = 30000)
public void testParallelWriteTwoHosts() {
String segmentName = "foo_write";
int appendCount = 5;
try (Storage s1 = createStorage();
Storage s2 = createStorage()) {
s1.initialize(DEFAULT_EPOCH);
s1.create(segmentName, TIMEOUT).join();
SegmentHandle writeHandle1 = s1.openWrite(segmentName).join();
SegmentHandle writeHandle2 = s2.openWrite(segmentName).join();
long offset = 0;
byte[] writeData = String.format("Segment_%s_Append", segmentName).getBytes();
for (int j = 0; j < appendCount; j++) {
ByteArrayInputStream dataStream1 = new ByteArrayInputStream(writeData);
ByteArrayInputStream dataStream2 = new ByteArrayInputStream(writeData);
CompletableFuture f1 = s1.write(writeHandle1, offset, dataStream1, writeData.length, TIMEOUT);
CompletableFuture f2 = s2.write(writeHandle2, offset, dataStream2, writeData.length, TIMEOUT);
assertMayThrow("Write expected to complete OR throw BadOffsetException." + "threw an unexpected exception.", () -> CompletableFuture.allOf(f1, f2), ex -> ex instanceof BadOffsetException);
// Make sure at least one operation is success.
Assert.assertTrue("At least one of the two parallel writes should succeed.", !f1.isCompletedExceptionally() || !f2.isCompletedExceptionally());
offset += writeData.length;
}
Assert.assertTrue("Writes at the same offset are expected to be idempotent.", s1.getStreamSegmentInfo(segmentName, TIMEOUT).join().getLength() == offset);
offset = 0;
byte[] readBuffer = new byte[writeData.length];
for (int j = 0; j < appendCount; j++) {
int bytesRead = s1.read(writeHandle1, j * readBuffer.length, readBuffer, 0, readBuffer.length, TIMEOUT).join();
Assert.assertEquals(String.format("Unexpected number of bytes read from offset %d.", offset), readBuffer.length, bytesRead);
AssertExtensions.assertArrayEquals(String.format("Unexpected read result from offset %d.", offset), readBuffer, 0, readBuffer, 0, bytesRead);
}
s1.delete(writeHandle1, TIMEOUT).join();
}
}
use of io.pravega.segmentstore.contracts.BadOffsetException in project pravega by pravega.
the class IdempotentStorageTestBase method testWrite.
/**
* Tests the write() method.
*
* @throws Exception if an unexpected error occurred.
*/
@Override
@Test(timeout = 30000)
public void testWrite() throws Exception {
String segmentName = "foo_write";
int appendCount = 100;
try (Storage s = createStorage()) {
s.initialize(DEFAULT_EPOCH);
s.create(segmentName, TIMEOUT).join();
// Invalid handle.
val readOnlyHandle = s.openRead(segmentName).join();
assertThrows("write() did not throw for read-only handle.", () -> s.write(readOnlyHandle, 0, new ByteArrayInputStream("h".getBytes()), 1, TIMEOUT), ex -> ex instanceof IllegalArgumentException);
assertThrows("write() did not throw for handle pointing to inexistent segment.", () -> s.write(createInexistentSegmentHandle(s, false), 0, new ByteArrayInputStream("h".getBytes()), 1, TIMEOUT), ex -> ex instanceof StreamSegmentNotExistsException);
val writeHandle = s.openWrite(segmentName).join();
long offset = 0;
for (int j = 0; j < appendCount; j++) {
byte[] writeData = String.format("Segment_%s_Append_%d", segmentName, j).getBytes();
ByteArrayInputStream dataStream = new ByteArrayInputStream(writeData);
s.write(writeHandle, offset, dataStream, writeData.length, TIMEOUT).join();
offset += writeData.length;
}
// Check bad offset.
final long finalOffset = offset;
assertThrows("write() did not throw bad offset write (larger).", () -> s.write(writeHandle, finalOffset + 1, new ByteArrayInputStream("h".getBytes()), 1, TIMEOUT), ex -> ex instanceof BadOffsetException);
// Check post-delete write.
s.delete(writeHandle, TIMEOUT).join();
assertThrows("write() did not throw for a deleted StreamSegment.", () -> s.write(writeHandle, 0, new ByteArrayInputStream(new byte[1]), 1, TIMEOUT), ex -> ex instanceof StreamSegmentNotExistsException);
}
}
use of io.pravega.segmentstore.contracts.BadOffsetException in project pravega by pravega.
the class FileSystemStorageTest method testWrite.
// region Write tests with metrics checks
/**
* Tests the write() method.
*
* @throws Exception if an unexpected error occurred.
*/
@Override
@Test(timeout = 30000)
public void testWrite() throws Exception {
String segmentName = "foo_write";
int appendCount = 100;
try (Storage s = createStorage()) {
s.initialize(DEFAULT_EPOCH);
s.create(segmentName, TIMEOUT).join();
long expectedMetricsSize = FileSystemMetrics.WRITE_BYTES.get();
long expectedMetricsSuccesses = FileSystemMetrics.WRITE_LATENCY.toOpStatsData().getNumSuccessfulEvents();
// Invalid handle.
val readOnlyHandle = s.openRead(segmentName).join();
assertThrows("write() did not throw for read-only handle.", () -> s.write(readOnlyHandle, 0, new ByteArrayInputStream("h".getBytes()), 1, TIMEOUT), ex -> ex instanceof IllegalArgumentException);
assertThrows("write() did not throw for handle pointing to inexistent segment.", () -> s.write(createInexistentSegmentHandle(s, false), 0, new ByteArrayInputStream("h".getBytes()), 1, TIMEOUT), ex -> ex instanceof StreamSegmentNotExistsException);
Assert.assertEquals("WRITE_BYTES should not change in case of unsuccessful writes", expectedMetricsSize, FileSystemMetrics.WRITE_BYTES.get());
Assert.assertEquals("WRITE_LATENCY should not increase the count of successful events in case of unsuccessful writes", expectedMetricsSuccesses, FileSystemMetrics.WRITE_LATENCY.toOpStatsData().getNumSuccessfulEvents());
val writeHandle = s.openWrite(segmentName).join();
long offset = 0;
for (int j = 0; j < appendCount; j++) {
byte[] writeData = String.format("Segment_%s_Append_%d", segmentName, j).getBytes();
ByteArrayInputStream dataStream = new ByteArrayInputStream(writeData);
s.write(writeHandle, offset, dataStream, writeData.length, TIMEOUT).join();
expectedMetricsSize += writeData.length;
expectedMetricsSuccesses += 1;
Assert.assertEquals("WRITE_LATENCY should increase the count of successful events in case of successful writes", expectedMetricsSuccesses, FileSystemMetrics.WRITE_LATENCY.toOpStatsData().getNumSuccessfulEvents());
Assert.assertEquals("WRITE_BYTES should increase by the size of successful writes", expectedMetricsSize, FileSystemMetrics.WRITE_BYTES.get());
offset += writeData.length;
}
// Check bad offset.
final long finalOffset = offset;
assertThrows("write() did not throw bad offset write (larger).", () -> s.write(writeHandle, finalOffset + 1, new ByteArrayInputStream("h".getBytes()), 1, TIMEOUT), ex -> ex instanceof BadOffsetException);
Assert.assertEquals("WRITE_BYTES should not change in case of unsuccessful writes", expectedMetricsSize, FileSystemMetrics.WRITE_BYTES.get());
Assert.assertEquals("WRITE_LATENCY should not increase the count of successful events in case of unsuccessful writes", expectedMetricsSuccesses, FileSystemMetrics.WRITE_LATENCY.toOpStatsData().getNumSuccessfulEvents());
// Check post-delete write.
s.delete(writeHandle, TIMEOUT).join();
assertThrows("write() did not throw for a deleted StreamSegment.", () -> s.write(writeHandle, 0, new ByteArrayInputStream(new byte[1]), 1, TIMEOUT), ex -> ex instanceof StreamSegmentNotExistsException);
Assert.assertEquals("WRITE_BYTES should not change in case of unsuccessful writes", expectedMetricsSize, FileSystemMetrics.WRITE_BYTES.get());
Assert.assertEquals("WRITE_LATENCY should not increase the count of successful events in case of unsuccessful writes", expectedMetricsSuccesses, FileSystemMetrics.WRITE_LATENCY.toOpStatsData().getNumSuccessfulEvents());
}
}
use of io.pravega.segmentstore.contracts.BadOffsetException in project pravega by pravega.
the class ConcatOperationTests method testInvalidInput.
/**
* Tests various combinations of bad input to the Concat command.
*/
@Test
public void testInvalidInput() throws Exception {
@Cleanup val fs = new MockFileSystem();
val context = newContext(1, fs);
val targetHandle = createNonEmptySegment(TARGET_SEGMENT, context, null);
val sourceHandle = createNonEmptySegment(SOURCE_SEGMENT, context, null);
// Same source and target.
AssertExtensions.assertThrows("ConcatOperation worked with same source and target.", () -> new ConcatOperation(targetHandle, WRITE_LENGTH, TARGET_SEGMENT, context).run(), ex -> ex instanceof IllegalArgumentException);
// Verify source is not sealed.
AssertExtensions.assertThrows("ConcatOperation worked on non-sealed source segment.", new ConcatOperation(targetHandle, WRITE_LENGTH, SOURCE_SEGMENT, context)::run, ex -> ex instanceof IllegalStateException);
// Seal it.
new SealOperation(sourceHandle, context).run();
// Verify target offset.
AssertExtensions.assertThrows("ConcatOperation worked with bad offset.", new ConcatOperation(targetHandle, WRITE_LENGTH - 1, SOURCE_SEGMENT, context)::run, ex -> ex instanceof BadOffsetException);
// Verify target is sealed.
new SealOperation(targetHandle, context).run();
AssertExtensions.assertThrows("ConcatOperation worked with sealed target.", new ConcatOperation(targetHandle, WRITE_LENGTH, SOURCE_SEGMENT, context)::run, ex -> ex instanceof AclException);
}
use of io.pravega.segmentstore.contracts.BadOffsetException in project pravega by pravega.
the class RollingStorage method serializeHandle.
private void serializeHandle(RollingSegmentHandle handle) throws StreamSegmentException {
ByteArraySegment handleData = HandleSerializer.serialize(handle);
try {
this.baseStorage.write(handle.getHeaderHandle(), 0, handleData.getReader(), handleData.getLength());
handle.setHeaderLength(handleData.getLength());
log.debug("Header for '{}' fully serialized to '{}'.", handle.getSegmentName(), handle.getHeaderHandle().getSegmentName());
} catch (BadOffsetException ex) {
// If we get BadOffsetException when writing the Handle, it means it was modified externally.
throw new StorageNotPrimaryException(handle.getSegmentName(), ex);
}
}
Aggregations