~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/blackbox/test_serve.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2009-09-22 05:29:23 UTC
  • mfrom: (4700.1.3 integration)
  • Revision ID: pqm@pqm.ubuntu.com-20090922052923-oj9unuqio1uf2f1b
(robertc) Cleanup end to end SSH connection test,
        hopefully fixing it on windows too. (Robert Collins,
        John Arbash Meinel)

Show diffs side-by-side

added added

removed removed

Lines of Context:
33
33
    )
34
34
from bzrlib.branch import Branch
35
35
from bzrlib.bzrdir import BzrDir
36
 
from bzrlib.errors import ParamikoNotPresent
37
36
from bzrlib.smart import client, medium
38
37
from bzrlib.smart.server import BzrServerFactory, SmartTCPServer
39
38
from bzrlib.tests import (
 
39
    ParamikoFeature,
 
40
    TestCaseWithMemoryTransport,
40
41
    TestCaseWithTransport,
41
 
    TestCaseWithMemoryTransport,
42
42
    TestSkipped,
43
43
    )
44
44
from bzrlib.trace import mutter
166
166
        self.make_read_requests(branch)
167
167
        self.assertServerFinishesCleanly(process)
168
168
 
169
 
    def test_bzr_connect_to_bzr_ssh(self):
170
 
        """User acceptance that get_transport of a bzr+ssh:// behaves correctly.
171
 
 
172
 
        bzr+ssh:// should cause bzr to run a remote bzr smart server over SSH.
173
 
        """
174
 
        try:
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
181
 
 
182
 
        # Make a branch
183
 
        self.make_branch('a_branch')
184
 
 
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
190
 
        # elsewhere?
191
 
        class StubSSHServer(StubServer):
192
 
 
193
 
            test = self
194
 
 
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)
200
 
 
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):
205
 
                    while True:
206
 
                        bytes = read(1)
207
 
                        if bytes == '':
208
 
                            close()
209
 
                            break
210
 
                        write(bytes)
211
 
 
212
 
                file_functions = [
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))
219
 
                    t.start()
220
 
 
221
 
                return True
222
 
 
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
228
 
 
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')
232
 
 
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
238
 
        try:
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')
247
 
        finally:
248
 
            # Restore the BZR_REMOTE_PATH environment variable back to its
249
 
            # original state.
250
 
            if orig_bzr_remote_path is None:
251
 
                del os.environ['BZR_REMOTE_PATH']
252
 
            else:
253
 
                os.environ['BZR_REMOTE_PATH'] = orig_bzr_remote_path
254
 
 
255
 
        self.assertEqual(
256
 
            ['%s serve --inet --directory=/ --allow-writes'
257
 
             % bzr_remote_path],
258
 
            self.command_executed)
259
 
 
260
169
 
261
170
class TestCmdServeChrooting(TestCaseWithTransport):
262
171