package org.ovirt.engine.core.bll.gluster; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.argThat; import static org.mockito.ArgumentMatchers.eq; 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.List; import org.junit.ClassRule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentMatcher; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.Spy; import org.mockito.junit.MockitoJUnitRunner; import org.ovirt.engine.core.bll.utils.GlusterAuditLogUtil; import org.ovirt.engine.core.bll.utils.GlusterUtil; import org.ovirt.engine.core.common.businessentities.Cluster; import org.ovirt.engine.core.common.businessentities.VDS; import org.ovirt.engine.core.common.businessentities.VDSStatus; import org.ovirt.engine.core.common.businessentities.gluster.GlusterHookConflictFlags; import org.ovirt.engine.core.common.businessentities.gluster.GlusterHookContentType; import org.ovirt.engine.core.common.businessentities.gluster.GlusterHookEntity; import org.ovirt.engine.core.common.businessentities.gluster.GlusterHookStatus; import org.ovirt.engine.core.common.vdscommands.VDSCommandType; import org.ovirt.engine.core.common.vdscommands.VDSReturnValue; import org.ovirt.engine.core.common.vdscommands.VdsIdVDSCommandParametersBase; import org.ovirt.engine.core.compat.Guid; import org.ovirt.engine.core.dao.ClusterDao; import org.ovirt.engine.core.dao.gluster.GlusterHooksDao; import org.ovirt.engine.core.utils.MockConfigRule; @RunWith(MockitoJUnitRunner.class) public class GlusterHookSyncJobTest { private static final Guid[] SERVER_GUIDS = {new Guid("11111111-1111-1111-1111-111111111111"), new Guid("22222222-2222-2222-2222-222222222222"), new Guid("33333333-3333-3333-3333-333333333333")}; private static final Guid[] CLUSTER_GUIDS = {new Guid("CC111111-1111-1111-1111-111111111111"), new Guid("CC222222-2222-2222-2222-222222222222")}; private static final Guid[] EXISTING_HOOK_IDS = {new Guid("AAAAAAAA-1111-1111-1111-111111111111"), new Guid("AAAAAAAA-2222-2222-2222-222222222222"), new Guid("AAAAAAAA-3333-3333-3333-333333333333")}; @Mock private GlusterUtil glusterUtil; @Mock private GlusterHooksDao hooksDao; @Mock private ClusterDao clusterDao; @InjectMocks @Spy private GlusterHookSyncJob hookSyncJob; @Mock private GlusterAuditLogUtil logUtil; @ClassRule public static MockConfigRule mcr = new MockConfigRule(); private void mockDaos() { List<Cluster> clusters = new ArrayList<>(); clusters.add(createCluster(0)); clusters.add(createCluster(1)); //to check for empty cluster doReturn(clusters).when(clusterDao).getAll(); } private void initMocks() { doReturn(getServers()).when(glusterUtil).getAllUpServers(CLUSTER_GUIDS[0]); mockDaos(); } private Object getHooksListVDSReturnVal(int count) { VDSReturnValue vdsRetValue = new VDSReturnValue(); vdsRetValue.setSucceeded(true); vdsRetValue.setReturnValue(getHooksList(count, false)); return vdsRetValue; } private Object getHooksListVDSReturnVal(List<GlusterHookEntity> list) { VDSReturnValue vdsRetValue = new VDSReturnValue(); vdsRetValue.setSucceeded(true); vdsRetValue.setReturnValue(list); return vdsRetValue; } private Object getHookContentVDSReturnVal() { VDSReturnValue vdsRetValue = new VDSReturnValue(); vdsRetValue.setSucceeded(true); vdsRetValue.setReturnValue("CONTENT"); return vdsRetValue; } private List<GlusterHookEntity> getHooksList(int listCount, boolean setIds) { List<GlusterHookEntity> hookList = new ArrayList<>(); for (int i=0; i< listCount; i++) { hookList.add(getHook( i , setIds)); } return hookList; } private GlusterHookEntity getHook(int index, boolean setId) { GlusterHookEntity hook = new GlusterHookEntity(); hook.setChecksum("234230--090934"); hook.setContentType(GlusterHookContentType.TEXT); hook.setStatus(GlusterHookStatus.ENABLED); hook.setGlusterCommand("create"); hook.setStage("PRE"); hook.setName("hook-"+index); if (setId) { hook.setId(EXISTING_HOOK_IDS[index]); hook.setClusterId(CLUSTER_GUIDS[0]); } return hook; } private ArgumentMatcher<VdsIdVDSCommandParametersBase> vdsServerWithGuid(int index) { return argument -> argument.getVdsId().equals(SERVER_GUIDS[index]); } private List<VDS> getServers() { List<VDS> vdsList = new ArrayList<>(); vdsList.add(createServer(SERVER_GUIDS[0], "HOST-0")); vdsList.add(createServer(SERVER_GUIDS[1], "HOST-1")); return vdsList; } private VDS createServer(Guid serverId, String hostname) { VDS vds = new VDS(); vds.setId(serverId); vds.setHostName(hostname); vds.setStatus(VDSStatus.Up); return vds; } private Cluster createCluster(int index) { Cluster cluster = new Cluster(); cluster.setId(CLUSTER_GUIDS[index]); cluster.setName("cluster"); cluster.setGlusterService(true); cluster.setVirtService(false); return cluster; } @Test public void syncHooksWhenDBInSyncWithServers() { initMocks(); doReturn(getHooksList(3, true)).when(hooksDao).getByClusterId(CLUSTER_GUIDS[0]); doReturn(getHooksListVDSReturnVal(3)).when(hookSyncJob).runVdsCommand(eq(VDSCommandType.GlusterHooksList), argThat(vdsServerWithGuid(0))); doReturn(getHooksListVDSReturnVal(3)).when(hookSyncJob).runVdsCommand(eq(VDSCommandType.GlusterHooksList), argThat(vdsServerWithGuid(1))); hookSyncJob.refreshHooks(); verify(hooksDao, times(0)).save(any()); verify(hooksDao, times(0)).saveOrUpdateGlusterServerHook(any()); verify(hooksDao, times(0)).updateGlusterHookConflictStatus(any(), any()); } @Test public void syncHooksWhenNewHooksFound() { initMocks(); doReturn(getHooksList(1, true)).when(hooksDao).getByClusterId(CLUSTER_GUIDS[0]); doReturn(getHooksListVDSReturnVal(3)).when(hookSyncJob).runVdsCommand(eq(VDSCommandType.GlusterHooksList), argThat(vdsServerWithGuid(0))); doReturn(getHooksListVDSReturnVal(3)).when(hookSyncJob).runVdsCommand(eq(VDSCommandType.GlusterHooksList), argThat(vdsServerWithGuid(1))); doReturn(getHookContentVDSReturnVal()).when(hookSyncJob).runVdsCommand(eq(VDSCommandType.GetGlusterHookContent), any()); hookSyncJob.refreshHooks(); verify(hooksDao, times(2)).save(any()); verify(hooksDao, times(2)).updateGlusterHookContent(any(), any(), any()); verify(hooksDao, times(0)).saveOrUpdateGlusterServerHook(any()); verify(hooksDao, times(0)).updateGlusterHookConflictStatus(any(), any()); } @Test public void syncHooksWhenHookMissingInAllServers() { initMocks(); doReturn(getHooksList(3, true)).when(hooksDao).getByClusterId(CLUSTER_GUIDS[0]); doReturn(getHooksListVDSReturnVal(2)).when(hookSyncJob).runVdsCommand(eq(VDSCommandType.GlusterHooksList), argThat(vdsServerWithGuid(0))); doReturn(getHooksListVDSReturnVal(2)).when(hookSyncJob).runVdsCommand(eq(VDSCommandType.GlusterHooksList), argThat(vdsServerWithGuid(1))); doReturn(getHook(2, true)).when(hooksDao).getById(EXISTING_HOOK_IDS[2]); hookSyncJob.refreshHooks(); verify(hooksDao, times(0)).save(any()); verify(hooksDao, times(2)).saveOrUpdateGlusterServerHook(any()); verify(hooksDao, times(2)).updateGlusterHookConflictStatus(any(), any()); } @Test public void syncHooksWhenHookMissingInOneServer() { initMocks(); doReturn(getHooksList(3, true)).when(hooksDao).getByClusterId(CLUSTER_GUIDS[0]); doReturn(getHooksListVDSReturnVal(3)).when(hookSyncJob).runVdsCommand(eq(VDSCommandType.GlusterHooksList), argThat(vdsServerWithGuid(0))); doReturn(getHooksListVDSReturnVal(2)).when(hookSyncJob).runVdsCommand(eq(VDSCommandType.GlusterHooksList), argThat(vdsServerWithGuid(1))); doReturn(getHook(2, true)).when(hooksDao).getById(EXISTING_HOOK_IDS[2]); hookSyncJob.refreshHooks(); verify(hooksDao, times(0)).save(any()); verify(hooksDao, times(1)).saveOrUpdateGlusterServerHook(any()); verify(hooksDao, times(1)).updateGlusterHookConflictStatus(any(), any()); } @Test public void syncHooksWhenHookContentConflictInOneServer() { initMocks(); doReturn(getHooksList(3, true)).when(hooksDao).getByClusterId(CLUSTER_GUIDS[0]); doReturn(getHooksListVDSReturnVal(3)).when(hookSyncJob).runVdsCommand(eq(VDSCommandType.GlusterHooksList), argThat(vdsServerWithGuid(0))); List<GlusterHookEntity> listHooks = getHooksList(3, false); listHooks.get(1).setChecksum("NEWCHECKSUM"); doReturn(getHooksListVDSReturnVal(listHooks)).when(hookSyncJob).runVdsCommand(eq(VDSCommandType.GlusterHooksList), argThat(vdsServerWithGuid(1))); hookSyncJob.refreshHooks(); verify(hooksDao, times(0)).save(any()); verify(hooksDao, times(1)).saveGlusterServerHook(any()); verify(hooksDao, times(1)).updateGlusterHookConflictStatus(EXISTING_HOOK_IDS[1], GlusterHookConflictFlags.CONTENT_CONFLICT.getValue()); } @Test public void syncHooksWhenHookMissingAndContentConflict() { initMocks(); doReturn(getHooksList(3, true)).when(hooksDao).getByClusterId(CLUSTER_GUIDS[0]); doReturn(getHooksListVDSReturnVal(2)).when(hookSyncJob).runVdsCommand(eq(VDSCommandType.GlusterHooksList), argThat(vdsServerWithGuid(0))); List<GlusterHookEntity> listHooks = getHooksList(3, false); listHooks.get(1).setChecksum("NEWCHECKSUM"); doReturn(getHooksListVDSReturnVal(listHooks)).when(hookSyncJob).runVdsCommand(eq(VDSCommandType.GlusterHooksList), argThat(vdsServerWithGuid(1))); doReturn(getHook(2, true)).when(hooksDao).getById(EXISTING_HOOK_IDS[2]); hookSyncJob.refreshHooks(); verify(hooksDao, times(0)).save(any()); verify(hooksDao, times(1)).saveOrUpdateGlusterServerHook(any()); verify(hooksDao, times(1)).saveGlusterServerHook(any()); verify(hooksDao, times(1)).updateGlusterHookConflictStatus(EXISTING_HOOK_IDS[1], GlusterHookConflictFlags.CONTENT_CONFLICT.getValue()); verify(hooksDao, times(1)).updateGlusterHookConflictStatus(EXISTING_HOOK_IDS[2], GlusterHookConflictFlags.MISSING_HOOK.getValue()); } }