~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

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

Make bzr+ssh:// actually work (at least with absolute paths).

This also adds an ugly blackbox test.

Show diffs side-by-side

added added

removed removed

Lines of Context:
105
105
        out, err = self.run_bzr_error(
106
106
            ['bzr serve requires one of --inet or --port'], 'serve')
107
107
 
 
108
    def test_bzr_connect_to_bzr_ssh(self):
 
109
        # Make a branch
 
110
        self.make_branch('.')
 
111
 
 
112
        # Start an SSH server
 
113
        # XXX: This is horrible -- we define a really dumb SSH server that
 
114
        # executes commands, and manage the hooking up of stdin/out/err to the
 
115
        # SSH channel ourselves.  Surely this has already been implemented
 
116
        # elsewhere?
 
117
        import subprocess
 
118
        import threading
 
119
        from paramiko.common import AUTH_SUCCESSFUL
 
120
        import bzrlib.tests.stub_sftp
 
121
        import bzrlib.transport.sftp
 
122
        class StubSSHServer(bzrlib.tests.stub_sftp.StubServer):
 
123
            test = self
 
124
 
 
125
            def get_allowed_auths(self, username):
 
126
                return 'none'
 
127
 
 
128
            def check_auth_none(self, username):
 
129
                return AUTH_SUCCESSFUL
 
130
            
 
131
            def check_channel_exec_request(self, channel, command):
 
132
                self.test.command_executed = command
 
133
                proc = subprocess.Popen(
 
134
                    command, shell=True, stdin=subprocess.PIPE,
 
135
                    stdout=subprocess.PIPE, stderr=subprocess.PIPE)
 
136
                
 
137
                # XXX: horribly inefficient, not to mention ugly.
 
138
                def do_stdin():
 
139
                    # copy bytes from the channel to the subprocess's stdin
 
140
                    while True:
 
141
                        bytes = channel.recv(1)
 
142
                        if bytes == '':
 
143
                            proc.stdin.close()
 
144
                            break
 
145
                        proc.stdin.write(bytes)
 
146
                        proc.stdin.flush()
 
147
                threading.Thread(target=do_stdin).start()
 
148
 
 
149
                def ferry_bytes(pipe):
 
150
                    while True:
 
151
                        bytes = pipe.read(1)
 
152
                        if bytes == '':
 
153
                            channel.close()
 
154
                            break
 
155
                        channel.sendall(bytes)
 
156
                threading.Thread(target=ferry_bytes, args=(proc.stdout,)).start()
 
157
                threading.Thread(target=ferry_bytes, args=(proc.stderr,)).start()
 
158
 
 
159
                return True
 
160
 
 
161
        ssh_server = bzrlib.transport.sftp.SFTPServer(StubSSHServer)
 
162
        ssh_server.setUp()
 
163
        self.addCleanup(ssh_server.tearDown)
 
164
        port = ssh_server._listener.port
 
165
 
 
166
        # Access the branch via a bzr+ssh URL.  The BZR_REMOTE_PATH environment
 
167
        # variable is used to tell bzr what command to run on the remote end.
 
168
        # '~/path/to/branch' will be interpreted by the special server on
 
169
        # the remote end to mean the branch we made earlier.
 
170
        import os, sys
 
171
        self.run_bzr_subprocess(
 
172
            'log', 'bzr+ssh://localhost:%d/%s' % (port, os.path.abspath('.')),
 
173
            env_changes={'BZR_REMOTE_PATH': self.get_bzr_path()})
 
174
        
 
175
        self.assertEqual(
 
176
            '%s serve --inet --directory=/' % self.get_bzr_path(),
 
177
            self.command_executed)
 
178
        
 
179