package org.ovirt.engine.core.bll.exportimport; import static java.util.Collections.emptyList; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyList; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Paths; import java.util.ArrayList; import java.util.List; import org.junit.Before; import org.junit.BeforeClass; import org.junit.ClassRule; import org.junit.Test; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.Spy; import org.ovirt.engine.core.bll.BaseCommandTest; import org.ovirt.engine.core.bll.ValidateTestUtils; import org.ovirt.engine.core.bll.ValidationResult; import org.ovirt.engine.core.bll.network.macpool.MacPool; import org.ovirt.engine.core.bll.network.vm.ExternalVmMacsFinder; import org.ovirt.engine.core.bll.storage.ovfstore.OvfHelper; import org.ovirt.engine.core.bll.validator.ImportValidator; import org.ovirt.engine.core.common.action.ImportVmParameters; import org.ovirt.engine.core.common.businessentities.ArchitectureType; import org.ovirt.engine.core.common.businessentities.Cluster; import org.ovirt.engine.core.common.businessentities.OvfEntityData; 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.errors.EngineMessage; import org.ovirt.engine.core.common.osinfo.OsRepository; import org.ovirt.engine.core.common.utils.SimpleDependencyInjector; import org.ovirt.engine.core.compat.Guid; import org.ovirt.engine.core.dao.UnregisteredOVFDataDao; import org.ovirt.engine.core.utils.MockConfigRule; import org.ovirt.engine.core.utils.ovf.OvfManager; public class ImportVMFromConfigurationCommandTest extends BaseCommandTest { private Guid vmId = Guid.newGuid(); private static final Guid storageDomainId = new Guid("7e2a7eac-3b76-4d45-a7dd-caae8fe0f588"); private final Guid storagePoolId = Guid.newGuid(); private final Guid clusterId = Guid.newGuid(); private static final String VM_OVF_XML_DATA = "src/test/resources/vmOvfData.xml"; private String xmlOvfData; @Mock private Cluster cluster; private StoragePool storagePool; @Spy @InjectMocks private ImportVmFromConfigurationCommand<ImportVmParameters> cmd = new ImportVmFromConfigurationCommand<>(createParametersWhenImagesExistOnTargetStorageDomain(), null); private ImportValidator validator; @ClassRule public static MockConfigRule mcr = new MockConfigRule(); @Mock private UnregisteredOVFDataDao unregisteredOVFDataDao; @Mock private ExternalVmMacsFinder externalVmMacsFinder; @Mock private ExternalVnicProfileMappingValidator externalVnicProfileMappingValidator; @Spy @InjectMocks private OvfHelper ovfHelper; @Mock private OvfManager ovfManager; @BeforeClass public static void setUpInjections() { // init the injector with the osRepository instance OsRepository osRepository = mock(OsRepository.class); SimpleDependencyInjector.getInstance().bind(OsRepository.class, osRepository); } @Before public void setUp() throws IOException { doReturn(cluster).when(cmd).getCluster(); doReturn(emptyList()).when(cmd).getImages(); mockCluster(); setXmlOvfData(); } private void setXmlOvfData() throws IOException { xmlOvfData = new String(Files.readAllBytes(Paths.get(VM_OVF_XML_DATA)), StandardCharsets.UTF_8); } @Test public void testPositiveImportVmFromConfiguration() { initCommand(getOvfEntityData()); doReturn(storagePool).when(cmd).getStoragePool(); doReturn(Boolean.TRUE).when(cmd).validateAfterCloneVm(any()); doReturn(Boolean.TRUE).when(cmd).validateBeforeCloneVm(any()); when(validator.validateUnregisteredEntity(any(), any())) .thenReturn(ValidationResult.VALID); when(validator.validateStorageExistForUnregisteredEntity(anyList(), anyBoolean(), any(), any())) .thenReturn(ValidationResult.VALID); ValidateTestUtils.runAndAssertValidateSuccess(cmd); } @Test public void testImportVMFromConfigurationWhenStorageDomainIsInMaintenance() { initCommand(getOvfEntityData()); StorageDomain storageDomain = createStorageDomain(); storageDomain.setStatus(StorageDomainStatus.Maintenance); doReturn(storageDomain).when(cmd).getStorageDomain(); when(validator.validateUnregisteredEntity(any(), any())).thenReturn(ValidationResult.VALID); when(validator.validateStorageExistForUnregisteredEntity(anyList(), anyBoolean(), any(), any())). thenReturn(new ValidationResult(EngineMessage.ACTION_TYPE_FAILED_STORAGE_DOMAIN_STATUS_ILLEGAL2)); ValidateTestUtils.runAndAssertValidateFailure(cmd, EngineMessage.ACTION_TYPE_FAILED_STORAGE_DOMAIN_STATUS_ILLEGAL2); } @Test public void testImportVMFromConfigurationWhenStorageDomainIsInactive() { initCommand(getOvfEntityData()); StorageDomain storageDomain = createStorageDomain(); storageDomain.setStatus(StorageDomainStatus.Inactive); when(validator.validateUnregisteredEntity(any(), any())).thenReturn(ValidationResult.VALID); when(validator.validateStorageExistForUnregisteredEntity(anyList(), anyBoolean(), any(), any())). thenReturn(new ValidationResult(EngineMessage.ACTION_TYPE_FAILED_STORAGE_DOMAIN_STATUS_ILLEGAL2)); ValidateTestUtils.runAndAssertValidateFailure(cmd, EngineMessage.ACTION_TYPE_FAILED_STORAGE_DOMAIN_STATUS_ILLEGAL2); } @Test public void testImportVMFromConfigurationWhenVMDoesNotExists() { initCommand(null); ValidateTestUtils.runAndAssertValidateFailure(cmd, EngineMessage.ACTION_TYPE_FAILED_UNSUPPORTED_OVF); } @Test public void testImportVMFromConfigurationXMLCouldNotGetParsed() { OvfEntityData ovfEntity = getOvfEntityData(); ovfEntity.setOvfData("This is not a valid XML"); initCommand(ovfEntity); List<OvfEntityData> ovfEntityDataList = new ArrayList<>(); ovfEntityDataList.add(ovfEntity); when(unregisteredOVFDataDao.getByEntityIdAndStorageDomain(vmId, storageDomainId)).thenReturn(ovfEntityDataList); when(validator.validateUnregisteredEntity( any(), any())). thenReturn(new ValidationResult(EngineMessage.ACTION_TYPE_FAILED_OVF_CONFIGURATION_NOT_SUPPORTED)); ValidateTestUtils.runAndAssertValidateFailure(cmd, EngineMessage.ACTION_TYPE_FAILED_OVF_CONFIGURATION_NOT_SUPPORTED); } private ImportVmParameters createParametersWhenImagesExistOnTargetStorageDomain() { ImportVmParameters params = new ImportVmParameters(emptyList(), true); params.setContainerId(vmId); params.setStorageDomainId(storageDomainId); params.setClusterId(clusterId); params.setImagesExistOnTargetStorageDomain(true); return params; } private void initCommand(OvfEntityData resultOvfEntityData) { initUnregisteredOVFData(resultOvfEntityData); doReturn(mock(MacPool.class)).when(cmd).getMacPool(); validator = spy(new ImportValidator(cmd.getParameters())); doReturn(validator).when(cmd).getImportValidator(); mockStoragePool(); doReturn(storagePool).when(validator).getStoragePool(); cmd.init(); } private void initUnregisteredOVFData(OvfEntityData resultOvfEntityData) { List<OvfEntityData> ovfEntityDataList = new ArrayList<>(); if (resultOvfEntityData != null) { ovfEntityDataList.add(resultOvfEntityData); } when(unregisteredOVFDataDao.getByEntityIdAndStorageDomain(vmId, storageDomainId)).thenReturn(ovfEntityDataList); } private OvfEntityData getOvfEntityData() { OvfEntityData ovfEntity = new OvfEntityData(); ovfEntity.setEntityId(vmId); ovfEntity.setEntityName("Some VM"); ovfEntity.setOvfData(xmlOvfData); return ovfEntity; } private void mockCluster() { cluster = mock(Cluster.class); doReturn(clusterId).when(cluster).getId(); doReturn(storagePoolId).when(cluster).getStoragePoolId(); doReturn(ArchitectureType.x86_64).when(cluster).getArchitecture(); } private void mockStoragePool() { storagePool = new StoragePool(); storagePool.setId(storagePoolId); } protected StorageDomain createStorageDomain() { StorageDomain sd = new StorageDomain(); sd.setId(storageDomainId); sd.setStorageDomainType(StorageDomainType.Data); sd.setStatus(StorageDomainStatus.Active); sd.setStoragePoolId(storagePoolId); return sd; } }