/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
2052.3.2 by John Arbash Meinel
Change Copyright .. by Canonical to Copyright ... Canonical
1
# Copyright (C) 2006 Canonical Ltd
1910.19.7 by Andrew Bennetts
Allow specifying the host/interface to bzr serve, and use the new test
2
#
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
7
#
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
12
#
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
4183.7.1 by Sabin Iacob
update FSF mailing address
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
1910.19.7 by Andrew Bennetts
Allow specifying the host/interface to bzr serve, and use the new test
16
17
18
"""Tests of the bzr serve command."""
19
2018.1.2 by Andrew Bennetts
Tidy imports, skip test if paramiko isn't installed.
20
import os
4634.43.7 by Andrew Bennetts
Add some unit tests for parts of userdir expansion.
21
import os.path
1910.19.7 by Andrew Bennetts
Allow specifying the host/interface to bzr serve, and use the new test
22
import signal
2018.1.2 by Andrew Bennetts
Tidy imports, skip test if paramiko isn't installed.
23
import subprocess
2309.2.5 by Alexander Belchenko
test_bzr_connect_to_bzr_ssh: win32-compatibility
24
import sys
4544.1.2 by Andrew Bennetts
Add test that would catch the lack of ChrootServer in cmd_serve.
25
import thread
2018.1.2 by Andrew Bennetts
Tidy imports, skip test if paramiko isn't installed.
26
import threading
1910.19.7 by Andrew Bennetts
Allow specifying the host/interface to bzr serve, and use the new test
27
2309.2.5 by Alexander Belchenko
test_bzr_connect_to_bzr_ssh: win32-compatibility
28
from bzrlib import (
4634.43.8 by Andrew Bennetts
Test for recovering the --directory value from the transport cmd_serve passes to bzr_serve.
29
    builtins,
2309.2.5 by Alexander Belchenko
test_bzr_connect_to_bzr_ssh: win32-compatibility
30
    errors,
31
    osutils,
2598.5.1 by Aaron Bentley
Start eliminating the use of None to indicate null revision
32
    revision as _mod_revision,
4797.3.21 by John Arbash Meinel
Use urlutils.local_path_to_url to handle both windows and linux.
33
    urlutils,
2309.2.5 by Alexander Belchenko
test_bzr_connect_to_bzr_ssh: win32-compatibility
34
    )
1910.19.7 by Andrew Bennetts
Allow specifying the host/interface to bzr serve, and use the new test
35
from bzrlib.branch import Branch
1910.19.11 by Andrew Bennetts
General code cleanup based on review comments and other observations.
36
from bzrlib.bzrdir import BzrDir
4544.1.2 by Andrew Bennetts
Add test that would catch the lack of ChrootServer in cmd_serve.
37
from bzrlib.smart import client, medium
4634.43.15 by Andrew Bennetts
Rename BzrServerMaker -> BzrServerFactory.
38
from bzrlib.smart.server import BzrServerFactory, SmartTCPServer
4634.43.7 by Andrew Bennetts
Add some unit tests for parts of userdir expansion.
39
from bzrlib.tests import (
4700.1.3 by Robert Collins
Merge trunk.
40
    ParamikoFeature,
41
    TestCaseWithMemoryTransport,
4634.43.7 by Andrew Bennetts
Add some unit tests for parts of userdir expansion.
42
    TestCaseWithTransport,
43
    TestSkipped,
44
    )
4544.1.2 by Andrew Bennetts
Add test that would catch the lack of ChrootServer in cmd_serve.
45
from bzrlib.trace import mutter
2018.5.21 by Andrew Bennetts
Move bzrlib.transport.smart to bzrlib.smart
46
from bzrlib.transport import get_transport, remote
1910.19.11 by Andrew Bennetts
General code cleanup based on review comments and other observations.
47
4815.3.7 by Gordon Tyler
Made a few changes at the suggestion of vila.
48
class TestBzrServeBase(TestCaseWithTransport):
4815.3.3 by Gordon Tyler
Changed test_bzr_serve_quiet to use in-process execution of the command.
49
50
    def run_bzr_serve_then_func(self, serve_args, retcode=0, func=None,
51
                                *func_args, **func_kwargs):
