Search in sources :

Example 6 with UpdateableContainerMetadata

use of io.pravega.segmentstore.server.UpdateableContainerMetadata in project pravega by pravega.

the class ContainerMetadataUpdateTransactionTests method testPreProcessStreamSegmentSeal.

// endregion
// region StreamSegmentSealOperation
/**
 * Tests the preProcess method with StreamSegmentSeal operations.
 * Scenarios:
 * * Recovery Mode
 * * Non-recovery mode
 * * StreamSegment is Merged (both in-transaction and in-metadata)
 * * StreamSegment is Sealed (both in-transaction and in-metadata)
 */
@Test
public void testPreProcessStreamSegmentSeal() throws Exception {
    UpdateableContainerMetadata metadata = createMetadata();
    StreamSegmentSealOperation sealOp = createSeal();
    // When everything is OK (in recovery mode) - nothing should change.
    metadata.enterRecoveryMode();
    val txn1 = createUpdateTransaction(metadata);
    txn1.preProcessOperation(sealOp);
    AssertExtensions.assertLessThan("Unexpected StreamSegmentLength after call to preProcess in recovery mode.", 0, sealOp.getStreamSegmentOffset());
    checkNoSequenceNumberAssigned(sealOp, "call to preProcess in recovery mode");
    Assert.assertFalse("preProcess(Seal) seems to have changed the Updater internal state in recovery mode.", txn1.getStreamSegmentMetadata(SEGMENT_ID).isSealed());
    Assert.assertFalse("preProcess(Seal) seems to have changed the metadata in recovery mode.", metadata.getStreamSegmentMetadata(SEGMENT_ID).isSealed());
    // When everything is OK (no recovery mode).
    metadata.exitRecoveryMode();
    val txn2 = createUpdateTransaction(metadata);
    txn2.preProcessOperation(sealOp);
    Assert.assertEquals("Unexpected StreamSegmentLength after call to preProcess in non-recovery mode.", SEGMENT_LENGTH, sealOp.getStreamSegmentOffset());
    checkNoSequenceNumberAssigned(sealOp, "call to preProcess in non-recovery mode");
    Assert.assertFalse("preProcess(Seal) seems to have changed the Updater internal state.", txn2.getStreamSegmentMetadata(SEGMENT_ID).isSealed());
    Assert.assertFalse("preProcess(Seal) seems to have changed the metadata.", metadata.getStreamSegmentMetadata(SEGMENT_ID).isSealed());
    // When StreamSegment is merged (via transaction).
    StreamSegmentSealOperation transactionSealOp = new StreamSegmentSealOperation(SEALED_TRANSACTION_ID);
    MergeTransactionOperation mergeOp = createMerge();
    txn2.preProcessOperation(mergeOp);
    txn2.acceptOperation(mergeOp);
    Assert.assertFalse("Transaction should not be merged in metadata (yet).", metadata.getStreamSegmentMetadata(SEALED_TRANSACTION_ID).isMerged());
    AssertExtensions.assertThrows("Unexpected behavior for preProcess(Seal) when Segment is merged (in transaction).", () -> txn2.preProcessOperation(transactionSealOp), ex -> ex instanceof StreamSegmentMergedException);
    // When StreamSegment is merged (via metadata).
    txn2.commit(metadata);
    Assert.assertTrue("Transaction should have been merged in metadata.", metadata.getStreamSegmentMetadata(SEALED_TRANSACTION_ID).isMerged());
    AssertExtensions.assertThrows("Unexpected behavior for preProcess(Seal) when Segment is merged (in metadata).", () -> txn2.preProcessOperation(transactionSealOp), ex -> ex instanceof StreamSegmentMergedException);
    // When StreamSegment is sealed (via transaction).
    txn2.acceptOperation(sealOp);
    Assert.assertFalse("StreamSegment should not be sealed in metadata (yet).", metadata.getStreamSegmentMetadata(SEGMENT_ID).isSealed());
    AssertExtensions.assertThrows("Unexpected behavior for preProcess(Seal) when Segment is sealed (in transaction).", () -> txn2.preProcessOperation(createSeal()), ex -> ex instanceof StreamSegmentSealedException);
    // When StreamSegment is sealed (via metadata).
    txn2.commit(metadata);
    Assert.assertTrue("StreamSegment should have been sealed in metadata.", metadata.getStreamSegmentMetadata(SEGMENT_ID).isSealed());
    AssertExtensions.assertThrows("Unexpected behavior for preProcess(Seal) when Segment is sealed (in metadata).", () -> txn2.preProcessOperation(createSeal()), ex -> ex instanceof StreamSegmentSealedException);
}
Also used : lombok.val(lombok.val) StreamSegmentSealOperation(io.pravega.segmentstore.server.logs.operations.StreamSegmentSealOperation) StreamSegmentSealedException(io.pravega.segmentstore.contracts.StreamSegmentSealedException) UpdateableContainerMetadata(io.pravega.segmentstore.server.UpdateableContainerMetadata) StreamSegmentMergedException(io.pravega.segmentstore.contracts.StreamSegmentMergedException) MergeTransactionOperation(io.pravega.segmentstore.server.logs.operations.MergeTransactionOperation) Test(org.junit.Test)

