147
class LoopbackSFTP(object):
148
"""Simple wrapper for a socket that pretends to be a paramiko Channel."""
150
def __init__(self, sock):
153
def send(self, data):
154
return self.__socket.send(data)
157
return self.__socket.recv(n)
159
def recv_ready(self):
163
self.__socket.close()
147
166
SYSTEM_HOSTKEYS = {}
148
167
BZR_HOSTKEYS = {}
209
230
def __del__(self):
210
231
"""Should this warn, or actually try to cleanup?"""
211
232
if self.lock_file:
212
warn("SFTPLock %r not explicitly unlocked" % (self.path,))
233
warning("SFTPLock %r not explicitly unlocked" % (self.path,))
215
236
def unlock(self):
635
655
vendor = _get_ssh_vendor()
656
if vendor == 'loopback':
657
sock = socket.socket()
658
sock.connect((self._host, self._port))
659
self._sftp = SFTPClient(LoopbackSFTP(sock))
660
elif vendor != 'none':
637
661
sock = SFTPSubprocess(self._host, vendor, self._port,
639
663
self._sftp = SFTPClient(sock)
651
675
t = paramiko.Transport((self._host, self._port or 22))
676
t.set_log_channel('bzr.paramiko')
653
678
except paramiko.SSHException, e:
654
679
raise ConnectionError('Unable to reach SSH host %s:%d' %
829
854
s, _ = self._socket.accept()
830
855
# now close the listen socket
831
856
self._socket.close()
832
self._callback(s, self.stop_event)
858
self._callback(s, self.stop_event)
860
# probably a failed test
861
warning('Exception from within unit test server thread: %r' % x)
835
864
self.stop_event.set()
836
# We should consider waiting for the other thread
837
# to stop, because otherwise we get spurious
838
# bzr: ERROR: Socket exception: Connection reset by peer (54)
839
# because the test suite finishes before the thread has a chance
840
# to close. (Especially when only running a few tests)
865
# use a timeout here, because if the test fails, the server thread may
866
# never notice the stop_event.
843
870
class SFTPServer(Server):
844
871
"""Common code for SFTP server facilities."""
846
def _get_sftp_url(self, path):
847
"""Calculate a sftp url to this server for path."""
848
return 'sftp://foo:bar@localhost:%d/%s' % (self._listener.port, path)
850
873
def __init__(self):
851
874
self._original_vendor = None
852
875
self._homedir = None
853
876
self._server_homedir = None
854
877
self._listener = None
855
878
self._root = None
879
self._vendor = 'none'
856
880
# sftp server logs
883
def _get_sftp_url(self, path):
884
"""Calculate an sftp url to this server for path."""
885
return 'sftp://foo:bar@localhost:%d/%s' % (self._listener.port, path)
859
887
def log(self, message):
860
"""What to do here? do we need this? Its for the StubServer.."""
888
"""StubServer uses this to log when a new server is created."""
861
889
self.logs.append(message)
863
891
def _run_server(self, s, stop_event):
874
902
ssh_server.start_server(event, server)
876
904
stop_event.wait(30.0)
879
"""See bzrlib.transport.Server.setUp."""
880
# XXX: 20051124 jamesh
881
# The tests currently pop up a password prompt when an external ssh
882
# is used. This forces the use of the paramiko implementation.
883
907
global _ssh_vendor
884
908
self._original_vendor = _ssh_vendor
909
_ssh_vendor = self._vendor
886
910
self._homedir = os.getcwdu()
887
911
if self._server_homedir is None:
888
912
self._server_homedir = self._homedir
899
923
_ssh_vendor = self._original_vendor
902
class SFTPAbsoluteServer(SFTPServer):
926
class SFTPServerWithoutSSH(SFTPServer):
928
Common code for an SFTP server over a clear TCP loopback socket,
929
instead of over an SSH secured socket.
933
super(SFTPServerWithoutSSH, self).__init__()
934
self._vendor = 'loopback'
936
def _run_server(self, sock, stop_event):
937
class FakeChannel(object):
938
def get_transport(self):
940
def get_log_channel(self):
944
def get_hexdump(self):
947
server = paramiko.SFTPServer(FakeChannel(), 'sftp', StubServer(self), StubSFTPServer,
948
root=self._root, home=self._server_homedir)
949
server.start_subsystem('sftp', None, sock)
950
server.finish_subsystem()
953
class SFTPAbsoluteServer(SFTPServerWithoutSSH):
903
954
"""A test server for sftp transports, using absolute urls."""
905
956
def get_url(self):
907
958
return self._get_sftp_url(urlescape(self._homedir[1:]))
910
class SFTPHomeDirServer(SFTPServer):
961
class SFTPHomeDirServer(SFTPServerWithoutSSH):
911
962
"""A test server for sftp transports, using homedir relative urls."""
913
964
def get_url(self):