Source:
public void testContainerFailureCorrectlyStopsProcessor() { JobCoordinator mockJobCoordinator = 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 { Thread.sleep(10); 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 StreamProcessorLifecycleListener() { @Override public void onStart() { } @Override public void onShutdown() { } @Override public void onFailure(Throwable t) { 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.onNewJobModel("1", getMockJobModel()); coordinatorStop.await(); processor.jobCoordinatorListener.onCoordinatorStop(); } catch (InterruptedException e) { e.printStackTrace(); } }).start(); return null; }).when(mockJobCoordinator).start(); try { processor.start(); runLoopStartedLatch.await(); Assert.assertTrue( "Container failed and processor listener failed was not invoked within timeout!", processorListenerFailed.await(30, TimeUnit.SECONDS)); Assert.assertEquals(expectedThrowable, actualThrowable.get()); } catch (InterruptedException e) { e.printStackTrace(); } }

Target:
public void testContainerFailureCorrectlyStopsProcessor() throws InterruptedException { JobCoordinator mockJobCoordinator = 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 StreamProcessorLifecycleListener() { @Override public void onStart() { processorListenerState.put(ListenerCallback.ON_START, true); } @Override public void onShutdown() { processorListenerState.put(ListenerCallback.ON_SHUTDOWN, true); } @Override public void onFailure(Throwable t) { processorListenerState.put(ListenerCallback.ON_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.onNewJobModel("1", getMockJobModel()); coordinatorStop.await(); processor.jobCoordinatorListener.onCoordinatorStop(); } catch (InterruptedException e) { e.printStackTrace(); } }).start(); return null; }).when(mockJobCoordinator).start(); processor.start(); runLoopStartedLatch.await(); Assert.assertTrue( "Container failed and processor listener failed was not invoked within timeout!", processorListenerFailed.await(30, TimeUnit.SECONDS)); Assert.assertEquals(expectedThrowable, actualThrowable.get()); Assert.assertFalse(processorListenerState.get(ListenerCallback.ON_SHUTDOWN)); Assert.assertTrue(processorListenerState.get(ListenerCallback.ON_START)); Assert.assertTrue(processorListenerState.get(ListenerCallback.ON_FAILURE)); }