Example 7 with UpdateableContainerMetadata

use of io.pravega.segmentstore.server.UpdateableContainerMetadata in project pravega by pravega.

the class ContainerMetadataUpdateTransactionTests method testGetActiveSegmentCount.

/**
 * Tests the correctness of getActiveSegmentCount(), especially in the case when the real ContainerMetadata has
 * changed its value.
 */
@Test
public void testGetActiveSegmentCount() throws Exception {
    // Create a base metadata and make sure it has one active segment.
    UpdateableContainerMetadata metadata = createMetadata();
    int expected = 3;
    Assert.assertEquals("Unexpected initial Active Segment Count for base metadata.", expected, metadata.getActiveSegmentCount());
    // Create an UpdateTransaction for it and map a new segment.
    val txn1 = new ContainerMetadataUpdateTransaction(metadata, metadata, 0);
    Assert.assertEquals("Unexpected Active Segment Count for first transaction.", expected, txn1.getActiveSegmentCount());
    val map1 = createMap("NewSegment1");
    txn1.preProcessOperation(map1);
    map1.setSequenceNumber(metadata.nextOperationSequenceNumber());
    txn1.acceptOperation(map1);
    expected++;
    Assert.assertEquals("Unexpected Active Segment Count for first transaction after map.", expected, txn1.getActiveSegmentCount());
    // Create a second UpdateTransaction for it and map a new segment.
    val txn2 = new ContainerMetadataUpdateTransaction(txn1, metadata, 0);
    Assert.assertEquals("Unexpected Active Segment Count for second transaction.", expected, txn2.getActiveSegmentCount());
    val map2 = createMap("NewSegment2");
    txn2.preProcessOperation(map2);
    map2.setSequenceNumber(metadata.nextOperationSequenceNumber());
    txn2.acceptOperation(map2);
    expected++;
    Assert.assertEquals("Unexpected Active Segment Count for first transaction after map.", expected, txn2.getActiveSegmentCount());
    // Clean up base metadata - simplest way to deactivate segments (even if this will cause a TxnCommit to fail,
    // but we don't test that here).
    metadata.enterRecoveryMode();
    metadata.reset();
    metadata.exitRecoveryMode();
    expected = 0;
    // Check Active Segment Count after the cleanup.
    Assert.assertEquals("Unexpected Active Segment Count for base metadata after cleanup.", expected, metadata.getActiveSegmentCount());
    Assert.assertEquals("Unexpected Active Segment Count for first transaction after cleanup.", expected + 1, txn1.getActiveSegmentCount());
    Assert.assertEquals("Unexpected Active Segment Count for second transaction after cleanup.", expected + 2, txn2.getActiveSegmentCount());
}
Also used : lombok.val(lombok.val) UpdateableContainerMetadata(io.pravega.segmentstore.server.UpdateableContainerMetadata) Test(org.junit.Test)

Example 8 with UpdateableContainerMetadata

use of io.pravega.segmentstore.server.UpdateableContainerMetadata in project pravega by pravega.

the class ContainerMetadataUpdateTransactionTests method testPreProcessStreamSegmentTruncate.

// endregion
// region StreamSegmentTruncate
/**
 * Tests the preProcess method with StreamSegmentTruncate operations.
 * Scenarios:
 * * Recovery Mode
 * * Non-recovery mode
 * * Invalid states or arguments (Segment not sealed, bad offsets, Transaction Segment).
 */
