/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 bzrlib/tests/test_smart.py

  • Committer: Robert Collins
  • Date: 2010-05-06 23:41:35 UTC
  • mto: This revision was merged to the branch mainline in revision 5223.
  • Revision ID: robertc@robertcollins.net-20100506234135-yivbzczw1sejxnxc
Lock methods on ``Tree``, ``Branch`` and ``Repository`` are now
expected to return an object which can be used to unlock them. This reduces
duplicate code when using cleanups. The previous 'tokens's returned by
``Branch.lock_write`` and ``Repository.lock_write`` are now attributes
on the result of the lock_write. ``repository.RepositoryWriteLockResult``
and ``branch.BranchWriteLockResult`` document this. (Robert Collins)

``log._get_info_for_log_files`` now takes an add_cleanup callable.
(Robert Collins)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2006-2012, 2016 Canonical Ltd
 
1
# Copyright (C) 2006-2010 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
25
25
"""
26
26
 
27
27
import bz2
28
 
from io import BytesIO
 
28
from cStringIO import StringIO
29
29
import tarfile
30
 
import zlib
31
30
 
32
 
from breezy import (
 
31
from bzrlib import (
33
32
    bencode,
34
33
    branch as _mod_branch,
35
 
    controldir,
 
34
    bzrdir,
36
35
    errors,
37
 
    gpg,
 
36
    pack,
38
37
    tests,
39
38
    transport,
40
39
    urlutils,
41
 
    )
42
 
from breezy.bzr import (
43
 
    branch as _mod_bzrbranch,
44
 
    inventory_delta,
45
40
    versionedfile,
46
41
    )
47
 
from breezy.bzr.smart import (
 
42
from bzrlib.smart import (
48
43
    branch as smart_branch,
49
44
    bzrdir as smart_dir,
50
45
    repository as smart_repo,
53
48
    server,
54
49
    vfs,
55
50
    )
56
 
from breezy.bzr.testament import Testament
57
 
from breezy.tests import test_server
58
 
from breezy.transport import (
 
51
from bzrlib.tests import test_server
 
52
from bzrlib.transport import (
59
53
    chroot,
60
54
    memory,
61
55
    )
62
56
 
63
57
 
64
 
def load_tests(loader, standard_tests, pattern):
 
58
def load_tests(standard_tests, module, loader):
65
59
    """Multiply tests version and protocol consistency."""
66
60
    # FindRepository tests.
67
61
    scenarios = [
72
66
        ("find_repositoryV3", {
73
67
            "_request_class": smart_dir.SmartServerRequestFindRepositoryV3}),
74
68
        ]
75
 
    to_adapt, result = tests.split_suite_by_re(
76
 
        standard_tests, "TestSmartServerRequestFindRepository")
77
 
    v2_only, v1_and_2 = tests.split_suite_by_re(to_adapt, "_v2")
 
69
    to_adapt, result = tests.split_suite_by_re(standard_tests,
 
70
        "TestSmartServerRequestFindRepository")
 
71
    v2_only, v1_and_2 = tests.split_suite_by_re(to_adapt,
 
72
        "_v2")
78
73
    tests.multiply_tests(v1_and_2, scenarios, result)
79
74
    # The first scenario is only applicable to v1 protocols, it is deleted
80
75
    # since.
86
81
 
87
82
    def setUp(self):
88
83
        self.vfs_transport_factory = memory.MemoryServer
89
 
        super(TestCaseWithChrootedTransport, self).setUp()
 
84
        tests.TestCaseWithTransport.setUp(self)
90
85
        self._chroot_server = None
91
86
 
92
87
    def get_transport(self, relpath=None):
94
89
            backing_transport = tests.TestCaseWithTransport.get_transport(self)
95
90
            self._chroot_server = chroot.ChrootServer(backing_transport)
96
91
            self.start_server(self._chroot_server)
97
 
        t = transport.get_transport_from_url(self._chroot_server.get_url())
 
92
        t = transport.get_transport(self._chroot_server.get_url())
98
93
        if relpath is not None:
99
94
            t = t.clone(relpath)
100
95
        return t
108
103
        # the default or a parameterized class, but rather use the
109
104
        # TestCaseWithTransport infrastructure to set up a smart server and
110
105
        # transport.
111
 
        self.overrideAttr(self, "transport_server", self.make_transport_server)
 
106
        self.transport_server = self.make_transport_server
112
107
 
113
108
    def make_transport_server(self):
114
109
        return test_server.SmartTCPServer_for_testing('-' + self.id())
122
117
 
123
118
    def test_repeated_substreams_same_kind_are_one_stream(self):
124
119
        # Make a stream - an iterable of bytestrings.
125
 
        stream = [
126
 
            ('text', [versionedfile.FulltextContentFactory((b'k1',), None,
127
 
             None, b'foo')]),
128
 
            ('text', [versionedfile.FulltextContentFactory((b'k2',), None,
129
 
             None, b'bar')])]
130
 
        fmt = controldir.format_registry.get('pack-0.92')().repository_format
 
120
        stream = [('text', [versionedfile.FulltextContentFactory(('k1',), None,
 
121
            None, 'foo')]),('text', [
 
122
            versionedfile.FulltextContentFactory(('k2',), None, None, 'bar')])]
 
123
        fmt = bzrdir.format_registry.get('pack-0.92')().repository_format
131
124
        bytes = smart_repo._stream_to_byte_stream(stream, fmt)
132
125
        streams = []
133
126
        # Iterate the resulting iterable; checking that we get only one stream
142
135
class TestSmartServerResponse(tests.TestCase):
143
136
 
144
137
    def test__eq__(self):
145
 
        self.assertEqual(smart_req.SmartServerResponse((b'ok', )),
146
 
                         smart_req.SmartServerResponse((b'ok', )))
147
 
        self.assertEqual(smart_req.SmartServerResponse((b'ok', ), b'body'),
148
 
                         smart_req.SmartServerResponse((b'ok', ), b'body'))
149
 
        self.assertNotEqual(smart_req.SmartServerResponse((b'ok', )),
150
 
                            smart_req.SmartServerResponse((b'notok', )))
151
 
        self.assertNotEqual(smart_req.SmartServerResponse((b'ok', ), b'body'),
152
 
                            smart_req.SmartServerResponse((b'ok', )))
 
138
        self.assertEqual(smart_req.SmartServerResponse(('ok', )),
 
139
            smart_req.SmartServerResponse(('ok', )))
 
140
        self.assertEqual(smart_req.SmartServerResponse(('ok', ), 'body'),
 
141
            smart_req.SmartServerResponse(('ok', ), 'body'))
 
142
        self.assertNotEqual(smart_req.SmartServerResponse(('ok', )),
 
143
            smart_req.SmartServerResponse(('notok', )))
 
144
        self.assertNotEqual(smart_req.SmartServerResponse(('ok', ), 'body'),
 
145
            smart_req.SmartServerResponse(('ok', )))
153
146
        self.assertNotEqual(None,
154
 
                            smart_req.SmartServerResponse((b'ok', )))
 
147
            smart_req.SmartServerResponse(('ok', )))
155
148
 
156
149
    def test__str__(self):
157
150
        """SmartServerResponses can be stringified."""
158
 
        self.assertIn(
159
 
            str(smart_req.SuccessfulSmartServerResponse((b'args',), b'body')),
160
 
            ("<SuccessfulSmartServerResponse args=(b'args',) body=b'body'>",
161
 
             "<SuccessfulSmartServerResponse args=('args',) body='body'>"))
162
 
        self.assertIn(
163
 
            str(smart_req.FailedSmartServerResponse((b'args',), b'body')),
164
 
            ("<FailedSmartServerResponse args=(b'args',) body=b'body'>",
165
 
             "<FailedSmartServerResponse args=('args',) body='body'>"))
 
151
        self.assertEqual(
 
152
            "<SuccessfulSmartServerResponse args=('args',) body='body'>",
 
153
            str(smart_req.SuccessfulSmartServerResponse(('args',), 'body')))
 
154
        self.assertEqual(
 
155
            "<FailedSmartServerResponse args=('args',) body='body'>",
 
156
            str(smart_req.FailedSmartServerResponse(('args',), 'body')))
166
157
 
167
158
 
168
159
class TestSmartServerRequest(tests.TestCaseWithMemoryTransport):
170
161
    def test_translate_client_path(self):
171
162
        transport = self.get_transport()
172
163
        request = smart_req.SmartServerRequest(transport, 'foo/')
173
 
        self.assertEqual('./', request.translate_client_path(b'foo/'))
174
 
        self.assertRaises(
175
 
            urlutils.InvalidURLJoin, request.translate_client_path, b'foo/..')
176
 
        self.assertRaises(
177
 
            errors.PathNotChild, request.translate_client_path, b'/')
178
 
        self.assertRaises(
179
 
            errors.PathNotChild, request.translate_client_path, b'bar/')
180
 
        self.assertEqual('./baz', request.translate_client_path(b'foo/baz'))
181
 
        e_acute = u'\N{LATIN SMALL LETTER E WITH ACUTE}'
182
 
        self.assertEqual(
183
 
            u'./' + urlutils.escape(e_acute),
184
 
            request.translate_client_path(b'foo/' + e_acute.encode('utf-8')))
 
164
        self.assertEqual('./', request.translate_client_path('foo/'))
 
165
        self.assertRaises(
 
166
            errors.InvalidURLJoin, request.translate_client_path, 'foo/..')
 
167
        self.assertRaises(
 
168
            errors.PathNotChild, request.translate_client_path, '/')
 
169
        self.assertRaises(
 
170
            errors.PathNotChild, request.translate_client_path, 'bar/')
 
171
        self.assertEqual('./baz', request.translate_client_path('foo/baz'))
 
172
        e_acute = u'\N{LATIN SMALL LETTER E WITH ACUTE}'.encode('utf-8')
 
173
        self.assertEqual('./' + urlutils.escape(e_acute),
 
174
                         request.translate_client_path('foo/' + e_acute))
185
175
 
186
176
    def test_translate_client_path_vfs(self):
187
177
        """VfsRequests receive escaped paths rather than raw UTF-8."""
188
178
        transport = self.get_transport()
189
179
        request = vfs.VfsRequest(transport, 'foo/')
190
 
        e_acute = u'\N{LATIN SMALL LETTER E WITH ACUTE}'
191
 
        escaped = urlutils.escape(u'foo/' + e_acute)
192
 
        self.assertEqual(
193
 
            './' + urlutils.escape(e_acute),
194
 
            request.translate_client_path(escaped.encode('ascii')))
 
180
        e_acute = u'\N{LATIN SMALL LETTER E WITH ACUTE}'.encode('utf-8')
 
181
        escaped = urlutils.escape('foo/' + e_acute)
 
182
        self.assertEqual('./' + urlutils.escape(e_acute),
 
183
                         request.translate_client_path(escaped))
195
184
 
196
185
    def test_transport_from_client_path(self):
197
186
        transport = self.get_transport()
198
187
        request = smart_req.SmartServerRequest(transport, 'foo/')
199
188
        self.assertEqual(
200
189
            transport.base,
201
 
            request.transport_from_client_path(b'foo/').base)
 
190
            request.transport_from_client_path('foo/').base)
202
191
 
203
192
 
204
193
class TestSmartServerBzrDirRequestCloningMetaDir(
205
 
        tests.TestCaseWithMemoryTransport):
 
194
    tests.TestCaseWithMemoryTransport):
206
195
    """Tests for BzrDir.cloning_metadir."""
207
196
 
208
197
    def test_cloning_metadir(self):
209
198
        """When there is a bzrdir present, the call succeeds."""
210
199
        backing = self.get_transport()
211
 
        dir = self.make_controldir('.')
 
200
        dir = self.make_bzrdir('.')
212
201
        local_result = dir.cloning_metadir()
213
202
        request_class = smart_dir.SmartServerBzrDirRequestCloningMetaDir
214
203
        request = request_class(backing)
215
204
        expected = smart_req.SuccessfulSmartServerResponse(
216
205
            (local_result.network_name(),
217
 
             local_result.repository_format.network_name(),
218
 
             (b'branch', local_result.get_branch_format().network_name())))
219
 
        self.assertEqual(expected, request.execute(b'', b'False'))
 
206
            local_result.repository_format.network_name(),
 
207
            ('branch', local_result.get_branch_format().network_name())))
 
208
        self.assertEqual(expected, request.execute('', 'False'))
220
209
 
221
210
    def test_cloning_metadir_reference(self):
222
211
        """The request fails when bzrdir contains a branch reference."""
223
212
        backing = self.get_transport()
224
213
        referenced_branch = self.make_branch('referenced')
225
 
        dir = self.make_controldir('.')
226
 
        dir.cloning_metadir()
227
 
        _mod_bzrbranch.BranchReferenceFormat().initialize(
 
214
        dir = self.make_bzrdir('.')
 
215
        local_result = dir.cloning_metadir()
 
216
        reference = _mod_branch.BranchReferenceFormat().initialize(
228
217
            dir, target_branch=referenced_branch)
229
 
        _mod_bzrbranch.BranchReferenceFormat().get_reference(dir)
 
218
        reference_url = _mod_branch.BranchReferenceFormat().get_reference(dir)
230
219
        # The server shouldn't try to follow the branch reference, so it's fine
231
220
        # if the referenced branch isn't reachable.
232
221
        backing.rename('referenced', 'moved')
233
222
        request_class = smart_dir.SmartServerBzrDirRequestCloningMetaDir
234
223
        request = request_class(backing)
235
 
        expected = smart_req.FailedSmartServerResponse((b'BranchReference',))
236
 
        self.assertEqual(expected, request.execute(b'', b'False'))
237
 
 
238
 
 
239
 
class TestSmartServerBzrDirRequestCheckoutMetaDir(
240
 
        tests.TestCaseWithMemoryTransport):
241
 
    """Tests for BzrDir.checkout_metadir."""
242
 
 
243
 
    def test_checkout_metadir(self):
244
 
        backing = self.get_transport()
245
 
        request = smart_dir.SmartServerBzrDirRequestCheckoutMetaDir(
246
 
            backing)
247
 
        self.make_branch('.', format='2a')
248
 
        response = request.execute(b'')
249
 
        self.assertEqual(
250
 
            smart_req.SmartServerResponse(
251
 
                (b'Bazaar-NG meta directory, format 1\n',
252
 
                 b'Bazaar repository format 2a (needs bzr 1.16 or later)\n',
253
 
                 b'Bazaar Branch Format 7 (needs bzr 1.6)\n')),
254
 
            response)
255
 
 
256
 
 
257
 
class TestSmartServerBzrDirRequestDestroyBranch(
258
 
        tests.TestCaseWithMemoryTransport):
259
 
    """Tests for BzrDir.destroy_branch."""
260
 
 
261
 
    def test_destroy_branch_default(self):
262
 
        """The default branch can be removed."""
263
 
        backing = self.get_transport()
264
 
        self.make_branch('.')
265
 
        request_class = smart_dir.SmartServerBzrDirRequestDestroyBranch
266
 
        request = request_class(backing)
267
 
        expected = smart_req.SuccessfulSmartServerResponse((b'ok',))
268
 
        self.assertEqual(expected, request.execute(b'', None))
269
 
 
270
 
    def test_destroy_branch_named(self):
271
 
        """A named branch can be removed."""
272
 
        backing = self.get_transport()
273
 
        dir = self.make_repository('.', format="development-colo").controldir
274
 
        dir.create_branch(name="branchname")
275
 
        request_class = smart_dir.SmartServerBzrDirRequestDestroyBranch
276
 
        request = request_class(backing)
277
 
        expected = smart_req.SuccessfulSmartServerResponse((b'ok',))
278
 
        self.assertEqual(expected, request.execute(b'', b"branchname"))
279
 
 
280
 
    def test_destroy_branch_missing(self):
281
 
        """An error is raised if the branch didn't exist."""
282
 
        backing = self.get_transport()
283
 
        self.make_controldir('.', format="development-colo")
284
 
        request_class = smart_dir.SmartServerBzrDirRequestDestroyBranch
285
 
        request = request_class(backing)
286
 
        expected = smart_req.FailedSmartServerResponse((b'nobranch',), None)
287
 
        self.assertEqual(expected, request.execute(b'', b"branchname"))
288
 
 
289
 
 
290
 
class TestSmartServerBzrDirRequestHasWorkingTree(
291
 
        tests.TestCaseWithTransport):
292
 
    """Tests for BzrDir.has_workingtree."""
293
 
 
294
 
    def test_has_workingtree_yes(self):
295
 
        """A working tree is present."""
296
 
        backing = self.get_transport()
297
 
        self.make_branch_and_tree('.')
298
 
        request_class = smart_dir.SmartServerBzrDirRequestHasWorkingTree
299
 
        request = request_class(backing)
300
 
        expected = smart_req.SuccessfulSmartServerResponse((b'yes',))
301
 
        self.assertEqual(expected, request.execute(b''))
302
 
 
303
 
    def test_has_workingtree_no(self):
304
 
        """A working tree is missing."""
305
 
        backing = self.get_transport()
306
 
        self.make_controldir('.')
307
 
        request_class = smart_dir.SmartServerBzrDirRequestHasWorkingTree
308
 
        request = request_class(backing)
309
 
        expected = smart_req.SuccessfulSmartServerResponse((b'no',))
310
 
        self.assertEqual(expected, request.execute(b''))
311
 
 
312
 
 
313
 
class TestSmartServerBzrDirRequestDestroyRepository(
314
 
        tests.TestCaseWithMemoryTransport):
315
 
    """Tests for BzrDir.destroy_repository."""
316
 
 
317
 
    def test_destroy_repository_default(self):
318
 
        """The repository can be removed."""
319
 
        backing = self.get_transport()
320
 
        self.make_repository('.')
321
 
        request_class = smart_dir.SmartServerBzrDirRequestDestroyRepository
322
 
        request = request_class(backing)
323
 
        expected = smart_req.SuccessfulSmartServerResponse((b'ok',))
324
 
        self.assertEqual(expected, request.execute(b''))
325
 
 
326
 
    def test_destroy_repository_missing(self):
327
 
        """An error is raised if the repository didn't exist."""
328
 
        backing = self.get_transport()
329
 
        self.make_controldir('.')
330
 
        request_class = smart_dir.SmartServerBzrDirRequestDestroyRepository
331
 
        request = request_class(backing)
332
 
        expected = smart_req.FailedSmartServerResponse(
333
 
            (b'norepository',), None)
334
 
        self.assertEqual(expected, request.execute(b''))
335
 
 
336
 
 
337
 
class TestSmartServerRequestCreateRepository(
338
 
        tests.TestCaseWithMemoryTransport):
 
224
        expected = smart_req.FailedSmartServerResponse(('BranchReference',))
 
225
        self.assertEqual(expected, request.execute('', 'False'))
 
226
 
 
227
 
 
228
class TestSmartServerRequestCreateRepository(tests.TestCaseWithMemoryTransport):
339
229
    """Tests for BzrDir.create_repository."""
340
230
 
341
231
    def test_makes_repository(self):
342
232
        """When there is a bzrdir present, the call succeeds."""
343
233
        backing = self.get_transport()
344
 
        self.make_controldir('.')
 
234
        self.make_bzrdir('.')
345
235
        request_class = smart_dir.SmartServerRequestCreateRepository
346
236
        request = request_class(backing)
347
 
        reference_bzrdir_format = controldir.format_registry.get('pack-0.92')()
 
237
        reference_bzrdir_format = bzrdir.format_registry.get('pack-0.92')()
348
238
        reference_format = reference_bzrdir_format.repository_format
349
239
        network_name = reference_format.network_name()
350
240
        expected = smart_req.SuccessfulSmartServerResponse(
351
 
            (b'ok', b'no', b'no', b'no', network_name))
352
 
        self.assertEqual(expected, request.execute(b'', network_name, b'True'))
 
241
            ('ok', 'no', 'no', 'no', network_name))
 
242
        self.assertEqual(expected, request.execute('', network_name, 'True'))
353
243
 
354
244
 
355
245
class TestSmartServerRequestFindRepository(tests.TestCaseWithMemoryTransport):
356
246
    """Tests for BzrDir.find_repository."""
357
247
 
358
248
    def test_no_repository(self):
359
 
        """If no repository is found, ('norepository', ) is returned."""
 
249
        """When there is no repository to be found, ('norepository', ) is returned."""
360
250
        backing = self.get_transport()
361
251
        request = self._request_class(backing)
362
 
        self.make_controldir('.')
363
 
        self.assertEqual(smart_req.SmartServerResponse((b'norepository', )),
364
 
                         request.execute(b''))
 
252
        self.make_bzrdir('.')
 
