/*
* ProActive Parallel Suite(TM):
* The Open Source library for parallel and distributed
* Workflows & Scheduling, Orchestration, Cloud Automation
* and Big Data Analysis on Enterprise Grids & Clouds.
*
* Copyright (c) 2007 - 2017 ActiveEon
* Contact: contact@activeeon.com
*
* This library is free software: you can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License
* as published by the Free Software Foundation: version 3 of
* the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* If needed, contact us to obtain a release under GPL Version 2 or 3
* or a different license than the AGPL.
*/
package org.ow2.proactive.scheduler.job.termination.handlers;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.util.Map;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.ow2.proactive.scheduler.common.job.JobPriority;
import org.ow2.proactive.scheduler.common.task.OnTaskError;
import org.ow2.proactive.scheduler.common.task.TaskId;
import org.ow2.proactive.scheduler.common.task.TaskStatus;
import org.ow2.proactive.scheduler.common.task.flow.FlowAction;
import org.ow2.proactive.scheduler.common.task.flow.FlowActionType;
import org.ow2.proactive.scheduler.common.task.flow.FlowBlock;
import org.ow2.proactive.scheduler.core.SchedulerStateUpdate;
import org.ow2.proactive.scheduler.descriptor.JobDescriptorImpl;
import org.ow2.proactive.scheduler.job.ChangedTasksInfo;
import org.ow2.proactive.scheduler.job.InternalJob;
import org.ow2.proactive.scheduler.job.InternalTaskFlowJob;
import org.ow2.proactive.scheduler.job.JobIdImpl;
import org.ow2.proactive.scheduler.job.JobInfoImpl;
import org.ow2.proactive.scheduler.task.TaskIdImpl;
import org.ow2.proactive.scheduler.task.internal.InternalScriptTask;
import org.ow2.proactive.scheduler.task.internal.InternalTask;
import org.python.google.common.collect.Lists;
import com.google.common.collect.Maps;
/**
* @author ActiveEon Team
* @since 2 Jan 2017
*/
public class TerminateReplicateTaskHandlerTest {
/**
*
*/
private static final long MERGE_TASK_ID = 777L;
private TerminateReplicateTaskHandler terminateReplicateTaskHandler;
@Mock
private InternalJob internalJob;
@Mock
private JobDescriptorImpl jobDescriptorImpl;
@Mock
private ChangedTasksInfo changesInfo;
@Mock
private SchedulerStateUpdate frontend;
@Mock
private JobInfoImpl jobInfoImpl;
private InternalTask initiator;
private FlowAction action;
private Map<TaskId, InternalTask> tasks = generateTasks();
@Before
public void init() {
action = new FlowAction(FlowActionType.REPLICATE);
action.setDupNumber(0);
MockitoAnnotations.initMocks(this);
when(internalJob.getJobInfo()).thenReturn(jobInfoImpl);
when(internalJob.getJobDescriptor()).thenReturn(jobDescriptorImpl);
terminateReplicateTaskHandler = new TerminateReplicateTaskHandler(internalJob);
}
@Test
public void testTerminateReplicateTaskSkipOneTask() {
tasks = generateTasks();
when(internalJob.getIHMTasks()).thenReturn(tasks);
initiator = generateInitiatorTask();
boolean result = terminateReplicateTaskHandler.terminateReplicateTask(action,
initiator,
changesInfo,
frontend,
initiator.getId());
assertThat(result, is(true));
verify(jobInfoImpl).setTasksChanges(changesInfo, internalJob);
assertThat(tasks.get(generateInternalTask(555L).getId()).getStatus(), is(TaskStatus.SKIPPED));
assertThat(tasks.get(generateInternalTask(MERGE_TASK_ID).getId()).getStatus(), is(TaskStatus.PENDING));
}
@Test
public void testTerminateReplicateTaskSkipBlockOfTasks() {
tasks = generateTasksWithBlock();
when(internalJob.getIHMTasks()).thenReturn(tasks);
initiator = generateInitiatorTask();
boolean result = terminateReplicateTaskHandler.terminateReplicateTask(action,
initiator,
changesInfo,
frontend,
initiator.getId());
assertThat(result, is(true));
verify(jobInfoImpl).setTasksChanges(changesInfo, internalJob);
assertThat(tasks.get(generateInternalTask(555L).getId()).getStatus(), is(TaskStatus.SKIPPED));
assertThat(tasks.get(generateInternalTask(666L).getId()).getStatus(), is(TaskStatus.SKIPPED));
assertThat(tasks.get(generateInternalTask(888L).getId()).getStatus(), is(TaskStatus.SKIPPED));
assertThat(tasks.get(generateInternalTask(999L).getId()).getStatus(), is(TaskStatus.SKIPPED));
assertThat(tasks.get(generateInternalTask(MERGE_TASK_ID).getId()).getStatus(), is(TaskStatus.PENDING));
}
private Map<TaskId, InternalTask> generateTasks() {
Map<TaskId, InternalTask> tempTasks = Maps.newHashMap();
InternalTask internalTask = generateInternalTask(555L);
tempTasks.put(internalTask.getId(), internalTask);
InternalTask mergeTask = generateInternalTask(MERGE_TASK_ID);
tempTasks.put(mergeTask.getId(), mergeTask);
InternalTask initiatorTask = generateInitiatorTask();
internalTask.addDependence(initiatorTask);
mergeTask.addDependence(internalTask);
tempTasks.put(initiatorTask.getId(), initiatorTask);
return tempTasks;
}
private Map<TaskId, InternalTask> generateTasksWithBlock() {
Map<TaskId, InternalTask> tempTasks = Maps.newHashMap();
InternalTask startTask = generateInternalTask(555L);
startTask.setFlowBlock(FlowBlock.START);
tempTasks.put(startTask.getId(), startTask);
InternalTask internalTask2 = generateInternalTask(666L);
tempTasks.put(internalTask2.getId(), internalTask2);
internalTask2.addDependence(startTask);
InternalTask internalTask3 = generateInternalTask(888L);
tempTasks.put(internalTask3.getId(), internalTask3);
internalTask3.addDependence(startTask);
when(jobDescriptorImpl.getTaskChildren(startTask)).thenReturn(Lists.newArrayList(internalTask2, internalTask3));
InternalTask endTask = generateInternalTask(999L);
tempTasks.put(endTask.getId(), endTask);
endTask.setFlowBlock(FlowBlock.END);
when(jobDescriptorImpl.getTaskChildren(internalTask2)).thenReturn(Lists.newArrayList(endTask));
when(jobDescriptorImpl.getTaskChildren(internalTask3)).thenReturn(Lists.newArrayList(endTask));
endTask.addDependence(internalTask2);
endTask.addDependence(internalTask3);
InternalTask mergeTask = generateInternalTask(MERGE_TASK_ID);
tempTasks.put(mergeTask.getId(), mergeTask);
mergeTask.addDependence(endTask);
InternalTask initiatorTask = generateInitiatorTask();
startTask.addDependence(initiatorTask);
tempTasks.put(initiatorTask.getId(), initiatorTask);
return tempTasks;
}
private InternalTask generateInternalTask(long id) {
InternalJob job = new InternalTaskFlowJob("test-name",
JobPriority.NORMAL,
OnTaskError.CANCEL_JOB,
"description");
InternalTask internalTask = new InternalScriptTask(job);
internalTask.setId(TaskIdImpl.createTaskId(new JobIdImpl(666L, "JobName"), "readableName", id));
internalTask.setStatus(TaskStatus.PENDING);
return internalTask;
}
private InternalTask generateInitiatorTask() {
InternalJob job = new InternalTaskFlowJob("initiator",
JobPriority.NORMAL,
OnTaskError.CANCEL_JOB,
"description");
InternalTask initiatorTask = new InternalScriptTask(job);
initiatorTask.setId(TaskIdImpl.createTaskId(new JobIdImpl(666L, "JobName"), "readableName", 111L));
initiatorTask.setReplicationIndex(1);
return initiatorTask;
}
}