/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
48
1910.19.7 by Andrew Bennetts
Allow specifying the host/interface to bzr serve, and use the new test
49
class TestBzrServe(TestCaseWithTransport):
1910.19.11 by Andrew Bennetts
General code cleanup based on review comments and other observations.
50
4695.3.1 by Vincent Ladeuil
Fix test failures with no C extensions loaded.
51
    def setUp(self):
52
        super(TestBzrServe, self).setUp()
4695.3.2 by Vincent Ladeuil
Simplified and claried as per Robert's review.
53
        self.disable_missing_extensions_warning()
4695.3.1 by Vincent Ladeuil
Fix test failures with no C extensions loaded.
54
2018.2.3 by Andrew Bennetts
Starting factoring out the smart server client "medium" from the protocol.
55
    def assertInetServerShutsdownCleanly(self, process):
2020.1.1 by Robert Collins
Add readonly support to the smart server, enabled by default via `bzr server`.
56
        """Shutdown the server process looking for errors."""
2018.2.3 by Andrew Bennetts
Starting factoring out the smart server client "medium" from the protocol.
57
        # Shutdown the server: the server should shut down when it cannot read
58
        # from stdin anymore.
59
        process.stdin.close()
1910.19.11 by Andrew Bennetts
General code cleanup based on review comments and other observations.
60
        # Hide stdin from the subprocess module, so it won't fail to close it.
61
        process.stdin = None
2581.1.2 by Martin Pool
Remove unnecessary retcode=0 to run_bzr calls
62
        result = self.finish_bzr_subprocess(process)
1910.19.11 by Andrew Bennetts
General code cleanup based on review comments and other observations.
63
        self.assertEqual('', result[0])
64
        self.assertEqual('', result[1])
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
65
2020.1.1 by Robert Collins
Add readonly support to the smart server, enabled by default via `bzr server`.
66
    def assertServerFinishesCleanly(self, process):
67
        """Shutdown the bzr serve instance process looking for errors."""
68
        # Shutdown the server
69
        result = self.finish_bzr_subprocess(process, retcode=3,
70
                                            send_signal=signal.SIGINT)
71
        self.assertEqual('', result[0])
72
        self.assertEqual('bzr: interrupted\n', result[1])
73
3287.6.4 by Robert Collins
Fix up deprecation warnings for get_revision_graph.
74
    def make_read_requests(self, branch):
75
        """Do some read only requests."""
76
        branch.lock_read()
77
        try:
78
            branch.repository.all_revision_ids()
79
            self.assertEqual(_mod_revision.NULL_REVISION,
80
                             _mod_revision.ensure_null(branch.last_revision()))
81
        finally:
82
            branch.unlock()
83
2020.1.1 by Robert Collins
Add readonly support to the smart server, enabled by default via `bzr server`.
84
    def start_server_inet(self, extra_options=()):
85
        """Start a bzr server subprocess using the --inet option.
86
87
        :param extra_options: extra options to give the server.
88
        :return: a tuple with the bzr process handle for passing to
89
            finish_bzr_subprocess, a client for the server, and a transport.
90
        """
91
        # Serve from the current directory
92
        process = self.start_bzr_subprocess(['serve', '--inet'])
93
94
        # Connect to the server
95
        # We use this url because while this is no valid URL to connect to this
96
        # server instance, the transport needs a URL.
3431.3.7 by Andrew Bennetts
Fix incidental breakage in blackbox/test_serve.py
97
        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.
98
        self.permit_url(url)
2018.5.15 by Andrew Bennetts
Tidy some imports, and bugs introduced when adding server.py
99
        client_medium = medium.SmartSimplePipesClientMedium(
3431.3.7 by Andrew Bennetts
Fix incidental breakage in blackbox/test_serve.py
100
            process.stdout, process.stdin, url)
101
        transport = remote.RemoteTransport(url, medium=client_medium)
