/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-05-19 13:16:11 UTC
  • mto: (6968.4.3 git-archive)
  • mto: This revision was merged to the branch mainline in revision 6972.
  • Revision ID: jelmer@jelmer.uk-20180519131611-l9h9ud41j7qg1m03
Move tar/zip to breezy.archive.

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''))
725
855
 
726
856
    def test_not_empty(self):
727
857
        """For a non-empty branch, the result is ('ok', 'revno', 'revid')."""
735
865
        r2 = tree.commit('2nd commit', rev_id=rev_id_utf8)
736
866
        tree.unlock()
737
867
        self.assertEqual(
738
 
            smart_req.SmartServerResponse(('ok', '2', rev_id_utf8)),
739
 
            request.execute(''))
 
868
            smart_req.SmartServerResponse((b'ok', b'2', rev_id_utf8)),
 
869
            request.execute(b''))
 
870
 
 
871
 
 
872
class TestSmartServerBranchRequestRevisionIdToRevno(
 
873
    tests.TestCaseWithMemoryTransport):
 
874
 
 
875
    def test_null(self):
 
876
        backing = self.get_transport()
 
877
        request = smart_branch.SmartServerBranchRequestRevisionIdToRevno(
 
878
            backing)
 
879
        self.make_branch('.')
 
880
        self.assertEqual(smart_req.SmartServerResponse((b'ok', b'0')),
 
881
            request.execute(b'', b'null:'))
 
882
 
 
883
    def test_simple(self):
 
884
        backing = self.get_transport()
 
885
        request = smart_branch.SmartServerBranchRequestRevisionIdToRevno(
 
886
            backing)
 
887
        tree = self.make_branch_and_memory_tree('.')
 
888
        tree.lock_write()
 
889
        tree.add('')
 
890
        r1 = tree.commit('1st commit')
 
891
        tree.unlock()
 
892
        self.assertEqual(
 
893
            smart_req.SmartServerResponse((b'ok', '1')),
 
894
            request.execute(b'', r1))
 
895
 
 
896
    def test_not_found(self):
 
897
        backing = self.get_transport()
 
898
        request = smart_branch.SmartServerBranchRequestRevisionIdToRevno(
 
899
            backing)
 
900
        branch = self.make_branch('.')
 
901
        self.assertEqual(
 
902
            smart_req.FailedSmartServerResponse(
 
903
                (b'NoSuchRevision', b'idontexist')),
 
904
            request.execute(b'', b'idontexist'))
740
905
 
741
906
 
742
907
class TestSmartServerBranchRequestGetConfigFile(
749
914
        branch = self.make_branch('.')
750
915
        # there should be no file by default
751
916
        content = ''
752
 
        self.assertEqual(smart_req.SmartServerResponse(('ok', ), content),
753
 
            request.execute(''))
 
917
        self.assertEqual(smart_req.SmartServerResponse((b'ok', ), content),
 
918
            request.execute(b''))
754
919
 
755
920
    def test_with_content(self):
756
921
        # SmartServerBranchGetConfigFile should return the content from
759
924
        backing = self.get_transport()
760
925
        request = smart_branch.SmartServerBranchGetConfigFile(backing)
761
926
        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(''))
 
927
        branch._transport.put_bytes('branch.conf', b'foo bar baz')
 
928
        self.assertEqual(smart_req.SmartServerResponse((b'ok', ), b'foo bar baz'),
 
929
            request.execute(b''))
765
930
 
766
931
 
767
932
class TestLockedBranch(tests.TestCaseWithMemoryTransport):
768
933
 
769
934
    def get_lock_tokens(self, branch):
770
 
        branch_token = branch.lock_write().branch_token
 
935
        branch_token = branch.lock_write().token
771
936
        repo_token = branch.repository.lock_write().repository_token
772
937
        branch.repository.unlock()
773
938
        return branch_token, repo_token
774
939
 
775
940
 
 
941
class TestSmartServerBranchRequestPutConfigFile(TestLockedBranch):
 
942
 
 
943
    def test_with_content(self):
 
944
        backing = self.get_transport()
 
945
        request = smart_branch.SmartServerBranchPutConfigFile(backing)
 
946
        branch = self.make_branch('.')
 
947
        branch_token, repo_token = self.get_lock_tokens(branch)
 
948
        self.assertIs(None, request.execute(b'', branch_token, repo_token))
 
949
        self.assertEqual(
 
950
            smart_req.SmartServerResponse((b'ok', )),
 
951
            request.do_body(b'foo bar baz'))
 
952
        self.assertEqual(
 
953
            branch.control_transport.get_bytes(b'branch.conf'),
 
954
            b'foo bar baz')
 
955
        branch.unlock()
 
956
 
 
957
 
776
958
class TestSmartServerBranchRequestSetConfigOption(TestLockedBranch):
777
959
 
778
960
    def test_value_name(self):
779
961
        branch = self.make_branch('.')
780
962
        request = smart_branch.SmartServerBranchRequestSetConfigOption(
781
 
            branch.bzrdir.root_transport)
 
963
            branch.controldir.root_transport)
782
964
        branch_token, repo_token = self.get_lock_tokens(branch)
783
965
        config = branch._get_config()
784
 
        result = request.execute('', branch_token, repo_token, 'bar', 'foo',
785
 
            '')
 
966
        result = request.execute(b'', branch_token, repo_token, b'bar', b'foo',
 
967
            b'')
786
968
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(()), result)
787
969
        self.assertEqual('bar', config.get_option('foo'))
788
970
        # Cleanup
791
973
    def test_value_name_section(self):
792
974
        branch = self.make_branch('.')
793
975
        request = smart_branch.SmartServerBranchRequestSetConfigOption(
794
 
            branch.bzrdir.root_transport)
 
976
            branch.controldir.root_transport)
795
977
        branch_token, repo_token = self.get_lock_tokens(branch)
796
978
        config = branch._get_config()
797
 
        result = request.execute('', branch_token, repo_token, 'bar', 'foo',
798
 
            'gam')
 
979
        result = request.execute(b'', branch_token, repo_token, b'bar', b'foo',
 
980
            b'gam')
799
981
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(()), result)
800
982
        self.assertEqual('bar', config.get_option('foo', 'gam'))
801
983
        # Cleanup
802
984
        branch.unlock()
803
985
 
804
986
 
 
987
class TestSmartServerBranchRequestSetConfigOptionDict(TestLockedBranch):
 
988
 
 
989
    def setUp(self):
 
990
        TestLockedBranch.setUp(self)
 
991
        # A dict with non-ascii keys and values to exercise unicode
 
992
        # roundtripping.
 
993
        self.encoded_value_dict = (
 
994
            'd5:ascii1:a11:unicode \xe2\x8c\x9a3:\xe2\x80\xbde')
 
995
        self.value_dict = {
 
996
            'ascii': 'a', u'unicode \N{WATCH}': u'\N{INTERROBANG}'}
 
997
 
 
998
    def test_value_name(self):
 
999
        branch = self.make_branch('.')
 
1000
        request = smart_branch.SmartServerBranchRequestSetConfigOptionDict(
 
1001
            branch.controldir.root_transport)
 
1002
        branch_token, repo_token = self.get_lock_tokens(branch)
 
1003
        config = branch._get_config()
 
1004
        result = request.execute(b'', branch_token, repo_token,
 
1005
            self.encoded_value_dict, b'foo', b'')
 
1006
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(()), result)
 
1007
        self.assertEqual(self.value_dict, config.get_option('foo'))
 
1008
        # Cleanup
 
1009
        branch.unlock()
 
1010
 
 
1011
    def test_value_name_section(self):
 
1012
        branch = self.make_branch('.')
 
1013
        request = smart_branch.SmartServerBranchRequestSetConfigOptionDict(
 
1014
            branch.controldir.root_transport)
 
1015
        branch_token, repo_token = self.get_lock_tokens(branch)
 
1016
        config = branch._get_config()
 
1017
        result = request.execute(b'', branch_token, repo_token,
 
1018
            self.encoded_value_dict, b'foo', b'gam')
 
1019
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(()), result)
 
1020
        self.assertEqual(self.value_dict, config.get_option('foo', 'gam'))
 
1021
        # Cleanup
 
1022
        branch.unlock()
 
1023
 
 
1024
 
805
1025
class TestSmartServerBranchRequestSetTagsBytes(TestLockedBranch):
806
1026
    # Only called when the branch format and tags match [yay factory
807
1027
    # methods] so only need to test straight forward cases.
813
1033
        branch_token, repo_token = self.get_lock_tokens(base_branch)
814
1034
        request = smart_branch.SmartServerBranchSetTagsBytes(
815
1035
            self.get_transport())
816
 
        response = request.execute('base', branch_token, repo_token)
 
1036
        response = request.execute(b'base', branch_token, repo_token)
817
1037
        self.assertEqual(None, response)
818
1038
        response = request.do_chunk(tag_bytes)
819
1039
        self.assertEqual(None, response)
820
1040
        response = request.do_end()
