1010 CommandListError ,
1111 FileSystemNotFoundError ,
1212 FileTransferError ,
13+ NotEnoughFreeSpaceError ,
1314 NTCFileNotFoundError ,
1415)
1516from pyntc .utils .models import FileCopyModel
@@ -139,14 +140,18 @@ def test_file_copy_remote_exists_failure(self):
139140 "source_file" , "dest_file" , file_system = FILE_SYSTEM
140141 )
141142
143+ @mock .patch .object (NXOSDevice , "_get_free_space" , return_value = 1024 * 1024 * 1024 )
144+ @mock .patch ("pyntc.devices.nxos_device.os.path.getsize" , return_value = 1024 )
142145 @mock .patch .object (NXOSDevice , "file_copy_remote_exists" , side_effect = [False , True ])
143- def test_file_copy (self , mock_fcre ):
146+ def test_file_copy (self , mock_fcre , mock_getsize , mock_get_free_space ):
144147 self .device .file_copy ("source_file" , "dest_file" )
145148 self .device .native .file_copy .assert_called_with ("source_file" , "dest_file" , file_system = FILE_SYSTEM )
146149 self .device .native .file_copy .assert_called ()
147150
151+ @mock .patch .object (NXOSDevice , "_get_free_space" , return_value = 1024 * 1024 * 1024 )
152+ @mock .patch ("pyntc.devices.nxos_device.os.path.getsize" , return_value = 1024 )
148153 @mock .patch .object (NXOSDevice , "file_copy_remote_exists" , side_effect = [False , True ])
149- def test_file_copy_no_dest (self , mock_fcre ):
154+ def test_file_copy_no_dest (self , mock_fcre , mock_getsize , mock_get_free_space ):
150155 self .device .file_copy ("source_file" )
151156 self .device .native .file_copy .assert_called_with ("source_file" , "source_file" , file_system = FILE_SYSTEM )
152157 self .device .native .file_copy .assert_called ()
@@ -156,12 +161,22 @@ def test_file_copy_file_exists(self, mock_fcre):
156161 self .device .file_copy ("source_file" , "dest_file" )
157162 self .device .native .file_copy .assert_not_called ()
158163
164+ @mock .patch .object (NXOSDevice , "_get_free_space" , return_value = 1024 * 1024 * 1024 )
165+ @mock .patch ("pyntc.devices.nxos_device.os.path.getsize" , return_value = 1024 )
159166 @mock .patch .object (NXOSDevice , "file_copy_remote_exists" , side_effect = [False , False ])
160- def test_file_copy_fail (self , mock_fcre ):
167+ def test_file_copy_fail (self , mock_fcre , mock_getsize , mock_get_free_space ):
161168 with self .assertRaises (FileTransferError ):
162169 self .device .file_copy ("source_file" )
163170 self .device .native .file_copy .assert_called ()
164171
172+ @mock .patch .object (NXOSDevice , "_get_free_space" , return_value = 1024 ) # Only 1KB free
173+ @mock .patch ("pyntc.devices.nxos_device.os.path.getsize" , return_value = 1024 * 1024 ) # Trying to copy 1MB
174+ @mock .patch .object (NXOSDevice , "file_copy_remote_exists" , side_effect = [False ])
175+ def test_file_copy_raises_not_enough_free_space (self , mock_fcre , mock_getsize , mock_get_free_space ):
176+ """Test file_copy raises NotEnoughFreeSpaceError when insufficient space."""
177+ with self .assertRaises (NotEnoughFreeSpaceError ):
178+ self .device .file_copy ("source_file" )
179+
165180 def test_reboot (self ):
166181 self .device .reboot ()
167182 self .device .native .show_list .assert_called_with (["terminal dont-ask" , "reload" ])
@@ -278,6 +293,41 @@ def test_get_file_system_not_found(self, mock_show):
278293 self .device ._get_file_system ()
279294 mock_show .assert_called_with ("dir" , raw_text = True )
280295
296+ @mock .patch .object (NXOSDevice , "show" )
297+ def test_get_free_space (self , mock_show ):
298+ """Test _get_free_space parses NXOS dir output correctly."""
299+ # NXOS dir output format with free space at the end
300+ mock_show .return_value = """Directory of bootflash:/
301+ 4096 Mar 03 22:47:15 2026 .rpmstore/
302+ 4733329408 bytes used
303+ 47171194880 bytes free
304+ 51904524288 bytes total
305+
306+ """
307+ result = self .device ._get_free_space ()
308+ self .assertEqual (result , 47171194880 )
309+ mock_show .assert_called_with ("dir bootflash:" , raw_text = True )
310+
311+ @mock .patch .object (NXOSDevice , "show" )
312+ def test_get_free_space_with_custom_filesystem (self , mock_show ):
313+ """Test _get_free_space uses custom file system when provided."""
314+ mock_show .return_value = """Directory of disk0:/
315+ 1000000 bytes used
316+ 2000000 bytes free
317+ 3000000 bytes total
318+
319+ """
320+ result = self .device ._get_free_space ("disk0:" )
321+ self .assertEqual (result , 2000000 )
322+ mock_show .assert_called_with ("dir disk0:" , raw_text = True )
323+
324+ @mock .patch .object (NXOSDevice , "show" )
325+ def test_get_free_space_raises_on_parse_error (self , mock_show ):
326+ """Test _get_free_space raises CommandError when output can't be parsed."""
327+ mock_show .return_value = "Directory of bootflash:/\n No free space info here\n "
328+ with self .assertRaises (CommandError ):
329+ self .device ._get_free_space ()
330+
281331 def test_check_file_exists_true (self ):
282332 self .device .native_ssh .send_command .return_value = "12345 bootflash:/nxos.bin"
283333 result = self .device .check_file_exists ("nxos.bin" , file_system = "bootflash:" )
@@ -362,6 +412,23 @@ def test_remote_file_copy_transfer_fails_verification(self):
362412 with self .assertRaises (FileTransferError ):
363413 self .device .remote_file_copy (src , file_system = "bootflash:" )
364414
415+ @mock .patch .object (NXOSDevice , "verify_file" , return_value = False )
416+ @mock .patch .object (NXOSDevice , "_get_free_space" , return_value = 1024 ) # Only 1KB free
417+ def test_remote_file_copy_raises_not_enough_free_space (self , mock_get_free_space , mock_verify ):
418+ """Test remote_file_copy raises NotEnoughFreeSpaceError when insufficient space."""
419+ src = FileCopyModel (
420+ download_url = "http://example.com/nxos.bin" ,
421+ checksum = "abc123" ,
422+ file_name = "nxos.bin" ,
423+ hashing_algorithm = "md5" ,
424+ timeout = 30 ,
425+ file_size = 1024 * 1024 , # Trying to copy 1MB
426+ )
427+ self .device .native_ssh .find_prompt .return_value = "host#"
428+ with self .assertRaises (NotEnoughFreeSpaceError ):
429+ self .device .remote_file_copy (src , file_system = "bootflash:" )
430+ self .device .native_ssh .send_command .assert_not_called ()
431+
365432 def test_remote_file_copy_invalid_scheme (self ):
366433 src = FileCopyModel (
367434 download_url = "smtp://example.com/nxos.bin" ,
0 commit comments