Vered Volansky has uploaded a new change for review.

Change subject: core: MoveOrCopyDiskCommand space verification
......................................................................

core: MoveOrCopyDiskCommand space verification

This is a part in a series of patches intended to fix storage space
allocation validation throughout the system (see bz).
Added hasSpaceForClonedDisk(s) in StorageDomainValidator.
Applied use in MoveOrCopyDiskCommand (former use is buggy).

Change-Id: I951aeb531cb7ff7aaf3f1d50fc55100b6a806059
Bug-url: https://bugzilla.redhat.com/960934
Signed-off-by: Vered Volansky <vvola...@redhat.com>
---
M 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/MoveOrCopyDiskCommand.java
M 
backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/validator/StorageDomainValidator.java
M 
backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/AddDiskToVmCommandTest.java
M 
backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/MoveOrCopyDiskCommandTest.java
M 
backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/validator/StorageDomainValidatorFreeSpaceTest.java
M 
backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/validator/StorageDomainValidatorTest.java
6 files changed, 133 insertions(+), 36 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/47/22447/1

diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/MoveOrCopyDiskCommand.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/MoveOrCopyDiskCommand.java
index 4da4fe8..ffedd6d 100644
--- 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/MoveOrCopyDiskCommand.java
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/MoveOrCopyDiskCommand.java
@@ -147,27 +147,9 @@
      * @return
      */
     protected boolean validateSpaceRequirements() {
-        if (!isStorageDomainSpaceWithinThresholds()) {
-            return false;
-        }
-
-        getImage().getSnapshots().addAll(getAllImageSnapshots());
-        if (!isDomainHasStorageSpaceForRequest()) {
-            return false;
-        }
-        return true;
-    }
-
-    private boolean isDomainHasStorageSpaceForRequest() {
-        return validate(new 
StorageDomainValidator(getStorageDomain()).isDomainHasSpaceForRequest(Math.round(getImage().getActualDiskWithSnapshotsSize())));
-    }
-
-    protected boolean isStorageDomainSpaceWithinThresholds() {
-        return validate(new 
StorageDomainValidator(getStorageDomain()).isDomainWithinThresholds());
-    }
-
-    protected List<DiskImage> getAllImageSnapshots() {
-        return ImagesHandler.getAllImageSnapshots(getImage().getImageId(), 
getImage().getImageTemplateId());
+        StorageDomainValidator storageDomainValidator = 
createStorageDomainValidator();
+        return validate(storageDomainValidator.isDomainWithinThresholds()) &&
+                
validate(storageDomainValidator.hasSpaceForClonedDisk(getImage()));
     }
 
     protected boolean checkIfNeedToBeOverride() {
@@ -206,7 +188,7 @@
      * @return
      */
     protected boolean checkCanBeMoveInVm() {
-        return validate(new 
DiskValidator(getImage()).isDiskPluggedToVmsThatAreNotDown(false, 
getVmsWithVmDeviceInfoForDiskId()));
+        return 
validate(createDiskValidator().isDiskPluggedToVmsThatAreNotDown(false, 
getVmsWithVmDeviceInfoForDiskId()));
     }
 
     /**
@@ -335,7 +317,6 @@
 
     /**
      * The following method will determine if a provided vm/template exists
-     * @param retValue
      * @return
      */
     private boolean canFindVmOrTemplate() {
@@ -440,4 +421,11 @@
         return jobProperties;
     }
 
+    protected StorageDomainValidator createStorageDomainValidator() {
+        return new StorageDomainValidator(getStorageDomain());
+    }
+
+    protected DiskValidator createDiskValidator() {
+        return new DiskValidator(getImage());
+    }
 }
diff --git 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/validator/StorageDomainValidator.java
 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/validator/StorageDomainValidator.java
index 4d92435..c37071d 100644
--- 
a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/validator/StorageDomainValidator.java
+++ 
b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/validator/StorageDomainValidator.java
@@ -3,8 +3,10 @@
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 
+import org.ovirt.engine.core.bll.ImagesHandler;
 import org.ovirt.engine.core.bll.ValidationResult;
 import org.ovirt.engine.core.common.businessentities.DiskImage;
 import org.ovirt.engine.core.common.businessentities.StorageDomain;
@@ -102,6 +104,34 @@
         return validateRequiredSpace(availableSize, totalSizeForDisks);
     }
 
