package org.ovirt.engine.core.bll; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.argThat; import static org.mockito.MockitoAnnotations.initMocks; import static org.powermock.api.mockito.PowerMockito.mock; import static org.powermock.api.mockito.PowerMockito.mockStatic; import static org.powermock.api.mockito.PowerMockito.when; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentMatcher; import org.mockito.Mock; import org.ovirt.engine.core.bll.interfaces.BackendInternal; import org.ovirt.engine.core.bll.utils.VersionSupport; import org.ovirt.engine.core.common.action.VdsGroupOperationParameters; import org.ovirt.engine.core.common.businessentities.StorageType; import org.ovirt.engine.core.common.businessentities.VDS; import org.ovirt.engine.core.common.businessentities.VDSGroup; import org.ovirt.engine.core.common.businessentities.VdsSelectionAlgorithm; import org.ovirt.engine.core.common.businessentities.VdsStatic; import org.ovirt.engine.core.common.businessentities.storage_pool; import org.ovirt.engine.core.common.config.Config; import org.ovirt.engine.core.common.config.ConfigValues; import org.ovirt.engine.core.common.interfaces.SearchType; import org.ovirt.engine.core.common.queries.SearchParameters; import org.ovirt.engine.core.common.queries.VdcQueryParametersBase; import org.ovirt.engine.core.common.queries.VdcQueryReturnValue; import org.ovirt.engine.core.common.queries.VdcQueryType; import org.ovirt.engine.core.compat.Guid; import org.ovirt.engine.core.compat.Version; import org.ovirt.engine.core.dal.VdcBllMessages; import org.ovirt.engine.core.dal.dbbroker.DbFacade; import org.ovirt.engine.core.dao.StoragePoolDAO; import org.ovirt.engine.core.dao.VdsGroupDAO; import org.ovirt.engine.core.dao.VdsStaticDAO; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; @PrepareForTest({DbFacade.class, CpuFlagsManagerHandler.class, Config.class, CpuFlagsManagerHandler.class, Backend.class, VersionSupport.class}) @RunWith(PowerMockRunner.class) public class UpdateVdsGroupCommandTest { private static final Version VERSION_1_0 = new Version(1, 0); private static final Version VERSION_1_1 = new Version(1, 1); private static final Version VERSION_1_2 = new Version(1, 2); private static final Guid STORAGE_POOL_ID = Guid.NewGuid(); @Mock private DbFacade dbFacade; @Mock private VdsGroupDAO vdsGroupDAO; @Mock private VdsStaticDAO vdsStaticDAO; @Mock private BackendInternal backendInternal; @Mock private StoragePoolDAO storagePoolDAO; private UpdateVdsGroupCommand<VdsGroupOperationParameters> cmd; @Before public void setUp() { initMocks(this); mockStatic(DbFacade.class); mockStatic(CpuFlagsManagerHandler.class); mockStatic(Config.class); mockStatic(CpuFlagsManagerHandler.class); mockStatic(Backend.class); when(DbFacade.getInstance()).thenReturn(dbFacade); when(dbFacade.getVdsGroupDAO()).thenReturn(vdsGroupDAO); when(dbFacade.getVdsStaticDAO()).thenReturn(vdsStaticDAO); when(dbFacade.getStoragePoolDAO()).thenReturn(storagePoolDAO); when(vdsGroupDAO.get(any(Guid.class))).thenReturn(createDefaultVdsGroup()); when(vdsGroupDAO.getByName(anyString())).thenReturn(createDefaultVdsGroup()); when(Backend.getInstance()).thenReturn(backendInternal); VdsGroupOperationParameters params = new VdsGroupOperationParameters(createNewVdsGroup()); cmd = new UpdateVdsGroupCommand<VdsGroupOperationParameters>(params); } @Test public void nameInUse() { createSimpleCommand(); createCommandWithDifferentName(); canDoActionFailedWithReason(VdcBllMessages.VDS_GROUP_CANNOT_DO_ACTION_NAME_IN_USE); } @Test public void invalidVdsGroup() { when(vdsGroupDAO.get(any(Guid.class))).thenReturn(null); canDoActionFailedWithReason(VdcBllMessages.VDS_CLUSTER_IS_NOT_VALID); } @Test public void invalidCpuSelection() { canDoActionFailedWithReason(VdcBllMessages.ACTION_TYPE_FAILED_CPU_NOT_FOUND); } @Test public void illegalCpuChange() { createSimpleCommand(); cpuExists(); cpuManufacturersDontMatch(); vdsGroupHasVds(); canDoActionFailedWithReason(VdcBllMessages.VDS_GROUP_CANNOT_UPDATE_CPU_ILLEGAL); } @Test public void invalidVersion() { createCommandWithInvalidVersion(); cpuExists(); cpuManufacturersMatch(); canDoActionFailedWithReason(VdcBllMessages.ACTION_TYPE_FAILED_GIVEN_VERSION_NOT_SUPPORTED); } @Test public void versionDecrease() { createCommandWithOlderVersion(); cpuExists(); cpuManufacturersMatch(); canDoActionFailedWithReason(VdcBllMessages.ACTION_TYPE_FAILED_CANNOT_DECREASE_COMPATIBILITY_VERSION); } @Test public void updateWithLowerVersionThanHosts() { createSimpleCommand(); cpuExists(); cpuManufacturersMatch(); VdsExistWithHigherVersion(); canDoActionFailedWithReason(VdcBllMessages.VDS_GROUP_CANNOT_UPDATE_COMPATIBILITY_VERSION_WITH_LOWER_HOSTS); } @Test public void updateWithCpuLowerThanHost() { createSimpleCommand(); cpuExists(); cpuManufacturersMatch(); clusterVersionIsSupported(); clusterHasVds(); CpuFlagsMissing(); canDoActionFailedWithReason(VdcBllMessages.VDS_GROUP_CANNOT_UPDATE_CPU_WITH_LOWER_HOSTS); } @Test public void updateStoragePool() { createCommandWithDifferentPool(); cpuExists(); cpuManufacturersMatch(); clusterHasVds(); cpuFlagsNotMissing(); canDoActionFailedWithReason(VdcBllMessages.VDS_GROUP_CANNOT_CHANGE_STORAGE_POOL); } @Test public void clusterAlreadyInLocalFs() { createCommandWithDefaultVdsGroup(); oldGroupIsDetachedDefault(); storagePoolIsLocalFS(); cpuExists(); cpuManufacturersMatch(); clusterVersionIsSupported(); allQueriesEmpty(); storagePoolAlreadyHasCluster(); canDoActionFailedWithReason(VdcBllMessages.VDS_GROUP_CANNOT_ADD_MORE_THEN_ONE_HOST_TO_LOCAL_STORAGE); } @Test public void defaultClusterInLocalFs() { createCommandWithDefaultVdsGroup(); oldGroupIsDetachedDefault(); storagePoolIsLocalFS(); cpuExists(); cpuManufacturersMatch(); clusterVersionIsSupported(); allQueriesEmpty(); canDoActionFailedWithReason(VdcBllMessages.DEFAULT_CLUSTER_CANNOT_BE_ON_LOCALFS); } @Test public void selectionAlgoNotNone() { createCommandWithPowerSaveVdsGroup(); oldGroupIsDetachedDefault(); storagePoolIsLocalFS(); cpuExists(); cpuManufacturersMatch(); clusterVersionIsSupported(); allQueriesEmpty(); canDoActionFailedWithReason(VdcBllMessages.VDS_GROUP_SELECTION_ALGORITHM_MUST_BE_SET_TO_NONE_ON_LOCAL_STORAGE); } @Test public void vdsGroupWithNoCpu() { createCommandWithNoCpuName(); when(vdsGroupDAO.get(any(Guid.class))).thenReturn(createVdsGroupWithNoCpuName()); when(vdsGroupDAO.getByName(anyString())).thenReturn(createVdsGroupWithNoCpuName()); allQueriesEmpty(); assertTrue(cmd.canDoAction()); } private void createSimpleCommand() { createCommand(createNewVdsGroup()); } private void createCommandWithOlderVersion() { createCommand(createVdsGroupWithOlderVersion()); } private void createCommandWithInvalidVersion() { createCommand(createVdsGroupWithBadVersion()); } private void createCommandWithDifferentPool() { createCommand(createVdsGroupWithDifferentPool()); } private void createCommandWithDefaultVdsGroup() { createCommand(createDefaultVdsGroup()); } private void createCommandWithNoCpuName() { createCommand(createVdsGroupWithNoCpuName()); } private void createCommandWithPowerSaveVdsGroup() { createCommand(createVdsGroupWithPowerSave()); } private void createCommand(final VDSGroup group) { setValidCpuVersionMap(); VdsGroupOperationParameters params = new VdsGroupOperationParameters(group); cmd = new UpdateVdsGroupCommand<VdsGroupOperationParameters>(params); } private void createCommandWithDifferentName() { createCommand(createVdsGroupWithDifferentName()); } private VDSGroup createVdsGroupWithDifferentName() { VDSGroup group = new VDSGroup(); group.setname("BadName"); return group; } private VDSGroup createNewVdsGroup() { VDSGroup group = new VDSGroup(); group.setcompatibility_version(VERSION_1_1); group.setname("Default"); return group; } private VDSGroup createDefaultVdsGroup() { VDSGroup group = new VDSGroup(); group.setname("Default"); group.setID(VDSGroup.DEFAULT_VDS_GROUP_ID); group.setcpu_name("Intel Conroe"); group.setcompatibility_version(VERSION_1_1); group.setstorage_pool_id(STORAGE_POOL_ID); return group; } private VDSGroup createVdsGroupWithNoCpuName() { VDSGroup group = new VDSGroup(); group.setname("Default"); group.setID(VDSGroup.DEFAULT_VDS_GROUP_ID); group.setcompatibility_version(VERSION_1_1); group.setstorage_pool_id(STORAGE_POOL_ID); return group; } private VDSGroup createDetachedDefaultVdsGroup() { VDSGroup group = createDefaultVdsGroup(); group.setstorage_pool_id(null); return group; } private VDSGroup createVdsGroupWithOlderVersion() { VDSGroup group = createNewVdsGroup(); group.setcompatibility_version(VERSION_1_0); return group; } private VDSGroup createVdsGroupWithBadVersion() { VDSGroup group = createNewVdsGroup(); group.setcompatibility_version(new Version(5, 0)); return group; } private VDSGroup createVdsGroupWithDifferentPool() { VDSGroup group = createNewVdsGroup(); group.setstorage_pool_id(Guid.NewGuid()); return group; } private VDSGroup createVdsGroupWithPowerSave() { VDSGroup group = createDefaultVdsGroup(); group.setselection_algorithm(VdsSelectionAlgorithm.PowerSave); return group; } private storage_pool createStoragePoolLocalFS() { storage_pool pool = new storage_pool(); pool.setstorage_pool_type(StorageType.LOCALFS); return pool; } private void storagePoolIsLocalFS() { when(storagePoolDAO.get(any(Guid.class))).thenReturn(createStoragePoolLocalFS()); } private void oldGroupIsDetachedDefault() { when(vdsGroupDAO.get(any(Guid.class))).thenReturn(createDetachedDefaultVdsGroup()); } private void storagePoolAlreadyHasCluster() { VDSGroup group = new VDSGroup(); List<VDSGroup> groupList = new ArrayList<VDSGroup>(); groupList.add(group); when(vdsGroupDAO.getAllForStoragePool(any(Guid.class))).thenReturn(groupList); } private void VdsExistWithHigherVersion() { VDS vds = new VDS(); List<VDS> vdsList = new ArrayList<VDS>(); vdsList.add(vds); VdcQueryReturnValue returnValue = mock(VdcQueryReturnValue.class); when(backendInternal.runInternalQuery(any(VdcQueryType.class), argThat( new ArgumentMatcher<VdcQueryParametersBase>() { @Override public boolean matches(final Object o) { SearchParameters param = (SearchParameters) o; return param.getSearchTypeValue().equals(SearchType.VDS); } }))) .thenReturn(returnValue); when(returnValue.getReturnValue()).thenReturn(vdsList); } private void allQueriesEmpty() { VdcQueryReturnValue returnValue = mock(VdcQueryReturnValue.class); when(backendInternal.runInternalQuery(any(VdcQueryType.class), any(SearchParameters.class))) .thenReturn(returnValue); when(returnValue.getReturnValue()).thenReturn(Collections.emptyList()); } private void vdsGroupHasVds() { List<VdsStatic> vdsList = new ArrayList<VdsStatic>(); vdsList.add(new VdsStatic()); when(vdsStaticDAO.getAllForVdsGroup(any(Guid.class))).thenReturn(vdsList); } private void clusterHasVds() { VDS vds = new VDS(); vds.setsupported_cluster_levels(VERSION_1_1.toString()); List<VDS> vdsList = new ArrayList<VDS>(); vdsList.add(vds); VdcQueryReturnValue returnValue = mock(VdcQueryReturnValue.class); when(backendInternal.runInternalQuery(any(VdcQueryType.class), any(SearchParameters.class))) .thenReturn(returnValue); when(returnValue.getReturnValue()).thenReturn(vdsList); } private void CpuFlagsMissing() { List<String> strings = new ArrayList<String>(); strings.add("foo"); when(CpuFlagsManagerHandler.missingServerCpuFlags(anyString(), anyString(), any(Version.class))) .thenReturn(strings); } private void cpuFlagsNotMissing() { when(CpuFlagsManagerHandler.missingServerCpuFlags(anyString(), anyString(), any(Version.class))) .thenReturn(null); } private void clusterVersionIsSupported() { mockStatic(VersionSupport.class); when(VersionSupport.checkVersionSupported(any(Version.class))).thenReturn(true); when(VersionSupport.checkClusterVersionSupported(any(Version.class), any(VDS.class))).thenReturn(true); } private void cpuManufacturersDontMatch() { when(CpuFlagsManagerHandler.CheckIfCpusSameManufacture(anyString(), anyString(), any(Version.class))) .thenReturn(false); } private void cpuManufacturersMatch() { when(CpuFlagsManagerHandler.CheckIfCpusSameManufacture(anyString(), anyString(), any(Version.class))) .thenReturn(true); } private void cpuExists() { when(CpuFlagsManagerHandler.CheckIfCpusExist(anyString(), any(Version.class))).thenReturn(true); } private void setValidCpuVersionMap() { CpuFlagsManagerHandler.InitDictionaries(); when(Config.GetValue(ConfigValues.SupportedClusterLevels)).thenReturn(createVersionSet()); } private Set<Version> createVersionSet() { Set<Version> versions = new HashSet<Version>(); versions.add(VERSION_1_0); versions.add(VERSION_1_1); versions.add(VERSION_1_2); return versions; } private void canDoActionFailedWithReason(final VdcBllMessages message) { assertFalse(cmd.canDoAction()); assertTrue(cmd.getReturnValue().getCanDoActionMessages().contains(message.toString())); } }