253
        self.assertEqual(smart_req.SmartServerResponse(('norepository', )),
 
254
            request.execute(''))
365
255
 
366
256
    def test_nonshared_repository(self):
367
257
        # nonshared repositorys only allow 'find' to return a handle when the
370
260
        backing = self.get_transport()
371
261
        request = self._request_class(backing)
372
262
        result = self._make_repository_and_result()
373
 
        self.assertEqual(result, request.execute(b''))
374
 
        self.make_controldir('subdir')
375
 
        self.assertEqual(smart_req.SmartServerResponse((b'norepository', )),
376
 
                         request.execute(b'subdir'))
 
263
        self.assertEqual(result, request.execute(''))
 
264
        self.make_bzrdir('subdir')
 
265
        self.assertEqual(smart_req.SmartServerResponse(('norepository', )),
 
266
            request.execute('subdir'))
377
267
 
378
268
    def _make_repository_and_result(self, shared=False, format=None):
379
269
        """Convenience function to setup a repository.
382
272
        """
383
273
        repo = self.make_repository('.', shared=shared, format=format)
384
274
        if repo.supports_rich_root():
385
 
            rich_root = b'yes'
 
275
            rich_root = 'yes'
386
276
        else:
387
 
            rich_root = b'no'
 
277
            rich_root = 'no'
388
278
        if repo._format.supports_tree_reference:
389
 
            subtrees = b'yes'
 
279
            subtrees = 'yes'
390
280
        else:
391
 
            subtrees = b'no'
 
281
            subtrees = 'no'
392
282
        if repo._format.supports_external_lookups:
393
 
            external = b'yes'
 
283
            external = 'yes'
394
284
        else:
395
 
            external = b'no'
 
285
            external = 'no'
396
286
        if (smart_dir.SmartServerRequestFindRepositoryV3 ==
397
 
                self._request_class):
 
287
            self._request_class):
398
288
            return smart_req.SuccessfulSmartServerResponse(
399
 
                (b'ok', b'', rich_root, subtrees, external,
 
289
                ('ok', '', rich_root, subtrees, external,
400
290
                 repo._format.network_name()))
401
291
        elif (smart_dir.SmartServerRequestFindRepositoryV2 ==
402
 
              self._request_class):
 
292
            self._request_class):
403
293
            # All tests so far are on formats, and for non-external
404
294
            # repositories.
405
295
            return smart_req.SuccessfulSmartServerResponse(
406
 
                (b'ok', b'', rich_root, subtrees, external))
 
296
                ('ok', '', rich_root, subtrees, external))
407
297
        else:
408
298
            return smart_req.SuccessfulSmartServerResponse(
409
 
                (b'ok', b'', rich_root, subtrees))
 
299
                ('ok', '', rich_root, subtrees))
410
300
 
411
301
    def test_shared_repository(self):
412
 
        """for a shared repository, we get 'ok', 'relpath-to-repo'."""
 
302
        """When there is a shared repository, we get 'ok', 'relpath-to-repo'."""
413
303
        backing = self.get_transport()
414
304
        request = self._request_class(backing)
415
305
        result = self._make_repository_and_result(shared=True)
416
 
        self.assertEqual(result, request.execute(b''))
417
 
        self.make_controldir('subdir')
 
306
        self.assertEqual(result, request.execute(''))
 
307
        self.make_bzrdir('subdir')
418
308
        result2 = smart_req.SmartServerResponse(
419
 
            result.args[0:1] + (b'..', ) + result.args[2:])
 
309
            result.args[0:1] + ('..', ) + result.args[2:])
420
310
        self.assertEqual(result2,
421
 
                         request.execute(b'subdir'))
422
 
        self.make_controldir('subdir/deeper')
 
311
            request.execute('subdir'))
 
312
        self.make_bzrdir('subdir/deeper')
423
313
        result3 = smart_req.SmartServerResponse(
424
 
            result.args[0:1] + (b'../..', ) + result.args[2:])
 
314
            result.args[0:1] + ('../..', ) + result.args[2:])
425
315
        self.assertEqual(result3,
426
 
                         request.execute(b'subdir/deeper'))
 
316
            request.execute('subdir/deeper'))
427
317
 
428
318
    def test_rich_root_and_subtree_encoding(self):
429
319
        """Test for the format attributes for rich root and subtree support."""
430
320
        backing = self.get_transport()
431
321
        request = self._request_class(backing)
432
322
        result = self._make_repository_and_result(
433
 
            format='development-subtree')
 
323
            format='dirstate-with-subtree')
434
324
        # check the test will be valid
435
 
        self.assertEqual(b'yes', result.args[2])
436
 
        self.assertEqual(b'yes', result.args[3])
437
 
        self.assertEqual(result, request.execute(b''))
 
325
        self.assertEqual('yes', result.args[2])
 
326
        self.assertEqual('yes', result.args[3])
 
327
        self.assertEqual(result, request.execute(''))
438
328
 
439
329
    def test_supports_external_lookups_no_v2(self):
440
330
        """Test for the supports_external_lookups attribute."""
441
331
        backing = self.get_transport()
442
332
        request = self._request_class(backing)
443
333
        result = self._make_repository_and_result(
444
 
            format='development-subtree')
 
334
            format='dirstate-with-subtree')
445
335
        # check the test will be valid
446
 
        self.assertEqual(b'yes', result.args[4])
447
 
        self.assertEqual(result, request.execute(b''))
 
336
        self.assertEqual('no', result.args[4])
 
337
        self.assertEqual(result, request.execute(''))
448
338
 
449
339
 
450
340
class TestSmartServerBzrDirRequestGetConfigFile(
451
 
        tests.TestCaseWithMemoryTransport):
 
341
    tests.TestCaseWithMemoryTransport):
452
342
    """Tests for BzrDir.get_config_file."""
453
343
 
454
344
    def test_present(self):
455
345
        backing = self.get_transport()
456
 
        dir = self.make_controldir('.')
 
346
        dir = self.make_bzrdir('.')
457
347
        dir.get_config().set_default_stack_on("/")
458
348
        local_result = dir._get_config()._get_config_file().read()
459
349
        request_class = smart_dir.SmartServerBzrDirRequestConfigFile
460
350
        request = request_class(backing)
461
351
        expected = smart_req.SuccessfulSmartServerResponse((), local_result)
462
 
        self.assertEqual(expected, request.execute(b''))
 
352
        self.assertEqual(expected, request.execute(''))
463
353
 
464
354
    def test_missing(self):
465
355
        backing = self.get_transport()
466
 
        self.make_controldir('.')
 
356
        dir = self.make_bzrdir('.')
467
357
        request_class = smart_dir.SmartServerBzrDirRequestConfigFile
468
358
        request = request_class(backing)
469
 
        expected = smart_req.SuccessfulSmartServerResponse((), b'')
470
 
        self.assertEqual(expected, request.execute(b''))
471
 
 
472
 
 
473
 
class TestSmartServerBzrDirRequestGetBranches(
474
 
        tests.TestCaseWithMemoryTransport):
475
 
    """Tests for BzrDir.get_branches."""
476
 
 
477
 
    def test_simple(self):
478
 
        backing = self.get_transport()
479
 
        branch = self.make_branch('.')
480
 
        request_class = smart_dir.SmartServerBzrDirRequestGetBranches
481
 
        request = request_class(backing)
482
 
        local_result = bencode.bencode(
483
 
            {b"": (b"branch", branch._format.network_name())})
484
 
        expected = smart_req.SuccessfulSmartServerResponse(
485
 
            (b"success", ), local_result)
486
 
        self.assertEqual(expected, request.execute(b''))
487
 
 
488
 
    def test_ref(self):
489
 
        backing = self.get_transport()
490
 
        dir = self.make_controldir('foo')
491
 
        b = self.make_branch('bar')
492
 
        dir.set_branch_reference(b)
493
 
        request_class = smart_dir.SmartServerBzrDirRequestGetBranches
494
 
        request = request_class(backing)
495
 
        local_result = bencode.bencode(
496
 
            {b"": (b"ref", b'../bar/')})
497
 
        expected = smart_req.SuccessfulSmartServerResponse(
498
 
            (b"success", ), local_result)
499
 
        self.assertEqual(expected, request.execute(b'foo'))
500
 
 
501
 
    def test_empty(self):
502
 
        backing = self.get_transport()
503
 
        self.make_controldir('.')
504
 
        request_class = smart_dir.SmartServerBzrDirRequestGetBranches
505
 
        request = request_class(backing)
506
 
        local_result = bencode.bencode({})
507
 
        expected = smart_req.SuccessfulSmartServerResponse(
508
 
            (b'success',), local_result)
509
 
        self.assertEqual(expected, request.execute(b''))
510
 
 
511
 
 
512
 
class TestSmartServerRequestInitializeBzrDir(
513
 
        tests.TestCaseWithMemoryTransport):
 
359
        expected = smart_req.SuccessfulSmartServerResponse((), '')
 
360
        self.assertEqual(expected, request.execute(''))
 
361
 
 
362
 
 
363
class TestSmartServerRequestInitializeBzrDir(tests.TestCaseWithMemoryTransport):
514
364
 
515
365
    def test_empty_dir(self):
516
366
        """Initializing an empty dir should succeed and do it."""
517
367
        backing = self.get_transport()
518
368
        request = smart_dir.SmartServerRequestInitializeBzrDir(backing)
519
 
        self.assertEqual(smart_req.SmartServerResponse((b'ok', )),
520
 
                         request.execute(b''))
521
 
        made_dir = controldir.ControlDir.open_from_transport(backing)
 
369
        self.assertEqual(smart_req.SmartServerResponse(('ok', )),
 
370
            request.execute(''))
 
371
        made_dir = bzrdir.BzrDir.open_from_transport(backing)
522
372
        # no branch, tree or repository is expected with the current
523
373
        # default formart.
524
374
        self.assertRaises(errors.NoWorkingTree, made_dir.open_workingtree)
530
380
        backing = self.get_transport()
531
381
        request = smart_dir.SmartServerRequestInitializeBzrDir(backing)
532
382
        self.assertRaises(errors.NoSuchFile,
533
 
                          request.execute, b'subdir')
 
383
            request.execute, 'subdir')
534
384
 
535
385
    def test_initialized_dir(self):
536
386
        """Initializing an extant bzrdir should fail like the bzrdir api."""
537
387
        backing = self.get_transport()
538
388
        request = smart_dir.SmartServerRequestInitializeBzrDir(backing)
539
 
        self.make_controldir('subdir')
540
 
        self.assertRaises(errors.AlreadyControlDirError,
541
 
                          request.execute, b'subdir')
 
389
        self.make_bzrdir('subdir')
 
390
        self.assertRaises(errors.FileExists,
 
391
            request.execute, 'subdir')
542
392
 
543
393
 
544
394
class TestSmartServerRequestBzrDirInitializeEx(
545
 
        tests.TestCaseWithMemoryTransport):
 
395
    tests.TestCaseWithMemoryTransport):
