Search in sources :

Example 26 with StreamSegmentNotExistsException

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;
}
Also used : lombok.val(lombok.val) StreamSegmentNotExistsException(io.pravega.segmentstore.contracts.StreamSegmentNotExistsException)

Example 27 with StreamSegmentNotExistsException

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);
    }
}
Also used : lombok.val(lombok.val) ArrayList(java.util.ArrayList) ByteArrayOutputStream(java.io.ByteArrayOutputStream) StreamSegmentNotExistsException(io.pravega.segmentstore.contracts.StreamSegmentNotExistsException) AtomicLong(java.util.concurrent.atomic.AtomicLong) ByteArrayInputStream(java.io.ByteArrayInputStream) SegmentProperties(io.pravega.segmentstore.contracts.SegmentProperties) Test(org.junit.Test)

Example 28 with StreamSegmentNotExistsException

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);
        }
    }
}
Also used : lombok.val(lombok.val) ByteArrayInputStream(java.io.ByteArrayInputStream) StreamSegmentSealedException(io.pravega.segmentstore.contracts.StreamSegmentSealedException) ByteArrayOutputStream(java.io.ByteArrayOutputStream) StreamSegmentNotExistsException(io.pravega.segmentstore.contracts.StreamSegmentNotExistsException) Test(org.junit.Test)

Example 29 with 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);
    }
}
Also used : lombok.val(lombok.val) ByteArrayOutputStream(java.io.ByteArrayOutputStream) StreamSegmentNotExistsException(io.pravega.segmentstore.contracts.StreamSegmentNotExistsException) Test(org.junit.Test)

Example 30 with 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);
}
Also used : lombok.val(lombok.val) CompletionException(java.util.concurrent.CompletionException) AtomicLong(java.util.concurrent.atomic.AtomicLong) UUID(java.util.UUID) Cleanup(lombok.Cleanup) StreamSegmentNotExistsException(io.pravega.segmentstore.contracts.StreamSegmentNotExistsException) HashSet(java.util.HashSet) Test(org.junit.Test)

Aggregations

StreamSegmentNotExistsException (io.pravega.segmentstore.contracts.StreamSegmentNotExistsException)51 lombok.val (lombok.val)27 Test (org.junit.Test)22 Cleanup (lombok.Cleanup)15 SegmentProperties (io.pravega.segmentstore.contracts.SegmentProperties)12 Storage (io.pravega.segmentstore.storage.Storage)11 SegmentMetadata (io.pravega.segmentstore.server.SegmentMetadata)10 StreamSegmentSealedException (io.pravega.segmentstore.contracts.StreamSegmentSealedException)9 ByteArrayInputStream (java.io.ByteArrayInputStream)9 Duration (java.time.Duration)8 ArrayList (java.util.ArrayList)8 CompletionException (java.util.concurrent.CompletionException)8 BadOffsetException (io.pravega.segmentstore.contracts.BadOffsetException)7 ReadResult (io.pravega.segmentstore.contracts.ReadResult)7 StreamSegmentAppendOperation (io.pravega.segmentstore.server.logs.operations.StreamSegmentAppendOperation)7 UUID (java.util.UUID)7 AtomicLong (java.util.concurrent.atomic.AtomicLong)7 Futures (io.pravega.common.concurrent.Futures)6 MergeTransactionOperation (io.pravega.segmentstore.server.logs.operations.MergeTransactionOperation)6 ByteArrayOutputStream (java.io.ByteArrayOutputStream)6