@@ -491,6 +491,7 @@ def test_04_attach_volume_to_vm(self):
491491 (Note: on ONTAP/NFS shared storage the volume state remains 'Ready';
492492 attachment is signalled by virtualmachineid being populated)
493493 - ONTAP: FlexVol remains online
494+ - ONTAP: NFS3 volume data file created in FlexVol after attach (lazy creation)
494495 - VM remains 'Running'
495496 """
496497 if self .__class__ .vm is None :
@@ -539,6 +540,17 @@ def test_04_attach_volume_to_vm(self):
539540 "ONTAP FlexVol should be 'online' after attach"
540541 )
541542
543+ # ONTAP: NFS3 uses lazy file creation — the volume data file is
544+ # materialised on the FlexVol only when CloudStack calls createAsync
545+ # during attachVolume. Verify that the file now exists.
546+ files = self .ontap .list_files_in_volume (pool .name )
547+ vol_file = next ((f for f in files if vol .id in f ), None )
548+ self .assertIsNotNone (
549+ vol_file ,
550+ "No data file matching volume UUID '%s' found in FlexVol '%s' "
551+ "after attach; files present: %s" % (vol .id , pool .name , files )
552+ )
553+
542554 # ------------------------------------------------------------------
543555 # Step 05 - Stop VM — export policy must be retained
544556 # ------------------------------------------------------------------
@@ -666,6 +678,7 @@ def test_07_detach_volume_from_vm(self):
666678 - Volume no longer lists the VM's ID
667679 - VM remains 'Running'
668680 - ONTAP: FlexVol remains online
681+ - ONTAP: NFS3 volume data file persists in FlexVol after detach
669682 """
670683 if self .__class__ .vm is None :
671684 self .skipTest ("VM not deployed — test_03 was skipped (no ready template)" )
@@ -723,6 +736,16 @@ def test_07_detach_volume_from_vm(self):
723736 "ONTAP FlexVol should be 'online' after detach"
724737 )
725738
739+ # ONTAP: NFS3 volume data file must still exist after detach — the file
740+ # is only removed when deleteVolume is called, not on detach.
741+ files = self .ontap .list_files_in_volume (pool .name )
742+ vol_file = next ((f for f in files if vol .id in f ), None )
743+ self .assertIsNotNone (
744+ vol_file ,
745+ "Volume data file for '%s' should persist in FlexVol '%s' after "
746+ "detach; files present: %s" % (vol .id , pool .name , files )
747+ )
748+
726749 # ------------------------------------------------------------------
727750 # Step 08 - Destroy VM, delete volume, delete pool
728751 # ------------------------------------------------------------------
@@ -735,6 +758,7 @@ def test_08_destroy_vm_and_cleanup(self):
735758 Verifies:
736759 - VM is destroyed/expunged from CloudStack
737760 - Volume is deleted from CloudStack
761+ - ONTAP: NFS3 volume data file removed from FlexVol after deleteVolume
738762 - Pool is removed from CloudStack
739763 - ONTAP: FlexVol is deleted after pool removal
740764 - ONTAP: Export policy is removed after pool removal
@@ -766,11 +790,24 @@ def test_08_destroy_vm_and_cleanup(self):
766790
767791 # Delete the ONTAP data volume
768792 if vol is not None :
793+ vol_id = vol .id
769794 cmd = deleteVolumeAPI .deleteVolumeCmd ()
770- cmd .id = vol . id
795+ cmd .id = vol_id
771796 self .apiClient .deleteVolume (cmd )
772797 self .__class__ .volume = None
773798
799+ # ONTAP: NFS3 volume data file must be removed from the FlexVol
800+ # after deleteVolume (CloudStack/libvirt deletes the file from the
801+ # NFS mount as part of the destroy workflow).
802+ files = self .ontap .list_files_in_volume (pool_name )
803+ vol_file = next ((f for f in files if vol_id in f ), None )
804+ self .assertIsNone (
805+ vol_file ,
806+ "Volume data file for '%s' should be gone from FlexVol '%s' "
807+ "after deleteVolume; files still present: %s"
808+ % (vol_id , pool_name , files )
809+ )
810+
774811 # Enter maintenance then delete the pool
775812 maint_cmd = enableStorageMaintenance .enableStorageMaintenanceCmd ()
776813 maint_cmd .id = pool .id
0 commit comments