package org.ovirt.engine.core.bll.gluster; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyList; import static org.mockito.ArgumentMatchers.anyString; 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.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.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.gluster.GeoRepSessionStatus; import org.ovirt.engine.core.common.businessentities.gluster.GlusterBrickEntity; import org.ovirt.engine.core.common.businessentities.gluster.GlusterGeoRepSession; import org.ovirt.engine.core.common.businessentities.gluster.GlusterGeoRepSessionConfiguration; import org.ovirt.engine.core.common.businessentities.gluster.GlusterGeoRepSessionDetails; import org.ovirt.engine.core.common.businessentities.gluster.GlusterStatus; import org.ovirt.engine.core.common.businessentities.gluster.GlusterVolumeEntity; import org.ovirt.engine.core.common.vdscommands.VDSCommandType; import org.ovirt.engine.core.common.vdscommands.VDSReturnValue; import org.ovirt.engine.core.common.vdscommands.gluster.GlusterVolumeGeoRepSessionVDSParameters; 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.StorageDomainDRDao; import org.ovirt.engine.core.dao.VdsDao; import org.ovirt.engine.core.dao.gluster.GlusterGeoRepDao; import org.ovirt.engine.core.dao.gluster.GlusterVolumeDao; import org.ovirt.engine.core.utils.MockConfigRule; import org.ovirt.engine.core.utils.lock.LockManager; @RunWith(MockitoJUnitRunner.class) public class GlusterGeoRepSyncJobTest { private static final Guid CLUSTER_GUID = new Guid("CC111111-1111-1111-1111-111111111111"); @Mock private LockManager lockManager; @Mock private GlusterGeoRepDao geoRepDao; @Mock private GlusterUtil glusterUtil; @Mock private ClusterDao clusterDao; @Mock private VdsDao vdsDao; @Mock private GlusterVolumeDao volumeDao; @Mock private StorageDomainDRDao storageDomainDRDao; @InjectMocks @Spy private GlusterGeoRepSyncJob syncJob; @Mock private GlusterAuditLogUtil logUtil; @ClassRule public static MockConfigRule mcr = new MockConfigRule(); @Before public void init() { doReturn(getClusters()).when(clusterDao).getAll(); doReturn(getVolume()).when(volumeDao).getByName(any(Guid.class), anyString()); doReturn(getVolume()).when(volumeDao).getById(any(Guid.class)); doReturn(getServer()).when(glusterUtil).getRandomUpServer(any(Guid.class)); doReturn(getSessions(2, true)).when(geoRepDao).getGeoRepSessionsInCluster(CLUSTER_GUID); } @Test public void testDiscoverGeoRepData() { doReturn(getSessionsVDSReturnVal(2)).when(syncJob) .runVdsCommand(eq(VDSCommandType.GetGlusterVolumeGeoRepSessionList), any(GlusterVolumeGeoRepSessionVDSParameters.class)); syncJob.discoverGeoRepData(); verify(geoRepDao, times(2)).save(any(GlusterGeoRepSession.class)); } @Test public void testDiscoverGeoRepDataWithConfig() { doReturn(getSessionsVDSReturnVal(2)).when(syncJob) .runVdsCommand(eq(VDSCommandType.GetGlusterVolumeGeoRepSessionList), any(GlusterVolumeGeoRepSessionVDSParameters.class)); doReturn(getSessionsConfigListVDSReturnVal()).when(syncJob) .runVdsCommand(eq(VDSCommandType.GetGlusterVolumeGeoRepConfigList), any(GlusterVolumeGeoRepSessionVDSParameters.class)); syncJob.discoverGeoRepData(); verify(geoRepDao, times(2)).save(any(GlusterGeoRepSession.class)); verify(geoRepDao, times(2)).saveConfig(any(GlusterGeoRepSessionConfiguration.class)); } @Test public void testDiscoverGeoRepDataWhenNoSessions() { doReturn(getSessionsVDSReturnVal(0)).when(syncJob) .runVdsCommand(eq(VDSCommandType.GetGlusterVolumeGeoRepSessionList), any(GlusterVolumeGeoRepSessionVDSParameters.class)); syncJob.discoverGeoRepData(); verify(geoRepDao, times(0)).save(any(GlusterGeoRepSession.class)); } @Test public void testRefreshStatus() { doReturn(getSessionDetailsVDSReturnVal(true)).when(syncJob) .runVdsCommand(eq(VDSCommandType.GetGlusterVolumeGeoRepSessionStatus), any(GlusterVolumeGeoRepSessionVDSParameters.class)); syncJob.refreshGeoRepSessionStatus(); verify(geoRepDao, times(2)).saveOrUpdateDetailsInBatch(anyList()); } @Test public void testRefreshStatusNoSessions() { doReturn(getSessionDetailsVDSReturnVal(false)).when(syncJob) .runVdsCommand(eq(VDSCommandType.GetGlusterVolumeGeoRepSessionStatus), any(GlusterVolumeGeoRepSessionVDSParameters.class)); syncJob.refreshGeoRepSessionStatus(); verify(geoRepDao, times(0)).saveOrUpdateDetailsInBatch(anyList()); } private Object getSessionsVDSReturnVal(int count) { VDSReturnValue vdsRetValue = new VDSReturnValue(); vdsRetValue.setSucceeded(true); vdsRetValue.setReturnValue(getSessions(count, false)); return vdsRetValue; } private Object getSessionDetailsVDSReturnVal(boolean ret) { VDSReturnValue vdsRetValue = new VDSReturnValue(); vdsRetValue.setSucceeded(ret); if (ret) { vdsRetValue.setReturnValue(getSessionDetailsList()); } else { vdsRetValue.setReturnValue(null); } return vdsRetValue; } private Object getSessionsConfigListVDSReturnVal() { VDSReturnValue vdsRetValue = new VDSReturnValue(); vdsRetValue.setSucceeded(true); vdsRetValue.setReturnValue(getSessionConfigList()); return vdsRetValue; } private List<GlusterGeoRepSessionConfiguration> getSessionConfigList() { List<GlusterGeoRepSessionConfiguration> configList = new ArrayList<>(); GlusterGeoRepSessionConfiguration config = new GlusterGeoRepSessionConfiguration(); config.setKey("georep-crawl"); config.setValue("hybrid"); configList.add(config); return configList; } private List<GlusterGeoRepSession> getSessions(int count, boolean populateVoId) { List<GlusterGeoRepSession> sessions = new ArrayList<>(); for (int i = 0; i < count; i++) { sessions.add(getSession(populateVoId)); } return sessions; } private GlusterGeoRepSession getSession(boolean populateVoId) { GlusterGeoRepSession session = new GlusterGeoRepSession(); session.setMasterVolumeName("VOL1"); if (populateVoId) { session.setMasterVolumeId(Guid.newGuid()); } session.setId(Guid.newGuid()); session.setSessionKey(session.getId() + session.getMasterVolumeName()); session.setStatus(GeoRepSessionStatus.ACTIVE); session.setSessionDetails(getSessionDetailsList()); return session; } private ArrayList<GlusterGeoRepSessionDetails> getSessionDetailsList() { ArrayList<GlusterGeoRepSessionDetails> list = new ArrayList<>(); GlusterGeoRepSessionDetails details = new GlusterGeoRepSessionDetails(); details.setMasterBrickId(Guid.newGuid()); list.add(details); return list; } private List<Cluster> getClusters() { List<Cluster> list = new ArrayList<>(); list.add(createCluster()); return list; } private static Cluster createCluster() { Cluster cluster = new Cluster(); cluster.setId(CLUSTER_GUID); cluster.setName("cluster"); cluster.setGlusterService(true); cluster.setVirtService(false); cluster.setCompatibilityVersion(Version.v4_0); return cluster; } private VDS getServer() { VDS vds = new VDS(); vds.setId(Guid.newGuid()); return vds; } private GlusterVolumeEntity getVolume() { GlusterVolumeEntity volume = new GlusterVolumeEntity(); volume.setName("VOL1"); volume.setClusterId(Guid.newGuid()); volume.setId(Guid.newGuid()); volume.setReplicaCount(2); GlusterBrickEntity brick = new GlusterBrickEntity(); brick.setVolumeId(volume.getId()); brick.setBrickDirectory("/export/testvol1"); brick.setStatus(GlusterStatus.UP); brick.setBrickOrder(0); volume.addBrick(brick); GlusterBrickEntity brick2 = new GlusterBrickEntity(); brick2.setVolumeId(volume.getId()); brick2.setBrickDirectory("/export/testvol1"); brick2.setStatus(GlusterStatus.UP); brick2.setBrickOrder(1); volume.addBrick(brick2); return volume; } }