546
396
    """Basic tests for BzrDir.initialize_ex_1.16 in the smart server.
547
397
 
548
398
    The main unit tests in test_bzrdir exercise the API comprehensively.
551
401
    def test_empty_dir(self):
552
402
        """Initializing an empty dir should succeed and do it."""
553
403
        backing = self.get_transport()
554
 
        name = self.make_controldir('reference')._format.network_name()
 
404
        name = self.make_bzrdir('reference')._format.network_name()
555
405
        request = smart_dir.SmartServerRequestBzrDirInitializeEx(backing)
556
406
        self.assertEqual(
557
 
            smart_req.SmartServerResponse((b'', b'', b'', b'', b'', b'', name,
558
 
                                           b'False', b'', b'', b'')),
559
 
            request.execute(name, b'', b'True', b'False', b'False', b'', b'',
560
 
                            b'', b'', b'False'))
561
 
        made_dir = controldir.ControlDir.open_from_transport(backing)
 
407
            smart_req.SmartServerResponse(('', '', '', '', '', '', name,
 
408
                                           'False', '', '', '')),
 
409
            request.execute(name, '', 'True', 'False', 'False', '', '', '', '',
 
410
                            'False'))
 
411
        made_dir = bzrdir.BzrDir.open_from_transport(backing)
562
412
        # no branch, tree or repository is expected with the current
563
413
        # default format.
564
414
        self.assertRaises(errors.NoWorkingTree, made_dir.open_workingtree)
568
418
    def test_missing_dir(self):
569
419
        """Initializing a missing directory should fail like the bzrdir api."""
570
420
        backing = self.get_transport()
571
 
        name = self.make_controldir('reference')._format.network_name()
 
421
        name = self.make_bzrdir('reference')._format.network_name()
572
422
        request = smart_dir.SmartServerRequestBzrDirInitializeEx(backing)
573
423
        self.assertRaises(errors.NoSuchFile, request.execute, name,
574
 
                          b'subdir/dir', b'False', b'False', b'False', b'',
575
 
                          b'', b'', b'', b'False')
 
424
            'subdir/dir', 'False', 'False', 'False', '', '', '', '', 'False')
576
425
 
577
426
    def test_initialized_dir(self):
578
427
        """Initializing an extant directory should fail like the bzrdir api."""
579
428
        backing = self.get_transport()
580
 
        name = self.make_controldir('reference')._format.network_name()
 
429
        name = self.make_bzrdir('reference')._format.network_name()
581
430
        request = smart_dir.SmartServerRequestBzrDirInitializeEx(backing)
582
 
        self.make_controldir('subdir')
583
 
        self.assertRaises(errors.FileExists, request.execute, name, b'subdir',
584
 
                          b'False', b'False', b'False', b'', b'', b'', b'',
585
 
                          b'False')
 
431
        self.make_bzrdir('subdir')
 
432
        self.assertRaises(errors.FileExists, request.execute, name, 'subdir',
 
433
            'False', 'False', 'False', '', '', '', '', 'False')
586
434
 
587
435
 
588
436
class TestSmartServerRequestOpenBzrDir(tests.TestCaseWithMemoryTransport):
590
438
    def test_no_directory(self):
591
439
        backing = self.get_transport()
592
440
        request = smart_dir.SmartServerRequestOpenBzrDir(backing)
593
 
        self.assertEqual(smart_req.SmartServerResponse((b'no', )),
594
 
                         request.execute(b'does-not-exist'))
 
441
        self.assertEqual(smart_req.SmartServerResponse(('no', )),
 
442
            request.execute('does-not-exist'))
595
443
 
596
444
    def test_empty_directory(self):
597
445
        backing = self.get_transport()
598
446
        backing.mkdir('empty')
599
447
        request = smart_dir.SmartServerRequestOpenBzrDir(backing)
600
 
        self.assertEqual(smart_req.SmartServerResponse((b'no', )),
601
 
                         request.execute(b'empty'))
 
448
        self.assertEqual(smart_req.SmartServerResponse(('no', )),
 
449
            request.execute('empty'))
602
450
 
603
451
    def test_outside_root_client_path(self):
604
452
        backing = self.get_transport()
605
 
        request = smart_dir.SmartServerRequestOpenBzrDir(
606
 
            backing, root_client_path='root')
607
 
        self.assertEqual(smart_req.SmartServerResponse((b'no', )),
608
 
                         request.execute(b'not-root'))
 
453
        request = smart_dir.SmartServerRequestOpenBzrDir(backing,
 
454
            root_client_path='root')
 
455
        self.assertEqual(smart_req.SmartServerResponse(('no', )),
 
456
            request.execute('not-root'))
609
457
 
610
458
 
611
459
class TestSmartServerRequestOpenBzrDir_2_1(tests.TestCaseWithMemoryTransport):
613
461
    def test_no_directory(self):
614
462
        backing = self.get_transport()
615
463
        request = smart_dir.SmartServerRequestOpenBzrDir_2_1(backing)
616
 
        self.assertEqual(smart_req.SmartServerResponse((b'no', )),
617
 
                         request.execute(b'does-not-exist'))
 
464
        self.assertEqual(smart_req.SmartServerResponse(('no', )),
 
465
            request.execute('does-not-exist'))
618
466
 
619
467
    def test_empty_directory(self):
620
468
        backing = self.get_transport()
621
469
        backing.mkdir('empty')
622
470
        request = smart_dir.SmartServerRequestOpenBzrDir_2_1(backing)
623
 
        self.assertEqual(smart_req.SmartServerResponse((b'no', )),
624
 
                         request.execute(b'empty'))
 
471
        self.assertEqual(smart_req.SmartServerResponse(('no', )),
 
472
            request.execute('empty'))
625
473
 
626
474
    def test_present_without_workingtree(self):
627
475
        backing = self.get_transport()
628
476
        request = smart_dir.SmartServerRequestOpenBzrDir_2_1(backing)
629
 
        self.make_controldir('.')
630
 
        self.assertEqual(smart_req.SmartServerResponse((b'yes', b'no')),
631
 
                         request.execute(b''))
 
477
        self.make_bzrdir('.')
 
478
        self.assertEqual(smart_req.SmartServerResponse(('yes', 'no')),
 
479
            request.execute(''))
632
480
 
633
481
    def test_outside_root_client_path(self):
634
482
        backing = self.get_transport()
635
 
        request = smart_dir.SmartServerRequestOpenBzrDir_2_1(
636
 
            backing, root_client_path='root')
637
 
        self.assertEqual(smart_req.SmartServerResponse((b'no',)),
638
 
                         request.execute(b'not-root'))
 
483
        request = smart_dir.SmartServerRequestOpenBzrDir_2_1(backing,
 
484
            root_client_path='root')
 
485
        self.assertEqual(smart_req.SmartServerResponse(('no',)),
 
486
            request.execute('not-root'))
639
487
 
640
488
 
641
489
class TestSmartServerRequestOpenBzrDir_2_1_disk(TestCaseWithChrootedTransport):
644
492
        self.vfs_transport_factory = test_server.LocalURLServer
645
493
        backing = self.get_transport()
646
494
        request = smart_dir.SmartServerRequestOpenBzrDir_2_1(backing)
647
 
        bd = self.make_controldir('.')
 
495
        bd = self.make_bzrdir('.')
648
496
        bd.create_repository()
649
497
        bd.create_branch()
650
498
        bd.create_workingtree()
651
 
        self.assertEqual(smart_req.SmartServerResponse((b'yes', b'yes')),
652
 
                         request.execute(b''))
 
499
        self.assertEqual(smart_req.SmartServerResponse(('yes', 'yes')),
 
500
            request.execute(''))
653
501
 
654
502
 
655
503
class TestSmartServerRequestOpenBranch(TestCaseWithChrootedTransport):
658
506
        """When there is no branch, ('nobranch', ) is returned."""
659
507
        backing = self.get_transport()
660
508
        request = smart_dir.SmartServerRequestOpenBranch(backing)
661
 
        self.make_controldir('.')
662
 
        self.assertEqual(smart_req.SmartServerResponse((b'nobranch', )),
663
 
                         request.execute(b''))
 
509
        self.make_bzrdir('.')
 
510
        self.assertEqual(smart_req.SmartServerResponse(('nobranch', )),
 
511
            request.execute(''))
664
512
 
665
513
    def test_branch(self):
666
514
        """When there is a branch, 'ok' is returned."""
667
515
        backing = self.get_transport()
668
516
        request = smart_dir.SmartServerRequestOpenBranch(backing)
669
517
        self.make_branch('.')
670
 
        self.assertEqual(smart_req.SmartServerResponse((b'ok', b'')),
671
 
                         request.execute(b''))
 
518
        self.assertEqual(smart_req.SmartServerResponse(('ok', '')),
 
519
            request.execute(''))
672
520
 
673
521
    def test_branch_reference(self):
674
522
        """When there is a branch reference, the reference URL is returned."""
676
524
        backing = self.get_transport()
677
525
        request = smart_dir.SmartServerRequestOpenBranch(backing)
678
526
        branch = self.make_branch('branch')
679
 
        checkout = branch.create_checkout('reference', lightweight=True)
680
 
        reference_url = _mod_bzrbranch.BranchReferenceFormat().get_reference(
681
 
            checkout.controldir).encode('utf-8')
 
527
        checkout = branch.create_checkout('reference',lightweight=True)
 
528
        reference_url = _mod_branch.BranchReferenceFormat().get_reference(
 
529
            checkout.bzrdir)
682
530
        self.assertFileEqual(reference_url, 'reference/.bzr/branch/location')
683
 
        self.assertEqual(smart_req.SmartServerResponse((b'ok', reference_url)),
684
 
                         request.execute(b'reference'))
 
531
        self.assertEqual(smart_req.SmartServerResponse(('ok', reference_url)),
 
532
            request.execute('reference'))
685
533
 
686
534
    def test_notification_on_branch_from_repository(self):
687
535
        """When there is a repository, the error should return details."""
688
536
        backing = self.get_transport()
689
537
        request = smart_dir.SmartServerRequestOpenBranch(backing)
690
 
        self.make_repository('.')
691
 
        self.assertEqual(smart_req.SmartServerResponse((b'nobranch',)),
692
 
                         request.execute(b''))
 
538
        repo = self.make_repository('.')
 
539
        self.assertEqual(smart_req.SmartServerResponse(('nobranch',)),
 
540
            request.execute(''))
693
541
 
694
542
 
695
543
class TestSmartServerRequestOpenBranchV2(TestCaseWithChrootedTransport):
697
545
    def test_no_branch(self):
698
546
        """When there is no branch, ('nobranch', ) is returned."""
699
547
        backing = self.get_transport()
700
 
        self.make_controldir('.')
 
548
        self.make_bzrdir('.')
701
549
        request = smart_dir.SmartServerRequestOpenBranchV2(backing)
702
 
        self.assertEqual(smart_req.SmartServerResponse((b'nobranch', )),
703
 
                         request.execute(b''))
 
550
        self.assertEqual(smart_req.SmartServerResponse(('nobranch', )),
 
551
            request.execute(''))
704
552
 
705
553
    def test_branch(self):
706
554
        """When there is a branch, 'ok' is returned."""
708
556
        expected = self.make_branch('.')._format.network_name()
709
557
        request = smart_dir.SmartServerRequestOpenBranchV2(backing)
710
558
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(
711
 
            (b'branch', expected)),
712
 
            request.execute(b''))
 
559
                ('branch', expected)),
 
560
                         request.execute(''))
713
561
 
714
562
    def test_branch_reference(self):
715
563
        """When there is a branch reference, the reference URL is returned."""
717
565
        backing = self.get_transport()
718
566
        request = smart_dir.SmartServerRequestOpenBranchV2(backing)
719
567
        branch = self.make_branch('branch')
720
 
        checkout = branch.create_checkout('reference', lightweight=True)
721
 
        reference_url = _mod_bzrbranch.BranchReferenceFormat().get_reference(
722
 
            checkout.controldir).encode('utf-8')
 
568
        checkout = branch.create_checkout('reference',lightweight=True)
 
569
        reference_url = _mod_branch.BranchReferenceFormat().get_reference(
 
570
            checkout.bzrdir)
723
571
        self.assertFileEqual(reference_url, 'reference/.bzr/branch/location')
724
572
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(
725
 
            (b'ref', reference_url)),
726
 
            request.execute(b'reference'))
 
573
                ('ref', reference_url)),
 
574
                         request.execute('reference'))
727
575
 
728
576
    def test_stacked_branch(self):
729
577
        """Opening a stacked branch does not open the stacked-on branch."""
737
585
        request = smart_dir.SmartServerRequestOpenBranchV2(backing)
738
586
        request.setup_jail()
739
587
        try:
740
 
            response = request.execute(b'feature')
 
588
            response = request.execute('feature')
741
589
        finally:
742
590
            request.teardown_jail()
743
591
        expected_format = feature._format.network_name()
744
592
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(
745
 
            (b'branch', expected_format)),
746
 
            response)
 
593
                ('branch', expected_format)),
 
594
                         response)
747
595
        self.assertLength(1, opened_branches)
748
596
 
749
597
    def test_notification_on_branch_from_repository(self):
750
598
        """When there is a repository, the error should return details."""
751
599
        backing = self.get_transport()
752
600
        request = smart_dir.SmartServerRequestOpenBranchV2(backing)
753
 
        self.make_repository('.')
754
 
        self.assertEqual(smart_req.SmartServerResponse((b'nobranch',)),
755
 
                         request.execute(b''))
 
601
        repo = self.make_repository('.')
 
602
        self.assertEqual(smart_req.SmartServerResponse(('nobranch',)),
 
603
            request.execute(''))
756
604
 
757
605
 
758
606
class TestSmartServerRequestOpenBranchV3(TestCaseWithChrootedTransport):
760
608
    def test_no_branch(self):
761
609
        """When there is no branch, ('nobranch', ) is returned."""
762
610
        backing = self.get_transport()
763
 
        self.make_controldir('.')
 
611
        self.make_bzrdir('.')
764
612
        request = smart_dir.SmartServerRequestOpenBranchV3(backing)
765
 
        self.assertEqual(smart_req.SmartServerResponse((b'nobranch',)),
766
 
                         request.execute(b''))
 
613
        self.assertEqual(smart_req.SmartServerResponse(('nobranch',)),
 
614
            request.execute(''))
767
615
 
768
616
    def test_branch(self):
769
617
        """When there is a branch, 'ok' is returned."""
771
619
        expected = self.make_branch('.')._format.network_name()
772
620
        request = smart_dir.SmartServerRequestOpenBranchV3(backing)
773
621
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(
774
 
            (b'branch', expected)),
775
 
            request.execute(b''))
 
622
                ('branch', expected)),
 
623
                         request.execute(''))
776
624
 
777
625
    def test_branch_reference(self):
778
626
        """When there is a branch reference, the reference URL is returned."""
780
628
        backing = self.get_transport()
781
629
        request = smart_dir.SmartServerRequestOpenBranchV3(backing)
782
630
        branch = self.make_branch('branch')
783
 
        checkout = branch.create_checkout('reference', lightweight=True)
784
 
        reference_url = _mod_bzrbranch.BranchReferenceFormat().get_reference(
785
 
            checkout.controldir).encode('utf-8')
 
631
        checkout = branch.create_checkout('reference',lightweight=True)
 
632
        reference_url = _mod_branch.BranchReferenceFormat().get_reference(
 
633
            checkout.bzrdir)
786
634
        self.assertFileEqual(reference_url, 'reference/.bzr/branch/location')
787
635
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(
788
 
            (b'ref', reference_url)),
789
 
            request.execute(b'reference'))
 
636
                ('ref', reference_url)),
 
637
                         request.execute('reference'))
790
638
 
791
639
    def test_stacked_branch(self):
792
640
        """Opening a stacked branch does not open the stacked-on branch."""
800
648
        request = smart_dir.SmartServerRequestOpenBranchV3(backing)
801
649
        request.setup_jail()
802
650
        try:
803
 
            response = request.execute(b'feature')
 
651
            response = request.execute('feature')
804
652
        finally:
805
653
            request.teardown_jail()
806
654
        expected_format = feature._format.network_name()
807
655
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(
808
 
            (b'branch', expected_format)),
809
 
            response)
 
656
                ('branch', expected_format)),
 
657
                         response)
810
658
        self.assertLength(1, opened_branches)
811
659
 
812
660
    def test_notification_on_branch_from_repository(self):
813
661
        """When there is a repository, the error should return details."""
814
662
        backing = self.get_transport()
815
663
        request = smart_dir.SmartServerRequestOpenBranchV3(backing)
816
 
        self.make_repository('.')
 
664
        repo = self.make_repository('.')
817
665
        self.assertEqual(smart_req.SmartServerResponse(
818
 
            (b'nobranch', b'location is a repository')),
819
 
            request.execute(b''))
 
666
                ('nobranch', 'location is a repository')),
 
667
                         request.execute(''))
820
668
 
821
669
 
822
670
class TestSmartServerRequestRevisionHistory(tests.TestCaseWithMemoryTransport):
826
674
        backing = self.get_transport()
827
675
        request = smart_branch.SmartServerRequestRevisionHistory(backing)
828
676
        self.make_branch('.')
829
 
        self.assertEqual(smart_req.SmartServerResponse((b'ok', ), b''),
830
 
                         request.execute(b''))
 
677
        self.assertEqual(smart_req.SmartServerResponse(('ok', ), ''),
 
678
            request.execute(''))
831
679
 
832
680
    def test_not_empty(self):
833
681
        """For a non-empty branch, the body is empty."""
840
688
        r2 = tree.commit('2nd commit', rev_id=u'\xc8'.encode('utf-8'))
841
689
        tree.unlock()
842
690
        self.assertEqual(
843
 
            smart_req.SmartServerResponse((b'ok', ), (b'\x00'.join([r1, r2]))),
844
 
            request.execute(b''))
 
691
            smart_req.SmartServerResponse(('ok', ), ('\x00'.join([r1, r2]))),
 
692
            request.execute(''))
845
693
 
846
694
 
847
695
class TestSmartServerBranchRequest(tests.TestCaseWithMemoryTransport):
850
698
        """When there is a bzrdir and no branch, NotBranchError is raised."""
851
699
        backing = self.get_transport()
852
700
        request = smart_branch.SmartServerBranchRequest(backing)
853
 
        self.make_controldir('.')
 
701
        self.make_bzrdir('.')
854
702
        self.assertRaises(errors.NotBranchError,
855
 
                          request.execute, b'')
 
703
            request.execute, '')
856
704
 
857
705
    def test_branch_reference(self):
858
706
        """When there is a branch reference, NotBranchError is raised."""
859
707
        backing = self.get_transport()
860
708
        request = smart_branch.SmartServerBranchRequest(backing)
861
709
        branch = self.make_branch('branch')
862
 
        branch.create_checkout('reference', lightweight=True)
 
710
        checkout = branch.create_checkout('reference',lightweight=True)
863
711
        self.assertRaises(errors.NotBranchError,
864
 
                          request.execute, b'checkout')
 
712
            request.execute, 'checkout')
865
713
 
866
714
 
867
715
class TestSmartServerBranchRequestLastRevisionInfo(
868
 
        tests.TestCaseWithMemoryTransport):
 
716
    tests.TestCaseWithMemoryTransport):
869
717
 
870
718
    def test_empty(self):
871
 
        """For an empty branch, the result is ('ok', '0', b'null:')."""
 
719
        """For an empty branch, the result is ('ok', '0', 'null:')."""
872
720
        backing = self.get_transport()
873
 
        request = smart_branch.SmartServerBranchRequestLastRevisionInfo(
874
 
            backing)
 
721
        request = smart_branch.SmartServerBranchRequestLastRevisionInfo(backing)
875
722
        self.make_branch('.')
876
 
        self.assertEqual(
877
 
            smart_req.SmartServerResponse((b'ok', b'0', b'null:')),
878
 
            request.execute(b''))
879
 
 
880
 
    def test_ghost(self):
881
 
        """For an empty branch, the result is ('ok', '0', b'null:')."""
882
 
        backing = self.get_transport()
883
 
        request = smart_branch.SmartServerBranchRequestLastRevisionInfo(
884
 
            backing)
885
 
        branch = self.make_branch('.')
886
 
 
887
 
        def last_revision_info():
888
 
            raise errors.GhostRevisionsHaveNoRevno(b'revid1', b'revid2')
889
 
        self.overrideAttr(branch, 'last_revision_info', last_revision_info)
890
 
        self.assertRaises(errors.GhostRevisionsHaveNoRevno,
891
 
                          request.do_with_branch, branch)
 
723
        self.assertEqual(smart_req.SmartServerResponse(('ok', '0', 'null:')),
 
724
            request.execute(''))
892
725
 
893
726
    def test_not_empty(self):
894
727
        """For a non-empty branch, the result is ('ok', 'revno', 'revid')."""
895
728
        backing = self.get_transport()
896
 
        request = smart_branch.SmartServerBranchRequestLastRevisionInfo(
897
 
            backing)
 
729
        request = smart_branch.SmartServerBranchRequestLastRevisionInfo(backing)
898
730
        tree = self.make_branch_and_memory_tree('.')
899
731
        tree.lock_write()
900
732
        tree.add('')
901
733
        rev_id_utf8 = u'\xc8'.encode('utf-8')
902
 
        tree.commit('1st commit')
903
 
        tree.commit('2nd commit', rev_id=rev_id_utf8)
904
 
        tree.unlock()
905
 
        self.assertEqual(
906
 
            smart_req.SmartServerResponse((b'ok', b'2', rev_id_utf8)),
907
 
            request.execute(b''))
908
 
 
909
 
 
910
 
class TestSmartServerBranchRequestRevisionIdToRevno(
911
 
        tests.TestCaseWithMemoryTransport):
912
 
 
913
 
    def test_null(self):
914
 
        backing = self.get_transport()
915
 
        request = smart_branch.SmartServerBranchRequestRevisionIdToRevno(
916
 
            backing)
917
 
        self.make_branch('.')
918
 
        self.assertEqual(smart_req.SmartServerResponse((b'ok', b'0')),
919
 
                         request.execute(b'', b'null:'))
920
 
 
921
 
    def test_ghost_revision(self):
922
 
        backing = self.get_transport()
923
 
        request = smart_branch.SmartServerBranchRequestRevisionIdToRevno(
924
 
            backing)
925
 
        branch = self.make_branch('.')
926
 
        def revision_id_to_dotted_revno(revid):
927
 
            raise errors.GhostRevisionsHaveNoRevno(revid, b'ghost-revid')
928
 
        self.overrideAttr(branch, 'revision_id_to_dotted_revno', revision_id_to_dotted_revno)
929
 
        self.assertEqual(
930
 
            smart_req.FailedSmartServerResponse(
931
 
                (b'GhostRevisionsHaveNoRevno', b'revid', b'ghost-revid')),
932
 
            request.do_with_branch(branch, b'revid'))
933
 
 
934
 
    def test_simple(self):
935
 
        backing = self.get_transport()
936
 
        request = smart_branch.SmartServerBranchRequestRevisionIdToRevno(
937
 
            backing)
938
 
        tree = self.make_branch_and_memory_tree('.')
939
 
        tree.lock_write()
940
 
        tree.add('')
941
734
        r1 = tree.commit('1st commit')
 
735
        r2 = tree.commit('2nd commit', rev_id=rev_id_utf8)
942
736
        tree.unlock()
943
737
        self.assertEqual(
944
 
            smart_req.SmartServerResponse((b'ok', b'1')),
945
 
            request.execute(b'', r1))
946
 
 
947
 
    def test_not_found(self):
948
 
        backing = self.get_transport()
949
 
        request = smart_branch.SmartServerBranchRequestRevisionIdToRevno(
950
 
            backing)
951
 
        self.make_branch('.')
952
 
        self.assertEqual(
953
 
            smart_req.FailedSmartServerResponse(
954
 
                (b'NoSuchRevision', b'idontexist')),
955
 
            request.execute(b'', b'idontexist'))
 
738
            smart_req.SmartServerResponse(('ok', '2', rev_id_utf8)),
 
739
            request.execute(''))
956
740
 
957
741
 
958
742
class TestSmartServerBranchRequestGetConfigFile(
959
 
        tests.TestCaseWithMemoryTransport):
 
743
    tests.TestCaseWithMemoryTransport):
960
744
 
961
745
    def test_default(self):
962
746
        """With no file, we get empty content."""
963
747
        backing = self.get_transport()
964
748
        request = smart_branch.SmartServerBranchGetConfigFile(backing)
965
 
        self.make_branch('.')
 
749
        branch = self.make_branch('.')
966
750
        # there should be no file by default
967
 
        content = b''
968
 
        self.assertEqual(smart_req.SmartServerResponse((b'ok', ), content),
969
 
                         request.execute(b''))
 
751
        content = ''
 
752
        self.assertEqual(smart_req.SmartServerResponse(('ok', ), content),
 
753
            request.execute(''))
970
754
 
971
755
    def test_with_content(self):
972
756
        # SmartServerBranchGetConfigFile should return the content from
973
 
        # branch.control_files.get('branch.conf') for now - in the future it
974
 
        # may perform more complex processing.
 
757
        # branch.control_files.get('branch.conf') for now - in the future it may
 
758
        # perform more complex processing.
975
759
        backing = self.get_transport()
976
760
        request = smart_branch.SmartServerBranchGetConfigFile(backing)
977
761
        branch = self.make_branch('.')
978
 
        branch._transport.put_bytes('branch.conf', b'foo bar baz')
979
 
        self.assertEqual(
980
 
            smart_req.SmartServerResponse((b'ok', ), b'foo bar baz'),
981
 
            request.execute(b''))
 
762
        branch._transport.put_bytes('branch.conf', 'foo bar baz')
 
763
        self.assertEqual(smart_req.SmartServerResponse(('ok', ), 'foo bar baz'),
 
764
            request.execute(''))
982
765
 
983
766
 
984
767
class TestLockedBranch(tests.TestCaseWithMemoryTransport):
985
768
 
986
769
    def get_lock_tokens(self, branch):
987
 
        branch_token = branch.lock_write().token
 
770
        branch_token = branch.lock_write().branch_token
988
771
        repo_token = branch.repository.lock_write().repository_token
989
772
        branch.repository.unlock()
990
773
        return branch_token, repo_token
991
774
 
992
775
 
993
 
class TestSmartServerBranchRequestPutConfigFile(TestLockedBranch):
994
 
 
995
 
    def test_with_content(self):
996
 
        backing = self.get_transport()
997
 
        request = smart_branch.SmartServerBranchPutConfigFile(backing)
998
 
        branch = self.make_branch('.')
999
 
        branch_token, repo_token = self.get_lock_tokens(branch)
1000
 
        self.assertIs(None, request.execute(b'', branch_token, repo_token))
1001
 
        self.assertEqual(
1002
 
            smart_req.SmartServerResponse((b'ok', )),
1003
 
            request.do_body(b'foo bar baz'))
1004
 
        self.assertEqual(
1005
 
            branch.control_transport.get_bytes('branch.conf'),
1006
 
            b'foo bar baz')
1007
 
        branch.unlock()
1008
 
 
1009
 
 
1010
776
class TestSmartServerBranchRequestSetConfigOption(TestLockedBranch):
1011
777
 
1012
778
    def test_value_name(self):
1013
779
        branch = self.make_branch('.')
1014
780
        request = smart_branch.SmartServerBranchRequestSetConfigOption(
1015
 
            branch.controldir.root_transport)
 
781
            branch.bzrdir.root_transport)
1016
782
        branch_token, repo_token = self.get_lock_tokens(branch)
1017
783
        config = branch._get_config()
1018
 
        result = request.execute(b'', branch_token, repo_token, b'bar', b'foo',
1019
 
                                 b'')
 
784
        result = request.execute('', branch_token, repo_token, 'bar', 'foo',
 
785
            '')
1020
786
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(()), result)
1021
787
        self.assertEqual('bar', config.get_option('foo'))
1022
788
        # Cleanup
1025
791
    def test_value_name_section(self):
1026
792
        branch = self.make_branch('.')
1027
793
        request = smart_branch.SmartServerBranchRequestSetConfigOption(
1028
 
            branch.controldir.root_transport)
 
794
            branch.bzrdir.root_transport)
1029
795
        branch_token, repo_token = self.get_lock_tokens(branch)
1030
796
        config = branch._get_config()
1031
 
        result = request.execute(b'', branch_token, repo_token, b'bar', b'foo',
1032
 
                                 b'gam')
 
797
        result = request.execute('', branch_token, repo_token, 'bar', 'foo',
 
798
            'gam')
1033
799
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(()), result)
1034
800
        self.assertEqual('bar', config.get_option('foo', 'gam'))
1035
801
        # Cleanup
1036
802
        branch.unlock()
1037
803
 
1038
804
 
1039
 
class TestSmartServerBranchRequestSetConfigOptionDict(TestLockedBranch):
1040
 
 
1041
 
    def setUp(self):
1042
 
        TestLockedBranch.setUp(self)
1043
 
        # A dict with non-ascii keys and values to exercise unicode
1044
 
        # roundtripping.
1045
 
        self.encoded_value_dict = (
1046
 
            b'd5:ascii1:a11:unicode \xe2\x8c\x9a3:\xe2\x80\xbde')
1047
 
        self.value_dict = {
1048
 
            'ascii': 'a', u'unicode \N{WATCH}': u'\N{INTERROBANG}'}
1049
 
 
1050
 
    def test_value_name(self):
1051
 
        branch = self.make_branch('.')
1052
 
        request = smart_branch.SmartServerBranchRequestSetConfigOptionDict(
1053
 
            branch.controldir.root_transport)
1054
 
        branch_token, repo_token = self.get_lock_tokens(branch)
1055
 
        config = branch._get_config()
1056
 
        result = request.execute(b'', branch_token, repo_token,
1057
 
                                 self.encoded_value_dict, b'foo', b'')
1058
 
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(()), result)
1059
 
        self.assertEqual(self.value_dict, config.get_option('foo'))
1060
 
        # Cleanup
1061
 
        branch.unlock()
1062
 
 
1063
 
    def test_value_name_section(self):
1064
 
        branch = self.make_branch('.')
1065
 
        request = smart_branch.SmartServerBranchRequestSetConfigOptionDict(
1066
 
            branch.controldir.root_transport)
1067
 
        branch_token, repo_token = self.get_lock_tokens(branch)
1068
 
        config = branch._get_config()
1069
 
        result = request.execute(b'', branch_token, repo_token,
1070
 
                                 self.encoded_value_dict, b'foo', b'gam')
1071
 
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(()), result)
1072
 
        self.assertEqual(self.value_dict, config.get_option('foo', 'gam'))
1073
 
        # Cleanup
1074
 
        branch.unlock()
1075
 
 
1076
 
 
1077
805
class TestSmartServerBranchRequestSetTagsBytes(TestLockedBranch):
1078
806
    # Only called when the branch format and tags match [yay factory
1079
807
    # methods] so only need to test straight forward cases.
1085
813
        branch_token, repo_token = self.get_lock_tokens(base_branch)
1086
814
        request = smart_branch.SmartServerBranchSetTagsBytes(
1087
815
            self.get_transport())
1088
 
        response = request.execute(b'base', branch_token, repo_token)
 
816
        response = request.execute('base', branch_token, repo_token)
1089
817
        self.assertEqual(None, response)
1090
818
        response = request.do_chunk(tag_bytes)
1091
819
        self.assertEqual(None, response)
1092
820
        response = request.do_end()
1093
 
        self.assertEqual(
 
821
        self.assertEquals(
1094
822
            smart_req.SuccessfulSmartServerResponse(()), response)
1095
823
        base_branch.unlock()
1096
824
 
1101
829
        request = smart_branch.SmartServerBranchSetTagsBytes(
1102
830
            self.get_transport())
1103
831
        self.assertRaises(errors.TokenMismatch, request.execute,
1104
 
                          b'base', b'wrong token', b'wrong token')
 
832
            'base', 'wrong token', 'wrong token')
1105
833
        # The request handler will keep processing the message parts, so even
1106
834
        # if the request fails immediately do_chunk and do_end are still
1107
835
        # called.
1110
838
        base_branch.unlock()
1111
839
 
1112
840
 
 
841
 
1113
842
class SetLastRevisionTestBase(TestLockedBranch):
1114
843
    """Base test case for verbs that implement set_last_revision."""
1115
844
 
1116
845
    def setUp(self):
1117
 
        super(SetLastRevisionTestBase, self).setUp()
 
846
        tests.TestCaseWithMemoryTransport.setUp(self)
1118
847
        backing_transport = self.get_transport()
1119
848
        self.request = self.request_class(backing_transport)
1120
849
        self.tree = self.make_branch_and_memory_tree('.')
1134
863
 
1135
864
    def assertRequestSucceeds(self, revision_id, revno):
1136
865
        response = self.set_last_revision(revision_id, revno)
1137
 
        self.assertEqual(smart_req.SuccessfulSmartServerResponse((b'ok',)),
 
866
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(('ok',)),
1138
867
                         response)
1139
868
 
1140
869
 
1142
871
    """Mixin test case for verbs that implement set_last_revision."""
1143
872
 
1144
873
    def test_set_null_to_null(self):
1145
 
        """An empty branch can have its last revision set to b'null:'."""
1146
 
        self.assertRequestSucceeds(b'null:', 0)
 
874
        """An empty branch can have its last revision set to 'null:'."""
 
875
        self.assertRequestSucceeds('null:', 0)
1147
876
 
1148
877
    def test_NoSuchRevision(self):
1149
878
        """If the revision_id is not present, the verb returns NoSuchRevision.