821
 
        self.assertEquals(
 
1041
        self.assertEqual(
822
1042
            smart_req.SuccessfulSmartServerResponse(()), response)
823
1043
        base_branch.unlock()
824
1044
 
843
1063
    """Base test case for verbs that implement set_last_revision."""
844
1064
 
845
1065
    def setUp(self):
846
 
        tests.TestCaseWithMemoryTransport.setUp(self)
 
1066
        super(SetLastRevisionTestBase, self).setUp()
847
1067
        backing_transport = self.get_transport()
848
1068
        self.request = self.request_class(backing_transport)
849
1069
        self.tree = self.make_branch_and_memory_tree('.')
863
1083
 
864
1084
    def assertRequestSucceeds(self, revision_id, revno):
865
1085
        response = self.set_last_revision(revision_id, revno)
866
 
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(('ok',)),
 
1086
        self.assertEqual(smart_req.SuccessfulSmartServerResponse((b'ok',)),
867
1087
                         response)
868
1088
 
869
1089
 
878
1098
        """If the revision_id is not present, the verb returns NoSuchRevision.
879
1099
        """
880
1100
        revision_id = 'non-existent revision'
881
 
        self.assertEqual(smart_req.FailedSmartServerResponse(('NoSuchRevision',
 
1101
        self.assertEqual(smart_req.FailedSmartServerResponse((b'NoSuchRevision',
882
1102
                                                              revision_id)),
883
1103
                         self.set_last_revision(revision_id, 1))
884
1104
 
887
1107
        self.tree.add('')
888
1108
        rev_id_utf8 = u'\xc8'.encode('utf-8')
889
1109
        r1 = self.tree.commit('1st commit', rev_id=rev_id_utf8)
890
 
        r2 = self.tree.commit('2nd commit', rev_id='rev-2')
 
1110
        r2 = self.tree.commit('2nd commit', rev_id=b'rev-2')
891
1111
        self.tree.unlock()
892
1112
 
893
1113
    def test_branch_last_revision_info_is_updated(self):
898
1118
        # its repository.
899
1119
        self.make_tree_with_two_commits()
900
1120
        rev_id_utf8 = u'\xc8'.encode('utf-8')
901
 
        self.tree.branch.set_revision_history([])
 
1121
        self.tree.branch.set_last_revision_info(0, 'null:')
902
1122
        self.assertEqual(
903
1123
            (0, 'null:'), self.tree.branch.last_revision_info())
904
1124
        # We can update the branch to a revision that is present in the
975
1195
    def assertRequestSucceeds(self, revision_id, revno):
976
1196
        response = self.set_last_revision(revision_id, revno)
977
1197
        self.assertEqual(
978
 
            smart_req.SuccessfulSmartServerResponse(('ok', revno, revision_id)),
 
1198
            smart_req.SuccessfulSmartServerResponse((b'ok', revno, revision_id)),
979
1199
            response)
980
1200
 
981
1201
    def test_branch_last_revision_info_rewind(self):
992
1212
        response = self.request.execute(
993
1213
            '', branch_token, repo_token, rev_id_utf8, 0, 0)
994
1214
        self.assertEqual(
995
 
            smart_req.SuccessfulSmartServerResponse(('ok', 2, 'rev-2')),
 
1215
            smart_req.SuccessfulSmartServerResponse((b'ok', 2, 'rev-2')),
996
1216
            response)
997
1217
        self.assertEqual(
998
1218
            (2, 'rev-2'), self.tree.branch.last_revision_info())
1002
1222
        response = self.request.execute(
1003
1223
            '', branch_token, repo_token, rev_id_utf8, 0, 1)
1004
1224
        self.assertEqual(
1005
 
            smart_req.SuccessfulSmartServerResponse(('ok', 1, rev_id_utf8)),
 
1225
            smart_req.SuccessfulSmartServerResponse((b'ok', 1, rev_id_utf8)),
1006
1226
            response)
1007
1227
        self.unlock_branch()
1008
1228
        self.assertEqual(
1018
1238
        self.tree.add('')
1019
1239
        r1 = self.tree.commit('1st commit')
1020
1240
        revno_1, revid_1 = self.tree.branch.last_revision_info()
1021
 
        r2 = self.tree.commit('2nd commit', rev_id='child-1')
 
1241
        r2 = self.tree.commit('2nd commit', rev_id=b'child-1')
1022
1242
        # Undo the second commit
1023
1243
        self.tree.branch.set_last_revision_info(revno_1, revid_1)
1024
1244
        self.tree.set_parent_ids([revid_1])
1025
1245
        # Make a new second commit, child-2.  child-2 has diverged from
1026
1246
        # child-1.
1027
 
        new_r2 = self.tree.commit('2nd commit', rev_id='child-2')
 
1247
        new_r2 = self.tree.commit('2nd commit', rev_id=b'child-2')
1028
1248
        self.tree.unlock()
1029
1249
 
1030
1250
    def test_not_allow_diverged(self):
1033
1253
        """
1034
1254
        self.make_branch_with_divergent_history()
1035
1255
        self.assertEqual(
1036
 
            smart_req.FailedSmartServerResponse(('Diverged',)),
 
1256
            smart_req.FailedSmartServerResponse((b'Diverged',)),
1037
1257
            self.set_last_revision('child-1', 2))
1038
1258
        # The branch tip was not changed.
1039
1259
        self.assertEqual('child-2', self.tree.branch.last_revision())
1047
1267
        response = self.request.execute(
1048
1268
            '', branch_token, repo_token, 'child-1', 1, 0)
1049
1269
        self.assertEqual(
1050
 
            smart_req.SuccessfulSmartServerResponse(('ok', 2, 'child-1')),
 
1270
            smart_req.SuccessfulSmartServerResponse((b'ok', 2, 'child-1')),
1051
1271
            response)
1052
1272
        self.unlock_branch()
1053
1273
        # The branch tip was changed.
1054
1274
        self.assertEqual('child-1', self.tree.branch.last_revision())
1055
1275
 
1056
1276
 
 
1277
class TestSmartServerBranchBreakLock(tests.TestCaseWithMemoryTransport):
 
1278
 
 
1279
    def test_lock_to_break(self):
 
1280
        base_branch = self.make_branch('base')
 
1281
        request = smart_branch.SmartServerBranchBreakLock(
 
1282
            self.get_transport())
 
1283
        base_branch.lock_write()
 
1284
        self.assertEqual(
 
1285
            smart_req.SuccessfulSmartServerResponse((b'ok', ), None),
 
1286
            request.execute(b'base'))
 
1287
 
 
1288
    def test_nothing_to_break(self):
 
1289
        base_branch = self.make_branch('base')
 
1290
        request = smart_branch.SmartServerBranchBreakLock(
 
1291
            self.get_transport())
 
1292
        self.assertEqual(
 
1293
            smart_req.SuccessfulSmartServerResponse((b'ok', ), None),
 
1294
            request.execute(b'base'))
 
1295
 
 
1296
 
1057
1297
class TestSmartServerBranchRequestGetParent(tests.TestCaseWithMemoryTransport):
1058
1298
 
1059
1299
    def test_get_parent_none(self):
1060
1300
        base_branch = self.make_branch('base')
1061
1301
        request = smart_branch.SmartServerBranchGetParent(self.get_transport())
1062
 
        response = request.execute('base')
1063
 
        self.assertEquals(
1064
 
            smart_req.SuccessfulSmartServerResponse(('',)), response)
 
1302
        response = request.execute(b'base')
 
1303
        self.assertEqual(
 
1304
            smart_req.SuccessfulSmartServerResponse((b'',)), response)
1065
1305
 
1066
1306
    def test_get_parent_something(self):
1067
1307
        base_branch = self.make_branch('base')
1068
1308
        base_branch.set_parent(self.get_url('foo'))
1069
1309
        request = smart_branch.SmartServerBranchGetParent(self.get_transport())
1070
 
        response = request.execute('base')
1071
 
        self.assertEquals(
1072
 
            smart_req.SuccessfulSmartServerResponse(("../foo",)),
 
1310
        response = request.execute(b'base')
 
1311
        self.assertEqual(
 
1312
            smart_req.SuccessfulSmartServerResponse((b"../foo",)),
1073
1313
            response)
1074
1314
 
1075
1315
 
1084
1324
            self.get_transport())
1085
1325
        branch_token, repo_token = self.get_lock_tokens(branch)
1086
1326
        try:
1087
 
            response = request.execute('base', branch_token, repo_token, '')
 
1327
            response = request.execute(b'base', branch_token, repo_token, b'')
1088
1328
        finally:
1089
1329
            branch.unlock()
1090
1330
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(()), response)
 
1331
        # Refresh branch as SetParentLocation modified it
 
1332
        branch = branch.controldir.open_branch()
1091
1333
        self.assertEqual(None, branch.get_parent())
1092
1334
 
1093
1335
    def test_set_parent_something(self):
1096
1338
            self.get_transport())
1097
1339
        branch_token, repo_token = self.get_lock_tokens(branch)
1098
1340
        try:
1099
 
            response = request.execute('base', branch_token, repo_token,
1100
 
            'http://bar/')
 
1341
            response = request.execute(b'base', branch_token, repo_token,
 
1342
                                       b'http://bar/')
1101
1343
        finally:
1102
1344
            branch.unlock()
1103
1345
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(()), response)
1104
 
        self.assertEqual('http://bar/', branch.get_parent())
 
1346
        refreshed = _mod_branch.Branch.open(branch.base)
 
1347
        self.assertEqual('http://bar/', refreshed.get_parent())
1105
1348
 
1106
1349
 
1107
1350
class TestSmartServerBranchRequestGetTagsBytes(
1113
1356
        base_branch = self.make_branch('base')
1114
1357
        request = smart_branch.SmartServerBranchGetTagsBytes(
1115
1358
            self.get_transport())
1116
 
        response = request.execute('base')
1117
 
        self.assertEquals(
1118
 
            smart_req.SuccessfulSmartServerResponse(('',)), response)
 
1359
        response = request.execute(b'base')
 
1360
        self.assertEqual(
 
1361
            smart_req.SuccessfulSmartServerResponse((b'',)), response)
1119
1362
 
1120
1363
 
1121
1364
class TestSmartServerBranchRequestGetStackedOnURL(tests.TestCaseWithMemoryTransport):
1127
1370
        stacked_branch.set_stacked_on_url('../base')
1128
1371
        request = smart_branch.SmartServerBranchRequestGetStackedOnURL(
1129
1372
            self.get_transport())
1130
 
        response = request.execute('stacked')
1131
 
        self.assertEquals(
1132
 
            smart_req.SmartServerResponse(('ok', '../base')),
 
1373
        response = request.execute(b'stacked')
 
1374
        self.assertEqual(
 
1375
            smart_req.SmartServerResponse((b'ok', b'../base')),
1133
1376
            response)
1134
1377
 
1135
1378
 
1136
1379
class TestSmartServerBranchRequestLockWrite(TestLockedBranch):
1137
1380
 
1138
 
    def setUp(self):
1139
 
        tests.TestCaseWithMemoryTransport.setUp(self)
1140
 
 
1141
1381
    def test_lock_write_on_unlocked_branch(self):
1142
1382
        backing = self.get_transport()
1143
1383
        request = smart_branch.SmartServerBranchRequestLockWrite(backing)
1144
1384
        branch = self.make_branch('.', format='knit')
1145
1385
        repository = branch.repository
1146
 
        response = request.execute('')
 
1386
        response = request.execute(b'')
1147
1387
        branch_nonce = branch.control_files._lock.peek().get('nonce')
1148
1388
        repository_nonce = repository.control_files._lock.peek().get('nonce')
1149
1389
        self.assertEqual(smart_req.SmartServerResponse(
1150
 
                ('ok', branch_nonce, repository_nonce)),
 
1390
                (b'ok', branch_nonce, repository_nonce)),
1151
1391
                         response)
1152
1392
        # The branch (and associated repository) is now locked.  Verify that
1153
1393
        # with a new branch object.
1154
 
        new_branch = repository.bzrdir.open_branch()
 
1394
        new_branch = repository.controldir.open_branch()
1155
1395
        self.assertRaises(errors.LockContention, new_branch.lock_write)
1156
1396
        # Cleanup
1157
1397
        request = smart_branch.SmartServerBranchRequestUnlock(backing)
1158
 
        response = request.execute('', branch_nonce, repository_nonce)
 
1398
        response = request.execute(b'', branch_nonce, repository_nonce)
1159
1399
 
1160
1400
    def test_lock_write_on_locked_branch(self):
1161
1401
        backing = self.get_transport()
1162
1402
        request = smart_branch.SmartServerBranchRequestLockWrite(backing)
1163
1403
        branch = self.make_branch('.')
1164
 
        branch_token = branch.lock_write().branch_token
 
1404
        branch_token = branch.lock_write().token
1165
1405
        branch.leave_lock_in_place()
1166
1406
        branch.unlock()
1167
 
        response = request.execute('')
 
1407
        response = request.execute(b'')
1168
1408
        self.assertEqual(
1169
 
            smart_req.SmartServerResponse(('LockContention',)), response)
 
1409
            smart_req.SmartServerResponse((b'LockContention',)), response)
1170
1410
        # Cleanup
1171
1411
        branch.lock_write(branch_token)
1172
1412
        branch.dont_leave_lock_in_place()
1180
1420
        branch.leave_lock_in_place()
1181
1421
        branch.repository.leave_lock_in_place()
1182
1422
        branch.unlock()
1183
 
        response = request.execute('',
 
1423
        response = request.execute(b'',
1184
1424
                                   branch_token, repo_token)
1185
1425
        self.assertEqual(
1186
 
            smart_req.SmartServerResponse(('ok', branch_token, repo_token)),
 
1426
            smart_req.SmartServerResponse((b'ok', branch_token, repo_token)),
1187
1427
            response)
1188
1428
        # Cleanup
1189
1429
        branch.repository.lock_write(repo_token)
1201
1441
        branch.leave_lock_in_place()
1202
1442
        branch.repository.leave_lock_in_place()
1203
1443
        branch.unlock()
1204
 
        response = request.execute('',
1205
 
                                   branch_token+'xxx', repo_token)
 
1444
        response = request.execute(b'',
 
1445
                                   branch_token+b'xxx', repo_token)
1206
1446
        self.assertEqual(
1207
 
            smart_req.SmartServerResponse(('TokenMismatch',)), response)
 
1447
            smart_req.SmartServerResponse((b'TokenMismatch',)), response)
1208
1448
        # Cleanup
1209
1449
        branch.repository.lock_write(repo_token)
1210
1450
        branch.repository.dont_leave_lock_in_place()
1221
1461
        repo_token = repo.lock_write().repository_token
1222
1462
        repo.leave_lock_in_place()
1223
1463
        repo.unlock()
1224
 
        response = request.execute('')
 
1464
        response = request.execute(b'')
1225
1465
        self.assertEqual(
1226
 
            smart_req.SmartServerResponse(('LockContention',)), response)
 
1466
            smart_req.SmartServerResponse((b'LockContention',)), response)
1227
1467
        # Cleanup
1228
1468
        repo.lock_write(repo_token)
1229
1469
        repo.dont_leave_lock_in_place()
1241
1481
        self.assertEqual('LockFailed', error_name)
1242
1482
 
1243
1483
 
 
1484
class TestSmartServerBranchRequestGetPhysicalLockStatus(TestLockedBranch):
 
1485
 
 
1486
    def test_true(self):
 
1487
        backing = self.get_transport()
 
1488
        request = smart_branch.SmartServerBranchRequestGetPhysicalLockStatus(
 
1489
            backing)
 
1490
        branch = self.make_branch('.')
 
1491
        branch_token, repo_token = self.get_lock_tokens(branch)
 
1492
        self.assertEqual(True, branch.get_physical_lock_status())
 
1493
        response = request.execute(b'')
 
1494
        self.assertEqual(
 
1495
            smart_req.SmartServerResponse((b'yes',)), response)
 
1496
        branch.unlock()
 
1497
 
 
1498
    def test_false(self):
 
1499
        backing = self.get_transport()
 
1500
        request = smart_branch.SmartServerBranchRequestGetPhysicalLockStatus(
 
1501
            backing)
 
1502
        branch = self.make_branch('.')
 
1503
        self.assertEqual(False, branch.get_physical_lock_status())
 
1504
        response = request.execute(b'')
 
1505
        self.assertEqual(
 
1506
            smart_req.SmartServerResponse((b'no',)), response)
 
1507
 
 
1508
 
1244
1509
class TestSmartServerBranchRequestUnlock(TestLockedBranch):
1245
1510
 
1246
 
    def setUp(self):
1247
 
        tests.TestCaseWithMemoryTransport.setUp(self)
1248
 
 
1249
1511
    def test_unlock_on_locked_branch_and_repo(self):
1250
1512
        backing = self.get_transport()
1251
1513
        request = smart_branch.SmartServerBranchRequestUnlock(backing)
1257
1519
        branch.leave_lock_in_place()
1258
1520
        branch.repository.leave_lock_in_place()
1259
1521
        branch.unlock()
1260
 
        response = request.execute('',
 
1522
        response = request.execute(b'',
1261
1523
                                   branch_token, repo_token)
1262
1524
        self.assertEqual(
1263
 
            smart_req.SmartServerResponse(('ok',)), response)
 
1525
            smart_req.SmartServerResponse((b'ok',)), response)
1264
1526
        # The branch is now unlocked.  Verify that with a new branch
1265
1527
        # object.
1266
 
        new_branch = branch.bzrdir.open_branch()
 
1528
        new_branch = branch.controldir.open_branch()
1267
1529
        new_branch.lock_write()
1268
1530
        new_branch.unlock()
1269
1531
 
1274
1536
        response = request.execute(
1275
1537
            '', 'branch token', 'repo token')
1276
1538
        self.assertEqual(
1277
 
            smart_req.SmartServerResponse(('TokenMismatch',)), response)
 
1539
            smart_req.SmartServerResponse((b'TokenMismatch',)), response)
1278
1540
 
1279
1541
    def test_unlock_on_unlocked_branch_locked_repo(self):
1280
1542
        backing = self.get_transport()
1286
1548
        branch.repository.unlock()
1287
1549
        # Issue branch lock_write request on the unlocked branch (with locked
1288
1550
        # repo).
1289
 
        response = request.execute('', 'branch token', repo_token)
 
1551
        response = request.execute(b'', 'branch token', repo_token)
1290
1552
        self.assertEqual(
1291
 
            smart_req.SmartServerResponse(('TokenMismatch',)), response)
 
1553
            smart_req.SmartServerResponse((b'TokenMismatch',)), response)
1292
1554
        # Cleanup
1293
1555
        branch.repository.lock_write(repo_token)
1294
1556
        branch.repository.dont_leave_lock_in_place()
1306
1568
        backing = self.get_transport()
1307
1569
        request = smart_repo.SmartServerRepositoryRequest(backing)
1308
1570
        self.make_repository('.', shared=True)
1309
 
        self.make_bzrdir('subdir')
 
1571
        self.make_controldir('subdir')
1310
1572
        self.assertRaises(errors.NoRepositoryPresent,
1311
1573
            request.execute, 'subdir')
1312
1574
 
1313
1575
 
 
1576
class TestSmartServerRepositoryAddSignatureText(tests.TestCaseWithMemoryTransport):
 
1577
 
 
1578
    def test_add_text(self):
 
1579
        backing = self.get_transport()
 
1580
        request = smart_repo.SmartServerRepositoryAddSignatureText(backing)
 
1581
        tree = self.make_branch_and_memory_tree('.')
 
1582
        write_token = tree.lock_write()
 
1583
        self.addCleanup(tree.unlock)
 
1584
        tree.add('')
 
1585
        tree.commit("Message", rev_id=b'rev1')
 
1586
        tree.branch.repository.start_write_group()
 
1587
        write_group_tokens = tree.branch.repository.suspend_write_group()
 
1588
        self.assertEqual(None, request.execute(b'', write_token,
 
1589
            b'rev1', *write_group_tokens))
 
1590
        response = request.do_body('somesignature')
 
1591
        self.assertTrue(response.is_successful())
 
1592
        self.assertEqual(response.args[0], 'ok')
 
1593
        write_group_tokens = response.args[1:]
 
1594
        tree.branch.repository.resume_write_group(write_group_tokens)
 
1595
        tree.branch.repository.commit_write_group()
 
1596
        tree.unlock()
 
1597
        self.assertEqual("somesignature",
 
1598
            tree.branch.repository.get_signature_text("rev1"))
 
1599
 
 
1600
 
 
1601
class TestSmartServerRepositoryAllRevisionIds(
 
1602
    tests.TestCaseWithMemoryTransport):
 
1603
 
 
1604
    def test_empty(self):
 
1605
        """An empty body should be returned for an empty repository."""
 
1606
        backing = self.get_transport()
 
1607
        request = smart_repo.SmartServerRepositoryAllRevisionIds(backing)
 
1608
        self.make_repository('.')
 
1609
        self.assertEqual(
 
1610
            smart_req.SuccessfulSmartServerResponse((b"ok", ), b""),
 
1611
            request.execute(b''))
 
1612
 
 
1613
    def test_some_revisions(self):
 
1614
        """An empty body should be returned for an empty repository."""
 
1615
        backing = self.get_transport()
 
1616
        request = smart_repo.SmartServerRepositoryAllRevisionIds(backing)
 
1617
        tree = self.make_branch_and_memory_tree('.')
 
1618
        tree.lock_write()
 
1619
        tree.add('')
 
1620
        tree.commit(rev_id=b'origineel', message="message")
 
1621
        tree.commit(rev_id=b'nog-een-revisie', message="message")
 
1622
        tree.unlock()
 
1623
        self.assertEqual(
 
1624
            smart_req.SuccessfulSmartServerResponse((b"ok", ),
 
1625
                b"origineel\nnog-een-revisie"),
 
1626
            request.execute(b''))
 
1627
 
 
1628
 
 
1629
class TestSmartServerRepositoryBreakLock(tests.TestCaseWithMemoryTransport):
 
1630
 
 
1631
    def test_lock_to_break(self):
 
1632
        backing = self.get_transport()
 
1633
        request = smart_repo.SmartServerRepositoryBreakLock(backing)
 
1634
        tree = self.make_branch_and_memory_tree('.')
 
1635
        tree.branch.repository.lock_write()
 
1636
        self.assertEqual(
 
1637
            smart_req.SuccessfulSmartServerResponse((b'ok', ), None),
 
1638
            request.execute(b''))
 
1639
 
 
1640
    def test_nothing_to_break(self):
 
1641
        backing = self.get_transport()
 
1642
        request = smart_repo.SmartServerRepositoryBreakLock(backing)
 
1643
        tree = self.make_branch_and_memory_tree('.')
 
1644
        self.assertEqual(
 
1645
            smart_req.SuccessfulSmartServerResponse((b'ok', ), None),
 
1646
            request.execute(b''))
 
1647
 
 
1648
 
1314
1649
class TestSmartServerRepositoryGetParentMap(tests.TestCaseWithMemoryTransport):
1315
1650
 
1316
1651
    def test_trivial_bzipped(self):
1320
1655
        tree = self.make_branch_and_memory_tree('.')
1321
1656
 
1322
1657
        self.assertEqual(None,
1323
 
            request.execute('', 'missing-id'))
 
1658
            request.execute(b'', b'missing-id'))
1324
1659
        # Note that it returns a body that is bzipped.
1325
1660
        self.assertEqual(
1326
 
            smart_req.SuccessfulSmartServerResponse(('ok', ), bz2.compress('')),
 
1661
            smart_req.SuccessfulSmartServerResponse((b'ok', ), bz2.compress(b'')),
1327
1662
            request.do_body('\n\n0\n'))
1328
1663
 
1329
1664
    def test_trivial_include_missing(self):
1332
1667
        tree = self.make_branch_and_memory_tree('.')
1333
1668
 
1334
1669
        self.assertEqual(None,
1335
 
            request.execute('', 'missing-id', 'include-missing:'))
 
1670
            request.execute(b'', b'missing-id', b'include-missing:'))
1336
1671
        self.assertEqual(
1337
 
            smart_req.SuccessfulSmartServerResponse(('ok', ),
1338
 
                bz2.compress('missing:missing-id')),
1339
 
            request.do_body('\n\n0\n'))
 
1672
            smart_req.SuccessfulSmartServerResponse((b'ok', ),
 
1673
                bz2.compress(b'missing:missing-id')),
 
1674
            request.do_body(b'\n\n0\n'))
1340
1675
 
1341
1676
 
1342
1677
class TestSmartServerRepositoryGetRevisionGraph(
1354
1689
 
1355
1690
        # the lines of revision_id->revision_parent_list has no guaranteed
1356
1691
        # order coming out of a dict, so sort both our test and response
1357
 
        lines = sorted([' '.join([r2, r1]), r1])
1358
 
        response = request.execute('', '')
 
1692
        lines = sorted([b' '.join([r2, r1]), r1])
 
1693
        response = request.execute(b'', b'')
1359
1694
        response.body = '\n'.join(sorted(response.body.split('\n')))
1360
1695
 
1361
1696
        self.assertEqual(
1362
 
            smart_req.SmartServerResponse(('ok', ), '\n'.join(lines)), response)
 
1697
            smart_req.SmartServerResponse((b'ok', ), b'\n'.join(lines)), response)
1363
1698
 
1364
1699
    def test_specific_revision_argument(self):
1365
1700
        backing = self.get_transport()
1372
1707
        r2 = tree.commit('2nd commit', rev_id=u'\xc8'.encode('utf-8'))
1373
1708
        tree.unlock()
1374
1709
 
1375
 
        self.assertEqual(smart_req.SmartServerResponse(('ok', ), rev_id_utf8),
1376
 
            request.execute('', rev_id_utf8))
 
1710
        self.assertEqual(smart_req.SmartServerResponse((b'ok', ), rev_id_utf8),
 
1711
            request.execute(b'', rev_id_utf8))
1377
1712
 
1378
1713
    def test_no_such_revision(self):
1379
1714
        backing = self.get_transport()
1386
1721
 
1387
1722
        # Note that it still returns body (of zero bytes).
1388
1723
        self.assertEqual(smart_req.SmartServerResponse(
1389
 
                ('nosuchrevision', 'missingrevision', ), ''),
1390
 
                         request.execute('', 'missingrevision'))
 
1724
                (b'nosuchrevision', b'missingrevision', ), b''),
 
1725
                         request.execute(b'', b'missingrevision'))
1391
1726
 
1392
1727
 
1393
1728
class TestSmartServerRepositoryGetRevIdForRevno(
1405
1740
        tree.commit('2nd commit', rev_id=rev2_id_utf8)
1406
1741
        tree.unlock()
1407
1742
 
1408
 
        self.assertEqual(smart_req.SmartServerResponse(('ok', rev1_id_utf8)),
1409
 
            request.execute('', 1, (2, rev2_id_utf8)))
 
1743
        self.assertEqual(smart_req.SmartServerResponse((b'ok', rev1_id_utf8)),
 
1744
            request.execute(b'', 1, (2, rev2_id_utf8)))
1410
1745
 
1411
1746
    def test_known_revid_missing(self):
1412
1747
        backing = self.get_transport()
1413
1748
        request = smart_repo.SmartServerRepositoryGetRevIdForRevno(backing)
1414
1749
        repo = self.make_repository('.')
1415
1750
        self.assertEqual(
1416
 
            smart_req.FailedSmartServerResponse(('nosuchrevision', 'ghost')),
1417
 
            request.execute('', 1, (2, 'ghost')))
 
1751
            smart_req.FailedSmartServerResponse((b'nosuchrevision', b'ghost')),
 
1752
            request.execute(b'', 1, (2, b'ghost')))
1418
1753
 
1419
1754
    def test_history_incomplete(self):
1420
1755
        backing = self.get_transport()
1432
1767
        local.branch.create_clone_on_transport(
1433
1768
            self.get_transport('stacked'), stacked_on=self.get_url('parent'))
1434
1769
        self.assertEqual(
1435
 
            smart_req.SmartServerResponse(('history-incomplete', 2, r2)),
1436
 
            request.execute('stacked', 1, (3, r3)))
1437
 
 
1438
 
 
1439
 
class TestSmartServerRepositoryGetStream(tests.TestCaseWithMemoryTransport):
 
1770
            smart_req.SmartServerResponse((b'history-incomplete', 2, r2)),
 
1771
            request.execute(b'stacked', 1, (3, r3)))
 
1772
 
 
1773
 
 
1774
class TestSmartServerRepositoryIterRevisions(
 
1775
    tests.TestCaseWithMemoryTransport):
 
1776
 
 
1777
    def test_basic(self):
 
1778
        backing = self.get_transport()
 
1779
        request = smart_repo.SmartServerRepositoryIterRevisions(backing)
 
1780
        tree = self.make_branch_and_memory_tree('.', format='2a')
 
1781
        tree.lock_write()
 
1782
        tree.add('')
 
1783
        tree.commit('1st commit', rev_id="rev1")
 
1784
        tree.commit('2nd commit', rev_id="rev2")
 
1785
        tree.unlock()
 
1786
 
 
1787
        self.assertIs(None, request.execute(b''))
 
1788
        response = request.do_body("rev1\nrev2")
 
1789
        self.assertTrue(response.is_successful())
 
1790
        # Format 2a uses serializer format 10
 
1791
        self.assertEqual(response.args, (b"ok", b"10"))
 
1792
 
 
1793
        self.addCleanup(tree.branch.lock_read().unlock)
 
1794
        entries = [zlib.compress(record.get_bytes_as("fulltext")) for record in
 
1795
            tree.branch.repository.revisions.get_record_stream(
 
1796
            [(b"rev1", ), (b"rev2", )], "unordered", True)]
 
1797
 
 
1798
        contents = b"".join(response.body_stream)
 
1799
        self.assertTrue(contents in (
 
1800
            "".join([entries[0], entries[1]]),
 
1801
            "".join([entries[1], entries[0]])))
 
1802
 
 
1803
    def test_missing(self):
 
1804
        backing = self.get_transport()
 
1805
        request = smart_repo.SmartServerRepositoryIterRevisions(backing)
 
1806
        tree = self.make_branch_and_memory_tree('.', format='2a')
 
1807
 
 
1808
        self.assertIs(None, request.execute(b''))
 
1809
        response = request.do_body(b"rev1\nrev2")
 
1810
        self.assertTrue(response.is_successful())
 
1811
        # Format 2a uses serializer format 10
 
1812
        self.assertEqual(response.args, (b"ok", b"10"))
 
1813
 
 
1814
        contents = b"".join(response.body_stream)
 
1815
        self.assertEqual(contents, b"")
 
1816
 
 
1817
 
 
1818
class GetStreamTestBase(tests.TestCaseWithMemoryTransport):
1440
1819
 
1441
1820
    def make_two_commit_repo(self):
1442
1821
        tree = self.make_branch_and_memory_tree('.')
1448
1827
        repo = tree.branch.repository
1449
1828
        return repo, r1, r2
1450
1829
 
 
1830
 
 
1831
class TestSmartServerRepositoryGetStream(GetStreamTestBase):
 
1832
 
1451
1833
    def test_ancestry_of(self):
1452
1834
        """The search argument may be a 'ancestry-of' some heads'."""
1453
1835
        backing = self.get_transport()
1454
1836
        request = smart_repo.SmartServerRepositoryGetStream(backing)
1455
1837
        repo, r1, r2 = self.make_two_commit_repo()
1456
 
        fetch_spec = ['ancestry-of', r2]
1457
 
        lines = '\n'.join(fetch_spec)
1458
 
        request.execute('', repo._format.network_name())
 
1838
        fetch_spec = [b'ancestry-of', r2]
 
1839
        lines = b'\n'.join(fetch_spec)
 
1840
        request.execute(b'', repo._format.network_name())
1459
1841
        response = request.do_body(lines)
1460
 
        self.assertEqual(('ok',), response.args)
1461
 
        stream_bytes = ''.join(response.body_stream)
1462
 
        self.assertStartsWith(stream_bytes, 'Bazaar pack format 1')
 
1842
        self.assertEqual((b'ok',), response.args)
 
1843
        stream_bytes = b''.join(response.body_stream)
 
1844
        self.assertStartsWith(stream_bytes, b'Bazaar pack format 1')
1463
1845
 
1464
1846
    def test_search(self):
1465
1847
        """The search argument may be a 'search' of some explicit keys."""
1466
1848
        backing = self.get_transport()
1467
1849
        request = smart_repo.SmartServerRepositoryGetStream(backing)
1468
1850
        repo, r1, r2 = self.make_two_commit_repo()
1469
 
        fetch_spec = ['search', '%s %s' % (r1, r2), 'null:', '2']
1470
 
        lines = '\n'.join(fetch_spec)
1471
 
        request.execute('', repo._format.network_name())
 
1851
        fetch_spec = [b'search', r1 + b' ' + r2, b'null:', b'2']
 
1852
        lines = b'\n'.join(fetch_spec)
 
1853
        request.execute(b'', repo._format.network_name())
1472
1854
        response = request.do_body(lines)
1473
 
        self.assertEqual(('ok',), response.args)
1474
 
        stream_bytes = ''.join(response.body_stream)
1475
 
        self.assertStartsWith(stream_bytes, 'Bazaar pack format 1')
 
1855
        self.assertEqual((b'ok',), response.args)
 
1856
        stream_bytes = b''.join(response.body_stream)
 
1857
        self.assertStartsWith(stream_bytes, b'Bazaar pack format 1')
 
1858
 
 
1859
    def test_search_everything(self):
 
1860
        """A search of 'everything' returns a stream."""
 
1861
        backing = self.get_transport()
 
1862
        request = smart_repo.SmartServerRepositoryGetStream_1_19(backing)
 
1863
        repo, r1, r2 = self.make_two_commit_repo()
 
1864
        serialised_fetch_spec = b'everything'
 
1865
        request.execute(b'', repo._format.network_name())
 
1866
        response = request.do_body(serialised_fetch_spec)
 
1867
        self.assertEqual((b'ok',), response.args)
 
1868
        stream_bytes = b''.join(response.body_stream)
 
1869
        self.assertStartsWith(stream_bytes, b'Bazaar pack format 1')
1476
1870
 
1477
1871
 
1478
1872
class TestSmartServerRequestHasRevision(tests.TestCaseWithMemoryTransport):
1482
1876
        backing = self.get_transport()
1483
1877
        request = smart_repo.SmartServerRequestHasRevision(backing)
1484
1878
        self.make_repository('.')
1485
 
        self.assertEqual(smart_req.SmartServerResponse(('no', )),
1486
 
            request.execute('', 'revid'))
 
1879
        self.assertEqual(smart_req.SmartServerResponse((b'no', )),
 
1880
            request.execute(b'', b'revid'))
1487
1881
 
1488
1882
    def test_present_revision(self):
1489
1883
        """For a present revision, ('yes', ) is returned."""
1496
1890
        r1 = tree.commit('a commit', rev_id=rev_id_utf8)
1497
1891
        tree.unlock()
1498
1892
        self.assertTrue(tree.branch.repository.has_revision(rev_id_utf8))
1499
 
        self.assertEqual(smart_req.SmartServerResponse(('yes', )),
1500
 
            request.execute('', rev_id_utf8))
 
1893
        self.assertEqual(smart_req.SmartServerResponse((b'yes', )),
 
1894
            request.execute(b'', rev_id_utf8))
 
1895
 
 
1896
 
 
1897
class TestSmartServerRepositoryIterFilesBytes(tests.TestCaseWithTransport):
 
1898
 
 
1899
    def test_single(self):
 
1900
        backing = self.get_transport()
 
1901
        request = smart_repo.SmartServerRepositoryIterFilesBytes(backing)
 
1902
        t = self.make_branch_and_tree('.')
 
1903
        self.addCleanup(t.lock_write().unlock)
 
1904
        self.build_tree_contents([("file", b"somecontents")])
 
1905
        t.add(["file"], [b"thefileid"])
 
1906
        t.commit(rev_id=b'somerev', message="add file")
 
1907
        self.assertIs(None, request.execute(b''))
 
1908
        response = request.do_body(b"thefileid\0somerev\n")
 
1909
        self.assertTrue(response.is_successful())
 
1910
        self.assertEqual(response.args, (b"ok", ))
 
1911
        self.assertEqual(b"".join(response.body_stream),
 
1912
            b"ok\x000\n" + zlib.compress(b"somecontents"))
 
1913
 
 
1914
    def test_missing(self):
 
1915
        backing = self.get_transport()
 
1916
        request = smart_repo.SmartServerRepositoryIterFilesBytes(backing)
 
1917
        t = self.make_branch_and_tree('.')
 
1918
        self.addCleanup(t.lock_write().unlock)
 
1919
        self.assertIs(None, request.execute(b''))
 
1920
        response = request.do_body(b"thefileid\0revision\n")
 
1921
        self.assertTrue(response.is_successful())
 
1922
        self.assertEqual(response.args, (b"ok", ))
 
1923
        self.assertEqual(b"".join(response.body_stream),
 
1924
            b"absent\x00thefileid\x00revision\x000\n")
 
1925
 
 
1926
 
 
1927
class TestSmartServerRequestHasSignatureForRevisionId(
 
1928
        tests.TestCaseWithMemoryTransport):
 
1929
 
 
1930
    def test_missing_revision(self):
 
1931
        """For a missing revision, NoSuchRevision is returned."""
 
1932
        backing = self.get_transport()
 
1933
        request = smart_repo.SmartServerRequestHasSignatureForRevisionId(
 
1934
            backing)
 
1935
        self.make_repository('.')
 
1936
        self.assertEqual(
 
1937
            smart_req.FailedSmartServerResponse(
 
1938
                (b'nosuchrevision', b'revid'), None),
 
1939
            request.execute(b'', b'revid'))
 
1940
 
 
1941
    def test_missing_signature(self):
 
1942
        """For a missing signature, ('no', ) is returned."""
 
1943
        backing = self.get_transport()
 
1944
        request = smart_repo.SmartServerRequestHasSignatureForRevisionId(
 
1945
            backing)
 
1946
        tree = self.make_branch_and_memory_tree('.')
 
1947
        tree.lock_write()
 
1948
        tree.add('')
 
1949
        r1 = tree.commit('a commit', rev_id=b'A')
 
1950
        tree.unlock()
 
1951
        self.assertTrue(tree.branch.repository.has_revision('A'))
 
1952
        self.assertEqual(smart_req.SmartServerResponse((b'no', )),
 
1953
            request.execute(b'', b'A'))
 
1954
 
 
1955
    def test_present_signature(self):
 
1956
        """For a present signature, ('yes', ) is returned."""
 
1957
        backing = self.get_transport()
 
1958
        request = smart_repo.SmartServerRequestHasSignatureForRevisionId(
 
1959
            backing)
 
1960
        strategy = gpg.LoopbackGPGStrategy(None)
 
1961
        tree = self.make_branch_and_memory_tree('.')
 
1962
        tree.lock_write()
 
1963
        tree.add('')
 
1964
        r1 = tree.commit('a commit', rev_id=b'A')
 
1965
        tree.branch.repository.start_write_group()
 
1966
        tree.branch.repository.sign_revision(b'A', strategy)
 
1967
        tree.branch.repository.commit_write_group()
 
1968
        tree.unlock()
 
1969
        self.assertTrue(tree.branch.repository.has_revision(b'A'))
 
1970
        self.assertEqual(smart_req.SmartServerResponse((b'yes', )),
 
1971
            request.execute(b'', b'A'))
1501
1972
 
1502
1973
 
1503
1974
class TestSmartServerRepositoryGatherStats(tests.TestCaseWithMemoryTransport):
1508
1979
        request = smart_repo.SmartServerRepositoryGatherStats(backing)
1509
1980
        repository = self.make_repository('.')
1510
1981
        stats = repository.gather_stats()
1511
 
        expected_body = 'revisions: 0\n'
1512
 
        self.assertEqual(smart_req.SmartServerResponse(('ok', ), expected_body),
1513
 
                         request.execute('', '', 'no'))
 
1982
        expected_body = b'revisions: 0\n'
 
1983
        self.assertEqual(smart_req.SmartServerResponse((b'ok', ), expected_body),
 
1984
                         request.execute(b'', b'', b'no'))
1514
1985
 
1515
1986
    def test_revid_with_committers(self):
1516
1987
        """For a revid we get more infos."""
1527
1998
        tree.unlock()
1528
1999
 
1529
2000
        stats = tree.branch.repository.gather_stats()
1530
 
        expected_body = ('firstrev: 123456.200 3600\n'
1531
 
                         'latestrev: 654321.400 0\n'
1532
 
                         'revisions: 2\n')
1533
 
        self.assertEqual(smart_req.SmartServerResponse(('ok', ), expected_body),
1534
 
                         request.execute('',
1535
 
                                         rev_id_utf8, 'no'))
 
2001
        expected_body = (b'firstrev: 123456.200 3600\n'
 
2002
                         b'latestrev: 654321.400 0\n'
 
2003
                         b'revisions: 2\n')
 
2004
        self.assertEqual(smart_req.SmartServerResponse((b'ok', ), expected_body),
 
2005
                         request.execute(b'', rev_id_utf8, b'no'))
1536
2006
 
1537
2007
    def test_not_empty_repository_with_committers(self):
1538
2008
        """For a revid and requesting committers we get the whole thing."""
1550
2020
        tree.unlock()
1551
2021
        stats = tree.branch.repository.gather_stats()
1552
2022
 
1553
 
        expected_body = ('committers: 2\n'
1554
 
                         'firstrev: 123456.200 3600\n'
1555
 
                         'latestrev: 654321.400 0\n'
1556
 
                         'revisions: 2\n')
1557
 
        self.assertEqual(smart_req.SmartServerResponse(('ok', ), expected_body),
1558
 
                         request.execute('',
1559
 
                                         rev_id_utf8, 'yes'))
 
2023
        expected_body = (b'committers: 2\n'
 
2024
                         b'firstrev: 123456.200 3600\n'
 
2025
                         b'latestrev: 654321.400 0\n'
 
2026
                         b'revisions: 2\n')
 
2027
        self.assertEqual(smart_req.SmartServerResponse((b'ok', ), expected_body),
 
2028
                         request.execute(b'',
 
2029
                                         rev_id_utf8, b'yes'))
 
2030
 
 
2031
    def test_unknown_revid(self):
 
2032
        """An unknown revision id causes a 'nosuchrevision' error."""
 
2033
        backing = self.get_transport()
 
2034
        request = smart_repo.SmartServerRepositoryGatherStats(backing)
 
2035
        repository = self.make_repository('.')
 
2036
        expected_body = b'revisions: 0\n'
 
2037
        self.assertEqual(
 
2038
            smart_req.FailedSmartServerResponse(
 
2039
                (b'nosuchrevision', b'mia'), None),
 
2040
            request.execute(b'', b'mia', b'yes'))
1560
2041
 
1561
2042
 
1562
2043
class TestSmartServerRepositoryIsShared(tests.TestCaseWithMemoryTransport):
1566
2047
        backing = self.get_transport()
1567
2048
        request = smart_repo.SmartServerRepositoryIsShared(backing)
1568
2049
        self.make_repository('.', shared=True)
1569
 
        self.assertEqual(smart_req.SmartServerResponse(('yes', )),
1570
 
            request.execute('', ))
 
2050
        self.assertEqual(smart_req.SmartServerResponse((b'yes', )),
 
2051
            request.execute(b'', ))
1571
2052
 
1572
2053
    def test_is_not_shared(self):
1573
2054
        """For a shared repository, ('no', ) is returned."""
1574
2055
        backing = self.get_transport()
1575
2056
        request = smart_repo.SmartServerRepositoryIsShared(backing)
1576
2057
        self.make_repository('.', shared=False)
1577
 
        self.assertEqual(smart_req.SmartServerResponse(('no', )),
1578
 
            request.execute('', ))
 
2058
        self.assertEqual(smart_req.SmartServerResponse((b'no', )),
 
2059
            request.execute(b'', ))
 
2060
 
 
2061
 
 
2062
class TestSmartServerRepositoryGetRevisionSignatureText(
 
2063
        tests.TestCaseWithMemoryTransport):
 
2064
 
 
2065
    def test_get_signature(self):
 
2066
        backing = self.get_transport()
 
2067
        request = smart_repo.SmartServerRepositoryGetRevisionSignatureText(
 
2068
            backing)
 
2069
        bb = self.make_branch_builder('.')
 
2070
        bb.build_commit(rev_id=b'A')
 
2071
        repo = bb.get_branch().repository
 
2072
        strategy = gpg.LoopbackGPGStrategy(None)
 
2073
        self.addCleanup(repo.lock_write().unlock)
 
2074
        repo.start_write_group()
 
2075
        repo.sign_revision(b'A', strategy)
 
2076
        repo.commit_write_group()
 
2077
        expected_body = (
 
2078
            b'-----BEGIN PSEUDO-SIGNED CONTENT-----\n' +
 
2079
            Testament.from_revision(repo, 'A').as_short_text() +
 
2080
            b'-----END PSEUDO-SIGNED CONTENT-----\n')
 
2081
        self.assertEqual(
 
2082
            smart_req.SmartServerResponse((b'ok', ), expected_body),
 
2083
            request.execute(b'', b'A'))
 
2084
 
 
2085
 
 
2086
class TestSmartServerRepositoryMakeWorkingTrees(
 
2087
        tests.TestCaseWithMemoryTransport):
 
2088
 
 
2089
    def test_make_working_trees(self):
 
2090
        """For a repository with working trees, ('yes', ) is returned."""
 
2091
        backing = self.get_transport()
 
2092
        request = smart_repo.SmartServerRepositoryMakeWorkingTrees(backing)
 
2093
        r = self.make_repository('.')
 
2094
        r.set_make_working_trees(True)
 
2095
        self.assertEqual(smart_req.SmartServerResponse((b'yes', )),
 
2096
            request.execute(b'', ))
 
2097
 
 
2098
    def test_is_not_shared(self):
 
2099
        """For a repository with working trees, ('no', ) is returned."""
 
2100
        backing = self.get_transport()
 
2101
        request = smart_repo.SmartServerRepositoryMakeWorkingTrees(backing)
 
2102
        r = self.make_repository('.')
 
2103
        r.set_make_working_trees(False)
 
2104
        self.assertEqual(smart_req.SmartServerResponse((b'no', )),
 
2105
            request.execute(b'', ))
1579
2106
 
1580
2107
 
1581
2108
class TestSmartServerRepositoryLockWrite(tests.TestCaseWithMemoryTransport):
1584
2111
        backing = self.get_transport()
1585
2112
        request = smart_repo.SmartServerRepositoryLockWrite(backing)
1586
2113
        repository = self.make_repository('.', format='knit')
1587
 
        response = request.execute('')
 
2114
        response = request.execute(b'')
1588
2115
        nonce = repository.control_files._lock.peek().get('nonce')
1589
 
        self.assertEqual(smart_req.SmartServerResponse(('ok', nonce)), response)
 
2116
        self.assertEqual(smart_req.SmartServerResponse((b'ok', nonce)), response)
1590
2117
        # The repository is now locked.  Verify that with a new repository
1591
2118
        # object.
1592
 
        new_repo = repository.bzrdir.open_repository()
 
2119
        new_repo = repository.controldir.open_repository()
1593
2120
        self.assertRaises(errors.LockContention, new_repo.lock_write)
1594
2121
        # Cleanup
1595
2122
        request = smart_repo.SmartServerRepositoryUnlock(backing)
1596
 
        response = request.execute('', nonce)
 
2123
        response = request.execute(b'', nonce)
1597
2124
 
1598
2125
    def test_lock_write_on_locked_repo(self):
1599
2126
        backing = self.get_transport()
1602
2129
        repo_token = repository.lock_write().repository_token
1603
2130
        repository.leave_lock_in_place()
1604
2131
        repository.unlock()
1605
 
        response = request.execute('')
 
2132
        response = request.execute(b'')
1606
2133
        self.assertEqual(
1607
 
            smart_req.SmartServerResponse(('LockContention',)), response)
 
2134
            smart_req.SmartServerResponse((b'LockContention',)), response)
1608
2135
        # Cleanup
1609
2136
        repository.lock_write(repo_token)
1610
2137
        repository.dont_leave_lock_in_place()
1614
2141
        backing = self.get_readonly_transport()
1615
2142
        request = smart_repo.SmartServerRepositoryLockWrite(backing)
1616
2143
        repository = self.make_repository('.', format='knit')
1617
 
        response = request.execute('')
 
2144
        response = request.execute(b'')
1618
2145
        self.assertFalse(response.is_successful())
1619
 
        self.assertEqual('LockFailed', response.args[0])
 
2146
        self.assertEqual(b'LockFailed', response.args[0])
1620
2147
 
1621
2148
 
1622
2149
class TestInsertStreamBase(tests.TestCaseWithMemoryTransport):
1623
2150
 
1624
2151
    def make_empty_byte_stream(self, repo):
1625
2152
        byte_stream = smart_repo._stream_to_byte_stream([], repo._format)
1626
 
        return ''.join(byte_stream)
 
2153
        return b''.join(byte_stream)
1627
2154
 
1628
2155
 
1629
2156
class TestSmartServerRepositoryInsertStream(TestInsertStreamBase):
1632
2159
        backing = self.get_transport()
1633
2160
        request = smart_repo.SmartServerRepositoryInsertStream(backing)
1634
2161
        repository = self.make_repository('.')
1635
 
        response = request.execute('', '')
 
2162
        response = request.execute(b'', b'')
1636
2163
        self.assertEqual(None, response)
1637
2164
        response = request.do_chunk(self.make_empty_byte_stream(repository))
1638
2165
        self.assertEqual(None, response)
1639
2166
        response = request.do_end()
1640
 
        self.assertEqual(smart_req.SmartServerResponse(('ok', )), response)
 
2167
        self.assertEqual(smart_req.SmartServerResponse((b'ok', )), response)
1641
2168
 
1642
2169
 
1643
2170
class TestSmartServerRepositoryInsertStreamLocked(TestInsertStreamBase):
1648
2175
            backing)
1649
2176
        repository = self.make_repository('.', format='knit')
1650
2177
        lock_token = repository.lock_write().repository_token
1651
 
        response = request.execute('', '', lock_token)
 
2178
        response = request.execute(b'', b'', lock_token)
1652
2179
        self.assertEqual(None, response)
1653
2180
        response = request.do_chunk(self.make_empty_byte_stream(repository))
1654
2181
        self.assertEqual(None, response)
1655
2182
        response = request.do_end()
1656
 
        self.assertEqual(smart_req.SmartServerResponse(('ok', )), response)
 
2183
        self.assertEqual(smart_req.SmartServerResponse((b'ok', )), response)
1657
2184
        repository.unlock()
1658
2185
 
1659
2186
    def test_insert_stream_with_wrong_lock_token(self):
1663
2190
        repository = self.make_repository('.', format='knit')
1664
2191
        lock_token = repository.lock_write().repository_token
1665
2192
        self.assertRaises(
1666
 
            errors.TokenMismatch, request.execute, '', '', 'wrong-token')
 
2193
            errors.TokenMismatch, request.execute, b'', b'', b'wrong-token')
1667
2194
        repository.unlock()
1668
2195
 
1669
2196
 
1670
2197
class TestSmartServerRepositoryUnlock(tests.TestCaseWithMemoryTransport):
1671
2198
 
1672
 
    def setUp(self):
1673
 
        tests.TestCaseWithMemoryTransport.setUp(self)
1674
 
 
1675
2199
    def test_unlock_on_locked_repo(self):
1676
2200
        backing = self.get_transport()
1677
2201
        request = smart_repo.SmartServerRepositoryUnlock(backing)
1679
2203
        token = repository.lock_write().repository_token
1680
2204
        repository.leave_lock_in_place()
1681
2205
        repository.unlock()
1682
 
        response = request.execute('', token)
 
2206
        response = request.execute(b'', token)
1683
2207
        self.assertEqual(
1684
 
            smart_req.SmartServerResponse(('ok',)), response)
 
2208
            smart_req.SmartServerResponse((b'ok',)), response)
1685
2209
        # The repository is now unlocked.  Verify that with a new repository
1686
2210
        # object.
1687
 
        new_repo = repository.bzrdir.open_repository()
 
2211
        new_repo = repository.controldir.open_repository()
1688
2212
        new_repo.lock_write()
1689
2213
        new_repo.unlock()
1690
2214
 
1692
2216
        backing = self.get_transport()
1693
2217
        request = smart_repo.SmartServerRepositoryUnlock(backing)
1694
2218
        repository = self.make_repository('.', format='knit')
1695
 
        response = request.execute('', 'some token')
 
2219
        response = request.execute(b'', b'some token')
1696
2220
        self.assertEqual(
1697
 
            smart_req.SmartServerResponse(('TokenMismatch',)), response)
 
2221
            smart_req.SmartServerResponse((b'TokenMismatch',)), response)
 
