Search in sources :

Example 26 with UpdateableContainerMetadata

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

the class ContainerMetadataUpdateTransactionTests method testAcceptStreamSegmentAppend.

/**
 * Tests the accept method with StreamSegmentAppend operations.
 */
@Test
public void testAcceptStreamSegmentAppend() throws Exception {
    UpdateableContainerMetadata metadata = createMetadata();
    val txn = createUpdateTransaction(metadata);
    StreamSegmentAppendOperation appendOp = createAppendNoOffset();
    // When no pre-process has happened.
    AssertExtensions.assertThrows("Unexpected behavior from acceptOperation() when no pre-processing was made.", () -> txn.acceptOperation(appendOp), ex -> ex instanceof MetadataUpdateException);
    Assert.assertEquals("acceptOperation updated the transaction even if it threw an exception.", SEGMENT_LENGTH, txn.getStreamSegmentMetadata(SEGMENT_ID).getLength());
    Assert.assertEquals("acceptOperation updated the metadata.", SEGMENT_LENGTH, metadata.getStreamSegmentMetadata(SEGMENT_ID).getLength());
    // When all is good.
    txn.preProcessOperation(appendOp);
    txn.acceptOperation(appendOp);
    Assert.assertEquals("acceptOperation did not update the transaction.", SEGMENT_LENGTH + appendOp.getData().length, txn.getStreamSegmentMetadata(SEGMENT_ID).getLength());
    Assert.assertEquals("acceptOperation updated the metadata.", SEGMENT_LENGTH, metadata.getStreamSegmentMetadata(SEGMENT_ID).getLength());
}
Also used : lombok.val(lombok.val) UpdateableContainerMetadata(io.pravega.segmentstore.server.UpdateableContainerMetadata) StreamSegmentAppendOperation(io.pravega.segmentstore.server.logs.operations.StreamSegmentAppendOperation) Test(org.junit.Test)

Example 27 with UpdateableContainerMetadata

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

the class ContainerMetadataUpdateTransactionTests method testRollback.

/**
 * Tests the ability of the ContainerMetadataUpdateTransaction to rollback all outstanding changes.
 */
@Test
public void testRollback() throws Exception {
    // Create a couple of operations, commit them, and then create a few more appends, merge a Transaction and seal the parent stream.
    // Then call rollback(); verify no changes have been applied after the call to commit().
    UpdateableContainerMetadata metadata = createMetadata();
    val txn = createUpdateTransaction(metadata);
    StreamSegmentAppendOperation committedAppend = createAppendNoOffset();
    txn.preProcessOperation(committedAppend);
    txn.acceptOperation(committedAppend);
    // This is the last extent of the modifications to the metadata.
    txn.commit(metadata);
    int appendCount = 500;
    ArrayList<StorageOperation> operations = new ArrayList<>();
    for (int i = 0; i < appendCount; i++) {
        operations.add(createAppendNoOffset());
    }
    operations.add(createMerge());
    operations.add(createSeal());
    long seqNo = 0;
    for (StorageOperation op : operations) {
        txn.preProcessOperation(op);
        op.setSequenceNumber(++seqNo);
        txn.acceptOperation(op);
    }
    txn.clear();
    long expectedLength = SEGMENT_LENGTH + DEFAULT_APPEND_DATA.length;
    // Verify metadata is untouched and that the updater has truly rolled back.
    SegmentMetadata parentMetadata = metadata.getStreamSegmentMetadata(SEGMENT_ID);
    Assert.assertEquals("Unexpected Length in metadata after rollback.", expectedLength, parentMetadata.getLength());
    Assert.assertFalse("Unexpected value for isSealed in metadata after rollback.", parentMetadata.isSealed());
    checkLastKnownSequenceNumber("Unexpected lastUsed for Parent after rollback.", 0, parentMetadata);
    SegmentMetadata transactionMetadata = metadata.getStreamSegmentMetadata(SEALED_TRANSACTION_ID);
    Assert.assertFalse("Unexpected value for isMerged in transaction segment metadata after rollback.", transactionMetadata.isMerged());
    checkLastKnownSequenceNumber("Unexpected lastUsed for Transaction segment after rollback.", 0, transactionMetadata);
    // Now the updater
    parentMetadata = txn.getStreamSegmentMetadata(SEGMENT_ID);
    Assert.assertEquals("Unexpected Length in transaction after rollback.", expectedLength, parentMetadata.getLength());
    Assert.assertFalse("Unexpected value for isSealed in transaction after rollback.", parentMetadata.isSealed());
    checkLastKnownSequenceNumber("Unexpected lastUsed for Parent (txn) after rollback.", 0, parentMetadata);
    transactionMetadata = txn.getStreamSegmentMetadata(SEALED_TRANSACTION_ID);
    Assert.assertFalse("Unexpected value for isMerged in transaction segment in update transaction after rollback.", transactionMetadata.isMerged());
    checkLastKnownSequenceNumber("Unexpected lastUsed for Transaction segment in update transaction after rollback.", 0, transactionMetadata);
}
Also used : lombok.val(lombok.val) UpdateableSegmentMetadata(io.pravega.segmentstore.server.UpdateableSegmentMetadata) SegmentMetadata(io.pravega.segmentstore.server.SegmentMetadata) StreamSegmentMetadata(io.pravega.segmentstore.server.containers.StreamSegmentMetadata) StorageOperation(io.pravega.segmentstore.server.logs.operations.StorageOperation) ArrayList(java.util.ArrayList) UpdateableContainerMetadata(io.pravega.segmentstore.server.UpdateableContainerMetadata) StreamSegmentAppendOperation(io.pravega.segmentstore.server.logs.operations.StreamSegmentAppendOperation) Test(org.junit.Test)

