diff options
author | Angus Lees <gus@inodes.org> | 2016-02-19 14:28:58 +1100 |
---|---|---|
committer | Angus Lees <gus@inodes.org> | 2016-02-19 15:52:23 +1100 |
commit | 9d289463957b74bed29e30f93326ee1e664d2873 (patch) | |
tree | 4409b381b8bd549cb3fb10a03fb3c9e6bf4758ab /oslo_concurrency | |
parent | fa04ee7df3493291ea66d05fa093db9f88f52048 (diff) | |
download | oslo-concurrency-9d289463957b74bed29e30f93326ee1e664d2873.tar.gz |
Make ProcessExecutionError picklable
Serialising/deserialising exceptions in python follows the protocol
defined by pickle. It relies on the base Exception.__init__ setting
self.args, and later resurrects exceptions with class(*args).
This change rewrites processutils.ProcessExecutionError so it survives a
pickle.dumps/loads round-trip.
Change-Id: I9b8d104f60df868be7b808c72c932d08f1752777
Diffstat (limited to 'oslo_concurrency')
-rw-r--r-- | oslo_concurrency/processutils.py | 15 | ||||
-rw-r--r-- | oslo_concurrency/tests/unit/test_processutils.py | 16 |
2 files changed, 27 insertions, 4 deletions
diff --git a/oslo_concurrency/processutils.py b/oslo_concurrency/processutils.py index 436922a..b74e5f2 100644 --- a/oslo_concurrency/processutils.py +++ b/oslo_concurrency/processutils.py @@ -63,26 +63,33 @@ class UnknownArgumentError(Exception): class ProcessExecutionError(Exception): def __init__(self, stdout=None, stderr=None, exit_code=None, cmd=None, description=None): + super(ProcessExecutionError, self).__init__( + stdout, stderr, exit_code, cmd, description) self.exit_code = exit_code self.stderr = stderr self.stdout = stdout self.cmd = cmd self.description = description + def __str__(self): + description = self.description if description is None: description = _("Unexpected error while running command.") + + exit_code = self.exit_code if exit_code is None: exit_code = '-' + message = _('%(description)s\n' 'Command: %(cmd)s\n' 'Exit code: %(exit_code)s\n' 'Stdout: %(stdout)r\n' 'Stderr: %(stderr)r') % {'description': description, - 'cmd': cmd, + 'cmd': self.cmd, 'exit_code': exit_code, - 'stdout': stdout, - 'stderr': stderr} - super(ProcessExecutionError, self).__init__(message) + 'stdout': self.stdout, + 'stderr': self.stderr} + return message class NoRootWrapSpecified(Exception): diff --git a/oslo_concurrency/tests/unit/test_processutils.py b/oslo_concurrency/tests/unit/test_processutils.py index b868cb5..0fd8045 100644 --- a/oslo_concurrency/tests/unit/test_processutils.py +++ b/oslo_concurrency/tests/unit/test_processutils.py @@ -19,6 +19,7 @@ import errno import logging import multiprocessing import os +import pickle import resource import stat import subprocess @@ -467,6 +468,21 @@ grep foo def test_binary_undecodable_bytes_error(self): self.check_undecodable_bytes_error(True) + def test_picklable(self): + exc = processutils.ProcessExecutionError( + stdout='my stdout', stderr='my stderr', + exit_code=42, cmd='my cmd', + description='my description') + exc_message = str(exc) + + exc = pickle.loads(pickle.dumps(exc)) + self.assertEqual('my stdout', exc.stdout) + self.assertEqual('my stderr', exc.stderr) + self.assertEqual(42, exc.exit_code) + self.assertEqual('my cmd', exc.cmd) + self.assertEqual('my description', exc.description) + self.assertEqual(exc_message, str(exc)) + class ProcessExecutionErrorLoggingTest(test_base.BaseTestCase): def setUp(self): |