52
        """Run 'bzr serve', and run the given func in a thread once the server
53
        has started.
54
        
55
        When 'func' terminates, the server will be terminated too.
56
        
57
        Returns stdout and stderr.
58
        """
59
        # install hook
60
        def on_server_start(backing_urls, tcp_server):
61
            t = threading.Thread(
62
                target=on_server_start_thread, args=(tcp_server,))
63
            t.start()
64
        def on_server_start_thread(tcp_server):
65
            try:
66
                # Run func if set
67
                self.tcp_server = tcp_server
68
                if not func is None:
69
                    try:
70
                        func(*func_args, **func_kwargs)
71
                    except Exception, e:
72
                        # Log errors to make some test failures a little less
73
                        # mysterious.
74
                        mutter('func broke: %r', e)
75
            finally:
76
                # Then stop the server
77
                mutter('interrupting...')
78
                thread.interrupt_main()
79
        SmartTCPServer.hooks.install_named_hook(
80
            'server_started_ex', on_server_start,
81
            'run_bzr_serve_then_func hook')
82
        # start a TCP server
83
        try:
4815.3.7 by Gordon Tyler
Made a few changes at the suggestion of vila.
84
            out, err = self.run_bzr(['serve'] + list(serve_args))
85
        except KeyboardInterrupt, e:
86
            out, err = e.args
87
        return out, err
88
89
90
class TestBzrServe(TestBzrServeBase):
1910.19.11 by Andrew Bennetts
General code cleanup based on review comments and other observations.
91
4695.3.1 by Vincent Ladeuil
Fix test failures with no C extensions loaded.
92
    def setUp(self):
4815.3.6 by Gordon Tyler
Fixed super call in TestBzrServe.
93
        super(TestBzrServe, self).setUp()
4695.3.2 by Vincent Ladeuil
Simplified and claried as per Robert's review.
94
        self.disable_missing_extensions_warning()
4695.3.1 by Vincent Ladeuil
Fix test failures with no C extensions loaded.
95
2018.2.3 by Andrew Bennetts
Starting factoring out the smart server client "medium" from the protocol.
96
    def assertInetServerShutsdownCleanly(self, process):
2020.1.1 by Robert Collins
Add readonly support to the smart server, enabled by default via `bzr server`.
97
        """Shutdown the server process looking for errors."""
2018.2.3 by Andrew Bennetts
Starting factoring out the smart server client "medium" from the protocol.
98
        # Shutdown the server: the server should shut down when it cannot read
99
        # from stdin anymore.
100
        process.stdin.close()
1910.19.11 by Andrew Bennetts
General code cleanup based on review comments and other observations.
101
        # Hide stdin from the subprocess module, so it won't fail to close it.
102
        process.stdin = None
2581.1.2 by Martin Pool
Remove unnecessary retcode=0 to run_bzr calls
103
        result = self.finish_bzr_subprocess(process)
1910.19.11 by Andrew Bennetts
General code cleanup based on review comments and other observations.
104
        self.assertEqual('', result[0])
105
        self.assertEqual('', result[1])
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
106
2020.1.1 by Robert Collins
Add readonly support to the smart server, enabled by default via `bzr server`.
107
    def assertServerFinishesCleanly(self, process):
108
        """Shutdown the bzr serve instance process looking for errors."""
109
        # Shutdown the server
110
        result = self.finish_bzr_subprocess(process, retcode=3,
111
                                            send_signal=signal.SIGINT)
112
        self.assertEqual('', result[0])
113
        self.assertEqual('bzr: interrupted\n', result[1])
114
3287.6.4 by Robert Collins
Fix up deprecation warnings for get_revision_graph.
115
    def make_read_requests(self, branch):
116
        """Do some read only requests."""
117
        branch.lock_read()