+    public ValidationResult hasSpaceForClonedDisks(Collection<DiskImage> 
diskImages) {
+        double availableSize = storageDomain.getAvailableDiskSizeInBytes();
+        double totalSizeForDisks = 0.0;
+
+        for (DiskImage diskImage : diskImages) {
+            double diskCapacity = diskImage.getSize();
+            double sizeForDisk = diskCapacity;
+
+            if ((storageDomain.getStorageType().isFileDomain() && 
diskImage.getVolumeType() == VolumeType.Sparse) ||
+                    storageDomain.getStorageType().isBlockDomain() && 
diskImage.getVolumeFormat() == VolumeFormat.COW) {
+                addImageSnapshots(diskImage);
+                double usedSapce = 
diskImage.getActualDiskWithSnapshotsSizeInBytes();
+                sizeForDisk = Math.min(diskCapacity, usedSapce);
+            }
+
+            if (diskImage.getVolumeFormat() == VolumeFormat.COW) {
+                sizeForDisk = Math.ceil(QCOW_OVERHEAD_FACTOR * sizeForDisk);
+            }
+            totalSizeForDisks += sizeForDisk;
+        }
+
+        return validateRequiredSpace(availableSize, totalSizeForDisks);
+    }
+
+    public ValidationResult hasSpaceForClonedDisk(DiskImage diskImage) {
+        return hasSpaceForClonedDisks(Collections.singleton(diskImage));
+    }
+
     public ValidationResult hasSpaceForNewDisk(DiskImage diskImage) {
         return hasSpaceForNewDisks(Collections.singleton(diskImage));
     }
@@ -144,4 +174,9 @@
         }
         return map;
     }
+
+    private void addImageSnapshots(DiskImage diskImage) {
+        List<DiskImage> snapshots = 
ImagesHandler.getAllImageSnapshots(diskImage.getImageId(), 
diskImage.getImageTemplateId());
+        diskImage.getSnapshots().addAll(snapshots);
+    }
 }
diff --git 
a/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/AddDiskToVmCommandTest.java
 
b/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/AddDiskToVmCommandTest.java
index de3ad44..a7cef3e 100644
--- 
a/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/AddDiskToVmCommandTest.java
+++ 
b/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/AddDiskToVmCommandTest.java
@@ -22,6 +22,7 @@
 import org.mockito.Mock;
 import org.mockito.runners.MockitoJUnitRunner;
 import org.ovirt.engine.core.bll.snapshots.SnapshotsValidator;
+import org.ovirt.engine.core.bll.validator.DiskImagesValidator;
 import org.ovirt.engine.core.bll.validator.DiskValidator;
 import org.ovirt.engine.core.bll.validator.StorageDomainValidator;
 import org.ovirt.engine.core.common.action.AddDiskParameters;
diff --git 
a/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/MoveOrCopyDiskCommandTest.java
 
b/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/MoveOrCopyDiskCommandTest.java
index 7d0c5b4..9720733 100644
--- 
a/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/MoveOrCopyDiskCommandTest.java
+++ 
b/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/MoveOrCopyDiskCommandTest.java
@@ -4,6 +4,7 @@
 import static org.junit.Assert.assertTrue;
 import static org.mockito.Matchers.any;
 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 static org.ovirt.engine.core.utils.MockConfigRule.mockConfig;
@@ -17,7 +18,10 @@
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.runners.MockitoJUnitRunner;
+import org.ovirt.engine.core.bll.validator.DiskValidator;
+import org.ovirt.engine.core.bll.validator.StorageDomainValidator;
 import org.ovirt.engine.core.common.action.MoveOrCopyImageGroupParameters;
+import org.ovirt.engine.core.common.businessentities.Disk;
 import org.ovirt.engine.core.common.businessentities.DiskImage;
 import org.ovirt.engine.core.common.businessentities.ImageOperation;
 import org.ovirt.engine.core.common.businessentities.ImageStatus;
@@ -99,7 +103,7 @@
     }
 
     @Test
