Skip to content

Commit 3cf3fd1

Browse files
committed
Update NXOS unittests
1 parent 93a3f42 commit 3cf3fd1

2 files changed

Lines changed: 132 additions & 3 deletions

File tree

changes/367.added

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
Added remote file copy feature to Cisco NXOS devices.
1+
Added remote file copy feature to Cisco NXOS devices.
2+
Added unittests for remote file copy for Cisco NXOS devices.

tests/unit/test_devices/test_nxos_device.py

Lines changed: 130 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,14 @@
55

66
from pyntc.devices.base_device import RollbackError
77
from pyntc.devices.nxos_device import NXOSDevice
8-
from pyntc.errors import CommandError, CommandListError, FileTransferError, NTCFileNotFoundError
8+
from pyntc.errors import (
9+
CommandError,
10+
CommandListError,
11+
FileSystemNotFoundError,
12+
FileTransferError,
13+
NTCFileNotFoundError,
14+
)
15+
from pyntc.utils.models import FileCopyModel
916

1017
from .device_mocks.nxos import show, show_list
1118

@@ -26,15 +33,19 @@
2633

2734

2835
class TestNXOSDevice(unittest.TestCase):
36+
@mock.patch("pyntc.devices.nxos_device.ConnectHandler", create=True)
2937
@mock.patch("pyntc.devices.nxos_device.NXOSNative", autospec=True)
3038
@mock.patch("pynxos.device.Device.facts", new_callable=mock.PropertyMock)
31-
def setUp(self, mock_device, mock_facts):
39+
def setUp(self, mock_facts, mock_device, mock_connect_handler):
40+
self.mock_native_ssh = mock_connect_handler.return_value
3241
self.device = NXOSDevice("host", "user", "pass")
3342
mock_device.show.side_effect = show
3443
mock_device.show_list.side_effect = show_list
3544
mock_facts.return_value = DEVICE_FACTS
3645

3746
self.device.native = mock_device
47+
self.device.native_ssh = self.mock_native_ssh
48+
self.device.native._facts = {}
3849
type(self.device.native).facts = mock_facts.return_value
3950

4051
def test_config(self):
@@ -256,6 +267,123 @@ def test_refresh(self):
256267
self.assertIsNone(self.device._uptime)
257268
self.assertFalse(hasattr(self.device.native, "_facts"))
258269