1150
879
        """
1151
 
        revision_id = b'non-existent revision'
1152
 
        self.assertEqual(
1153
 
            smart_req.FailedSmartServerResponse(
1154
 
                (b'NoSuchRevision', revision_id)),
1155
 
            self.set_last_revision(revision_id, 1))
 
880
        revision_id = 'non-existent revision'
 
881
        self.assertEqual(smart_req.FailedSmartServerResponse(('NoSuchRevision',
 
882
                                                              revision_id)),
 
883
                         self.set_last_revision(revision_id, 1))
1156
884
 
1157
885
    def make_tree_with_two_commits(self):
1158
886
        self.tree.lock_write()
1159
887
        self.tree.add('')
1160
888
        rev_id_utf8 = u'\xc8'.encode('utf-8')
1161
 
        self.tree.commit('1st commit', rev_id=rev_id_utf8)
1162
 
        self.tree.commit('2nd commit', rev_id=b'rev-2')
 
889
        r1 = self.tree.commit('1st commit', rev_id=rev_id_utf8)
 
890
        r2 = self.tree.commit('2nd commit', rev_id='rev-2')
1163
891
        self.tree.unlock()
1164
892
 
1165
893
    def test_branch_last_revision_info_is_updated(self):
1170
898
        # its repository.
1171
899
        self.make_tree_with_two_commits()
1172
900
        rev_id_utf8 = u'\xc8'.encode('utf-8')
1173
 
        self.tree.branch.set_last_revision_info(0, b'null:')
 
901
        self.tree.branch.set_revision_history([])
1174
902
        self.assertEqual(
1175
 
            (0, b'null:'), self.tree.branch.last_revision_info())
 
903
            (0, 'null:'), self.tree.branch.last_revision_info())
1176
904
        # We can update the branch to a revision that is present in the
1177
905
        # repository.
1178
906
        self.assertRequestSucceeds(rev_id_utf8, 1)
1186
914
        self.make_tree_with_two_commits()
1187
915
        rev_id_utf8 = u'\xc8'.encode('utf-8')
1188
916
        self.assertEqual(
1189
 
            (2, b'rev-2'), self.tree.branch.last_revision_info())
 
917
            (2, 'rev-2'), self.tree.branch.last_revision_info())
1190
918
        self.assertRequestSucceeds(rev_id_utf8, 1)
1191
919
        self.assertEqual(
1192
920
            (1, rev_id_utf8), self.tree.branch.last_revision_info())
1196
924
        returns TipChangeRejected.
1197
925
        """
1198
926
        rejection_message = u'rejection message\N{INTERROBANG}'
1199
 
 
1200
927
        def hook_that_rejects(params):
1201
928
            raise errors.TipChangeRejected(rejection_message)
1202
929
        _mod_branch.Branch.hooks.install_named_hook(
1203
930
            'pre_change_branch_tip', hook_that_rejects, None)
1204
931
        self.assertEqual(
1205
932
            smart_req.FailedSmartServerResponse(
1206
 
                (b'TipChangeRejected', rejection_message.encode('utf-8'))),
1207
 
            self.set_last_revision(b'null:', 0))
 
933
                ('TipChangeRejected', rejection_message.encode('utf-8'))),
 
934
            self.set_last_revision('null:', 0))
1208
935
 
1209
936
 
1210
937
class TestSmartServerBranchRequestSetLastRevision(
1215
942
 
1216
943
    def _set_last_revision(self, revision_id, revno, branch_token, repo_token):
1217
944
        return self.request.execute(
1218
 
            b'', branch_token, repo_token, revision_id)
 
945
            '', branch_token, repo_token, revision_id)
1219
946
 
1220
947
 
1221
948
class TestSmartServerBranchRequestSetLastRevisionInfo(
1226
953
 
1227
954
    def _set_last_revision(self, revision_id, revno, branch_token, repo_token):
1228
955
        return self.request.execute(
1229
 
            b'', branch_token, repo_token, revno, revision_id)
 
956
            '', branch_token, repo_token, revno, revision_id)
1230
957
 
1231
958
    def test_NoSuchRevision(self):
1232
959
        """Branch.set_last_revision_info does not have to return
1243
970
 
1244
971
    def _set_last_revision(self, revision_id, revno, branch_token, repo_token):
1245
972
        return self.request.execute(
1246
 
            b'', branch_token, repo_token, revision_id, 0, 0)
 
973
            '', branch_token, repo_token, revision_id, 0, 0)
1247
974
 
1248
975
    def assertRequestSucceeds(self, revision_id, revno):
1249
976
        response = self.set_last_revision(revision_id, revno)
1250
977
        self.assertEqual(
1251
 
            smart_req.SuccessfulSmartServerResponse(
1252
 
                (b'ok', revno, revision_id)),
 
978
            smart_req.SuccessfulSmartServerResponse(('ok', revno, revision_id)),
1253
979
            response)
1254
980
 
1255
981
    def test_branch_last_revision_info_rewind(self):
1259
985
        self.make_tree_with_two_commits()
1260
986
        rev_id_utf8 = u'\xc8'.encode('utf-8')
1261
987
        self.assertEqual(
1262
 
            (2, b'rev-2'), self.tree.branch.last_revision_info())
 
988
            (2, 'rev-2'), self.tree.branch.last_revision_info())
1263
989
        # If allow_overwrite_descendant flag is 0, then trying to set the tip
1264
990
        # to an older revision ID has no effect.
1265
991
        branch_token, repo_token = self.lock_branch()
1266
992
        response = self.request.execute(
1267
 
            b'', branch_token, repo_token, rev_id_utf8, 0, 0)
 
993
            '', branch_token, repo_token, rev_id_utf8, 0, 0)
1268
994
        self.assertEqual(
1269
 
            smart_req.SuccessfulSmartServerResponse((b'ok', 2, b'rev-2')),
 
995
            smart_req.SuccessfulSmartServerResponse(('ok', 2, 'rev-2')),
1270
996
            response)
1271
997
        self.assertEqual(
1272
 
            (2, b'rev-2'), self.tree.branch.last_revision_info())
 
998
            (2, 'rev-2'), self.tree.branch.last_revision_info())
1273
999
 
1274
1000
        # If allow_overwrite_descendant flag is 1, then setting the tip to an
1275
1001
        # ancestor works.
1276
1002
        response = self.request.execute(
1277
 
            b'', branch_token, repo_token, rev_id_utf8, 0, 1)
 
1003
            '', branch_token, repo_token, rev_id_utf8, 0, 1)
1278
1004
        self.assertEqual(
1279
 
            smart_req.SuccessfulSmartServerResponse((b'ok', 1, rev_id_utf8)),
 
1005
            smart_req.SuccessfulSmartServerResponse(('ok', 1, rev_id_utf8)),
1280
1006
            response)
1281
1007
        self.unlock_branch()
1282
1008
        self.assertEqual(
1290
1016
        """
1291
1017
        self.tree.lock_write()
1292
1018
        self.tree.add('')
1293
 
        self.tree.commit('1st commit')
 
1019
        r1 = self.tree.commit('1st commit')
1294
1020
        revno_1, revid_1 = self.tree.branch.last_revision_info()
1295
 
        self.tree.commit('2nd commit', rev_id=b'child-1')
 
1021
        r2 = self.tree.commit('2nd commit', rev_id='child-1')
1296
1022
        # Undo the second commit
1297
1023
        self.tree.branch.set_last_revision_info(revno_1, revid_1)
1298
1024
        self.tree.set_parent_ids([revid_1])
1299
1025
        # Make a new second commit, child-2.  child-2 has diverged from
1300
1026
        # child-1.
1301
 
        self.tree.commit('2nd commit', rev_id=b'child-2')
 
1027
        new_r2 = self.tree.commit('2nd commit', rev_id='child-2')
1302
1028
        self.tree.unlock()
1303
1029
 
1304
1030
    def test_not_allow_diverged(self):
1307
1033
        """
1308
1034
        self.make_branch_with_divergent_history()
1309
1035
        self.assertEqual(
1310
 
            smart_req.FailedSmartServerResponse((b'Diverged',)),
1311
 
            self.set_last_revision(b'child-1', 2))
 
1036
            smart_req.FailedSmartServerResponse(('Diverged',)),
 
1037
            self.set_last_revision('child-1', 2))
1312
1038
        # The branch tip was not changed.
1313
 
        self.assertEqual(b'child-2', self.tree.branch.last_revision())
 
1039
        self.assertEqual('child-2', self.tree.branch.last_revision())
1314
1040
 
1315
1041
    def test_allow_diverged(self):
1316
1042
        """If allow_diverged is passed, then setting a divergent history
1319
1045
        self.make_branch_with_divergent_history()
1320
1046
        branch_token, repo_token = self.lock_branch()
1321
1047
        response = self.request.execute(
1322
 
            b'', branch_token, repo_token, b'child-1', 1, 0)
 
1048
            '', branch_token, repo_token, 'child-1', 1, 0)
1323
1049
        self.assertEqual(
1324
 
            smart_req.SuccessfulSmartServerResponse((b'ok', 2, b'child-1')),
 
1050
            smart_req.SuccessfulSmartServerResponse(('ok', 2, 'child-1')),
1325
1051
            response)
1326
1052
        self.unlock_branch()
1327
1053
        # The branch tip was changed.
1328
 
        self.assertEqual(b'child-1', self.tree.branch.last_revision())
1329
 
 
1330
 
 
1331
 
class TestSmartServerBranchBreakLock(tests.TestCaseWithMemoryTransport):
1332
 
 
1333
 
    def test_lock_to_break(self):
1334
 
        base_branch = self.make_branch('base')
1335
 
        request = smart_branch.SmartServerBranchBreakLock(
1336
 
            self.get_transport())
1337
 
        base_branch.lock_write()
1338
 
        self.assertEqual(
1339
 
            smart_req.SuccessfulSmartServerResponse((b'ok', ), None),
1340
 
            request.execute(b'base'))
1341
 
 
1342
 
    def test_nothing_to_break(self):
1343
 
        self.make_branch('base')
1344
 
        request = smart_branch.SmartServerBranchBreakLock(
1345
 
            self.get_transport())
1346
 
        self.assertEqual(
1347
 
            smart_req.SuccessfulSmartServerResponse((b'ok', ), None),
1348
 
            request.execute(b'base'))
 
1054
        self.assertEqual('child-1', self.tree.branch.last_revision())
1349
1055
 
1350
1056
 
1351
1057
class TestSmartServerBranchRequestGetParent(tests.TestCaseWithMemoryTransport):
1352
1058
 
1353
1059
    def test_get_parent_none(self):
1354
 
        self.make_branch('base')
 
1060
        base_branch = self.make_branch('base')
1355
1061
        request = smart_branch.SmartServerBranchGetParent(self.get_transport())
1356
 
        response = request.execute(b'base')
1357
 
        self.assertEqual(
1358
 
            smart_req.SuccessfulSmartServerResponse((b'',)), response)
 
1062
        response = request.execute('base')
 
1063
        self.assertEquals(
 
1064
            smart_req.SuccessfulSmartServerResponse(('',)), response)
1359
1065
 
1360
1066
    def test_get_parent_something(self):
1361
1067
        base_branch = self.make_branch('base')
1362
1068
        base_branch.set_parent(self.get_url('foo'))
1363
1069
        request = smart_branch.SmartServerBranchGetParent(self.get_transport())
1364
 
        response = request.execute(b'base')
1365
 
        self.assertEqual(
1366
 
            smart_req.SuccessfulSmartServerResponse((b"../foo",)),
 
1070
        response = request.execute('base')
 
1071
        self.assertEquals(
 
1072
            smart_req.SuccessfulSmartServerResponse(("../foo",)),
1367
1073
            response)
1368
1074
 
1369
1075
 
1378
1084
            self.get_transport())
1379
1085
        branch_token, repo_token = self.get_lock_tokens(branch)
1380
1086
        try:
1381
 
            response = request.execute(b'base', branch_token, repo_token, b'')
 
1087
            response = request.execute('base', branch_token, repo_token, '')
1382
1088
        finally:
1383
1089
            branch.unlock()
1384
1090
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(()), response)
1385
 
        # Refresh branch as SetParentLocation modified it
1386
 
        branch = branch.controldir.open_branch()
1387
1091
        self.assertEqual(None, branch.get_parent())
1388
1092
 
1389
1093
    def test_set_parent_something(self):
1392
1096
            self.get_transport())
1393
1097
        branch_token, repo_token = self.get_lock_tokens(branch)
1394
1098
        try:
1395
 
            response = request.execute(b'base', branch_token, repo_token,
1396
 
                                       b'http://bar/')
 
1099
            response = request.execute('base', branch_token, repo_token,
 
1100
            'http://bar/')
1397
1101
        finally:
1398
1102
            branch.unlock()
1399
1103
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(()), response)
1400
 
        refreshed = _mod_branch.Branch.open(branch.base)
1401
 
        self.assertEqual('http://bar/', refreshed.get_parent())
 
1104
        self.assertEqual('http://bar/', branch.get_parent())
1402
1105
 
1403
1106
 
1404
1107
class TestSmartServerBranchRequestGetTagsBytes(
1405
 
        tests.TestCaseWithMemoryTransport):
 
1108
    tests.TestCaseWithMemoryTransport):
1406
1109
    # Only called when the branch format and tags match [yay factory
1407
1110
    # methods] so only need to test straight forward cases.
1408
1111
 
1409
1112
    def test_get_bytes(self):
1410
 
        self.make_branch('base')
 
1113
        base_branch = self.make_branch('base')
1411
1114
        request = smart_branch.SmartServerBranchGetTagsBytes(
1412
1115
            self.get_transport())
1413
 
        response = request.execute(b'base')
1414
 
        self.assertEqual(
1415
 
            smart_req.SuccessfulSmartServerResponse((b'',)), response)
1416
 
 
1417
 
 
1418
 
class TestSmartServerBranchRequestGetStackedOnURL(
1419
 
        tests.TestCaseWithMemoryTransport):
 
1116
        response = request.execute('base')
 
1117
        self.assertEquals(
 
1118
            smart_req.SuccessfulSmartServerResponse(('',)), response)
 
1119
 
 
1120
 
 
1121
class TestSmartServerBranchRequestGetStackedOnURL(tests.TestCaseWithMemoryTransport):
1420
1122
 
1421
1123
    def test_get_stacked_on_url(self):
1422
 
        self.make_branch('base', format='1.6')
 
1124
        base_branch = self.make_branch('base', format='1.6')
1423
1125
        stacked_branch = self.make_branch('stacked', format='1.6')
1424
1126
        # typically should be relative
1425
1127
        stacked_branch.set_stacked_on_url('../base')
1426
1128
        request = smart_branch.SmartServerBranchRequestGetStackedOnURL(
1427
1129
            self.get_transport())
1428
 
        response = request.execute(b'stacked')
1429
 
        self.assertEqual(
1430
 
            smart_req.SmartServerResponse((b'ok', b'../base')),
 
1130
        response = request.execute('stacked')
 
1131
        self.assertEquals(
 
1132
            smart_req.SmartServerResponse(('ok', '../base')),
1431
1133
            response)
1432
1134
 
1433
1135
 
1434
1136
class TestSmartServerBranchRequestLockWrite(TestLockedBranch):
1435
1137
 
 
1138
    def setUp(self):
 
1139
        tests.TestCaseWithMemoryTransport.setUp(self)
 
1140
 
1436
1141
    def test_lock_write_on_unlocked_branch(self):
1437
1142
        backing = self.get_transport()
1438
1143
        request = smart_branch.SmartServerBranchRequestLockWrite(backing)
1439
1144
        branch = self.make_branch('.', format='knit')
1440
1145
        repository = branch.repository
1441
 
        response = request.execute(b'')
 
1146
        response = request.execute('')
1442
1147
        branch_nonce = branch.control_files._lock.peek().get('nonce')
1443
1148
        repository_nonce = repository.control_files._lock.peek().get('nonce')
1444
1149
        self.assertEqual(smart_req.SmartServerResponse(
1445
 
            (b'ok', branch_nonce, repository_nonce)),
1446
 
            response)
 
1150
                ('ok', branch_nonce, repository_nonce)),
 
1151
                         response)
1447
1152
        # The branch (and associated repository) is now locked.  Verify that
1448
1153
        # with a new branch object.
1449
 
        new_branch = repository.controldir.open_branch()
 
1154
        new_branch = repository.bzrdir.open_branch()
1450
1155
        self.assertRaises(errors.LockContention, new_branch.lock_write)
1451
1156
        # Cleanup
1452
1157
        request = smart_branch.SmartServerBranchRequestUnlock(backing)
1453
 
        response = request.execute(b'', branch_nonce, repository_nonce)
 
1158
        response = request.execute('', branch_nonce, repository_nonce)
1454
1159
 
1455
1160
    def test_lock_write_on_locked_branch(self):
1456
1161
        backing = self.get_transport()
1457
1162
        request = smart_branch.SmartServerBranchRequestLockWrite(backing)
1458
1163
        branch = self.make_branch('.')
1459
 
        branch_token = branch.lock_write().token
 
1164
        branch_token = branch.lock_write().branch_token
1460
1165
        branch.leave_lock_in_place()
1461
1166
        branch.unlock()
1462
 
        response = request.execute(b'')
 
1167
        response = request.execute('')
1463
1168
        self.assertEqual(
1464
 
            smart_req.SmartServerResponse((b'LockContention',)), response)
 
1169
            smart_req.SmartServerResponse(('LockContention',)), response)