Example 28 with UpdateableContainerMetadata

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

the class ContainerMetadataUpdateTransactionTests method testAcceptMergeTransaction.

/**
 * Tests the accept method with MergeTransactionOperations.
 */
@Test
public void testAcceptMergeTransaction() throws Exception {
    UpdateableContainerMetadata metadata = createMetadata();
    val txn = createUpdateTransaction(metadata);
    MergeTransactionOperation mergeOp = createMerge();
    // When no pre-process has happened
    AssertExtensions.assertThrows("Unexpected behavior from acceptOperation() when no pre-processing was made.", () -> txn.acceptOperation(mergeOp), ex -> ex instanceof MetadataUpdateException);
    Assert.assertEquals("acceptOperation updated the transaction even if it threw an exception (parent segment).", SEGMENT_LENGTH, txn.getStreamSegmentMetadata(SEGMENT_ID).getLength());
    Assert.assertEquals("acceptOperation updated the metadata (parent segment).", SEGMENT_LENGTH, metadata.getStreamSegmentMetadata(SEGMENT_ID).getLength());
    // This would naturally happen in case of a failure, so we need to simulate this here too.
    txn.clear();
    // When all is good.
    txn.preProcessOperation(mergeOp);
    txn.acceptOperation(mergeOp);
    Assert.assertTrue("acceptOperation did not update the transaction(Transaction).", txn.getStreamSegmentMetadata(SEALED_TRANSACTION_ID).isMerged());
    Assert.assertFalse("acceptOperation updated the metadata (Transaction).", metadata.getStreamSegmentMetadata(SEALED_TRANSACTION_ID).isMerged());
    Assert.assertEquals("acceptOperation did not update the transaction.", SEGMENT_LENGTH + SEALED_TRANSACTION_LENGTH, txn.getStreamSegmentMetadata(SEGMENT_ID).getLength());
    Assert.assertEquals("acceptOperation updated the metadata.", SEGMENT_LENGTH, metadata.getStreamSegmentMetadata(SEGMENT_ID).getLength());
}
Also used : lombok.val(lombok.val) UpdateableContainerMetadata(io.pravega.segmentstore.server.UpdateableContainerMetadata) MergeTransactionOperation(io.pravega.segmentstore.server.logs.operations.MergeTransactionOperation) Test(org.junit.Test)

