~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

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

  • Committer: John Ferlito
  • Date: 2009-09-02 04:31:45 UTC
  • mto: (4665.7.1 serve-init)
  • mto: This revision was merged to the branch mainline in revision 4913.
  • Revision ID: johnf@inodes.org-20090902043145-gxdsfw03ilcwbyn5
Add a debian init script for bzr --serve

Show diffs side-by-side

added added

removed removed

Lines of Context:
12
12
#
13
13
# You should have received a copy of the GNU General Public License
14
14
# along with this program; if not, write to the Free Software
15
 
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
16
 
17
17
 
18
18
"""Tests of the bzr serve command."""
21
21
import signal
22
22
import subprocess
23
23
import sys
 
24
import thread
24
25
import threading
25
26
 
26
27
from bzrlib import (
27
28
    errors,
28
29
    osutils,
29
30
    revision as _mod_revision,
 
31
    transport,
30
32
    )
31
33
from bzrlib.branch import Branch
32
34
from bzrlib.bzrdir import BzrDir
33
35
from bzrlib.errors import ParamikoNotPresent
34
 
from bzrlib.smart import medium
 
36
from bzrlib.smart import client, medium
 
37
from bzrlib.smart.server import SmartTCPServer
35
38
from bzrlib.tests import TestCaseWithTransport, TestSkipped
 
39
from bzrlib.trace import mutter
36
40
from bzrlib.transport import get_transport, remote
37
41
 
38
42
 
48
52
        result = self.finish_bzr_subprocess(process)
49
53
        self.assertEqual('', result[0])
50
54
        self.assertEqual('', result[1])
51
 
    
 
55
 
52
56
    def assertServerFinishesCleanly(self, process):
53
57
        """Shutdown the bzr serve instance process looking for errors."""
54
58
        # Shutdown the server
97
101
        args = ['serve', '--port', 'localhost:0']
98
102
        args.extend(extra_options)
99
103
        process = self.start_bzr_subprocess(args, skip_if_plan_to_signal=True)
100
 
        port_line = process.stdout.readline()
 
104
        port_line = process.stderr.readline()
101
105
        prefix = 'listening on port: '
102
106
        self.assertStartsWith(port_line, prefix)
103
107
        port = int(port_line[len(prefix):])
138
142
        self.make_read_requests(branch)
139
143
        self.assertServerFinishesCleanly(process)
140
144
 
 
145
    def test_bzr_serve_supports_protocol(self):
 
146
        # Make a branch
 
147
        self.make_branch('.')
 
148
 
 
149
        process, url = self.start_server_port(['--allow-writes',
 
150
                                               '--protocol=bzr'])
 
151
 
 
152
        # Connect to the server
 
153
        branch = Branch.open(url)
 
154
        self.make_read_requests(branch)
 
155
        self.assertServerFinishesCleanly(process)
 
156
 
141
157
    def test_bzr_connect_to_bzr_ssh(self):
142
158
        """User acceptance that get_transport of a bzr+ssh:// behaves correctly.
143
159
 
148
164
        except ParamikoNotPresent:
149
165
            raise TestSkipped('Paramiko not installed')
150
166
        from bzrlib.tests.stub_sftp import StubServer
151
 
        
 
167
 
152
168
        # Make a branch
153
169
        self.make_branch('a_branch')
154
170
 
167
183
                proc = subprocess.Popen(
168
184
                    command, shell=True, stdin=subprocess.PIPE,
169
185
                    stdout=subprocess.PIPE, stderr=subprocess.PIPE)
170
 
                
 
186
 
171
187
                # XXX: horribly inefficient, not to mention ugly.
172
188
                # Start a thread for each of stdin/out/err, and relay bytes from
173
189
                # the subprocess to channel and vice versa.
193
209
        ssh_server = SFTPServer(StubSSHServer)
194
210
        # XXX: We *don't* want to override the default SSH vendor, so we set
195
211
        # _vendor to what _get_ssh_vendor returns.
196
 
        ssh_server.setUp()
197
 
        self.addCleanup(ssh_server.tearDown)
 
212
        self.start_server(ssh_server)
198
213
        port = ssh_server._listener.port
199
214
 
200
215
        # Access the branch via a bzr+ssh URL.  The BZR_REMOTE_PATH environment
201
216
        # variable is used to tell bzr what command to run on the remote end.
202
217
        path_to_branch = osutils.abspath('a_branch')
203
 
        
 
218
 
204
219
        orig_bzr_remote_path = os.environ.get('BZR_REMOTE_PATH')
205
220
        bzr_remote_path = self.get_bzr_path()
206
221
        if sys.platform == 'win32':
226
241
            ['%s serve --inet --directory=/ --allow-writes'
227
242
             % bzr_remote_path],
228
243
            self.command_executed)
229
 
        
 
244
 
 
245
 
 
246
class TestCmdServeChrooting(TestCaseWithTransport):
 
247
 
 
248
    def test_serve_tcp(self):
 
249
        """'bzr serve' wraps the given --directory in a ChrootServer.
 
