/*
* Copyright (C) 2006-2016 DLR, Germany
*
* All rights reserved
*
* http://www.rcenvironment.de/
*/
package de.rcenvironment.core.component.workflow.execution.internal;
import java.util.HashSet;
import java.util.Set;
import org.easymock.Capture;
import org.easymock.EasyMock;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import de.rcenvironment.core.component.execution.api.ExecutionControllerException;
import de.rcenvironment.core.component.workflow.execution.api.WorkflowExecutionContext;
import de.rcenvironment.core.utils.common.rpc.RemoteOperationException;
/**
* Test cases for {@link ParallelComponentCaller}.
*
* @author Doreen Seider
*/
public class ParallelComponentCallerTest {
private static final String METHOD_NAME = "method-to-call";
private static final String COMP_EXE_ID_1 = "comp-exe-id-1";
private static final String COMP_EXE_ID_2 = "comp-exe-id-2";
private static final Set<String> COMP_EXE_IDS = new HashSet<>();
/**
* Set up test scenario.
*/
@BeforeClass
public static void setup() {
COMP_EXE_IDS.add(COMP_EXE_ID_1);
COMP_EXE_IDS.add(COMP_EXE_ID_2);
}
/**
* Tests if abstracted methods are called as expected.
* @throws RemoteOperationException on unexpected errors
* @throws ExecutionControllerException on unexpected errors
*/
@Test
public void testCallingComponentSucceeding() throws ExecutionControllerException, RemoteOperationException {
Callbacks callbacksMock = EasyMock.createStrictMock(Callbacks.class);
Capture<String> capturedCompExeId1 = new Capture<>();
callbacksMock.callSingleComponent(EasyMock.capture(capturedCompExeId1));
Capture<String> capturedCompExeId2 = new Capture<>();
callbacksMock.callSingleComponent(EasyMock.capture(capturedCompExeId2));
EasyMock.expect(callbacksMock.getMethodToCallAsString()).andStubReturn(METHOD_NAME);
EasyMock.replay(callbacksMock);
TestableParallelComponentCaller caller = new TestableParallelComponentCaller(COMP_EXE_IDS, createWorkflowExecutionContextMock());
caller.setCallbacks(callbacksMock);
Throwable t = caller.callParallelAndWait();
EasyMock.verify(callbacksMock);
Assert.assertNull(t);
assertCallToCallSingleComponent(capturedCompExeId1, capturedCompExeId2);
}
/**
* Tests if abstracted methods are called as expected.
* @throws RemoteOperationException on unexpected errors
* @throws ExecutionControllerException on unexpected errors
*/
@Test
public void testCallingThrowingRuntimeException() throws ExecutionControllerException, RemoteOperationException {
testCallingComponentThrowingAnException(new ExecutionControllerException("ece-exe-message"));
testCallingComponentThrowingAnException(new RuntimeException());
testCallingComponentThrowingAnException(new RemoteOperationException("roe-exe-message"));
}
private void testCallingComponentThrowingAnException(Exception e) throws ExecutionControllerException, RemoteOperationException {
Callbacks callbacksMock = EasyMock.createStrictMock(Callbacks.class);
Capture<String> capturedCompExeId1 = new Capture<>();
callbacksMock.callSingleComponent(EasyMock.capture(capturedCompExeId1));
Capture<String> capturedCompExeId2 = new Capture<>();
callbacksMock.callSingleComponent(EasyMock.capture(capturedCompExeId2));
EasyMock.expectLastCall().andThrow(e);
EasyMock.expect(callbacksMock.getMethodToCallAsString()).andStubReturn(METHOD_NAME);
EasyMock.replay(callbacksMock);
TestableParallelComponentCaller caller = new TestableParallelComponentCaller(COMP_EXE_IDS, createWorkflowExecutionContextMock());
caller.setCallbacks(callbacksMock);
String methodName = caller.getMethodToCallAsString();
Throwable t = caller.callParallelAndWait();
EasyMock.verify(callbacksMock);
Assert.assertEquals(METHOD_NAME, methodName);
Assert.assertTrue(t.getMessage().contains("Failed to"));
Assert.assertEquals(e, t.getCause());
assertCallToCallSingleComponent(capturedCompExeId1, capturedCompExeId2);
}
private void assertCallToCallSingleComponent(Capture<String> capturedCompExeId1, Capture<String> capturedCompExeId2) {
Assert.assertEquals(1, capturedCompExeId1.getValues().size());
Assert.assertEquals(1, capturedCompExeId2.getValues().size());
Assert.assertNotSame(capturedCompExeId1.getValues().get(0), capturedCompExeId2.getValues().get(0));
Assert.assertTrue(COMP_EXE_IDS.contains(capturedCompExeId1.getValues().get(0)));
Assert.assertTrue(COMP_EXE_IDS.contains(capturedCompExeId2.getValues().get(0)));
}
private WorkflowExecutionContext createWorkflowExecutionContextMock() {
WorkflowExecutionContext wfExeCtxMock = EasyMock.createStrictMock(WorkflowExecutionContext.class);
EasyMock.expect(wfExeCtxMock.getInstanceName()).andReturn("wf");
EasyMock.expect(wfExeCtxMock.getExecutionIdentifier()).andReturn("exe id");
EasyMock.replay(wfExeCtxMock);
return wfExeCtxMock;
}
/**
* Stub implementation of {@link ParallelComponentCaller}.
*
* @author Doreen Seider
*/
private class TestableParallelComponentCaller extends ParallelComponentCaller {
private Callbacks callbacks;
protected TestableParallelComponentCaller(Set<String> componentsToConsider, WorkflowExecutionContext wfExeCtx) {
super(componentsToConsider, wfExeCtx);
}
@Override
protected void callSingleComponent(String compExeId) throws ExecutionControllerException, RemoteOperationException {
callbacks.callSingleComponent(compExeId);
}
@Override
protected String getMethodToCallAsString() {
return callbacks.getMethodToCallAsString();
}
private void setCallbacks(Callbacks callbacks) {
this.callbacks = callbacks;
}
}
/**
* Interface used to recognize abstract method calls.
*
* @author Doreen Seider
*/
private interface Callbacks {
void callSingleComponent(String compExeId) throws ExecutionControllerException, RemoteOperationException;
String getMethodToCallAsString();
}
}