summaryrefslogtreecommitdiffhomepage
path: root/tests/test_client.py
diff options
context:
space:
mode:
authorJeff Forcier <jeff@bitprophet.org>2016-11-30 20:02:20 -0800
committerJeff Forcier <jeff@bitprophet.org>2016-11-30 20:02:20 -0800
commit9aec0c6300686e571fab5405c52876e6399f92e9 (patch)
tree8521aae70c6ebe889b92cbb9db69fd632f0fed08 /tests/test_client.py
parent2a568863bb462fbae50fdd4795bf4d3e05e101bb (diff)
parent7366f965546c015c3f9e9dd1ccb8f0b7b8758dae (diff)
Merge branch 'master' into 398-int
Diffstat (limited to 'tests/test_client.py')
-rw-r--r--tests/test_client.py99
1 files changed, 62 insertions, 37 deletions
diff --git a/tests/test_client.py b/tests/test_client.py
index 0022a4d9..32d9ac60 100644
--- a/tests/test_client.py
+++ b/tests/test_client.py
@@ -22,6 +22,8 @@ Some unit tests for SSHClient.
from __future__ import with_statement
+import gc
+import platform
import socket
from tempfile import mkstemp
import threading
@@ -31,8 +33,9 @@ import warnings
import os
import time
from tests.util import test_path
+
import paramiko
-from paramiko.common import PY2, b
+from paramiko.common import PY2
from paramiko.ssh_exception import SSHException
@@ -75,7 +78,7 @@ class NullServer (paramiko.ServerInterface):
return paramiko.OPEN_SUCCEEDED
def check_channel_exec_request(self, channel, command):
- if command != 'yes':
+ if command != b'yes':
return False
return True
@@ -97,6 +100,12 @@ class SSHClientTest (unittest.TestCase):
self.sockl.bind(('localhost', 0))
self.sockl.listen(1)
self.addr, self.port = self.sockl.getsockname()
+ self.connect_kwargs = dict(
+ hostname=self.addr,
+ port=self.port,
+ username='slowdive',
+ look_for_keys=False,
+ )
self.event = threading.Event()
def tearDown(self):
@@ -134,11 +143,11 @@ class SSHClientTest (unittest.TestCase):
self.tc.get_host_keys().add('[%s]:%d' % (self.addr, self.port), 'ssh-rsa', public_host_key)
# Actual connection
- self.tc.connect(self.addr, self.port, username='slowdive', **kwargs)
+ self.tc.connect(**dict(self.connect_kwargs, **kwargs))
# Authentication successful?
self.event.wait(1.0)
- self.assertTrue(self.event.isSet())
+ self.assertTrue(self.event.is_set())
self.assertTrue(self.ts.is_active())
self.assertEqual('slowdive', self.ts.get_username())
self.assertEqual(True, self.ts.is_authenticated())
@@ -183,7 +192,7 @@ class SSHClientTest (unittest.TestCase):
"""
verify that SSHClient works with an ECDSA key.
"""
- self._test_connection(key_filename=test_path('test_ecdsa.key'))
+ self._test_connection(key_filename=test_path('test_ecdsa_256.key'))
def test_3_multiple_key_files(self):
"""
@@ -200,15 +209,21 @@ class SSHClientTest (unittest.TestCase):
for attempt, accept in (
(['rsa', 'dss'], ['dss']), # Original test #3
(['dss', 'rsa'], ['dss']), # Ordering matters sometimes, sadly
- (['dss', 'rsa', 'ecdsa'], ['dss']), # Try ECDSA but fail
- (['rsa', 'ecdsa'], ['ecdsa']), # ECDSA success
+ (['dss', 'rsa', 'ecdsa_256'], ['dss']), # Try ECDSA but fail
+ (['rsa', 'ecdsa_256'], ['ecdsa']), # ECDSA success
):
- self._test_connection(
- key_filename=[
- test_path('test_{0}.key'.format(x)) for x in attempt
- ],
- allowed_keys=[types_[x] for x in accept],
- )
+ try:
+ self._test_connection(
+ key_filename=[
+ test_path('test_{0}.key'.format(x)) for x in attempt
+ ],
+ allowed_keys=[types_[x] for x in accept],
+ )
+ finally:
+ # Clean up to avoid occasional gc-related deadlocks.
+ # TODO: use nose test generators after nose port
+ self.tearDown()
+ self.setUp()
def test_multiple_key_files_failure(self):
"""
@@ -233,10 +248,10 @@ class SSHClientTest (unittest.TestCase):
self.tc = paramiko.SSHClient()
self.tc.set_missing_host_key_policy(paramiko.AutoAddPolicy())
self.assertEqual(0, len(self.tc.get_host_keys()))
- self.tc.connect(self.addr, self.port, username='slowdive', password='pygmalion')
+ self.tc.connect(password='pygmalion', **self.connect_kwargs)
self.event.wait(1.0)
- self.assertTrue(self.event.isSet())
+ self.assertTrue(self.event.is_set())
self.assertTrue(self.ts.is_active())
self.assertEqual('slowdive', self.ts.get_username())
self.assertEqual(True, self.ts.is_authenticated())
@@ -276,22 +291,21 @@ class SSHClientTest (unittest.TestCase):
transport's packetizer) is closed.
"""
# Unclear why this is borked on Py3, but it is, and does not seem worth
- # pursuing at the moment.
+ # pursuing at the moment. Skipped on PyPy because it fails on travis
+ # for unknown reasons, works fine locally.
# XXX: It's the release of the references to e.g packetizer that fails
# in py3...
- if not PY2:
+ if not PY2 or platform.python_implementation() == "PyPy":
return
threading.Thread(target=self._run).start()
- host_key = paramiko.RSAKey.from_private_key_file(test_path('test_rsa.key'))
- public_host_key = paramiko.RSAKey(data=host_key.asbytes())
self.tc = paramiko.SSHClient()
self.tc.set_missing_host_key_policy(paramiko.AutoAddPolicy())
self.assertEqual(0, len(self.tc.get_host_keys()))
- self.tc.connect(self.addr, self.port, username='slowdive', password='pygmalion')
+ self.tc.connect(**dict(self.connect_kwargs, password='pygmalion'))
self.event.wait(1.0)
- self.assertTrue(self.event.isSet())
+ self.assertTrue(self.event.is_set())
self.assertTrue(self.ts.is_active())
p = weakref.ref(self.tc._transport.packetizer)
@@ -299,14 +313,10 @@ class SSHClientTest (unittest.TestCase):
self.tc.close()
del self.tc
- # hrm, sometimes p isn't cleared right away. why is that?
- #st = time.time()
- #while (time.time() - st < 5.0) and (p() is not None):
- # time.sleep(0.1)
-
- # instead of dumbly waiting for the GC to collect, force a collection
- # to see whether the SSHClient object is deallocated correctly
- import gc
+ # force a collection to see whether the SSHClient object is deallocated
+ # correctly. 2 GCs are needed to make sure it's really collected on
+ # PyPy
+ gc.collect()
gc.collect()
self.assertTrue(p() is None)
@@ -316,17 +326,15 @@ class SSHClientTest (unittest.TestCase):
verify that an SSHClient can be used a context manager
"""
threading.Thread(target=self._run).start()
- host_key = paramiko.RSAKey.from_private_key_file(test_path('test_rsa.key'))
- public_host_key = paramiko.RSAKey(data=host_key.asbytes())
with paramiko.SSHClient() as tc:
self.tc = tc
self.tc.set_missing_host_key_policy(paramiko.AutoAddPolicy())
self.assertEquals(0, len(self.tc.get_host_keys()))
- self.tc.connect(self.addr, self.port, username='slowdive', password='pygmalion')
+ self.tc.connect(**dict(self.connect_kwargs, password='pygmalion'))
self.event.wait(1.0)
- self.assertTrue(self.event.isSet())
+ self.assertTrue(self.event.is_set())
self.assertTrue(self.ts.is_active())
self.assertTrue(self.tc._transport is not None)
@@ -345,15 +353,32 @@ class SSHClientTest (unittest.TestCase):
self.tc = paramiko.SSHClient()
self.tc.get_host_keys().add('[%s]:%d' % (self.addr, self.port), 'ssh-rsa', public_host_key)
# Connect with a half second banner timeout.
+ kwargs = dict(self.connect_kwargs, banner_timeout=0.5)
self.assertRaises(
paramiko.SSHException,
self.tc.connect,
- self.addr,
- self.port,
- username='slowdive',
+ **kwargs
+ )
+
+ def test_8_auth_trickledown(self):
+ """
+ Failed key auth doesn't prevent subsequent pw auth from succeeding
+ """
+ # NOTE: re #387, re #394
+ # If pkey module used within Client._auth isn't correctly handling auth
+ # errors (e.g. if it allows things like ValueError to bubble up as per
+ # midway thru #394) client.connect() will fail (at key load step)
+ # instead of succeeding (at password step)
+ kwargs = dict(
+ # Password-protected key whose passphrase is not 'pygmalion' (it's
+ # 'television' as per tests/test_pkey.py). NOTE: must use
+ # key_filename, loading the actual key here with PKey will except
+ # immediately; we're testing the try/except crap within Client.
+ key_filename=[test_path('test_rsa_password.key')],
+ # Actual password for default 'slowdive' user
password='pygmalion',
- banner_timeout=0.5
)
+ self._test_connection(**kwargs)
def test_update_environment(self):
"""