/* * Copyright (C) 2006-2016 DLR, Germany * * All rights reserved * * http://www.rcenvironment.de/ */ package de.rcenvironment.core.component.execution.internal; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import org.easymock.Capture; import org.easymock.EasyMock; import org.junit.Test; import de.rcenvironment.core.component.execution.api.ComponentExecutionContext; import de.rcenvironment.core.component.execution.api.ComponentState; import de.rcenvironment.core.component.execution.api.ConsoleRow; import de.rcenvironment.core.component.execution.api.ExecutionControllerException; import de.rcenvironment.core.component.execution.api.WorkflowExecutionControllerCallbackService; import de.rcenvironment.core.utils.common.rpc.RemoteOperationException; /** * Test cases for {@link WorkflowExecutionControllerBridgeDelegator}. * * @author Doreen Seider */ public class WorkflowExecutionControllerBridgeDelegatorTest { private static final String EXECEPTION_MESSAGE = "exeception message"; private static final String SERIALIZED_TYPED_DATUM = "ser-td"; private static final String ERR_ID = "err-id"; private static final String ERR_MSG = "failure"; private static final String EXE_COUNT_ON_RESET = "5"; private static final int EXE_COUNT = 5; private static final ComponentState COMP_STATE = ComponentState.CANCELED; private static final String COMP_EXE_ID = "comp-exe-id"; private static final String WF_EXE_ID = "wf-exe-id"; private ConsoleRow[] consoleRows = new ConsoleRow[5]; /** * Tests the callback {@link WorkflowExecutionControllerBridgeDelegator#onConsoleRowsProcessed(ConsoleRow[])} in success and failure * case. * * @throws ExecutionControllerException on unexpected error * @throws RemoteOperationException on unexpected error */ @Test public void testOnConsoleRowsProcessedCallback() throws ExecutionControllerException, RemoteOperationException { WorkflowExecutionControllerCallbackService wfExeCtrlBridgeMock = EasyMock.createStrictMock(WorkflowExecutionControllerCallbackService.class); wfExeCtrlBridgeMock.onConsoleRowsProcessed(WF_EXE_ID, consoleRows); EasyMock.expectLastCall().andThrow(new RemoteOperationException(EXECEPTION_MESSAGE)).times(1); EasyMock.replay(wfExeCtrlBridgeMock); Capture<ComponentStateMachineEvent> eventCapture = new Capture<>(); ComponentStateMachine compStateMachineMock = createComponentStateMachineMockExpectingFailureEvent(eventCapture); WorkflowExecutionControllerBridgeDelegator wfExeCtrlBridgeDelegator = new WorkflowExecutionControllerBridgeDelegator(createCompExeRelatedInstancesStub(createComponentExecutionMock(), compStateMachineMock, wfExeCtrlBridgeMock)); verifyWorkflowControllerReachable(eventCapture, wfExeCtrlBridgeDelegator); wfExeCtrlBridgeDelegator.processConsoleRows(consoleRows); verifyWorkflowControllerNotReachable(eventCapture, compStateMachineMock, wfExeCtrlBridgeDelegator); // to ensure even if called twice, the failure is posted to the state machine only once wfExeCtrlBridgeDelegator.processConsoleRows(consoleRows); verifyMocks(wfExeCtrlBridgeMock, compStateMachineMock); } /** * Tests the callback * {@link WorkflowExecutionControllerBridgeDelegator#onComponentStateChanged(String, ComponentState, Integer, String, String, String)} * in success and failure case. * * @throws ExecutionControllerException on unexpected error * @throws RemoteOperationException on unexpected error */ @Test public void testOnComponentStateChangedCallback() throws ExecutionControllerException, RemoteOperationException { WorkflowExecutionControllerCallbackService wfExeCtrlBridgeMock = EasyMock.createStrictMock(WorkflowExecutionControllerCallbackService.class); wfExeCtrlBridgeMock.onComponentStateChanged(WF_EXE_ID, COMP_EXE_ID, COMP_STATE, EXE_COUNT, EXE_COUNT_ON_RESET, ERR_ID, ERR_MSG); EasyMock.expectLastCall().andThrow(new RemoteOperationException(EXECEPTION_MESSAGE)).times(1); EasyMock.replay(wfExeCtrlBridgeMock); Capture<ComponentStateMachineEvent> eventCapture = new Capture<>(); ComponentStateMachine compStateMachineMock = createComponentStateMachineMockExpectingFailureEvent(eventCapture); WorkflowExecutionControllerBridgeDelegator wfExeCtrlBridgeDelegator = new WorkflowExecutionControllerBridgeDelegator(createCompExeRelatedInstancesStub(createComponentExecutionMock(), compStateMachineMock, wfExeCtrlBridgeMock)); verifyWorkflowControllerReachable(eventCapture, wfExeCtrlBridgeDelegator); wfExeCtrlBridgeDelegator.onComponentStateChanged(COMP_EXE_ID, COMP_STATE, EXE_COUNT, EXE_COUNT_ON_RESET, ERR_ID, ERR_MSG); verifyWorkflowControllerNotReachable(eventCapture, compStateMachineMock, wfExeCtrlBridgeDelegator); // to ensure even if called twice, the failure is posted to the state machine only once wfExeCtrlBridgeDelegator.onComponentStateChanged(COMP_EXE_ID, COMP_STATE, EXE_COUNT, EXE_COUNT_ON_RESET, ERR_ID, ERR_MSG); verifyMocks(wfExeCtrlBridgeMock, compStateMachineMock); } /** * Tests the callback {@link WorkflowExecutionControllerBridgeDelegator#onInputProcessed(String)} in success and failure case. * * @throws ExecutionControllerException on unexpected error * @throws RemoteOperationException on unexpected error */ @Test public void testOnInputProcessedCallback() throws ExecutionControllerException, RemoteOperationException { WorkflowExecutionControllerCallbackService wfExeCtrlBridgeMock = EasyMock.createStrictMock(WorkflowExecutionControllerCallbackService.class); wfExeCtrlBridgeMock.onInputProcessed(WF_EXE_ID, SERIALIZED_TYPED_DATUM); EasyMock.expectLastCall().andThrow(new RemoteOperationException(EXECEPTION_MESSAGE)); wfExeCtrlBridgeMock.onInputProcessed(WF_EXE_ID, SERIALIZED_TYPED_DATUM); EasyMock.expectLastCall(); wfExeCtrlBridgeMock.onInputProcessed(WF_EXE_ID, SERIALIZED_TYPED_DATUM); EasyMock.expectLastCall().andThrow(new RemoteOperationException(EXECEPTION_MESSAGE)).times(5); EasyMock.replay(wfExeCtrlBridgeMock); Capture<ComponentStateMachineEvent> eventCapture = new Capture<>(); ComponentStateMachine compStateMachineMock = createComponentStateMachineMockExpectingFailureEvent(eventCapture); WorkflowExecutionControllerBridgeDelegator wfExeCtrlBridgeDelegator = new WorkflowExecutionControllerBridgeDelegator(createCompExeRelatedInstancesStub(createComponentExecutionMock(), compStateMachineMock, wfExeCtrlBridgeMock)); verifyWorkflowControllerReachable(eventCapture, wfExeCtrlBridgeDelegator); wfExeCtrlBridgeDelegator.onInputProcessed(SERIALIZED_TYPED_DATUM); verifyWorkflowControllerReachable(eventCapture, wfExeCtrlBridgeDelegator); wfExeCtrlBridgeDelegator.onInputProcessed(SERIALIZED_TYPED_DATUM); verifyWorkflowControllerReachable(eventCapture, wfExeCtrlBridgeDelegator); wfExeCtrlBridgeDelegator.onInputProcessed(SERIALIZED_TYPED_DATUM); verifyWorkflowControllerReachable(eventCapture, wfExeCtrlBridgeDelegator); wfExeCtrlBridgeDelegator.onInputProcessed(SERIALIZED_TYPED_DATUM); verifyWorkflowControllerReachable(eventCapture, wfExeCtrlBridgeDelegator); wfExeCtrlBridgeDelegator.onInputProcessed(SERIALIZED_TYPED_DATUM); verifyWorkflowControllerReachable(eventCapture, wfExeCtrlBridgeDelegator); wfExeCtrlBridgeDelegator.onInputProcessed(SERIALIZED_TYPED_DATUM); verifyWorkflowControllerReachable(eventCapture, wfExeCtrlBridgeDelegator); wfExeCtrlBridgeDelegator.onInputProcessed(SERIALIZED_TYPED_DATUM); verifyWorkflowControllerNotReachable(eventCapture, compStateMachineMock, wfExeCtrlBridgeDelegator); wfExeCtrlBridgeDelegator.onInputProcessed(SERIALIZED_TYPED_DATUM); verifyMocks(wfExeCtrlBridgeMock, compStateMachineMock); } /** * Tests the callback {@link WorkflowExecutionControllerBridgeDelegator#onComponentHeartbeatReceived(String))} in success and failure * case. * * @throws ExecutionControllerException on unexpected error * @throws RemoteOperationException on unexpected error */ @Test public void testOnComponentHeartbeatReceivedCallback() throws ExecutionControllerException, RemoteOperationException { WorkflowExecutionControllerCallbackService wfExeCtrlBridgeMock = EasyMock.createStrictMock(WorkflowExecutionControllerCallbackService.class); wfExeCtrlBridgeMock.onComponentHeartbeatReceived(WF_EXE_ID, COMP_EXE_ID); EasyMock.expectLastCall().andThrow(new RemoteOperationException(EXECEPTION_MESSAGE)); wfExeCtrlBridgeMock.onComponentHeartbeatReceived(WF_EXE_ID, COMP_EXE_ID); EasyMock.expectLastCall(); wfExeCtrlBridgeMock.onComponentHeartbeatReceived(WF_EXE_ID, COMP_EXE_ID); EasyMock.expectLastCall().andThrow(new RemoteOperationException(EXECEPTION_MESSAGE)).times(5); EasyMock.replay(wfExeCtrlBridgeMock); Capture<ComponentStateMachineEvent> eventCapture = new Capture<>(); ComponentStateMachine compStateMachineMock = createComponentStateMachineMockExpectingFailureEvent(eventCapture); WorkflowExecutionControllerBridgeDelegator wfExeCtrlBridgeDelegator = new WorkflowExecutionControllerBridgeDelegator(createCompExeRelatedInstancesStub(createComponentExecutionMock(), compStateMachineMock, wfExeCtrlBridgeMock)); verifyWorkflowControllerReachable(eventCapture, wfExeCtrlBridgeDelegator); wfExeCtrlBridgeDelegator.onComponentHeartbeatReceived(COMP_EXE_ID); verifyWorkflowControllerReachable(eventCapture, wfExeCtrlBridgeDelegator); wfExeCtrlBridgeDelegator.onComponentHeartbeatReceived(COMP_EXE_ID); verifyWorkflowControllerReachable(eventCapture, wfExeCtrlBridgeDelegator); wfExeCtrlBridgeDelegator.onComponentHeartbeatReceived(COMP_EXE_ID); verifyWorkflowControllerReachable(eventCapture, wfExeCtrlBridgeDelegator); wfExeCtrlBridgeDelegator.onComponentHeartbeatReceived(COMP_EXE_ID); verifyWorkflowControllerReachable(eventCapture, wfExeCtrlBridgeDelegator); wfExeCtrlBridgeDelegator.onComponentHeartbeatReceived(COMP_EXE_ID); verifyWorkflowControllerReachable(eventCapture, wfExeCtrlBridgeDelegator); wfExeCtrlBridgeDelegator.onComponentHeartbeatReceived(COMP_EXE_ID); verifyWorkflowControllerReachable(eventCapture, wfExeCtrlBridgeDelegator); wfExeCtrlBridgeDelegator.onComponentHeartbeatReceived(COMP_EXE_ID); verifyWorkflowControllerNotReachable(eventCapture, compStateMachineMock, wfExeCtrlBridgeDelegator); // to ensure even if called twice, the failure is posted to the state machine only once wfExeCtrlBridgeDelegator.onComponentHeartbeatReceived(COMP_EXE_ID); verifyMocks(wfExeCtrlBridgeMock, compStateMachineMock); } private void verifyMocks(WorkflowExecutionControllerCallbackService wfExeCtrlBridgeMock, ComponentStateMachine compStateMachineMock) { EasyMock.verify(wfExeCtrlBridgeMock); EasyMock.verify(compStateMachineMock); } private void verifyWorkflowControllerReachable(Capture<ComponentStateMachineEvent> eventCapture, WorkflowExecutionControllerBridgeDelegator wfExeCtrlBridgeDelegator) { assertTrue(wfExeCtrlBridgeDelegator.isWorkflowControllerReachable()); assertFalse(eventCapture.hasCaptured()); } private void verifyWorkflowControllerNotReachable(Capture<ComponentStateMachineEvent> eventCapture, ComponentStateMachine compStateMachineMock, WorkflowExecutionControllerBridgeDelegator wfExeCtrlBridgeDelegator) { assertFalse(wfExeCtrlBridgeDelegator.isWorkflowControllerReachable()); assertTrue(eventCapture.hasCaptured()); assertEquals(1, eventCapture.getValues().size()); assertEquals(ComponentStateMachineEventType.WF_CRTL_CALLBACK_FAILED, eventCapture.getValues().get(0).getType()); } private ComponentExecutionContext createComponentExecutionMock() { ComponentExecutionContext compExeCtxMock = EasyMock.createStrictMock(ComponentExecutionContext.class); EasyMock.expect(compExeCtxMock.getExecutionIdentifier()).andStubReturn(COMP_EXE_ID); EasyMock.expect(compExeCtxMock.getInstanceName()).andStubReturn("comp inst name"); EasyMock.expect(compExeCtxMock.getWorkflowExecutionIdentifier()).andStubReturn(WF_EXE_ID); EasyMock.expect(compExeCtxMock.getWorkflowInstanceName()).andStubReturn("wf inst name"); EasyMock.replay(compExeCtxMock); return compExeCtxMock; } private ComponentStateMachine createComponentStateMachineMockExpectingFailureEvent(Capture<ComponentStateMachineEvent> eventCapture) { ComponentStateMachine compStateMachineMock = EasyMock.createStrictMock(ComponentStateMachine.class); compStateMachineMock.postEvent(EasyMock.capture(eventCapture)); EasyMock.replay(compStateMachineMock); return compStateMachineMock; } private ComponentExecutionRelatedInstances createCompExeRelatedInstancesStub(ComponentExecutionContext compExeCtx, ComponentStateMachine compStateMachine, WorkflowExecutionControllerCallbackService wfExeCtrlBridge) { ComponentExecutionRelatedInstances compExeRelatedInstances = new ComponentExecutionRelatedInstances(); compExeRelatedInstances.compExeCtx = compExeCtx; compExeRelatedInstances.compStateMachine = compStateMachine; compExeRelatedInstances.wfExeCtrlBridge = wfExeCtrlBridge; return compExeRelatedInstances; } }