Search in sources :

Example 26 with IntentionalException

use of io.pravega.test.common.IntentionalException in project pravega by pravega.

the class StorageReadManagerTests method testDependents.

/**
 * Tests the ability to queue dependent reads (subsequent reads that only want to read a part of a previous read).
 * Test this both with successful and failed reads.
 */
@Test
public void testDependents() {
    final Duration waitTimeout = Duration.ofSeconds(5);
    TestStorage storage = new TestStorage();
    CompletableFuture<Integer> signal = new CompletableFuture<>();
    AtomicBoolean wasReadInvoked = new AtomicBoolean();
    storage.readImplementation = () -> {
        if (wasReadInvoked.getAndSet(true)) {
            Assert.fail("Read was invoked multiple times, which is a likely indicator that the requests were not chained.");
        }
        return signal;
    };
    @Cleanup StorageReadManager reader = new StorageReadManager(SEGMENT_METADATA, storage, executorService());
    // Create some reads.
    CompletableFuture<StorageReadManager.Result> c1 = new CompletableFuture<>();
    CompletableFuture<StorageReadManager.Result> c2 = new CompletableFuture<>();
    reader.execute(new StorageReadManager.Request(0, 100, c1::complete, c1::completeExceptionally, TIMEOUT));
    reader.execute(new StorageReadManager.Request(50, 100, c2::complete, c2::completeExceptionally, TIMEOUT));
    Assert.assertFalse("One or more of the reads has completed prematurely.", c1.isDone() || c2.isDone());
    signal.completeExceptionally(new IntentionalException());
    AssertExtensions.assertThrows("The first read was not failed with the correct exception.", () -> c1.get(waitTimeout.toMillis(), TimeUnit.MILLISECONDS), ex -> ex instanceof IntentionalException);
    AssertExtensions.assertThrows("The second read was not failed with the correct exception.", () -> c2.get(waitTimeout.toMillis(), TimeUnit.MILLISECONDS), ex -> ex instanceof IntentionalException);
}
Also used : AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) CompletableFuture(java.util.concurrent.CompletableFuture) Duration(java.time.Duration) Cleanup(lombok.Cleanup) IntentionalException(io.pravega.test.common.IntentionalException) Test(org.junit.Test)

Example 27 with IntentionalException

use of io.pravega.test.common.IntentionalException in project pravega by pravega.

the class StreamSegmentContainerRegistryTests method testStartAlreadyRunning.

/**
 * Tests a scenario where a container startup is requested immediately after the shutdown of the same container or
 * while that one is running. This tests both the case when a container auto-shuts down due to failure and when it
 * is shut down in a controlled manner.
 */
@Test
public void testStartAlreadyRunning() throws Exception {
    final int containerId = 1;
    TestContainerFactory factory = new TestContainerFactory();
    @Cleanup StreamSegmentContainerRegistry registry = new StreamSegmentContainerRegistry(factory, executorService());
    registry.startContainer(containerId, TIMEOUT).join();
    TestContainer container1 = (TestContainer) registry.getContainer(containerId);
    // 1. While running.
    AssertExtensions.assertThrows("startContainer() did not throw for already registered container.", () -> registry.startContainer(containerId, TIMEOUT), ex -> ex instanceof IllegalArgumentException);
    // 2. After a container fails - while shutting down.
    // Manually control when the Container actually shuts down.
    container1.stopSignal = new ReusableLatch();
    container1.fail(new IntentionalException());
    val startContainer2 = registry.startContainer(containerId, TIMEOUT);
    Assert.assertFalse("startContainer() completed before previous container shut down (with failure).", startContainer2.isDone());
    container1.stopSignal.release();
    startContainer2.get(TIMEOUT.toMillis(), TimeUnit.MILLISECONDS);
    TestContainer container2 = (TestContainer) registry.getContainer(containerId);
    Assert.assertEquals("Container1 was not shut down (with failure).", Service.State.FAILED, container1.state());
    Assert.assertEquals("Container2 was not started properly.", Service.State.RUNNING, container2.state());
    // 3. After a controlled shutdown - while shutting down.
    // Manually control when the Container actually shuts down.
    container2.stopSignal = new ReusableLatch();
    container2.stopAsync();
    val startContainer3 = registry.startContainer(containerId, TIMEOUT);
    Assert.assertFalse("startContainer() completed before previous container shut down (normally).", startContainer3.isDone());
    container2.stopSignal.release();
    startContainer3.get(TIMEOUT.toMillis(), TimeUnit.MILLISECONDS);
    TestContainer container3 = (TestContainer) registry.getContainer(containerId);
    Assert.assertEquals("Container2 was not shut down (normally).", Service.State.TERMINATED, container2.state());
    Assert.assertEquals("Container3 was not started properly.", Service.State.RUNNING, container3.state());
}
Also used : lombok.val(lombok.val) ReusableLatch(io.pravega.common.util.ReusableLatch) Cleanup(lombok.Cleanup) IntentionalException(io.pravega.test.common.IntentionalException) Test(org.junit.Test)