@Test
public void testPreProcessStreamSegmentTruncate() throws Exception {
    final UpdateableContainerMetadata metadata = createMetadata();
    // When trying to truncate beyond last offset.
    val txn = createUpdateTransaction(metadata);
    AssertExtensions.assertThrows("preProcess did not throw when offset is too large.", () -> txn.preProcessOperation(createTruncate(SEGMENT_LENGTH + 1)), ex -> ex instanceof BadOffsetException);
    // Actually truncate the segment, and re-verify bounds.
    val op1 = createTruncate(SEGMENT_LENGTH / 2);
    txn.preProcessOperation(op1);
    txn.acceptOperation(op1);
    txn.commit(metadata);
    AssertExtensions.assertThrows("preProcess did not throw when offset is too small (on truncated segment).", () -> txn.preProcessOperation(createTruncate(op1.getStreamSegmentOffset() - 1)), ex -> ex instanceof BadOffsetException);
    AssertExtensions.assertThrows("preProcess did not throw when offset is too large (on truncated segment).", () -> txn.preProcessOperation(createTruncate(SEGMENT_LENGTH + 1)), ex -> ex instanceof BadOffsetException);
    // For a transaction
    AssertExtensions.assertThrows("preProcess did not throw for a Transaction Segment.", () -> txn.preProcessOperation(new StreamSegmentTruncateOperation(SEALED_TRANSACTION_ID, SEALED_TRANSACTION_LENGTH / 2)), ex -> ex instanceof MetadataUpdateException);
    // Now verify that a valid offset does work (not throwing means the test passes).
    txn.preProcessOperation(createTruncate(op1.getStreamSegmentOffset()));
    txn.preProcessOperation(createTruncate(op1.getStreamSegmentOffset() + 1));
    txn.preProcessOperation(createTruncate(SEGMENT_LENGTH));
}
Also used : lombok.val(lombok.val) StreamSegmentTruncateOperation(io.pravega.segmentstore.server.logs.operations.StreamSegmentTruncateOperation) BadOffsetException(io.pravega.segmentstore.contracts.BadOffsetException) UpdateableContainerMetadata(io.pravega.segmentstore.server.UpdateableContainerMetadata) Test(org.junit.Test)

Example 9 with UpdateableContainerMetadata

use of io.pravega.segmentstore.server.UpdateableContainerMetadata in project pravega by pravega.

the class ContainerMetadataUpdateTransactionTests method testStreamSegmentAppendWithOffset.

/**
 * Tests the ability of the ContainerMetadataUpdateTransaction to process (and accept) StreamSegmentAppendOperations with
 * predefined offsets.
 */
@Test
public void testStreamSegmentAppendWithOffset() throws Exception {
    UpdateableContainerMetadata metadata = createMetadata();
    val txn = createUpdateTransaction(metadata);
    // Append #1 (at offset 0).
    long offset = metadata.getStreamSegmentMetadata(SEGMENT_ID).getLength();
    StreamSegmentAppendOperation appendOp = createAppendWithOffset(offset);
    txn.preProcessOperation(appendOp);
    Assert.assertEquals("Unexpected StreamSegmentOffset after call to preProcess in non-recovery mode.", offset, appendOp.getStreamSegmentOffset());
    checkNoSequenceNumberAssigned(appendOp, "call to preProcess in non-recovery mode");
    Assert.assertEquals("preProcess(Append) seems to have changed the Updater internal state.", offset, txn.getStreamSegmentMetadata(SEGMENT_ID).getLength());
    Assert.assertEquals("preProcess(Append) seems to have changed the metadata.", offset, metadata.getStreamSegmentMetadata(SEGMENT_ID).getLength());
    txn.acceptOperation(appendOp);
    // Append #2 (after Append #1)
    offset = appendOp.getStreamSegmentOffset() + appendOp.getLength();
    appendOp = createAppendWithOffset(offset);
    txn.preProcessOperation(appendOp);
    Assert.assertEquals("Unexpected StreamSegmentOffset after call to preProcess in non-recovery mode.", offset, appendOp.getStreamSegmentOffset());
    checkNoSequenceNumberAssigned(appendOp, "call to preProcess in non-recovery mode");
    Assert.assertEquals("preProcess(Append) seems to have changed the Updater internal state.", offset, txn.getStreamSegmentMetadata(SEGMENT_ID).getLength());
    Assert.assertEquals("preProcess(Append) seems to have changed the metadata.", SEGMENT_LENGTH, metadata.getStreamSegmentMetadata(SEGMENT_ID).getLength());
    txn.acceptOperation(appendOp);
    // Append #3 (wrong offset)
    offset = appendOp.getStreamSegmentOffset() + appendOp.getLength() - 1;
    StreamSegmentAppendOperation badAppendOp = createAppendWithOffset(offset);
    AssertExtensions.assertThrows("preProcessOperations accepted an append with the wrong offset.", () -> txn.preProcessOperation(badAppendOp), ex -> ex instanceof BadOffsetException);
    AssertExtensions.assertThrows("acceptOperation accepted an append that was rejected during preProcessing.", () -> txn.acceptOperation(badAppendOp), ex -> ex instanceof MetadataUpdateException);
}
Also used : lombok.val(lombok.val) BadOffsetException(io.pravega.segmentstore.contracts.BadOffsetException) UpdateableContainerMetadata(io.pravega.segmentstore.server.UpdateableContainerMetadata) StreamSegmentAppendOperation(io.pravega.segmentstore.server.logs.operations.StreamSegmentAppendOperation) Test(org.junit.Test)