118
        try:
119
            branch.repository.all_revision_ids()
120
            self.assertEqual(_mod_revision.NULL_REVISION,
121
                             _mod_revision.ensure_null(branch.last_revision()))
122
        finally:
123
            branch.unlock()
124
2020.1.1 by Robert Collins
Add readonly support to the smart server, enabled by default via `bzr server`.
125
    def start_server_inet(self, extra_options=()):
126
        """Start a bzr server subprocess using the --inet option.
127
128
        :param extra_options: extra options to give the server.
129
        :return: a tuple with the bzr process handle for passing to
130
            finish_bzr_subprocess, a client for the server, and a transport.
131
        """
132
        # Serve from the current directory
133
        process = self.start_bzr_subprocess(['serve', '--inet'])
134
135
        # Connect to the server
136
        # We use this url because while this is no valid URL to connect to this
137
        # server instance, the transport needs a URL.
3431.3.7 by Andrew Bennetts
Fix incidental breakage in blackbox/test_serve.py
138
        url = 'bzr://localhost/'
4691.2.1 by Robert Collins
Add stronger test isolation by interception BzrDir.open and checking the thing being opened is known to the test suite.
139
        self.permit_url(url)
2018.5.15 by Andrew Bennetts
Tidy some imports, and bugs introduced when adding server.py
140
        client_medium = medium.SmartSimplePipesClientMedium(
3431.3.7 by Andrew Bennetts
Fix incidental breakage in blackbox/test_serve.py
141
            process.stdout, process.stdin, url)
142
        transport = remote.RemoteTransport(url, medium=client_medium)
2018.2.3 by Andrew Bennetts
Starting factoring out the smart server client "medium" from the protocol.
143
        return process, transport
2020.1.1 by Robert Collins
Add readonly support to the smart server, enabled by default via `bzr server`.
144
145
    def start_server_port(self, extra_options=()):
146
        """Start a bzr server subprocess.
147
148
        :param extra_options: extra options to give the server.
149
        :return: a tuple with the bzr process handle for passing to
150
            finish_bzr_subprocess, and the base url for the server.
151
        """
152
        # Serve from the current directory
153
        args = ['serve', '--port', 'localhost:0']
154
        args.extend(extra_options)
155
        process = self.start_bzr_subprocess(args, skip_if_plan_to_signal=True)
3955.1.7 by Jonathan Lange
Fix some tests that assumed the port was on stderr rather than stdout.
156
        port_line = process.stderr.readline()
1910.19.7 by Andrew Bennetts
Allow specifying the host/interface to bzr serve, and use the new test
157
        prefix = 'listening on port: '
158
        self.assertStartsWith(port_line, prefix)
159
        port = int(port_line[len(prefix):])
4691.2.1 by Robert Collins
Add stronger test isolation by interception BzrDir.open and checking the thing being opened is known to the test suite.
160
        url = 'bzr://localhost:%d/' % port
161
        self.permit_url(url)
162
        return process, url
4815.3.1 by Gordon Tyler
Added test_bzr_serve_quiet which tests that the output of 'bzr serve --quiet' is really quiet.
163
    
164
    def test_bzr_serve_quiet(self):
165
        self.make_branch('.')
4815.3.3 by Gordon Tyler
Changed test_bzr_serve_quiet to use in-process execution of the command.
166
        args = ['--port', 'localhost:0', '--quiet']
167
        out, err = self.run_bzr_serve_then_func(args, retcode=3)
4815.3.2 by Gordon Tyler
test_bzr_serve_quiet should be skipped if signals are not available.
168
        self.assertEqual('', out)
169
        self.assertEqual('', err)
2020.1.1 by Robert Collins
Add readonly support to the smart server, enabled by default via `bzr server`.
170
171
    def test_bzr_serve_inet_readonly(self):
172
        """bzr server should provide a read only filesystem by default."""
2018.2.3 by Andrew Bennetts
Starting factoring out the smart server client "medium" from the protocol.
173
        process, transport = self.start_server_inet()