Example 28 with IntentionalException

use of io.pravega.test.common.IntentionalException in project pravega by pravega.

the class StreamSegmentContainerRegistryTests method testContainerFailureOnStartup.

/**
 * Tests the ability to detect a container failure and unregister the container in case the container fails on startup.
 */
@Test
public void testContainerFailureOnStartup() throws Exception {
    final int containerId = 123;
    // We insert a ReusableLatch that will allow us to manually delay the TestContainer's shutdown/closing process
    // so that we have enough time to verify that calling getContainer() on a currently shutting down container will
    // throw the appropriate exception.
    ReusableLatch closeReleaseSignal = new ReusableLatch();
    TestContainerFactory factory = new TestContainerFactory(new IntentionalException(), closeReleaseSignal);
    @Cleanup StreamSegmentContainerRegistry registry = new StreamSegmentContainerRegistry(factory, executorService());
    AssertExtensions.assertThrows("Unexpected exception thrown upon failed container startup.", registry.startContainer(containerId, TIMEOUT)::join, ex -> ex instanceof IntentionalException || (ex instanceof IllegalStateException && ex.getCause() instanceof IntentionalException));
    AssertExtensions.assertThrows("Container is registered even if it failed to start (and is currently shut down).", () -> registry.getContainer(containerId), ex -> ex instanceof ContainerNotFoundException);
    // Unblock container closing, which will, in turn, unblock its de-registration.
    closeReleaseSignal.release();
    AssertExtensions.assertThrows("Container is registered even if it failed to start (and has been unregistered).", () -> registry.getContainer(containerId), ex -> ex instanceof ContainerNotFoundException);
}
Also used : ReusableLatch(io.pravega.common.util.ReusableLatch) Cleanup(lombok.Cleanup) ContainerNotFoundException(io.pravega.segmentstore.contracts.ContainerNotFoundException) IntentionalException(io.pravega.test.common.IntentionalException) Test(org.junit.Test)

Example 29 with IntentionalException

use of io.pravega.test.common.IntentionalException in project pravega by pravega.

the class RollingStorageTests method testConcatNativelyFailure.

/**
 * Tests the ability to use native concat for those cases when it's appropriate.
 */
@Test
public void testConcatNativelyFailure() throws Exception {
    final int initialTargetLength = (int) DEFAULT_ROLLING_POLICY.getMaxLength() / 2;
    final int initialSourceLength = (int) DEFAULT_ROLLING_POLICY.getMaxLength() - initialTargetLength;
    final String sourceSegmentName = "SourceSegment";
    // Concat succeeds, but can't delete header.
    @Cleanup val baseStorage = new TestStorage();
    @Cleanup val s = new RollingStorage(baseStorage, DEFAULT_ROLLING_POLICY);
    s.initialize(1);
    // Create a target and a source, making sure they have the right sizes for a native concat.
    s.create(SEGMENT_NAME);
    val targetHandle = (RollingSegmentHandle) s.openWrite(SEGMENT_NAME);
    val writeStream = new ByteArrayOutputStream();
    populate(s, targetHandle, 1, initialTargetLength, initialTargetLength, writeStream);
    s.create(sourceSegmentName);
    val sourceHandle = (RollingSegmentHandle) s.openWrite(sourceSegmentName);
    populate(s, sourceHandle, 1, initialSourceLength, initialSourceLength, writeStream);
    s.seal(sourceHandle);
    // Attempt to concat, but intentionally fail the deletion of the source header.
    baseStorage.deleteFailure = sn -> sn.equals(sourceHandle.getHeaderHandle().getSegmentName()) ? new IntentionalException() : null;
    AssertExtensions.assertThrows("Unexpected exception when doing native concat.", () -> s.concat(targetHandle, initialTargetLength, sourceSegmentName), ex -> ex instanceof IntentionalException);
    // However, the concat should have worked, so the source segment is now inaccessible.
    baseStorage.deleteFailure = null;
    checkConcatResult(s, targetHandle, sourceSegmentName, 1, initialTargetLength + initialSourceLength);
    checkWrittenData(writeStream.toByteArray(), s.openRead(SEGMENT_NAME), s);
}
Also used : lombok.val(lombok.val) ByteArrayOutputStream(java.io.ByteArrayOutputStream) Cleanup(lombok.Cleanup) IntentionalException(io.pravega.test.common.IntentionalException) Test(org.junit.Test)

