Search in sources :

Example 6 with ReusableLatch

use of io.pravega.common.util.ReusableLatch 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 7 with ReusableLatch

use of io.pravega.common.util.ReusableLatch in project pravega by pravega.

the class AsyncStorageWrapperTests method testConcurrencySameSegment.

/**
 * Tests basic same-segment concurrency for simple operations. Since all operations use the same sequencing mechanism
 * it suffices to test using two arbitrary operations instead of every possible pair.
 */
@Test
public void testConcurrencySameSegment() throws Exception {
    final String segmentName = "Segment";
    final String op1 = TestStorage.CREATE;
    final String op2 = TestStorage.DELETE;
    // Create a set of latches that can be used to detect when an operation was invoked and when to release it.
    val invoked = new HashMap<String, ReusableLatch>();
    val waitOn = new HashMap<String, ReusableLatch>();
    invoked.put(op1, new ReusableLatch());
    invoked.put(op2, new ReusableLatch());
    waitOn.put(op1, new ReusableLatch());
    waitOn.put(op2, new ReusableLatch());
    val innerStorage = new TestStorage((operation, segment) -> {
        invoked.get(operation).release();
        Exceptions.handleInterrupted(() -> waitOn.get(operation).await());
        return null;
    });
    @Cleanup val s = new AsyncStorageWrapper(innerStorage, executorService());
    // Begin executing one operation (Create) and wait for it properly "acquire" the lock.
    val futures = new ArrayList<CompletableFuture<?>>();
    futures.add(s.create(segmentName, TIMEOUT));
    invoked.get(op1).await(LOCK_TIMEOUT_MILLIS);
    Assert.assertEquals("Unexpected number of active segments.", 1, s.getSegmentWithOngoingOperationsCount());
    // Begin executing a second operation (Delete) and verify that it hasn't started within a reasonable amount of time.
    futures.add(s.delete(InMemoryStorage.newHandle(segmentName, false), TIMEOUT));
    AssertExtensions.assertThrows("Second operation was invoked while the first one was still running.", () -> invoked.get(op2).await(LOCK_TIMEOUT_MILLIS), ex -> ex instanceof TimeoutException);
    // Complete the first operation and await the second operation to begin executing, then release it too.
    waitOn.get(op1).release();
    invoked.get(op2).await(LOCK_TIMEOUT_MILLIS);
    Assert.assertEquals("Unexpected number of active segments.", 1, s.getSegmentWithOngoingOperationsCount());
    waitOn.get(op2).release();
    // Wait for both operations to complete. This will re-throw any exceptions that may have occurred.
    allOf(futures).get(TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
    Assert.assertEquals("Unexpected final number of active segments.", 0, s.getSegmentWithOngoingOperationsCount());
}
Also used : lombok.val(lombok.val) ReusableLatch(io.pravega.common.util.ReusableLatch) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) Cleanup(lombok.Cleanup) TimeoutException(java.util.concurrent.TimeoutException) Test(org.junit.Test)

Example 8 with ReusableLatch

use of io.pravega.common.util.ReusableLatch in project pravega by pravega.

the class EndOfDataNotifierTest method endOfStreamNotifierTest.

@Test
public void endOfStreamNotifierTest() throws Exception {
    AtomicBoolean listenerInvoked = new AtomicBoolean();
    ReusableLatch latch = new ReusableLatch();
    when(state.isEndOfData()).thenReturn(false).thenReturn(true);
    when(sync.getState()).thenReturn(state);
    Listener<EndOfDataNotification> listener1 = notification -> {
        log.info("listener 1 invoked");
        listenerInvoked.set(true);
        latch.release();
    };
    Listener<EndOfDataNotification> listener2 = notification -> {
    };
    EndOfDataNotifier notifier = new EndOfDataNotifier(system, sync, executor);
    notifier.registerListener(listener1);
    verify(executor, times(1)).scheduleAtFixedRate(any(Runnable.class), anyLong(), anyLong(), any(TimeUnit.class));
    latch.await();
    verify(state, times(2)).isEndOfData();
    assertTrue(listenerInvoked.get());
    notifier.registerListener(listener2);
    verify(executor, times(1)).scheduleAtFixedRate(any(Runnable.class), anyLong(), anyLong(), any(TimeUnit.class));
    notifier.unregisterAllListeners();
    verify(system, times(1)).removeListeners(EndOfDataNotification.class.getSimpleName());
}
Also used : ArgumentMatchers.any(org.mockito.ArgumentMatchers.any) StateSynchronizer(io.pravega.client.state.StateSynchronizer) EndOfDataNotifier(io.pravega.client.stream.notifications.notifier.EndOfDataNotifier) ArgumentMatchers.anyLong(org.mockito.ArgumentMatchers.anyLong) BeforeClass(org.junit.BeforeClass) Mock(org.mockito.Mock) RunWith(org.junit.runner.RunWith) Assert.assertTrue(org.junit.Assert.assertTrue) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) Mockito.times(org.mockito.Mockito.times) Test(org.junit.Test) Mockito.when(org.mockito.Mockito.when) Mockito.verify(org.mockito.Mockito.verify) TimeUnit(java.util.concurrent.TimeUnit) Slf4j(lombok.extern.slf4j.Slf4j) After(org.junit.After) Spy(org.mockito.Spy) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) InlineExecutor(io.pravega.test.common.InlineExecutor) MockitoJUnitRunner(org.mockito.junit.MockitoJUnitRunner) ReaderGroupState(io.pravega.client.stream.impl.ReaderGroupState) ReusableLatch(io.pravega.common.util.ReusableLatch) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) ReusableLatch(io.pravega.common.util.ReusableLatch) EndOfDataNotifier(io.pravega.client.stream.notifications.notifier.EndOfDataNotifier) TimeUnit(java.util.concurrent.TimeUnit) Test(org.junit.Test)

Aggregations

ReusableLatch (io.pravega.common.util.ReusableLatch)8 Test (org.junit.Test)8 Cleanup (lombok.Cleanup)6 HashMap (java.util.HashMap)4 lombok.val (lombok.val)4 ArrayList (java.util.ArrayList)3 ScheduledExecutorService (java.util.concurrent.ScheduledExecutorService)3 ArgumentMatchers.any (org.mockito.ArgumentMatchers.any)3 StateSynchronizer (io.pravega.client.state.StateSynchronizer)2 ReaderGroupState (io.pravega.client.stream.impl.ReaderGroupState)2 SegmentProperties (io.pravega.segmentstore.contracts.SegmentProperties)2 StreamSegmentInformation (io.pravega.segmentstore.contracts.StreamSegmentInformation)2 InlineExecutor (io.pravega.test.common.InlineExecutor)2 IntentionalException (io.pravega.test.common.IntentionalException)2 Collection (java.util.Collection)2 TimeUnit (java.util.concurrent.TimeUnit)2 Mockito.times (org.mockito.Mockito.times)2 Mockito.verify (org.mockito.Mockito.verify)2 Mockito.when (org.mockito.Mockito.when)2 Unpooled (io.netty.buffer.Unpooled)1