250
 
 
251
        So requests that search up through the parent directories (like
 
252
        find_repositoryV3) will give "not found" responses, rather than
 
253
        InvalidURLJoin or jail break errors.
 
254
        """
 
255
        t = self.get_transport()
 
256
        t.mkdir('server-root')
 
257
        self.run_bzr_serve_then_func(
 
258
            ['--port', '0', '--directory', t.local_abspath('server-root'),
 
259
             '--allow-writes'],
 
260
            self.when_server_started)
 
261
        # The when_server_started method issued a find_repositoryV3 that should
 
262
        # fail with 'norepository' because there are no repositories inside the
 
263
        # --directory.
 
264
        self.assertEqual(('norepository',), self.client_resp)
 
265
        
 
266
    def run_bzr_serve_then_func(self, serve_args, func, *func_args,
 
267
            **func_kwargs):
 
268
        """Run 'bzr serve', and run the given func in a thread once the server
 
269
        has started.
 
270
        
 
271
        When 'func' terminates, the server will be terminated too.
 
272
        """
 
273
        # install hook
 
274
        def on_server_start(backing_urls, tcp_server):
 
275
            t = threading.Thread(
 
276
                target=on_server_start_thread, args=(tcp_server,))
 
277
            t.start()
 
278
        def on_server_start_thread(tcp_server):
 
279
            try:
 
280
                # Run func
 
281
                self.tcp_server = tcp_server
 
282
                try:
 
283
                    func(*func_args, **func_kwargs)
 
284
                except Exception, e:
 
285
                    # Log errors to make some test failures a little less
 
286
                    # mysterious.
 
287
                    mutter('func broke: %r', e)
 
288
            finally:
 
289
                # Then stop the server
 
290
                mutter('interrupting...')
 
291
                thread.interrupt_main()
 
292
        SmartTCPServer.hooks.install_named_hook(
 
293
            'server_started_ex', on_server_start,
 
294
            'run_bzr_serve_then_func hook')
 
295
        # start a TCP server
 
296
        try:
 
297
            self.run_bzr(['serve'] + list(serve_args))
 
298
        except KeyboardInterrupt:
 
299
            pass
 
300
 
 
301
    def when_server_started(self):
 
302
        # Connect to the TCP server and issue some requests and see what comes
 
303
        # back.
 
304
        client_medium = medium.SmartTCPClientMedium(
 
305
            '127.0.0.1', self.tcp_server.port,
 
306
            'bzr://localhost:%d/' % (self.tcp_server.port,))
 
307
        smart_client = client._SmartClient(client_medium)
 
308
        resp = smart_client.call('mkdir', 'foo', '')
 
309
        resp = smart_client.call('BzrDirFormat.initialize', 'foo/')
 
310
        try:
 
311
            resp = smart_client.call('BzrDir.find_repositoryV3', 'foo/')
 
312
        except errors.ErrorFromSmartServer, e:
 
313
            resp = e.error_tuple
 
314
        self.client_resp = resp
 
315
        client_medium.disconnect()
 
316
 
 
317
 
 
318