Example 29 with UpdateableContainerMetadata

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

the class ContainerMetadataUpdateTransactionTests method testPreProcessAndAcceptWithInvalidSegmentId.

// endregion
// region Other tests
/**
 * Tests the behavior of preProcessOperation and acceptOperation when encountering an invalid StreamSegmentId, or
 * when encountering a StreamSegment Id for a deleted StreamSegment.
 */
@Test
public void testPreProcessAndAcceptWithInvalidSegmentId() throws Exception {
    UpdateableContainerMetadata metadata = createBlankMetadata();
    val txn = createUpdateTransaction(metadata);
    ArrayList<StorageOperation> testOperations = new ArrayList<>();
    testOperations.add(createAppendNoOffset());
    testOperations.add(createSeal());
    testOperations.add(createMerge());
    for (StorageOperation op : testOperations) {
        AssertExtensions.assertThrows("Unexpected behavior from preProcessOperation when processing an operation for a non-existent Segment: " + op, () -> txn.preProcessOperation(op), ex -> ex instanceof MetadataUpdateException);
        AssertExtensions.assertThrows("Unexpected behavior from acceptOperation when processing an operation for a non-existent Segment: " + op, () -> txn.acceptOperation(op), ex -> ex instanceof MetadataUpdateException);
    }
    // If the StreamSegment was previously marked as deleted.
    UpdateableSegmentMetadata segmentMetadata = metadata.mapStreamSegmentId("foo", SEGMENT_ID);
    segmentMetadata.markDeleted();
    for (StorageOperation op : testOperations) {
        AssertExtensions.assertThrows("Unexpected behavior from preProcessOperation when processing an operation for deleted Segment: " + op, () -> txn.preProcessOperation(op), ex -> ex instanceof StreamSegmentNotExistsException);
    }
}
Also used : lombok.val(lombok.val) UpdateableSegmentMetadata(io.pravega.segmentstore.server.UpdateableSegmentMetadata) StorageOperation(io.pravega.segmentstore.server.logs.operations.StorageOperation) ArrayList(java.util.ArrayList) UpdateableContainerMetadata(io.pravega.segmentstore.server.UpdateableContainerMetadata) StreamSegmentNotExistsException(io.pravega.segmentstore.contracts.StreamSegmentNotExistsException) Test(org.junit.Test)

Example 30 with UpdateableContainerMetadata

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

the class ContainerMetadataUpdateTransactionTests method testPreProcessMergeTransaction.

// endregion
// region MergeTransactionOperation
/**
 * Tests the preProcess method with MergeTransactionOperations.
 * Scenarios:
 * * Recovery/non-recovery mode
 * * Target StreamSegment is sealed
 * * Target StreamSegment is a Transaction
 * * Transaction StreamSegment is already merged
 * * Transaction StreamSegment is not sealed
 */
