2222import java .util .HashMap ;
2323import java .util .List ;
2424import java .util .Map ;
25+ import java .util .Optional ;
2526
2627import org .apache .cloudstack .api .ApiConstants ;
2728import org .apache .cloudstack .api .command .admin .storage .ChangeStoragePoolScopeCmd ;
29+ import org .apache .cloudstack .engine .subsystem .api .storage .DataStore ;
30+ import org .apache .cloudstack .engine .subsystem .api .storage .DataStoreLifeCycle ;
31+ import org .apache .cloudstack .engine .subsystem .api .storage .DataStoreManager ;
32+ import org .apache .cloudstack .engine .subsystem .api .storage .DataStoreProvider ;
33+ import org .apache .cloudstack .engine .subsystem .api .storage .DataStoreProviderManager ;
2834import org .apache .cloudstack .engine .subsystem .api .storage .PrimaryDataStoreDriver ;
2935import org .apache .cloudstack .framework .config .ConfigDepot ;
3036import org .apache .cloudstack .framework .config .ConfigKey ;
3137import org .apache .cloudstack .framework .config .dao .ConfigurationDao ;
3238import org .apache .cloudstack .resourcedetail .dao .DiskOfferingDetailsDao ;
3339import org .apache .cloudstack .storage .command .CheckDataStoreStoragePolicyComplainceCommand ;
40+ import org .apache .cloudstack .storage .datastore .db .ObjectStoreDao ;
41+ import org .apache .cloudstack .storage .datastore .db .ObjectStoreVO ;
3442import org .apache .cloudstack .storage .datastore .db .PrimaryDataStoreDao ;
3543import org .apache .cloudstack .storage .datastore .db .StoragePoolDetailVO ;
3644import org .apache .cloudstack .storage .datastore .db .StoragePoolDetailsDao ;
3745import org .apache .cloudstack .storage .datastore .db .StoragePoolVO ;
46+ import org .apache .cloudstack .storage .object .ObjectStore ;
3847import org .apache .commons .collections .MapUtils ;
3948import org .junit .Assert ;
4049import org .junit .Test ;
5059import com .cloud .agent .AgentManager ;
5160import com .cloud .agent .api .Command ;
5261import com .cloud .agent .api .StoragePoolInfo ;
62+ import com .cloud .capacity .Capacity ;
5363import com .cloud .capacity .CapacityManager ;
64+ import com .cloud .capacity .CapacityVO ;
5465import com .cloud .dc .ClusterVO ;
5566import com .cloud .dc .DataCenter ;
5667import com .cloud .dc .DataCenterVO ;
@@ -125,6 +136,15 @@ public class StorageManagerImplTest {
125136 @ Mock
126137 private VMInstanceVO vmInstanceVOMock ;
127138
139+ @ Mock
140+ protected ObjectStoreDao objectStoreDao ;
141+
142+ @ Mock
143+ DataStoreProviderManager dataStoreProviderMgr ;
144+
145+ @ Mock
146+ DataStoreManager dataStoreMgr ;
147+
128148 @ Test
129149 public void createLocalStoragePoolName () {
130150 String hostMockName = "host1" ;
@@ -239,7 +259,7 @@ public void testExtractUriParamsAsMapWithSolidFireUrl() {
239259 String sfUrl = "MVIP=1.2.3.4;SVIP=6.7.8.9;clusterAdminUsername=admin;" +
240260 "clusterAdminPassword=password;clusterDefaultMinIops=1000;" +
241261 "clusterDefaultMaxIops=2000;clusterDefaultBurstIopsPercentOfMaxIops=2" ;
242- Map <String ,String > uriParams = storageManagerImpl .extractUriParamsAsMap (sfUrl );
262+ Map <String , String > uriParams = storageManagerImpl .extractUriParamsAsMap (sfUrl );
243263 Assert .assertTrue (MapUtils .isEmpty (uriParams ));
244264 }
245265
@@ -249,7 +269,7 @@ public void testExtractUriParamsAsMapWithNFSUrl() {
249269 String host = "HOST" ;
250270 String path = "/PATH" ;
251271 String sfUrl = String .format ("%s://%s%s" , scheme , host , path );
252- Map <String ,String > uriParams = storageManagerImpl .extractUriParamsAsMap (sfUrl );
272+ Map <String , String > uriParams = storageManagerImpl .extractUriParamsAsMap (sfUrl );
253273 Assert .assertTrue (MapUtils .isNotEmpty (uriParams ));
254274 Assert .assertEquals (scheme , uriParams .get ("scheme" ));
255275 Assert .assertEquals (host , uriParams .get ("host" ));
@@ -408,7 +428,7 @@ public void testIsStoragePoolCompliantWithStoragePolicy() {
408428 }
409429 try {
410430 Mockito .doReturn (new com .cloud .agent .api .Answer (
411- Mockito .mock (CheckDataStoreStoragePolicyComplainceCommand .class )))
431+ Mockito .mock (CheckDataStoreStoragePolicyComplainceCommand .class )))
412432 .when (storageManagerImpl ).getCheckDatastorePolicyComplianceAnswer ("policy" , pool );
413433 Assert .assertTrue (storageManagerImpl .isStoragePoolCompliantWithStoragePolicy (1L , pool ));
414434 } catch (StorageUnavailableException e ) {
@@ -455,8 +475,7 @@ public void testGetCheckDatastorePolicyComplianceAnswerAgentException() throws S
455475 Mockito .when (policy .getPolicyId ()).thenReturn ("some" );
456476 Mockito .when (vsphereStoragePolicyDao .findById (Mockito .anyLong ()))
457477 .thenReturn (policy );
458- Mockito .doReturn (new ArrayList <>(List .of (1L , 2L )))
459- .when (storageManagerImpl ).getUpHostsInPool (Mockito .anyLong ());
478+ Mockito .doReturn (new ArrayList <>(List .of (1L , 2L ))).when (storageManagerImpl ).getUpHostsInPool (Mockito .anyLong ());
460479 Mockito .when (hvGuruMgr .getGuruProcessedCommandTargetHost (Mockito .anyLong (),
461480 Mockito .any (CheckDataStoreStoragePolicyComplainceCommand .class ))).thenReturn (1L );
462481 try {
@@ -527,7 +546,7 @@ public void testEnableDefaultDatastoreDownloadRedirectionForExistingInstallation
527546 .thenReturn (new ArrayList <>()); //new installation
528547 storageManagerImpl .enableDefaultDatastoreDownloadRedirectionForExistingInstallations ();
529548 Mockito .verify (configurationDao , Mockito .never ())
530- .update (StorageManager .DataStoreDownloadFollowRedirects .key (),StorageManager .DataStoreDownloadFollowRedirects .defaultValue ());
549+ .update (StorageManager .DataStoreDownloadFollowRedirects .key (), StorageManager .DataStoreDownloadFollowRedirects .defaultValue ());
531550 }
532551
533552 @ Test
@@ -771,7 +790,7 @@ private Long testCheckPoolforSpaceForResizeSetup(StoragePoolVO pool, Long alloca
771790 Long zoneId = 2L ;
772791
773792 Long capacityBytes = (long ) (allocatedSizeWithTemplate / Double .valueOf (CapacityManager .StorageAllocatedCapacityDisableThreshold .defaultValue ())
774- / Double .valueOf (CapacityManager .StorageOverprovisioningFactor .defaultValue ()));
793+ / Double .valueOf (CapacityManager .StorageOverprovisioningFactor .defaultValue ()));
775794 Long maxAllocatedSizeForResize = (long ) (capacityBytes * Double .valueOf (CapacityManager .StorageOverprovisioningFactor .defaultValue ())
776795 * Double .valueOf (CapacityManager .StorageAllocatedCapacityDisableThresholdForVolumeSize .defaultValue ()));
777796
@@ -894,4 +913,162 @@ public void testGetStoragePoolIopsStats_UsedIopsNegative() {
894913 Assert .assertEquals ("Capacity IOPS should match pool's capacity IOPS" , 1000L , result .first ().longValue ());
895914 Assert .assertNull ("Used IOPS should be null when usedIops <= 0" , result .second ());
896915 }
916+
917+ @ Test
918+ public void testGetObjectStorageUsedStats () {
919+ Long zoneId = 1L ;
920+ List <ObjectStoreVO > objectStores = new ArrayList <>();
921+
922+ ObjectStoreVO store1 = new ObjectStoreVO ();
923+ store1 .setAllocatedSize (1000L );
924+ store1 .setTotalSize (2000L );
925+ objectStores .add (store1 );
926+
927+ ObjectStoreVO store2 = new ObjectStoreVO ();
928+ store2 .setAllocatedSize (2000L );
929+ store2 .setTotalSize (4000L );
930+ objectStores .add (store2 );
931+
932+ ObjectStoreVO store3 = new ObjectStoreVO ();
933+ store3 .setAllocatedSize (null );
934+ store3 .setTotalSize (null );
935+ objectStores .add (store3 );
936+
937+ Mockito .when (objectStoreDao .listObjectStores ()).thenReturn (objectStores );
938+
939+ CapacityVO result = storageManagerImpl .getObjectStorageUsedStats (zoneId );
940+
941+ Assert .assertEquals (zoneId , result .getDataCenterId ());
942+ Assert .assertEquals (Optional .of (3000L ), Optional .of (result .getUsedCapacity ())); // 1000 + 2000
943+ Assert .assertEquals (6000L , result .getTotalCapacity ()); // 2000 + 4000
944+ Assert .assertEquals (Capacity .CAPACITY_TYPE_OBJECT_STORAGE , result .getCapacityType ());
945+ Assert .assertNull (result .getPodId ());
946+ Assert .assertNull (result .getClusterId ());
947+ }
948+
949+ @ Test
950+ public void testGetObjectStorageUsedStatsWithNullSizes () {
951+ Long zoneId = 1L ;
952+ List <ObjectStoreVO > objectStores = new ArrayList <>();
953+
954+ ObjectStoreVO store1 = new ObjectStoreVO ();
955+ store1 .setAllocatedSize (null );
956+ store1 .setTotalSize (null );
957+ objectStores .add (store1 );
958+
959+ ObjectStoreVO store2 = new ObjectStoreVO ();
960+ store2 .setAllocatedSize (null );
961+ store2 .setTotalSize (null );
962+ objectStores .add (store2 );
963+
964+ Mockito .when (objectStoreDao .listObjectStores ()).thenReturn (objectStores );
965+
966+ CapacityVO result = storageManagerImpl .getObjectStorageUsedStats (zoneId );
967+
968+ Assert .assertEquals (zoneId , result .getDataCenterId ());
969+ Assert .assertEquals (Optional .of (0L ), Optional .of (result .getUsedCapacity ()));
970+ Assert .assertEquals (0L , result .getTotalCapacity ());
971+ Assert .assertEquals (Capacity .CAPACITY_TYPE_OBJECT_STORAGE , result .getCapacityType ());
972+ Assert .assertNull (result .getPodId ());
973+ Assert .assertNull (result .getClusterId ());
974+ }
975+
976+ @ Test
977+ public void testDiscoverObjectStore () {
978+ Long objectStoreId = 1L ;
979+
980+ String name = "test-store" ;
981+ String url = "http://10.1.1.33:80" ;
982+ Long size = 1000L ;
983+ String providerName = "test-provider" ;
984+ Map <String , String > details = new HashMap <>();
985+ details .put ("key1" , "value1" );
986+
987+ ObjectStoreVO objectStoreVO = new ObjectStoreVO ();
988+ ReflectionTestUtils .setField (objectStoreVO , "id" , objectStoreId );
989+ objectStoreVO .setName (name );
990+ objectStoreVO .setUrl (url );
991+ objectStoreVO .setProviderName (providerName );
992+ objectStoreVO .setTotalSize (size );
993+
994+ DataStoreProvider storeProvider = Mockito .mock (DataStoreProvider .class );
995+ DataStoreLifeCycle lifeCycle = Mockito .mock (DataStoreLifeCycle .class );
996+ DataStore store = Mockito .mock (DataStore .class );
997+ ObjectStore objectStore = Mockito .mock (ObjectStore .class );
998+
999+ Mockito .when (dataStoreProviderMgr .getDataStoreProvider (providerName )).thenReturn (storeProvider );
1000+ Mockito .when (storeProvider .getDataStoreLifeCycle ()).thenReturn (lifeCycle );
1001+ Mockito .when (lifeCycle .initialize (Mockito .any ())).thenReturn (store );
1002+ Mockito .when (store .getId ()).thenReturn (1L );
1003+ Mockito .when (dataStoreMgr .getDataStore (1L , DataStoreRole .Object )).thenReturn (null );
1004+
1005+ ObjectStore result = storageManagerImpl .discoverObjectStore (name , url , size , providerName , details );
1006+
1007+ Mockito .verify (dataStoreProviderMgr ).getDataStoreProvider (providerName );
1008+ Mockito .verify (lifeCycle ).initialize (Mockito .any ());
1009+ Mockito .verify (dataStoreMgr ).getDataStore (1L , DataStoreRole .Object );
1010+ }
1011+
1012+ @ Test (expected = InvalidParameterValueException .class )
1013+ public void testDiscoverObjectStoreInvalidProvider () {
1014+ // Setup
1015+ String name = "test-store" ;
1016+ String url = "http://10.1.1.33:80" ;
1017+ Long size = 1000L ;
1018+ String providerName = "invalid-provider" ;
1019+ Map <String , String > details = new HashMap <>();
1020+
1021+ Mockito .when (dataStoreProviderMgr .getDataStoreProvider (providerName )).thenReturn (null );
1022+
1023+ storageManagerImpl .discoverObjectStore (name , url , size , providerName , details );
1024+ }
1025+
1026+ @ Test (expected = IllegalArgumentException .class )
1027+ public void testDiscoverObjectStoreInvalidUrl () {
1028+ String name = "test-store" ;
1029+ String url = "invalid-url" ;
1030+ Long size = 1000L ;
1031+ String providerName = "test-provider" ;
1032+ Map <String , String > details = new HashMap <>();
1033+
1034+ DataStoreProvider storeProvider = Mockito .mock (DataStoreProvider .class );
1035+ Mockito .when (dataStoreProviderMgr .getDataStoreProvider (providerName )).thenReturn (storeProvider );
1036+
1037+ storageManagerImpl .discoverObjectStore (name , url , size , providerName , details );
1038+ }
1039+
1040+ @ Test (expected = InvalidParameterValueException .class )
1041+ public void testDiscoverObjectStoreDuplicateUrl () {
1042+ String name = "test-store" ;
1043+ String url = "http://10.1.1.33:80" ;
1044+ Long size = 1000L ;
1045+ String providerName = "test-provider" ;
1046+ Map <String , String > details = new HashMap <>();
1047+
1048+ DataStoreProvider storeProvider = Mockito .mock (DataStoreProvider .class );
1049+ ObjectStoreVO existingStore = new ObjectStoreVO ();
1050+
1051+ Mockito .when (dataStoreProviderMgr .getDataStoreProvider (providerName )).thenReturn (storeProvider );
1052+ Mockito .when (objectStoreDao .findByUrl (url )).thenReturn (existingStore );
1053+
1054+ storageManagerImpl .discoverObjectStore (name , url , size , providerName , details );
1055+ }
1056+
1057+ @ Test (expected = CloudRuntimeException .class )
1058+ public void testDiscoverObjectStoreInitializationFailure () {
1059+ String name = "test-store" ;
1060+ String url = "http://10.1.1.33:80" ;
1061+ Long size = 1000L ;
1062+ String providerName = "test-provider" ;
1063+ Map <String , String > details = new HashMap <>();
1064+
1065+ DataStoreProvider storeProvider = Mockito .mock (DataStoreProvider .class );
1066+ DataStoreLifeCycle lifeCycle = Mockito .mock (DataStoreLifeCycle .class );
1067+
1068+ Mockito .when (dataStoreProviderMgr .getDataStoreProvider (providerName )).thenReturn (storeProvider );
1069+ Mockito .when (storeProvider .getDataStoreLifeCycle ()).thenReturn (lifeCycle );
1070+ Mockito .when (lifeCycle .initialize (Mockito .any ())).thenThrow (new RuntimeException ("Initialization failed" ));
1071+
1072+ storageManagerImpl .discoverObjectStore (name , url , size , providerName , details );
1073+ }
8971074}
0 commit comments