Skip to content

Commit 207e4e7

Browse files
piyush5netappSrivastava, Piyush
andauthored
feature/CSTACKEX-253: automation changes for ontapIscsi pool type int… (#97)
…roduction ### Description This PR... <!--- Describe your changes in DETAIL - And how has behaviour functionally changed. --> <!-- For new features, provide link to FS, dev ML discussion etc. --> <!-- In case of bug fix, the expected and actual behaviours, steps to reproduce. --> <!-- When "Fixes: #<id>" is specified, the issue/PR will automatically be closed when this PR gets merged --> <!-- For addressing multiple issues/PRs, use multiple "Fixes: #<id>" --> <!-- Fixes: # --> <!--- ******************************************************************************* --> <!--- NOTE: AUTOMATION USES THE DESCRIPTIONS TO SET LABELS AND PRODUCE DOCUMENTATION. --> <!--- PLEASE PUT AN 'X' in only **ONE** box --> <!--- ******************************************************************************* --> ### Types of changes - [ ] Breaking change (fix or feature that would cause existing functionality to change) - [ ] New feature (non-breaking change which adds functionality) - [ ] Bug fix (non-breaking change which fixes an issue) - [ ] Enhancement (improves an existing feature and functionality) - [ ] Cleanup (Code refactoring and cleanup, that may add test cases) - [x] Build/CI - [ ] Test (unit or integration test code) ### Feature/Enhancement Scale or Bug Severity #### Feature/Enhancement Scale - [ ] Major - [ ] Minor #### Bug Severity - [ ] BLOCKER - [ ] Critical - [ ] Major - [ ] Minor - [ ] Trivial ### Screenshots (if appropriate): ### How Has This Been Tested? Automation has been run TEST SUMMARY [iscsi_workflow] iSCSI pool lifecycle PASS test_01_create_primary_storage_pool PASS test_02_disable_storage_pool PASS test_03_enable_storage_pool PASS test_04_enter_maintenance_mode PASS test_05_cancel_maintenance_mode PASS test_06_enter_maintenance_and_delete_pool PASS test_07_create_volume_on_pool PASS test_08_delete_volume_and_pool [iscsi_with_volumes] iSCSI pool with volumes PASS test_01_create_pool_and_volume PASS test_02_disable_pool_volume_survives PASS test_03_enable_pool_volume_intact PASS test_04_enter_maintenance_volume_present PASS test_05_cancel_maintenance_volume_present PASS test_06_forced_false_delete_rejected PASS test_07_delete_volume_and_force_delete_pool [iscsi_volume] iSCSI volume lifecycle PASS test_01_create_pool_and_volume PASS test_02_delete_volume PASS test_03_recreate_volume_for_delete_tests PASS test_04_forced_false_delete_with_volume_fails PASS test_05_delete_volume_and_force_delete_pool [iscsi_zone_pool] iSCSI zone-scoped pool PASS test_01_create_zone_scoped_pool PASS test_02_disable_zone_scoped_pool PASS test_03_enable_zone_scoped_pool PASS test_04_delete_zone_scoped_pool [iscsi_vm_workflow] iSCSI VM volume workflow PASS test_01_create_iscsi_pool PASS test_02_create_ontap_data_volume PASS test_03_deploy_vm PASS test_04_attach_volume_to_vm PASS test_05_stop_vm_lun_unmapped PASS test_06_start_vm_lun_remapped PASS test_07_detach_volume_from_vm PASS test_08_destroy_vm_and_cleanup ================================================================ TOTAL: 32 passed, 0 failed, 0 skipped (32 tests) <!-- Please describe in detail how you tested your changes. --> <!-- Include details of your testing environment, and the tests you ran to --> #### How did you try to break this feature and the system with this change? <!-- see how your change affects other areas of the code, etc. --> <!-- Please read the [CONTRIBUTING](https://github.com/apache/cloudstack/blob/main/CONTRIBUTING.md) document --> Co-authored-by: Srivastava, Piyush <Piyush.Srivastava@netapp.com>
1 parent ef67042 commit 207e4e7

5 files changed

Lines changed: 66 additions & 38 deletions

File tree

test/integration/plugins/ontap/TEST_CASES.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ Each suite is sequential — tests must run in numbered order; each step builds
138138

139139
| # | Test method | Goal | Depends on | CloudStack success criteria | ONTAP success criteria | Type |
140140
|---|-------------|------|------------|-----------------------------|------------------------|------|
141-
| 01 | `test_01_create_primary_storage_pool` | Create a cluster-scoped iSCSI primary storage pool | setUpClass | `pool.state == "Up"`, `pool.type == "Iscsi"` | FlexVol `online`; one igroup per cluster host (named `cs_{svmName}_{hostShortName}`) with host IQN as initiator | positive |
141+
| 01 | `test_01_create_primary_storage_pool` | Create a cluster-scoped iSCSI primary storage pool | setUpClass | `pool.state == "Up"`, `pool.type == "OntapiSCSI"` | FlexVol `online`; one igroup per cluster host (named `cs_{svmName}_{hostShortName}`) with host IQN as initiator | positive |
142142
| 02 | `test_02_disable_storage_pool` | Disable the pool | test_01 (`pool`) | `pool.state == "Disabled"` | FlexVol still `online` | positive |
143143
| 03 | `test_03_enable_storage_pool` | Re-enable the pool | test_02 | `pool.state == "Up"` | FlexVol still `online` | positive |
144144
| 04 | `test_04_enter_maintenance_mode` | Put pool into maintenance | test_03 | `pool.state == "Maintenance"` | FlexVol still `online`; igroups unchanged | positive |
@@ -210,7 +210,7 @@ Each suite is sequential — tests must run in numbered order; each step builds
210210

211211
| # | Test method | Goal | Depends on | CloudStack success criteria | ONTAP success criteria | Type |
212212
|---|-------------|------|------------|-----------------------------|------------------------|------|
213-
| 01 | `test_01_create_iscsi_pool` | Create iSCSI ONTAP primary storage pool | setUpClass | `pool.state == "Up"`, `pool.type == "Iscsi"` | FlexVol `online`; igroup per cluster host with host IQN | positive |
213+
| 01 | `test_01_create_iscsi_pool` | Create iSCSI ONTAP primary storage pool | setUpClass | `pool.state == "Up"`, `pool.type == "OntapiSCSI"` | FlexVol `online`; igroup per cluster host with host IQN | positive |
214214
| 02 | `test_02_create_ontap_data_volume` | Allocate a CloudStack data volume (creates a LUN in the FlexVol) | test_01 (`pool`) | Volume non-None | ≥1 LUN in FlexVol | positive |
215215
| 03 | `test_03_deploy_vm` | Deploy VM using first ready KVM template; verify 0 LUN-maps exist before attach | test_02 (`volume`) | `vm.state == "Running"`; 0 LUN-maps on ONTAP | 0 LUN-maps (`list_lun_maps_for_volume` returns empty) | positive |
216216
| 04 | `test_04_attach_volume_to_vm` | Hot-attach the ONTAP iSCSI volume to the running VM — a LUN-map is created (TDS SN 27) | test_03 (`vm`, `volume`) | `volume.virtualmachineid == vm.id` | ≥1 LUN-map linking the LUN to the host's igroup | positive |

test/integration/plugins/ontap/iscsi/instance/test_vm_volume_attach.py

Lines changed: 52 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -404,12 +404,42 @@ def _poll_volume_field(self, vol_id, field, target, timeout=120,
404404
time.sleep(interval)
405405
return None
406406

407-
def _lun_maps(self):
408-
"""Return current LUN-maps for the pool's FlexVol."""
409-
if self.__class__.pool is None:
407+
def _data_lun_name(self, volume=None):
408+
"""
409+
Full ONTAP path of the LUN backing the CloudStack data volume.
410+
411+
UnifiedSANStrategy names the LUN after the CloudStack volume with
412+
hyphens replaced by underscores, inside the pool's FlexVol.
413+
"""
414+
volume = volume or self.__class__.volume
415+
if volume is None or self.__class__.pool is None:
416+
return None
417+
return "/vol/%s/%s" % (self.__class__.pool.name,
418+
volume.name.replace("-", "_"))
419+
420+
def _lun_maps(self, volume=None):
421+
"""
422+
Return LUN-maps belonging to the data volume's LUN only.
423+
424+
The same FlexVol also holds the VM's ROOT LUN whenever the allocator
425+
places the root disk on this pool, so the unfiltered map list is not a
426+
measure of the data volume's accessibility.
427+
"""
428+
lun_name = self._data_lun_name(volume)
429+
if lun_name is None:
430+
return []
431+
return [m for m in self.ontap.list_lun_maps_for_volume(
432+
self.svm_name, self.__class__.pool.name)
433+
if m.get("lun", {}).get("name") == lun_name]
434+
435+
def _data_luns(self, volume=None):
436+
"""Return LUN records for the data volume's LUN only."""
437+
lun_name = self._data_lun_name(volume)
438+
if lun_name is None:
410439
return []
411-
return self.ontap.list_lun_maps_for_volume(
412-
self.svm_name, self.__class__.pool.name)
440+
return [lun for lun in self.ontap.list_luns_in_volume(
441+
self.svm_name, self.__class__.pool.name)
442+
if lun.get("name") == lun_name]
413443

414444
# ==================================================================
415445
# Test steps
@@ -424,7 +454,7 @@ def test_01_create_iscsi_pool(self):
424454
"""
425455
Create an iSCSI primary storage pool on ONTAP.
426456
Verifies:
427-
- Pool reaches 'Up' state; type is 'Iscsi'
457+
- Pool reaches 'Up' state; type is 'OntapiSCSI'
428458
- ONTAP: FlexVol is online
429459
- ONTAP: igroup exists for every host in the cluster that has an IQN
430460
"""
@@ -433,8 +463,8 @@ def test_01_create_iscsi_pool(self):
433463

434464
self.assertEqual(pool.state, "Up",
435465
"Pool state should be 'Up', got '%s'" % pool.state)
436-
self.assertEqual(pool.type, "Iscsi",
437-
"Pool type should be 'Iscsi', got '%s'" % pool.type)
466+
self.assertEqual(pool.type, "OntapiSCSI",
467+
"Pool type should be 'OntapiSCSI', got '%s'" % pool.type)
438468

439469
ontap_vol = self.ontap.get_volume(pool.name)
440470
self.assertIsNotNone(
@@ -462,12 +492,12 @@ def test_02_create_ontap_data_volume(self):
462492
self.__class__.volume = vol
463493
self.assertIsNotNone(vol, "createVolume returned None")
464494

465-
luns = self.ontap.list_luns_in_volume(
466-
self.svm_name, self.__class__.pool.name)
495+
luns = self._data_luns()
467496
self.assertTrue(
468497
len(luns) > 0,
469-
"Expected ≥1 LUN in ONTAP FlexVol '%s' after volume creation, "
470-
"found 0" % self.__class__.pool.name
498+
"Expected the data volume's LUN '%s' in ONTAP FlexVol '%s' after "
499+
"volume creation, found none"
500+
% (self._data_lun_name(), self.__class__.pool.name)
471501
)
472502

473503
# ------------------------------------------------------------------
@@ -511,7 +541,7 @@ def test_03_deploy_vm(self):
511541
lun_maps = self._lun_maps()
512542
self.assertEqual(
513543
len(lun_maps), 0,
514-
"Expected 0 LUN-maps before volume attach, found %d: %s"
544+
"Expected 0 data-volume LUN-maps before volume attach, found %d: %s"
515545
% (len(lun_maps), lun_maps)
516546
)
517547

@@ -590,16 +620,15 @@ def test_05_stop_vm_lun_unmapped(self):
590620
lun_maps = self._lun_maps()
591621
self.assertEqual(
592622
len(lun_maps), 0,
593-
"Expected 0 LUN-maps after VM stop, found %d: %s"
623+
"Expected 0 data-volume LUN-maps after VM stop, found %d: %s"
594624
% (len(lun_maps), lun_maps)
595625
)
596626

597627
# ONTAP: LUN itself must still exist in the FlexVol
598-
luns = self.ontap.list_luns_in_volume(
599-
self.svm_name, self.__class__.pool.name)
628+
luns = self._data_luns()
600629
self.assertTrue(
601630
len(luns) > 0,
602-
"LUN should still exist in ONTAP FlexVol after VM stop"
631+
"Data volume LUN should still exist in ONTAP FlexVol after VM stop"
603632
)
604633

605634
# ------------------------------------------------------------------
@@ -689,16 +718,15 @@ def test_07_detach_volume_from_vm(self):
689718
lun_maps = self._lun_maps()
690719
self.assertEqual(
691720
len(lun_maps), 0,
692-
"Expected 0 LUN-maps after volume detach, found %d: %s"
721+
"Expected 0 data-volume LUN-maps after volume detach, found %d: %s"
693722
% (len(lun_maps), lun_maps)
694723
)
695724

696725
# ONTAP: LUN still exists in FlexVol
697-
luns = self.ontap.list_luns_in_volume(
698-
self.svm_name, self.__class__.pool.name)
726+
luns = self._data_luns()
699727
self.assertTrue(
700728
len(luns) > 0,
701-
"LUN should still exist in ONTAP FlexVol after detach"
729+
"Data volume LUN should still exist in ONTAP FlexVol after detach"
702730
)
703731

704732
# ------------------------------------------------------------------
@@ -751,11 +779,11 @@ def test_08_destroy_vm_and_cleanup(self):
751779
self.__class__.volume = None
752780

753781
# ONTAP: LUN must be removed after volume deletion
754-
luns = self.ontap.list_luns_in_volume(self.svm_name, pool_name)
782+
luns = self._data_luns(vol)
755783
self.assertEqual(
756784
len(luns), 0,
757-
"Expected 0 LUNs in FlexVol '%s' after volume delete, "
758-
"found %d" % (pool_name, len(luns))
785+
"Expected the data volume's LUN to be gone from FlexVol '%s' "
786+
"after volume delete, found %d" % (pool_name, len(luns))
759787
)
760788

761789
# Enter maintenance and force-delete the pool

test/integration/plugins/ontap/iscsi/pool/test_pool_lifecycle.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,7 @@ def _assert_pool_capacity(self, pool, label):
276276
def test_01_create_primary_storage_pool(self):
277277
"""
278278
Create an iSCSI primary storage pool and verify:
279-
- CloudStack state is Up, type is Iscsi
279+
- CloudStack state is Up, type is OntapiSCSI
280280
- ONTAP: FlexVol exists and is online
281281
- ONTAP: one igroup per cluster host exists with the correct IQN initiator
282282
"""
@@ -288,8 +288,8 @@ def test_01_create_primary_storage_pool(self):
288288
"Pool state should be 'Up', got '%s'" % pool.state
289289
)
290290
self.assertEqual(
291-
pool.type, "Iscsi",
292-
"Pool type should be 'Iscsi', got '%s'" % pool.type
291+
pool.type, "OntapiSCSI",
292+
"Pool type should be 'OntapiSCSI', got '%s'" % pool.type
293293
)
294294

295295
# ONTAP: FlexVol must be online
@@ -502,7 +502,7 @@ def test_07_create_volume_on_pool(self):
502502
Create a new iSCSI pool and allocate a CloudStack data volume.
503503
For iSCSI, createAsync creates a LUN inside the pool's ONTAP FlexVol.
504504
Verifies:
505-
- pool.state is Up, type is Iscsi
505+
- pool.state is Up, type is OntapiSCSI
506506
- createVolume returns a non-None volume object
507507
- ONTAP: FlexVol is still online
508508
- ONTAP: at least one LUN is present in the FlexVol
@@ -520,8 +520,8 @@ def test_07_create_volume_on_pool(self):
520520
"Pool state should be 'Up', got '%s'" % pool.state
521521
)
522522
self.assertEqual(
523-
pool.type, "Iscsi",
524-
"Pool type should be 'Iscsi', got '%s'" % pool.type
523+
pool.type, "OntapiSCSI",
524+
"Pool type should be 'OntapiSCSI', got '%s'" % pool.type
525525
)
526526

527527
vol = self._create_volume(pool.id)

test/integration/plugins/ontap/iscsi/pool/test_pool_with_volumes.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,7 @@ def test_01_create_pool_and_volume(self):
311311
Create an iSCSI primary storage pool and allocate a CloudStack data
312312
volume on it.
313313
Verifies:
314-
- Pool state is Up; pool type is Iscsi
314+
- Pool state is Up; pool type is OntapiSCSI
315315
- ONTAP: FlexVol is online
316316
- ONTAP: at least one igroup exists (one per cluster host with IQN)
317317
- ONTAP: after createVolume, a LUN exists in the FlexVol
@@ -324,8 +324,8 @@ def test_01_create_pool_and_volume(self):
324324
"Pool state should be 'Up', got '%s'" % pool.state
325325
)
326326
self.assertEqual(
327-
pool.type, "Iscsi",
328-
"Pool type should be 'Iscsi', got '%s'" % pool.type
327+
pool.type, "OntapiSCSI",
328+
"Pool type should be 'OntapiSCSI', got '%s'" % pool.type
329329
)
330330

331331
# ONTAP: FlexVol must be online

test/integration/plugins/ontap/iscsi/pool/test_zone_scoped_pool.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,7 @@ def test_01_create_zone_scoped_pool(self):
249249
CloudStack calls attachZone(), which connects all eligible KVM hosts
250250
in the zone and creates igroups for each host's IQN.
251251
Verifies:
252-
- pool.state is Up, type is Iscsi
252+
- pool.state is Up, type is OntapiSCSI
253253
- ONTAP: FlexVol is online
254254
- ONTAP: igroup exists for each cluster host with the correct IQN
255255
"""
@@ -261,8 +261,8 @@ def test_01_create_zone_scoped_pool(self):
261261
"Pool state should be 'Up', got '%s'" % pool.state
262262
)
263263
self.assertEqual(
264-
pool.type, "Iscsi",
265-
"Pool type should be 'Iscsi', got '%s'" % pool.type
264+
pool.type, "OntapiSCSI",
265+
"Pool type should be 'OntapiSCSI', got '%s'" % pool.type
266266
)
267267

268268
# ONTAP: FlexVol must be online

0 commit comments

Comments
 (0)