~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

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

  • Committer: Tarmac
  • Author(s): Vincent Ladeuil
  • Date: 2017-01-30 14:42:05 UTC
  • mfrom: (6620.1.1 trunk)
  • Revision ID: tarmac-20170130144205-r8fh2xpmiuxyozpv
Merge  2.7 into trunk including fix for bug #1657238 [r=vila]

Show diffs side-by-side

added added

removed removed

Lines of Context:
25
25
 
26
26
from bzrlib import (
27
27
    builtins,
 
28
    config,
28
29
    errors,
29
30
    osutils,
30
31
    revision as _mod_revision,
33
34
    urlutils,
34
35
    )
35
36
from bzrlib.branch import Branch
36
 
from bzrlib.bzrdir import BzrDir
 
37
from bzrlib.controldir import ControlDir
37
38
from bzrlib.smart import client, medium
38
39
from bzrlib.smart.server import (
39
40
    BzrServerFactory,
66
67
            try:
67
68
                # Run func if set
68
69
                self.tcp_server = tcp_server
69
 
                if not func is None:
 
70
                if func is not None:
70
71
                    try:
71
72
                        func(*func_args, **func_kwargs)
72
73
                    except Exception, e:
87
88
        SmartTCPServer.hooks.install_named_hook(
88
89
            'server_started_ex', on_server_start,
89
90
            'run_bzr_serve_then_func hook')
 
91
        # It seesm thread.interrupt_main() will not raise KeyboardInterrupt
 
92
        # until after socket.accept returns. So we set the timeout low to make
 
93
        # the test faster.
 
94
        self.overrideAttr(SmartTCPServer, '_ACCEPT_TIMEOUT', 0.1)
90
95
        # start a TCP server
91
96
        try:
92
97
            out, err = self.run_bzr(['serve'] + list(serve_args),
117
122
        SmartTCPServer.hooks.install_named_hook(
118
123
            'server_exception', hook,
119
124
            'test_server_except_hook hook')
120
 
        args = ['--port', 'localhost:0', '--quiet']
 
125
        args = ['--listen', 'localhost', '--port', '0', '--quiet']
121
126
        out, err = self.run_bzr_serve_then_func(args, retcode=0)
122
127
        self.assertEqual('catching KeyboardInterrupt\n', err)
123
128
 
185
190
            finish_bzr_subprocess, and the base url for the server.
186
191
        """
187
192
        # Serve from the current directory
188
 
        args = ['serve', '--port', 'localhost:0']
 
193
        args = ['serve', '--listen', 'localhost', '--port', '0']
189
194
        args.extend(extra_options)
190
195
        process = self.start_bzr_subprocess(args, skip_if_plan_to_signal=True)
191
196
        port_line = process.stderr.readline()
198
203
 
199
204
    def test_bzr_serve_quiet(self):
200
205
        self.make_branch('.')
201
 
        args = ['--port', 'localhost:0', '--quiet']
 
206
        args = ['--listen', 'localhost', '--port', '0', '--quiet']
202
207
        out, err = self.run_bzr_serve_then_func(args, retcode=3)
203
208
        self.assertEqual('', out)
204
209
        self.assertEqual('', err)
216
221
        process, transport = self.start_server_inet(['--allow-writes'])
217
222
 
218
223
        # We get a working branch, and can create a directory
219
 
        branch = BzrDir.open_from_transport(transport).open_branch()
 
224
        branch = ControlDir.open_from_transport(transport).open_branch()
220
225
        self.make_read_requests(branch)
221
226
        transport.mkdir('adir')
222
227
        self.assertInetServerShutsdownCleanly(process)
224
229
    def test_bzr_serve_port_readonly(self):
225
230
        """bzr server should provide a read only filesystem by default."""
226
231
        process, url = self.start_server_port()
227
 
        t = transport.get_transport(url)
 
232
        t = transport.get_transport_from_url(url)
228
233
        self.assertRaises(errors.TransportNotPossible, t.mkdir, 'adir')
229
234
        self.assertServerFinishesCleanly(process)
230
235
 
258
263
        log_fname = os.getcwd() + '/server.log'
259
264
        self.overrideEnv('BZR_LOG', log_fname)
260
265
        process, transport = self.start_server_inet(['-Dhpss'])
261
 
        branch = BzrDir.open_from_transport(transport).open_branch()
 
266
        branch = ControlDir.open_from_transport(transport).open_branch()
262
267
        self.make_read_requests(branch)
263
268
        self.assertInetServerShutsdownCleanly(process)
264
269
        f = open(log_fname, 'rb')
266
271
        f.close()
267
272
        self.assertContainsRe(content, r'hpss request: \[[0-9-]+\]')
268
273
 
 
274
    def test_bzr_serve_supports_configurable_timeout(self):
 
275
        gs = config.GlobalStack()
 
276
        gs.set('serve.client_timeout', 0.2)
 
277
        # Save the config as the subprocess will use it
 
278
        gs.store.save()
 
279
        process, url = self.start_server_port()
 
280
        self.build_tree_contents([('a_file', 'contents\n')])
 
281
        # We can connect and issue a request
 
282
        t = transport.get_transport_from_url(url)
 
283
        self.assertEqual('contents\n', t.get_bytes('a_file'))
 
284
        # However, if we just wait for more content from the server, it will
 
285
        # eventually disconnect us.
 
286
        m = t.get_smart_medium()
 
287
        m.read_bytes(1)
 
288
        # Now, we wait for timeout to trigger
 
289
        err = process.stderr.readline()
 
290
        self.assertEqual(
 
291
            'Connection Timeout: disconnecting client after 0.2 seconds\n',
 
292
            err)
 
293
        self.assertServerFinishesCleanly(process)
 
294
 
 
295
    def test_bzr_serve_supports_client_timeout(self):
 
296
        process, url = self.start_server_port(['--client-timeout=0.1'])
 
297
        self.build_tree_contents([('a_file', 'contents\n')])
 
298
        # We can connect and issue a request
 
299
        t = transport.get_transport_from_url(url)
 
300
        self.assertEqual('contents\n', t.get_bytes('a_file'))
 
301
        # However, if we just wait for more content from the server, it will
 
302
        # eventually disconnect us.
 
303
        # TODO: Use something like signal.alarm() so that if the server doesn't
 
304
        #       properly handle the timeout, we end up failing the test instead
 
305
        #       of hanging forever.
 
306
        m = t.get_smart_medium()
 
307
        m.read_bytes(1)
 
308
        # Now, we wait for timeout to trigger
 
309
        err = process.stderr.readline()
 
310
        self.assertEqual(
 
311
            'Connection Timeout: disconnecting client after 0.1 seconds\n',
 
312
            err)
 
313
        self.assertServerFinishesCleanly(process)
 
314
 
 
315
    def test_bzr_serve_graceful_shutdown(self):
 
316
        big_contents = 'a'*64*1024
 
317
        self.build_tree_contents([('bigfile', big_contents)])
 
318
        process, url = self.start_server_port(['--client-timeout=1.0'])
 
319
        t = transport.get_transport_from_url(url)
 
320
        m = t.get_smart_medium()
 
321
        c = client._SmartClient(m)
 
322
        # Start, but don't finish a response
 
323
        resp, response_handler = c.call_expecting_body('get', 'bigfile')
 
324
        self.assertEqual(('ok',), resp)
 
325
        # Note: process.send_signal is a Python 2.6ism
 
326
        process.send_signal(signal.SIGHUP)
 
327
        # Wait for the server to notice the signal, and then read the actual
 
328
        # body of the response. That way we know that it is waiting for the
 
329
        # request to finish
 
330
        self.assertEqual('Requested to stop gracefully\n',
 
331
                         process.stderr.readline())
 
332
        self.assertEqual('Waiting for 1 client(s) to finish\n',
 
333
                         process.stderr.readline())
 
334
        body = response_handler.read_body_bytes()
 
335
        if body != big_contents:
 
336
            self.fail('Failed to properly read the contents of "bigfile"')
 
337
        # Now that our request is finished, the medium should notice it has
 
338
        # been disconnected.
 
339
        self.assertEqual('', m.read_bytes(1))
 
340
        # And the server should be stopping
 
341
        self.assertEqual(0, process.wait())
 
342
 
269
343
 
270
344
class TestCmdServeChrooting(TestBzrServeBase):
271
345
 
279
353
        t = self.get_transport()
280
354
        t.mkdir('server-root')
281
355
        self.run_bzr_serve_then_func(
282
 
            ['--port', '127.0.0.1:0',
 
356
            ['--listen', '127.0.0.1', '--port', '0',
283
357
             '--directory', t.local_abspath('server-root'),
284
358
             '--allow-writes'],
285
359
            func=self.when_server_started)
327
401
            self.fake_expanduser, lambda t: base_path)
328
402
        mem_transport = self.get_transport()
329
403
        mem_transport.mkdir_multi(['home', 'home/user'])
330
 
        bzr_server.set_up(mem_transport, None, None, inet=True)
 
404
        bzr_server.set_up(mem_transport, None, None, inet=True, timeout=4.0)
331
405
        self.addCleanup(bzr_server.tear_down)
332
406
        return bzr_server
333
407
 
349
423
        base_url = urlutils.local_path_to_url(base_dir) + '/'
350
424
        # Define a fake 'protocol' to capture the transport that cmd_serve
351
425
        # passes to serve_bzr.
352
 
        def capture_transport(transport, host, port, inet):
 
426
        def capture_transport(transport, host, port, inet, timeout):
353
427
            self.bzr_serve_transport = transport
354
428
        cmd = builtins.cmd_serve()
355
429
        # Read-only
366
440
        self.assertEqual(base_url, self.bzr_serve_transport.base)
367
441
        self.assertEqual(base_dir,
368
442
            server_maker.get_base_path(self.bzr_serve_transport))
 
443
        # Read-only, from a URL
 
444
        cmd.run(directory=base_url, protocol=capture_transport)
 
445
        server_maker = BzrServerFactory()
 
446
        self.assertEqual(
 
447
            'readonly+%s' % base_url, self.bzr_serve_transport.base)
 
448
        self.assertEqual(
 
449
            base_dir, server_maker.get_base_path(self.bzr_serve_transport))