2222
 
 
2223
 
 
2224
class TestSmartServerRepositoryGetPhysicalLockStatus(
 
2225
    tests.TestCaseWithTransport):
 
2226
 
 
2227
    def test_with_write_lock(self):
 
2228
        backing = self.get_transport()
 
2229
        repo = self.make_repository('.')
 
2230
        self.addCleanup(repo.lock_write().unlock)
 
2231
        # lock_write() doesn't necessarily actually take a physical
 
2232
        # lock out.
 
2233
        if repo.get_physical_lock_status():
 
2234
            expected = b'yes'
 
2235
        else:
 
2236
            expected = b'no'
 
2237
        request_class = smart_repo.SmartServerRepositoryGetPhysicalLockStatus
 
2238
        request = request_class(backing)
 
2239
        self.assertEqual(smart_req.SuccessfulSmartServerResponse((expected,)),
 
2240
            request.execute(b'', ))
 
2241
 
 
2242
    def test_without_write_lock(self):
 
2243
        backing = self.get_transport()
 
2244
        repo = self.make_repository('.')
 
2245
        self.assertEqual(False, repo.get_physical_lock_status())
 
2246
        request_class = smart_repo.SmartServerRepositoryGetPhysicalLockStatus
 
2247
        request = request_class(backing)
 
