package org.ovirt.engine.core.bll; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyList; import static org.mockito.ArgumentMatchers.anySet; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; import java.util.stream.Stream; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.Spy; import org.ovirt.engine.core.bll.validator.storage.MultipleStorageDomainsValidator; import org.ovirt.engine.core.common.action.AddVmPoolParameters; import org.ovirt.engine.core.common.businessentities.ArchitectureType; import org.ovirt.engine.core.common.businessentities.Cluster; import org.ovirt.engine.core.common.businessentities.StorageDomain; import org.ovirt.engine.core.common.businessentities.StorageDomainStatus; import org.ovirt.engine.core.common.businessentities.StorageDomainType; import org.ovirt.engine.core.common.businessentities.StoragePool; import org.ovirt.engine.core.common.businessentities.StoragePoolStatus; import org.ovirt.engine.core.common.businessentities.VM; import org.ovirt.engine.core.common.businessentities.VMStatus; import org.ovirt.engine.core.common.businessentities.VmPool; import org.ovirt.engine.core.common.businessentities.VmStatic; import org.ovirt.engine.core.common.businessentities.VmTemplate; import org.ovirt.engine.core.common.businessentities.storage.DiskImage; import org.ovirt.engine.core.common.errors.EngineMessage; import org.ovirt.engine.core.common.osinfo.OsRepository; 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.DiskImageDao; import org.ovirt.engine.core.dao.StorageDomainDao; import org.ovirt.engine.core.dao.StoragePoolDao; import org.ovirt.engine.core.dao.VmPoolDao; import org.ovirt.engine.core.dao.VmTemplateDao; import org.ovirt.engine.core.dao.network.VmNetworkInterfaceDao; import org.ovirt.engine.core.utils.MockConfigRule; public abstract class CommonVmPoolCommandTestAbstract extends BaseCommandTest { @Rule public MockConfigRule mcr = new MockConfigRule(); private final Guid clusterId = Guid.newGuid(); protected final Guid firstStorageDomainId = Guid.newGuid(); private final Guid secondStorageDomainId = Guid.newGuid(); private final Guid storagePoolId = Guid.newGuid(); private final Guid vmTemplateId = Guid.newGuid(); protected Guid vmPoolId = Guid.newGuid(); private Cluster cluster = mockCluster(); protected VM testVm = mockVm(); protected VmPool vmPools = mockVmPools(); protected static int VM_COUNT = 5; protected VmTemplate vmTemplate = mockVmTemplate(); protected StoragePool storagePool = mockStoragePool(); protected List<StorageDomain> storageDomainsList; protected static final int MAX_MEMORY_SIZE = 4096; @Mock protected ClusterDao clusterDao; @Mock protected DiskImageDao diskImageDao; @Mock protected VmPoolDao vmPoolDao; @Mock protected StoragePoolDao storagePoolDao; @Mock protected VmTemplateDao vmTemplateDao; @Mock protected VmNetworkInterfaceDao vmNetworkInterfaceDao; @Mock protected StorageDomainDao storageDomainDao; @Mock private MultipleStorageDomainsValidator multipleSdValidator; /** * The command under test. */ @Spy @InjectMocks protected CommonVmPoolCommand<AddVmPoolParameters> command = createCommand(); protected abstract CommonVmPoolCommand<AddVmPoolParameters> createCommand(); @Test public void validateSufficientSpaceOnDestinationDomains() { setupForStorageTests(); command.ensureDestinationImageMap(); assertTrue(command.checkDestDomains()); verify(multipleSdValidator).allDomainsWithinThresholds(); verify(multipleSdValidator).allDomainsHaveSpaceForNewDisks(anyList()); } @Test public void validateInsufficientSpaceOnDomains() { setupForStorageTests(); doReturn(new ValidationResult(EngineMessage.ACTION_TYPE_FAILED_DISK_SPACE_LOW_ON_STORAGE_DOMAIN)). when(multipleSdValidator).allDomainsHaveSpaceForNewDisks(anyList()); assertFalse(command.validate()); assertTrue(command.getReturnValue() .getValidationMessages() .contains(EngineMessage.ACTION_TYPE_FAILED_DISK_SPACE_LOW_ON_STORAGE_DOMAIN.toString())); verify(multipleSdValidator).allDomainsWithinThresholds(); verify(multipleSdValidator).allDomainsHaveSpaceForNewDisks(anyList()); } @Test public void validateDomainNotWithinThreshold() { setupForStorageTests(); doReturn(new ValidationResult(EngineMessage.ACTION_TYPE_FAILED_DISK_SPACE_LOW_ON_STORAGE_DOMAIN)). when(multipleSdValidator).allDomainsWithinThresholds(); assertFalse(command.validate()); assertTrue(command.getReturnValue() .getValidationMessages() .contains(EngineMessage.ACTION_TYPE_FAILED_DISK_SPACE_LOW_ON_STORAGE_DOMAIN.toString())); verify(multipleSdValidator).allDomainsWithinThresholds(); verify(multipleSdValidator, never()).allDomainsHaveSpaceForNewDisks(anyList()); } @Before public void setupMocks() { setUpCommand(); mockGetStorageDomainList(); mockDbDao(); command.init(); } protected void setUpCommand() { doNothing().when(command).initTemplate(); doReturn(true).when(command).areTemplateImagesInStorageReady(any(Guid.class)); doReturn(true).when(command).verifyAddVm(); doReturn(true).when(command).setAndValidateDiskProfiles(); doReturn(true).when(command).setAndValidateCpuProfile(); } protected void mockGetStorageDomainList() { // Mock Dao storageDomainsList = getStorageDomainList(); mockDiskImageDao(); mockStorageDomainDao(storageDomainsList); } private void mockStoragePoolDao() { when(storagePoolDao.get(storagePoolId)).thenReturn(storagePool); } private void mockVMTemplateDao() { when(vmTemplateDao.get(vmTemplateId)).thenReturn(vmTemplate); } private void mockClusterDao() { when(clusterDao.get(clusterId)).thenReturn(cluster); } private void mockDiskImageDao() { when(diskImageDao.getSnapshotById(any(Guid.class))).thenReturn(getDiskImageList().get(0)); } private void mockStorageDomainDao(List<StorageDomain> storageDomains) { for (StorageDomain storageDomain : storageDomains) { when(storageDomainDao.getForStoragePool(storageDomain.getId(), storagePoolId)).thenReturn(storageDomain); } } /** * Mock a VM. */ private VM mockVm() { VM vm = new VM(); vm.setStatus(VMStatus.Down); vm.setVmtGuid(vmTemplateId); vm.setStaticData(getVmStatic()); vm.setClusterArch(ArchitectureType.x86_64); vm.setName("my_vm"); return vm; } private StorageDomain mockDomain(Guid id) { StorageDomain storageDomain = new StorageDomain(); storageDomain.setStatus(StorageDomainStatus.Active); storageDomain.setId(id); storageDomain.setStorageDomainType(StorageDomainType.Data); return storageDomain; } protected List<StorageDomain> getStorageDomainList() { return Stream.of(firstStorageDomainId, secondStorageDomainId).map(this::mockDomain).collect(Collectors.toList()); } /** * Mock VDS Group. */ private Cluster mockCluster() { Cluster group = new Cluster(); group.setClusterId(clusterId); group.setCompatibilityVersion(new Version()); group.setStoragePoolId(storagePoolId); group.setCpuName("Intel Conroe Family"); group.setArchitecture(ArchitectureType.x86_64); return group; } /** * Mock VM Template. */ private VmTemplate mockVmTemplate() { VmTemplate template = new VmTemplate(); template.setId(vmTemplateId); template.setStoragePoolId(storagePoolId); template.setClusterArch(ArchitectureType.x86_64); setDiskList(template); return template; } /** * Mock Storage Pool */ private StoragePool mockStoragePool() { StoragePool storagePool = new StoragePool(); storagePool.setStatus(StoragePoolStatus.Up); return storagePool; } private static void setDiskList(VmTemplate vmTemplate) { for (DiskImage diskImage : getDiskImageList()) { vmTemplate.getDiskList().add(diskImage); } Map<Guid, DiskImage> diskImageTemplate = getDiskImageTempalteList(); vmTemplate.getDiskTemplateMap().putAll(diskImageTemplate); } private static List<DiskImage> getDiskImageList() { List<DiskImage> diskList = new ArrayList<>(); DiskImage diskImage = new DiskImage(); diskImage.setId(Guid.newGuid()); diskImage.setStorageIds(new ArrayList<>()); diskList.add(diskImage); diskImage = new DiskImage(); diskImage.setId(Guid.newGuid()); diskImage.setStorageIds(new ArrayList<>()); diskList.add(diskImage); return diskList; } private static Map<Guid, DiskImage> getDiskImageTempalteList() { Map<Guid, DiskImage> diskTemplateList = new HashMap<>(); DiskImage diskImageTemplate = new DiskImage(); diskImageTemplate.setId(Guid.newGuid()); diskImageTemplate.setImageId(Guid.newGuid()); diskImageTemplate.setStorageIds(new ArrayList<>()); diskTemplateList.put(diskImageTemplate.getId(), diskImageTemplate); diskImageTemplate = new DiskImage(); diskImageTemplate.setId(Guid.newGuid()); diskImageTemplate.setImageId(Guid.newGuid()); diskImageTemplate.setStorageIds(new ArrayList<>()); diskTemplateList.put(diskImageTemplate.getId(), diskImageTemplate); return diskTemplateList; } private VmStatic getVmStatic() { VmStatic vmStatic = new VmStatic(); vmStatic.setOsId(OsRepository.DEFAULT_X86_OS); vmStatic.setNumOfMonitors(1); vmStatic.setMemSizeMb(300); vmStatic.setMaxMemorySizeMb(MAX_MEMORY_SIZE); vmStatic.setStateless(false); vmStatic.setVmtGuid(vmTemplateId); return vmStatic; } /** * Mock VM pools. */ private VmPool mockVmPools() { VmPool pool = new VmPool(); pool.setName("simplePoolName"); pool.setClusterId(clusterId); pool.setVmPoolId(vmPoolId); return pool; } private void mockDbDao() { mockClusterDao(); mockVMTemplateDao(); mockStoragePoolDao(); } protected void setupForStorageTests() { doReturn(multipleSdValidator).when(command).getStorageDomainsValidator(any(Guid.class), anySet()); } }