2018.2.3 by Andrew Bennetts
Starting factoring out the smart server client "medium" from the protocol.
102
        return process, transport
2020.1.1 by Robert Collins
Add readonly support to the smart server, enabled by default via `bzr server`.
103
104
    def start_server_port(self, extra_options=()):
105
        """Start a bzr server subprocess.
106
107
        :param extra_options: extra options to give the server.
108
        :return: a tuple with the bzr process handle for passing to
109
            finish_bzr_subprocess, and the base url for the server.
110
        """
111
        # Serve from the current directory
112
        args = ['serve', '--port', 'localhost:0']
113
        args.extend(extra_options)
114
        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.
115
        port_line = process.stderr.readline()
1910.19.7 by Andrew Bennetts
Allow specifying the host/interface to bzr serve, and use the new test
116
        prefix = 'listening on port: '
117
        self.assertStartsWith(port_line, prefix)
118
        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.
119
        url = 'bzr://localhost:%d/' % port
120
        self.permit_url(url)
121
        return process, url
2020.1.1 by Robert Collins
Add readonly support to the smart server, enabled by default via `bzr server`.
122
123
    def test_bzr_serve_inet_readonly(self):
124
        """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.
125
        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`.
126
        self.assertRaises(errors.TransportNotPossible, transport.mkdir, 'adir')
2018.2.3 by Andrew Bennetts
Starting factoring out the smart server client "medium" from the protocol.
127
        self.assertInetServerShutsdownCleanly(process)
2020.1.1 by Robert Collins
Add readonly support to the smart server, enabled by default via `bzr server`.
128
129
    def test_bzr_serve_inet_readwrite(self):
130
        # Make a branch
131
        self.make_branch('.')
132
2018.2.3 by Andrew Bennetts
Starting factoring out the smart server client "medium" from the protocol.
133
        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`.
134
135
        # We get a working branch
136
        branch = BzrDir.open_from_transport(transport).open_branch()
3287.6.4 by Robert Collins
Fix up deprecation warnings for get_revision_graph.
137
        self.make_read_requests(branch)
2018.2.3 by Andrew Bennetts
Starting factoring out the smart server client "medium" from the protocol.
138
        self.assertInetServerShutsdownCleanly(process)
2020.1.1 by Robert Collins
Add readonly support to the smart server, enabled by default via `bzr server`.
139
140
    def test_bzr_serve_port_readonly(self):
141
        """bzr server should provide a read only filesystem by default."""
142
        process, url = self.start_server_port()
143
        transport = get_transport(url)
144
        self.assertRaises(errors.TransportNotPossible, transport.mkdir, 'adir')
145
        self.assertServerFinishesCleanly(process)
146
147
    def test_bzr_serve_port_readwrite(self):
148
        # Make a branch
149
        self.make_branch('.')
150
151
        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
152
153
        # Connect to the server
2020.1.1 by Robert Collins
Add readonly support to the smart server, enabled by default via `bzr server`.
154
        branch = Branch.open(url)
3287.6.4 by Robert Collins
Fix up deprecation warnings for get_revision_graph.
155
        self.make_read_requests(branch)
2020.1.1 by Robert Collins
Add readonly support to the smart server, enabled by default via `bzr server`.
156
        self.assertServerFinishesCleanly(process)
1910.19.7 by Andrew Bennetts
Allow specifying the host/interface to bzr serve, and use the new test
157
4370.4.2 by Jelmer Vernooij
Add --protocol option to 'bzr serve'.
158
    def test_bzr_serve_supports_protocol(self):
159
        # Make a branch
160
        self.make_branch('.')
161
162
        process, url = self.start_server_port(['--allow-writes',
163
                                               '--protocol=bzr'])
164
165
        # Connect to the server
166
        branch = Branch.open(url)
167
        self.make_read_requests(branch)
168
        self.assertServerFinishesCleanly(process)
169
4544.1.2 by Andrew Bennetts
Add test that would catch the lack of ChrootServer in cmd_serve.
170
171
class TestCmdServeChrooting(TestCaseWithTransport):
172
173
    def test_serve_tcp(self):
174
        """'bzr serve' wraps the given --directory in a ChrootServer.