Example 30 with IntentionalException

use of io.pravega.test.common.IntentionalException in project pravega by pravega.

the class RollingStorageTests method testConcatHeaderFailure.

/**
 * Tests the ability to handle partially executed concat operations for header concat, such as being able to write
 * the concat entry but not actually concat the source header file.
 */
@Test
public void testConcatHeaderFailure() throws Exception {
    final int initialTargetLength = (int) DEFAULT_ROLLING_POLICY.getMaxLength() / 2;
    final String sourceSegmentName = "SourceSegment";
    @Cleanup val baseStorage = new TestStorage();
    @Cleanup val s = new RollingStorage(baseStorage, DEFAULT_ROLLING_POLICY);
    s.initialize(1);
    // Create a Target Segment and a Source Segment and write some data to them.
    s.create(SEGMENT_NAME);
    val targetHandle = (RollingSegmentHandle) s.openWrite(SEGMENT_NAME);
    val writeStream = new ByteArrayOutputStream();
    populate(s, targetHandle, 1, initialTargetLength, initialTargetLength, writeStream);
    s.create(sourceSegmentName);
    val sourceHandle = (RollingSegmentHandle) s.openWrite(sourceSegmentName);
    populate(s, sourceHandle, APPENDS_PER_SEGMENT, initialTargetLength, initialTargetLength, writeStream);
    s.seal(sourceHandle);
    // Simulate a native concat exception, and try a few times.
    baseStorage.concatFailure = sn -> sn.equals(sourceHandle.getHeaderHandle().getSegmentName()) ? new IntentionalException() : null;
    for (int i = 0; i < 4; i++) {
        AssertExtensions.assertThrows("Unexpected error reported from concat.", () -> s.concat(targetHandle, initialTargetLength, sourceSegmentName), ex -> ex instanceof IntentionalException);
    }
    // Clear the intentional failure and try again, after which check the results.
    baseStorage.concatFailure = null;
    s.concat(targetHandle, initialTargetLength, sourceSegmentName);
    checkConcatResult(s, targetHandle, sourceSegmentName, 1 + sourceHandle.chunks().size(), initialTargetLength + (int) sourceHandle.length());
    checkWrittenData(writeStream.toByteArray(), s.openRead(SEGMENT_NAME), s);
}
Also used : lombok.val(lombok.val) ByteArrayOutputStream(java.io.ByteArrayOutputStream) Cleanup(lombok.Cleanup) IntentionalException(io.pravega.test.common.IntentionalException) Test(org.junit.Test)

Aggregations

IntentionalException (io.pravega.test.common.IntentionalException)40 Test (org.junit.Test)39 lombok.val (lombok.val)26 Cleanup (lombok.Cleanup)25 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)16 AtomicReference (java.util.concurrent.atomic.AtomicReference)14 Assert (org.junit.Assert)11 AssertExtensions (io.pravega.test.common.AssertExtensions)10 ArrayList (java.util.ArrayList)10 CompletableFuture (java.util.concurrent.CompletableFuture)10 ByteArrayOutputStream (java.io.ByteArrayOutputStream)9 Duration (java.time.Duration)9 Rule (org.junit.Rule)9 Timeout (org.junit.rules.Timeout)9 StreamSegmentNotExistsException (io.pravega.segmentstore.contracts.StreamSegmentNotExistsException)8 StorageOperation (io.pravega.segmentstore.server.logs.operations.StorageOperation)8 ThreadPooledTestSuite (io.pravega.test.common.ThreadPooledTestSuite)8 HashSet (java.util.HashSet)8 Random (java.util.Random)8 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)8