diff --git a/neutron/agent/linux/utils.py b/neutron/agent/linux/utils.py index c5249e499a6..5e86cf516e0 100644 --- a/neutron/agent/linux/utils.py +++ b/neutron/agent/linux/utils.py @@ -45,6 +45,12 @@ from neutron import wsgi LOG = logging.getLogger(__name__) +class ProcessExecutionError(RuntimeError): + def __init__(self, message, returncode): + super(ProcessExecutionError, self).__init__(message) + self.returncode = returncode + + class RootwrapDaemonHelper(object): __client = None __lock = threading.Lock() @@ -136,7 +142,7 @@ def execute(cmd, process_input=None, addl_env=None, if log_fail_as_error: LOG.error(msg) if check_exit_code: - raise RuntimeError(msg) + raise ProcessExecutionError(msg, returncode=returncode) else: LOG.debug("Exit code: %d", returncode) @@ -169,11 +175,11 @@ def find_child_pids(pid): try: raw_pids = execute(['ps', '--ppid', pid, '-o', 'pid='], log_fail_as_error=False) - except RuntimeError as e: + except ProcessExecutionError as e: # Unexpected errors are the responsibility of the caller with excutils.save_and_reraise_exception() as ctxt: # Exception has already been logged by execute - no_children_found = 'Exit code: 1' in str(e) + no_children_found = e.returncode == 1 if no_children_found: ctxt.reraise = False return [] diff --git a/neutron/tests/unit/agent/linux/test_utils.py b/neutron/tests/unit/agent/linux/test_utils.py index e78e09ad5e8..9244ab05bcf 100644 --- a/neutron/tests/unit/agent/linux/test_utils.py +++ b/neutron/tests/unit/agent/linux/test_utils.py @@ -122,7 +122,7 @@ class AgentUtilsExecuteTest(base.BaseTestCase): self.mock_popen.return_value = ('', '') self.process.return_value.returncode = 1 with mock.patch.object(utils, 'LOG') as log: - self.assertRaises(RuntimeError, utils.execute, + self.assertRaises(utils.ProcessExecutionError, utils.execute, ['ls'], log_fail_as_error=False) self.assertFalse(log.error.called) @@ -185,7 +185,8 @@ class TestFindChildPids(base.BaseTestCase): def test_returns_empty_list_for_exit_code_1(self): with mock.patch.object(utils, 'execute', - side_effect=RuntimeError('Exit code: 1')): + side_effect=utils.ProcessExecutionError( + '', returncode=1)): self.assertEqual([], utils.find_child_pids(-1)) def test_returns_empty_list_for_no_output(self):