From 9349b3e0f5c8d981706929ad532fea1a867a63dc Mon Sep 17 00:00:00 2001 From: Antonio Balmaseda Date: Mon, 3 Feb 2025 12:14:16 +0100 Subject: [PATCH 1/5] adding test to cover the failed scenario --- tests/unit/test_devices/test_ios_device.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tests/unit/test_devices/test_ios_device.py b/tests/unit/test_devices/test_ios_device.py index a2b53b2d..e9bfd15c 100644 --- a/tests/unit/test_devices/test_ios_device.py +++ b/tests/unit/test_devices/test_ios_device.py @@ -389,6 +389,21 @@ def test_install_os_error(self, mock_wait, mock_reboot, mock_set_boot, mock_imag mock_raw_version_data.return_value = DEVICE_FACTS self.assertRaises(ios_module.OSInstallError, self.device.install_os, BOOT_IMAGE) + @mock.patch.object(IOSDevice, "os_version", new_callable=mock.PropertyMock) + @mock.patch.object(IOSDevice, "_image_booted", side_effect=[False, True]) + @mock.patch.object(IOSDevice, "set_boot_options") + @mock.patch.object(IOSDevice, "show") + @mock.patch.object(IOSDevice, "reboot") + @mock.patch.object(IOSDevice, "_wait_for_device_reboot") + def test_install_os_not_enough_space( + self, mock_wait, mock_reboot, mock_show, mock_set_boot, mock_image_booted, mock_os_version + ): + mock_os_version.return_value = "17.4.3" + mock_show.return_value = "FAILED: There is not enough free disk available to perform this operation on switch 1. At least 1276287 KB of free disk is required" + self.assertRaises(ios_module.OSInstallError, self.device.install_os(image_name=BOOT_IMAGE, install_mode=True)) + mock_wait.assert_not_called() + mock_reboot.assert_not_called() + if __name__ == "__main__": unittest.main() From 463e78810bc7db57f9469df9ded160f395fc585b Mon Sep 17 00:00:00 2001 From: Antonio Balmaseda Date: Mon, 3 Feb 2025 12:22:35 +0100 Subject: [PATCH 2/5] fixing test --- tests/unit/test_devices/test_ios_device.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/unit/test_devices/test_ios_device.py b/tests/unit/test_devices/test_ios_device.py index e9bfd15c..2a388f8a 100644 --- a/tests/unit/test_devices/test_ios_device.py +++ b/tests/unit/test_devices/test_ios_device.py @@ -395,12 +395,14 @@ def test_install_os_error(self, mock_wait, mock_reboot, mock_set_boot, mock_imag @mock.patch.object(IOSDevice, "show") @mock.patch.object(IOSDevice, "reboot") @mock.patch.object(IOSDevice, "_wait_for_device_reboot") + @mock.patch.object(IOSDevice, "_raw_version_data") def test_install_os_not_enough_space( - self, mock_wait, mock_reboot, mock_show, mock_set_boot, mock_image_booted, mock_os_version + self, mock_raw_version_data, mock_wait, mock_reboot, mock_show, mock_set_boot, mock_image_booted, mock_os_version ): + mock_raw_version_data.return_value = DEVICE_FACTS mock_os_version.return_value = "17.4.3" mock_show.return_value = "FAILED: There is not enough free disk available to perform this operation on switch 1. At least 1276287 KB of free disk is required" - self.assertRaises(ios_module.OSInstallError, self.device.install_os(image_name=BOOT_IMAGE, install_mode=True)) + self.assertRaises(ios_module.OSInstallError, self.device.install_os, image_name=BOOT_IMAGE, install_mode=True) mock_wait.assert_not_called() mock_reboot.assert_not_called() From 88d4560c5ab3eaeefdbee4e904b2fbb3f2792ea7 Mon Sep 17 00:00:00 2001 From: Antonio Balmaseda Date: Mon, 3 Feb 2025 12:23:04 +0100 Subject: [PATCH 3/5] raising exception when install message has an error --- pyntc/devices/ios_device.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pyntc/devices/ios_device.py b/pyntc/devices/ios_device.py index d2f150fd..a6e8429c 100644 --- a/pyntc/devices/ios_device.py +++ b/pyntc/devices/ios_device.py @@ -718,7 +718,10 @@ def install_os(self, image_name, install_mode=False, read_timeout=2000, **vendor ) # Set a higher read_timeout and send it in try: - self.show(command, read_timeout=read_timeout) + install_message = self.show(command, read_timeout=read_timeout) + if install_message.startswith("FAILED:"): + log.error("Host %s: OS install error for image %s", self.host, image_name) + raise OSInstallError(hostname=self.hostname, desired_boot=image_name) except IOError: log.error("Host %s: IO error for image %s", self.host, image_name) except CommandError: From bbed09c6b511267fd205d057f44a45cd705b909e Mon Sep 17 00:00:00 2001 From: Antonio Balmaseda Date: Mon, 3 Feb 2025 14:11:38 +0100 Subject: [PATCH 4/5] linting --- tests/unit/test_devices/test_ios_device.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/tests/unit/test_devices/test_ios_device.py b/tests/unit/test_devices/test_ios_device.py index 2a388f8a..c2479026 100644 --- a/tests/unit/test_devices/test_ios_device.py +++ b/tests/unit/test_devices/test_ios_device.py @@ -397,7 +397,14 @@ def test_install_os_error(self, mock_wait, mock_reboot, mock_set_boot, mock_imag @mock.patch.object(IOSDevice, "_wait_for_device_reboot") @mock.patch.object(IOSDevice, "_raw_version_data") def test_install_os_not_enough_space( - self, mock_raw_version_data, mock_wait, mock_reboot, mock_show, mock_set_boot, mock_image_booted, mock_os_version + self, + mock_raw_version_data, + mock_wait, + mock_reboot, + mock_show, + mock_set_boot, + mock_image_booted, + mock_os_version, ): mock_raw_version_data.return_value = DEVICE_FACTS mock_os_version.return_value = "17.4.3" From f960f1b9f54edfb89bceb0fe4c973e03566debe4 Mon Sep 17 00:00:00 2001 From: Antonio Balmaseda Date: Mon, 3 Feb 2025 14:58:52 +0100 Subject: [PATCH 5/5] fixing unit test --- tests/unit/test_devices/test_ios_device.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/unit/test_devices/test_ios_device.py b/tests/unit/test_devices/test_ios_device.py index c2479026..beb7ea34 100644 --- a/tests/unit/test_devices/test_ios_device.py +++ b/tests/unit/test_devices/test_ios_device.py @@ -1286,6 +1286,7 @@ def test_install_os_install_mode_with_retries( mock_has_reload_happened_recently.side_effect = [False, False, True] mock_image_booted.side_effect = [False, True] mock_sleep.return_value = None + mock_show.return_value = "show must go on" # Call the install os function actual = ios_device.install_os(image_name, install_mode=True)