Skip to content

Commit 47f6feb

Browse files
authored
check sonic-installer message and return proper error code for when image doesn't exist. (#210)
1 parent 1fe9a76 commit 47f6feb

File tree

2 files changed

+39
-2
lines changed

2 files changed

+39
-2
lines changed

host_modules/image_service.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,9 @@ def set_next_boot(self, image):
178178
if result.returncode:
179179
logger.error("Failed to set next boot image: {}".format(result.stderr.decode()))
180180
msg = result.stderr.decode()
181+
# sonic-installer might not return a proper error code, so we need to check the message.
182+
if "not" in msg.lower() and ("exist" in msg.lower() or "found" in msg.lower()):
183+
return errno.ENOENT, msg
181184
return result.returncode, msg
182185

183186

tests/host_modules/image_service_test.py

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import stat
66
import pytest
77
import json
8+
import errno
89
from unittest import mock
910
from host_modules.image_service import ImageService
1011

@@ -608,7 +609,7 @@ def test_image_set_next_boot_fail_not_exists(self, mock_run, MockInit, MockBusNa
608609
image_service = ImageService(mod_name="image_service")
609610
image = "nonexistent_image"
610611
mock_result = mock.Mock()
611-
mock_result.returncode = 1
612+
mock_result.returncode = errno.ENOENT
612613
mock_result.stderr = b"Error: Image does not exist"
613614
mock_run.return_value = mock_result
614615

@@ -617,7 +618,40 @@ def test_image_set_next_boot_fail_not_exists(self, mock_run, MockInit, MockBusNa
617618

618619
# Assert
619620
assert rc != 0, "wrong return value"
620-
assert "Error: Image does not exist" in msg, "message should contain 'Error: Image does not exist'"
621+
assert (
622+
"not" in msg.lower() and ("exist" in msg.lower() or "found" in msg.lower())
623+
), "message should contain 'not' and 'exist' or 'found'"
624+
mock_run.assert_called_once_with(
625+
["/usr/local/bin/sonic-installer", "set-next-boot", image],
626+
stdout=subprocess.PIPE,
627+
stderr=subprocess.PIPE,
628+
)
629+
630+
@mock.patch("dbus.SystemBus")
631+
@mock.patch("dbus.service.BusName")
632+
@mock.patch("dbus.service.Object.__init__")
633+
@mock.patch("subprocess.run")
634+
def test_image_set_next_boot_fail_not_exists_generic_rc(self, mock_run, MockInit, MockBusName, MockSystemBus):
635+
"""
636+
Test that the `set_next_boot` method fails when the image does not exist, and sonic-installer returns a generic error code
637+
instead of errno.ENOENT.
638+
"""
639+
# Arrange
640+
image_service = ImageService(mod_name="image_service")
641+
image = "nonexistent_image"
642+
mock_result = mock.Mock()
643+
mock_result.returncode = 1 # returns generic error code
644+
mock_result.stderr = b"Error: Image does not exist"
645+
mock_run.return_value = mock_result
646+
647+
# Act
648+
rc, msg = image_service.set_next_boot(image)
649+
650+
# Assert
651+
assert rc == errno.ENOENT, "wrong return value"
652+
assert (
653+
"not" in msg.lower() and ("exist" in msg.lower() or "found" in msg.lower())
654+
), "message should contain 'not' and 'exist' or 'found'"
621655
mock_run.assert_called_once_with(
622656
["/usr/local/bin/sonic-installer", "set-next-boot", image],
623657
stdout=subprocess.PIPE,

0 commit comments

Comments
 (0)