175
176
        So requests that search up through the parent directories (like
177
        find_repositoryV3) will give "not found" responses, rather than
178
        InvalidURLJoin or jail break errors.
179
        """
180
        t = self.get_transport()
181
        t.mkdir('server-root')
182
        self.run_bzr_serve_then_func(
4676.3.3 by Vincent Ladeuil
Force IPV4 to fix failure on IPV6-enabled hosts.
183
            ['--port', '127.0.0.1:0',
184
             '--directory', t.local_abspath('server-root'),
4544.1.2 by Andrew Bennetts
Add test that would catch the lack of ChrootServer in cmd_serve.
185
             '--allow-writes'],
186
            self.when_server_started)
187
        # The when_server_started method issued a find_repositoryV3 that should
188
        # fail with 'norepository' because there are no repositories inside the
189
        # --directory.
4676.3.3 by Vincent Ladeuil
Force IPV4 to fix failure on IPV6-enabled hosts.
190
        self.assertEqual(('norepository',), self.client_resp)
4676.3.1 by Vincent Ladeuil
Marking TestCmdServeChrooting.test_serve_tcp as expected failure
191
4544.1.2 by Andrew Bennetts
Add test that would catch the lack of ChrootServer in cmd_serve.
192
    def run_bzr_serve_then_func(self, serve_args, func, *func_args,
193
            **func_kwargs):
194
        """Run 'bzr serve', and run the given func in a thread once the server
195
        has started.
196
        
197
        When 'func' terminates, the server will be terminated too.
198
        """
199
        # install hook
4544.1.3 by Andrew Bennetts
Pass backing_urls to the new server_started_ex hook.
200
        def on_server_start(backing_urls, tcp_server):
201
            t = threading.Thread(
202
                target=on_server_start_thread, args=(tcp_server,))
4544.1.2 by Andrew Bennetts
Add test that would catch the lack of ChrootServer in cmd_serve.
203
            t.start()
204
        def on_server_start_thread(tcp_server):
205
            try:
206
                # Run func
207
                self.tcp_server = tcp_server
208
                try:
209
                    func(*func_args, **func_kwargs)
210
                except Exception, e:
211
                    # Log errors to make some test failures a little less
212
                    # mysterious.
213
                    mutter('func broke: %r', e)
214
            finally:
215
                # Then stop the server
216
                mutter('interrupting...')
217
                thread.interrupt_main()
218
        SmartTCPServer.hooks.install_named_hook(
219
            'server_started_ex', on_server_start,
220
            'run_bzr_serve_then_func hook')
221
        # start a TCP server
222
        try:
223
            self.run_bzr(['serve'] + list(serve_args))
224
        except KeyboardInterrupt:
225
            pass
226
227
    def when_server_started(self):
228
        # Connect to the TCP server and issue some requests and see what comes
229
        # back.
230
        client_medium = medium.SmartTCPClientMedium(
231
            '127.0.0.1', self.tcp_server.port,
232
            'bzr://localhost:%d/' % (self.tcp_server.port,))
233
        smart_client = client._SmartClient(client_medium)
234
        resp = smart_client.call('mkdir', 'foo', '')
235
        resp = smart_client.call('BzrDirFormat.initialize', 'foo/')
236
        try:
237
            resp = smart_client.call('BzrDir.find_repositoryV3', 'foo/')
238
        except errors.ErrorFromSmartServer, e:
239
            resp = e.error_tuple
240
        self.client_resp = resp
241
        client_medium.disconnect()
242
243
4634.43.7 by Andrew Bennetts
Add some unit tests for parts of userdir expansion.
244
class TestUserdirExpansion(TestCaseWithMemoryTransport):
245
246
    def fake_expanduser(self, path):
247
        """A simple, environment-independent, function for the duration of this