2248
        self.assertEqual(smart_req.SuccessfulSmartServerResponse((b'no',)),
 
2249
            request.execute(b'', ))
 
2250
 
 
2251
 
 
2252
class TestSmartServerRepositoryReconcile(tests.TestCaseWithTransport):
 
2253
 
 
2254
    def test_reconcile(self):
 
2255
        backing = self.get_transport()
 
2256
        repo = self.make_repository('.')
 
2257
        token = repo.lock_write().repository_token
 
2258
        self.addCleanup(repo.unlock)
 
2259
        request_class = smart_repo.SmartServerRepositoryReconcile
 
2260
        request = request_class(backing)
 
2261
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(
 
2262
            (b'ok', ),
 
2263
             b'garbage_inventories: 0\n'
 
2264
             b'inconsistent_parents: 0\n'),
 
2265
            request.execute(b'', token))
1698
2266
 
1699
2267
 
1700
2268
class TestSmartServerIsReadonly(tests.TestCaseWithMemoryTransport):
1704
2272
        request = smart_req.SmartServerIsReadonly(backing)
1705
2273
        response = request.execute()
1706
2274
        self.assertEqual(
1707
 
            smart_req.SmartServerResponse(('no',)), response)
 
2275
            smart_req.SmartServerResponse((b'no',)), response)
