Skip to content

Commit 8ebc56a

Browse files
authored
[sonic_installer]: Improve exception handling: introduce notes. (#3029)
Signed-off-by: Nazarii Hnydyn <[email protected]>
1 parent 3610ce9 commit 8ebc56a

File tree

3 files changed

+34
-3
lines changed

3 files changed

+34
-3
lines changed

sonic_installer/common.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,15 @@ def run_command_or_raise(argv, raise_exception=True, capture=True):
4646

4747
stdout = subprocess.PIPE if capture else None
4848
proc = subprocess.Popen(argv, text=True, stdout=stdout)
49-
out, _ = proc.communicate()
49+
out, err = proc.communicate()
5050

5151
if proc.returncode != 0 and raise_exception:
52-
raise SonicRuntimeException("Failed to run command '{0}'".format(argv))
52+
sre = SonicRuntimeException("Failed to run command '{0}'".format(argv))
53+
if out:
54+
sre.add_note("\nSTDOUT:\n{}".format(out.rstrip("\n")))
55+
if err:
56+
sre.add_note("\nSTDERR:\n{}".format(err.rstrip("\n")))
57+
raise sre
5358

5459
if out is not None:
5560
out = out.rstrip("\n")

sonic_installer/exception.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,15 @@
55
class SonicRuntimeException(Exception):
66
"""SONiC Runtime Excpetion class used to report SONiC related errors
77
"""
8-
pass
8+
def __init__(self, *args, **kwargs):
9+
super().__init__(*args, **kwargs)
10+
self.notes = []
11+
12+
def __str__(self):
13+
msg = super().__str__()
14+
if self.notes:
15+
msg += "\n" + "\n".join(self.notes)
16+
return msg
17+
18+
def add_note(self, note):
19+
self.notes.append(note)

tests/test_sonic_installer.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,3 +129,18 @@ def test_set_fips(get_bootloader):
129129
mock_bootloader.get_fips = Mock(return_value=True)
130130
result = runner.invoke(sonic_installer.commands["get-fips"], [next_image])
131131
assert "FIPS is enabled" in result.output
132+
133+
@patch("sonic_installer.common.subprocess.Popen")
134+
def test_runtime_exception(mock_popen):
135+
""" This test covers the "sonic-installer" exception handling. """
136+
137+
mock_popen.return_value.returncode = 1
138+
mock_popen.return_value.communicate.return_value = ('Running', 'Failed')
139+
140+
with pytest.raises(sonic_installer_common.SonicRuntimeException) as sre:
141+
sonic_installer_common.run_command_or_raise(["test.sh"])
142+
143+
assert '\nSTDOUT:\nRunning' in sre.value.notes, "Invalid STDOUT"
144+
assert '\nSTDERR:\nFailed' in sre.value.notes, "Invalid STDERR"
145+
146+
assert all(v in str(sre.value) for v in ['test.sh', 'Running', 'Failed']), "Invalid message"

0 commit comments

Comments
 (0)