-    public void canDoActionCanNotFindTemplet() throws Exception {
+    public void canDoActionCanNotFindTemplate() throws Exception {
         initializeCommand(ImageOperation.Copy);
         initTemplateDiskImage();
         doReturn(null).when(command).getTemplateForImage();
@@ -115,7 +119,7 @@
         destStorageId = srcStorageId;
         initializeCommand(ImageOperation.Move);
         initVmDiskImage();
-        initVm();
+        initVmForFail();
         initSrcStorageDomain();
         assertFalse(command.canDoAction());
         assertTrue(command.getReturnValue()
@@ -127,7 +131,7 @@
     public void canDoActionVmIsNotDown() throws Exception {
         initializeCommand(ImageOperation.Move);
         initVmDiskImage();
-        initVm();
+        initVmForFail();
         initSrcStorageDomain();
         initDestStorageDomain();
         doReturn(vmDeviceDao).when(command).getVmDeviceDAO();
@@ -141,7 +145,7 @@
     public void canDoActionDiskIsLocked() throws Exception {
         initializeCommand(ImageOperation.Move);
         initVmDiskImage();
-        initVm();
+        initVmForFail();
         command.getImage().setImageStatus(ImageStatus.LOCKED);
         doReturn(vmDeviceDao).when(command).getVmDeviceDAO();
         assertFalse(command.canDoAction());
@@ -162,7 +166,40 @@
                 VdcBllMessages.VM_TEMPLATE_IMAGE_IS_LOCKED.toString()));
     }
 
-    protected void initVm() {
+    @Test
+    public void canDoActionNotEnoughSpace() throws Exception {
+        initializeCommand(ImageOperation.Move);
+        initVmForSpace();
+        initVmDiskImage();
+        initSrcStorageDomain();
+        initDestStorageDomain();
+        
doReturn(mockStorageDomainValidatorWithoutSpace()).when(command).createStorageDomainValidator();
+        CanDoActionTestUtils.runAndAssertCanDoActionFailure(command, 
VdcBllMessages.ACTION_TYPE_FAILED_DISK_SPACE_LOW_ON_TARGET_STORAGE_DOMAIN);
+    }
+
+    @Test
+    public void canDoActionEnoughSpace() throws Exception {
+        initializeCommand(ImageOperation.Move);
+        initVmForSpace();
+        initVmDiskImage();
+        initSrcStorageDomain();
+        initDestStorageDomain();
+        //when(diskImageDao.getSnapshotById(any(Guid.class))).thenReturn(null);
+        
doReturn(mockStorageDomainValidatorWithSpace()).when(command).createStorageDomainValidator();
+        CanDoActionTestUtils.runAndAssertCanDoActionSuccess(command);
+    }
+
+    protected void initVmForSpace() {
+        VM vm = new VM();
+        vm.setStatus(VMStatus.Down);
+        doReturn(vmDao).when(command).getVmDAO();
+        when(vmDao.get(any(Guid.class))).thenReturn(vm);
+        VmDevice device = new VmDevice();
+        List<Pair<VM, VmDevice>> vmList = Collections.singletonList(new 
Pair<>(vm, device));
+        when(vmDao.getVmsWithPlugInfo(any(Guid.class))).thenReturn(vmList);
+    }
+
+    protected void initVmForFail() {
         VM vm = new VM();
         vm.setStatus(VMStatus.Down);
         doReturn(vmDao).when(command).getVmDAO();
@@ -186,6 +223,26 @@
         when(vmDao.getVmsWithPlugInfo(any(Guid.class))).thenReturn(vmList);
     }
 
+    private static StorageDomainValidator 
mockStorageDomainValidatorWithoutSpace() {
+        StorageDomainValidator storageDomainValidator = 
mockStorageDomainValidator();
+        
when(storageDomainValidator.hasSpaceForClonedDisk(any(DiskImage.class))).thenReturn(
+                new 
ValidationResult(VdcBllMessages.ACTION_TYPE_FAILED_DISK_SPACE_LOW_ON_TARGET_STORAGE_DOMAIN));
+        return storageDomainValidator;
+    }
+
+    private static StorageDomainValidator 
mockStorageDomainValidatorWithSpace() {
+        StorageDomainValidator storageDomainValidator = 
mockStorageDomainValidator();
+        
when(storageDomainValidator.hasSpaceForClonedDisk(any(DiskImage.class))).thenReturn(ValidationResult.VALID);
+        return storageDomainValidator;
+    }
+
+    private static StorageDomainValidator mockStorageDomainValidator() {
+        StorageDomainValidator storageDomainValidator = 
mock(StorageDomainValidator.class);
+        
when(storageDomainValidator.isDomainExistAndActive()).thenReturn(ValidationResult.VALID);
+        
when(storageDomainValidator.isDomainWithinThresholds()).thenReturn(ValidationResult.VALID);
+        return storageDomainValidator;
+    }
+
     private void initSrcStorageDomain() {
         StorageDomain stDomain = new StorageDomain();
         stDomain.setStatus(StorageDomainStatus.Active);
@@ -207,12 +264,10 @@
                 destStorageId,
                 operation)));
 
-        // Spy away the storage domain checker methods
-        doReturn(true).when(command).isStorageDomainSpaceWithinThresholds();
-
-        // Spy away the image handler methods
+        // Spy away the image handler method
         doReturn(true).when(command).checkImageConfiguration();
-        doReturn(Collections.emptyList()).when(command).getAllImageSnapshots();
+
+        
doReturn(mockStorageDomainValidatorWithSpace()).when(command).createStorageDomainValidator();
 
         doReturn(false).when(command).acquireLock();
     }