1465
1170
        # Cleanup
1466
1171
        branch.lock_write(branch_token)
1467
1172
        branch.dont_leave_lock_in_place()
1475
1180
        branch.leave_lock_in_place()
1476
1181
        branch.repository.leave_lock_in_place()
1477
1182
        branch.unlock()
1478
 
        response = request.execute(b'',
 
1183
        response = request.execute('',
1479
1184
                                   branch_token, repo_token)
1480
1185
        self.assertEqual(
1481
 
            smart_req.SmartServerResponse((b'ok', branch_token, repo_token)),
 
1186
            smart_req.SmartServerResponse(('ok', branch_token, repo_token)),
1482
1187
            response)
1483
1188
        # Cleanup
1484
1189
        branch.repository.lock_write(repo_token)
1496
1201
        branch.leave_lock_in_place()
1497
1202
        branch.repository.leave_lock_in_place()
1498
1203
        branch.unlock()
1499
 
        response = request.execute(b'',
1500
 
                                   branch_token + b'xxx', repo_token)
 
1204
        response = request.execute('',
 
1205
                                   branch_token+'xxx', repo_token)
1501
1206
        self.assertEqual(
1502
 
            smart_req.SmartServerResponse((b'TokenMismatch',)), response)
 
1207
            smart_req.SmartServerResponse(('TokenMismatch',)), response)
1503
1208
        # Cleanup
1504
1209
        branch.repository.lock_write(repo_token)
1505
1210
        branch.repository.dont_leave_lock_in_place()
1516
1221
        repo_token = repo.lock_write().repository_token
1517
1222
        repo.leave_lock_in_place()
1518
1223
        repo.unlock()
1519
 
        response = request.execute(b'')
 
1224
        response = request.execute('')
1520
1225
        self.assertEqual(
1521
 
            smart_req.SmartServerResponse((b'LockContention',)), response)
 
1226
            smart_req.SmartServerResponse(('LockContention',)), response)
1522
1227
        # Cleanup
1523
1228
        repo.lock_write(repo_token)
1524
1229
        repo.dont_leave_lock_in_place()
1527
1232
    def test_lock_write_on_readonly_transport(self):
1528
1233
        backing = self.get_readonly_transport()
1529
1234
        request = smart_branch.SmartServerBranchRequestLockWrite(backing)
1530
 
        self.make_branch('.')
 
1235
        branch = self.make_branch('.')
1531
1236
        root = self.get_transport().clone('/')
1532
1237
        path = urlutils.relative_url(root.base, self.get_transport().base)
1533
 
        response = request.execute(path.encode('utf-8'))
 
1238
        response = request.execute(path)
1534
1239
        error_name, lock_str, why_str = response.args
1535
1240
        self.assertFalse(response.is_successful())
1536
 
        self.assertEqual(b'LockFailed', error_name)
1537
 
 
1538
 
 
1539
 
class TestSmartServerBranchRequestGetPhysicalLockStatus(TestLockedBranch):
1540
 
 
1541
 
    def test_true(self):
1542
 
        backing = self.get_transport()
1543
 
        request = smart_branch.SmartServerBranchRequestGetPhysicalLockStatus(
1544
 
            backing)
1545
 
        branch = self.make_branch('.')
1546
 
        branch_token, repo_token = self.get_lock_tokens(branch)
1547
 
        self.assertEqual(True, branch.get_physical_lock_status())
1548
 
        response = request.execute(b'')
1549
 
        self.assertEqual(
1550
 
            smart_req.SmartServerResponse((b'yes',)), response)
1551
 
        branch.unlock()
1552
 
 
1553
 
    def test_false(self):
1554
 
        backing = self.get_transport()
1555
 
        request = smart_branch.SmartServerBranchRequestGetPhysicalLockStatus(
1556
 
            backing)
1557
 
        branch = self.make_branch('.')
1558
 
        self.assertEqual(False, branch.get_physical_lock_status())
1559
 
        response = request.execute(b'')
1560
 
        self.assertEqual(
1561
 
            smart_req.SmartServerResponse((b'no',)), response)
 
1241
        self.assertEqual('LockFailed', error_name)
1562
1242
 
1563
1243
 
1564
1244
class TestSmartServerBranchRequestUnlock(TestLockedBranch):
1565
1245
 
 
1246
    def setUp(self):
 
1247
        tests.TestCaseWithMemoryTransport.setUp(self)
 
1248
 
1566
1249
    def test_unlock_on_locked_branch_and_repo(self):
1567
1250
        backing = self.get_transport()
1568
1251
        request = smart_branch.SmartServerBranchRequestUnlock(backing)
1574
1257
        branch.leave_lock_in_place()
1575
1258
        branch.repository.leave_lock_in_place()
1576
1259
        branch.unlock()
1577
 
        response = request.execute(b'',
 
1260
        response = request.execute('',
1578
1261
                                   branch_token, repo_token)
1579
1262
        self.assertEqual(
1580
 
            smart_req.SmartServerResponse((b'ok',)), response)
 
1263
            smart_req.SmartServerResponse(('ok',)), response)
1581
1264
        # The branch is now unlocked.  Verify that with a new branch
1582
1265
        # object.
1583
 
        new_branch = branch.controldir.open_branch()
 
1266
        new_branch = branch.bzrdir.open_branch()
1584
1267
        new_branch.lock_write()
1585
1268
        new_branch.unlock()
1586
1269
 
1587
1270
    def test_unlock_on_unlocked_branch_unlocked_repo(self):
1588
1271
        backing = self.get_transport()
1589
1272
        request = smart_branch.SmartServerBranchRequestUnlock(backing)
1590
 
        self.make_branch('.', format='knit')
 
1273
        branch = self.make_branch('.', format='knit')
1591
1274
        response = request.execute(
1592
 
            b'', b'branch token', b'repo token')
 
1275
            '', 'branch token', 'repo token')
1593
1276
        self.assertEqual(
1594
 
            smart_req.SmartServerResponse((b'TokenMismatch',)), response)
 
1277
            smart_req.SmartServerResponse(('TokenMismatch',)), response)
1595
1278
 
1596
1279
    def test_unlock_on_unlocked_branch_locked_repo(self):
1597
1280
        backing = self.get_transport()
1603
1286
        branch.repository.unlock()
1604
1287
        # Issue branch lock_write request on the unlocked branch (with locked
1605
1288
        # repo).
1606
 
        response = request.execute(b'', b'branch token', repo_token)
 
1289
        response = request.execute('', 'branch token', repo_token)
1607
1290
        self.assertEqual(
1608
 
            smart_req.SmartServerResponse((b'TokenMismatch',)), response)
 
1291
            smart_req.SmartServerResponse(('TokenMismatch',)), response)
1609
1292
        # Cleanup
1610
1293
        branch.repository.lock_write(repo_token)
1611
1294
        branch.repository.dont_leave_lock_in_place()
1623
1306
        backing = self.get_transport()
1624
1307
        request = smart_repo.SmartServerRepositoryRequest(backing)
1625
1308
        self.make_repository('.', shared=True)
1626
 
        self.make_controldir('subdir')
 
1309
        self.make_bzrdir('subdir')
1627
1310
        self.assertRaises(errors.NoRepositoryPresent,
1628
 
                          request.execute, b'subdir')
1629
 
 
1630
 
 
1631
 
class TestSmartServerRepositoryAddSignatureText(
1632
 
        tests.TestCaseWithMemoryTransport):
1633
 
 
1634
 
    def test_add_text(self):
1635
 
        backing = self.get_transport()
1636
 
        request = smart_repo.SmartServerRepositoryAddSignatureText(backing)
1637
 
        tree = self.make_branch_and_memory_tree('.')
1638
 
        write_token = tree.lock_write()
1639
 
        self.addCleanup(tree.unlock)
1640
 
        tree.add('')
1641
 
        tree.commit("Message", rev_id=b'rev1')
1642
 
        tree.branch.repository.start_write_group()
1643
 
        write_group_tokens = tree.branch.repository.suspend_write_group()
1644
 
        self.assertEqual(
1645
 
            None, request.execute(
1646
 
                b'', write_token, b'rev1',
1647
 
                *[token.encode('utf-8') for token in write_group_tokens]))
1648
 
        response = request.do_body(b'somesignature')
1649
 
        self.assertTrue(response.is_successful())
1650
 
        self.assertEqual(response.args[0], b'ok')
1651
 
        write_group_tokens = [token.decode('utf-8')
1652
 
                              for token in response.args[1:]]
1653
 
        tree.branch.repository.resume_write_group(write_group_tokens)
1654
 
        tree.branch.repository.commit_write_group()
1655
 
        tree.unlock()
1656
 
        self.assertEqual(b"somesignature",
1657
 
                         tree.branch.repository.get_signature_text(b"rev1"))
1658
 
 
1659
 
 
1660
 
class TestSmartServerRepositoryAllRevisionIds(
1661
 
        tests.TestCaseWithMemoryTransport):
1662
 
 
1663
 
    def test_empty(self):
1664
 
        """An empty body should be returned for an empty repository."""
1665
 
        backing = self.get_transport()
1666
 
        request = smart_repo.SmartServerRepositoryAllRevisionIds(backing)
1667
 
        self.make_repository('.')
1668
 
        self.assertEqual(
1669
 
            smart_req.SuccessfulSmartServerResponse((b"ok", ), b""),
1670
 
            request.execute(b''))
1671
 
 
1672
 
    def test_some_revisions(self):
1673
 
        """An empty body should be returned for an empty repository."""
1674
 
        backing = self.get_transport()
1675
 
        request = smart_repo.SmartServerRepositoryAllRevisionIds(backing)
1676
 
        tree = self.make_branch_and_memory_tree('.')
1677
 
        tree.lock_write()
1678
 
        tree.add('')
1679
 
        tree.commit(rev_id=b'origineel', message="message")
1680
 
        tree.commit(rev_id=b'nog-een-revisie', message="message")
1681
 
        tree.unlock()
1682
 
        self.assertIn(
1683
 
            request.execute(b''),
1684
 
            [smart_req.SuccessfulSmartServerResponse(
1685
 
                (b"ok", ), b"origineel\nnog-een-revisie"),
1686
 
             smart_req.SuccessfulSmartServerResponse(
1687
 
                 (b"ok", ), b"nog-een-revisie\norigineel")])
1688
 
 
1689
 
 
1690
 
class TestSmartServerRepositoryBreakLock(tests.TestCaseWithMemoryTransport):
1691
 
 
1692
 
    def test_lock_to_break(self):
1693
 
        backing = self.get_transport()
1694
 
        request = smart_repo.SmartServerRepositoryBreakLock(backing)
1695
 
        tree = self.make_branch_and_memory_tree('.')
1696
 
        tree.branch.repository.lock_write()
1697
 
        self.assertEqual(
1698
 
            smart_req.SuccessfulSmartServerResponse((b'ok', ), None),
1699
 
            request.execute(b''))
1700
 
 
1701
 
    def test_nothing_to_break(self):
1702
 
        backing = self.get_transport()
1703
 
        request = smart_repo.SmartServerRepositoryBreakLock(backing)
1704
 
        self.make_branch_and_memory_tree('.')
1705
 
        self.assertEqual(
1706
 
            smart_req.SuccessfulSmartServerResponse((b'ok', ), None),
1707
 
            request.execute(b''))
 
1311
            request.execute, 'subdir')
1708
1312
 
1709
1313
 
1710
1314
class TestSmartServerRepositoryGetParentMap(tests.TestCaseWithMemoryTransport):
1713
1317
        # This tests that the wire encoding is actually bzipped
1714
1318
        backing = self.get_transport()
1715
1319
        request = smart_repo.SmartServerRepositoryGetParentMap(backing)
1716
 
        self.make_branch_and_memory_tree('.')
 
1320
        tree = self.make_branch_and_memory_tree('.')
1717
1321
 
1718
1322
        self.assertEqual(None,
1719
 
                         request.execute(b'', b'missing-id'))
 
1323
            request.execute('', 'missing-id'))
1720
1324
        # Note that it returns a body that is bzipped.
1721
1325
        self.assertEqual(
1722
 
            smart_req.SuccessfulSmartServerResponse(
1723
 
                (b'ok', ), bz2.compress(b'')),
1724
 
            request.do_body(b'\n\n0\n'))
 
1326
            smart_req.SuccessfulSmartServerResponse(('ok', ), bz2.compress('')),
 
1327
            request.do_body('\n\n0\n'))
1725
1328
 
1726
1329
    def test_trivial_include_missing(self):
1727
1330
        backing = self.get_transport()
1728
1331
        request = smart_repo.SmartServerRepositoryGetParentMap(backing)
1729
 
        self.make_branch_and_memory_tree('.')
 
1332
        tree = self.make_branch_and_memory_tree('.')
1730
1333
 
1731
 
        self.assertEqual(
1732
 
            None, request.execute(b'', b'missing-id', b'include-missing:'))
1733
 
        self.assertEqual(
1734
 
            smart_req.SuccessfulSmartServerResponse(
1735
 
                (b'ok', ), bz2.compress(b'missing:missing-id')),
1736
 
            request.do_body(b'\n\n0\n'))
 
1334
        self.assertEqual(None,
 
1335
            request.execute('', 'missing-id', 'include-missing:'))
 
1336
        self.assertEqual(
 
1337
            smart_req.SuccessfulSmartServerResponse(('ok', ),
 
1338
                bz2.compress('missing:missing-id')),
 
1339
            request.do_body('\n\n0\n'))
1737
1340
 
1738
1341
 
1739
1342
class TestSmartServerRepositoryGetRevisionGraph(
1740
 
        tests.TestCaseWithMemoryTransport):
 
1343
    tests.TestCaseWithMemoryTransport):
1741
1344
 
1742
1345
    def test_none_argument(self):
1743
1346
        backing = self.get_transport()
1751
1354
 
1752
1355
        # the lines of revision_id->revision_parent_list has no guaranteed
1753
1356
        # order coming out of a dict, so sort both our test and response
1754
 
        lines = sorted([b' '.join([r2, r1]), r1])
1755
 
        response = request.execute(b'', b'')
1756
 
        response.body = b'\n'.join(sorted(response.body.split(b'\n')))
 
1357
        lines = sorted([' '.join([r2, r1]), r1])
 
1358
        response = request.execute('', '')
 
1359
        response.body = '\n'.join(sorted(response.body.split('\n')))
1757
1360
 
1758
1361
        self.assertEqual(
1759
 
            smart_req.SmartServerResponse((b'ok', ), b'\n'.join(lines)),
1760
 
            response)
 
1362
            smart_req.SmartServerResponse(('ok', ), '\n'.join(lines)), response)
1761
1363
 
1762
1364
    def test_specific_revision_argument(self):
1763
1365
        backing = self.get_transport()
1766
1368
        tree.lock_write()
1767
1369
        tree.add('')
1768
1370
        rev_id_utf8 = u'\xc9'.encode('utf-8')
1769
 
        tree.commit('1st commit', rev_id=rev_id_utf8)
1770
 
        tree.commit('2nd commit', rev_id=u'\xc8'.encode('utf-8'))
 
1371
        r1 = tree.commit('1st commit', rev_id=rev_id_utf8)
 
1372
        r2 = tree.commit('2nd commit', rev_id=u'\xc8'.encode('utf-8'))
1771
1373
        tree.unlock()
1772
1374
 
1773
 
        self.assertEqual(smart_req.SmartServerResponse((b'ok', ), rev_id_utf8),
1774
 
                         request.execute(b'', rev_id_utf8))
 
1375
        self.assertEqual(smart_req.SmartServerResponse(('ok', ), rev_id_utf8),
 
1376
            request.execute('', rev_id_utf8))
1775
1377
 
1776
1378
    def test_no_such_revision(self):
1777
1379
        backing = self.get_transport()
1779
1381
        tree = self.make_branch_and_memory_tree('.')
1780
1382
        tree.lock_write()
1781
1383
        tree.add('')
1782
 
        tree.commit('1st commit')
 
1384
        r1 = tree.commit('1st commit')
1783
1385
        tree.unlock()
1784
1386
 
1785
1387
        # Note that it still returns body (of zero bytes).
1786
1388
        self.assertEqual(smart_req.SmartServerResponse(
1787
 
            (b'nosuchrevision', b'missingrevision', ), b''),
1788
 
            request.execute(b'', b'missingrevision'))
 
1389
                ('nosuchrevision', 'missingrevision', ), ''),
 
1390
                         request.execute('', 'missingrevision'))
1789
1391
 
1790
1392
 
1791
1393
class TestSmartServerRepositoryGetRevIdForRevno(
1792
 
        tests.TestCaseWithMemoryTransport):
 
1394
    tests.TestCaseWithMemoryTransport):
1793
1395
 
1794
1396
    def test_revno_found(self):
1795
1397
        backing = self.get_transport()
1803
1405
        tree.commit('2nd commit', rev_id=rev2_id_utf8)
1804
1406
        tree.unlock()
1805
1407
 
1806
 
        self.assertEqual(smart_req.SmartServerResponse((b'ok', rev1_id_utf8)),
1807
 
                         request.execute(b'', 1, (2, rev2_id_utf8)))
 
1408
        self.assertEqual(smart_req.SmartServerResponse(('ok', rev1_id_utf8)),
 
1409
            request.execute('', 1, (2, rev2_id_utf8)))
1808
1410
 
1809
1411
    def test_known_revid_missing(self):
1810
1412
        backing = self.get_transport()
1811
1413
        request = smart_repo.SmartServerRepositoryGetRevIdForRevno(backing)
1812
 
        self.make_repository('.')
 
1414
        repo = self.make_repository('.')
1813
1415
        self.assertEqual(
1814
 
            smart_req.FailedSmartServerResponse((b'nosuchrevision', b'ghost')),
1815
 
            request.execute(b'', 1, (2, b'ghost')))
 
1416
            smart_req.FailedSmartServerResponse(('nosuchrevision', 'ghost')),
 
1417
            request.execute('', 1, (2, 'ghost')))
1816
1418
 
1817
1419
    def test_history_incomplete(self):
1818
1420
        backing = self.get_transport()
1819
1421
        request = smart_repo.SmartServerRepositoryGetRevIdForRevno(backing)
1820
1422
        parent = self.make_branch_and_memory_tree('parent', format='1.9')
1821
1423
        parent.lock_write()
1822
 
        parent.add([''], [b'TREE_ROOT'])
1823
 
        parent.commit(message='first commit')
 
1424
        parent.add([''], ['TREE_ROOT'])
 
1425
        r1 = parent.commit(message='first commit')
1824
1426
        r2 = parent.commit(message='second commit')
1825
1427
        parent.unlock()
1826
1428
        local = self.make_branch_and_memory_tree('local', format='1.9')
1830
1432
        local.branch.create_clone_on_transport(
1831
1433
            self.get_transport('stacked'), stacked_on=self.get_url('parent'))
1832
1434
        self.assertEqual(
1833
 
            smart_req.SmartServerResponse((b'history-incomplete', 2, r2)),
1834
 
            request.execute(b'stacked', 1, (3, r3)))
1835
 
 
1836
 
 
1837
 
class TestSmartServerRepositoryIterRevisions(
1838
 
        tests.TestCaseWithMemoryTransport):
1839
 
 
1840
 
    def test_basic(self):
1841
 
        backing = self.get_transport()
1842
 
        request = smart_repo.SmartServerRepositoryIterRevisions(backing)
1843
 
        tree = self.make_branch_and_memory_tree('.', format='2a')
1844
 
        tree.lock_write()
1845
 
        tree.add('')
1846
 
        tree.commit('1st commit', rev_id=b"rev1")
1847
 
        tree.commit('2nd commit', rev_id=b"rev2")
1848
 
        tree.unlock()
1849
 
 
1850
 
        self.assertIs(None, request.execute(b''))
1851
 
        response = request.do_body(b"rev1\nrev2")
1852
 
        self.assertTrue(response.is_successful())
1853
 
        # Format 2a uses serializer format 10
1854
 
        self.assertEqual(response.args, (b"ok", b"10"))
1855
 
 
1856
 
        self.addCleanup(tree.branch.lock_read().unlock)
1857
 
        entries = [zlib.compress(record.get_bytes_as("fulltext")) for record in
1858
 
                   tree.branch.repository.revisions.get_record_stream(
1859
 
            [(b"rev1", ), (b"rev2", )], "unordered", True)]
1860
 
 
1861
 
        contents = b"".join(response.body_stream)
1862
 
        self.assertTrue(contents in (
1863
 
            b"".join([entries[0], entries[1]]),
1864
 
            b"".join([entries[1], entries[0]])))
1865
 
 
1866
 
    def test_missing(self):
1867
 
        backing = self.get_transport()
