package org.ovirt.engine.core.bll.snapshots; import static org.hamcrest.Matchers.empty; import static org.hamcrest.Matchers.hasItem; import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyList; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.verify; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import org.junit.Before; 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.memory.MemoryImageBuilder; import org.ovirt.engine.core.bll.utils.VmOverheadCalculator; import org.ovirt.engine.core.bll.utils.VmOverheadCalculatorImpl; import org.ovirt.engine.core.bll.validator.VmValidator; import org.ovirt.engine.core.bll.validator.storage.DiskImagesValidator; import org.ovirt.engine.core.bll.validator.storage.MultipleStorageDomainsValidator; import org.ovirt.engine.core.bll.validator.storage.StoragePoolValidator; import org.ovirt.engine.core.common.action.CreateAllSnapshotsFromVmParameters; import org.ovirt.engine.core.common.businessentities.DisplayType; import org.ovirt.engine.core.common.businessentities.VM; import org.ovirt.engine.core.common.businessentities.VmStatic; import org.ovirt.engine.core.common.businessentities.storage.DiskImage; import org.ovirt.engine.core.common.errors.EngineMessage; import org.ovirt.engine.core.compat.Guid; /** A test case for the {@link CreateAllSnapshotsFromVmCommand} class. */ public class CreateAllSnapshotsFromVmCommandTest extends BaseCommandTest { @Spy @InjectMocks private CreateAllSnapshotsFromVmCommand<CreateAllSnapshotsFromVmParameters> cmd = new CreateAllSnapshotsFromVmCommand<> (new CreateAllSnapshotsFromVmParameters(Guid.newGuid(), "", false), null); @Mock private VmValidator vmValidator; @Mock private SnapshotsValidator snapshotsValidator; @Mock private VM vm; @Mock private VmStatic vmStatic; @Mock private DiskImagesValidator diskImagesValidator; @Mock private MultipleStorageDomainsValidator multipleStorageDomainsValidator; @Mock private StoragePoolValidator storagePoolValidator; @Mock private MemoryImageBuilder memoryImageBuilder; @Spy private VmOverheadCalculator vmOverheadCalculator = new VmOverheadCalculatorImpl(); @SuppressWarnings("unchecked") @Before public void setUp() { doReturn(true).when(vm).isManagedVm(); doReturn(DisplayType.vga).when(vmStatic).getDefaultDisplayType(); doReturn(vmStatic).when(vm).getStaticData(); doReturn(vm).when(cmd).getVm(); doReturn(vmValidator).when(cmd).createVmValidator(); doReturn(storagePoolValidator).when(cmd).createStoragePoolValidator(); doReturn(diskImagesValidator).when(cmd).createDiskImageValidator(anyList()); doReturn(multipleStorageDomainsValidator).when(cmd).createMultipleStorageDomainsValidator(anyList()); doReturn(memoryImageBuilder).when(cmd).getMemoryImageBuilder(); doReturn(true).when(cmd).validateCinder(); doReturn(Guid.newGuid()).when(cmd).getStorageDomainIdForVmMemory(anyList()); doReturn(getEmptyDiskList()).when(cmd).getDisksListForChecks(); doReturn(getEmptyDiskList()).when(cmd).getDiskImagesForVm(); } @Test public void testPositiveValidateWithNoDisks() { doReturn(getEmptyDiskList()).when(cmd).getDisksList(); doReturn(Guid.newGuid()).when(cmd).getStorageDomainId(); assertTrue(cmd.validate()); assertTrue(cmd.getReturnValue().getValidationMessages().isEmpty()); } @Test public void testVMIsNotValid() { doReturn(Boolean.FALSE).when(cmd).validateVM(vmValidator); doReturn(getEmptyDiskList()).when(cmd).getDisksList(); assertFalse(cmd.validate()); } @Test public void testStoragePoolIsNotUp() { doReturn(new ValidationResult(EngineMessage.ACTION_TYPE_FAILED_IMAGE_REPOSITORY_NOT_FOUND)).when(storagePoolValidator) .isUp(); doReturn(getEmptyDiskList()).when(cmd).getDisksList(); assertFalse(cmd.validate()); assertTrue(cmd.getReturnValue() .getValidationMessages() .contains(EngineMessage.ACTION_TYPE_FAILED_IMAGE_REPOSITORY_NOT_FOUND.name())); } @Test public void testVmDuringSnaoshot() { doReturn(new ValidationResult(EngineMessage.ACTION_TYPE_FAILED_VM_IS_DURING_SNAPSHOT)).when(snapshotsValidator) .vmNotDuringSnapshot(any(Guid.class)); doReturn(getEmptyDiskList()).when(cmd).getDisksList(); assertFalse(cmd.validate()); assertTrue(cmd.getReturnValue() .getValidationMessages() .contains(EngineMessage.ACTION_TYPE_FAILED_VM_IS_DURING_SNAPSHOT.name())); } @Test public void testVmInPreview() { doReturn(new ValidationResult(EngineMessage.ACTION_TYPE_FAILED_VM_IN_PREVIEW)).when(snapshotsValidator) .vmNotInPreview(any(Guid.class)); doReturn(getEmptyDiskList()).when(cmd).getDisksList(); assertFalse(cmd.validate()); assertTrue(cmd.getReturnValue() .getValidationMessages() .contains(EngineMessage.ACTION_TYPE_FAILED_VM_IN_PREVIEW.name())); } @Test public void testVmDuringMigration() { doReturn(new ValidationResult(EngineMessage.ACTION_TYPE_FAILED_MIGRATION_IN_PROGRESS)).when(vmValidator) .vmNotDuringMigration(); doReturn(getEmptyDiskList()).when(cmd).getDisksList(); assertFalse(cmd.validate()); assertTrue(cmd.getReturnValue() .getValidationMessages() .contains(EngineMessage.ACTION_TYPE_FAILED_MIGRATION_IN_PROGRESS.name())); } @Test public void testSaveMemoryPciPassthroughFailure() { cmd.getParameters().setSaveMemory(true); doReturn(new ValidationResult(EngineMessage.ACTION_TYPE_FAILED_VM_HAS_ATTACHED_PCI_HOST_DEVICES)) .when(vmValidator) .vmNotHavingPciPassthroughDevices(); doReturn(getEmptyDiskList()).when(cmd).getDisksList(); assertFalse(cmd.validate()); assertThat(cmd.getReturnValue().getValidationMessages(), hasItem(EngineMessage.ACTION_TYPE_FAILED_VM_HAS_ATTACHED_PCI_HOST_DEVICES.name())); } @Test public void testNoMemoryPciPassthroughSuccess() { cmd.getParameters().setSaveMemory(false); doReturn(new ValidationResult(EngineMessage.ACTION_TYPE_FAILED_VM_HAS_ATTACHED_PCI_HOST_DEVICES)) .when(vmValidator) .vmNotHavingPciPassthroughDevices(); doReturn(getEmptyDiskList()).when(cmd).getDisksList(); assertTrue(cmd.validate()); assertThat(cmd.getReturnValue().getValidationMessages(), is(empty())); } @Test public void testVmRunningStateless() { doReturn(new ValidationResult(EngineMessage.ACTION_TYPE_FAILED_VM_RUNNING_STATELESS)).when(vmValidator) .vmNotRunningStateless(); doReturn(getEmptyDiskList()).when(cmd).getDisksList(); assertFalse(cmd.validate()); assertTrue(cmd.getReturnValue() .getValidationMessages() .contains(EngineMessage.ACTION_TYPE_FAILED_VM_RUNNING_STATELESS.name())); } @Test public void testLiveSnapshotWhenNoPluggedDiskSnapshot() { doReturn(true).when(cmd).isLiveSnapshotApplicable(); doReturn(getEmptyDiskList()).when(cmd).getDisksList(); assertTrue(cmd.validate()); assertTrue(cmd.getReturnValue() .getValidationMessages() .isEmpty()); } @Test public void testVmIllegal() { doReturn(new ValidationResult(EngineMessage.ACTION_TYPE_FAILED_VM_IMAGE_IS_ILLEGAL)).when(vmValidator) .vmNotIlegal(); doReturn(getEmptyDiskList()).when(cmd).getDisksList(); assertFalse(cmd.validate()); assertTrue(cmd.getReturnValue() .getValidationMessages() .contains(EngineMessage.ACTION_TYPE_FAILED_VM_IMAGE_IS_ILLEGAL.name())); } @Test public void testVmLocked() { doReturn(new ValidationResult(EngineMessage.ACTION_TYPE_FAILED_VM_IS_LOCKED)).when(vmValidator) .vmNotLocked(); doReturn(getEmptyDiskList()).when(cmd).getDisksList(); assertFalse(cmd.validate()); assertTrue(cmd.getReturnValue() .getValidationMessages() .contains(EngineMessage.ACTION_TYPE_FAILED_VM_IS_LOCKED.name())); } @Test public void testPositiveValidateWithDisks() { doReturn(getNonEmptyDiskList()).when(cmd).getDisksList(); doReturn(Guid.newGuid()).when(cmd).getStorageDomainId(); assertTrue(cmd.validate()); assertTrue(cmd.getReturnValue().getValidationMessages().isEmpty()); } @Test public void testImagesExceededNumberOfVolumesInChain() { doReturn(getNonEmptyDiskList()).when(cmd).getDisksList(); doReturn(getNonEmptyDiskList()).when(cmd).getDisksListForChecks(); doReturn(new ValidationResult(EngineMessage.ACTION_TYPE_FAILED_MAXIMUM_LIMIT_OF_VOLUMES_IN_CHAIN)).when(diskImagesValidator) .diskImagesHaveNotExceededMaxNumberOfVolumesInImageChain(); assertFalse(cmd.validate()); assertTrue(cmd.getReturnValue() .getValidationMessages() .contains(EngineMessage.ACTION_TYPE_FAILED_MAXIMUM_LIMIT_OF_VOLUMES_IN_CHAIN.name())); } @Test public void testImagesLocked() { doReturn(getNonEmptyDiskList()).when(cmd).getDisksList(); doReturn(getNonEmptyDiskList()).when(cmd).getDisksListForChecks(); doReturn(new ValidationResult(EngineMessage.ACTION_TYPE_FAILED_DISKS_LOCKED)).when(diskImagesValidator) .diskImagesNotLocked(); assertFalse(cmd.validate()); assertTrue(cmd.getReturnValue() .getValidationMessages() .contains(EngineMessage.ACTION_TYPE_FAILED_DISKS_LOCKED.name())); } @Test public void testImagesIllegal() { doReturn(getNonEmptyDiskList()).when(cmd).getDisksList(); doReturn(getNonEmptyDiskList()).when(cmd).getDisksListForChecks(); doReturn(new ValidationResult(EngineMessage.ACTION_TYPE_FAILED_DISKS_ILLEGAL)).when(diskImagesValidator) .diskImagesNotIllegal(); assertFalse(cmd.validate()); assertTrue(cmd.getReturnValue() .getValidationMessages() .contains(EngineMessage.ACTION_TYPE_FAILED_DISKS_ILLEGAL.name())); } @Test public void testImagesDoesNotExist() { DiskImage diskImage1 = getNewDiskImage(); DiskImage diskImage2 = getNewDiskImage(); List<DiskImage> diskImagesFromParams = new ArrayList<>(); diskImagesFromParams.addAll(Arrays.asList(diskImage1, diskImage2)); cmd.getParameters().setDisks(diskImagesFromParams); doReturn(new ValidationResult(EngineMessage.ACTION_TYPE_FAILED_DISKS_NOT_EXIST)).when(diskImagesValidator) .diskImagesNotExist(); ValidateTestUtils.runAndAssertValidateFailure(cmd, EngineMessage.ACTION_TYPE_FAILED_DISKS_NOT_EXIST); } @Test public void testAllDomainsExistAndActive() { doReturn(Collections.emptyList()).when(cmd).getDisksList(); doReturn(new ValidationResult(EngineMessage.ACTION_TYPE_FAILED_STORAGE_DOMAIN_NOT_EXIST)).when(multipleStorageDomainsValidator) .allDomainsExistAndActive(); assertFalse(cmd.validate()); assertTrue(cmd.getReturnValue() .getValidationMessages() .contains(EngineMessage.ACTION_TYPE_FAILED_STORAGE_DOMAIN_NOT_EXIST.name())); } @Test public void testAllDomainsHaveSpaceForNewDisksFailure() { List<DiskImage> disksList = Collections.emptyList(); doReturn(disksList).when(cmd).getDisksList(); doReturn(new ValidationResult(EngineMessage.ACTION_TYPE_FAILED_DISK_SPACE_LOW_ON_STORAGE_DOMAIN)).when(multipleStorageDomainsValidator) .allDomainsHaveSpaceForNewDisks(disksList); ValidateTestUtils.runAndAssertValidateFailure(cmd, EngineMessage.ACTION_TYPE_FAILED_DISK_SPACE_LOW_ON_STORAGE_DOMAIN); verify(multipleStorageDomainsValidator).allDomainsHaveSpaceForNewDisks(disksList); } @Test public void testAllDomainsHaveSpaceForNewDisksSuccess() { List<DiskImage> disksList = Collections.emptyList(); doReturn(disksList).when(cmd).getDisksList(); ValidateTestUtils.runAndAssertValidateSuccess(cmd); verify(multipleStorageDomainsValidator).allDomainsHaveSpaceForNewDisks(disksList); } @Test public void testAllDomainsWithinThreshold() { doReturn(Collections.emptyList()).when(cmd).getDisksList(); doReturn(new ValidationResult(EngineMessage.ACTION_TYPE_FAILED_DISK_SPACE_LOW_ON_STORAGE_DOMAIN)).when(multipleStorageDomainsValidator) .allDomainsExistAndActive(); assertFalse(cmd.validate()); assertTrue(cmd.getReturnValue() .getValidationMessages() .contains(EngineMessage.ACTION_TYPE_FAILED_DISK_SPACE_LOW_ON_STORAGE_DOMAIN.name())); } @Test public void testAllDomainsHaveSpaceForAllDisksFailure() { doReturn(Collections.emptyList()).when(cmd).getDisksList(); cmd.getParameters().setSaveMemory(true); doReturn(Guid.newGuid()).when(cmd).getStorageDomainIdForVmMemory(eq(Collections.emptyList())); doReturn(new ValidationResult(EngineMessage.ACTION_TYPE_FAILED_DISK_SPACE_LOW_ON_STORAGE_DOMAIN)).when(multipleStorageDomainsValidator) .allDomainsHaveSpaceForAllDisks(eq(Collections.emptyList()), anyList()); ValidateTestUtils.runAndAssertValidateFailure(cmd, EngineMessage.ACTION_TYPE_FAILED_DISK_SPACE_LOW_ON_STORAGE_DOMAIN); verify(multipleStorageDomainsValidator).allDomainsHaveSpaceForAllDisks(eq(Collections.emptyList()), anyList()); } @Test public void testAllDomainsHaveSpaceForAllDisksSuccess() { doReturn(Collections.emptyList()).when(cmd).getDisksList(); cmd.getParameters().setSaveMemory(true); doReturn(Guid.newGuid()).when(cmd).getStorageDomainIdForVmMemory(eq(Collections.emptyList())); ValidateTestUtils.runAndAssertValidateSuccess(cmd); verify(multipleStorageDomainsValidator).allDomainsHaveSpaceForAllDisks(eq(Collections.emptyList()), anyList()); } private static List<DiskImage> getEmptyDiskList() { List<DiskImage> diskList = new ArrayList<>(); return diskList; } private static List<DiskImage> getNonEmptyDiskList() { List<DiskImage> diskList = new ArrayList<>(); DiskImage newDiskImage = new DiskImage(); newDiskImage.setStorageIds(new ArrayList<>()); diskList.add(newDiskImage); return diskList; } private static DiskImage getNewDiskImage() { DiskImage diskImage = new DiskImage(); diskImage.setId(Guid.newGuid()); return diskImage; } }