2020.1.1 by Robert Collins
Add readonly support to the smart server, enabled by default via `bzr server`.
174
        self.assertRaises(errors.TransportNotPossible, transport.mkdir, 'adir')
2018.2.3 by Andrew Bennetts
Starting factoring out the smart server client "medium" from the protocol.
175
        self.assertInetServerShutsdownCleanly(process)
2020.1.1 by Robert Collins
Add readonly support to the smart server, enabled by default via `bzr server`.
176
177
    def test_bzr_serve_inet_readwrite(self):
178
        # Make a branch
179
        self.make_branch('.')
180
2018.2.3 by Andrew Bennetts
Starting factoring out the smart server client "medium" from the protocol.
181
        process, transport = self.start_server_inet(['--allow-writes'])
2020.1.1 by Robert Collins
Add readonly support to the smart server, enabled by default via `bzr server`.
182
183
        # We get a working branch
184
        branch = BzrDir.open_from_transport(transport).open_branch()
3287.6.4 by Robert Collins
Fix up deprecation warnings for get_revision_graph.
185
        self.make_read_requests(branch)
2018.2.3 by Andrew Bennetts
Starting factoring out the smart server client "medium" from the protocol.
186
        self.assertInetServerShutsdownCleanly(process)
2020.1.1 by Robert Collins
Add readonly support to the smart server, enabled by default via `bzr server`.
187
188
    def test_bzr_serve_port_readonly(self):
189
        """bzr server should provide a read only filesystem by default."""
190
        process, url = self.start_server_port()
191
        transport = get_transport(url)
192
        self.assertRaises(errors.TransportNotPossible, transport.mkdir, 'adir')
193
        self.assertServerFinishesCleanly(process)
194
195
    def test_bzr_serve_port_readwrite(self):
196
        # Make a branch
197
        self.make_branch('.')
198
199
        process, url = self.start_server_port(['--allow-writes'])
1910.19.7 by Andrew Bennetts
Allow specifying the host/interface to bzr serve, and use the new test
200
201
        # Connect to the server
2020.1.1 by Robert Collins
Add readonly support to the smart server, enabled by default via `bzr server`.
202
        branch = Branch.open(url)
3287.6.4 by Robert Collins
Fix up deprecation warnings for get_revision_graph.
203
        self.make_read_requests(branch)
2020.1.1 by Robert Collins
Add readonly support to the smart server, enabled by default via `bzr server`.
204
        self.assertServerFinishesCleanly(process)
1910.19.7 by Andrew Bennetts
Allow specifying the host/interface to bzr serve, and use the new test
205
4370.4.2 by Jelmer Vernooij
Add --protocol option to 'bzr serve'.
206
    def test_bzr_serve_supports_protocol(self):
207
        # Make a branch
208
        self.make_branch('.')
209
210
        process, url = self.start_server_port(['--allow-writes',
211
                                               '--protocol=bzr'])
212
213
        # Connect to the server
214
        branch = Branch.open(url)
215
        self.make_read_requests(branch)
216
        self.assertServerFinishesCleanly(process)
217
4544.1.2 by Andrew Bennetts
Add test that would catch the lack of ChrootServer in cmd_serve.
218
4815.3.7 by Gordon Tyler
Made a few changes at the suggestion of vila.
219
class TestCmdServeChrooting(TestBzrServeBase):
4544.1.2 by Andrew Bennetts
Add test that would catch the lack of ChrootServer in cmd_serve.
220
221
    def test_serve_tcp(self):
222
        """'bzr serve' wraps the given --directory in a ChrootServer.
223
224
        So requests that search up through the parent directories (like
225
        find_repositoryV3) will give "not found" responses, rather than
226
        InvalidURLJoin or jail break errors.
227
        """
228
        t = self.get_transport()
229
        t.mkdir('server-root')