248
        test.
249
250
        Paths starting with a path segment of '~user' will expand to start with
251
        '/home/user/'.  Every other path will be unchanged.
252
        """
253
        if path.split('/', 1)[0] == '~user':
254
            return '/home/user' + path[len('~user'):]
255
        return path
256
257
    def make_test_server(self, base_path='/'):
4634.43.15 by Andrew Bennetts
Rename BzrServerMaker -> BzrServerFactory.
258
        """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.
259
        creat '/home/user' in that transport.
260
        """
4634.43.15 by Andrew Bennetts
Rename BzrServerMaker -> BzrServerFactory.
261
        bzr_server = BzrServerFactory(
4634.43.7 by Andrew Bennetts
Add some unit tests for parts of userdir expansion.
262
            self.fake_expanduser, lambda t: base_path)
263
        mem_transport = self.get_transport()
264
        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.
265
        bzr_server.set_up(mem_transport, None, None, inet=True)
266
        self.addCleanup(bzr_server.tear_down)
4634.43.7 by Andrew Bennetts
Add some unit tests for parts of userdir expansion.
267
        return bzr_server
268
269
    def test_bzr_serve_expands_userdir(self):
270
        bzr_server = self.make_test_server()
271
        self.assertTrue(bzr_server.smart_server.backing_transport.has('~user'))
272
273
    def test_bzr_serve_does_not_expand_userdir_outside_base(self):
274
        bzr_server = self.make_test_server('/foo')
275
        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.
276
4634.43.8 by Andrew Bennetts
Test for recovering the --directory value from the transport cmd_serve passes to bzr_serve.
277
    def test_get_base_path(self):
278
        """cmd_serve will turn the --directory option into a LocalTransport
4634.43.15 by Andrew Bennetts
Rename BzrServerMaker -> BzrServerFactory.
279
        (optionally decorated with 'readonly+').  BzrServerFactory can
280
        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.
281
        """
4797.3.4 by John Arbash Meinel
Per review recommendation, use 'osutils.abspath' instead of hardcoded string.
282
        # URLs always include the trailing slash, and get_base_path returns it
283
        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.
284
        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.
285
        # Define a fake 'protocol' to capture the transport that cmd_serve
286
        # passes to serve_bzr.
287
        def capture_transport(transport, host, port, inet):
288
            self.bzr_serve_transport = transport
289
        cmd = builtins.cmd_serve()
290
        # Read-only
4789.7.1 by John Arbash Meinel
Fix a 'bzr serve' test that didn't expect windows translating '/a' to 'C:/a'.
291
        cmd.run(directory=base_dir, protocol=capture_transport)
4634.43.15 by Andrew Bennetts
Rename BzrServerMaker -> BzrServerFactory.
292
        server_maker = BzrServerFactory()
4634.43.8 by Andrew Bennetts
Test for recovering the --directory value from the transport cmd_serve passes to bzr_serve.
293
        self.assertEqual(
4797.3.21 by John Arbash Meinel
Use urlutils.local_path_to_url to handle both windows and linux.
294
            '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.
295
        self.assertEqual(
4789.7.1 by John Arbash Meinel
Fix a 'bzr serve' test that didn't expect windows translating '/a' to 'C:/a'.
296
            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.
297
        # Read-write
4789.7.1 by John Arbash Meinel
Fix a 'bzr serve' test that didn't expect windows translating '/a' to 'C:/a'.
298
        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.
299
            allow_writes=True)
4634.43.15 by Andrew Bennetts
Rename BzrServerMaker -> BzrServerFactory.
300
        server_maker = BzrServerFactory()
4797.3.21 by John Arbash Meinel
Use urlutils.local_path_to_url to handle both windows and linux.
301
        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'.
302
        self.assertEqual(base_dir,
303
            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.
304