use of org.apache.samza.runtime.ProcessorLifecycleListener in project samza by apache.
the class TestStreamProcessor method testCoordinatorFailureShouldStopTheStreamProcessor.
@Test
public void testCoordinatorFailureShouldStopTheStreamProcessor() {
JobCoordinator mockJobCoordinator = Mockito.mock(JobCoordinator.class);
ProcessorLifecycleListener lifecycleListener = Mockito.mock(ProcessorLifecycleListener.class);
SamzaContainer mockSamzaContainer = Mockito.mock(SamzaContainer.class);
MapConfig config = new MapConfig(ImmutableMap.of("task.shutdown.ms", "0"));
StreamProcessor streamProcessor = new StreamProcessor("TestProcessorId", config, new HashMap<>(), null, Optional.empty(), Optional.empty(), Optional.empty(), sp -> lifecycleListener, mockJobCoordinator, Mockito.mock(MetadataStore.class));
Exception failureException = new Exception("dummy exception");
streamProcessor.container = mockSamzaContainer;
streamProcessor.state = State.RUNNING;
streamProcessor.jobCoordinatorListener.onCoordinatorFailure(failureException);
Mockito.doNothing().when(mockSamzaContainer).shutdown();
Mockito.when(mockSamzaContainer.hasStopped()).thenReturn(false);
assertEquals(State.STOPPED, streamProcessor.state);
Mockito.verify(lifecycleListener).afterFailure(failureException);
Mockito.verify(mockSamzaContainer).shutdown();
}
use of org.apache.samza.runtime.ProcessorLifecycleListener in project samza by apache.
the class TestStreamProcessor method testStopByProcessor.
/**
* Tests stop() method when Container AND JobCoordinator are running
*/
@Test
public void testStopByProcessor() throws InterruptedException {
JobCoordinator mockJobCoordinator = mock(JobCoordinator.class);
final CountDownLatch processorListenerStop = new CountDownLatch(1);
final CountDownLatch processorListenerStart = new CountDownLatch(1);
TestableStreamProcessor processor = new TestableStreamProcessor(new MapConfig(), new HashMap<>(), mock(StreamTaskFactory.class), new ProcessorLifecycleListener() {
@Override
public void afterStart() {
processorListenerState.put(ListenerCallback.AFTER_START, true);
processorListenerStart.countDown();
}
@Override
public void afterFailure(Throwable t) {
processorListenerState.put(ListenerCallback.AFTER_FAILURE, true);
}
@Override
public void afterStop() {
processorListenerState.put(ListenerCallback.AFTER_STOP, true);
processorListenerStop.countDown();
}
@Override
public void beforeStart() {
processorListenerState.put(ListenerCallback.BEFORE_START, true);
}
}, mockJobCoordinator, null);
final CountDownLatch coordinatorStop = new CountDownLatch(1);
final Thread jcThread = new Thread(() -> {
try {
processor.jobCoordinatorListener.onJobModelExpired();
processor.jobCoordinatorListener.onNewJobModel("1", getMockJobModel());
coordinatorStop.await();
processor.jobCoordinatorListener.onCoordinatorStop();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
doAnswer(invocation -> {
coordinatorStop.countDown();
return null;
}).when(mockJobCoordinator).stop();
doAnswer(invocation -> {
jcThread.start();
return null;
}).when(mockJobCoordinator).start();
processor.start();
processorListenerStart.await(10, TimeUnit.SECONDS);
assertEquals(SamzaContainerStatus.STARTED, processor.getContainerStatus());
// This block is required for the mockRunloop is actually start.
// Otherwise, processor.stop gets triggered before mockRunloop begins to block
processor.runLoopStartForMain.await();
processor.stop();
processorListenerStop.await();
// Assertions on which callbacks are expected to be invoked
assertTrue(processorListenerState.get(ListenerCallback.BEFORE_START));
assertTrue(processorListenerState.get(ListenerCallback.AFTER_START));
assertTrue(processorListenerState.get(ListenerCallback.AFTER_STOP));
Assert.assertFalse(processorListenerState.get(ListenerCallback.AFTER_FAILURE));
}
use of org.apache.samza.runtime.ProcessorLifecycleListener in project samza by apache.
the class TestStreamProcessor method testStartOperationShouldBeIdempotent.
@Test
public void testStartOperationShouldBeIdempotent() {
JobCoordinator mockJobCoordinator = Mockito.mock(JobCoordinator.class);
Mockito.doNothing().when(mockJobCoordinator).start();
ProcessorLifecycleListener lifecycleListener = Mockito.mock(ProcessorLifecycleListener.class);
StreamProcessor streamProcessor = Mockito.spy(new StreamProcessor("TestProcessorId", new MapConfig(), new HashMap<>(), null, Optional.empty(), Optional.empty(), Optional.empty(), sp -> lifecycleListener, mockJobCoordinator, Mockito.mock(MetadataStore.class)));
assertEquals(State.NEW, streamProcessor.getState());
streamProcessor.start();
assertEquals(State.STARTED, streamProcessor.getState());
streamProcessor.start();
assertEquals(State.STARTED, streamProcessor.getState());
Mockito.verify(mockJobCoordinator, Mockito.times(1)).start();
}
use of org.apache.samza.runtime.ProcessorLifecycleListener in project samza by apache.
the class TestStreamProcessor method testStopShouldBeIdempotent.
@Test
public void testStopShouldBeIdempotent() {
JobCoordinator mockJobCoordinator = Mockito.mock(JobCoordinator.class);
ProcessorLifecycleListener lifecycleListener = Mockito.mock(ProcessorLifecycleListener.class);
SamzaContainer mockSamzaContainer = Mockito.mock(SamzaContainer.class);
MapConfig config = new MapConfig(ImmutableMap.of("task.shutdown.ms", "0"));
StreamProcessor streamProcessor = PowerMockito.spy(new StreamProcessor("TestProcessorId", config, new HashMap<>(), null, Optional.empty(), Optional.empty(), Optional.empty(), sp -> lifecycleListener, mockJobCoordinator, Mockito.mock(MetadataStore.class)));
Mockito.doNothing().when(mockJobCoordinator).stop();
Mockito.doNothing().when(mockSamzaContainer).shutdown();
Mockito.when(mockSamzaContainer.hasStopped()).thenReturn(false);
Mockito.when(mockSamzaContainer.getStatus()).thenReturn(SamzaContainerStatus.STARTED).thenReturn(SamzaContainerStatus.STOPPED);
streamProcessor.state = State.RUNNING;
streamProcessor.stop();
assertEquals(State.STOPPING, streamProcessor.state);
}
use of org.apache.samza.runtime.ProcessorLifecycleListener in project samza by apache.
the class TestStreamProcessor method testContainerFailureCorrectlyStopsProcessor.
/**
* Tests that a failure in container correctly stops a running JobCoordinator and propagates the exception
* through the StreamProcessor
*
* Assertions:
* - JobCoordinator has been stopped from the JobCoordinatorListener callback
* - ProcessorLifecycleListener#afterStop(Throwable) has been invoked w/ non-null Throwable
*/
@Test
public void testContainerFailureCorrectlyStopsProcessor() throws InterruptedException {
JobCoordinator mockJobCoordinator = Mockito.mock(JobCoordinator.class);
Throwable expectedThrowable = new SamzaException("Failure in Container!");
AtomicReference<Throwable> actualThrowable = new AtomicReference<>();
final CountDownLatch runLoopStartedLatch = new CountDownLatch(1);
RunLoop failingRunLoop = mock(RunLoop.class);
doAnswer(invocation -> {
try {
runLoopStartedLatch.countDown();
throw expectedThrowable;
} catch (InterruptedException ie) {
ie.printStackTrace();
}
return null;
}).when(failingRunLoop).run();
SamzaContainer mockContainer = StreamProcessorTestUtils.getDummyContainer(failingRunLoop, mock(StreamTask.class));
final CountDownLatch processorListenerFailed = new CountDownLatch(1);
TestableStreamProcessor processor = new TestableStreamProcessor(new MapConfig(), new HashMap<>(), mock(StreamTaskFactory.class), new ProcessorLifecycleListener() {
@Override
public void beforeStart() {
processorListenerState.put(ListenerCallback.BEFORE_START, true);
}
@Override
public void afterStart() {
processorListenerState.put(ListenerCallback.AFTER_START, true);
}
@Override
public void afterStop() {
processorListenerState.put(ListenerCallback.AFTER_STOP, true);
}
@Override
public void afterFailure(Throwable t) {
processorListenerState.put(ListenerCallback.AFTER_FAILURE, true);
actualThrowable.getAndSet(t);
processorListenerFailed.countDown();
}
}, mockJobCoordinator, mockContainer);
final CountDownLatch coordinatorStop = new CountDownLatch(1);
doAnswer(invocation -> {
coordinatorStop.countDown();
return null;
}).when(mockJobCoordinator).stop();
doAnswer(invocation -> {
new Thread(() -> {
try {
processor.jobCoordinatorListener.onJobModelExpired();
processor.jobCoordinatorListener.onNewJobModel("1", getMockJobModel());
coordinatorStop.await();
processor.jobCoordinatorListener.onCoordinatorStop();
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
return null;
}).when(mockJobCoordinator).start();
processor.start();
// This block is required for the mockRunloop is actually started.
// Otherwise, processor.stop gets triggered before mockRunloop begins to block
runLoopStartedLatch.await();
assertTrue("Container failed and processor listener failed was not invoked within timeout!", processorListenerFailed.await(30, TimeUnit.SECONDS));
assertEquals(expectedThrowable, actualThrowable.get());
assertTrue(processorListenerState.get(ListenerCallback.BEFORE_START));
assertTrue(processorListenerState.get(ListenerCallback.AFTER_START));
Assert.assertFalse(processorListenerState.get(ListenerCallback.AFTER_STOP));
assertTrue(processorListenerState.get(ListenerCallback.AFTER_FAILURE));
}
Aggregations