270+
@mock.patch.object(NXOSDevice, "show", return_value="bootflash:")
271+
def test_get_file_system(self, mock_show):
272+
self.assertEqual(self.device._get_file_system(), "bootflash:")
273+
mock_show.assert_called_with("dir", raw_text=True)
274+
275+
@mock.patch.object(NXOSDevice, "show", return_value="no filesystems here")
276+
def test_get_file_system_not_found(self, mock_show):
277+
with self.assertRaises(FileSystemNotFoundError):
278+
self.device._get_file_system()
279+
mock_show.assert_called_with("dir", raw_text=True)
280+
281+
def test_check_file_exists_true(self):
282+
self.device.native_ssh.send_command.return_value = "12345 bootflash:/nxos.bin"
283+
result = self.device.check_file_exists("nxos.bin", file_system="bootflash:")
284+
self.assertTrue(result)
285+
self.device.native_ssh.send_command.assert_called_with("dir bootflash:/nxos.bin", read_timeout=30)
286+
287+
def test_check_file_exists_false(self):
288+
self.device.native_ssh.send_command.return_value = "No such file or directory"
289+
result = self.device.check_file_exists("nxos.bin", file_system="bootflash:")
290+
self.assertFalse(result)
291+
self.device.native_ssh.send_command.assert_called_with("dir bootflash:/nxos.bin", read_timeout=30)
292+
293+
def test_check_file_exists_command_error(self):
294+
self.device.native_ssh.send_command.return_value = "some ambiguous output"
295+
with self.assertRaises(CommandError):
296+
self.device.check_file_exists("nxos.bin", file_system="bootflash:")
297+
298+
def test_get_remote_checksum(self):
299+
self.device.native_ssh.send_command.return_value = "abc123"
300+
result = self.device.get_remote_checksum("nxos.bin", hashing_algorithm="md5", file_system="bootflash:")
301+
self.assertEqual(result, "abc123")
302+
self.device.native_ssh.send_command.assert_called_with("show file bootflash:/nxos.bin md5sum", read_timeout=30)
303+
304+
def test_get_remote_checksum_invalid_algorithm(self):
305+
with self.assertRaises(ValueError):
306+
self.device.get_remote_checksum("nxos.bin", hashing_algorithm="sha1", file_system="bootflash:")
307+
308+
def test_verify_file_true(self):
309+
with (
310+
mock.patch.object(NXOSDevice, "check_file_exists", return_value=True),
311+
mock.patch.object(NXOSDevice, "get_remote_checksum", return_value="abc123"),
312+
):
313+
result = self.device.verify_file("abc123", "nxos.bin", file_system="bootflash:")
314+
self.assertTrue(result)
315+
316+
def test_verify_file_false(self):
317+
with (
318+
mock.patch.object(NXOSDevice, "check_file_exists", return_value=True),
319+
mock.patch.object(NXOSDevice, "get_remote_checksum", return_value="different"),
320+
):
321+
result = self.device.verify_file("abc123", "nxos.bin", file_system="bootflash:")
322+
self.assertFalse(result)
323+
324+
def test_remote_file_copy_existing_verified_file(self):
325+
src = FileCopyModel(
326+
download_url="http://example.com/nxos.bin",
327+
checksum="abc123",
328+
file_name="nxos.bin",
329+
hashing_algorithm="md5",
330+
timeout=30,
331+
)
332+
with mock.patch.object(NXOSDevice, "verify_file", return_value=True) as verify_mock:
333+
self.device.remote_file_copy(src, file_system="bootflash:")
334+
verify_mock.assert_called_once_with("abc123", "nxos.bin", hashing_algorithm="md5", file_system="bootflash:")
335+
self.device.native_ssh.send_command.assert_not_called()
336+
337+
def test_remote_file_copy_transfer_success(self):
338+
src = FileCopyModel(
339+
download_url="http://example.com/nxos.bin",
340+
checksum="abc123",
341+
file_name="nxos.bin",
342+
hashing_algorithm="md5",
343+
timeout=30,
344+
)
345+
self.device.native_ssh.find_prompt.return_value = "host#"
346+
self.device.native_ssh.send_command.return_value = "Copy complete"
347+
with mock.patch.object(NXOSDevice, "verify_file", side_effect=[False, True]):
348+
self.device.remote_file_copy(src, file_system="bootflash:")
349+
self.device.native_ssh.send_command.assert_called_once()
350+
351+
def test_remote_file_copy_transfer_fails_verification(self):
352+
src = FileCopyModel(
353+
download_url="http://example.com/nxos.bin",
354+
checksum="abc123",
355+
file_name="nxos.bin",
356+
hashing_algorithm="md5",
357+
timeout=30,
358+
)
359+
self.device.native_ssh.find_prompt.return_value = "host#"
360+
self.device.native_ssh.send_command.return_value = "Copy complete"
361+
with mock.patch.object(NXOSDevice, "verify_file", side_effect=[False, False]):
362+
with self.assertRaises(FileTransferError):
363+
self.device.remote_file_copy(src, file_system="bootflash:")
364+
365+
def test_remote_file_copy_invalid_scheme(self):
366+
src = FileCopyModel(
367+
download_url="smtp://example.com/nxos.bin",
368+
checksum="abc123",
369+
file_name="nxos.bin",
370+
hashing_algorithm="md5",
371+
timeout=30,
372+
)
373+
with self.assertRaises(ValueError):
374+
self.device.remote_file_copy(src, file_system="bootflash:")
375+
376+
def test_remote_file_copy_query_string_not_supported(self):
377+
src = FileCopyModel(
378+
download_url="https://example.com/nxos.bin?token=foo",
379+
checksum="abc123",
380+
file_name="nxos.bin",
381+
hashing_algorithm="md5",
382+
timeout=30,
383+
)
384+
with self.assertRaises(ValueError):
385+
self.device.remote_file_copy(src, file_system="bootflash:")
386+
259387

260388
if __name__ == "__main__":
261389
unittest.main()

0 commit comments

Comments
 (0)