/* * Copyright (c) MuleSoft, Inc. All rights reserved. http://www.mulesoft.com * The software in this package is published under the terms of the CPAL v1.0 * license, a copy of which has been included with this distribution in the * LICENSE.txt file. */ package org.mule.runtime.core.message.processing; import static org.mockito.Matchers.any; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import org.mule.runtime.core.api.exception.SystemExceptionHandler; import org.mule.runtime.core.execution.EndPhaseTemplate; import org.mule.runtime.core.execution.EndProcessPhase; import org.mule.runtime.core.execution.MessageProcessContext; import org.mule.runtime.core.execution.MessageProcessPhase; import org.mule.runtime.core.execution.MessageProcessTemplate; import org.mule.runtime.core.execution.PhaseExecutionEngine; import org.mule.runtime.core.execution.PhaseResultNotifier; import org.mule.tck.size.SmallTest; import java.util.ArrayList; import java.util.List; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Answers; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.invocation.InvocationOnMock; import org.mockito.runners.MockitoJUnitRunner; import org.mockito.stubbing.Answer; @RunWith(MockitoJUnitRunner.class) @SmallTest public class PhaseExecutionEngineTestCase { @Mock(answer = Answers.RETURNS_DEEP_STUBS) private SystemExceptionHandler mockExceptionHandler; private List<MessageProcessPhase> phaseList = new ArrayList<MessageProcessPhase>(); @Mock(answer = Answers.RETURNS_DEEP_STUBS) private EndProcessPhase mockEndPhase; @Mock(answer = Answers.RETURNS_DEEP_STUBS) private MessageProcessPhase mockProcessPhase1; @Mock(answer = Answers.RETURNS_DEEP_STUBS) private MessageProcessPhase mockProcessPhase2; @Mock(answer = Answers.RETURNS_DEEP_STUBS) private MessageProcessPhase mockProcessPhase3; @Mock(answer = Answers.RETURNS_DEEP_STUBS) private MessageProcessPhase mockFailingPhase; @Mock(answer = Answers.RETURNS_DEEP_STUBS) private EndPhaseTemplate mockTemplate; @Mock(answer = Answers.RETURNS_DEEP_STUBS) private MessageProcessContext mockContext; @Mock(answer = Answers.RETURNS_DEEP_STUBS) private PhaseResultNotifier mockNotifier; @Test public void allPhasesRun() throws Exception { when(mockEndPhase.supportsTemplate(mockTemplate)).thenReturn(true); verifyAllPhasesAreRun(); verify(mockEndPhase, Mockito.times(1)).runPhase(any(EndPhaseTemplate.class), any(MessageProcessContext.class), any(PhaseResultNotifier.class)); } @Test public void endPhaseDoesNotRun() throws Exception { when(mockEndPhase.supportsTemplate(mockTemplate)).thenReturn(false); verifyAllPhasesAreRun(); verify(mockEndPhase, Mockito.times(0)).runPhase(any(EndPhaseTemplate.class), any(MessageProcessContext.class), any(PhaseResultNotifier.class)); } @Test public void exceptionHandlerIsCalledOnFailure() throws Exception { addSupportedPhase(mockFailingPhase); addSupportedPhase(mockProcessPhase1); when(mockEndPhase.supportsTemplate(mockTemplate)).thenReturn(true); PhaseExecutionEngine phaseExecutionEngine = new PhaseExecutionEngine(phaseList, mockExceptionHandler, mockEndPhase); phaseExecutionEngine.process(mockTemplate, mockContext); verify(mockEndPhase, times(1)).runPhase(any(EndPhaseTemplate.class), any(MessageProcessContext.class), any(PhaseResultNotifier.class)); } @Test public void phaseItsNoSupportedThenNextPhaseExecutes() throws Exception { addSupportedPhase(mockProcessPhase1); addNotSupportedPhase(mockProcessPhase2); addSupportedPhase(mockProcessPhase3); when(mockProcessPhase2.supportsTemplate(mockTemplate)).thenReturn(false); PhaseExecutionEngine phaseExecutionEngine = new PhaseExecutionEngine(phaseList, mockExceptionHandler, mockEndPhase); phaseExecutionEngine.process(mockTemplate, mockContext); verify(mockProcessPhase1, times(1)).runPhase(any(EndPhaseTemplate.class), any(MessageProcessContext.class), any(PhaseResultNotifier.class)); verify(mockProcessPhase2, times(0)).runPhase(any(EndPhaseTemplate.class), any(MessageProcessContext.class), any(PhaseResultNotifier.class)); verify(mockProcessPhase3, times(1)).runPhase(any(EndPhaseTemplate.class), any(MessageProcessContext.class), any(PhaseResultNotifier.class)); } private void verifyAllPhasesAreRun() { PhaseExecutionEngine engine = new PhaseExecutionEngine(phaseList, mockExceptionHandler, mockEndPhase); addAllPhases(); engine.process(mockTemplate, mockContext); verify(mockProcessPhase1, Mockito.times(1)).runPhase(any(MessageProcessTemplate.class), any(MessageProcessContext.class), any(PhaseResultNotifier.class)); verify(mockProcessPhase2, Mockito.times(1)).runPhase(any(MessageProcessTemplate.class), any(MessageProcessContext.class), any(PhaseResultNotifier.class)); verify(mockProcessPhase3, Mockito.times(1)).runPhase(any(MessageProcessTemplate.class), any(MessageProcessContext.class), any(PhaseResultNotifier.class)); } private void addAllPhases() { addSupportedPhase(mockProcessPhase1); addSupportedPhase(mockProcessPhase2); addSupportedPhase(mockProcessPhase3); } private void addSupportedPhase(MessageProcessPhase mockProcessPhase) { addPhase(mockProcessPhase, true); } private void addNotSupportedPhase(MessageProcessPhase mockProcessPhase) { addPhase(mockProcessPhase, false); } private void addPhase(MessageProcessPhase mockProcessPhase, boolean supportsTemplate) { phaseList.add(mockProcessPhase); when(mockProcessPhase.supportsTemplate(mockTemplate)).thenReturn(supportsTemplate); Mockito.doAnswer(new Answer() { @Override public Object answer(InvocationOnMock invocationOnMock) throws Throwable { ((PhaseResultNotifier) invocationOnMock.getArguments()[2]).phaseSuccessfully(); return null; } }).when(mockProcessPhase).runPhase(any(MessageProcessTemplate.class), any(MessageProcessContext.class), any(PhaseResultNotifier.class)); } }