@@ -699,6 +699,89 @@ def test_build_system_disk_size_too_small(self, mock_exists, mock_qemu_tool_clas
699699 msg = f"The system disk size is too small to import the base image: { expected_system_size } < 21474836480"
700700 )
701701
702+ @mock .patch ('ansible_collections.community.libvirt.plugins.modules.virt_cloud_instance.QemuImgTool' )
703+ @mock .patch ('os.path.exists' )
704+ @mock .patch ('os.remove' )
705+ def test_build_system_disk_force_disk_removes_existing (self , mock_remove , mock_exists , mock_qemu_tool_class ):
706+ """Test building system disk with force_disk=True removes existing file"""
707+ mock_exists .return_value = True # System disk exists
708+
709+ # Configure the mocked QemuImgTool
710+ mock_qemu_instance = mock .Mock ()
711+ mock_qemu_tool_class .return_value = mock_qemu_instance
712+ mock_qemu_instance .info .return_value = (0 , {
713+ 'format' : 'qcow2' ,
714+ 'virtual-size' : 1073741824 # 1GB
715+ }, '' )
716+ mock_qemu_instance .resize .return_value = (0 , '' , '' )
717+
718+ disk_param = {
719+ 'path' : '/var/lib/libvirt/images/vm.qcow2' ,
720+ 'size' : 20 ,
721+ 'format' : 'qcow2'
722+ }
723+
724+ result = self .operator .build_system_disk (disk_param , force_disk = True )
725+
726+ # Verify the existing file was removed
727+ mock_remove .assert_called_once_with ('/var/lib/libvirt/images/vm.qcow2' )
728+ self .assertEqual (result , disk_param )
729+
730+ # Verify disk was created after removal
731+ self .mock_module .preserved_copy .assert_called_once_with (
732+ '/path/to/base.qcow2' , '/var/lib/libvirt/images/vm.qcow2'
733+ )
734+ mock_qemu_instance .resize .assert_called_once ()
735+
736+ @mock .patch ('ansible_collections.community.libvirt.plugins.modules.virt_cloud_instance.QemuImgTool' )
737+ @mock .patch ('os.path.exists' )
738+ @mock .patch ('os.remove' )
739+ def test_build_system_disk_force_disk_check_mode (self , mock_remove , mock_exists , mock_qemu_tool_class ):
740+ """Test building system disk with force_disk=True in check_mode doesn't remove file"""
741+ self .mock_module .check_mode = True
742+ # System disk exists, base image doesn't exist
743+ mock_exists .side_effect = lambda path : path == '/var/lib/libvirt/images/vm.qcow2'
744+
745+ # Configure the mocked QemuImgTool
746+ mock_qemu_instance = mock .Mock ()
747+ mock_qemu_tool_class .return_value = mock_qemu_instance
748+
749+ disk_param = {
750+ 'path' : '/var/lib/libvirt/images/vm.qcow2' ,
751+ 'size' : 20 ,
752+ 'format' : 'qcow2'
753+ }
754+
755+ result = self .operator .build_system_disk (disk_param , force_disk = True )
756+
757+ # In check_mode, file should NOT be removed
758+ mock_remove .assert_not_called ()
759+
760+ # Should return disk config without creating files
761+ self .assertEqual (result , disk_param )
762+ self .mock_module .preserved_copy .assert_not_called ()
763+ mock_qemu_instance .resize .assert_not_called ()
764+
765+ @mock .patch ('os.path.exists' )
766+ def test_build_system_disk_force_disk_false_existing_fails (self , mock_exists ):
767+ """Test building system disk with force_disk=False fails when disk exists"""
768+ mock_exists .return_value = True # System disk exists
769+
770+ # Make fail_json raise an exception to simulate real behavior
771+ self .mock_module .fail_json .side_effect = Exception ("Module failed" )
772+
773+ disk_param = {
774+ 'path' : '/var/lib/libvirt/images/vm.qcow2' ,
775+ 'size' : 20
776+ }
777+
778+ with self .assertRaises (Exception ):
779+ self .operator .build_system_disk (disk_param , force_disk = False )
780+
781+ self .mock_module .fail_json .assert_called_once_with (
782+ msg = "The system disk file already exists: /var/lib/libvirt/images/vm.qcow2"
783+ )
784+
702785
703786class TestBaseImageOperatorCheckMode (unittest .TestCase ):
704787 """Test BaseImageOperator check_mode support"""
@@ -928,9 +1011,13 @@ def setUp(self):
9281011 'base_image' : 'https://example.com/image.qcow2' ,
9291012 'image_cache_dir' : '/tmp/cache' ,
9301013 'force_pull' : False ,
1014+ 'force_disk' : False ,
9311015 'disks' : [{'path' : '/var/lib/libvirt/images/test.qcow2' , 'size' : 20 }],
9321016 'image_checksum' : None ,
933- 'url_timeout' : None
1017+ 'url_timeout' : None ,
1018+ 'wait_for_cloud_init_reboot' : True ,
1019+ 'cloud_init_auto_reboot' : True ,
1020+ 'cloud_init_reboot_timeout' : 600
9341021 }
9351022
9361023 @mock .patch ('ansible_collections.community.libvirt.plugins.modules.virt_cloud_instance.BaseImageOperator' )
@@ -973,7 +1060,7 @@ def test_core_vm_not_exists_create_success(self, mock_update_params, mock_valida
9731060 mock_operator .validate_checksum .assert_called_once ()
9741061 mock_operator .build_system_disk .assert_called_once ()
9751062 mock_update_params .assert_called_once ()
976- mock_virt_install .execute .assert_called_once_with (dryrun = False , wait_timeout = None )
1063+ mock_virt_install .execute .assert_called_once_with (dryrun = False , wait_timeout = 600 )
9771064
9781065 # VM should not be destroyed (doesn't exist)
9791066 mock_virt_conn .destroy .assert_not_called ()
@@ -1068,7 +1155,7 @@ def test_core_vm_exists_recreate_active(self, mock_update_params, mock_validate_
10681155 mock_operator .fetch_image .assert_called_once ()
10691156 mock_operator .validate_checksum .assert_called_once ()
10701157 mock_operator .build_system_disk .assert_called_once ()
1071- mock_virt_install .execute .assert_called_once_with (dryrun = False , wait_timeout = None )
1158+ mock_virt_install .execute .assert_called_once_with (dryrun = False , wait_timeout = 600 )
10721159
10731160 # Should return success
10741161 self .assertEqual (rc , VIRT_SUCCESS )
@@ -1258,12 +1345,104 @@ def test_core_check_mode_vm_recreation(self, mock_update_params, mock_validate_d
12581345 mock_virt_conn .undefine .assert_not_called ()
12591346
12601347 # But virt-install should be called with dryrun=True
1261- mock_virt_install .execute .assert_called_once_with (dryrun = True , wait_timeout = None )
1348+ mock_virt_install .execute .assert_called_once_with (dryrun = True , wait_timeout = 600 )
12621349
12631350 # Should still return success
12641351 self .assertEqual (rc , VIRT_SUCCESS )
12651352 self .assertTrue (result ['changed' ])
12661353
1354+ @mock .patch ('ansible_collections.community.libvirt.plugins.modules.virt_cloud_instance.BaseImageOperator' )
1355+ @mock .patch ('ansible_collections.community.libvirt.plugins.modules.virt_cloud_instance.VirtInstallTool' )
1356+ @mock .patch ('ansible_collections.community.libvirt.plugins.modules.virt_cloud_instance.LibvirtWrapper' )
1357+ @mock .patch ('ansible_collections.community.libvirt.plugins.modules.virt_cloud_instance.validate_disks' )
1358+ @mock .patch ('ansible_collections.community.libvirt.plugins.modules.virt_cloud_instance.update_virtinst_params' )
1359+ def test_core_force_disk_passed_to_build_system_disk (self , mock_update_params , mock_validate_disks ,
1360+ mock_libvirt_wrapper_class , mock_virt_install_class ,
1361+ mock_base_image_operator_class ):
1362+ """Test that force_disk parameter is passed to build_system_disk"""
1363+ from ansible_collections .community .libvirt .plugins .modules .virt_cloud_instance import core , VIRT_SUCCESS
1364+ from ansible_collections .community .libvirt .plugins .module_utils .libvirt import VMNotFound
1365+
1366+ # Set force_disk to True
1367+ self .mock_module .params ['force_disk' ] = True
1368+
1369+ # Mock LibvirtWrapper - VM doesn't exist
1370+ mock_virt_conn = mock .Mock ()
1371+ mock_virt_conn .find_vm .side_effect = VMNotFound ("VM not found" )
1372+ mock_libvirt_wrapper_class .return_value = mock_virt_conn
1373+
1374+ # Mock VirtInstallTool
1375+ mock_virt_install = mock .Mock ()
1376+ mock_virt_install .execute .return_value = (
1377+ True , VIRT_SUCCESS , {'some' : 'data' })
1378+ mock_virt_install_class .return_value = mock_virt_install
1379+
1380+ # Mock BaseImageOperator
1381+ mock_operator = mock .Mock ()
1382+ mock_operator .validate_checksum .return_value = True
1383+ mock_operator .build_system_disk .return_value = {
1384+ 'path' : '/var/lib/libvirt/images/test.qcow2' }
1385+ mock_base_image_operator_class .return_value = mock_operator
1386+
1387+ # Execute core function
1388+ rc , result = core (self .mock_module )
1389+
1390+ # Verify force_disk=True was passed to build_system_disk
1391+ mock_operator .build_system_disk .assert_called_once_with (
1392+ {'path' : '/var/lib/libvirt/images/test.qcow2' , 'size' : 20 },
1393+ force_disk = True
1394+ )
1395+
1396+ # Should return success
1397+ self .assertEqual (rc , VIRT_SUCCESS )
1398+ self .assertTrue (result ['changed' ])
1399+
1400+ @mock .patch ('ansible_collections.community.libvirt.plugins.modules.virt_cloud_instance.BaseImageOperator' )
1401+ @mock .patch ('ansible_collections.community.libvirt.plugins.modules.virt_cloud_instance.VirtInstallTool' )
1402+ @mock .patch ('ansible_collections.community.libvirt.plugins.modules.virt_cloud_instance.LibvirtWrapper' )
1403+ @mock .patch ('ansible_collections.community.libvirt.plugins.modules.virt_cloud_instance.validate_disks' )
1404+ @mock .patch ('ansible_collections.community.libvirt.plugins.modules.virt_cloud_instance.update_virtinst_params' )
1405+ def test_core_force_disk_false_passed_to_build_system_disk (self , mock_update_params , mock_validate_disks ,
1406+ mock_libvirt_wrapper_class , mock_virt_install_class ,
1407+ mock_base_image_operator_class ):
1408+ """Test that force_disk=False parameter is passed to build_system_disk"""
1409+ from ansible_collections .community .libvirt .plugins .modules .virt_cloud_instance import core , VIRT_SUCCESS
1410+ from ansible_collections .community .libvirt .plugins .module_utils .libvirt import VMNotFound
1411+
1412+ # Ensure force_disk is False (default)
1413+ self .mock_module .params ['force_disk' ] = False
1414+
1415+ # Mock LibvirtWrapper - VM doesn't exist
1416+ mock_virt_conn = mock .Mock ()
1417+ mock_virt_conn .find_vm .side_effect = VMNotFound ("VM not found" )
1418+ mock_libvirt_wrapper_class .return_value = mock_virt_conn
1419+
1420+ # Mock VirtInstallTool
1421+ mock_virt_install = mock .Mock ()
1422+ mock_virt_install .execute .return_value = (
1423+ True , VIRT_SUCCESS , {'some' : 'data' })
1424+ mock_virt_install_class .return_value = mock_virt_install
1425+
1426+ # Mock BaseImageOperator
1427+ mock_operator = mock .Mock ()
1428+ mock_operator .validate_checksum .return_value = True
1429+ mock_operator .build_system_disk .return_value = {
1430+ 'path' : '/var/lib/libvirt/images/test.qcow2' }
1431+ mock_base_image_operator_class .return_value = mock_operator
1432+
1433+ # Execute core function
1434+ rc , result = core (self .mock_module )
1435+
1436+ # Verify force_disk=False was passed to build_system_disk
1437+ mock_operator .build_system_disk .assert_called_once_with (
1438+ {'path' : '/var/lib/libvirt/images/test.qcow2' , 'size' : 20 },
1439+ force_disk = False
1440+ )
1441+
1442+ # Should return success
1443+ self .assertEqual (rc , VIRT_SUCCESS )
1444+ self .assertTrue (result ['changed' ])
1445+
12671446
12681447if __name__ == '__main__' :
12691448 unittest .main (verbosity = 2 )
0 commit comments