private ComponentStateMachine createComponentStateMachineEventForRuns( Capture<ComponentStateMachineEvent> compStateMachineEventCapture) { ComponentStateMachine compStateMachineMock = EasyMock.createStrictMock(ComponentStateMachine.class); compStateMachineMock.postEvent(EasyMock.capture(compStateMachineEventCapture)); EasyMock.expectLastCall(); EasyMock.replay(compStateMachineMock); return compStateMachineMock; }
/** * Tests canceling of {@link Component#processInputs()} in failure case, that means {@link * Component#processInputs()} doesn't return within expected amount of time. * * @throws ComponentExecutionException on unexpected error * @throws ComponentException on unexpected error * @throws InterruptedException on unexpected error * @throws ExecutionException on unexpected error */ @Test(timeout = TEST_TIMEOUT_500_MSEC) public void testCancelProcessingInputsFailure() throws ComponentExecutionException, ComponentException, InterruptedException, ExecutionException { ComponentExecutionRelatedInstances compExeRelatedInstancesStub = createComponentExecutionRelatedInstancesStub(); final CountDownLatch processInputsCalledLatch = new CountDownLatch(1); Component compStub = new ComponentDefaultStub.Default() { private int processInputsCount = 0; private int onProcessInputsInterruptedCount = 0; @Override public void processInputs() throws ComponentException { if (processInputsCount > 0) { fail("'processInputs' is expected to be called only once"); } processInputsCalledLatch.countDown(); final CountDownLatch dummyLatch = new CountDownLatch(1); while (true) { try { dummyLatch.await(); } catch (InterruptedException e) { // ignore for test purposes e = null; } } } @Override public void onProcessInputsInterrupted(ThreadHandler executingThreadHandler) { if (onProcessInputsInterruptedCount > 0) { fail("'onProcessInputsInterrupted' is expected to be called only once"); } } }; compExeRelatedInstancesStub.component.set(compStub); ComponentStateMachine compStateMachineMock = EasyMock.createStrictMock(ComponentStateMachine.class); Capture<ComponentStateMachineEvent> compStateMachineEventCapture = new Capture<>(); compStateMachineMock.postEvent(EasyMock.capture(compStateMachineEventCapture)); EasyMock.expectLastCall(); EasyMock.replay(compStateMachineMock); compExeRelatedInstancesStub.compStateMachine = compStateMachineMock; ComponentExecutionStorageBridge compExeStorageBridgeMock = createComponentExecutionStorageBridgeRunFailure(compExeRelatedInstancesStub); compExeRelatedInstancesStub.compExeStorageBridge = compExeStorageBridgeMock; ComponentContextBridge compCtxBridgeMock = EasyMock.createStrictMock(ComponentContextBridge.class); EasyMock.expect(compCtxBridgeMock.getEndpointDatumsForExecution()) .andStubReturn(new HashMap<String, EndpointDatum>()); EasyMock.replay(compCtxBridgeMock); compExeRelatedInstancesStub.compCtxBridge = compCtxBridgeMock; compExeRelatedInstancesStub.compExeScheduler = createComponentExecutionSchedulerMock(false); Capture<ConsoleRow.Type> consoleRowTypeCapture = new Capture<>(); Capture<String> logMessageCapture = new Capture<>(); ConsoleRowsSender consoleRowsSenderMock = createConsoleRowsSenderMock(consoleRowTypeCapture, logMessageCapture); compExeRelatedInstancesStub.consoleRowsSender = consoleRowsSenderMock; ComponentExecutionStatsService compExeStatsServiceMock = createComponentExecutionStatsServiceMock(compExeRelatedInstancesStub); final ComponentExecutor compExecutor = new ComponentExecutor(compExeRelatedInstancesStub, ComponentExecutionType.ProcessInputs); compExecutor.bindComponentExecutionPermitsService(createComponentExecutionPermitServiceMock()); compExecutor.bindComponentExecutionStatsService(compExeStatsServiceMock); ComponentExecutor.waitIntervalAfterCacelledCalledMSec = WAIT_INTERVAL_100_MSEC; final AtomicReference<Exception> expectedExceptionRef = new AtomicReference<Exception>(null); final CountDownLatch executedLatch = new CountDownLatch(1); final Future<?> executeTask = ConcurrencyUtils.getAsyncTaskService() .submit( new Runnable() { @Override public void run() { try { compExecutor.executeByConsideringLimitations(); } catch (ComponentException | ComponentExecutionException e) { expectedExceptionRef.set(e); } executedLatch.countDown(); } }); processInputsCalledLatch.await(); compExecutor.onCancelled(); executeTask.cancel(true); executedLatch.await(); assertNotNull(expectedExceptionRef.get()); assertTrue(expectedExceptionRef.get() instanceof ComponentException); assertFailureHandling( consoleRowTypeCapture, logMessageCapture, (ComponentException) expectedExceptionRef.get(), "didn't terminate in time"); assertTrue(compExeRelatedInstancesStub.compExeRelatedStates.isComponentCancelled.get()); EasyMock.verify(compStateMachineMock); assertEquals( ComponentStateMachineEventType.RUNNING, compStateMachineEventCapture.getValue().getType()); assertEquals( ComponentState.PROCESSING_INPUTS, compStateMachineEventCapture.getValue().getNewComponentState()); EasyMock.verify(compExeStorageBridgeMock); EasyMock.verify(consoleRowsSenderMock); }