1708
2276
 
1709
2277
    def test_is_readonly_yes(self):
1710
2278
        backing = self.get_readonly_transport()
1711
2279
        request = smart_req.SmartServerIsReadonly(backing)
1712
2280
        response = request.execute()
1713
2281
        self.assertEqual(
1714
 
            smart_req.SmartServerResponse(('yes',)), response)
 
2282
            smart_req.SmartServerResponse((b'yes',)), response)
1715
2283
 
1716
2284
 
1717
2285
class TestSmartServerRepositorySetMakeWorkingTrees(
1723
2291
        repo.set_make_working_trees(True)
1724
2292
        request_class = smart_repo.SmartServerRepositorySetMakeWorkingTrees
1725
2293
        request = request_class(backing)
1726
 
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(('ok',)),
1727
 
            request.execute('', 'False'))
1728
 
        repo = repo.bzrdir.open_repository()
 
2294
        self.assertEqual(smart_req.SuccessfulSmartServerResponse((b'ok',)),
 
2295
            request.execute(b'', b'False'))
 
2296
        repo = repo.controldir.open_repository()
1729
2297
        self.assertFalse(repo.make_working_trees())
1730
2298
 
1731
2299
    def test_set_true(self):
1734
2302
        repo.set_make_working_trees(False)
1735
2303
        request_class = smart_repo.SmartServerRepositorySetMakeWorkingTrees
