~bzr-pqm/bzr/bzr.dev

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