@@ -229,6 +284,12 @@
         when(diskImageDao.get(any(Guid.class))).thenReturn(diskImage);
     }
 
+    private DiskValidator spyDiskValidator(Disk disk) {
+        DiskValidator diskValidator = spy(new DiskValidator(disk));
+        doReturn(diskValidator).when(command).createDiskValidator();
+        return diskValidator;
+    }
+
     /**
      * The following class is created in order to allow to use a mock 
diskImageDao in constructor
      */
diff --git 
a/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/validator/StorageDomainValidatorFreeSpaceTest.java
 
b/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/validator/StorageDomainValidatorFreeSpaceTest.java
index 9d8ab62..00a6833 100644
--- 
a/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/validator/StorageDomainValidatorFreeSpaceTest.java
+++ 
b/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/validator/StorageDomainValidatorFreeSpaceTest.java
@@ -22,13 +22,17 @@
 public class StorageDomainValidatorFreeSpaceTest {
     private DiskImage disk;
     private StorageDomain sd;
+
+    private boolean isValidForCloned;
     private boolean isValidForNew;
 
     public StorageDomainValidatorFreeSpaceTest(DiskImage disk,
-                                               StorageDomain sd,
-                                               boolean isValidForNew) {
+            StorageDomain sd,
+            boolean isValidForCloned,
+            boolean isValidForNew) {
         this.disk = disk;
         this.sd = sd;
+        this.isValidForCloned = isValidForCloned;
         this.isValidForNew = isValidForNew;
     }
 
@@ -55,6 +59,7 @@
                         sd.setAvailableDiskSize(107); // GB
 
                         params.add(new Object[] { disk, sd,
+                                volumeFormat == VolumeFormat.RAW && volumeType 
== VolumeType.Sparse,
                                 volumeFormat == VolumeFormat.COW || volumeType 
== VolumeType.Sparse });
                     }
                 }
@@ -64,6 +69,13 @@
         return params;
     }
 
+    public void testValidateClonedDisk() {
+        StorageDomainValidator sdValidator = new StorageDomainValidator(sd);
+        assertEquals(disk.getVolumeFormat() + ", " + disk.getVolumeType() + ", 
" + sd.getStorageType(),
+                isValidForCloned,
+                sdValidator.hasSpaceForClonedDisk(disk).isValid());
+    }
+
     @Test
     public void testValidateNewDisk() {
         StorageDomainValidator sdValidator = new StorageDomainValidator(sd);
diff --git 
a/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/validator/StorageDomainValidatorTest.java
 
b/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/validator/StorageDomainValidatorTest.java
index 70a94bd..e210aaf 100644
--- 
a/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/validator/StorageDomainValidatorTest.java
+++ 
b/backend/manager/modules/bll/src/test/java/org/ovirt/engine/core/bll/validator/StorageDomainValidatorTest.java
@@ -16,7 +16,7 @@
 
 /**
  * A test case for the {@link StorageDomainValidator} class.
- * The hasSpaceForNewDisk() method is covered separately in
+ * The hasSpaceForClonedDisk() and hasSpaceForNewDisk() methods are covered 
separately in
  * {@link StorageDomainValidatorFreeSpaceTest}.
  */
 public class StorageDomainValidatorTest {


-- 
To view, visit http://gerrit.ovirt.org/22447
To unsubscribe, visit http://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I951aeb531cb7ff7aaf3f1d50fc55100b6a806059
Gerrit-PatchSet: 1
Gerrit-Project: ovirt-engine
Gerrit-Branch: master
Gerrit-Owner: Vered Volansky <vvola...@redhat.com>
_______________________________________________
Engine-patches mailing list
Engine-patches@ovirt.org
http://lists.ovirt.org/mailman/listinfo/engine-patches

Reply via email to