230
        self.run_bzr_serve_then_func(
4676.3.3 by Vincent Ladeuil
Force IPV4 to fix failure on IPV6-enabled hosts.
231
            ['--port', '127.0.0.1:0',
232
             '--directory', t.local_abspath('server-root'),
4544.1.2 by Andrew Bennetts
Add test that would catch the lack of ChrootServer in cmd_serve.
233
             '--allow-writes'],
4815.3.3 by Gordon Tyler
Changed test_bzr_serve_quiet to use in-process execution of the command.
234
            func=self.when_server_started)
4544.1.2 by Andrew Bennetts
Add test that would catch the lack of ChrootServer in cmd_serve.
235
        # The when_server_started method issued a find_repositoryV3 that should
236
        # fail with 'norepository' because there are no repositories inside the
237
        # --directory.
4676.3.3 by Vincent Ladeuil
Force IPV4 to fix failure on IPV6-enabled hosts.
238
        self.assertEqual(('norepository',), self.client_resp)
4676.3.1 by Vincent Ladeuil
Marking TestCmdServeChrooting.test_serve_tcp as expected failure
239
4544.1.2 by Andrew Bennetts
Add test that would catch the lack of ChrootServer in cmd_serve.
240
    def when_server_started(self):
241
        # Connect to the TCP server and issue some requests and see what comes
242
        # back.
243
        client_medium = medium.SmartTCPClientMedium(
244
            '127.0.0.1', self.tcp_server.port,
245
            'bzr://localhost:%d/' % (self.tcp_server.port,))
246
        smart_client = client._SmartClient(client_medium)
247
        resp = smart_client.call('mkdir', 'foo', '')
248
        resp = smart_client.call('BzrDirFormat.initialize', 'foo/')
249
        try:
250
            resp = smart_client.call('BzrDir.find_repositoryV3', 'foo/')
251
        except errors.ErrorFromSmartServer, e:
252
            resp = e.error_tuple
253
        self.client_resp = resp
254
        client_medium.disconnect()
255
256
4634.43.7 by Andrew Bennetts
Add some unit tests for parts of userdir expansion.
257
class TestUserdirExpansion(TestCaseWithMemoryTransport):
258
259
    def fake_expanduser(self, path):
260
        """A simple, environment-independent, function for the duration of this
261
        test.
262
263
        Paths starting with a path segment of '~user' will expand to start with
264
        '/home/user/'.  Every other path will be unchanged.
265
        """
266
        if path.split('/', 1)[0] == '~user':
267
            return '/home/user' + path[len('~user'):]
268
        return path
269
270
    def make_test_server(self, base_path='/'):
4634.43.15 by Andrew Bennetts
Rename BzrServerMaker -> BzrServerFactory.
271
        """Make and setUp a BzrServerFactory, backed by a memory transport, and
4634.43.7 by Andrew Bennetts
Add some unit tests for parts of userdir expansion.
272
        creat '/home/user' in that transport.
273
        """
4634.43.15 by Andrew Bennetts
Rename BzrServerMaker -> BzrServerFactory.
274
        bzr_server = BzrServerFactory(
4634.43.7 by Andrew Bennetts
Add some unit tests for parts of userdir expansion.
275
            self.fake_expanduser, lambda t: base_path)
276
        mem_transport = self.get_transport()
277
        mem_transport.mkdir_multi(['home', 'home/user'])
4634.43.19 by Andrew Bennetts
Rename BzrServerFactory's setUp/tearDown to set_up/tear_down; this isn't a TestCase (or transport Server), so we should not use camelCase names.
278
        bzr_server.set_up(mem_transport, None, None, inet=True)
279
        self.addCleanup(bzr_server.tear_down)
4634.43.7 by Andrew Bennetts
Add some unit tests for parts of userdir expansion.
280
        return bzr_server
281
282
    def test_bzr_serve_expands_userdir(self):
283
        bzr_server = self.make_test_server()
284
        self.assertTrue(bzr_server.smart_server.backing_transport.has('~user'))
285
286
    def test_bzr_serve_does_not_expand_userdir_outside_base(self):
