/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

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

  • Committer: Jelmer Vernooij
  • Date: 2017-07-23 22:06:41 UTC
  • mfrom: (6738 trunk)
  • mto: This revision was merged to the branch mainline in revision 6739.
  • Revision ID: jelmer@jelmer.uk-20170723220641-69eczax9bmv8d6kk
Merge trunk, address review comments.

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
import os
21
21
import signal
22
22
import sys
23
 
from _thread import interrupt_main
24
 
 
 
23
import thread
25
24
import threading
26
25
 
27
26
from ... import (
78
77
            finally:
79
78
                # Then stop the server
80
79
                trace.mutter('interrupting...')
81
 
                interrupt_main()
 
80
                thread.interrupt_main()
82
81
        # When the hook is fired, it just starts ``on_server_start_thread`` and
83
82
        # return
84
 
 
85
83
        def on_server_start(backing_urls, tcp_server):
86
84
            t = threading.Thread(
87
85
                target=on_server_start_thread, args=(tcp_server,))
90
88
        SmartTCPServer.hooks.install_named_hook(
91
89
            'server_started_ex', on_server_start,
92
90
            'run_bzr_serve_then_func hook')
93
 
        # It seems interrupt_main() will not raise KeyboardInterrupt
 
91
        # It seesm thread.interrupt_main() will not raise KeyboardInterrupt
94
92
        # until after socket.accept returns. So we set the timeout low to make
95
93
        # the test faster.
96
94
        self.overrideAttr(SmartTCPServer, '_ACCEPT_TIMEOUT', 0.1)
100
98
                                    retcode=retcode)
101
99
        except KeyboardInterrupt as e:
102
100
            return (self._last_cmd_stdout.getvalue(),
103
 
                    self._last_cmd_stderr.getvalue())
 
101
                self._last_cmd_stderr.getvalue())
104
102
        return out, err
105
103
 
106
104
 
118
116
        """
119
117
        def hook(exception):
120
118
            if exception[0] is KeyboardInterrupt:
121
 
                sys.stderr.write(b'catching KeyboardInterrupt\n')
 
119
                sys.stderr.write('catching KeyboardInterrupt\n')
122
120
                return True
123
121
            else:
124
122
                return False
142
140
        # Hide stdin from the subprocess module, so it won't fail to close it.
143
141
        process.stdin = None
144
142
        result = self.finish_bzr_subprocess(process)
145
 
        self.assertEqual(b'', result[0])
146
 
        self.assertEqual(b'', result[1])
 
143
        self.assertEqual('', result[0])
 
144
        self.assertEqual('', result[1])
147
145
 
148
146
    def assertServerFinishesCleanly(self, process):
149
147
        """Shutdown the brz serve instance process looking for errors."""
150
148
        # Shutdown the server
151
149
        result = self.finish_bzr_subprocess(process, retcode=3,
152
150
                                            send_signal=signal.SIGINT)
153
 
        self.assertEqual(b'', result[0])
154
 
        self.assertEqual(b'brz: interrupted\n', result[1])
 
151
        self.assertEqual('', result[0])
 
152
        self.assertEqual('brz: interrupted\n', result[1])
155
153
 
156
154
    def make_read_requests(self, branch):
157
155
        """Do some read only requests."""
158
 
        with branch.lock_read():
 
156
        branch.lock_read()
 
157
        try:
159
158
            branch.repository.all_revision_ids()
160
159
            self.assertEqual(_mod_revision.NULL_REVISION,
161
160
                             _mod_revision.ensure_null(branch.last_revision()))
 
161
        finally:
 
162
            branch.unlock()
162
163
 
163
164
    def start_server_inet(self, extra_options=()):
164
165
        """Start a brz server subprocess using the --inet option.
194
195
        args.extend(extra_options)
195
196
        process = self.start_bzr_subprocess(args, skip_if_plan_to_signal=True)
196
197
        port_line = process.stderr.readline()
197
 
        prefix = b'listening on port: '
 
198
        prefix = 'listening on port: '
198
199
        self.assertStartsWith(port_line, prefix)
199
200
        port = int(port_line[len(prefix):])
200
201
        url = 'bzr://localhost:%d/' % port
269
270
        f = open(log_fname, 'rb')
270
271
        content = f.read()
271
272
        f.close()
272
 
        self.assertContainsRe(content, br'hpss request: \[[0-9-]+\]')
 
273
        self.assertContainsRe(content, r'hpss request: \[[0-9-]+\]')
273
274
 
274
275
    def test_bzr_serve_supports_configurable_timeout(self):
275
276
        gs = config.GlobalStack()
277
278
        # Save the config as the subprocess will use it
278
279
        gs.store.save()
279
280
        process, url = self.start_server_port()
280
 
        self.build_tree_contents([('a_file', b'contents\n')])
 
281
        self.build_tree_contents([('a_file', 'contents\n')])
281
282
        # We can connect and issue a request
282
283
        t = transport.get_transport_from_url(url)
283
 
        self.assertEqual(b'contents\n', t.get_bytes('a_file'))
 
284
        self.assertEqual('contents\n', t.get_bytes('a_file'))
284
285
        # However, if we just wait for more content from the server, it will
285
286
        # eventually disconnect us.
286
287
        m = t.get_smart_medium()
288
289
        # Now, we wait for timeout to trigger
289
290
        err = process.stderr.readline()
290
291
        self.assertEqual(
291
 
            b'Connection Timeout: disconnecting client after 0.2 seconds\n',
 
292
            'Connection Timeout: disconnecting client after 0.2 seconds\n',
292
293
            err)
293
294
        self.assertServerFinishesCleanly(process)
294
295
 
295
296
    def test_bzr_serve_supports_client_timeout(self):
