diff options
-rw-r--r-- | paramiko/ssh_exception.py | 10 | ||||
-rw-r--r-- | sites/www/changelog.rst | 5 | ||||
-rwxr-xr-x | test.py | 4 | ||||
-rw-r--r-- | tests/test_ssh_exception.py | 31 |
4 files changed, 47 insertions, 3 deletions
diff --git a/paramiko/ssh_exception.py b/paramiko/ssh_exception.py index 016a411e..ed36a952 100644 --- a/paramiko/ssh_exception.py +++ b/paramiko/ssh_exception.py @@ -164,12 +164,18 @@ class NoValidConnectionsError(socket.error): :param dict errors: The errors dict to store, as described by class docstring. """ - addrs = errors.keys() + addrs = sorted(errors.keys()) body = ', '.join([x[0] for x in addrs[:-1]]) tail = addrs[-1][0] - msg = "Unable to connect to port {0} on {1} or {2}" + if body: + msg = "Unable to connect to port {0} on {1} or {2}" + else: + msg = "Unable to connect to port {0} on {2}" super(NoValidConnectionsError, self).__init__( None, # stand-in for errno msg.format(addrs[0][1], body, tail) ) self.errors = errors + + def __reduce__(self): + return (self.__class__, (self.errors, )) diff --git a/sites/www/changelog.rst b/sites/www/changelog.rst index 9ec970c7..340379fc 100644 --- a/sites/www/changelog.rst +++ b/sites/www/changelog.rst @@ -2,6 +2,11 @@ Changelog ========= +* :bug:`617` (aka `fabric/fabric#1429 + <https://github.com/fabric/fabric/issues/1429>`_; via :issue:`679`; related: + :issue:`678`, :issue:`685`) Fix up + `~paramiko.ssh_exception.NoValidConnectionsError` so it pickles correctly. + Thanks to Rebecca Schlussel for the report & Marius Gedminas for the patch. * :bug:`613` (via :issue:`619`) Update to ``jaraco.windows`` 3.4.1 to fix some errors related to ``ctypes`` on Windows platforms. Credit to Jason R. Coombs. * :support:`621 backported` Annotate some public attributes on @@ -43,8 +43,9 @@ from tests.test_kex import KexTest from tests.test_packetizer import PacketizerTest from tests.test_auth import AuthTest from tests.test_transport import TransportTest +from tests.test_ssh_exception import NoValidConnectionsErrorTest from tests.test_client import SSHClientTest -from test_client import SSHClientTest +from test_client import SSHClientTest # XXX why shadow the above import? from test_gssapi import GSSAPITest from test_ssh_gss import GSSAuthTest from test_kex_gss import GSSKexTest @@ -156,6 +157,7 @@ def main(): if options.use_transport: suite.addTest(unittest.makeSuite(AuthTest)) suite.addTest(unittest.makeSuite(TransportTest)) + suite.addTest(unittest.makeSuite(NoValidConnectionsErrorTest)) suite.addTest(unittest.makeSuite(SSHClientTest)) if options.use_sftp: suite.addTest(unittest.makeSuite(SFTPTest)) diff --git a/tests/test_ssh_exception.py b/tests/test_ssh_exception.py new file mode 100644 index 00000000..18f2a97d --- /dev/null +++ b/tests/test_ssh_exception.py @@ -0,0 +1,31 @@ +import pickle +import unittest + +from paramiko.ssh_exception import NoValidConnectionsError + + +class NoValidConnectionsErrorTest (unittest.TestCase): + + def test_pickling(self): + # Regression test for https://github.com/paramiko/paramiko/issues/617 + exc = NoValidConnectionsError({('127.0.0.1', '22'): Exception()}) + new_exc = pickle.loads(pickle.dumps(exc)) + self.assertEqual(type(exc), type(new_exc)) + self.assertEqual(str(exc), str(new_exc)) + self.assertEqual(exc.args, new_exc.args) + + def test_error_message_for_single_host(self): + exc = NoValidConnectionsError({('127.0.0.1', '22'): Exception()}) + assert "Unable to connect to port 22 on 127.0.0.1" in str(exc) + + def test_error_message_for_two_hosts(self): + exc = NoValidConnectionsError({('127.0.0.1', '22'): Exception(), + ('::1', '22'): Exception()}) + assert "Unable to connect to port 22 on 127.0.0.1 or ::1" in str(exc) + + def test_error_message_for_multiple_hosts(self): + exc = NoValidConnectionsError({('127.0.0.1', '22'): Exception(), + ('::1', '22'): Exception(), + ('10.0.0.42', '22'): Exception()}) + exp = "Unable to connect to port 22 on 10.0.0.42, 127.0.0.1 or ::1" + assert exp in str(exc) |