1868
 
        request = smart_repo.SmartServerRepositoryIterRevisions(backing)
1869
 
        self.make_branch_and_memory_tree('.', format='2a')
1870
 
 
1871
 
        self.assertIs(None, request.execute(b''))
1872
 
        response = request.do_body(b"rev1\nrev2")
1873
 
        self.assertTrue(response.is_successful())
1874
 
        # Format 2a uses serializer format 10
1875
 
        self.assertEqual(response.args, (b"ok", b"10"))
1876
 
 
1877
 
        contents = b"".join(response.body_stream)
1878
 
        self.assertEqual(contents, b"")
1879
 
 
1880
 
 
1881
 
class GetStreamTestBase(tests.TestCaseWithMemoryTransport):
 
1435
            smart_req.SmartServerResponse(('history-incomplete', 2, r2)),
 
1436
            request.execute('stacked', 1, (3, r3)))
 
1437
 
 
1438
 
 
1439
class TestSmartServerRepositoryGetStream(tests.TestCaseWithMemoryTransport):
1882
1440
 
1883
1441
    def make_two_commit_repo(self):
1884
1442
        tree = self.make_branch_and_memory_tree('.')
1890
1448
        repo = tree.branch.repository
1891
1449
        return repo, r1, r2
1892
1450
 
1893
 
 
1894
 
class TestSmartServerRepositoryGetStream(GetStreamTestBase):
1895
 
 
1896
1451
    def test_ancestry_of(self):
1897
1452
        """The search argument may be a 'ancestry-of' some heads'."""
1898
1453
        backing = self.get_transport()
1899
1454
        request = smart_repo.SmartServerRepositoryGetStream(backing)
1900
1455
        repo, r1, r2 = self.make_two_commit_repo()
1901
 
        fetch_spec = [b'ancestry-of', r2]
1902
 
        lines = b'\n'.join(fetch_spec)
1903
 
        request.execute(b'', repo._format.network_name())
 
1456
        fetch_spec = ['ancestry-of', r2]
 
1457
        lines = '\n'.join(fetch_spec)
 
1458
        request.execute('', repo._format.network_name())
1904
1459
        response = request.do_body(lines)
1905
 
        self.assertEqual((b'ok',), response.args)
1906
 
        stream_bytes = b''.join(response.body_stream)
1907
 
        self.assertStartsWith(stream_bytes, b'Bazaar pack format 1')
 
1460
        self.assertEqual(('ok',), response.args)
 
1461
        stream_bytes = ''.join(response.body_stream)
 
1462
        self.assertStartsWith(stream_bytes, 'Bazaar pack format 1')
1908
1463
 
1909
1464
    def test_search(self):
1910
1465
        """The search argument may be a 'search' of some explicit keys."""
1911
1466
        backing = self.get_transport()
1912
1467
        request = smart_repo.SmartServerRepositoryGetStream(backing)
1913
1468
        repo, r1, r2 = self.make_two_commit_repo()
1914
 
        fetch_spec = [b'search', r1 + b' ' + r2, b'null:', b'2']
1915
 
        lines = b'\n'.join(fetch_spec)
1916
 
        request.execute(b'', repo._format.network_name())
 
1469
        fetch_spec = ['search', '%s %s' % (r1, r2), 'null:', '2']
 
1470
        lines = '\n'.join(fetch_spec)
 
1471
        request.execute('', repo._format.network_name())
1917
1472
        response = request.do_body(lines)
1918
 
        self.assertEqual((b'ok',), response.args)
1919
 
        stream_bytes = b''.join(response.body_stream)
1920
 
        self.assertStartsWith(stream_bytes, b'Bazaar pack format 1')
1921
 
 
1922
 
    def test_search_everything(self):
1923
 
        """A search of 'everything' returns a stream."""
1924
 
        backing = self.get_transport()
1925
 
        request = smart_repo.SmartServerRepositoryGetStream_1_19(backing)
1926
 
        repo, r1, r2 = self.make_two_commit_repo()
1927
 
        serialised_fetch_spec = b'everything'
1928
 
        request.execute(b'', repo._format.network_name())
1929
 
        response = request.do_body(serialised_fetch_spec)
1930
 
        self.assertEqual((b'ok',), response.args)
1931
 
        stream_bytes = b''.join(response.body_stream)
1932
 
        self.assertStartsWith(stream_bytes, b'Bazaar pack format 1')
 
1473
        self.assertEqual(('ok',), response.args)
 
1474
        stream_bytes = ''.join(response.body_stream)
 
1475
        self.assertStartsWith(stream_bytes, 'Bazaar pack format 1')
1933
1476
 
1934
1477
 
1935
1478
class TestSmartServerRequestHasRevision(tests.TestCaseWithMemoryTransport):
1939
1482
        backing = self.get_transport()
1940
1483
        request = smart_repo.SmartServerRequestHasRevision(backing)
1941
1484
        self.make_repository('.')
1942
 
        self.assertEqual(smart_req.SmartServerResponse((b'no', )),
1943
 
                         request.execute(b'', b'revid'))
 
1485
        self.assertEqual(smart_req.SmartServerResponse(('no', )),
 
1486
            request.execute('', 'revid'))
1944
1487
 
1945
1488
    def test_present_revision(self):
1946
1489
        """For a present revision, ('yes', ) is returned."""
1950
1493
        tree.lock_write()
1951
1494
        tree.add('')
1952
1495
        rev_id_utf8 = u'\xc8abc'.encode('utf-8')
1953
 
        tree.commit('a commit', rev_id=rev_id_utf8)
 
1496
        r1 = tree.commit('a commit', rev_id=rev_id_utf8)
1954
1497
        tree.unlock()
1955
1498
        self.assertTrue(tree.branch.repository.has_revision(rev_id_utf8))
1956
 
        self.assertEqual(smart_req.SmartServerResponse((b'yes', )),
1957
 
                         request.execute(b'', rev_id_utf8))
1958
 
 
1959
 
 
1960
 
class TestSmartServerRepositoryIterFilesBytes(tests.TestCaseWithTransport):
1961
 
 
1962
 
    def test_single(self):
1963
 
        backing = self.get_transport()
1964
 
        request = smart_repo.SmartServerRepositoryIterFilesBytes(backing)
1965
 
        t = self.make_branch_and_tree('.')
1966
 
        self.addCleanup(t.lock_write().unlock)
1967
 
        self.build_tree_contents([("file", b"somecontents")])
1968
 
        t.add(["file"], [b"thefileid"])
1969
 
        t.commit(rev_id=b'somerev', message="add file")
1970
 
        self.assertIs(None, request.execute(b''))
1971
 
        response = request.do_body(b"thefileid\0somerev\n")
1972
 
        self.assertTrue(response.is_successful())
1973
 
        self.assertEqual(response.args, (b"ok", ))
1974
 
        self.assertEqual(b"".join(response.body_stream),
1975
 
                         b"ok\x000\n" + zlib.compress(b"somecontents"))
1976
 
 
1977
 
    def test_missing(self):
1978
 
        backing = self.get_transport()
1979
 
        request = smart_repo.SmartServerRepositoryIterFilesBytes(backing)
1980
 
        t = self.make_branch_and_tree('.')
1981
 
        self.addCleanup(t.lock_write().unlock)
1982
 
        self.assertIs(None, request.execute(b''))
1983
 
        response = request.do_body(b"thefileid\0revision\n")
1984
 
        self.assertTrue(response.is_successful())
1985
 
        self.assertEqual(response.args, (b"ok", ))
1986
 
        self.assertEqual(b"".join(response.body_stream),
1987
 
                         b"absent\x00thefileid\x00revision\x000\n")
1988
 
 
1989
 
 
1990
 
class TestSmartServerRequestHasSignatureForRevisionId(
1991
 
        tests.TestCaseWithMemoryTransport):
1992
 
 
1993
 
    def test_missing_revision(self):
1994
 
        """For a missing revision, NoSuchRevision is returned."""
1995
 
        backing = self.get_transport()
1996
 
        request = smart_repo.SmartServerRequestHasSignatureForRevisionId(
1997
 
            backing)
1998
 
        self.make_repository('.')
1999
 
        self.assertEqual(
2000
 
            smart_req.FailedSmartServerResponse(
2001
 
                (b'nosuchrevision', b'revid'), None),
2002
 
            request.execute(b'', b'revid'))
2003
 
 
2004
 
    def test_missing_signature(self):
2005
 
        """For a missing signature, ('no', ) is returned."""
2006
 
        backing = self.get_transport()
2007
 
        request = smart_repo.SmartServerRequestHasSignatureForRevisionId(
2008
 
            backing)
2009
 
        tree = self.make_branch_and_memory_tree('.')
2010
 
        tree.lock_write()
2011
 
        tree.add('')
2012
 
        tree.commit('a commit', rev_id=b'A')
2013
 
        tree.unlock()
2014
 
        self.assertTrue(tree.branch.repository.has_revision(b'A'))
2015
 
        self.assertEqual(smart_req.SmartServerResponse((b'no', )),
2016
 
                         request.execute(b'', b'A'))
2017
 
 
2018
 
    def test_present_signature(self):
2019
 
        """For a present signature, ('yes', ) is returned."""
2020
 
        backing = self.get_transport()
2021
 
        request = smart_repo.SmartServerRequestHasSignatureForRevisionId(
2022
 
            backing)
2023
 
        strategy = gpg.LoopbackGPGStrategy(None)
2024
 
        tree = self.make_branch_and_memory_tree('.')
2025
 
        tree.lock_write()
2026
 
        tree.add('')
2027
 
        tree.commit('a commit', rev_id=b'A')
2028
 
        tree.branch.repository.start_write_group()
2029
 
        tree.branch.repository.sign_revision(b'A', strategy)
2030
 
        tree.branch.repository.commit_write_group()
2031
 
        tree.unlock()
2032
 
        self.assertTrue(tree.branch.repository.has_revision(b'A'))
2033
 
        self.assertEqual(smart_req.SmartServerResponse((b'yes', )),
2034
 
                         request.execute(b'', b'A'))
 
1499
        self.assertEqual(smart_req.SmartServerResponse(('yes', )),
 
1500
            request.execute('', rev_id_utf8))
2035
1501
 
2036
1502
 
2037
1503
class TestSmartServerRepositoryGatherStats(tests.TestCaseWithMemoryTransport):
2041
1507
        backing = self.get_transport()
2042
1508
        request = smart_repo.SmartServerRepositoryGatherStats(backing)
2043
1509
        repository = self.make_repository('.')
2044
 
        repository.gather_stats()
2045
 
        expected_body = b'revisions: 0\n'
2046
 
        self.assertEqual(
2047
 
            smart_req.SmartServerResponse((b'ok', ), expected_body),
2048
 
            request.execute(b'', b'', b'no'))
 
1510
        stats = repository.gather_stats()
 
1511
        expected_body = 'revisions: 0\n'
 
1512
        self.assertEqual(smart_req.SmartServerResponse(('ok', ), expected_body),
 
1513
                         request.execute('', '', 'no'))
2049
1514
 
2050
1515
    def test_revid_with_committers(self):
2051
1516
        """For a revid we get more infos."""
2061
1526
                    rev_id=rev_id_utf8)
2062
1527
        tree.unlock()
2063
1528
 
2064
 
        tree.branch.repository.gather_stats()
2065
 
        expected_body = (b'firstrev: 123456.200 3600\n'
2066
 
                         b'latestrev: 654321.400 0\n'
2067
 
                         b'revisions: 2\n')
2068
 
        self.assertEqual(
2069
 
            smart_req.SmartServerResponse((b'ok', ), expected_body),
2070
 
            request.execute(b'', rev_id_utf8, b'no'))
 
1529
        stats = tree.branch.repository.gather_stats()
 
1530
        expected_body = ('firstrev: 123456.200 3600\n'
 
1531
                         'latestrev: 654321.400 0\n'
 
1532
                         'revisions: 2\n')
 
1533
        self.assertEqual(smart_req.SmartServerResponse(('ok', ), expected_body),
 
1534
                         request.execute('',
 
1535
                                         rev_id_utf8, 'no'))
2071
1536
 
2072
1537
    def test_not_empty_repository_with_committers(self):
2073
1538
        """For a revid and requesting committers we get the whole thing."""
2083
1548
        tree.commit('a commit', timestamp=654321.4, timezone=0,
2084
1549
                    committer='bar', rev_id=rev_id_utf8)
2085
1550
        tree.unlock()
2086
 
        tree.branch.repository.gather_stats()
2087
 
 
2088
 
        expected_body = (b'committers: 2\n'
2089
 
                         b'firstrev: 123456.200 3600\n'
2090
 
                         b'latestrev: 654321.400 0\n'
2091
 
                         b'revisions: 2\n')
2092
 
        self.assertEqual(
2093
 
            smart_req.SmartServerResponse((b'ok', ), expected_body),
2094
 
            request.execute(b'', rev_id_utf8, b'yes'))
2095
 
 
2096
 
    def test_unknown_revid(self):
2097
 
        """An unknown revision id causes a 'nosuchrevision' error."""
2098
 
        backing = self.get_transport()
2099
 
        request = smart_repo.SmartServerRepositoryGatherStats(backing)
2100
 
        self.make_repository('.')
2101
 
        self.assertEqual(
2102
 
            smart_req.FailedSmartServerResponse(
2103
 
                (b'nosuchrevision', b'mia'), None),
2104
 
            request.execute(b'', b'mia', b'yes'))
 
1551
        stats = tree.branch.repository.gather_stats()
 
1552
 
 
1553
        expected_body = ('committers: 2\n'
 
1554
                         'firstrev: 123456.200 3600\n'
 
1555
                         'latestrev: 654321.400 0\n'
 
1556
                         'revisions: 2\n')
 
1557
        self.assertEqual(smart_req.SmartServerResponse(('ok', ), expected_body),
 
1558
                         request.execute('',
 
1559
                                         rev_id_utf8, 'yes'))
2105
1560
 
2106
1561
 
2107
1562
class TestSmartServerRepositoryIsShared(tests.TestCaseWithMemoryTransport):
2111
1566
        backing = self.get_transport()
2112
1567
        request = smart_repo.SmartServerRepositoryIsShared(backing)
2113
1568
        self.make_repository('.', shared=True)
2114
 
        self.assertEqual(smart_req.SmartServerResponse((b'yes', )),
2115
 
                         request.execute(b'', ))
 
1569
        self.assertEqual(smart_req.SmartServerResponse(('yes', )),
 
1570
            request.execute('', ))
2116
1571
 
2117
1572
    def test_is_not_shared(self):
2118
1573
        """For a shared repository, ('no', ) is returned."""
2119
1574
        backing = self.get_transport()
2120
1575
        request = smart_repo.SmartServerRepositoryIsShared(backing)
2121
1576
        self.make_repository('.', shared=False)
2122
 
        self.assertEqual(smart_req.SmartServerResponse((b'no', )),
2123
 
                         request.execute(b'', ))
2124
 
 
2125
 
 
2126
 
class TestSmartServerRepositoryGetRevisionSignatureText(
2127
 
        tests.TestCaseWithMemoryTransport):
2128
 
 
2129
 
    def test_get_signature(self):
2130
 
        backing = self.get_transport()
2131
 
        request = smart_repo.SmartServerRepositoryGetRevisionSignatureText(
2132
 
            backing)
2133
 
        bb = self.make_branch_builder('.')
2134
 
        bb.build_commit(rev_id=b'A')
2135
 
        repo = bb.get_branch().repository
2136
 
        strategy = gpg.LoopbackGPGStrategy(None)
2137
 
        self.addCleanup(repo.lock_write().unlock)
2138
 
        repo.start_write_group()
2139
 
        repo.sign_revision(b'A', strategy)
2140
 
        repo.commit_write_group()
2141
 
        expected_body = (
2142
 
            b'-----BEGIN PSEUDO-SIGNED CONTENT-----\n' +
2143
 
            Testament.from_revision(repo, b'A').as_short_text() +
2144
 
            b'-----END PSEUDO-SIGNED CONTENT-----\n')
2145
 
        self.assertEqual(
2146
 
            smart_req.SmartServerResponse((b'ok', ), expected_body),
2147
 
            request.execute(b'', b'A'))
2148
 
 
2149
 
 
2150
 
class TestSmartServerRepositoryMakeWorkingTrees(
2151
 
        tests.TestCaseWithMemoryTransport):
2152
 
 
2153
 
    def test_make_working_trees(self):
2154
 
        """For a repository with working trees, ('yes', ) is returned."""
2155
 
        backing = self.get_transport()
2156
 
        request = smart_repo.SmartServerRepositoryMakeWorkingTrees(backing)
2157
 
        r = self.make_repository('.')
2158
 
        r.set_make_working_trees(True)
2159
 
        self.assertEqual(smart_req.SmartServerResponse((b'yes', )),
2160
 
                         request.execute(b'', ))
2161
 
 
2162
 
    def test_is_not_shared(self):
2163
 
        """For a repository with working trees, ('no', ) is returned."""
2164
 
        backing = self.get_transport()
2165
 
        request = smart_repo.SmartServerRepositoryMakeWorkingTrees(backing)
2166
 
        r = self.make_repository('.')
2167
 
        r.set_make_working_trees(False)
2168
 
        self.assertEqual(smart_req.SmartServerResponse((b'no', )),
2169
 
                         request.execute(b'', ))
 
1577
        self.assertEqual(smart_req.SmartServerResponse(('no', )),
 
1578
            request.execute('', ))
2170
1579
 
2171
1580
 
2172
1581
class TestSmartServerRepositoryLockWrite(tests.TestCaseWithMemoryTransport):
2175
1584
        backing = self.get_transport()
2176
1585
        request = smart_repo.SmartServerRepositoryLockWrite(backing)
2177
1586
        repository = self.make_repository('.', format='knit')
2178
 
        response = request.execute(b'')
 
1587
        response = request.execute('')
2179
1588
        nonce = repository.control_files._lock.peek().get('nonce')
2180
 
        self.assertEqual(smart_req.SmartServerResponse(
2181
 
            (b'ok', nonce)), response)
 
1589
        self.assertEqual(smart_req.SmartServerResponse(('ok', nonce)), response)
2182
1590
        # The repository is now locked.  Verify that with a new repository
2183
1591
        # object.
2184
 
        new_repo = repository.controldir.open_repository()
 
1592
        new_repo = repository.bzrdir.open_repository()
2185
1593
        self.assertRaises(errors.LockContention, new_repo.lock_write)
2186
1594
        # Cleanup
2187
1595
        request = smart_repo.SmartServerRepositoryUnlock(backing)
2188
 
        response = request.execute(b'', nonce)
 
1596
        response = request.execute('', nonce)
2189
1597
 
2190
1598
    def test_lock_write_on_locked_repo(self):
2191
1599
        backing = self.get_transport()
2194
1602
        repo_token = repository.lock_write().repository_token
2195
1603
        repository.leave_lock_in_place()
2196
1604
        repository.unlock()
2197
 
        response = request.execute(b'')
 
1605
        response = request.execute('')
2198
1606
        self.assertEqual(
2199
 
            smart_req.SmartServerResponse((b'LockContention',)), response)
 
1607
            smart_req.SmartServerResponse(('LockContention',)), response)
2200
1608
        # Cleanup
2201
1609
        repository.lock_write(repo_token)
2202
1610
        repository.dont_leave_lock_in_place()
2205
1613
    def test_lock_write_on_readonly_transport(self):
2206
1614
        backing = self.get_readonly_transport()
2207
1615
        request = smart_repo.SmartServerRepositoryLockWrite(backing)
2208
 
        self.make_repository('.', format='knit')
2209
 
        response = request.execute(b'')
 
1616
        repository = self.make_repository('.', format='knit')
 
1617
        response = request.execute('')
2210
1618
        self.assertFalse(response.is_successful())
2211
 
        self.assertEqual(b'LockFailed', response.args[0])
 
1619
        self.assertEqual('LockFailed', response.args[0])
2212
1620
 
2213
1621
 
2214
1622
class TestInsertStreamBase(tests.TestCaseWithMemoryTransport):
2215
1623
 
2216
1624
    def make_empty_byte_stream(self, repo):
2217
1625
        byte_stream = smart_repo._stream_to_byte_stream([], repo._format)
2218
 
        return b''.join(byte_stream)
 
1626
        return ''.join(byte_stream)
2219
1627
 
2220
1628
 
2221
1629
class TestSmartServerRepositoryInsertStream(TestInsertStreamBase):
2224
1632
        backing = self.get_transport()
2225
1633
        request = smart_repo.SmartServerRepositoryInsertStream(backing)
2226
1634
        repository = self.make_repository('.')
2227
 
        response = request.execute(b'', b'')
 
1635
        response = request.execute('', '')