1736
2304
        request = request_class(backing)
1737
 
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(('ok',)),
1738
 
            request.execute('', 'True'))
1739
 
        repo = repo.bzrdir.open_repository()
 
2305
        self.assertEqual(smart_req.SuccessfulSmartServerResponse((b'ok',)),
 
2306
            request.execute(b'', b'True'))
 
2307
        repo = repo.controldir.open_repository()
1740
2308
        self.assertTrue(repo.make_working_trees())
1741
2309
 
1742
2310
 
 
2311
class TestSmartServerRepositoryGetSerializerFormat(
 
2312
    tests.TestCaseWithMemoryTransport):
 
2313
 
 
2314
    def test_get_serializer_format(self):
 
2315
        backing = self.get_transport()
 
2316
        repo = self.make_repository('.', format='2a')
 
2317
        request_class = smart_repo.SmartServerRepositoryGetSerializerFormat
 
2318
        request = request_class(backing)
 
2319
        self.assertEqual(
 
2320
            smart_req.SuccessfulSmartServerResponse((b'ok', b'10')),
 
2321
            request.execute(b''))
 
2322
 
 
2323
 
 
2324
class TestSmartServerRepositoryWriteGroup(
 
2325
    tests.TestCaseWithMemoryTransport):
 
2326
 
 
2327
    def test_start_write_group(self):
 
2328
        backing = self.get_transport()
 
2329
        repo = self.make_repository('.')
 
2330
        lock_token = repo.lock_write().repository_token
 
2331
        self.addCleanup(repo.unlock)
 
2332
        request_class = smart_repo.SmartServerRepositoryStartWriteGroup
 
2333
        request = request_class(backing)
 
2334
        self.assertEqual(smart_req.SuccessfulSmartServerResponse((b'ok', [])),
 
2335
            request.execute(b'', lock_token))
 
2336
 
 
2337
    def test_start_write_group_unsuspendable(self):
 
2338
        backing = self.get_transport()
 
2339
        repo = self.make_repository('.', format='knit')
 
2340
        lock_token = repo.lock_write().repository_token
 
2341
        self.addCleanup(repo.unlock)
 
2342
        request_class = smart_repo.SmartServerRepositoryStartWriteGroup
 
2343
        request = request_class(backing)
 
2344
        self.assertEqual(
 
2345
            smart_req.FailedSmartServerResponse((b'UnsuspendableWriteGroup',)),
 
2346
            request.execute(b'', lock_token))
 
2347
 
 
2348
    def test_commit_write_group(self):
 
2349
        backing = self.get_transport()
 
2350
        repo = self.make_repository('.')
 
2351
        lock_token = repo.lock_write().repository_token
 
2352
        self.addCleanup(repo.unlock)
 
2353
        repo.start_write_group()
 
2354
        tokens = repo.suspend_write_group()
 
2355
        request_class = smart_repo.SmartServerRepositoryCommitWriteGroup
 
2356
        request = request_class(backing)
 
