166
166
self.make_read_requests(branch)
167
167
self.assertServerFinishesCleanly(process)
169
def test_bzr_connect_to_bzr_ssh(self):
170
"""User acceptance that get_transport of a bzr+ssh:// behaves correctly.
172
bzr+ssh:// should cause bzr to run a remote bzr smart server over SSH.
175
# SFTPFullAbsoluteServer has a get_url method, and doesn't
176
# override the interface (doesn't change self._vendor).
177
from bzrlib.transport.sftp import SFTPFullAbsoluteServer
178
except ParamikoNotPresent:
179
raise TestSkipped('Paramiko not installed')
180
from bzrlib.tests.stub_sftp import StubServer
183
self.make_branch('a_branch')
185
# Start an SSH server
186
self.command_executed = []
187
# XXX: This is horrible -- we define a really dumb SSH server that
188
# executes commands, and manage the hooking up of stdin/out/err to the
189
# SSH channel ourselves. Surely this has already been implemented
191
class StubSSHServer(StubServer):
195
def check_channel_exec_request(self, channel, command):
196
self.test.command_executed.append(command)
197
proc = subprocess.Popen(
198
command, shell=True, stdin=subprocess.PIPE,
199
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
201
# XXX: horribly inefficient, not to mention ugly.
202
# Start a thread for each of stdin/out/err, and relay bytes from
203
# the subprocess to channel and vice versa.
204
def ferry_bytes(read, write, close):
213
(channel.recv, proc.stdin.write, proc.stdin.close),
214
(proc.stdout.read, channel.sendall, channel.close),
215
(proc.stderr.read, channel.sendall_stderr, channel.close)]
216
for read, write, close in file_functions:
217
t = threading.Thread(
218
target=ferry_bytes, args=(read, write, close))
223
ssh_server = SFTPFullAbsoluteServer(StubSSHServer)
224
# XXX: We *don't* want to override the default SSH vendor, so we set
225
# _vendor to what _get_ssh_vendor returns.
226
self.start_server(ssh_server)
227
port = ssh_server._listener.port
229
# Access the branch via a bzr+ssh URL. The BZR_REMOTE_PATH environment
230
# variable is used to tell bzr what command to run on the remote end.
231
path_to_branch = osutils.abspath('a_branch')
233
orig_bzr_remote_path = os.environ.get('BZR_REMOTE_PATH')
234
bzr_remote_path = self.get_bzr_path()
235
if sys.platform == 'win32':
236
bzr_remote_path = sys.executable + ' ' + self.get_bzr_path()
237
os.environ['BZR_REMOTE_PATH'] = bzr_remote_path
239
if sys.platform == 'win32':
240
path_to_branch = os.path.splitdrive(path_to_branch)[1]
241
url_suffix = '@localhost:%d%s' % (port, path_to_branch)
242
self.permit_url('bzr+ssh://fred' + url_suffix)
243
branch = Branch.open('bzr+ssh://fred:secret' + url_suffix)
244
self.make_read_requests(branch)
245
# Check we can perform write operations
246
branch.bzrdir.root_transport.mkdir('foo')
248
# Restore the BZR_REMOTE_PATH environment variable back to its
250
if orig_bzr_remote_path is None:
251
del os.environ['BZR_REMOTE_PATH']
253
os.environ['BZR_REMOTE_PATH'] = orig_bzr_remote_path
256
['%s serve --inet --directory=/ --allow-writes'
258
self.command_executed)
261
170
class TestCmdServeChrooting(TestCaseWithTransport):