2228
1636
        self.assertEqual(None, response)
2229
1637
        response = request.do_chunk(self.make_empty_byte_stream(repository))
2230
1638
        self.assertEqual(None, response)
2231
1639
        response = request.do_end()
2232
 
        self.assertEqual(smart_req.SmartServerResponse((b'ok', )), response)
 
1640
        self.assertEqual(smart_req.SmartServerResponse(('ok', )), response)
2233
1641
 
2234
1642
 
2235
1643
class TestSmartServerRepositoryInsertStreamLocked(TestInsertStreamBase):
2240
1648
            backing)
2241
1649
        repository = self.make_repository('.', format='knit')
2242
1650
        lock_token = repository.lock_write().repository_token
2243
 
        response = request.execute(b'', b'', lock_token)
 
1651
        response = request.execute('', '', lock_token)
2244
1652
        self.assertEqual(None, response)
2245
1653
        response = request.do_chunk(self.make_empty_byte_stream(repository))
2246
1654
        self.assertEqual(None, response)
2247
1655
        response = request.do_end()
2248
 
        self.assertEqual(smart_req.SmartServerResponse((b'ok', )), response)
 
1656
        self.assertEqual(smart_req.SmartServerResponse(('ok', )), response)
2249
1657
        repository.unlock()
2250
1658
 
2251
1659
    def test_insert_stream_with_wrong_lock_token(self):
2253
1661
        request = smart_repo.SmartServerRepositoryInsertStreamLocked(
2254
1662
            backing)
2255
1663
        repository = self.make_repository('.', format='knit')
2256
 
        with repository.lock_write():
2257
 
            self.assertRaises(
2258
 
                errors.TokenMismatch, request.execute, b'', b'',
2259
 
                b'wrong-token')
 
1664
        lock_token = repository.lock_write().repository_token
 
1665
        self.assertRaises(
 
1666
            errors.TokenMismatch, request.execute, '', '', 'wrong-token')
 
1667
        repository.unlock()
2260
1668
 
2261
1669
 
2262
1670
class TestSmartServerRepositoryUnlock(tests.TestCaseWithMemoryTransport):
2263
1671
 
 
1672
    def setUp(self):
 
1673
        tests.TestCaseWithMemoryTransport.setUp(self)
 
1674
 
2264
1675
    def test_unlock_on_locked_repo(self):
2265
1676
        backing = self.get_transport()
2266
1677
        request = smart_repo.SmartServerRepositoryUnlock(backing)
2268
1679
        token = repository.lock_write().repository_token
2269
1680
        repository.leave_lock_in_place()
2270
1681
        repository.unlock()
2271
 
        response = request.execute(b'', token)
 
1682
        response = request.execute('', token)
2272
1683
        self.assertEqual(
2273
 
            smart_req.SmartServerResponse((b'ok',)), response)
 
1684
            smart_req.SmartServerResponse(('ok',)), response)
2274
1685
        # The repository is now unlocked.  Verify that with a new repository
2275
1686
        # object.
2276
 
        new_repo = repository.controldir.open_repository()
 
1687
        new_repo = repository.bzrdir.open_repository()
2277
1688
        new_repo.lock_write()
2278
1689
        new_repo.unlock()
2279
1690
 
2280
1691
    def test_unlock_on_unlocked_repo(self):
2281
1692
        backing = self.get_transport()
2282
1693
        request = smart_repo.SmartServerRepositoryUnlock(backing)
2283
 
        self.make_repository('.', format='knit')
2284
 
        response = request.execute(b'', b'some token')
 
1694
        repository = self.make_repository('.', format='knit')
 
1695
        response = request.execute('', 'some token')
2285
1696
        self.assertEqual(
2286
 
            smart_req.SmartServerResponse((b'TokenMismatch',)), response)
2287
 
 
2288
 
 
2289
 
class TestSmartServerRepositoryGetPhysicalLockStatus(
2290
 
        tests.TestCaseWithTransport):
2291
 
 
2292
 
    def test_with_write_lock(self):
2293
 
        backing = self.get_transport()
2294
 
        repo = self.make_repository('.')
2295
 
        self.addCleanup(repo.lock_write().unlock)
2296
 
        # lock_write() doesn't necessarily actually take a physical
2297
 
        # lock out.
2298
 
        if repo.get_physical_lock_status():
2299
 
            expected = b'yes'
2300
 
        else:
2301
 
            expected = b'no'
2302
 
        request_class = smart_repo.SmartServerRepositoryGetPhysicalLockStatus
2303
 
        request = request_class(backing)
2304
 
        self.assertEqual(smart_req.SuccessfulSmartServerResponse((expected,)),
2305
 
                         request.execute(b'', ))
2306
 
 
2307
 
    def test_without_write_lock(self):
2308
 
        backing = self.get_transport()
2309
 
        repo = self.make_repository('.')
2310
 
        self.assertEqual(False, repo.get_physical_lock_status())
2311
 
        request_class = smart_repo.SmartServerRepositoryGetPhysicalLockStatus
2312
 
        request = request_class(backing)
2313
 
        self.assertEqual(smart_req.SuccessfulSmartServerResponse((b'no',)),
2314
 
                         request.execute(b'', ))
2315
 
 
2316
 
 
2317
 
class TestSmartServerRepositoryReconcile(tests.TestCaseWithTransport):
2318
 
 
2319
 
    def test_reconcile(self):
2320
 
        backing = self.get_transport()
2321
 
        repo = self.make_repository('.')
2322
 
        token = repo.lock_write().repository_token
2323
 
        self.addCleanup(repo.unlock)
2324
 
        request_class = smart_repo.SmartServerRepositoryReconcile
2325
 
        request = request_class(backing)
2326
 
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(
2327
 
            (b'ok', ),
2328
 
            b'garbage_inventories: 0\n'
2329
 
            b'inconsistent_parents: 0\n'),
2330
 
            request.execute(b'', token))
 
1697
            smart_req.SmartServerResponse(('TokenMismatch',)), response)
2331
1698
 
2332
1699
 
2333
1700
class TestSmartServerIsReadonly(tests.TestCaseWithMemoryTransport):
2337
1704
        request = smart_req.SmartServerIsReadonly(backing)
2338
1705
        response = request.execute()
2339
1706
        self.assertEqual(
2340
 
            smart_req.SmartServerResponse((b'no',)), response)
 
1707
            smart_req.SmartServerResponse(('no',)), response)
2341
1708
 
2342
1709
    def test_is_readonly_yes(self):
2343
1710
        backing = self.get_readonly_transport()
2344
1711
        request = smart_req.SmartServerIsReadonly(backing)
2345
1712
        response = request.execute()
2346
1713
        self.assertEqual(
2347
 
            smart_req.SmartServerResponse((b'yes',)), response)
 
1714
            smart_req.SmartServerResponse(('yes',)), response)
2348
1715
 
2349
1716
 
2350
1717
class TestSmartServerRepositorySetMakeWorkingTrees(
2351
 
        tests.TestCaseWithMemoryTransport):
 
1718
    tests.TestCaseWithMemoryTransport):
2352
1719
 
2353
1720
    def test_set_false(self):
2354
1721
        backing = self.get_transport()
2356
1723
        repo.set_make_working_trees(True)
2357
1724
        request_class = smart_repo.SmartServerRepositorySetMakeWorkingTrees
2358
1725
        request = request_class(backing)
2359
 
        self.assertEqual(smart_req.SuccessfulSmartServerResponse((b'ok',)),
2360
 
                         request.execute(b'', b'False'))
2361
 
        repo = repo.controldir.open_repository()
 
1726
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(('ok',)),
 
1727
            request.execute('', 'False'))
 
1728
        repo = repo.bzrdir.open_repository()
2362
1729
        self.assertFalse(repo.make_working_trees())
2363
1730
 
2364
1731
    def test_set_true(self):
2367
1734
        repo.set_make_working_trees(False)
2368
1735
        request_class = smart_repo.SmartServerRepositorySetMakeWorkingTrees
2369
1736
        request = request_class(backing)
2370
 
        self.assertEqual(smart_req.SuccessfulSmartServerResponse((b'ok',)),
2371
 
                         request.execute(b'', b'True'))
2372
 
        repo = repo.controldir.open_repository()
 
1737
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(('ok',)),
 
1738
            request.execute('', 'True'))
 
1739
        repo = repo.bzrdir.open_repository()
2373
1740
        self.assertTrue(repo.make_working_trees())
2374
1741
 
2375
1742
 
2376
 
class TestSmartServerRepositoryGetSerializerFormat(
2377
 
        tests.TestCaseWithMemoryTransport):
2378
 
 
2379
 
    def test_get_serializer_format(self):
2380
 
        backing = self.get_transport()
2381
 
        repo = self.make_repository('.', format='2a')
2382
 
        request_class = smart_repo.SmartServerRepositoryGetSerializerFormat
2383
 
        request = request_class(backing)
2384
 
        self.assertEqual(
2385
 
            smart_req.SuccessfulSmartServerResponse((b'ok', b'10')),
2386
 
            request.execute(b''))
2387
 
 
2388
 
 
2389
 
class TestSmartServerRepositoryWriteGroup(
2390
 
        tests.TestCaseWithMemoryTransport):
2391
 
 
2392
 
    def test_start_write_group(self):
2393
 
        backing = self.get_transport()
2394
 
        repo = self.make_repository('.')
2395
 
        lock_token = repo.lock_write().repository_token
2396
 
        self.addCleanup(repo.unlock)
2397
 
        request_class = smart_repo.SmartServerRepositoryStartWriteGroup
2398
 
        request = request_class(backing)
2399
 
        self.assertEqual(smart_req.SuccessfulSmartServerResponse((b'ok', [])),
2400
 
                         request.execute(b'', lock_token))
2401
 
 
2402
 
    def test_start_write_group_unsuspendable(self):
2403
 
        backing = self.get_transport()
2404
 
        repo = self.make_repository('.', format='knit')
2405
 
        lock_token = repo.lock_write().repository_token
2406
 
        self.addCleanup(repo.unlock)
2407
 
        request_class = smart_repo.SmartServerRepositoryStartWriteGroup
2408
 
        request = request_class(backing)
2409
 
        self.assertEqual(
2410
 
            smart_req.FailedSmartServerResponse((b'UnsuspendableWriteGroup',)),
2411
 
            request.execute(b'', lock_token))
2412
 
 
2413
 
    def test_commit_write_group(self):
2414
 
        backing = self.get_transport()
2415
 
        repo = self.make_repository('.')
2416
 
        lock_token = repo.lock_write().repository_token
2417
 
        self.addCleanup(repo.unlock)
2418
 
        repo.start_write_group()
2419
 
        tokens = repo.suspend_write_group()
2420
 
        request_class = smart_repo.SmartServerRepositoryCommitWriteGroup
2421
 
        request = request_class(backing)
2422
 
        self.assertEqual(smart_req.SuccessfulSmartServerResponse((b'ok',)),
2423
 
                         request.execute(b'', lock_token, tokens))
2424
 
 
2425
 
    def test_abort_write_group(self):
2426
 
        backing = self.get_transport()
2427
 
        repo = self.make_repository('.')
2428
 
        lock_token = repo.lock_write().repository_token
2429
 
        repo.start_write_group()
2430
 
        tokens = repo.suspend_write_group()
2431
 
        self.addCleanup(repo.unlock)
2432
 
        request_class = smart_repo.SmartServerRepositoryAbortWriteGroup
2433
 
        request = request_class(backing)
2434
 
        self.assertEqual(smart_req.SuccessfulSmartServerResponse((b'ok',)),
2435
 
                         request.execute(b'', lock_token, tokens))
2436
 
 
2437
 
    def test_check_write_group(self):
2438
 
        backing = self.get_transport()
2439
 
        repo = self.make_repository('.')
2440
 
        lock_token = repo.lock_write().repository_token
2441
 
        repo.start_write_group()
2442
 
        tokens = repo.suspend_write_group()
2443
 
        self.addCleanup(repo.unlock)
2444
 
        request_class = smart_repo.SmartServerRepositoryCheckWriteGroup
2445
 
        request = request_class(backing)
2446
 
        self.assertEqual(smart_req.SuccessfulSmartServerResponse((b'ok',)),
2447
 
                         request.execute(b'', lock_token, tokens))
2448
 
 
2449
 
    def test_check_write_group_invalid(self):
2450
 
        backing = self.get_transport()
2451
 
        repo = self.make_repository('.')
2452
 
        lock_token = repo.lock_write().repository_token
2453
 
        self.addCleanup(repo.unlock)
2454
 
        request_class = smart_repo.SmartServerRepositoryCheckWriteGroup
2455
 
        request = request_class(backing)
2456
 
        self.assertEqual(smart_req.FailedSmartServerResponse(
2457
 
            (b'UnresumableWriteGroup', [b'random'],
2458
 
                b'Malformed write group token')),
2459
 
            request.execute(b'', lock_token, [b"random"]))
2460
 
 
2461
 
 
2462
1743
class TestSmartServerPackRepositoryAutopack(tests.TestCaseWithTransport):
2463
1744
 
2464
1745
    def make_repo_needing_autopacking(self, path='.'):
2480
1761
        backing = self.get_transport()
2481
1762
        request = smart_packrepo.SmartServerPackRepositoryAutopack(
2482
1763
            backing)
2483
 
        response = request.execute(b'')
2484
 
        self.assertEqual(smart_req.SmartServerResponse((b'ok',)), response)
 
1764
        response = request.execute('')
 
1765
        self.assertEqual(smart_req.SmartServerResponse(('ok',)), response)
2485
1766
        repo._pack_collection.reload_pack_names()
2486
1767
        self.assertEqual(1, len(repo._pack_collection.names()))
2487
1768
 
2495
1776
        backing = self.get_transport()
2496
1777
        request = smart_packrepo.SmartServerPackRepositoryAutopack(
2497
1778
            backing)
2498
 
        response = request.execute(b'')
2499
 
        self.assertEqual(smart_req.SmartServerResponse((b'ok',)), response)
 
1779
        response = request.execute('')
 
1780
        self.assertEqual(smart_req.SmartServerResponse(('ok',)), response)
2500
1781
        repo._pack_collection.reload_pack_names()
2501
1782
        self.assertEqual(9, len(repo._pack_collection.names()))
2502
1783
 
2506
1787
        backing = self.get_transport()
2507
1788
        request = smart_packrepo.SmartServerPackRepositoryAutopack(
2508
1789
            backing)
2509
 
        response = request.execute(b'')
2510
 
        self.assertEqual(smart_req.SmartServerResponse((b'ok',)), response)
 
1790
        response = request.execute('')
 
1791
        self.assertEqual(smart_req.SmartServerResponse(('ok',)), response)
2511
1792
 
2512
1793
 
2513
1794
class TestSmartServerVfsGet(tests.TestCaseWithMemoryTransport):
2518
1799
        filename_escaped = urlutils.escape(filename)
2519
1800
        backing = self.get_transport()
2520
1801
        request = vfs.GetRequest(backing)
2521
 
        backing.put_bytes_non_atomic(filename_escaped, b'contents')
2522
 
        self.assertEqual(smart_req.SmartServerResponse((b'ok', ), b'contents'),
2523
 
                         request.execute(filename_escaped.encode('ascii')))
 
1802
        backing.put_bytes_non_atomic(filename_escaped, 'contents')
 
1803
        self.assertEqual(smart_req.SmartServerResponse(('ok', ), 'contents'),
 
1804
            request.execute(filename_escaped))
2524
1805
 
2525
1806
 
2526
1807
class TestHandlers(tests.TestCase):
2530
1811
        """All registered request_handlers can be found."""
2531
1812
        # If there's a typo in a register_lazy call, this loop will fail with
2532
1813
        # an AttributeError.
2533
 
        for key in smart_req.request_handlers.keys():
2534
 
            try:
2535
 
                item = smart_req.request_handlers.get(key)
2536
 
            except AttributeError as e:
2537
 
                raise AttributeError('failed to get %s: %s' % (key, e))
 
1814
        for key, item in smart_req.request_handlers.iteritems():
 
1815
            pass
2538
1816
 
2539
1817
    def assertHandlerEqual(self, verb, handler):
2540
1818
        self.assertEqual(smart_req.request_handlers.get(verb), handler)
2541
1819
 
2542
1820
    def test_registered_methods(self):
2543
1821
        """Test that known methods are registered to the correct object."""
2544
 
        self.assertHandlerEqual(b'Branch.break_lock',
2545
 
                                smart_branch.SmartServerBranchBreakLock)
2546
 
        self.assertHandlerEqual(b'Branch.get_config_file',
2547
 
                                smart_branch.SmartServerBranchGetConfigFile)
2548
 
        self.assertHandlerEqual(b'Branch.put_config_file',
2549
 
                                smart_branch.SmartServerBranchPutConfigFile)
2550
 
        self.assertHandlerEqual(b'Branch.get_parent',
2551
 
                                smart_branch.SmartServerBranchGetParent)
2552
 
        self.assertHandlerEqual(b'Branch.get_physical_lock_status',
2553
 
                                smart_branch.SmartServerBranchRequestGetPhysicalLockStatus)
2554
 
        self.assertHandlerEqual(b'Branch.get_tags_bytes',
2555
 
                                smart_branch.SmartServerBranchGetTagsBytes)
2556
 
        self.assertHandlerEqual(b'Branch.lock_write',
2557
 
                                smart_branch.SmartServerBranchRequestLockWrite)
2558
 
        self.assertHandlerEqual(b'Branch.last_revision_info',
2559
 
                                smart_branch.SmartServerBranchRequestLastRevisionInfo)
2560
 
        self.assertHandlerEqual(b'Branch.revision_history',
2561
 
                                smart_branch.SmartServerRequestRevisionHistory)
2562
 
        self.assertHandlerEqual(b'Branch.revision_id_to_revno',
2563
 
                                smart_branch.SmartServerBranchRequestRevisionIdToRevno)
2564
 
        self.assertHandlerEqual(b'Branch.set_config_option',
2565
 
                                smart_branch.SmartServerBranchRequestSetConfigOption)
2566
 
        self.assertHandlerEqual(b'Branch.set_last_revision',
2567
 
                                smart_branch.SmartServerBranchRequestSetLastRevision)
2568
 
        self.assertHandlerEqual(b'Branch.set_last_revision_info',
2569
 
                                smart_branch.SmartServerBranchRequestSetLastRevisionInfo)
2570
 
        self.assertHandlerEqual(b'Branch.set_last_revision_ex',
2571
 
                                smart_branch.SmartServerBranchRequestSetLastRevisionEx)
2572
 
        self.assertHandlerEqual(b'Branch.set_parent_location',
2573
 
                                smart_branch.SmartServerBranchRequestSetParentLocation)
2574
 
        self.assertHandlerEqual(b'Branch.unlock',
2575
 
                                smart_branch.SmartServerBranchRequestUnlock)
2576
 
        self.assertHandlerEqual(b'BzrDir.destroy_branch',
2577
 
                                smart_dir.SmartServerBzrDirRequestDestroyBranch)
2578
 
        self.assertHandlerEqual(b'BzrDir.find_repository',
2579
 
                                smart_dir.SmartServerRequestFindRepositoryV1)
2580
 
        self.assertHandlerEqual(b'BzrDir.find_repositoryV2',
2581
 
                                smart_dir.SmartServerRequestFindRepositoryV2)
2582
 
        self.assertHandlerEqual(b'BzrDirFormat.initialize',
2583
 
                                smart_dir.SmartServerRequestInitializeBzrDir)
2584
 
        self.assertHandlerEqual(b'BzrDirFormat.initialize_ex_1.16',
2585
 
                                smart_dir.SmartServerRequestBzrDirInitializeEx)
2586
 
        self.assertHandlerEqual(b'BzrDir.checkout_metadir',
2587
 
                                smart_dir.SmartServerBzrDirRequestCheckoutMetaDir)
2588
 
        self.assertHandlerEqual(b'BzrDir.cloning_metadir',
2589
 
                                smart_dir.SmartServerBzrDirRequestCloningMetaDir)
2590
 
        self.assertHandlerEqual(b'BzrDir.get_branches',
2591
 
                                smart_dir.SmartServerBzrDirRequestGetBranches)
2592
 
        self.assertHandlerEqual(b'BzrDir.get_config_file',
2593
 
                                smart_dir.SmartServerBzrDirRequestConfigFile)
2594
 
        self.assertHandlerEqual(b'BzrDir.open_branch',
2595
 
                                smart_dir.SmartServerRequestOpenBranch)
2596
 
        self.assertHandlerEqual(b'BzrDir.open_branchV2',
2597
 
                                smart_dir.SmartServerRequestOpenBranchV2)
