Skip to content

Commit c14c5cc

Browse files
Srivastava, PiyushSrivastava, Piyush
authored andcommitted
feature/CSTACKEX-122: UTs updated
1 parent 6f266fe commit c14c5cc

File tree

4 files changed

+220
-219
lines changed

4 files changed

+220
-219
lines changed

plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/driver/OntapPrimaryDatastoreDriver.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,12 @@ public DataStoreTO getStoreTO(DataStore store) {
114114
return null;
115115
}
116116

117+
@Override
118+
public boolean volumesRequireGrantAccessWhenUsed(){
119+
s_logger.info("OntapPrimaryDatastoreDriver: volumesRequireGrantAccessWhenUsed: Called");
120+
return true;
121+
}
122+
117123
/**
118124
* Creates a volume on the ONTAP storage system.
119125
*/

plugins/storage/volume/ontap/src/test/java/org/apache/cloudstack/storage/driver/OntapPrimaryDatastoreDriverTest.java

Lines changed: 48 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
import com.cloud.exception.InvalidParameterValueException;
2222
import com.cloud.host.Host;
23+
import com.cloud.host.HostVO;
2324
import com.cloud.storage.ScopeType;
2425
import com.cloud.storage.Storage;
2526
import com.cloud.storage.VolumeVO;
@@ -38,6 +39,7 @@
3839
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
3940
import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailsDao;
4041
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
42+
import org.apache.cloudstack.storage.feign.model.Igroup;
4143
import org.apache.cloudstack.storage.feign.model.Lun;
4244
import org.apache.cloudstack.storage.service.UnifiedSANStrategy;
4345
import org.apache.cloudstack.storage.service.model.AccessGroup;
@@ -172,7 +174,6 @@ void testCreateAsync_VolumeWithISCSI_Success() {
172174
when(storagePoolDao.findById(1L)).thenReturn(storagePool);
173175
when(storagePool.getId()).thenReturn(1L);
174176
when(storagePool.getPoolType()).thenReturn(Storage.StoragePoolType.NetworkFilesystem);
175-
when(storagePool.getPath()).thenReturn("iqn.1992-08.com.netapp:sn.123456");
176177

177178
when(storagePoolDetailsDao.listDetailsKeyPairs(1L)).thenReturn(storagePoolDetails);
178179
when(volumeDao.findById(100L)).thenReturn(volumeVO);
@@ -181,19 +182,19 @@ void testCreateAsync_VolumeWithISCSI_Success() {
181182
Lun mockLun = new Lun();
182183
mockLun.setName("/vol/vol1/lun1");
183184
mockLun.setUuid("lun-uuid-123");
184-
CloudStackVolume mockCloudStackVolume = new CloudStackVolume();
185-
mockCloudStackVolume.setLun(mockLun);
185+
// Create request volume (returned by Utility.createCloudStackVolumeRequestByProtocol)
186+
CloudStackVolume requestVolume = new CloudStackVolume();
187+
requestVolume.setLun(mockLun);
188+
// Create response volume (returned by sanStrategy.createCloudStackVolume)
189+
CloudStackVolume responseVolume = new CloudStackVolume();
190+
responseVolume.setLun(mockLun);
186191

187192
try (MockedStatic<Utility> utilityMock = mockStatic(Utility.class)) {
188-
utilityMock.when(() -> Utility.getStrategyByStoragePoolDetails(storagePoolDetails))
193+
utilityMock.when(() -> Utility.getStrategyByStoragePoolDetails(any()))
189194
.thenReturn(sanStrategy);
190195
utilityMock.when(() -> Utility.createCloudStackVolumeRequestByProtocol(
191-
any(), any(), any())).thenReturn(mockCloudStackVolume);
192-
utilityMock.when(() -> Utility.getIgroupName(anyString(), anyString()))
193-
.thenReturn("igroup1");
194-
195-
when(sanStrategy.createCloudStackVolume(any())).thenReturn(mockCloudStackVolume);
196-
when(sanStrategy.ensureLunMapped(anyString(), anyString(), anyString())).thenReturn("0");
196+
any(), any(), any())).thenReturn(requestVolume);
197+
when(sanStrategy.createCloudStackVolume(any())).thenReturn(responseVolume);
197198

198199
// Execute
199200
driver.createAsync(dataStore, volumeInfo, createCallback);
@@ -356,19 +357,24 @@ void testGrantAccess_ClusterScope_Success() {
356357
when(volumeDao.findById(100L)).thenReturn(volumeVO);
357358
when(volumeVO.getId()).thenReturn(100L);
358359

359-
when(host.getStorageUrl()).thenReturn("iqn.1993-08.org.debian:01:host1");
360+
when(host.getName()).thenReturn("host1");
360361

361362
VolumeDetailVO lunNameDetail = new VolumeDetailVO(100L, Constants.LUN_DOT_NAME, "/vol/vol1/lun1", false);
362363
when(volumeDetailsDao.findDetail(100L, Constants.LUN_DOT_NAME)).thenReturn(lunNameDetail);
363364

365+
// Mock AccessGroup with existing igroup
366+
AccessGroup existingAccessGroup = new AccessGroup();
367+
Igroup existingIgroup = new Igroup();
368+
existingIgroup.setName("igroup1");
369+
existingAccessGroup.setIgroup(existingIgroup);
370+
364371
try (MockedStatic<Utility> utilityMock = mockStatic(Utility.class)) {
365372
utilityMock.when(() -> Utility.getStrategyByStoragePoolDetails(storagePoolDetails))
366373
.thenReturn(sanStrategy);
367374
utilityMock.when(() -> Utility.getIgroupName(anyString(), anyString()))
368375
.thenReturn("igroup1");
369376

370-
when(sanStrategy.validateInitiatorInAccessGroup(anyString(), anyString(), anyString()))
371-
.thenReturn(true);
377+
when(sanStrategy.getAccessGroup(any())).thenReturn(existingAccessGroup);
372378
when(sanStrategy.ensureLunMapped(anyString(), anyString(), anyString())).thenReturn("0");
373379

374380
// Execute
@@ -377,14 +383,18 @@ void testGrantAccess_ClusterScope_Success() {
377383
// Verify
378384
assertTrue(result);
379385
verify(volumeDao).update(eq(100L), any(VolumeVO.class));
380-
verify(sanStrategy).validateInitiatorInAccessGroup(anyString(), anyString(), anyString());
386+
verify(sanStrategy).getAccessGroup(any());
381387
verify(sanStrategy).ensureLunMapped(anyString(), anyString(), anyString());
388+
verify(sanStrategy, never()).validateInitiatorInAccessGroup(anyString(), anyString(), any(Igroup.class));
382389
}
383390
}
384391

385392
@Test
386-
void testGrantAccess_InitiatorNotInIgroup_ThrowsException() {
387-
// Setup
393+
void testGrantAccess_IgroupNotFound_CreatesNewIgroup() {
394+
// Setup - use HostVO mock since production code casts Host to HostVO
395+
HostVO hostVO = mock(HostVO.class);
396+
when(hostVO.getName()).thenReturn("host1");
397+
388398
when(dataStore.getId()).thenReturn(1L);
389399
when(dataStore.getUuid()).thenReturn("pool-uuid-123");
390400
when(volumeInfo.getType()).thenReturn(VOLUME);
@@ -393,29 +403,41 @@ void testGrantAccess_InitiatorNotInIgroup_ThrowsException() {
393403
when(storagePoolDao.findById(1L)).thenReturn(storagePool);
394404
when(storagePool.getId()).thenReturn(1L);
395405
when(storagePool.getScope()).thenReturn(ScopeType.CLUSTER);
406+
when(storagePool.getPath()).thenReturn("iqn.1992-08.com.netapp:sn.123456");
407+
when(storagePool.getPoolType()).thenReturn(Storage.StoragePoolType.NetworkFilesystem);
408+
396409
when(storagePoolDetailsDao.listDetailsKeyPairs(1L)).thenReturn(storagePoolDetails);
397410
when(volumeDao.findById(100L)).thenReturn(volumeVO);
398411
when(volumeVO.getId()).thenReturn(100L);
399412

400-
when(host.getStorageUrl()).thenReturn("iqn.1993-08.org.debian:01:host1");
401-
402413
VolumeDetailVO lunNameDetail = new VolumeDetailVO(100L, Constants.LUN_DOT_NAME, "/vol/vol1/lun1", false);
403414
when(volumeDetailsDao.findDetail(100L, Constants.LUN_DOT_NAME)).thenReturn(lunNameDetail);
404415

416+
// Mock getAccessGroup returning null (igroup doesn't exist)
417+
AccessGroup createdAccessGroup = new AccessGroup();
418+
Igroup createdIgroup = new Igroup();
419+
createdIgroup.setName("igroup1");
420+
createdAccessGroup.setIgroup(createdIgroup);
421+
405422
try (MockedStatic<Utility> utilityMock = mockStatic(Utility.class)) {
406423
utilityMock.when(() -> Utility.getStrategyByStoragePoolDetails(storagePoolDetails))
407424
.thenReturn(sanStrategy);
408425
utilityMock.when(() -> Utility.getIgroupName(anyString(), anyString()))
409426
.thenReturn("igroup1");
410427

411-
when(sanStrategy.validateInitiatorInAccessGroup(anyString(), anyString(), anyString()))
412-
.thenReturn(false);
428+
when(sanStrategy.getAccessGroup(any())).thenReturn(null);
429+
when(sanStrategy.createAccessGroup(any())).thenReturn(createdAccessGroup);
430+
when(sanStrategy.ensureLunMapped(anyString(), anyString(), anyString())).thenReturn("0");
413431

414-
// Execute & Verify
415-
CloudRuntimeException exception = assertThrows(CloudRuntimeException.class,
416-
() -> driver.grantAccess(volumeInfo, host, dataStore));
432+
// Execute
433+
boolean result = driver.grantAccess(volumeInfo, hostVO, dataStore);
417434

418-
assertTrue(exception.getMessage().contains("is not present in iGroup"));
435+
// Verify
436+
assertTrue(result);
437+
verify(sanStrategy).getAccessGroup(any());
438+
verify(sanStrategy).createAccessGroup(any());
439+
verify(sanStrategy).ensureLunMapped(anyString(), anyString(), anyString());
440+
verify(volumeDao).update(eq(100L), any(VolumeVO.class));
419441
}
420442
}
421443

@@ -499,7 +521,7 @@ void testRevokeAccess_ISCSIVolume_Success() {
499521
when(sanStrategy.validateInitiatorInAccessGroup(
500522
eq("iqn.1993-08.org.debian:01:host1"),
501523
eq("svm1"),
502-
eq("igroup1")
524+
any(Igroup.class)
503525
)).thenReturn(true);
504526

505527
doNothing().when(sanStrategy).disableLogicalAccess(argThat(map ->
@@ -514,7 +536,7 @@ void testRevokeAccess_ISCSIVolume_Success() {
514536
// Verify
515537
verify(sanStrategy).getCloudStackVolume(any());
516538
verify(sanStrategy).getAccessGroup(any());
517-
verify(sanStrategy).validateInitiatorInAccessGroup(anyString(), anyString(), anyString());
539+
verify(sanStrategy).validateInitiatorInAccessGroup(anyString(), anyString(), any(Igroup.class));
518540
verify(sanStrategy).disableLogicalAccess(any());
519541
}
520542
}

plugins/storage/volume/ontap/src/test/java/org/apache/cloudstack/storage/service/UnifiedNASStrategyTest.java

Lines changed: 19 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
import com.cloud.utils.exception.CloudRuntimeException;
2727
import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
2828
import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector;
29-
import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo;
3029
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
3130
import org.apache.cloudstack.storage.command.CreateObjectCommand;
3231
import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailsDao;
@@ -261,7 +260,6 @@ public void testCreateCloudStackVolume_NoEndpoint() {
261260
public void testCreateAccessGroup_Success() throws Exception {
262261
// Setup
263262
AccessGroup accessGroup = mock(AccessGroup.class);
264-
PrimaryDataStoreInfo primaryDataStoreInfo = mock(PrimaryDataStoreInfo.class);
265263
Map<String, String> details = new HashMap<>();
266264
details.put(Constants.SVM_NAME, "svm1");
267265
details.put(Constants.VOLUME_UUID, "vol-uuid-123");
@@ -287,9 +285,9 @@ public void testCreateAccessGroup_Success() throws Exception {
287285
job.setState(Constants.JOB_SUCCESS);
288286
jobResponse.setJob(job);
289287

290-
when(accessGroup.getPrimaryDataStoreInfo()).thenReturn(primaryDataStoreInfo);
291-
when(primaryDataStoreInfo.getDetails()).thenReturn(details);
292-
when(primaryDataStoreInfo.getId()).thenReturn(1L);
288+
// Removed primaryDataStoreInfo mock - using storage pool ID directly
289+
when(storagePoolDetailsDao.listDetailsKeyPairs(1L)).thenReturn(details);
290+
when(accessGroup.getStoragePoolId()).thenReturn(1L);
293291
when(accessGroup.getHostsToConnect()).thenReturn(hosts);
294292
doNothing().when(nasFeignClient).createExportPolicy(anyString(), any(ExportPolicy.class));
295293
when(nasFeignClient.getExportPolicyResponse(anyString(), anyMap())).thenReturn(policyResponse);
@@ -312,7 +310,6 @@ public void testCreateAccessGroup_Success() throws Exception {
312310
@Test
313311
public void testCreateAccessGroup_FailedToCreatePolicy() {
314312
AccessGroup accessGroup = mock(AccessGroup.class);
315-
PrimaryDataStoreInfo primaryDataStoreInfo = mock(PrimaryDataStoreInfo.class);
316313
Map<String, String> details = new HashMap<>();
317314
details.put(Constants.SVM_NAME, "svm1");
318315
details.put(Constants.VOLUME_UUID, "vol-uuid-123");
@@ -323,8 +320,8 @@ public void testCreateAccessGroup_FailedToCreatePolicy() {
323320
when(host1.getStorageIpAddress()).thenReturn("10.0.0.1");
324321
hosts.add(host1);
325322

326-
when(accessGroup.getPrimaryDataStoreInfo()).thenReturn(primaryDataStoreInfo);
327-
when(primaryDataStoreInfo.getDetails()).thenReturn(details);
323+
// Removed primaryDataStoreInfo mock - using storage pool ID directly
324+
when(storagePoolDetailsDao.listDetailsKeyPairs(1L)).thenReturn(details);
328325
when(accessGroup.getHostsToConnect()).thenReturn(hosts);
329326
doThrow(new RuntimeException("Failed to create policy")).when(nasFeignClient)
330327
.createExportPolicy(anyString(), any(ExportPolicy.class));
@@ -338,7 +335,6 @@ public void testCreateAccessGroup_FailedToCreatePolicy() {
338335
@Test
339336
public void testCreateAccessGroup_FailedToVerifyPolicy() {
340337
AccessGroup accessGroup = mock(AccessGroup.class);
341-
PrimaryDataStoreInfo primaryDataStoreInfo = mock(PrimaryDataStoreInfo.class);
342338
Map<String, String> details = new HashMap<>();
343339
details.put(Constants.SVM_NAME, "svm1");
344340
details.put(Constants.VOLUME_UUID, "vol-uuid-123");
@@ -352,8 +348,8 @@ public void testCreateAccessGroup_FailedToVerifyPolicy() {
352348
OntapResponse<ExportPolicy> emptyResponse = new OntapResponse<>();
353349
emptyResponse.setRecords(new ArrayList<>());
354350

355-
when(accessGroup.getPrimaryDataStoreInfo()).thenReturn(primaryDataStoreInfo);
356-
when(primaryDataStoreInfo.getDetails()).thenReturn(details);
351+
// Removed primaryDataStoreInfo mock - using storage pool ID directly
352+
when(storagePoolDetailsDao.listDetailsKeyPairs(1L)).thenReturn(details);
357353
when(accessGroup.getHostsToConnect()).thenReturn(hosts);
358354
doNothing().when(nasFeignClient).createExportPolicy(anyString(), any(ExportPolicy.class));
359355
when(nasFeignClient.getExportPolicyResponse(anyString(), anyMap())).thenReturn(emptyResponse);
@@ -369,7 +365,6 @@ public void testCreateAccessGroup_FailedToVerifyPolicy() {
369365
@Test
370366
public void testCreateAccessGroup_JobFailure() throws Exception {
371367
AccessGroup accessGroup = mock(AccessGroup.class);
372-
PrimaryDataStoreInfo primaryDataStoreInfo = mock(PrimaryDataStoreInfo.class);
373368
Map<String, String> details = new HashMap<>();
374369
details.put(Constants.SVM_NAME, "svm1");
375370
details.put(Constants.VOLUME_UUID, "vol-uuid-123");
@@ -396,9 +391,9 @@ public void testCreateAccessGroup_JobFailure() throws Exception {
396391
job.setMessage("Job failed");
397392
jobResponse.setJob(job);
398393

399-
when(accessGroup.getPrimaryDataStoreInfo()).thenReturn(primaryDataStoreInfo);
400-
when(primaryDataStoreInfo.getDetails()).thenReturn(details);
401-
when(primaryDataStoreInfo.getId()).thenReturn(1L);
394+
// Removed primaryDataStoreInfo mock - using storage pool ID directly
395+
when(storagePoolDetailsDao.listDetailsKeyPairs(1L)).thenReturn(details);
396+
when(accessGroup.getStoragePoolId()).thenReturn(1L);
402397
when(accessGroup.getHostsToConnect()).thenReturn(hosts);
403398
doNothing().when(nasFeignClient).createExportPolicy(anyString(), any(ExportPolicy.class));
404399
when(nasFeignClient.getExportPolicyResponse(anyString(), anyMap())).thenReturn(policyResponse);
@@ -414,7 +409,6 @@ public void testCreateAccessGroup_JobFailure() throws Exception {
414409
@Test
415410
public void testCreateAccessGroup_HostWithPrivateIP() throws Exception {
416411
AccessGroup accessGroup = mock(AccessGroup.class);
417-
PrimaryDataStoreInfo primaryDataStoreInfo = mock(PrimaryDataStoreInfo.class);
418412
Map<String, String> details = new HashMap<>();
419413
details.put(Constants.SVM_NAME, "svm1");
420414
details.put(Constants.VOLUME_UUID, "vol-uuid-123");
@@ -441,9 +435,9 @@ public void testCreateAccessGroup_HostWithPrivateIP() throws Exception {
441435
job.setState(Constants.JOB_SUCCESS);
442436
jobResponse.setJob(job);
443437

444-
when(accessGroup.getPrimaryDataStoreInfo()).thenReturn(primaryDataStoreInfo);
445-
when(primaryDataStoreInfo.getDetails()).thenReturn(details);
446-
when(primaryDataStoreInfo.getId()).thenReturn(1L);
438+
// Removed primaryDataStoreInfo mock - using storage pool ID directly
439+
when(storagePoolDetailsDao.listDetailsKeyPairs(1L)).thenReturn(details);
440+
when(accessGroup.getStoragePoolId()).thenReturn(1L);
447441
when(accessGroup.getHostsToConnect()).thenReturn(hosts);
448442
doNothing().when(nasFeignClient).createExportPolicy(anyString(), any(ExportPolicy.class));
449443
when(nasFeignClient.getExportPolicyResponse(anyString(), anyMap())).thenReturn(policyResponse);
@@ -466,14 +460,13 @@ public void testCreateAccessGroup_HostWithPrivateIP() throws Exception {
466460
@Test
467461
public void testDeleteAccessGroup_Success() {
468462
AccessGroup accessGroup = mock(AccessGroup.class);
469-
PrimaryDataStoreInfo primaryDataStoreInfo = mock(PrimaryDataStoreInfo.class);
470463
Map<String, String> details = new HashMap<>();
471464
details.put(Constants.EXPORT_POLICY_NAME, "export-policy-1");
472465
details.put(Constants.EXPORT_POLICY_ID, "1");
473466

474-
when(accessGroup.getPrimaryDataStoreInfo()).thenReturn(primaryDataStoreInfo);
475-
when(primaryDataStoreInfo.getDetails()).thenReturn(details);
476-
when(primaryDataStoreInfo.getName()).thenReturn("storage-pool-1");
467+
when(accessGroup.getStoragePoolId()).thenReturn(1L);
468+
when(storagePoolDetailsDao.listDetailsKeyPairs(1L)).thenReturn(details);
469+
// Removed primaryDataStoreInfo.getName() - not used
477470
doNothing().when(nasFeignClient).deleteExportPolicyById(anyString(), anyString());
478471

479472
// Execute
@@ -495,7 +488,7 @@ public void testDeleteAccessGroup_NullAccessGroup() {
495488
@Test
496489
public void testDeleteAccessGroup_NullPrimaryDataStoreInfo() {
497490
AccessGroup accessGroup = mock(AccessGroup.class);
498-
when(accessGroup.getPrimaryDataStoreInfo()).thenReturn(null);
491+
when(accessGroup.getStoragePoolId()).thenReturn(null);
499492

500493
assertThrows(CloudRuntimeException.class, () -> {
501494
strategy.deleteAccessGroup(accessGroup);
@@ -506,14 +499,12 @@ public void testDeleteAccessGroup_NullPrimaryDataStoreInfo() {
506499
@Test
507500
public void testDeleteAccessGroup_Failed() {
508501
AccessGroup accessGroup = mock(AccessGroup.class);
509-
PrimaryDataStoreInfo primaryDataStoreInfo = mock(PrimaryDataStoreInfo.class);
510502
Map<String, String> details = new HashMap<>();
511503
details.put(Constants.EXPORT_POLICY_NAME, "export-policy-1");
512504
details.put(Constants.EXPORT_POLICY_ID, "1");
513505

514-
when(accessGroup.getPrimaryDataStoreInfo()).thenReturn(primaryDataStoreInfo);
515-
when(primaryDataStoreInfo.getDetails()).thenReturn(details);
516-
when(primaryDataStoreInfo.getName()).thenReturn("storage-pool-1");
506+
when(accessGroup.getStoragePoolId()).thenReturn(1L);
507+
when(storagePoolDetailsDao.listDetailsKeyPairs(1L)).thenReturn(details);
517508
doThrow(new RuntimeException("Failed to delete")).when(nasFeignClient)
518509
.deleteExportPolicyById(anyString(), anyString());
519510

0 commit comments

Comments
 (0)