287
        bzr_server = self.make_test_server('/foo')
288
        self.assertFalse(bzr_server.smart_server.backing_transport.has('~user'))
4544.1.2 by Andrew Bennetts
Add test that would catch the lack of ChrootServer in cmd_serve.
289
4634.43.8 by Andrew Bennetts
Test for recovering the --directory value from the transport cmd_serve passes to bzr_serve.
290
    def test_get_base_path(self):
291
        """cmd_serve will turn the --directory option into a LocalTransport
4634.43.15 by Andrew Bennetts
Rename BzrServerMaker -> BzrServerFactory.
292
        (optionally decorated with 'readonly+').  BzrServerFactory can
293
        determine the original --directory from that transport.
4634.43.8 by Andrew Bennetts
Test for recovering the --directory value from the transport cmd_serve passes to bzr_serve.
294
        """
4797.3.4 by John Arbash Meinel
Per review recommendation, use 'osutils.abspath' instead of hardcoded string.
295
        # URLs always include the trailing slash, and get_base_path returns it
296
        base_dir = osutils.abspath('/a/b/c') + '/'
4797.3.21 by John Arbash Meinel
Use urlutils.local_path_to_url to handle both windows and linux.
297
        base_url = urlutils.local_path_to_url(base_dir) + '/'
4634.43.8 by Andrew Bennetts
Test for recovering the --directory value from the transport cmd_serve passes to bzr_serve.
298
        # Define a fake 'protocol' to capture the transport that cmd_serve
299
        # passes to serve_bzr.
300
        def capture_transport(transport, host, port, inet):
301
            self.bzr_serve_transport = transport
302
        cmd = builtins.cmd_serve()
303
        # Read-only
4789.7.1 by John Arbash Meinel
Fix a 'bzr serve' test that didn't expect windows translating '/a' to 'C:/a'.
304
        cmd.run(directory=base_dir, protocol=capture_transport)
4634.43.15 by Andrew Bennetts
Rename BzrServerMaker -> BzrServerFactory.
305
        server_maker = BzrServerFactory()
4634.43.8 by Andrew Bennetts
Test for recovering the --directory value from the transport cmd_serve passes to bzr_serve.
306
        self.assertEqual(
4797.3.21 by John Arbash Meinel
Use urlutils.local_path_to_url to handle both windows and linux.
307
            'readonly+%s' % base_url, self.bzr_serve_transport.base)
4634.43.8 by Andrew Bennetts
Test for recovering the --directory value from the transport cmd_serve passes to bzr_serve.
308
        self.assertEqual(
4789.7.1 by John Arbash Meinel
Fix a 'bzr serve' test that didn't expect windows translating '/a' to 'C:/a'.
309
            base_dir, server_maker.get_base_path(self.bzr_serve_transport))
4634.43.8 by Andrew Bennetts
Test for recovering the --directory value from the transport cmd_serve passes to bzr_serve.
310
        # Read-write
4789.7.1 by John Arbash Meinel
Fix a 'bzr serve' test that didn't expect windows translating '/a' to 'C:/a'.
311
        cmd.run(directory=base_dir, protocol=capture_transport,
4634.43.8 by Andrew Bennetts
Test for recovering the --directory value from the transport cmd_serve passes to bzr_serve.
312
            allow_writes=True)
4634.43.15 by Andrew Bennetts
Rename BzrServerMaker -> BzrServerFactory.
313
        server_maker = BzrServerFactory()
4797.3.21 by John Arbash Meinel
Use urlutils.local_path_to_url to handle both windows and linux.
314
        self.assertEqual(base_url, self.bzr_serve_transport.base)
4789.7.1 by John Arbash Meinel
Fix a 'bzr serve' test that didn't expect windows translating '/a' to 'C:/a'.
315
        self.assertEqual(base_dir,
316
            server_maker.get_base_path(self.bzr_serve_transport))
4634.43.8 by Andrew Bennetts
Test for recovering the --directory value from the transport cmd_serve passes to bzr_serve.
317