2598
 
        self.assertHandlerEqual(b'BzrDir.open_branchV3',
2599
 
                                smart_dir.SmartServerRequestOpenBranchV3)
2600
 
        self.assertHandlerEqual(b'PackRepository.autopack',
2601
 
                                smart_packrepo.SmartServerPackRepositoryAutopack)
2602
 
        self.assertHandlerEqual(b'Repository.add_signature_text',
2603
 
                                smart_repo.SmartServerRepositoryAddSignatureText)
2604
 
        self.assertHandlerEqual(b'Repository.all_revision_ids',
2605
 
                                smart_repo.SmartServerRepositoryAllRevisionIds)
2606
 
        self.assertHandlerEqual(b'Repository.break_lock',
2607
 
                                smart_repo.SmartServerRepositoryBreakLock)
2608
 
        self.assertHandlerEqual(b'Repository.gather_stats',
2609
 
                                smart_repo.SmartServerRepositoryGatherStats)
2610
 
        self.assertHandlerEqual(b'Repository.get_parent_map',
2611
 
                                smart_repo.SmartServerRepositoryGetParentMap)
2612
 
        self.assertHandlerEqual(b'Repository.get_physical_lock_status',
2613
 
                                smart_repo.SmartServerRepositoryGetPhysicalLockStatus)
2614
 
        self.assertHandlerEqual(b'Repository.get_rev_id_for_revno',
2615
 
                                smart_repo.SmartServerRepositoryGetRevIdForRevno)
2616
 
        self.assertHandlerEqual(b'Repository.get_revision_graph',
2617
 
                                smart_repo.SmartServerRepositoryGetRevisionGraph)
2618
 
        self.assertHandlerEqual(b'Repository.get_revision_signature_text',
2619
 
                                smart_repo.SmartServerRepositoryGetRevisionSignatureText)
2620
 
        self.assertHandlerEqual(b'Repository.get_stream',
2621
 
                                smart_repo.SmartServerRepositoryGetStream)
2622
 
        self.assertHandlerEqual(b'Repository.get_stream_1.19',
2623
 
                                smart_repo.SmartServerRepositoryGetStream_1_19)
2624
 
        self.assertHandlerEqual(b'Repository.iter_revisions',
2625
 
                                smart_repo.SmartServerRepositoryIterRevisions)
2626
 
        self.assertHandlerEqual(b'Repository.has_revision',
2627
 
                                smart_repo.SmartServerRequestHasRevision)
2628
 
        self.assertHandlerEqual(b'Repository.insert_stream',
2629
 
                                smart_repo.SmartServerRepositoryInsertStream)
2630
 
        self.assertHandlerEqual(b'Repository.insert_stream_locked',
2631
 
                                smart_repo.SmartServerRepositoryInsertStreamLocked)
2632
 
        self.assertHandlerEqual(b'Repository.is_shared',
2633
 
                                smart_repo.SmartServerRepositoryIsShared)
2634
 
        self.assertHandlerEqual(b'Repository.iter_files_bytes',
2635
 
                                smart_repo.SmartServerRepositoryIterFilesBytes)
2636
 
        self.assertHandlerEqual(b'Repository.lock_write',
2637
 
                                smart_repo.SmartServerRepositoryLockWrite)
2638
 
        self.assertHandlerEqual(b'Repository.make_working_trees',
2639
 
                                smart_repo.SmartServerRepositoryMakeWorkingTrees)
2640
 
        self.assertHandlerEqual(b'Repository.pack',
2641
 
                                smart_repo.SmartServerRepositoryPack)
2642
 
        self.assertHandlerEqual(b'Repository.reconcile',
2643
 
                                smart_repo.SmartServerRepositoryReconcile)
2644
 
        self.assertHandlerEqual(b'Repository.tarball',
2645
 
                                smart_repo.SmartServerRepositoryTarball)
2646
 
        self.assertHandlerEqual(b'Repository.unlock',
2647
 
                                smart_repo.SmartServerRepositoryUnlock)
2648
 
        self.assertHandlerEqual(b'Repository.start_write_group',
2649
 
                                smart_repo.SmartServerRepositoryStartWriteGroup)
2650
 
        self.assertHandlerEqual(b'Repository.check_write_group',
2651
 
                                smart_repo.SmartServerRepositoryCheckWriteGroup)
2652
 
        self.assertHandlerEqual(b'Repository.commit_write_group',
2653
 
                                smart_repo.SmartServerRepositoryCommitWriteGroup)
2654
 
        self.assertHandlerEqual(b'Repository.abort_write_group',
2655
 
                                smart_repo.SmartServerRepositoryAbortWriteGroup)
2656
 
        self.assertHandlerEqual(b'VersionedFileRepository.get_serializer_format',
2657
 
                                smart_repo.SmartServerRepositoryGetSerializerFormat)
2658
 
        self.assertHandlerEqual(b'VersionedFileRepository.get_inventories',
2659
 
                                smart_repo.SmartServerRepositoryGetInventories)
2660
 
        self.assertHandlerEqual(b'Transport.is_readonly',
2661
 
                                smart_req.SmartServerIsReadonly)
2662
 
 
2663
 
 
2664
 
class SmartTCPServerHookTests(tests.TestCaseWithMemoryTransport):
2665
 
    """Tests for SmartTCPServer hooks."""
2666
 
 
2667
 
    def setUp(self):
2668
 
        super(SmartTCPServerHookTests, self).setUp()
2669
 
        self.server = server.SmartTCPServer(self.get_transport())
2670
 
 
2671
 
    def test_run_server_started_hooks(self):
2672
 
        """Test the server started hooks get fired properly."""
2673
 
        started_calls = []
2674
 
        server.SmartTCPServer.hooks.install_named_hook('server_started',
2675
 
                                                       lambda backing_urls, url: started_calls.append(
2676
 
                                                           (backing_urls, url)),
2677
 
                                                       None)
2678
 
        started_ex_calls = []
2679
 
        server.SmartTCPServer.hooks.install_named_hook('server_started_ex',
2680
 
                                                       lambda backing_urls, url: started_ex_calls.append(
2681
 
                                                           (backing_urls, url)),
2682
 
                                                       None)
2683
 
        self.server._sockname = ('example.com', 42)
2684
 
        self.server.run_server_started_hooks()
2685
 
        self.assertEqual(started_calls,
2686
 
                         [([self.get_transport().base], 'bzr://example.com:42/')])
2687
 
        self.assertEqual(started_ex_calls,
2688
 
                         [([self.get_transport().base], self.server)])
2689
 
 
2690
 
    def test_run_server_started_hooks_ipv6(self):
2691
 
        """Test that socknames can contain 4-tuples."""
2692
 
        self.server._sockname = ('::', 42, 0, 0)
2693
 
        started_calls = []
2694
 
        server.SmartTCPServer.hooks.install_named_hook('server_started',
2695
 
                                                       lambda backing_urls, url: started_calls.append(
2696
 
                                                           (backing_urls, url)),
2697
 
                                                       None)
2698
 
        self.server.run_server_started_hooks()
2699
 
        self.assertEqual(started_calls,
2700
 
                         [([self.get_transport().base], 'bzr://:::42/')])
2701
 
 
2702
 
    def test_run_server_stopped_hooks(self):
2703
 
        """Test the server stopped hooks."""
2704
 
        self.server._sockname = ('example.com', 42)
2705
 
        stopped_calls = []
2706
 
        server.SmartTCPServer.hooks.install_named_hook('server_stopped',
2707
 
                                                       lambda backing_urls, url: stopped_calls.append(
2708
 
                                                           (backing_urls, url)),
2709
 
                                                       None)
2710
 
        self.server.run_server_stopped_hooks()
2711
 
        self.assertEqual(stopped_calls,
2712
 
                         [([self.get_transport().base], 'bzr://example.com:42/')])
2713
 
 
2714
 
 
2715
 
class TestSmartServerRepositoryPack(tests.TestCaseWithMemoryTransport):
2716
 
 
2717
 
    def test_pack(self):
2718
 
        backing = self.get_transport()
2719
 
        request = smart_repo.SmartServerRepositoryPack(backing)
2720
 
        tree = self.make_branch_and_memory_tree('.')
2721
 
        repo_token = tree.branch.repository.lock_write().repository_token
2722
 
 
2723
 
        self.assertIs(None, request.execute(b'', repo_token, False))
2724
 
 
2725
 
        self.assertEqual(
2726
 
            smart_req.SuccessfulSmartServerResponse((b'ok', ), ),
2727
 
            request.do_body(b''))
2728
 
 
2729
 
 
2730
 
class TestSmartServerRepositoryGetInventories(tests.TestCaseWithTransport):
2731
 
 
2732
 
    def _get_serialized_inventory_delta(self, repository, base_revid, revid):
2733
 
        base_inv = repository.revision_tree(base_revid).root_inventory
2734
 
        inv = repository.revision_tree(revid).root_inventory
2735
 
        inv_delta = inv._make_delta(base_inv)
2736
 
        serializer = inventory_delta.InventoryDeltaSerializer(True, True)
2737
 
        return b"".join(serializer.delta_to_lines(base_revid, revid, inv_delta))
2738
 
 
2739
 
    def test_single(self):
2740
 
        backing = self.get_transport()
2741
 
        request = smart_repo.SmartServerRepositoryGetInventories(backing)
2742
 
        t = self.make_branch_and_tree('.', format='2a')
2743
 
        self.addCleanup(t.lock_write().unlock)
2744
 
        self.build_tree_contents([("file", b"somecontents")])
2745
 
        t.add(["file"], [b"thefileid"])
2746
 
        t.commit(rev_id=b'somerev', message="add file")
2747
 
        self.assertIs(None, request.execute(b'', b'unordered'))
2748
 
        response = request.do_body(b"somerev\n")
2749
 
        self.assertTrue(response.is_successful())
2750
 
        self.assertEqual(response.args, (b"ok", ))
2751
 
        stream = [('inventory-deltas', [
2752
 
            versionedfile.FulltextContentFactory(b'somerev', None, None,
2753
 
                                                 self._get_serialized_inventory_delta(
2754
 
                                                     t.branch.repository, b'null:', b'somerev'))])]
2755
 
        fmt = controldir.format_registry.get('2a')().repository_format
2756
 
        self.assertEqual(
2757
 
            b"".join(response.body_stream),
2758
 
            b"".join(smart_repo._stream_to_byte_stream(stream, fmt)))
2759
 
 
2760
 
    def test_empty(self):
2761
 
        backing = self.get_transport()
2762
 
        request = smart_repo.SmartServerRepositoryGetInventories(backing)
2763
 
        t = self.make_branch_and_tree('.', format='2a')
2764
 
        self.addCleanup(t.lock_write().unlock)
2765
 
        self.build_tree_contents([("file", b"somecontents")])
2766
 
        t.add(["file"], [b"thefileid"])
2767
 
        t.commit(rev_id=b'somerev', message="add file")
2768
 
        self.assertIs(None, request.execute(b'', b'unordered'))
2769
 
        response = request.do_body(b"")
2770
 
        self.assertTrue(response.is_successful())
2771
 
        self.assertEqual(response.args, (b"ok", ))
2772
 
        self.assertEqual(b"".join(response.body_stream),
2773
 
                         b"Bazaar pack format 1 (introduced in 0.18)\nB54\n\nBazaar repository format 2a (needs bzr 1.16 or later)\nE")
2774
 
 
2775
 
 
2776
 
class TestSmartServerRepositoryGetStreamForMissingKeys(GetStreamTestBase):
2777
 
 
2778
 
    def test_missing(self):
2779
 
        """The search argument may be a 'ancestry-of' some heads'."""
2780
 
        backing = self.get_transport()
2781
 
        request = smart_repo.SmartServerRepositoryGetStreamForMissingKeys(
2782
 
            backing)
2783
 
        repo, r1, r2 = self.make_two_commit_repo()
2784
 
        request.execute(b'', repo._format.network_name())
2785
 
        lines = b'inventories\t' + r1
2786
 
        response = request.do_body(lines)
2787
 
        self.assertEqual((b'ok',), response.args)
2788
 
        stream_bytes = b''.join(response.body_stream)
2789
 
        self.assertStartsWith(stream_bytes, b'Bazaar pack format 1')
2790
 
 
2791
 
    def test_unknown_format(self):
2792
 
        """The format may not be known by the remote server."""
2793
 
        backing = self.get_transport()
2794
 
        request = smart_repo.SmartServerRepositoryGetStreamForMissingKeys(
2795
 
            backing)
2796
 
        repo, r1, r2 = self.make_two_commit_repo()
2797
 
        request.execute(b'', b'yada yada yada')
2798
 
        expected = smart_req.FailedSmartServerResponse(
2799
 
            (b'UnknownFormat', b'repository', b'yada yada yada'))
2800
 
 
2801
 
 
2802
 
class TestSmartServerRepositoryRevisionArchive(tests.TestCaseWithTransport):
2803
 
    def test_get(self):
2804
 
        backing = self.get_transport()
2805
 
        request = smart_repo.SmartServerRepositoryRevisionArchive(backing)
2806
 
        t = self.make_branch_and_tree('.')
2807
 
        self.addCleanup(t.lock_write().unlock)
2808
 
        self.build_tree_contents([("file", b"somecontents")])
2809
 
        t.add(["file"], [b"thefileid"])
2810
 
        t.commit(rev_id=b'somerev', message="add file")
2811
 
        response = request.execute(b'', b"somerev", b"tar", b"foo.tar", b"foo")
2812
 
        self.assertTrue(response.is_successful())
2813
 
        self.assertEqual(response.args, (b"ok", ))
2814
 
        b = BytesIO(b"".join(response.body_stream))
2815
 
        with tarfile.open(mode='r', fileobj=b) as tf:
2816
 
            self.assertEqual(['foo/file'], tf.getnames())
2817
 
 
2818
 
 
2819
 
class TestSmartServerRepositoryAnnotateFileRevision(tests.TestCaseWithTransport):
2820
 
 
2821
 
    def test_get(self):
2822
 
        backing = self.get_transport()
2823
 
        request = smart_repo.SmartServerRepositoryAnnotateFileRevision(backing)
2824
 
        t = self.make_branch_and_tree('.')
2825
 
        self.addCleanup(t.lock_write().unlock)
2826
 
        self.build_tree_contents([("file", b"somecontents\nmorecontents\n")])
2827
 
        t.add(["file"], [b"thefileid"])
2828
 
        t.commit(rev_id=b'somerev', message="add file")
2829
 
        response = request.execute(b'', b"somerev", b"file")
2830
 
        self.assertTrue(response.is_successful())
2831
 
        self.assertEqual(response.args, (b"ok", ))
2832
 
        self.assertEqual(
2833
 
            [[b'somerev', b'somecontents\n'], [b'somerev', b'morecontents\n']],
2834
 
            bencode.bdecode(response.body))
2835
 
 
2836
 
 
2837
 
class TestSmartServerBranchRequestGetAllReferenceInfo(TestLockedBranch):
2838
 
 
2839
 
    def test_get_some(self):
2840
 
        backing = self.get_transport()
2841
 
        request = smart_branch.SmartServerBranchRequestGetAllReferenceInfo(backing)
2842
 
        branch = self.make_branch('.')
2843
 
        branch.set_reference_info('some/path', 'http://www.example.com/')
2844
 
        response = request.execute(b'')
2845
 
        self.assertTrue(response.is_successful())
2846
 
        self.assertEqual(response.args, (b"ok", ))
2847
 
        self.assertEqual(
2848
 
            [[b'some/path', b'http://www.example.com/', b'']],
2849
 
            bencode.bdecode(response.body))
 
1822
        self.assertHandlerEqual('Branch.get_config_file',
 
1823
            smart_branch.SmartServerBranchGetConfigFile)
 
1824
        self.assertHandlerEqual('Branch.get_parent',
 
1825
            smart_branch.SmartServerBranchGetParent)
 
1826
        self.assertHandlerEqual('Branch.get_tags_bytes',
 
1827
            smart_branch.SmartServerBranchGetTagsBytes)
 
1828
        self.assertHandlerEqual('Branch.lock_write',
 
1829
            smart_branch.SmartServerBranchRequestLockWrite)
 
1830
        self.assertHandlerEqual('Branch.last_revision_info',
 
1831
            smart_branch.SmartServerBranchRequestLastRevisionInfo)
 
1832
        self.assertHandlerEqual('Branch.revision_history',
 
1833
            smart_branch.SmartServerRequestRevisionHistory)
 
1834
        self.assertHandlerEqual('Branch.set_config_option',
 
1835
            smart_branch.SmartServerBranchRequestSetConfigOption)
 
1836
        self.assertHandlerEqual('Branch.set_last_revision',
 
1837
            smart_branch.SmartServerBranchRequestSetLastRevision)
 
1838
        self.assertHandlerEqual('Branch.set_last_revision_info',
 
1839
            smart_branch.SmartServerBranchRequestSetLastRevisionInfo)
 
1840
        self.assertHandlerEqual('Branch.set_last_revision_ex',
 
1841
            smart_branch.SmartServerBranchRequestSetLastRevisionEx)
 
1842
        self.assertHandlerEqual('Branch.set_parent_location',
 
1843
            smart_branch.SmartServerBranchRequestSetParentLocation)
 
1844
        self.assertHandlerEqual('Branch.unlock',
 
1845
            smart_branch.SmartServerBranchRequestUnlock)
 
1846
        self.assertHandlerEqual('BzrDir.find_repository',
 
1847
            smart_dir.SmartServerRequestFindRepositoryV1)
 
1848
        self.assertHandlerEqual('BzrDir.find_repositoryV2',
 
1849
            smart_dir.SmartServerRequestFindRepositoryV2)
 
1850
        self.assertHandlerEqual('BzrDirFormat.initialize',
 
1851
            smart_dir.SmartServerRequestInitializeBzrDir)
 
1852
        self.assertHandlerEqual('BzrDirFormat.initialize_ex_1.16',
 
1853
            smart_dir.SmartServerRequestBzrDirInitializeEx)
 
1854
        self.assertHandlerEqual('BzrDir.cloning_metadir',
 
1855
            smart_dir.SmartServerBzrDirRequestCloningMetaDir)
 
1856
        self.assertHandlerEqual('BzrDir.get_config_file',
 
1857
            smart_dir.SmartServerBzrDirRequestConfigFile)
 
1858
        self.assertHandlerEqual('BzrDir.open_branch',
 
1859
            smart_dir.SmartServerRequestOpenBranch)
 
1860
        self.assertHandlerEqual('BzrDir.open_branchV2',
 
1861
            smart_dir.SmartServerRequestOpenBranchV2)
 
1862
        self.assertHandlerEqual('BzrDir.open_branchV3',
 
1863
            smart_dir.SmartServerRequestOpenBranchV3)
 
1864
        self.assertHandlerEqual('PackRepository.autopack',
 
1865
            smart_packrepo.SmartServerPackRepositoryAutopack)
 
1866
        self.assertHandlerEqual('Repository.gather_stats',
 
1867
            smart_repo.SmartServerRepositoryGatherStats)
 
1868
        self.assertHandlerEqual('Repository.get_parent_map',
 
1869
            smart_repo.SmartServerRepositoryGetParentMap)
 
1870
        self.assertHandlerEqual('Repository.get_rev_id_for_revno',
 
1871
            smart_repo.SmartServerRepositoryGetRevIdForRevno)
 
1872
        self.assertHandlerEqual('Repository.get_revision_graph',
 
1873
            smart_repo.SmartServerRepositoryGetRevisionGraph)
 
1874
        self.assertHandlerEqual('Repository.get_stream',
 
1875
            smart_repo.SmartServerRepositoryGetStream)
 
1876
        self.assertHandlerEqual('Repository.has_revision',
 
1877
            smart_repo.SmartServerRequestHasRevision)
 
1878
        self.assertHandlerEqual('Repository.insert_stream',
 
1879
            smart_repo.SmartServerRepositoryInsertStream)
 
1880
        self.assertHandlerEqual('Repository.insert_stream_locked',
 
1881
            smart_repo.SmartServerRepositoryInsertStreamLocked)
 
1882
        self.assertHandlerEqual('Repository.is_shared',
 
1883
            smart_repo.SmartServerRepositoryIsShared)
 
1884
        self.assertHandlerEqual('Repository.lock_write',
 
1885
            smart_repo.SmartServerRepositoryLockWrite)
 
1886
        self.assertHandlerEqual('Repository.tarball',
 
1887
            smart_repo.SmartServerRepositoryTarball)
 
1888
        self.assertHandlerEqual('Repository.unlock',
 
1889
            smart_repo.SmartServerRepositoryUnlock)
 
1890
        self.assertHandlerEqual('Transport.is_readonly',
 
1891
            smart_req.SmartServerIsReadonly)