/brz/remove-bazaar

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

« back to all changes in this revision

Viewing changes to breezy/tests/test_smart.py

  • Committer: Jelmer Vernooij
  • Date: 2018-06-11 20:48:24 UTC
  • mfrom: (6974.2.1 python3-graph)
  • Revision ID: jelmer@jelmer.uk-20180611204824-zll0a3pzyciekd1f
merge lp:~jelmer/brz/python3-graph

Show diffs side-by-side

added added

removed removed

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