Source:
<code>public void testStopByProcessor() { 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 StreamProcessorLifecycleListener() { @Override public void onStart() { processorListenerStart.countDown(); } @Override public void onShutdown() { processorListenerStop.countDown(); } @Override public void onFailure(Throwable t) { <START> <END> } }, mockJobCoordinator, null); final CountDownLatch coordinatorStop = new CountDownLatch(1); final Thread jcThread = new Thread(() -> { try { 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(); try { processor.start(); processorListenerStart.await(); Assert.assertEquals(SamzaContainerStatus.STARTED, processor.container.getStatus()); processor.runLoopStartForMain.await(); processor.stop(); processorListenerStop.await(); } catch (InterruptedException e) { e.printStackTrace(); } }</code><technical_language>Similar below, is worth asserting failure is called a clean shutdown (though worried this case)</technical_language>

Target:
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 StreamProcessorLifecycleListener() { @Override public void onStart() { processorListenerState.put(ListenerCallback.ON_START, true); processorListenerStart.countDown(); } @Override public void onShutdown() { processorListenerState.put(ListenerCallback.ON_SHUTDOWN, true); processorListenerStop.countDown(); } @Override public void onFailure(Throwable t) { processorListenerState.put(ListenerCallback.ON_FAILURE, true); } }, mockJobCoordinator, null); final CountDownLatch coordinatorStop = new CountDownLatch(1); final Thread jcThread = new Thread(() -> { try { 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(); Assert.assertEquals(SamzaContainerStatus.STARTED, processor.getContainerStatus()); processor.runLoopStartForMain.await(); processor.stop(); processorListenerStop.await(); Assert.assertTrue(processorListenerState.get(ListenerCallback.ON_START)); Assert.assertTrue(processorListenerState.get(ListenerCallback.ON_SHUTDOWN)); Assert.assertFalse(processorListenerState.get(ListenerCallback.ON_FAILURE)); }