@Test
public void testPreProcessMergeTransaction() throws Exception {
    UpdateableContainerMetadata metadata = createMetadata();
    // When everything is OK (recovery mode).
    MergeTransactionOperation recoveryMergeOp = createMerge();
    metadata.enterRecoveryMode();
    val txn1 = createUpdateTransaction(metadata);
    AssertExtensions.assertThrows("preProcess(Merge) handled an operation with no Transaction StreamSegment Length set.", () -> txn1.preProcessOperation(createMerge()), ex -> ex instanceof MetadataUpdateException);
    // In recovery mode, the updater does not set the length; it just validates that it has one.
    recoveryMergeOp.setLength(metadata.getStreamSegmentMetadata(SEALED_TRANSACTION_ID).getLength());
    txn1.preProcessOperation(recoveryMergeOp);
    AssertExtensions.assertLessThan("Unexpected Target StreamSegmentOffset after call to preProcess in recovery mode.", 0, recoveryMergeOp.getStreamSegmentOffset());
    checkNoSequenceNumberAssigned(recoveryMergeOp, "call to preProcess in recovery mode");
    Assert.assertFalse("preProcess(Merge) seems to have changed the Updater internal state in recovery mode.", txn1.getStreamSegmentMetadata(SEALED_TRANSACTION_ID).isMerged());
    Assert.assertFalse("preProcess(Merge) seems to have changed the metadata in recovery mode.", metadata.getStreamSegmentMetadata(SEALED_TRANSACTION_ID).isMerged());
    // When everything is OK (non-recovery mode).
    MergeTransactionOperation mergeOp = createMerge();
    metadata.exitRecoveryMode();
    val txn2 = createUpdateTransaction(metadata);
    txn2.preProcessOperation(mergeOp);
    Assert.assertEquals("Unexpected Transaction StreamSegmentLength after call to preProcess in non-recovery mode.", SEALED_TRANSACTION_LENGTH, mergeOp.getLength());
    Assert.assertEquals("Unexpected Target StreamSegmentOffset after call to preProcess in non-recovery mode.", SEGMENT_LENGTH, mergeOp.getStreamSegmentOffset());
    checkNoSequenceNumberAssigned(mergeOp, "call to preProcess in non-recovery mode");
    Assert.assertFalse("preProcess(Merge) seems to have changed the Updater internal state in non-recovery mode.", txn2.getStreamSegmentMetadata(SEALED_TRANSACTION_ID).isMerged());
    Assert.assertFalse("preProcess(Merge) seems to have changed the metadata in non-recovery mode.", metadata.getStreamSegmentMetadata(SEALED_TRANSACTION_ID).isMerged());
    // When Target StreamSegment is sealed.
    StreamSegmentSealOperation sealTargetOp = createSeal();
    txn2.preProcessOperation(sealTargetOp);
    txn2.acceptOperation(sealTargetOp);
    AssertExtensions.assertThrows("Unexpected behavior for preProcess(Merge) when Target StreamSegment is sealed.", () -> txn2.preProcessOperation(createMerge()), ex -> ex instanceof StreamSegmentSealedException);
    // Rollback the seal
    txn2.clear();
    // When Target StreamSegment is a Transaction.
    MergeTransactionOperation mergeToTransactionOp = new MergeTransactionOperation(NOTSEALED_TRANSACTION_ID, SEALED_TRANSACTION_ID);
    AssertExtensions.assertThrows("Unexpected behavior for preProcess(Merge) when Target StreamSegment is a Transaction.", () -> txn2.preProcessOperation(mergeToTransactionOp), ex -> ex instanceof MetadataUpdateException);
    // When Transaction is not sealed.
    MergeTransactionOperation mergeNonSealed = new MergeTransactionOperation(NOTSEALED_TRANSACTION_ID, SEGMENT_ID);
    AssertExtensions.assertThrows("Unexpected behavior for preProcess(Merge) when Transaction StreamSegment is not sealed.", () -> txn2.preProcessOperation(mergeNonSealed), ex -> ex instanceof StreamSegmentNotSealedException);
    // When Transaction is already merged.
    txn2.preProcessOperation(mergeOp);
    txn2.acceptOperation(mergeOp);
    AssertExtensions.assertThrows("Unexpected behavior for preProcess(Merge) when Transaction StreamSegment is already merged (in transaction).", () -> txn2.preProcessOperation(createMerge()), ex -> ex instanceof StreamSegmentMergedException);
    txn2.commit(metadata);
    AssertExtensions.assertThrows("Unexpected behavior for preProcess(Merge) when Transaction StreamSegment is already merged (in metadata).", () -> txn2.preProcessOperation(createMerge()), ex -> ex instanceof StreamSegmentMergedException);
}
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) StreamSegmentNotSealedException(io.pravega.segmentstore.contracts.StreamSegmentNotSealedException) MergeTransactionOperation(io.pravega.segmentstore.server.logs.operations.MergeTransactionOperation) Test(org.junit.Test)

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