package org.ovirt.engine.core.bll.gluster; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyList; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import org.junit.Before; import org.junit.ClassRule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.Spy; import org.mockito.junit.MockitoJUnitRunner; import org.ovirt.engine.core.bll.gluster.tasks.GlusterTaskUtils; import org.ovirt.engine.core.bll.gluster.tasks.GlusterTasksService; import org.ovirt.engine.core.common.asynctasks.gluster.GlusterAsyncTask; import org.ovirt.engine.core.common.asynctasks.gluster.GlusterTaskParameters; import org.ovirt.engine.core.common.asynctasks.gluster.GlusterTaskType; import org.ovirt.engine.core.common.businessentities.Cluster; import org.ovirt.engine.core.common.job.JobExecutionStatus; import org.ovirt.engine.core.common.job.Step; import org.ovirt.engine.core.common.job.StepEnum; import org.ovirt.engine.core.compat.Guid; import org.ovirt.engine.core.compat.Version; import org.ovirt.engine.core.dao.ClusterDao; import org.ovirt.engine.core.dao.StepDao; import org.ovirt.engine.core.dao.gluster.GlusterVolumeDao; import org.ovirt.engine.core.utils.MockConfigRule; @RunWith(MockitoJUnitRunner.class) public class GlusterTasksSyncJobTest { private static final Guid[] CLUSTER_GUIDS = {new Guid("CC111111-1111-1111-1111-111111111111"), new Guid("CC222222-2222-2222-2222-222222222222")}; private static final Guid[] TASK_GUIDS = {new Guid("EE111111-1111-1111-1111-111111111111"), new Guid("EE222222-2222-2222-2222-222222222222"), new Guid("EE333333-3333-3333-3333-333333333333"), new Guid("EE444444-4444-4444-4444-444444444444")}; private static final Guid[] VOL_GUIDS = {new Guid("AA111111-1111-1111-1111-111111111111"), new Guid("AA222222-2222-2222-2222-222222222222"), new Guid("AA333333-3333-3333-3333-333333333333")}; @Mock private StepDao stepDao; @Mock private ClusterDao clusterDao; @Mock private GlusterVolumeDao volumeDao; @Mock private GlusterTasksService provider; @Mock private GlusterTaskUtils taskUtils; @InjectMocks @Spy private GlusterTasksSyncJob tasksSyncJob; @ClassRule public static MockConfigRule mcr = new MockConfigRule(); @Before public void init() { doReturn(getClusters()).when(clusterDao).getAll(); } @Test public void updateTasksInCluster() { doReturn(getTasks()).when(provider).getTaskListForCluster(CLUSTER_GUIDS[1]); prepareMocks(); tasksSyncJob.updateGlusterAsyncTasks(); verify(taskUtils, times(2)).updateSteps(any(Cluster.class), any(GlusterAsyncTask.class), anyList()); } @Test public void cleanOrphanTasks() { doReturn(getTasks()).when(provider).getTaskListForCluster(CLUSTER_GUIDS[1]); doReturn(Arrays.asList(TASK_GUIDS[2], TASK_GUIDS[3])).when(provider).getMonitoredTaskIDsInDB(); prepareMocks(); tasksSyncJob.updateGlusterAsyncTasks(); verify(taskUtils, times(1)).endStepJob(any(Step.class)); verify(taskUtils, times(2)).updateSteps(any(Cluster.class), any(GlusterAsyncTask.class), anyList()); } @Test public void cleanOrphanTasksWhenNoVolume() { doReturn(Collections.singletonList(TASK_GUIDS[2])).when(provider).getMonitoredTaskIDsInDB(); doReturn(getSteps(TASK_GUIDS[2])).when(stepDao).getStepsByExternalId(TASK_GUIDS[2]); tasksSyncJob.updateGlusterAsyncTasks(); verify(taskUtils, times(1)).endStepJob(any(Step.class)); } @Test public void testUpdateWhenNoTasks() { tasksSyncJob.updateGlusterAsyncTasks(); verify(volumeDao, times(0)).updateVolumeTask(VOL_GUIDS[0], null); verify(volumeDao, times(0)).updateVolumeTask(VOL_GUIDS[1], null); verify(taskUtils, times(0)).endStepJob(any(Step.class)); } @Test public void testCreateTasksStartedFromCLI() { doReturn(getTasks(JobExecutionStatus.STARTED)).when(provider).getTaskListForCluster(CLUSTER_GUIDS[1]); tasksSyncJob.updateGlusterAsyncTasks(); verify(taskUtils, times(0)).endStepJob(any(Step.class)); } @Test public void testCreateTasksStartedFromCLIWithErrors() { doReturn(getTasks(JobExecutionStatus.STARTED)).when(provider).getTaskListForCluster(CLUSTER_GUIDS[1]); tasksSyncJob.updateGlusterAsyncTasks(); verify(taskUtils, times(0)).endStepJob(any(Step.class)); } @Test public void testUpdateWhenNoCompletedTasks() { doReturn(getTasks(JobExecutionStatus.STARTED)).when(provider).getTaskListForCluster(CLUSTER_GUIDS[1]); prepareMocks(); tasksSyncJob.updateGlusterAsyncTasks(); verify(taskUtils, times(2)).updateSteps(any(Cluster.class), any(GlusterAsyncTask.class), anyList()); } @Test public void testUpdateWhenAbortedTasks() { doReturn(getTasks(JobExecutionStatus.ABORTED)).when(provider).getTaskListForCluster(CLUSTER_GUIDS[1]); prepareMocks(); tasksSyncJob.updateGlusterAsyncTasks(); verify(taskUtils, times(2)).updateSteps(any(Cluster.class), any(GlusterAsyncTask.class), anyList()); } private void prepareMocks() { doReturn(getSteps(TASK_GUIDS[0])).when(stepDao).getStepsByExternalId(TASK_GUIDS[0]); doReturn(getSteps(TASK_GUIDS[1])).when(stepDao).getStepsByExternalId(TASK_GUIDS[1]); doReturn(getSteps(TASK_GUIDS[2])).when(stepDao).getStepsByExternalId(TASK_GUIDS[2]); } private List<Step> getSteps(Guid taskGuid) { List<Step> steps = new ArrayList<>(); steps.add(createStep(taskGuid)); return steps; } private Step createStep(Guid taskGuid) { Step step = new Step(); step.setStepType(StepEnum.REBALANCING_VOLUME); Calendar stepTime = Calendar.getInstance(); if (taskGuid.equals(TASK_GUIDS[2])) { //only create TASK_GUIDS[2] as older job stepTime.set(Calendar.HOUR, stepTime.get(Calendar.HOUR) -1); } step.setStartTime(stepTime.getTime()); return step; } private Map<Guid, GlusterAsyncTask> getTasks() { Map<Guid, GlusterAsyncTask> tasks = new HashMap<>(); tasks.put(TASK_GUIDS[0], createTask(TASK_GUIDS[0], JobExecutionStatus.FINISHED)); tasks.put(TASK_GUIDS[1], createTask(TASK_GUIDS[1], JobExecutionStatus.STARTED)); return tasks; } private Map<Guid, GlusterAsyncTask> getTasks(JobExecutionStatus status) { Map<Guid, GlusterAsyncTask> tasks = new HashMap<>(); tasks.put(TASK_GUIDS[0], createTask(TASK_GUIDS[0], status)); tasks.put(TASK_GUIDS[1], createTask(TASK_GUIDS[1], status)); return tasks; } private GlusterAsyncTask createTask(Guid guid, JobExecutionStatus status) { GlusterAsyncTask task = new GlusterAsyncTask(); task.setTaskId(guid); task.setTaskParameters(new GlusterTaskParameters()); task.getTaskParameters().setVolumeName("VOL"); task.setMessage("message"); task.setStatus(status); task.setType(GlusterTaskType.REBALANCE); return task; } private List<Cluster> getClusters() { List<Cluster> list = new ArrayList<>(); list.add(createCluster(0, Version.v3_6)); list.add(createCluster(1, Version.v4_0)); return list; } private Cluster createCluster(int index, Version v) { Cluster cluster = new Cluster(); cluster.setId(CLUSTER_GUIDS[index]); cluster.setName("cluster"); cluster.setGlusterService(true); cluster.setVirtService(false); cluster.setCompatibilityVersion(v); return cluster; } }