2357
        self.assertEqual(smart_req.SuccessfulSmartServerResponse((b'ok',)),
 
2358
            request.execute(b'', lock_token, tokens))
 
2359
 
 
2360
    def test_abort_write_group(self):
 
2361
        backing = self.get_transport()
 
2362
        repo = self.make_repository('.')
 
2363
        lock_token = repo.lock_write().repository_token
 
2364
        repo.start_write_group()
 
2365
        tokens = repo.suspend_write_group()
 
2366
        self.addCleanup(repo.unlock)
 
2367
        request_class = smart_repo.SmartServerRepositoryAbortWriteGroup
 
2368
        request = request_class(backing)
 
2369
        self.assertEqual(smart_req.SuccessfulSmartServerResponse((b'ok',)),
 
2370
            request.execute(b'', lock_token, tokens))
 
2371
 
 
2372
    def test_check_write_group(self):
 
2373
        backing = self.get_transport()
 
2374
        repo = self.make_repository('.')
 
2375
        lock_token = repo.lock_write().repository_token
 
2376
        repo.start_write_group()
 
2377
        tokens = repo.suspend_write_group()
 
2378
        self.addCleanup(repo.unlock)
 
2379
        request_class = smart_repo.SmartServerRepositoryCheckWriteGroup
 
2380
        request = request_class(backing)
 
2381
        self.assertEqual(smart_req.SuccessfulSmartServerResponse((b'ok',)),
 
2382
            request.execute(b'', lock_token, tokens))
 
2383
 
 
2384
    def test_check_write_group_invalid(self):
 
2385
        backing = self.get_transport()
 
2386
        repo = self.make_repository('.')
 
2387
        lock_token = repo.lock_write().repository_token
 
2388
        self.addCleanup(repo.unlock)
 
2389
        request_class = smart_repo.SmartServerRepositoryCheckWriteGroup
 
2390
        request = request_class(backing)
 
2391
        self.assertEqual(smart_req.FailedSmartServerResponse(
 
2392
            (b'UnresumableWriteGroup', [b'random'],
 
2393
                b'Malformed write group token')),
 
2394
            request.execute(b'', lock_token, [b"random"]))
 
2395
 
 
2396
 
1743
2397
class TestSmartServerPackRepositoryAutopack(tests.TestCaseWithTransport):
1744
2398
 
1745
2399
    def make_repo_needing_autopacking(self, path='.'):
1761
2415
        backing = self.get_transport()
1762
2416
        request = smart_packrepo.SmartServerPackRepositoryAutopack(
1763
2417
            backing)
1764
 
        response = request.execute('')
1765
 
        self.assertEqual(smart_req.SmartServerResponse(('ok',)), response)
 
2418
        response = request.execute(b'')
 
2419
        self.assertEqual(smart_req.SmartServerResponse((b'ok',)), response)
1766
2420
        repo._pack_collection.reload_pack_names()
1767
2421
        self.assertEqual(1, len(repo._pack_collection.names()))
1768
2422
 
1776
2430
        backing = self.get_transport()
1777
2431
        request = smart_packrepo.SmartServerPackRepositoryAutopack(
1778
2432
            backing)
1779
 
        response = request.execute('')
1780
 
        self.assertEqual(smart_req.SmartServerResponse(('ok',)), response)
 
2433
        response = request.execute(b'')
 
2434
        self.assertEqual(smart_req.SmartServerResponse((b'ok',)), response)
1781
2435
        repo._pack_collection.reload_pack_names()
1782
2436
        self.assertEqual(9, len(repo._pack_collection.names()))
1783
2437
 
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
 
1793
2447
 
1794
2448
class TestSmartServerVfsGet(tests.TestCaseWithMemoryTransport):
1799
2453
        filename_escaped = urlutils.escape(filename)
1800
2454
        backing = self.get_transport()
1801
2455
        request = vfs.GetRequest(backing)
1802
 
        backing.put_bytes_non_atomic(filename_escaped, 'contents')