Example 10 with UpdateableContainerMetadata

use of io.pravega.segmentstore.server.UpdateableContainerMetadata in project pravega by pravega.

the class ContainerMetadataUpdateTransactionTests method createMetadata.

private UpdateableContainerMetadata createMetadata() {
    UpdateableContainerMetadata metadata = createBlankMetadata();
    UpdateableSegmentMetadata segmentMetadata = metadata.mapStreamSegmentId(SEGMENT_NAME, SEGMENT_ID);
    segmentMetadata.setLength(SEGMENT_LENGTH);
    // Different from Length.
    segmentMetadata.setStorageLength(SEGMENT_LENGTH - 1);
    segmentMetadata = metadata.mapStreamSegmentId(SEALED_TRANSACTION_NAME, SEALED_TRANSACTION_ID, SEGMENT_ID);
    segmentMetadata.setLength(SEALED_TRANSACTION_LENGTH);
    segmentMetadata.setStorageLength(SEALED_TRANSACTION_LENGTH);
    segmentMetadata.markSealed();
    segmentMetadata = metadata.mapStreamSegmentId(NOTSEALED_TRANSACTION_NAME, NOTSEALED_TRANSACTION_ID, SEGMENT_ID);
    segmentMetadata.setLength(0);
    segmentMetadata.setStorageLength(0);
    return metadata;
}
Also used : UpdateableSegmentMetadata(io.pravega.segmentstore.server.UpdateableSegmentMetadata) UpdateableContainerMetadata(io.pravega.segmentstore.server.UpdateableContainerMetadata)

Aggregations

UpdateableContainerMetadata (io.pravega.segmentstore.server.UpdateableContainerMetadata)39 Test (org.junit.Test)35 lombok.val (lombok.val)26 StreamSegmentMapOperation (io.pravega.segmentstore.server.logs.operations.StreamSegmentMapOperation)17 StreamSegmentAppendOperation (io.pravega.segmentstore.server.logs.operations.StreamSegmentAppendOperation)16 MetadataBuilder (io.pravega.segmentstore.server.MetadataBuilder)15 Operation (io.pravega.segmentstore.server.logs.operations.Operation)12 ArrayList (java.util.ArrayList)12 StorageOperation (io.pravega.segmentstore.server.logs.operations.StorageOperation)11 MergeTransactionOperation (io.pravega.segmentstore.server.logs.operations.MergeTransactionOperation)10 MetadataCheckpointOperation (io.pravega.segmentstore.server.logs.operations.MetadataCheckpointOperation)10 StorageMetadataCheckpointOperation (io.pravega.segmentstore.server.logs.operations.StorageMetadataCheckpointOperation)10 StreamSegmentSealOperation (io.pravega.segmentstore.server.logs.operations.StreamSegmentSealOperation)9 SegmentMetadata (io.pravega.segmentstore.server.SegmentMetadata)7 UpdateableSegmentMetadata (io.pravega.segmentstore.server.UpdateableSegmentMetadata)7 HashMap (java.util.HashMap)7 AttributeUpdate (io.pravega.segmentstore.contracts.AttributeUpdate)6 UUID (java.util.UUID)6 ReadIndex (io.pravega.segmentstore.server.ReadIndex)5 LogAddress (io.pravega.segmentstore.storage.LogAddress)5