296
297
        process, url = self.start_server_port(['--client-timeout=0.1'])
297
 
        self.build_tree_contents([('a_file', b'contents\n')])
 
298
        self.build_tree_contents([('a_file', 'contents\n')])
298
299
        # We can connect and issue a request
299
300
        t = transport.get_transport_from_url(url)
300
 
        self.assertEqual(b'contents\n', t.get_bytes('a_file'))
 
301
        self.assertEqual('contents\n', t.get_bytes('a_file'))
301
302
        # However, if we just wait for more content from the server, it will
302
303
        # eventually disconnect us.
303
304
        # TODO: Use something like signal.alarm() so that if the server doesn't
308
309
        # Now, we wait for timeout to trigger
309
310
        err = process.stderr.readline()
310
311
        self.assertEqual(
311
 
            b'Connection Timeout: disconnecting client after 0.1 seconds\n',
 
312
            'Connection Timeout: disconnecting client after 0.1 seconds\n',
312
313
            err)
313
314
        self.assertServerFinishesCleanly(process)
314
315
 
315
316
    def test_bzr_serve_graceful_shutdown(self):
316
 
        big_contents = b'a' * 64 * 1024
 
317
        big_contents = 'a'*64*1024
317
318
        self.build_tree_contents([('bigfile', big_contents)])
318
319
        process, url = self.start_server_port(['--client-timeout=1.0'])
319
320
        t = transport.get_transport_from_url(url)
320
321
        m = t.get_smart_medium()
321
322
        c = client._SmartClient(m)
322
323
        # Start, but don't finish a response
323
 
        resp, response_handler = c.call_expecting_body(b'get', b'bigfile')
324
 
        self.assertEqual((b'ok',), resp)
 
324
        resp, response_handler = c.call_expecting_body('get', 'bigfile')
 
325
        self.assertEqual(('ok',), resp)
325
326
        # Note: process.send_signal is a Python 2.6ism
326
327
        process.send_signal(signal.SIGHUP)
327
328
        # Wait for the server to notice the signal, and then read the actual
328
329
        # body of the response. That way we know that it is waiting for the
329
330
        # request to finish
330
 
        self.assertEqual(b'Requested to stop gracefully\n',
331
 
                         process.stderr.readline())
332
 
        self.assertIn(process.stderr.readline(),
333
 
                      (b'', b'Waiting for 1 client(s) to finish\n'))
 
331
        self.assertEqual('Requested to stop gracefully\n',
 
332
                         process.stderr.readline())
 
333
        self.assertEqual('Waiting for 1 client(s) to finish\n',
 
334
                         process.stderr.readline())
334
335
        body = response_handler.read_body_bytes()
335
336
        if body != big_contents:
336
337
            self.fail('Failed to properly read the contents of "bigfile"')
337
338
        # Now that our request is finished, the medium should notice it has
338
339
        # been disconnected.
339
 
        self.assertEqual(b'', m.read_bytes(1))
 
340
        self.assertEqual('', m.read_bytes(1))
340
341
        # And the server should be stopping
341
342
        self.assertEqual(0, process.wait())
342
343
 
360
361
        # The when_server_started method issued a find_repositoryV3 that should
361
362
        # fail with 'norepository' because there are no repositories inside the
362
363
        # --directory.
363
 
        self.assertEqual((b'norepository',), self.client_resp)
 
364
        self.assertEqual(('norepository',), self.client_resp)
364
365
 
365
366
    def when_server_started(self):
366
367
        # Connect to the TCP server and issue some requests and see what comes
400
401
        bzr_server = BzrServerFactory(
401
402
            self.fake_expanduser, lambda t: base_path)
402
403
        mem_transport = self.get_transport()
403
 
        mem_transport.mkdir('home')
404
 
        mem_transport.mkdir('home/user')
 
404
        mem_transport.mkdir_multi(['home', 'home/user'])
405
405
        bzr_server.set_up(mem_transport, None, None, inet=True, timeout=4.0)
406
406
        self.addCleanup(bzr_server.tear_down)
407
407
        return bzr_server
412
412
 
413
413
    def test_bzr_serve_does_not_expand_userdir_outside_base(self):
414
414
        bzr_server = self.make_test_server('/foo')
415
 
        self.assertFalse(
416
 
            bzr_server.smart_server.backing_transport.has('~user'))
 
415
        self.assertFalse(bzr_server.smart_server.backing_transport.has('~user'))
417
416
 
418
417
    def test_get_base_path(self):
419
418
        """cmd_serve will turn the --directory option into a LocalTransport
425
424
        base_url = urlutils.local_path_to_url(base_dir) + '/'
426
425
        # Define a fake 'protocol' to capture the transport that cmd_serve
427
426
        # passes to serve_bzr.
428
 
 
429
427
        def capture_transport(transport, host, port, inet, timeout):
430
428
            self.bzr_serve_transport = transport
431
429
        cmd = builtins.cmd_serve()
438
436
            base_dir, server_maker.get_base_path(self.bzr_serve_transport))
439
437
        # Read-write
440
438
        cmd.run(directory=base_dir, protocol=capture_transport,
441
 
                allow_writes=True)
 
439
            allow_writes=True)
442
440
        server_maker = BzrServerFactory()
443
441
        self.assertEqual(base_url, self.bzr_serve_transport.base)
444
442
        self.assertEqual(base_dir,
445
 
                         server_maker.get_base_path(self.bzr_serve_transport))
 
443
            server_maker.get_base_path(self.bzr_serve_transport))
446
444
        # Read-only, from a URL
447
445
        cmd.run(directory=base_url, protocol=capture_transport)
448
446
        server_maker = BzrServerFactory()