package cz.cuni.mff.d3s.been.hostruntime;
import static cz.cuni.mff.d3s.been.core.task.TaskExclusivity.*;
import static org.mockito.Mockito.*;
import java.io.IOException;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import com.hazelcast.core.IMap;
import cz.cuni.mff.d3s.been.cluster.context.ClusterContext;
import cz.cuni.mff.d3s.been.cluster.context.Runtimes;
import cz.cuni.mff.d3s.been.core.ri.RuntimeInfo;
import cz.cuni.mff.d3s.been.core.task.TaskDescriptor;
import cz.cuni.mff.d3s.been.core.task.TaskExclusivity;
import cz.cuni.mff.d3s.been.hostruntime.task.TaskHandle;
import cz.cuni.mff.d3s.been.hostruntime.task.TaskProcess;
/**
*
*
* @author Martin Sixta
*/
public class ProcessManagerContextTest extends Assert {
private static final String runtimeId = "851e0f34-9271-4c2f-a970-4cbcac5f033e";
private static final String taskId1 = "bd6dbca3-9825-4b16-9bbe-447e6333a3d9";
private static final String taskId2 = "dc7750c7-f661-4c26-bf82-ccadeba3f524";
private static final String contextId1 = "1234567890";
private static final String contextId2 = "0987654321";
@Rule
public TemporaryFolder tmp = new TemporaryFolder();
@Mock
private TaskProcess process1;
@Mock
private Runtimes runtimes;
@Mock
private ClusterContext clusterContext;
@Mock
private TaskDescriptor taskDescriptor1;
@Mock
private TaskDescriptor taskDescriptor2;
@Mock
private TaskHandle taskHandle1;
@Mock
private TaskHandle taskHandle2;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
when(clusterContext.getRuntimes()).thenReturn(runtimes);
}
// ------------------------------------------------------------------------
// IN NON_EXCLUSIVE
// ------------------------------------------------------------------------
@Test
public void testAcceptNonExclusiveInNonExclusive() throws IOException {
RuntimeInfo runtimeInfo = createRuntimeInfo();
testAcceptTaskTemplate(NON_EXCLUSIVE, null, runtimeInfo);
}
@Test
public void testAcceptSecondNonExclusiveInNonExclusive() throws IOException {
testAcceptSecondTemplate(NON_EXCLUSIVE, NON_EXCLUSIVE, null);
}
@Test(expected = IllegalStateException.class)
public void testRejectSecondExclusiveInNonExclusive() throws IOException {
testRejectSecondTemplate(NON_EXCLUSIVE, EXCLUSIVE, null);
}
@Test(expected = IllegalStateException.class)
public void testRejectSecondContextExclusiveInNonExclusive() throws IOException {
testRejectSecondTemplate(NON_EXCLUSIVE, CONTEXT_EXCLUSIVE, null);
}
// ------------------------------------------------------------------------
// IN EXCLUSIVE
// ------------------------------------------------------------------------
@Test
public void testAcceptExclusiveInNonExclusive() throws IOException {
RuntimeInfo runtimeInfo = createRuntimeInfo();
testAcceptTaskTemplate(EXCLUSIVE, taskId1, runtimeInfo);
}
@Test(expected = IllegalStateException.class)
public void testRejectSecondNonExclusiveInExclusive() throws IOException {
testRejectSecondTemplate(EXCLUSIVE, NON_EXCLUSIVE, taskId1);
}
@Test(expected = IllegalStateException.class)
public void testRejectSecondExclusiveInExclusive() throws IOException {
testRejectSecondTemplate(EXCLUSIVE, EXCLUSIVE, taskId1);
}
@Test(expected = IllegalStateException.class)
public void testRejectSecondContextExclusiveInExclusive() throws IOException {
testRejectSecondTemplate(EXCLUSIVE, CONTEXT_EXCLUSIVE, taskId1);
}
// ------------------------------------------------------------------------
// IN CONTEXT_EXCLUSIVE
// ------------------------------------------------------------------------
@Test
public void testAcceptContextExclusiveInNonExclusive() throws IOException {
RuntimeInfo runtimeInfo = createRuntimeInfo();
testAcceptTaskTemplate(CONTEXT_EXCLUSIVE, contextId1, runtimeInfo);
}
@Test
public void testAcceptSecondContextExclusiveInContextExclusiveSameContext() throws IOException {
testAcceptSecondTemplate(CONTEXT_EXCLUSIVE, CONTEXT_EXCLUSIVE, contextId1);
}
@Test(expected = IllegalStateException.class)
public void testRejectSecondContextExclusiveInContextExclusiveDifferentContext() throws IOException {
RuntimeInfo runtimeInfo = createRuntimeInfo();
ProcessManagerContext managerContext = new ProcessManagerContext(clusterContext, runtimeInfo);
setUpTaskHandle(taskHandle1, CONTEXT_EXCLUSIVE, taskId1, contextId1);
setUpTaskHandle(taskHandle2, CONTEXT_EXCLUSIVE, taskId2, contextId2);
try {
managerContext.tryAcceptTask(taskHandle1);
} catch (Exception e) {
assertFalse(true); // no exception allowed
}
try {
managerContext.tryAcceptTask(taskHandle2);
} finally {
verifySetAcceptedCalled(taskHandle1);
verifySetAcceptedNotCalled(taskHandle2);
verifyMangerContext(managerContext, 1, CONTEXT_EXCLUSIVE, contextId1, runtimeInfo);
}
}
@Test(expected = IllegalStateException.class)
public void testRejectSecondNonExclusiveInContextExclusive() throws IOException {
testRejectSecondTemplate(CONTEXT_EXCLUSIVE, NON_EXCLUSIVE, contextId1);
}
@Test(expected = IllegalStateException.class)
public void testRejectSecondExclusiveInContextExclusive() throws IOException {
testRejectSecondTemplate(CONTEXT_EXCLUSIVE, EXCLUSIVE, contextId1);
}
// ------------------------------------------------------------------------
// REMOVE
// ------------------------------------------------------------------------
@Mock
TaskProcess taskProcess;
@Mock
IMap map;
@Test
public void testRemoveNonExclusiveLast() throws IOException {
testRemoveLastTemplate(NON_EXCLUSIVE, null);
}
@Test
public void testRemoveExclusiveLast() throws IOException {
testRemoveLastTemplate(EXCLUSIVE, taskId1);
}
@Test
public void testRemoveContextExclusiveLast() throws IOException {
testRemoveLastTemplate(CONTEXT_EXCLUSIVE, contextId1);
}
// ------------------------------------------------------------------------
// AUXILIARIES
// ------------------------------------------------------------------------
private void testRejectSecondTemplate(TaskExclusivity firstExclusivity, TaskExclusivity secondExclusivity,
String exclusivityId) throws IOException {
RuntimeInfo runtimeInfo = createRuntimeInfo();
ProcessManagerContext managerContext = new ProcessManagerContext(clusterContext, runtimeInfo);
setUpTaskHandle(taskHandle1, firstExclusivity, taskId1, contextId1);
setUpTaskHandle(taskHandle2, secondExclusivity, taskId2, contextId2);
try {
managerContext.tryAcceptTask(taskHandle1);
} catch (Exception e) {
assertFalse(true);
}
try {
managerContext.tryAcceptTask(taskHandle2);
} finally {
verifySetAcceptedCalled(taskHandle1);
verifySetAcceptedNotCalled(taskHandle2);
verifyMangerContext(managerContext, 1, firstExclusivity, exclusivityId, runtimeInfo);
}
}
private ProcessManagerContext testAcceptTaskTemplate(TaskExclusivity exclusivity, String exclusiveId,
RuntimeInfo runtimeInfo) {
ProcessManagerContext managerContext = new ProcessManagerContext(clusterContext, runtimeInfo);
setUpTaskHandle(taskHandle1, exclusivity, taskId1, contextId1);
managerContext.tryAcceptTask(taskHandle1);
verifySetAcceptedCalled(taskHandle1);
verifyMangerContext(managerContext, 1, exclusivity, exclusiveId, runtimeInfo);
return managerContext;
}
private void testAcceptSecondTemplate(TaskExclusivity firstExclusivity, TaskExclusivity secondExclusivity,
String exclusiveId) throws IOException {
RuntimeInfo runtimeInfo = createRuntimeInfo();
ProcessManagerContext managerContext = testAcceptTaskTemplate(firstExclusivity, exclusiveId, runtimeInfo);
setUpTaskHandle(taskHandle2, secondExclusivity, taskId2, contextId1);
managerContext.tryAcceptTask(taskHandle2);
verifySetAcceptedCalled(taskHandle1, taskHandle2);
verifyMangerContext(managerContext, 2, firstExclusivity, exclusiveId, runtimeInfo);
}
private void testRemoveLastTemplate(TaskExclusivity exclusivity, String exclusivityId) throws IOException {
RuntimeInfo runtimeInfo = createRuntimeInfo();
ProcessManagerContext managerContext = testAcceptTaskTemplate(exclusivity, exclusivityId, runtimeInfo);
managerContext.addTask(taskId1, taskProcess);
assertEquals(1, managerContext.getTasksCount());
when(clusterContext.getMap("BEEN_MAP_DEBUG_ASSISTANT")).thenReturn(map);
managerContext.removeTask(taskHandle1);
verifyMangerContext(managerContext, 0, NON_EXCLUSIVE, null, runtimeInfo);
}
private void setUpTaskHandle(TaskHandle taskHandle, TaskExclusivity exclusivity, String taskId, String contextId) {
when(taskHandle.getTaskId()).thenReturn(taskId);
when(taskHandle.getContextId()).thenReturn(contextId);
when(taskHandle.getExclusivity()).thenReturn(exclusivity);
}
private void verifyMangerContext(ProcessManagerContext managerContext, int tasks, TaskExclusivity exclusivity,
String exclusiveId, RuntimeInfo runtimeInfo) {
assertEquals(tasks, managerContext.getTasksCount());
assertEquals(tasks, runtimeInfo.getTaskCount());
assertEquals(exclusivity.toString(), runtimeInfo.getExclusivity());
assertEquals(exclusiveId, runtimeInfo.getExclusiveId());
}
private void verifySetAcceptedCalled(TaskHandle... handles) {
for (TaskHandle handle : handles) {
verify(handle, times(1)).setAccepted();
}
}
private void verifySetAcceptedNotCalled(TaskHandle... handles) {
for (TaskHandle handle : handles) {
verify(handle, times(0)).setAccepted();
}
}
private RuntimeInfo createRuntimeInfo() throws IOException {
return new RuntimeInfo().withMaxTasks(15).withId(runtimeId).withTasksWorkingDirectory(tmp.newFolder().toString());
}
}