1803
 
        self.assertEqual(smart_req.SmartServerResponse(('ok', ), 'contents'),
 
2456
        backing.put_bytes_non_atomic(filename_escaped, b'contents')
 
2457
        self.assertEqual(smart_req.SmartServerResponse((b'ok', ), b'contents'),
1804
2458
            request.execute(filename_escaped))
1805
2459
 
1806
2460
 
1811
2465
        """All registered request_handlers can be found."""
1812
2466
        # If there's a typo in a register_lazy call, this loop will fail with
1813
2467
        # an AttributeError.
1814
 
        for key, item in smart_req.request_handlers.iteritems():
1815
 
            pass
 
2468
        for key in smart_req.request_handlers.keys():
 
2469
            try:
 
2470
                item = smart_req.request_handlers.get(key)
 
2471
            except AttributeError as e:
 
2472
                raise AttributeError('failed to get %s: %s' % (key, e))
1816
2473
 
1817
2474
    def assertHandlerEqual(self, verb, handler):
1818
2475
        self.assertEqual(smart_req.request_handlers.get(verb), handler)
1819
2476
 
1820
2477
    def test_registered_methods(self):
1821
2478
        """Test that known methods are registered to the correct object."""
1822
 
        self.assertHandlerEqual('Branch.get_config_file',
 
2479
        self.assertHandlerEqual(b'Branch.break_lock',
 
2480
            smart_branch.SmartServerBranchBreakLock)
 
2481
        self.assertHandlerEqual(b'Branch.get_config_file',
1823
2482
            smart_branch.SmartServerBranchGetConfigFile)
1824
 
        self.assertHandlerEqual('Branch.get_parent',
 
2483
        self.assertHandlerEqual(b'Branch.put_config_file',
 
2484
            smart_branch.SmartServerBranchPutConfigFile)
 
2485
        self.assertHandlerEqual(b'Branch.get_parent',
1825
2486
            smart_branch.SmartServerBranchGetParent)
1826
 
        self.assertHandlerEqual('Branch.get_tags_bytes',
 
2487
        self.assertHandlerEqual(b'Branch.get_physical_lock_status',
 
2488
            smart_branch.SmartServerBranchRequestGetPhysicalLockStatus)
 
2489
        self.assertHandlerEqual(b'Branch.get_tags_bytes',
1827
2490
            smart_branch.SmartServerBranchGetTagsBytes)
1828
 
        self.assertHandlerEqual('Branch.lock_write',
 
2491
        self.assertHandlerEqual(b'Branch.lock_write',
1829
2492
            smart_branch.SmartServerBranchRequestLockWrite)
1830
 
        self.assertHandlerEqual('Branch.last_revision_info',
 
2493
        self.assertHandlerEqual(b'Branch.last_revision_info',
1831
2494
            smart_branch.SmartServerBranchRequestLastRevisionInfo)
1832
 
        self.assertHandlerEqual('Branch.revision_history',
 
2495
        self.assertHandlerEqual(b'Branch.revision_history',
1833
2496
            smart_branch.SmartServerRequestRevisionHistory)
1834
 
        self.assertHandlerEqual('Branch.set_config_option',
 
2497
        self.assertHandlerEqual(b'Branch.revision_id_to_revno',
 
2498
            smart_branch.SmartServerBranchRequestRevisionIdToRevno)
 
2499
        self.assertHandlerEqual(b'Branch.set_config_option',
1835
2500
            smart_branch.SmartServerBranchRequestSetConfigOption)
1836
 
        self.assertHandlerEqual('Branch.set_last_revision',
 
2501
        self.assertHandlerEqual(b'Branch.set_last_revision',
1837
2502
            smart_branch.SmartServerBranchRequestSetLastRevision)
1838
 
        self.assertHandlerEqual('Branch.set_last_revision_info',
 
2503
        self.assertHandlerEqual(b'Branch.set_last_revision_info',
1839
2504
            smart_branch.SmartServerBranchRequestSetLastRevisionInfo)
1840
 
        self.assertHandlerEqual('Branch.set_last_revision_ex',
 
2505
        self.assertHandlerEqual(b'Branch.set_last_revision_ex',
1841
2506
            smart_branch.SmartServerBranchRequestSetLastRevisionEx)
1842
 
        self.assertHandlerEqual('Branch.set_parent_location',
 
2507
        self.assertHandlerEqual(b'Branch.set_parent_location',
1843
2508
            smart_branch.SmartServerBranchRequestSetParentLocation)
1844
 
        self.assertHandlerEqual('Branch.unlock',
 
2509
        self.assertHandlerEqual(b'Branch.unlock',
1845
2510
            smart_branch.SmartServerBranchRequestUnlock)
1846
 
        self.assertHandlerEqual('BzrDir.find_repository',
 
2511
        self.assertHandlerEqual(b'BzrDir.destroy_branch',
 
2512
            smart_dir.SmartServerBzrDirRequestDestroyBranch)
 
2513
        self.assertHandlerEqual(b'BzrDir.find_repository',
1847
2514
            smart_dir.SmartServerRequestFindRepositoryV1)
1848
 
        self.assertHandlerEqual('BzrDir.find_repositoryV2',
 
2515
        self.assertHandlerEqual(b'BzrDir.find_repositoryV2',
1849
2516
            smart_dir.SmartServerRequestFindRepositoryV2)
1850
 
        self.assertHandlerEqual('BzrDirFormat.initialize',
 
2517
        self.assertHandlerEqual(b'BzrDirFormat.initialize',
1851
2518
            smart_dir.SmartServerRequestInitializeBzrDir)
1852
 
        self.assertHandlerEqual('BzrDirFormat.initialize_ex_1.16',
 
2519
        self.assertHandlerEqual(b'BzrDirFormat.initialize_ex_1.16',
1853
2520
            smart_dir.SmartServerRequestBzrDirInitializeEx)
1854
 
        self.assertHandlerEqual('BzrDir.cloning_metadir',
 
2521
        self.assertHandlerEqual(b'BzrDir.checkout_metadir',
 
2522
            smart_dir.SmartServerBzrDirRequestCheckoutMetaDir)
 
2523
        self.assertHandlerEqual(b'BzrDir.cloning_metadir',
1855
2524
            smart_dir.SmartServerBzrDirRequestCloningMetaDir)
1856
 
        self.assertHandlerEqual('BzrDir.get_config_file',
 
2525
        self.assertHandlerEqual(b'BzrDir.get_branches',
 
2526
            smart_dir.SmartServerBzrDirRequestGetBranches)
 
2527
        self.assertHandlerEqual(b'BzrDir.get_config_file',
1857
2528
            smart_dir.SmartServerBzrDirRequestConfigFile)
1858
 
        self.assertHandlerEqual('BzrDir.open_branch',
 
2529
        self.assertHandlerEqual(b'BzrDir.open_branch',
1859
2530
            smart_dir.SmartServerRequestOpenBranch)
1860
 
        self.assertHandlerEqual('BzrDir.open_branchV2',
 
2531
        self.assertHandlerEqual(b'BzrDir.open_branchV2',
1861
2532
            smart_dir.SmartServerRequestOpenBranchV2)
1862
 
        self.assertHandlerEqual('BzrDir.open_branchV3',
 
2533
        self.assertHandlerEqual(b'BzrDir.open_branchV3',
1863
2534
            smart_dir.SmartServerRequestOpenBranchV3)
1864
 
        self.assertHandlerEqual('PackRepository.autopack',
 
2535
        self.assertHandlerEqual(b'PackRepository.autopack',
1865
2536
            smart_packrepo.SmartServerPackRepositoryAutopack)
1866
 
        self.assertHandlerEqual('Repository.gather_stats',
 
2537
        self.assertHandlerEqual(b'Repository.add_signature_text',
 
2538
            smart_repo.SmartServerRepositoryAddSignatureText)
 
2539
        self.assertHandlerEqual(b'Repository.all_revision_ids',
 
2540
            smart_repo.SmartServerRepositoryAllRevisionIds)
 
2541
        self.assertHandlerEqual(b'Repository.break_lock',
 
2542
            smart_repo.SmartServerRepositoryBreakLock)
 
2543
        self.assertHandlerEqual(b'Repository.gather_stats',
1867
2544
            smart_repo.SmartServerRepositoryGatherStats)
1868
 
        self.assertHandlerEqual('Repository.get_parent_map',
 
2545
        self.assertHandlerEqual(b'Repository.get_parent_map',
1869
2546
            smart_repo.SmartServerRepositoryGetParentMap)
1870
 
        self.assertHandlerEqual('Repository.get_rev_id_for_revno',
 
2547
        self.assertHandlerEqual(b'Repository.get_physical_lock_status',
 
2548
            smart_repo.SmartServerRepositoryGetPhysicalLockStatus)
 
2549
        self.assertHandlerEqual(b'Repository.get_rev_id_for_revno',
1871
2550
            smart_repo.SmartServerRepositoryGetRevIdForRevno)
1872
 
        self.assertHandlerEqual('Repository.get_revision_graph',
 
2551
        self.assertHandlerEqual(b'Repository.get_revision_graph',
1873
2552
            smart_repo.SmartServerRepositoryGetRevisionGraph)
1874
 
        self.assertHandlerEqual('Repository.get_stream',
 
2553
        self.assertHandlerEqual(b'Repository.get_revision_signature_text',
 
2554
            smart_repo.SmartServerRepositoryGetRevisionSignatureText)
 
2555
        self.assertHandlerEqual(b'Repository.get_stream',
1875
2556
            smart_repo.SmartServerRepositoryGetStream)
1876
 
        self.assertHandlerEqual('Repository.has_revision',
 
2557
        self.assertHandlerEqual(b'Repository.get_stream_1.19',
 
2558
            smart_repo.SmartServerRepositoryGetStream_1_19)
 
2559
        self.assertHandlerEqual(b'Repository.iter_revisions',
 
2560
            smart_repo.SmartServerRepositoryIterRevisions)
 
2561
        self.assertHandlerEqual(b'Repository.has_revision',
1877
2562
            smart_repo.SmartServerRequestHasRevision)
1878
 
        self.assertHandlerEqual('Repository.insert_stream',
 
2563
        self.assertHandlerEqual(b'Repository.insert_stream',
1879
2564
            smart_repo.SmartServerRepositoryInsertStream)
1880
 
        self.assertHandlerEqual('Repository.insert_stream_locked',
 
2565
        self.assertHandlerEqual(b'Repository.insert_stream_locked',
1881
2566
            smart_repo.SmartServerRepositoryInsertStreamLocked)
1882
 
        self.assertHandlerEqual('Repository.is_shared',
 
2567
        self.assertHandlerEqual(b'Repository.is_shared',
1883
2568
            smart_repo.SmartServerRepositoryIsShared)
1884
 
        self.assertHandlerEqual('Repository.lock_write',
 
2569
        self.assertHandlerEqual(b'Repository.iter_files_bytes',
 
2570
            smart_repo.SmartServerRepositoryIterFilesBytes)
 
2571
        self.assertHandlerEqual(b'Repository.lock_write',
1885
2572
            smart_repo.SmartServerRepositoryLockWrite)
1886
 
        self.assertHandlerEqual('Repository.tarball',
 
2573
        self.assertHandlerEqual(b'Repository.make_working_trees',
 
2574
            smart_repo.SmartServerRepositoryMakeWorkingTrees)
 
2575
        self.assertHandlerEqual(b'Repository.pack',
 
2576
            smart_repo.SmartServerRepositoryPack)
 
2577
        self.assertHandlerEqual(b'Repository.reconcile',
 
2578
            smart_repo.SmartServerRepositoryReconcile)
 
2579
        self.assertHandlerEqual(b'Repository.tarball',
1887
2580
            smart_repo.SmartServerRepositoryTarball)
1888
 
        self.assertHandlerEqual('Repository.unlock',
 
2581
        self.assertHandlerEqual(b'Repository.unlock',
1889
2582
            smart_repo.SmartServerRepositoryUnlock)
1890
 
        self.assertHandlerEqual('Transport.is_readonly',
 
2583
        self.assertHandlerEqual(b'Repository.start_write_group',
 
2584
            smart_repo.SmartServerRepositoryStartWriteGroup)
 
2585
        self.assertHandlerEqual(b'Repository.check_write_group',
 
2586
            smart_repo.SmartServerRepositoryCheckWriteGroup)
 
2587
        self.assertHandlerEqual(b'Repository.commit_write_group',
 
2588
            smart_repo.SmartServerRepositoryCommitWriteGroup)
 
2589
        self.assertHandlerEqual(b'Repository.abort_write_group',
 
2590
            smart_repo.SmartServerRepositoryAbortWriteGroup)
 
2591
        self.assertHandlerEqual(b'VersionedFileRepository.get_serializer_format',
 
2592
            smart_repo.SmartServerRepositoryGetSerializerFormat)
 
2593
        self.assertHandlerEqual(b'VersionedFileRepository.get_inventories',
 
2594
            smart_repo.SmartServerRepositoryGetInventories)
 
2595
        self.assertHandlerEqual(b'Transport.is_readonly',
1891
2596
            smart_req.SmartServerIsReadonly)
 
2597
 
 
2598
 
 
2599
class SmartTCPServerHookTests(tests.TestCaseWithMemoryTransport):
 
2600
    """Tests for SmartTCPServer hooks."""
 
2601
 
 
2602
    def setUp(self):
 
2603
        super(SmartTCPServerHookTests, self).setUp()
 
2604
        self.server = server.SmartTCPServer(self.get_transport())
 
2605
 
 
2606
    def test_run_server_started_hooks(self):
 
2607
        """Test the server started hooks get fired properly."""
 
2608
        started_calls = []
 
2609
        server.SmartTCPServer.hooks.install_named_hook('server_started',
 
2610
            lambda backing_urls, url: started_calls.append((backing_urls, url)),
 
2611
            None)
 
2612
        started_ex_calls = []
 
2613
        server.SmartTCPServer.hooks.install_named_hook('server_started_ex',
 
2614
            lambda backing_urls, url: started_ex_calls.append((backing_urls, url)),
 
2615
            None)
 
2616
        self.server._sockname = ('example.com', 42)
 
2617
        self.server.run_server_started_hooks()
 
2618
        self.assertEqual(started_calls,
 
2619
            [([self.get_transport().base], 'bzr://example.com:42/')])
 
2620
        self.assertEqual(started_ex_calls,
 
2621
            [([self.get_transport().base], self.server)])
 
2622
 
 
2623
    def test_run_server_started_hooks_ipv6(self):
 
2624
        """Test that socknames can contain 4-tuples."""
 
2625
        self.server._sockname = ('::', 42, 0, 0)
 
2626
        started_calls = []
 
2627
        server.SmartTCPServer.hooks.install_named_hook('server_started',
 
2628
            lambda backing_urls, url: started_calls.append((backing_urls, url)),
 
2629
            None)
 
2630
        self.server.run_server_started_hooks()
 
2631
        self.assertEqual(started_calls,
 
2632
                [([self.get_transport().base], 'bzr://:::42/')])
 
2633
 
 
2634
    def test_run_server_stopped_hooks(self):
 
2635
        """Test the server stopped hooks."""
 
2636
        self.server._sockname = ('example.com', 42)
 
2637
        stopped_calls = []
 
2638
        server.SmartTCPServer.hooks.install_named_hook('server_stopped',
 
2639
            lambda backing_urls, url: stopped_calls.append((backing_urls, url)),
 
2640
            None)
 
2641
        self.server.run_server_stopped_hooks()
 
2642
        self.assertEqual(stopped_calls,
 
2643
            [([self.get_transport().base], 'bzr://example.com:42/')])
 
2644
 
 
2645
 
 
2646
class TestSmartServerRepositoryPack(tests.TestCaseWithMemoryTransport):
 
2647
 
 
2648
    def test_pack(self):
 
2649
        backing = self.get_transport()
 
2650
        request = smart_repo.SmartServerRepositoryPack(backing)
 
2651
        tree = self.make_branch_and_memory_tree('.')
 
2652
        repo_token = tree.branch.repository.lock_write().repository_token
 
2653
 
 
2654
        self.assertIs(None, request.execute(b'', repo_token, False))
 
2655
 
 
2656
        self.assertEqual(
 
2657
            smart_req.SuccessfulSmartServerResponse((b'ok', ), ),
 
2658
            request.do_body(b''))
 
2659
 
 
2660
 
 
2661
class TestSmartServerRepositoryGetInventories(tests.TestCaseWithTransport):
 
2662
 
 
2663
    def _get_serialized_inventory_delta(self, repository, base_revid, revid):
 
2664
        base_inv = repository.revision_tree(base_revid).root_inventory
 
2665
        inv = repository.revision_tree(revid).root_inventory
 
2666
        inv_delta = inv._make_delta(base_inv)
 
2667
        serializer = inventory_delta.InventoryDeltaSerializer(True, False)
 
2668
        return "".join(serializer.delta_to_lines(base_revid, revid, inv_delta))
 
2669
 
 
2670
    def test_single(self):
 
2671
        backing = self.get_transport()
 
2672
        request = smart_repo.SmartServerRepositoryGetInventories(backing)
 
2673
        t = self.make_branch_and_tree('.', format='2a')
 
2674
        self.addCleanup(t.lock_write().unlock)
 
2675
        self.build_tree_contents([("file", b"somecontents")])
 
2676
        t.add(["file"], [b"thefileid"])
 
2677
        t.commit(rev_id=b'somerev', message="add file")
 
2678
        self.assertIs(None, request.execute(b'', b'unordered'))
 
2679
        response = request.do_body(b"somerev\n")
 
2680
        self.assertTrue(response.is_successful())
 
2681
        self.assertEqual(response.args, (b"ok", ))
 
2682
        stream = [('inventory-deltas', [
 
2683
            versionedfile.FulltextContentFactory('somerev', None, None,
 
2684
                self._get_serialized_inventory_delta(
 
2685
                    t.branch.repository, b'null:', b'somerev'))])]
 
2686
        fmt = controldir.format_registry.get('2a')().repository_format
 
2687
        self.assertEqual(
 
2688
            b"".join(response.body_stream),
 
2689
            b"".join(smart_repo._stream_to_byte_stream(stream, fmt)))
 
2690
 
 
2691
    def test_empty(self):
 
2692
        backing = self.get_transport()
 
2693
        request = smart_repo.SmartServerRepositoryGetInventories(backing)
 
2694
        t = self.make_branch_and_tree('.', format='2a')
 
2695
        self.addCleanup(t.lock_write().unlock)
 
2696
        self.build_tree_contents([("file", b"somecontents")])
 
2697
        t.add(["file"], [b"thefileid"])
 
2698
        t.commit(rev_id=b'somerev', message="add file")
 
2699
        self.assertIs(None, request.execute(b'', b'unordered'))
 
2700
        response = request.do_body(b"")
 
2701
        self.assertTrue(response.is_successful())
 
2702
        self.assertEqual(response.args, (b"ok", ))
 
2703
        self.assertEqual(b"".join(response.body_stream),
 
2704
            b"Bazaar pack format 1 (introduced in 0.18)\nB54\n\nBazaar repository format 2a (needs bzr 1.16 or later)\nE")