summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKota Tsuyuzaki <tsuyuzaki.kota@lab.ntt.co.jp>2015-04-01 21:26:06 -0700
committerKota Tsuyuzaki <tsuyuzaki.kota@lab.ntt.co.jp>2015-04-02 00:17:35 -0700
commit132683ba8cf644e5d10c8d2818ae3556c2062958 (patch)
tree1519379580eaf7f3b82952ab70c468559080ca58
parent9b2ed408c1ff526799d72350cf6c953f105f2b2f (diff)
downloadpyeclib-132683ba8cf644e5d10c8d2818ae3556c2062958.tar.gz
Fix ECDriverError.__str__
If ECDriverError is initialized with a non-string argument then its str method returns non-string, it will return a confusable message for users. This patch fixes ECDriverError to set a string message when the argument doesn't have str method which return a string.
-rw-r--r--pyeclib/ec_iface.py8
-rw-r--r--test/test_pyeclib_api.py44
2 files changed, 49 insertions, 3 deletions
diff --git a/pyeclib/ec_iface.py b/pyeclib/ec_iface.py
index fbe82f0..4785d18 100644
--- a/pyeclib/ec_iface.py
+++ b/pyeclib/ec_iface.py
@@ -112,8 +112,12 @@ class PyECLib_FRAGHDRCHKSUM_Types(PyECLibEnum):
# Generic ECDriverException
class ECDriverError(Exception):
- def __init__(self, error_str):
- self.error_str = error_str
+ def __init__(self, error):
+ try:
+ self.error_str = str(error)
+ except TypeError:
+ self.error_str = 'Error retrieving the error message from %s' \
+ % error.__class__.__name__
def __str__(self):
return self.error_str
diff --git a/test/test_pyeclib_api.py b/test/test_pyeclib_api.py
index b00abc0..2e7cdaf 100644
--- a/test/test_pyeclib_api.py
+++ b/test/test_pyeclib_api.py
@@ -26,12 +26,14 @@ from string import ascii_letters, ascii_uppercase, digits
import sys
import tempfile
import unittest
+import mock
from pyeclib.ec_iface import ECDriverError
from pyeclib.ec_iface import ECDriver, VALID_EC_TYPES, ECDriverError, \
PyECLib_EC_Types
from test_pyeclib_c import _available_backends
import pyeclib_c
+from pyeclib_c import error as PyECLibError
if sys.version < '3':
def b2i(b):
@@ -207,7 +209,7 @@ class TestPyECLibDriver(unittest.TestCase):
def test_get_metadata_formatted(self):
pyeclib_driver = ECDriver(k=12, m=2, ec_type="jerasure_rs_vand", chksum_type="inline_crc32")
-
+
filesize = 1024 * 1024 * 3
file_str = ''.join(random.choice(ascii_letters) for i in range(filesize))
file_bytes = file_str.encode('utf-8')
@@ -547,5 +549,45 @@ class TestPyECLibDriver(unittest.TestCase):
self.assertTrue(
pyeclib_drivers[0].min_parity_fragments_needed() == 1)
+ def test_ECDriver_error_handling(self):
+ driver = ECDriver(k=3, m=1, ec_type="jerasure_rs_vand")
+
+ class MockPyECLibError(PyECLibError):
+ def __str__(self):
+ return mock.MagicMock()
+
+ with mock.patch('pyeclib_c.decode', side_effect=MockPyECLibError()):
+ with self.assertRaises(ECDriverError) as cm:
+ driver.decode([' ' for x in xrange(4)])
+ exception = cm.exception
+ expected = 'Error retrieving the error message from MockPyECLibError'
+ self.assertEquals(expected, str(exception))
+
+ def test_ECDriverError_init(self):
+
+ class mock_class(object):
+ def __init__(self, return_str):
+ self.return_str = return_str
+
+ def __str__(self):
+ if self.return_str:
+ return 'message'
+ else:
+ return mock.MagicMock()
+
+ # init with str
+ error = ECDriverError('message')
+ self.assertEquals('message', str(error))
+
+ # init with instance with valid __str__
+ error = ECDriverError(mock_class(True))
+ self.assertEquals('message', str(error))
+
+ # init with instance with invalid __str__
+ error = ECDriverError(mock_class(False))
+ self.assertEquals('Error retrieving the error message from mock_class',
+ str(error))
+
+
if __name__ == '__main__':
unittest.main()