1919import static org .junit .Assert .assertEquals ;
2020import static org .junit .Assert .fail ;
2121import static org .mockito .ArgumentMatchers .any ;
22+ import static org .mockito .ArgumentMatchers .anyBoolean ;
2223import static org .mockito .ArgumentMatchers .anyLong ;
2324import static org .mockito .ArgumentMatchers .anyString ;
2425import static org .mockito .ArgumentMatchers .eq ;
26+ import static org .mockito .ArgumentMatchers .nullable ;
2527import static org .mockito .Mockito .doNothing ;
28+ import static org .mockito .Mockito .doReturn ;
2629import static org .mockito .Mockito .doThrow ;
2730import static org .mockito .Mockito .lenient ;
2831import static org .mockito .Mockito .mock ;
3841import java .util .UUID ;
3942import java .util .concurrent .ExecutionException ;
4043
44+ import com .cloud .server .ManagementService ;
4145import org .apache .cloudstack .acl .ControlledEntity ;
4246import org .apache .cloudstack .acl .SecurityChecker .AccessType ;
4347import org .apache .cloudstack .api .command .user .volume .CheckAndRepairVolumeCmd ;
4448import org .apache .cloudstack .api .command .user .volume .CreateVolumeCmd ;
4549import org .apache .cloudstack .api .command .user .volume .DetachVolumeCmd ;
4650import org .apache .cloudstack .api .command .user .volume .MigrateVolumeCmd ;
51+ import org .apache .cloudstack .api .command .user .volume .ResizeVolumeCmd ;
4752import org .apache .cloudstack .backup .dao .BackupDao ;
4853import org .apache .cloudstack .context .CallContext ;
54+ import org .apache .cloudstack .engine .orchestration .service .VolumeOrchestrationService ;
4955import org .apache .cloudstack .engine .subsystem .api .storage .DataStore ;
5056import org .apache .cloudstack .engine .subsystem .api .storage .DataStoreManager ;
5157import org .apache .cloudstack .engine .subsystem .api .storage .PrimaryDataStore ;
8591import org .springframework .test .util .ReflectionTestUtils ;
8692
8793import com .cloud .api .query .dao .ServiceOfferingJoinDao ;
94+ import com .cloud .configuration .ConfigurationManager ;
8895import com .cloud .configuration .Resource ;
8996import com .cloud .configuration .Resource .ResourceType ;
9097import com .cloud .dc .DataCenterVO ;
@@ -210,6 +217,8 @@ public class VolumeApiServiceImplTest {
210217 private StoragePool storagePoolMock ;
211218 private long storagePoolMockId = 1 ;
212219 @ Mock
220+ private DiskOfferingVO diskOfferingMock ;
221+ @ Mock
213222 private DiskOfferingVO newDiskOfferingMock ;
214223
215224 @ Mock
@@ -238,10 +247,20 @@ public class VolumeApiServiceImplTest {
238247 @ Mock
239248 private StorageManager storageMgr ;
240249
250+ @ Mock
251+ private ConfigurationManager _configMgr ;
252+
253+ @ Mock
254+ private VolumeOrchestrationService _volumeMgr ;
255+
256+ @ Mock
257+ private ManagementService managementService ;
258+
241259 private long accountMockId = 456l ;
242260 private long volumeMockId = 12313l ;
243261 private long vmInstanceMockId = 1123l ;
244262 private long volumeSizeMock = 456789921939l ;
263+ private long newVolumeSizeMock = 456789930000l ;
245264 private static long imageStoreId = 10L ;
246265
247266 private String projectMockUuid = "projectUuid" ;
@@ -250,6 +269,7 @@ public class VolumeApiServiceImplTest {
250269 private long projectMockAccountId = 132329390L ;
251270
252271 private long diskOfferingMockId = 100203L ;
272+ private long newDiskOfferingMockId = 100204L ;
253273
254274 private long offeringMockId = 31902L ;
255275
@@ -1820,4 +1840,75 @@ public void testValidationsForCheckVolumeAPIWithInvalidVolumeFormat() {
18201840
18211841 volumeApiServiceImpl .validationsForCheckVolumeOperation (volume );
18221842 }
1843+
1844+ private void testResizeVolumeSetup () throws ExecutionException , InterruptedException {
1845+ Long poolId = 11L ;
1846+
1847+ when (volumeDaoMock .findById (volumeMockId )).thenReturn (volumeVoMock );
1848+ when (volumeVoMock .getId ()).thenReturn (volumeMockId );
1849+ when (volumeDaoMock .getHypervisorType (volumeMockId )).thenReturn (HypervisorType .KVM );
1850+ when (volumeVoMock .getState ()).thenReturn (Volume .State .Ready );
1851+ when (volumeVoMock .getDiskOfferingId ()).thenReturn (diskOfferingMockId );
1852+ when (_diskOfferingDao .findById (diskOfferingMockId )).thenReturn (diskOfferingMock );
1853+ when (_diskOfferingDao .findById (newDiskOfferingMockId )).thenReturn (newDiskOfferingMock );
1854+ when (newDiskOfferingMock .getRemoved ()).thenReturn (null );
1855+ when (diskOfferingMock .getDiskSizeStrictness ()).thenReturn (false );
1856+ when (newDiskOfferingMock .getDiskSizeStrictness ()).thenReturn (false );
1857+ when (volumeVoMock .getInstanceId ()).thenReturn (null );
1858+ when (volumeVoMock .getVolumeType ()).thenReturn (Type .DATADISK );
1859+ when (newDiskOfferingMock .getDiskSize ()).thenReturn (newVolumeSizeMock );
1860+
1861+ VolumeInfo volInfo = Mockito .mock (VolumeInfo .class );
1862+ when (volumeDataFactoryMock .getVolume (volumeMockId )).thenReturn (volInfo );
1863+ DataStore dataStore = Mockito .mock (DataStore .class );
1864+ when ((volInfo .getDataStore ())).thenReturn (dataStore );
1865+
1866+ when (volumeVoMock .getPoolId ()).thenReturn (poolId );
1867+ StoragePoolVO storagePool = Mockito .mock (StoragePoolVO .class );
1868+ when (primaryDataStoreDaoMock .findById (poolId )).thenReturn (storagePool );
1869+
1870+ Mockito .lenient ().doReturn (asyncCallFutureVolumeapiResultMock ).when (volumeServiceMock ).resize (any (VolumeInfo .class ));
1871+ Mockito .doReturn (Mockito .mock (VolumeApiResult .class )).when (asyncCallFutureVolumeapiResultMock ).get ();
1872+ }
1873+
1874+ @ Test
1875+ public void testResizeVolumeWithEnoughCapacity () throws ResourceAllocationException , ExecutionException , InterruptedException {
1876+ ResizeVolumeCmd cmd = new ResizeVolumeCmd ();
1877+ ReflectionTestUtils .setField (cmd , "id" , volumeMockId );
1878+ ReflectionTestUtils .setField (cmd , "newDiskOfferingId" , newDiskOfferingMockId );
1879+
1880+ testResizeVolumeSetup ();
1881+
1882+ when (storageMgr .storagePoolHasEnoughSpaceForResize (any (), nullable (Long .class ), nullable (Long .class ))).thenReturn (true );
1883+
1884+ try (MockedStatic <UsageEventUtils > ignored = Mockito .mockStatic (UsageEventUtils .class )) {
1885+ volumeApiServiceImpl .resizeVolume (cmd );
1886+
1887+ verify (volumeServiceMock ).resize (any (VolumeInfo .class ));
1888+ }
1889+ }
1890+
1891+ @ Test
1892+ public void testResizeVolumeWithoutEnoughCapacity () throws ResourceAllocationException , ExecutionException , InterruptedException {
1893+ ResizeVolumeCmd cmd = new ResizeVolumeCmd ();
1894+ ReflectionTestUtils .setField (cmd , "id" , volumeMockId );
1895+ ReflectionTestUtils .setField (cmd , "newDiskOfferingId" , newDiskOfferingMockId );
1896+ ReflectionTestUtils .setField (cmd , "autoMigrate" , true );
1897+
1898+ testResizeVolumeSetup ();
1899+
1900+ when (storageMgr .storagePoolHasEnoughSpaceForResize (any (), nullable (Long .class ), nullable (Long .class ))).thenReturn (false ).thenReturn (true );
1901+ StoragePoolVO suitableStoragePool = Mockito .mock (StoragePoolVO .class );
1902+ Pair <List <? extends StoragePool >, List <? extends StoragePool >> poolsPair = new Pair <>(Arrays .asList (suitableStoragePool ), Arrays .asList (suitableStoragePool ));
1903+ when (managementService .listStoragePoolsForSystemMigrationOfVolume (anyLong (), anyLong (), anyLong (), anyLong (), anyLong (), anyBoolean (), anyBoolean ())).thenReturn (poolsPair );
1904+ doReturn (volumeInfoMock ).when (volumeApiServiceImpl ).migrateVolume (any ());
1905+ when (volumeInfoMock .getId ()).thenReturn (volumeMockId );
1906+
1907+ try (MockedStatic <UsageEventUtils > ignored = Mockito .mockStatic (UsageEventUtils .class )) {
1908+ volumeApiServiceImpl .resizeVolume (cmd );
1909+
1910+ verify (volumeApiServiceImpl ).migrateVolume (any ());
1911+ verify (volumeServiceMock ).resize (any (VolumeInfo .class ));
1912+ }
1913+ }
18231914}
0 commit comments