/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: Martin
  • Date: 2017-06-09 16:31:49 UTC
  • mto: This revision was merged to the branch mainline in revision 6673.
  • Revision ID: gzlist@googlemail.com-20170609163149-liveiasey25480q6
Make InventoryDeltaError use string formatting, and repr for fileids

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
    bzrbranch as _mod_bzrbranch,
 
34
    controldir,
35
35
    errors,
36
 
    pack,
 
36
    gpg,
 
37
    inventory_delta,
37
38
    tests,
38
39
    transport,
39
40
    urlutils,
40
41
    versionedfile,
41
42
    )
42
 
from bzrlib.smart import (
 
43
from breezy.smart import (
43
44
    branch as smart_branch,
44
45
    bzrdir as smart_dir,
45
46
    repository as smart_repo,
48
49
    server,
49
50
    vfs,
50
51
    )
51
 
from bzrlib.tests import test_server
52
 
from bzrlib.transport import (
 
52
from breezy.testament import Testament
 
53
from breezy.tests import test_server
 
54
from breezy.transport import (
53
55
    chroot,
54
56
    memory,
55
57
    )
56
58
 
57
59
 
58
 
def load_tests(standard_tests, module, loader):
 
60
def load_tests(loader, standard_tests, pattern):
59
61
    """Multiply tests version and protocol consistency."""
60
62
    # FindRepository tests.
61
63
    scenarios = [
81
83
 
82
84
    def setUp(self):
83
85
        self.vfs_transport_factory = memory.MemoryServer
84
 
        tests.TestCaseWithTransport.setUp(self)
 
86
        super(TestCaseWithChrootedTransport, self).setUp()
85
87
        self._chroot_server = None
86
88
 
87
89
    def get_transport(self, relpath=None):
89
91
            backing_transport = tests.TestCaseWithTransport.get_transport(self)
90
92
            self._chroot_server = chroot.ChrootServer(backing_transport)
91
93
            self.start_server(self._chroot_server)
92
 
        t = transport.get_transport(self._chroot_server.get_url())
 
94
        t = transport.get_transport_from_url(self._chroot_server.get_url())
93
95
        if relpath is not None:
94
96
            t = t.clone(relpath)
95
97
        return t
103
105
        # the default or a parameterized class, but rather use the
104
106
        # TestCaseWithTransport infrastructure to set up a smart server and
105
107
        # transport.
106
 
        self.transport_server = self.make_transport_server
 
108
        self.overrideAttr(self, "transport_server", self.make_transport_server)
107
109
 
108
110
    def make_transport_server(self):
109
111
        return test_server.SmartTCPServer_for_testing('-' + self.id())
120
122
        stream = [('text', [versionedfile.FulltextContentFactory(('k1',), None,
121
123
            None, 'foo')]),('text', [
122
124
            versionedfile.FulltextContentFactory(('k2',), None, None, 'bar')])]
123
 
        fmt = bzrdir.format_registry.get('pack-0.92')().repository_format
 
125
        fmt = controldir.format_registry.get('pack-0.92')().repository_format
124
126
        bytes = smart_repo._stream_to_byte_stream(stream, fmt)
125
127
        streams = []
126
128
        # Iterate the resulting iterable; checking that we get only one stream
213
215
        referenced_branch = self.make_branch('referenced')
214
216
        dir = self.make_bzrdir('.')
215
217
        local_result = dir.cloning_metadir()
216
 
        reference = _mod_branch.BranchReferenceFormat().initialize(
 
218
        reference = _mod_bzrbranch.BranchReferenceFormat().initialize(
217
219
            dir, target_branch=referenced_branch)
218
 
        reference_url = _mod_branch.BranchReferenceFormat().get_reference(dir)
 
220
        reference_url = _mod_bzrbranch.BranchReferenceFormat().get_reference(dir)
219
221
        # The server shouldn't try to follow the branch reference, so it's fine
220
222
        # if the referenced branch isn't reachable.
221
223
        backing.rename('referenced', 'moved')
225
227
        self.assertEqual(expected, request.execute('', 'False'))
226
228
 
227
229
 
 
230
class TestSmartServerBzrDirRequestCloningMetaDir(
 
231
    tests.TestCaseWithMemoryTransport):
 
232
    """Tests for BzrDir.checkout_metadir."""
 
233
 
 
234
    def test_checkout_metadir(self):
 
235
        backing = self.get_transport()
 
236
        request = smart_dir.SmartServerBzrDirRequestCheckoutMetaDir(
 
237
            backing)
 
238
        branch = self.make_branch('.', format='2a')
 
239
        response = request.execute('')
 
240
        self.assertEqual(
 
241
            smart_req.SmartServerResponse(
 
242
                ('Bazaar-NG meta directory, format 1\n',
 
243
                 'Bazaar repository format 2a (needs bzr 1.16 or later)\n',
 
244
                 'Bazaar Branch Format 7 (needs bzr 1.6)\n')),
 
245
            response)
 
246
 
 
247
 
 
248
class TestSmartServerBzrDirRequestDestroyBranch(
 
249
    tests.TestCaseWithMemoryTransport):
 
250
    """Tests for BzrDir.destroy_branch."""
 
251
 
 
252
    def test_destroy_branch_default(self):
 
253
        """The default branch can be removed."""
 
254
        backing = self.get_transport()
 
255
        dir = self.make_branch('.').bzrdir
 
256
        request_class = smart_dir.SmartServerBzrDirRequestDestroyBranch
 
257
        request = request_class(backing)
 
258
        expected = smart_req.SuccessfulSmartServerResponse(('ok',))
 
259
        self.assertEqual(expected, request.execute('', None))
 
260
 
 
261
    def test_destroy_branch_named(self):
 
262
        """A named branch can be removed."""
 
263
        backing = self.get_transport()
 
264
        dir = self.make_repository('.', format="development-colo").bzrdir
 
265
        dir.create_branch(name="branchname")
 
266
        request_class = smart_dir.SmartServerBzrDirRequestDestroyBranch
 
267
        request = request_class(backing)
 
268
        expected = smart_req.SuccessfulSmartServerResponse(('ok',))
 
269
        self.assertEqual(expected, request.execute('', "branchname"))
 
270
 
 
271
    def test_destroy_branch_missing(self):
 
272
        """An error is raised if the branch didn't exist."""
 
273
        backing = self.get_transport()
 
274
        dir = self.make_bzrdir('.', format="development-colo")
 
275
        request_class = smart_dir.SmartServerBzrDirRequestDestroyBranch
 
276
        request = request_class(backing)
 
277
        expected = smart_req.FailedSmartServerResponse(('nobranch',), None)
 
278
        self.assertEqual(expected, request.execute('', "branchname"))
 
279
 
 
280
 
 
281
class TestSmartServerBzrDirRequestHasWorkingTree(
 
282
    tests.TestCaseWithTransport):
 
283
    """Tests for BzrDir.has_workingtree."""
 
284
 
 
285
    def test_has_workingtree_yes(self):
 
286
        """A working tree is present."""
 
287
        backing = self.get_transport()
 
288
        dir = self.make_branch_and_tree('.').bzrdir
 
289
        request_class = smart_dir.SmartServerBzrDirRequestHasWorkingTree
 
290
        request = request_class(backing)
 
291
        expected = smart_req.SuccessfulSmartServerResponse(('yes',))
 
292
        self.assertEqual(expected, request.execute(''))
 
293
 
 
294
    def test_has_workingtree_no(self):
 
295
        """A working tree is missing."""
 
296
        backing = self.get_transport()
 
297
        dir = self.make_bzrdir('.')
 
298
        request_class = smart_dir.SmartServerBzrDirRequestHasWorkingTree
 
299
        request = request_class(backing)
 
300
        expected = smart_req.SuccessfulSmartServerResponse(('no',))
 
301
        self.assertEqual(expected, request.execute(''))
 
302
 
 
303
 
 
304
class TestSmartServerBzrDirRequestDestroyRepository(
 
305
    tests.TestCaseWithMemoryTransport):
 
306
    """Tests for BzrDir.destroy_repository."""
 
307
 
 
308
    def test_destroy_repository_default(self):
 
309
        """The repository can be removed."""
 
310
        backing = self.get_transport()
 
311
        dir = self.make_repository('.').bzrdir
 
312
        request_class = smart_dir.SmartServerBzrDirRequestDestroyRepository
 
313
        request = request_class(backing)
 
314
        expected = smart_req.SuccessfulSmartServerResponse(('ok',))
 
315
        self.assertEqual(expected, request.execute(''))
 
316
 
 
317
    def test_destroy_repository_missing(self):
 
318
        """An error is raised if the repository didn't exist."""
 
319
        backing = self.get_transport()
 
320
        dir = self.make_bzrdir('.')
 
321
        request_class = smart_dir.SmartServerBzrDirRequestDestroyRepository
 
322
        request = request_class(backing)
 
323
        expected = smart_req.FailedSmartServerResponse(
 
324
            ('norepository',), None)
 
325
        self.assertEqual(expected, request.execute(''))
 
326
 
 
327
 
228
328
class TestSmartServerRequestCreateRepository(tests.TestCaseWithMemoryTransport):
229
329
    """Tests for BzrDir.create_repository."""
230
330
 
234
334
        self.make_bzrdir('.')
235
335
        request_class = smart_dir.SmartServerRequestCreateRepository
236
336
        request = request_class(backing)
237
 
        reference_bzrdir_format = bzrdir.format_registry.get('pack-0.92')()
 
337
        reference_bzrdir_format = controldir.format_registry.get('pack-0.92')()
238
338
        reference_format = reference_bzrdir_format.repository_format
239
339
        network_name = reference_format.network_name()
240
340
        expected = smart_req.SuccessfulSmartServerResponse(
320
420
        backing = self.get_transport()
321
421
        request = self._request_class(backing)
322
422
        result = self._make_repository_and_result(
323
 
            format='dirstate-with-subtree')
 
423
            format='development-subtree')
324
424
        # check the test will be valid
325
425
        self.assertEqual('yes', result.args[2])
326
426
        self.assertEqual('yes', result.args[3])
331
431
        backing = self.get_transport()
332
432
        request = self._request_class(backing)
333
433
        result = self._make_repository_and_result(
334
 
            format='dirstate-with-subtree')
 
434
            format='development-subtree')
335
435
        # check the test will be valid
336
 
        self.assertEqual('no', result.args[4])
 
436
        self.assertEqual('yes', result.args[4])
337
437
        self.assertEqual(result, request.execute(''))
338
438
 
339
439
 
360
460
        self.assertEqual(expected, request.execute(''))
361
461
 
362
462
 
 
463
class TestSmartServerBzrDirRequestGetBranches(
 
464
    tests.TestCaseWithMemoryTransport):
 
465
    """Tests for BzrDir.get_branches."""
 
466
 
 
467
    def test_simple(self):
 
468
        backing = self.get_transport()
 
469
        branch = self.make_branch('.')
 
470
        request_class = smart_dir.SmartServerBzrDirRequestGetBranches
 
471
        request = request_class(backing)
 
472
        local_result = bencode.bencode(
 
473
            {"": ("branch", branch._format.network_name())})
 
474
        expected = smart_req.SuccessfulSmartServerResponse(
 
475
            ("success", ), local_result)
 
476
        self.assertEqual(expected, request.execute(''))
 
477
 
 
478
    def test_empty(self):
 
479
        backing = self.get_transport()
 
480
        dir = self.make_bzrdir('.')
 
481
        request_class = smart_dir.SmartServerBzrDirRequestGetBranches
 
482
        request = request_class(backing)
 
483
        local_result = bencode.bencode({})
 
484
        expected = smart_req.SuccessfulSmartServerResponse(
 
485
            ('success',), local_result)
 
486
        self.assertEqual(expected, request.execute(''))
 
487
 
 
488
 
363
489
class TestSmartServerRequestInitializeBzrDir(tests.TestCaseWithMemoryTransport):
364
490
 
365
491
    def test_empty_dir(self):
368
494
        request = smart_dir.SmartServerRequestInitializeBzrDir(backing)
369
495
        self.assertEqual(smart_req.SmartServerResponse(('ok', )),
370
496
            request.execute(''))
371
 
        made_dir = bzrdir.BzrDir.open_from_transport(backing)
 
497
        made_dir = controldir.ControlDir.open_from_transport(backing)
372
498
        # no branch, tree or repository is expected with the current
373
499
        # default formart.
374
500
        self.assertRaises(errors.NoWorkingTree, made_dir.open_workingtree)
387
513
        backing = self.get_transport()
388
514
        request = smart_dir.SmartServerRequestInitializeBzrDir(backing)
389
515
        self.make_bzrdir('subdir')
390
 
        self.assertRaises(errors.FileExists,
 
516
        self.assertRaises(errors.AlreadyControlDirError,
391
517
            request.execute, 'subdir')
392
518
 
393
519
 
408
534
                                           'False', '', '', '')),
409
535
            request.execute(name, '', 'True', 'False', 'False', '', '', '', '',
410
536
                            'False'))
411
 
        made_dir = bzrdir.BzrDir.open_from_transport(backing)
 
537
        made_dir = controldir.ControlDir.open_from_transport(backing)
412
538
        # no branch, tree or repository is expected with the current
413
539
        # default format.
414
540
        self.assertRaises(errors.NoWorkingTree, made_dir.open_workingtree)
525
651
        request = smart_dir.SmartServerRequestOpenBranch(backing)
526
652
        branch = self.make_branch('branch')
527
653
        checkout = branch.create_checkout('reference',lightweight=True)
528
 
        reference_url = _mod_branch.BranchReferenceFormat().get_reference(
 
654
        reference_url = _mod_bzrbranch.BranchReferenceFormat().get_reference(
529
655
            checkout.bzrdir)
530
656
        self.assertFileEqual(reference_url, 'reference/.bzr/branch/location')
531
657
        self.assertEqual(smart_req.SmartServerResponse(('ok', reference_url)),
566
692
        request = smart_dir.SmartServerRequestOpenBranchV2(backing)
567
693
        branch = self.make_branch('branch')
568
694
        checkout = branch.create_checkout('reference',lightweight=True)
569
 
        reference_url = _mod_branch.BranchReferenceFormat().get_reference(
 
695
        reference_url = _mod_bzrbranch.BranchReferenceFormat().get_reference(
570
696
            checkout.bzrdir)
571
697
        self.assertFileEqual(reference_url, 'reference/.bzr/branch/location')
572
698
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(
629
755
        request = smart_dir.SmartServerRequestOpenBranchV3(backing)
630
756
        branch = self.make_branch('branch')
631
757
        checkout = branch.create_checkout('reference',lightweight=True)
632
 
        reference_url = _mod_branch.BranchReferenceFormat().get_reference(
 
758
        reference_url = _mod_bzrbranch.BranchReferenceFormat().get_reference(
633
759
            checkout.bzrdir)
634
760
        self.assertFileEqual(reference_url, 'reference/.bzr/branch/location')
635
761
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(
739
865
            request.execute(''))
740
866
 
741
867
 
 
868
class TestSmartServerBranchRequestRevisionIdToRevno(
 
869
    tests.TestCaseWithMemoryTransport):
 
870
 
 
871
    def test_null(self):
 
872
        backing = self.get_transport()
 
873
        request = smart_branch.SmartServerBranchRequestRevisionIdToRevno(
 
874
            backing)
 
875
        self.make_branch('.')
 
876
        self.assertEqual(smart_req.SmartServerResponse(('ok', '0')),
 
877
            request.execute('', 'null:'))
 
878
 
 
879
    def test_simple(self):
 
880
        backing = self.get_transport()
 
881
        request = smart_branch.SmartServerBranchRequestRevisionIdToRevno(
 
882
            backing)
 
883
        tree = self.make_branch_and_memory_tree('.')
 
884
        tree.lock_write()
 
885
        tree.add('')
 
886
        r1 = tree.commit('1st commit')
 
887
        tree.unlock()
 
888
        self.assertEqual(
 
889
            smart_req.SmartServerResponse(('ok', '1')),
 
890
            request.execute('', r1))
 
891
 
 
892
    def test_not_found(self):
 
893
        backing = self.get_transport()
 
894
        request = smart_branch.SmartServerBranchRequestRevisionIdToRevno(
 
895
            backing)
 
896
        branch = self.make_branch('.')
 
897
        self.assertEqual(
 
898
            smart_req.FailedSmartServerResponse(
 
899
                ('NoSuchRevision', 'idontexist')),
 
900
            request.execute('', 'idontexist'))
 
901
 
 
902
 
742
903
class TestSmartServerBranchRequestGetConfigFile(
743
904
    tests.TestCaseWithMemoryTransport):
744
905
 
767
928
class TestLockedBranch(tests.TestCaseWithMemoryTransport):
768
929
 
769
930
    def get_lock_tokens(self, branch):
770
 
        branch_token = branch.lock_write()
771
 
        repo_token = branch.repository.lock_write()
 
931
        branch_token = branch.lock_write().branch_token
 
932
        repo_token = branch.repository.lock_write().repository_token
772
933
        branch.repository.unlock()
773
934
        return branch_token, repo_token
774
935
 
775
936
 
 
937
class TestSmartServerBranchRequestPutConfigFile(TestLockedBranch):
 
938
 
 
939
    def test_with_content(self):
 
940
        backing = self.get_transport()
 
941
        request = smart_branch.SmartServerBranchPutConfigFile(backing)
 
942
        branch = self.make_branch('.')
 
943
        branch_token, repo_token = self.get_lock_tokens(branch)
 
944
        self.assertIs(None, request.execute('', branch_token, repo_token))
 
945
        self.assertEqual(
 
946
            smart_req.SmartServerResponse(('ok', )),
 
947
            request.do_body('foo bar baz'))
 
948
        self.assertEqual(
 
949
            branch.control_transport.get_bytes('branch.conf'),
 
950
            'foo bar baz')
 
951
        branch.unlock()
 
952
 
 
953
 
776
954
class TestSmartServerBranchRequestSetConfigOption(TestLockedBranch):
777
955
 
778
956
    def test_value_name(self):
802
980
        branch.unlock()
803
981
 
804
982
 
 
983
class TestSmartServerBranchRequestSetConfigOptionDict(TestLockedBranch):
 
984
 
 
985
    def setUp(self):
 
986
        TestLockedBranch.setUp(self)
 
987
        # A dict with non-ascii keys and values to exercise unicode
 
988
        # roundtripping.
 
989
        self.encoded_value_dict = (
 
990
            'd5:ascii1:a11:unicode \xe2\x8c\x9a3:\xe2\x80\xbde')
 
991
        self.value_dict = {
 
992
            'ascii': 'a', u'unicode \N{WATCH}': u'\N{INTERROBANG}'}
 
993
 
 
994
    def test_value_name(self):
 
995
        branch = self.make_branch('.')
 
996
        request = smart_branch.SmartServerBranchRequestSetConfigOptionDict(
 
997
            branch.bzrdir.root_transport)
 
998
        branch_token, repo_token = self.get_lock_tokens(branch)
 
999
        config = branch._get_config()
 
1000
        result = request.execute('', branch_token, repo_token,
 
1001
            self.encoded_value_dict, 'foo', '')
 
1002
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(()), result)
 
1003
        self.assertEqual(self.value_dict, config.get_option('foo'))
 
1004
        # Cleanup
 
1005
        branch.unlock()
 
1006
 
 
1007
    def test_value_name_section(self):
 
1008
        branch = self.make_branch('.')
 
1009
        request = smart_branch.SmartServerBranchRequestSetConfigOptionDict(
 
1010
            branch.bzrdir.root_transport)
 
1011
        branch_token, repo_token = self.get_lock_tokens(branch)
 
1012
        config = branch._get_config()
 
1013
        result = request.execute('', branch_token, repo_token,
 
1014
            self.encoded_value_dict, 'foo', 'gam')
 
1015
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(()), result)
 
1016
        self.assertEqual(self.value_dict, config.get_option('foo', 'gam'))
 
1017
        # Cleanup
 
1018
        branch.unlock()
 
1019
 
 
1020
 
805
1021
class TestSmartServerBranchRequestSetTagsBytes(TestLockedBranch):
806
1022
    # Only called when the branch format and tags match [yay factory
807
1023
    # methods] so only need to test straight forward cases.
818
1034
        response = request.do_chunk(tag_bytes)
819
1035
        self.assertEqual(None, response)
820
1036
        response = request.do_end()
821
 
        self.assertEquals(
 
1037
        self.assertEqual(
822
1038
            smart_req.SuccessfulSmartServerResponse(()), response)
823
1039
        base_branch.unlock()
824
1040
 
843
1059
    """Base test case for verbs that implement set_last_revision."""
844
1060
 
845
1061
    def setUp(self):
846
 
        tests.TestCaseWithMemoryTransport.setUp(self)
 
1062
        super(SetLastRevisionTestBase, self).setUp()
847
1063
        backing_transport = self.get_transport()
848
1064
        self.request = self.request_class(backing_transport)
849
1065
        self.tree = self.make_branch_and_memory_tree('.')
898
1114
        # its repository.
899
1115
        self.make_tree_with_two_commits()
900
1116
        rev_id_utf8 = u'\xc8'.encode('utf-8')
901
 
        self.tree.branch.set_revision_history([])
 
1117
        self.tree.branch.set_last_revision_info(0, 'null:')
902
1118
        self.assertEqual(
903
1119
            (0, 'null:'), self.tree.branch.last_revision_info())
904
1120
        # We can update the branch to a revision that is present in the
1054
1270
        self.assertEqual('child-1', self.tree.branch.last_revision())
1055
1271
 
1056
1272
 
 
1273
class TestSmartServerBranchBreakLock(tests.TestCaseWithMemoryTransport):
 
1274
 
 
1275
    def test_lock_to_break(self):
 
1276
        base_branch = self.make_branch('base')
 
1277
        request = smart_branch.SmartServerBranchBreakLock(
 
1278
            self.get_transport())
 
1279
        base_branch.lock_write()
 
1280
        self.assertEqual(
 
1281
            smart_req.SuccessfulSmartServerResponse(('ok', ), None),
 
1282
            request.execute('base'))
 
1283
 
 
1284
    def test_nothing_to_break(self):
 
1285
        base_branch = self.make_branch('base')
 
1286
        request = smart_branch.SmartServerBranchBreakLock(
 
1287
            self.get_transport())
 
1288
        self.assertEqual(
 
1289
            smart_req.SuccessfulSmartServerResponse(('ok', ), None),
 
1290
            request.execute('base'))
 
1291
 
 
1292
 
1057
1293
class TestSmartServerBranchRequestGetParent(tests.TestCaseWithMemoryTransport):
1058
1294
 
1059
1295
    def test_get_parent_none(self):
1060
1296
        base_branch = self.make_branch('base')
1061
1297
        request = smart_branch.SmartServerBranchGetParent(self.get_transport())
1062
1298
        response = request.execute('base')
1063
 
        self.assertEquals(
 
1299
        self.assertEqual(
1064
1300
            smart_req.SuccessfulSmartServerResponse(('',)), response)
1065
1301
 
1066
1302
    def test_get_parent_something(self):
1068
1304
        base_branch.set_parent(self.get_url('foo'))
1069
1305
        request = smart_branch.SmartServerBranchGetParent(self.get_transport())
1070
1306
        response = request.execute('base')
1071
 
        self.assertEquals(
 
1307
        self.assertEqual(
1072
1308
            smart_req.SuccessfulSmartServerResponse(("../foo",)),
1073
1309
            response)
1074
1310
 
1075
1311
 
1076
 
class TestSmartServerBranchRequestSetParent(tests.TestCaseWithMemoryTransport):
 
1312
class TestSmartServerBranchRequestSetParent(TestLockedBranch):
1077
1313
 
1078
1314
    def test_set_parent_none(self):
1079
1315
        branch = self.make_branch('base', format="1.9")
1082
1318
        branch.unlock()
1083
1319
        request = smart_branch.SmartServerBranchRequestSetParentLocation(
1084
1320
            self.get_transport())
1085
 
        branch_token = branch.lock_write()
1086
 
        repo_token = branch.repository.lock_write()
 
1321
        branch_token, repo_token = self.get_lock_tokens(branch)
1087
1322
        try:
1088
1323
            response = request.execute('base', branch_token, repo_token, '')
1089
1324
        finally:
1090
 
            branch.repository.unlock()
1091
1325
            branch.unlock()
1092
1326
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(()), response)
 
1327
        # Refresh branch as SetParentLocation modified it
 
1328
        branch = branch.bzrdir.open_branch()
1093
1329
        self.assertEqual(None, branch.get_parent())
1094
1330
 
1095
1331
    def test_set_parent_something(self):
1096
1332
        branch = self.make_branch('base', format="1.9")
1097
1333
        request = smart_branch.SmartServerBranchRequestSetParentLocation(
1098
1334
            self.get_transport())
1099
 
        branch_token = branch.lock_write()
1100
 
        repo_token = branch.repository.lock_write()
 
1335
        branch_token, repo_token = self.get_lock_tokens(branch)
1101
1336
        try:
1102
1337
            response = request.execute('base', branch_token, repo_token,
1103
 
            'http://bar/')
 
1338
                                       'http://bar/')
1104
1339
        finally:
1105
 
            branch.repository.unlock()
1106
1340
            branch.unlock()
1107
1341
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(()), response)
1108
 
        self.assertEqual('http://bar/', branch.get_parent())
 
1342
        refreshed = _mod_branch.Branch.open(branch.base)
 
1343
        self.assertEqual('http://bar/', refreshed.get_parent())
1109
1344
 
1110
1345
 
1111
1346
class TestSmartServerBranchRequestGetTagsBytes(
1118
1353
        request = smart_branch.SmartServerBranchGetTagsBytes(
1119
1354
            self.get_transport())
1120
1355
        response = request.execute('base')
1121
 
        self.assertEquals(
 
1356
        self.assertEqual(
1122
1357
            smart_req.SuccessfulSmartServerResponse(('',)), response)
1123
1358
 
1124
1359
 
1132
1367
        request = smart_branch.SmartServerBranchRequestGetStackedOnURL(
1133
1368
            self.get_transport())
1134
1369
        response = request.execute('stacked')
1135
 
        self.assertEquals(
 
1370
        self.assertEqual(
1136
1371
            smart_req.SmartServerResponse(('ok', '../base')),
1137
1372
            response)
1138
1373
 
1139
1374
 
1140
 
class TestSmartServerBranchRequestLockWrite(tests.TestCaseWithMemoryTransport):
1141
 
 
1142
 
    def setUp(self):
1143
 
        tests.TestCaseWithMemoryTransport.setUp(self)
 
1375
class TestSmartServerBranchRequestLockWrite(TestLockedBranch):
1144
1376
 
1145
1377
    def test_lock_write_on_unlocked_branch(self):
1146
1378
        backing = self.get_transport()
1165
1397
        backing = self.get_transport()
1166
1398
        request = smart_branch.SmartServerBranchRequestLockWrite(backing)
1167
1399
        branch = self.make_branch('.')
1168
 
        branch_token = branch.lock_write()
 
1400
        branch_token = branch.lock_write().branch_token
1169
1401
        branch.leave_lock_in_place()
1170
1402
        branch.unlock()
1171
1403
        response = request.execute('')
1180
1412
        backing = self.get_transport()
1181
1413
        request = smart_branch.SmartServerBranchRequestLockWrite(backing)
1182
1414
        branch = self.make_branch('.', format='knit')
1183
 
        branch_token = branch.lock_write()
1184
 
        repo_token = branch.repository.lock_write()
1185
 
        branch.repository.unlock()
 
1415
        branch_token, repo_token = self.get_lock_tokens(branch)
1186
1416
        branch.leave_lock_in_place()
1187
1417
        branch.repository.leave_lock_in_place()
1188
1418
        branch.unlock()
1203
1433
        backing = self.get_transport()
1204
1434
        request = smart_branch.SmartServerBranchRequestLockWrite(backing)
1205
1435
        branch = self.make_branch('.', format='knit')
1206
 
        branch_token = branch.lock_write()
1207
 
        repo_token = branch.repository.lock_write()
1208
 
        branch.repository.unlock()
 
1436
        branch_token, repo_token = self.get_lock_tokens(branch)
1209
1437
        branch.leave_lock_in_place()
1210
1438
        branch.repository.leave_lock_in_place()
1211
1439
        branch.unlock()
1226
1454
        request = smart_branch.SmartServerBranchRequestLockWrite(backing)
1227
1455
        branch = self.make_branch('.', format='knit')
1228
1456
        repo = branch.repository
1229
 
        repo_token = repo.lock_write()
 
1457
        repo_token = repo.lock_write().repository_token
1230
1458
        repo.leave_lock_in_place()
1231
1459
        repo.unlock()
1232
1460
        response = request.execute('')
1249
1477
        self.assertEqual('LockFailed', error_name)
1250
1478
 
1251
1479
 
1252
 
class TestSmartServerBranchRequestUnlock(tests.TestCaseWithMemoryTransport):
1253
 
 
1254
 
    def setUp(self):
1255
 
        tests.TestCaseWithMemoryTransport.setUp(self)
 
1480
class TestSmartServerBranchRequestGetPhysicalLockStatus(TestLockedBranch):
 
1481
 
 
1482
    def test_true(self):
 
1483
        backing = self.get_transport()
 
1484
        request = smart_branch.SmartServerBranchRequestGetPhysicalLockStatus(
 
1485
            backing)
 
1486
        branch = self.make_branch('.')
 
1487
        branch_token, repo_token = self.get_lock_tokens(branch)
 
1488
        self.assertEqual(True, branch.get_physical_lock_status())
 
1489
        response = request.execute('')
 
1490
        self.assertEqual(
 
1491
            smart_req.SmartServerResponse(('yes',)), response)
 
1492
        branch.unlock()
 
1493
 
 
1494
    def test_false(self):
 
1495
        backing = self.get_transport()
 
1496
        request = smart_branch.SmartServerBranchRequestGetPhysicalLockStatus(
 
1497
            backing)
 
1498
        branch = self.make_branch('.')
 
1499
        self.assertEqual(False, branch.get_physical_lock_status())
 
1500
        response = request.execute('')
 
1501
        self.assertEqual(
 
1502
            smart_req.SmartServerResponse(('no',)), response)
 
1503
 
 
1504
 
 
1505
class TestSmartServerBranchRequestUnlock(TestLockedBranch):
1256
1506
 
1257
1507
    def test_unlock_on_locked_branch_and_repo(self):
1258
1508
        backing = self.get_transport()
1259
1509
        request = smart_branch.SmartServerBranchRequestUnlock(backing)
1260
1510
        branch = self.make_branch('.', format='knit')
1261
1511
        # Lock the branch
1262
 
        branch_token = branch.lock_write()
1263
 
        repo_token = branch.repository.lock_write()
1264
 
        branch.repository.unlock()
 
1512
        branch_token, repo_token = self.get_lock_tokens(branch)
1265
1513
        # Unlock the branch (and repo) object, leaving the physical locks
1266
1514
        # in place.
1267
1515
        branch.leave_lock_in_place()
1291
1539
        request = smart_branch.SmartServerBranchRequestUnlock(backing)
1292
1540
        branch = self.make_branch('.', format='knit')
1293
1541
        # Lock the repository.
1294
 
        repo_token = branch.repository.lock_write()
 
1542
        repo_token = branch.repository.lock_write().repository_token
1295
1543
        branch.repository.leave_lock_in_place()
1296
1544
        branch.repository.unlock()
1297
1545
        # Issue branch lock_write request on the unlocked branch (with locked
1298
1546
        # repo).
1299
 
        response = request.execute(
1300
 
            '', 'branch token', repo_token)
 
1547
        response = request.execute('', 'branch token', repo_token)
1301
1548
        self.assertEqual(
1302
1549
            smart_req.SmartServerResponse(('TokenMismatch',)), response)
1303
1550
        # Cleanup
1322
1569
            request.execute, 'subdir')
1323
1570
 
1324
1571
 
 
1572
class TestSmartServerRepositoryAddSignatureText(tests.TestCaseWithMemoryTransport):
 
1573
 
 
1574
    def test_add_text(self):
 
1575
        backing = self.get_transport()
 
1576
        request = smart_repo.SmartServerRepositoryAddSignatureText(backing)
 
1577
        tree = self.make_branch_and_memory_tree('.')
 
1578
        write_token = tree.lock_write()
 
1579
        self.addCleanup(tree.unlock)
 
1580
        tree.add('')
 
1581
        tree.commit("Message", rev_id='rev1')
 
1582
        tree.branch.repository.start_write_group()
 
1583
        write_group_tokens = tree.branch.repository.suspend_write_group()
 
1584
        self.assertEqual(None, request.execute('', write_token,
 
1585
            'rev1', *write_group_tokens))
 
1586
        response = request.do_body('somesignature')
 
1587
        self.assertTrue(response.is_successful())
 
1588
        self.assertEqual(response.args[0], 'ok')
 
1589
        write_group_tokens = response.args[1:]
 
1590
        tree.branch.repository.resume_write_group(write_group_tokens)
 
1591
        tree.branch.repository.commit_write_group()
 
1592
        tree.unlock()
 
1593
        self.assertEqual("somesignature",
 
1594
            tree.branch.repository.get_signature_text("rev1"))
 
1595
 
 
1596
 
 
1597
class TestSmartServerRepositoryAllRevisionIds(
 
1598
    tests.TestCaseWithMemoryTransport):
 
1599
 
 
1600
    def test_empty(self):
 
1601
        """An empty body should be returned for an empty repository."""
 
1602
        backing = self.get_transport()
 
1603
        request = smart_repo.SmartServerRepositoryAllRevisionIds(backing)
 
1604
        self.make_repository('.')
 
1605
        self.assertEqual(
 
1606
            smart_req.SuccessfulSmartServerResponse(("ok", ), ""),
 
1607
            request.execute(''))
 
1608
 
 
1609
    def test_some_revisions(self):
 
1610
        """An empty body should be returned for an empty repository."""
 
1611
        backing = self.get_transport()
 
1612
        request = smart_repo.SmartServerRepositoryAllRevisionIds(backing)
 
1613
        tree = self.make_branch_and_memory_tree('.')
 
1614
        tree.lock_write()
 
1615
        tree.add('')
 
1616
        tree.commit(rev_id='origineel', message="message")
 
1617
        tree.commit(rev_id='nog-een-revisie', message="message")
 
1618
        tree.unlock()
 
1619
        self.assertEqual(
 
1620
            smart_req.SuccessfulSmartServerResponse(("ok", ),
 
1621
                "origineel\nnog-een-revisie"),
 
1622
            request.execute(''))
 
1623
 
 
1624
 
 
1625
class TestSmartServerRepositoryBreakLock(tests.TestCaseWithMemoryTransport):
 
1626
 
 
1627
    def test_lock_to_break(self):
 
1628
        backing = self.get_transport()
 
1629
        request = smart_repo.SmartServerRepositoryBreakLock(backing)
 
1630
        tree = self.make_branch_and_memory_tree('.')
 
1631
        tree.branch.repository.lock_write()
 
1632
        self.assertEqual(
 
1633
            smart_req.SuccessfulSmartServerResponse(('ok', ), None),
 
1634
            request.execute(''))
 
1635
 
 
1636
    def test_nothing_to_break(self):
 
1637
        backing = self.get_transport()
 
1638
        request = smart_repo.SmartServerRepositoryBreakLock(backing)
 
1639
        tree = self.make_branch_and_memory_tree('.')
 
1640
        self.assertEqual(
 
1641
            smart_req.SuccessfulSmartServerResponse(('ok', ), None),
 
1642
            request.execute(''))
 
1643
 
 
1644
 
1325
1645
class TestSmartServerRepositoryGetParentMap(tests.TestCaseWithMemoryTransport):
1326
1646
 
1327
1647
    def test_trivial_bzipped(self):
1447
1767
            request.execute('stacked', 1, (3, r3)))
1448
1768
 
1449
1769
 
1450
 
class TestSmartServerRepositoryGetStream(tests.TestCaseWithMemoryTransport):
 
1770
class TestSmartServerRepositoryIterRevisions(
 
1771
    tests.TestCaseWithMemoryTransport):
 
1772
 
 
1773
    def test_basic(self):
 
1774
        backing = self.get_transport()
 
1775
        request = smart_repo.SmartServerRepositoryIterRevisions(backing)
 
1776
        tree = self.make_branch_and_memory_tree('.', format='2a')
 
1777
        tree.lock_write()
 
1778
        tree.add('')
 
1779
        tree.commit('1st commit', rev_id="rev1")
 
1780
        tree.commit('2nd commit', rev_id="rev2")
 
1781
        tree.unlock()
 
1782
 
 
1783
        self.assertIs(None, request.execute(''))
 
1784
        response = request.do_body("rev1\nrev2")
 
1785
        self.assertTrue(response.is_successful())
 
1786
        # Format 2a uses serializer format 10
 
1787
        self.assertEqual(response.args, ("ok", "10"))
 
1788
 
 
1789
        self.addCleanup(tree.branch.lock_read().unlock)
 
1790
        entries = [zlib.compress(record.get_bytes_as("fulltext")) for record in
 
1791
            tree.branch.repository.revisions.get_record_stream(
 
1792
            [("rev1", ), ("rev2", )], "unordered", True)]
 
1793
 
 
1794
        contents = "".join(response.body_stream)
 
1795
        self.assertTrue(contents in (
 
1796
            "".join([entries[0], entries[1]]),
 
1797
            "".join([entries[1], entries[0]])))
 
1798
 
 
1799
    def test_missing(self):
 
1800
        backing = self.get_transport()
 
1801
        request = smart_repo.SmartServerRepositoryIterRevisions(backing)
 
1802
        tree = self.make_branch_and_memory_tree('.', format='2a')
 
1803
 
 
1804
        self.assertIs(None, request.execute(''))
 
1805
        response = request.do_body("rev1\nrev2")
 
1806
        self.assertTrue(response.is_successful())
 
1807
        # Format 2a uses serializer format 10
 
1808
        self.assertEqual(response.args, ("ok", "10"))
 
1809
 
 
1810
        contents = "".join(response.body_stream)
 
1811
        self.assertEqual(contents, "")
 
1812
 
 
1813
 
 
1814
class GetStreamTestBase(tests.TestCaseWithMemoryTransport):
1451
1815
 
1452
1816
    def make_two_commit_repo(self):
1453
1817
        tree = self.make_branch_and_memory_tree('.')
1459
1823
        repo = tree.branch.repository
1460
1824
        return repo, r1, r2
1461
1825
 
 
1826
 
 
1827
class TestSmartServerRepositoryGetStream(GetStreamTestBase):
 
1828
 
1462
1829
    def test_ancestry_of(self):
1463
1830
        """The search argument may be a 'ancestry-of' some heads'."""
1464
1831
        backing = self.get_transport()
1485
1852
        stream_bytes = ''.join(response.body_stream)
1486
1853
        self.assertStartsWith(stream_bytes, 'Bazaar pack format 1')
1487
1854
 
 
1855
    def test_search_everything(self):
 
1856
        """A search of 'everything' returns a stream."""
 
1857
        backing = self.get_transport()
 
1858
        request = smart_repo.SmartServerRepositoryGetStream_1_19(backing)
 
1859
        repo, r1, r2 = self.make_two_commit_repo()
 
1860
        serialised_fetch_spec = 'everything'
 
1861
        request.execute('', repo._format.network_name())
 
1862
        response = request.do_body(serialised_fetch_spec)
 
1863
        self.assertEqual(('ok',), response.args)
 
1864
        stream_bytes = ''.join(response.body_stream)
 
1865
        self.assertStartsWith(stream_bytes, 'Bazaar pack format 1')
 
1866
 
1488
1867
 
1489
1868
class TestSmartServerRequestHasRevision(tests.TestCaseWithMemoryTransport):
1490
1869
 
1511
1890
            request.execute('', rev_id_utf8))
1512
1891
 
1513
1892
 
 
1893
class TestSmartServerRepositoryIterFilesBytes(tests.TestCaseWithTransport):
 
1894
 
 
1895
    def test_single(self):
 
1896
        backing = self.get_transport()
 
1897
        request = smart_repo.SmartServerRepositoryIterFilesBytes(backing)
 
1898
        t = self.make_branch_and_tree('.')
 
1899
        self.addCleanup(t.lock_write().unlock)
 
1900
        self.build_tree_contents([("file", "somecontents")])
 
1901
        t.add(["file"], ["thefileid"])
 
1902
        t.commit(rev_id='somerev', message="add file")
 
1903
        self.assertIs(None, request.execute(''))
 
1904
        response = request.do_body("thefileid\0somerev\n")
 
1905
        self.assertTrue(response.is_successful())
 
1906
        self.assertEqual(response.args, ("ok", ))
 
1907
        self.assertEqual("".join(response.body_stream),
 
1908
            "ok\x000\n" + zlib.compress("somecontents"))
 
1909
 
 
1910
    def test_missing(self):
 
1911
        backing = self.get_transport()
 
1912
        request = smart_repo.SmartServerRepositoryIterFilesBytes(backing)
 
1913
        t = self.make_branch_and_tree('.')
 
1914
        self.addCleanup(t.lock_write().unlock)
 
1915
        self.assertIs(None, request.execute(''))
 
1916
        response = request.do_body("thefileid\0revision\n")
 
1917
        self.assertTrue(response.is_successful())
 
1918
        self.assertEqual(response.args, ("ok", ))
 
1919
        self.assertEqual("".join(response.body_stream),
 
1920
            "absent\x00thefileid\x00revision\x000\n")
 
1921
 
 
1922
 
 
1923
class TestSmartServerRequestHasSignatureForRevisionId(
 
1924
        tests.TestCaseWithMemoryTransport):
 
1925
 
 
1926
    def test_missing_revision(self):
 
1927
        """For a missing revision, NoSuchRevision is returned."""
 
1928
        backing = self.get_transport()
 
1929
        request = smart_repo.SmartServerRequestHasSignatureForRevisionId(
 
1930
            backing)
 
1931
        self.make_repository('.')
 
1932
        self.assertEqual(
 
1933
            smart_req.FailedSmartServerResponse(
 
1934
                ('nosuchrevision', 'revid'), None),
 
1935
            request.execute('', 'revid'))
 
1936
 
 
1937
    def test_missing_signature(self):
 
1938
        """For a missing signature, ('no', ) is returned."""
 
1939
        backing = self.get_transport()
 
1940
        request = smart_repo.SmartServerRequestHasSignatureForRevisionId(
 
1941
            backing)
 
1942
        tree = self.make_branch_and_memory_tree('.')
 
1943
        tree.lock_write()
 
1944
        tree.add('')
 
1945
        r1 = tree.commit('a commit', rev_id='A')
 
1946
        tree.unlock()
 
1947
        self.assertTrue(tree.branch.repository.has_revision('A'))
 
1948
        self.assertEqual(smart_req.SmartServerResponse(('no', )),
 
1949
            request.execute('', 'A'))
 
1950
 
 
1951
    def test_present_signature(self):
 
1952
        """For a present signature, ('yes', ) is returned."""
 
1953
        backing = self.get_transport()
 
1954
        request = smart_repo.SmartServerRequestHasSignatureForRevisionId(
 
1955
            backing)
 
1956
        strategy = gpg.LoopbackGPGStrategy(None)
 
1957
        tree = self.make_branch_and_memory_tree('.')
 
1958
        tree.lock_write()
 
1959
        tree.add('')
 
1960
        r1 = tree.commit('a commit', rev_id='A')
 
1961
        tree.branch.repository.start_write_group()
 
1962
        tree.branch.repository.sign_revision('A', strategy)
 
1963
        tree.branch.repository.commit_write_group()
 
1964
        tree.unlock()
 
1965
        self.assertTrue(tree.branch.repository.has_revision('A'))
 
1966
        self.assertEqual(smart_req.SmartServerResponse(('yes', )),
 
1967
            request.execute('', 'A'))
 
1968
 
 
1969
 
1514
1970
class TestSmartServerRepositoryGatherStats(tests.TestCaseWithMemoryTransport):
1515
1971
 
1516
1972
    def test_empty_revid(self):
1569
2025
                         request.execute('',
1570
2026
                                         rev_id_utf8, 'yes'))
1571
2027
 
 
2028
    def test_unknown_revid(self):
 
2029
        """An unknown revision id causes a 'nosuchrevision' error."""
 
2030
        backing = self.get_transport()
 
2031
        request = smart_repo.SmartServerRepositoryGatherStats(backing)
 
2032
        repository = self.make_repository('.')
 
2033
        expected_body = 'revisions: 0\n'
 
2034
        self.assertEqual(
 
2035
            smart_req.FailedSmartServerResponse(
 
2036
                ('nosuchrevision', 'mia'), None),
 
2037
            request.execute('', 'mia', 'yes'))
 
2038
 
1572
2039
 
1573
2040
class TestSmartServerRepositoryIsShared(tests.TestCaseWithMemoryTransport):
1574
2041
 
1589
2056
            request.execute('', ))
1590
2057
 
1591
2058
 
 
2059
class TestSmartServerRepositoryGetRevisionSignatureText(
 
2060
        tests.TestCaseWithMemoryTransport):
 
2061
 
 
2062
    def test_get_signature(self):
 
2063
        backing = self.get_transport()
 
2064
        request = smart_repo.SmartServerRepositoryGetRevisionSignatureText(
 
2065
            backing)
 
2066
        bb = self.make_branch_builder('.')
 
2067
        bb.build_commit(rev_id='A')
 
2068
        repo = bb.get_branch().repository
 
2069
        strategy = gpg.LoopbackGPGStrategy(None)
 
2070
        self.addCleanup(repo.lock_write().unlock)
 
2071
        repo.start_write_group()
 
2072
        repo.sign_revision('A', strategy)
 
2073
        repo.commit_write_group()
 
2074
        expected_body = (
 
2075
            '-----BEGIN PSEUDO-SIGNED CONTENT-----\n' +
 
2076
            Testament.from_revision(repo, 'A').as_short_text() +
 
2077
            '-----END PSEUDO-SIGNED CONTENT-----\n')
 
2078
        self.assertEqual(
 
2079
            smart_req.SmartServerResponse(('ok', ), expected_body),
 
2080
            request.execute('', 'A'))
 
2081
 
 
2082
 
 
2083
class TestSmartServerRepositoryMakeWorkingTrees(
 
2084
        tests.TestCaseWithMemoryTransport):
 
2085
 
 
2086
    def test_make_working_trees(self):
 
2087
        """For a repository with working trees, ('yes', ) is returned."""
 
2088
        backing = self.get_transport()
 
2089
        request = smart_repo.SmartServerRepositoryMakeWorkingTrees(backing)
 
2090
        r = self.make_repository('.')
 
2091
        r.set_make_working_trees(True)
 
2092
        self.assertEqual(smart_req.SmartServerResponse(('yes', )),
 
2093
            request.execute('', ))
 
2094
 
 
2095
    def test_is_not_shared(self):
 
2096
        """For a repository with working trees, ('no', ) is returned."""
 
2097
        backing = self.get_transport()
 
2098
        request = smart_repo.SmartServerRepositoryMakeWorkingTrees(backing)
 
2099
        r = self.make_repository('.')
 
2100
        r.set_make_working_trees(False)
 
2101
        self.assertEqual(smart_req.SmartServerResponse(('no', )),
 
2102
            request.execute('', ))
 
2103
 
 
2104
 
1592
2105
class TestSmartServerRepositoryLockWrite(tests.TestCaseWithMemoryTransport):
1593
2106
 
1594
2107
    def test_lock_write_on_unlocked_repo(self):
1610
2123
        backing = self.get_transport()
1611
2124
        request = smart_repo.SmartServerRepositoryLockWrite(backing)
1612
2125
        repository = self.make_repository('.', format='knit')
1613
 
        repo_token = repository.lock_write()
 
2126
        repo_token = repository.lock_write().repository_token
1614
2127
        repository.leave_lock_in_place()
1615
2128
        repository.unlock()
1616
2129
        response = request.execute('')
1658
2171
        request = smart_repo.SmartServerRepositoryInsertStreamLocked(
1659
2172
            backing)
1660
2173
        repository = self.make_repository('.', format='knit')
1661
 
        lock_token = repository.lock_write()
 
2174
        lock_token = repository.lock_write().repository_token
1662
2175
        response = request.execute('', '', lock_token)
1663
2176
        self.assertEqual(None, response)
1664
2177
        response = request.do_chunk(self.make_empty_byte_stream(repository))
1672
2185
        request = smart_repo.SmartServerRepositoryInsertStreamLocked(
1673
2186
            backing)
1674
2187
        repository = self.make_repository('.', format='knit')
1675
 
        lock_token = repository.lock_write()
 
2188
        lock_token = repository.lock_write().repository_token
1676
2189
        self.assertRaises(
1677
2190
            errors.TokenMismatch, request.execute, '', '', 'wrong-token')
1678
2191
        repository.unlock()
1680
2193
 
1681
2194
class TestSmartServerRepositoryUnlock(tests.TestCaseWithMemoryTransport):
1682
2195
 
1683
 
    def setUp(self):
1684
 
        tests.TestCaseWithMemoryTransport.setUp(self)
1685
 
 
1686
2196
    def test_unlock_on_locked_repo(self):
1687
2197
        backing = self.get_transport()
1688
2198
        request = smart_repo.SmartServerRepositoryUnlock(backing)
1689
2199
        repository = self.make_repository('.', format='knit')
1690
 
        token = repository.lock_write()
 
2200
        token = repository.lock_write().repository_token
1691
2201
        repository.leave_lock_in_place()
1692
2202
        repository.unlock()
1693
2203
        response = request.execute('', token)
1708
2218
            smart_req.SmartServerResponse(('TokenMismatch',)), response)
1709
2219
 
1710
2220
 
 
2221
class TestSmartServerRepositoryGetPhysicalLockStatus(
 
2222
    tests.TestCaseWithTransport):
 
2223
 
 
2224
    def test_with_write_lock(self):
 
2225
        backing = self.get_transport()
 
2226
        repo = self.make_repository('.')
 
2227
        self.addCleanup(repo.lock_write().unlock)
 
2228
        # lock_write() doesn't necessarily actually take a physical
 
2229
        # lock out.
 
2230
        if repo.get_physical_lock_status():
 
2231
            expected = 'yes'
 
2232
        else:
 
2233
            expected = 'no'
 
2234
        request_class = smart_repo.SmartServerRepositoryGetPhysicalLockStatus
 
2235
        request = request_class(backing)
 
2236
        self.assertEqual(smart_req.SuccessfulSmartServerResponse((expected,)),
 
2237
            request.execute('', ))
 
2238
 
 
2239
    def test_without_write_lock(self):
 
2240
        backing = self.get_transport()
 
2241
        repo = self.make_repository('.')
 
2242
        self.assertEqual(False, repo.get_physical_lock_status())
 
2243
        request_class = smart_repo.SmartServerRepositoryGetPhysicalLockStatus
 
2244
        request = request_class(backing)
 
2245
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(('no',)),
 
2246
            request.execute('', ))
 
2247
 
 
2248
 
 
2249
class TestSmartServerRepositoryReconcile(tests.TestCaseWithTransport):
 
2250
 
 
2251
    def test_reconcile(self):
 
2252
        backing = self.get_transport()
 
2253
        repo = self.make_repository('.')
 
2254
        token = repo.lock_write().repository_token
 
2255
        self.addCleanup(repo.unlock)
 
2256
        request_class = smart_repo.SmartServerRepositoryReconcile
 
2257
        request = request_class(backing)
 
2258
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(
 
2259
            ('ok', ),
 
2260
             'garbage_inventories: 0\n'
 
2261
             'inconsistent_parents: 0\n'),
 
2262
            request.execute('', token))
 
2263
 
 
2264
 
1711
2265
class TestSmartServerIsReadonly(tests.TestCaseWithMemoryTransport):
1712
2266
 
1713
2267
    def test_is_readonly_no(self):
1751
2305
        self.assertTrue(repo.make_working_trees())
1752
2306
 
1753
2307
 
 
2308
class TestSmartServerRepositoryGetSerializerFormat(
 
2309
    tests.TestCaseWithMemoryTransport):
 
2310
 
 
2311
    def test_get_serializer_format(self):
 
2312
        backing = self.get_transport()
 
2313
        repo = self.make_repository('.', format='2a')
 
2314
        request_class = smart_repo.SmartServerRepositoryGetSerializerFormat
 
2315
        request = request_class(backing)
 
2316
        self.assertEqual(
 
2317
            smart_req.SuccessfulSmartServerResponse(('ok', '10')),
 
2318
            request.execute(''))
 
2319
 
 
2320
 
 
2321
class TestSmartServerRepositoryWriteGroup(
 
2322
    tests.TestCaseWithMemoryTransport):
 
2323
 
 
2324
    def test_start_write_group(self):
 
2325
        backing = self.get_transport()
 
2326
        repo = self.make_repository('.')
 
2327
        lock_token = repo.lock_write().repository_token
 
2328
        self.addCleanup(repo.unlock)
 
2329
        request_class = smart_repo.SmartServerRepositoryStartWriteGroup
 
2330
        request = request_class(backing)
 
2331
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(('ok', [])),
 
2332
            request.execute('', lock_token))
 
2333
 
 
2334
    def test_start_write_group_unsuspendable(self):
 
2335
        backing = self.get_transport()
 
2336
        repo = self.make_repository('.', format='knit')
 
2337
        lock_token = repo.lock_write().repository_token
 
2338
        self.addCleanup(repo.unlock)
 
2339
        request_class = smart_repo.SmartServerRepositoryStartWriteGroup
 
2340
        request = request_class(backing)
 
2341
        self.assertEqual(
 
2342
            smart_req.FailedSmartServerResponse(('UnsuspendableWriteGroup',)),
 
2343
            request.execute('', lock_token))
 
2344
 
 
2345
    def test_commit_write_group(self):
 
2346
        backing = self.get_transport()
 
2347
        repo = self.make_repository('.')
 
2348
        lock_token = repo.lock_write().repository_token
 
2349
        self.addCleanup(repo.unlock)
 
2350
        repo.start_write_group()
 
2351
        tokens = repo.suspend_write_group()
 
2352
        request_class = smart_repo.SmartServerRepositoryCommitWriteGroup
 
2353
        request = request_class(backing)
 
2354
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(('ok',)),
 
2355
            request.execute('', lock_token, tokens))
 
2356
 
 
2357
    def test_abort_write_group(self):
 
2358
        backing = self.get_transport()
 
2359
        repo = self.make_repository('.')
 
2360
        lock_token = repo.lock_write().repository_token
 
2361
        repo.start_write_group()
 
2362
        tokens = repo.suspend_write_group()
 
2363
        self.addCleanup(repo.unlock)
 
2364
        request_class = smart_repo.SmartServerRepositoryAbortWriteGroup
 
2365
        request = request_class(backing)
 
2366
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(('ok',)),
 
2367
            request.execute('', lock_token, tokens))
 
2368
 
 
2369
    def test_check_write_group(self):
 
2370
        backing = self.get_transport()
 
2371
        repo = self.make_repository('.')
 
2372
        lock_token = repo.lock_write().repository_token
 
2373
        repo.start_write_group()
 
2374
        tokens = repo.suspend_write_group()
 
2375
        self.addCleanup(repo.unlock)
 
2376
        request_class = smart_repo.SmartServerRepositoryCheckWriteGroup
 
2377
        request = request_class(backing)
 
2378
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(('ok',)),
 
2379
            request.execute('', lock_token, tokens))
 
2380
 
 
2381
    def test_check_write_group_invalid(self):
 
2382
        backing = self.get_transport()
 
2383
        repo = self.make_repository('.')
 
2384
        lock_token = repo.lock_write().repository_token
 
2385
        self.addCleanup(repo.unlock)
 
2386
        request_class = smart_repo.SmartServerRepositoryCheckWriteGroup
 
2387
        request = request_class(backing)
 
2388
        self.assertEqual(smart_req.FailedSmartServerResponse(
 
2389
            ('UnresumableWriteGroup', ['random'],
 
2390
                'Malformed write group token')),
 
2391
            request.execute('', lock_token, ["random"]))
 
2392
 
 
2393
 
1754
2394
class TestSmartServerPackRepositoryAutopack(tests.TestCaseWithTransport):
1755
2395
 
1756
2396
    def make_repo_needing_autopacking(self, path='.'):
1822
2462
        """All registered request_handlers can be found."""
1823
2463
        # If there's a typo in a register_lazy call, this loop will fail with
1824
2464
        # an AttributeError.
1825
 
        for key, item in smart_req.request_handlers.iteritems():
1826
 
            pass
 
2465
        for key in smart_req.request_handlers.keys():
 
2466
            try:
 
2467
                item = smart_req.request_handlers.get(key)
 
2468
            except AttributeError as e:
 
2469
                raise AttributeError('failed to get %s: %s' % (key, e))
1827
2470
 
1828
2471
    def assertHandlerEqual(self, verb, handler):
1829
2472
        self.assertEqual(smart_req.request_handlers.get(verb), handler)
1830
2473
 
1831
2474
    def test_registered_methods(self):
1832
2475
        """Test that known methods are registered to the correct object."""
 
2476
        self.assertHandlerEqual('Branch.break_lock',
 
2477
            smart_branch.SmartServerBranchBreakLock)
1833
2478
        self.assertHandlerEqual('Branch.get_config_file',
1834
2479
            smart_branch.SmartServerBranchGetConfigFile)
 
2480
        self.assertHandlerEqual('Branch.put_config_file',
 
2481
            smart_branch.SmartServerBranchPutConfigFile)
1835
2482
        self.assertHandlerEqual('Branch.get_parent',
1836
2483
            smart_branch.SmartServerBranchGetParent)
 
2484
        self.assertHandlerEqual('Branch.get_physical_lock_status',
 
2485
            smart_branch.SmartServerBranchRequestGetPhysicalLockStatus)
1837
2486
        self.assertHandlerEqual('Branch.get_tags_bytes',
1838
2487
            smart_branch.SmartServerBranchGetTagsBytes)
1839
2488
        self.assertHandlerEqual('Branch.lock_write',
1842
2491
            smart_branch.SmartServerBranchRequestLastRevisionInfo)
1843
2492
        self.assertHandlerEqual('Branch.revision_history',
1844
2493
            smart_branch.SmartServerRequestRevisionHistory)
 
2494
        self.assertHandlerEqual('Branch.revision_id_to_revno',
 
2495
            smart_branch.SmartServerBranchRequestRevisionIdToRevno)
1845
2496
        self.assertHandlerEqual('Branch.set_config_option',
1846
2497
            smart_branch.SmartServerBranchRequestSetConfigOption)
1847
2498
        self.assertHandlerEqual('Branch.set_last_revision',
1854
2505
            smart_branch.SmartServerBranchRequestSetParentLocation)
1855
2506
        self.assertHandlerEqual('Branch.unlock',
1856
2507
            smart_branch.SmartServerBranchRequestUnlock)
 
2508
        self.assertHandlerEqual('BzrDir.destroy_branch',
 
2509
            smart_dir.SmartServerBzrDirRequestDestroyBranch)
1857
2510
        self.assertHandlerEqual('BzrDir.find_repository',
1858
2511
            smart_dir.SmartServerRequestFindRepositoryV1)
1859
2512
        self.assertHandlerEqual('BzrDir.find_repositoryV2',
1862
2515
            smart_dir.SmartServerRequestInitializeBzrDir)
1863
2516
        self.assertHandlerEqual('BzrDirFormat.initialize_ex_1.16',
1864
2517
            smart_dir.SmartServerRequestBzrDirInitializeEx)
 
2518
        self.assertHandlerEqual('BzrDir.checkout_metadir',
 
2519
            smart_dir.SmartServerBzrDirRequestCheckoutMetaDir)
1865
2520
        self.assertHandlerEqual('BzrDir.cloning_metadir',
1866
2521
            smart_dir.SmartServerBzrDirRequestCloningMetaDir)
 
2522
        self.assertHandlerEqual('BzrDir.get_branches',
 
2523
            smart_dir.SmartServerBzrDirRequestGetBranches)
1867
2524
        self.assertHandlerEqual('BzrDir.get_config_file',
1868
2525
            smart_dir.SmartServerBzrDirRequestConfigFile)
1869
2526
        self.assertHandlerEqual('BzrDir.open_branch',
1874
2531
            smart_dir.SmartServerRequestOpenBranchV3)
1875
2532
        self.assertHandlerEqual('PackRepository.autopack',
1876
2533
            smart_packrepo.SmartServerPackRepositoryAutopack)
 
2534
        self.assertHandlerEqual('Repository.add_signature_text',
 
2535
            smart_repo.SmartServerRepositoryAddSignatureText)
 
2536
        self.assertHandlerEqual('Repository.all_revision_ids',
 
2537
            smart_repo.SmartServerRepositoryAllRevisionIds)
 
2538
        self.assertHandlerEqual('Repository.break_lock',
 
2539
            smart_repo.SmartServerRepositoryBreakLock)
1877
2540
        self.assertHandlerEqual('Repository.gather_stats',
1878
2541
            smart_repo.SmartServerRepositoryGatherStats)
1879
2542
        self.assertHandlerEqual('Repository.get_parent_map',
1880
2543
            smart_repo.SmartServerRepositoryGetParentMap)
 
2544
        self.assertHandlerEqual('Repository.get_physical_lock_status',
 
2545
            smart_repo.SmartServerRepositoryGetPhysicalLockStatus)
1881
2546
        self.assertHandlerEqual('Repository.get_rev_id_for_revno',
1882
2547
            smart_repo.SmartServerRepositoryGetRevIdForRevno)
1883
2548
        self.assertHandlerEqual('Repository.get_revision_graph',
1884
2549
            smart_repo.SmartServerRepositoryGetRevisionGraph)
 
2550
        self.assertHandlerEqual('Repository.get_revision_signature_text',
 
2551
            smart_repo.SmartServerRepositoryGetRevisionSignatureText)
1885
2552
        self.assertHandlerEqual('Repository.get_stream',
1886
2553
            smart_repo.SmartServerRepositoryGetStream)
 
2554
        self.assertHandlerEqual('Repository.get_stream_1.19',
 
2555
            smart_repo.SmartServerRepositoryGetStream_1_19)
 
2556
        self.assertHandlerEqual('Repository.iter_revisions',
 
2557
            smart_repo.SmartServerRepositoryIterRevisions)
1887
2558
        self.assertHandlerEqual('Repository.has_revision',
1888
2559
            smart_repo.SmartServerRequestHasRevision)
1889
2560
        self.assertHandlerEqual('Repository.insert_stream',
1892
2563
            smart_repo.SmartServerRepositoryInsertStreamLocked)
1893
2564
        self.assertHandlerEqual('Repository.is_shared',
1894
2565
            smart_repo.SmartServerRepositoryIsShared)
 
2566
        self.assertHandlerEqual('Repository.iter_files_bytes',
 
2567
            smart_repo.SmartServerRepositoryIterFilesBytes)
1895
2568
        self.assertHandlerEqual('Repository.lock_write',
1896
2569
            smart_repo.SmartServerRepositoryLockWrite)
 
2570
        self.assertHandlerEqual('Repository.make_working_trees',
 
2571
            smart_repo.SmartServerRepositoryMakeWorkingTrees)
 
2572
        self.assertHandlerEqual('Repository.pack',
 
2573
            smart_repo.SmartServerRepositoryPack)
 
2574
        self.assertHandlerEqual('Repository.reconcile',
 
2575
            smart_repo.SmartServerRepositoryReconcile)
1897
2576
        self.assertHandlerEqual('Repository.tarball',
1898
2577
            smart_repo.SmartServerRepositoryTarball)
1899
2578
        self.assertHandlerEqual('Repository.unlock',
1900
2579
            smart_repo.SmartServerRepositoryUnlock)
 
2580
        self.assertHandlerEqual('Repository.start_write_group',
 
2581
            smart_repo.SmartServerRepositoryStartWriteGroup)
 
2582
        self.assertHandlerEqual('Repository.check_write_group',
 
2583
            smart_repo.SmartServerRepositoryCheckWriteGroup)
 
2584
        self.assertHandlerEqual('Repository.commit_write_group',
 
2585
            smart_repo.SmartServerRepositoryCommitWriteGroup)
 
2586
        self.assertHandlerEqual('Repository.abort_write_group',
 
2587
            smart_repo.SmartServerRepositoryAbortWriteGroup)
 
2588
        self.assertHandlerEqual('VersionedFileRepository.get_serializer_format',
 
2589
            smart_repo.SmartServerRepositoryGetSerializerFormat)
 
2590
        self.assertHandlerEqual('VersionedFileRepository.get_inventories',
 
2591
            smart_repo.SmartServerRepositoryGetInventories)
1901
2592
        self.assertHandlerEqual('Transport.is_readonly',
1902
2593
            smart_req.SmartServerIsReadonly)
 
2594
 
 
2595
 
 
2596
class SmartTCPServerHookTests(tests.TestCaseWithMemoryTransport):
 
2597
    """Tests for SmartTCPServer hooks."""
 
2598
 
 
2599
    def setUp(self):
 
2600
        super(SmartTCPServerHookTests, self).setUp()
 
2601
        self.server = server.SmartTCPServer(self.get_transport())
 
2602
 
 
2603
    def test_run_server_started_hooks(self):
 
2604
        """Test the server started hooks get fired properly."""
 
2605
        started_calls = []
 
2606
        server.SmartTCPServer.hooks.install_named_hook('server_started',
 
2607
            lambda backing_urls, url: started_calls.append((backing_urls, url)),
 
2608
            None)
 
2609
        started_ex_calls = []
 
2610
        server.SmartTCPServer.hooks.install_named_hook('server_started_ex',
 
2611
            lambda backing_urls, url: started_ex_calls.append((backing_urls, url)),
 
2612
            None)
 
2613
        self.server._sockname = ('example.com', 42)
 
2614
        self.server.run_server_started_hooks()
 
2615
        self.assertEqual(started_calls,
 
2616
            [([self.get_transport().base], 'bzr://example.com:42/')])
 
2617
        self.assertEqual(started_ex_calls,
 
2618
            [([self.get_transport().base], self.server)])
 
2619
 
 
2620
    def test_run_server_started_hooks_ipv6(self):
 
2621
        """Test that socknames can contain 4-tuples."""
 
2622
        self.server._sockname = ('::', 42, 0, 0)
 
2623
        started_calls = []
 
2624
        server.SmartTCPServer.hooks.install_named_hook('server_started',
 
2625
            lambda backing_urls, url: started_calls.append((backing_urls, url)),
 
2626
            None)
 
2627
        self.server.run_server_started_hooks()
 
2628
        self.assertEqual(started_calls,
 
2629
                [([self.get_transport().base], 'bzr://:::42/')])
 
2630
 
 
2631
    def test_run_server_stopped_hooks(self):
 
2632
        """Test the server stopped hooks."""
 
2633
        self.server._sockname = ('example.com', 42)
 
2634
        stopped_calls = []
 
2635
        server.SmartTCPServer.hooks.install_named_hook('server_stopped',
 
2636
            lambda backing_urls, url: stopped_calls.append((backing_urls, url)),
 
2637
            None)
 
2638
        self.server.run_server_stopped_hooks()
 
2639
        self.assertEqual(stopped_calls,
 
2640
            [([self.get_transport().base], 'bzr://example.com:42/')])
 
2641
 
 
2642
 
 
2643
class TestSmartServerRepositoryPack(tests.TestCaseWithMemoryTransport):
 
2644
 
 
2645
    def test_pack(self):
 
2646
        backing = self.get_transport()
 
2647
        request = smart_repo.SmartServerRepositoryPack(backing)
 
2648
        tree = self.make_branch_and_memory_tree('.')
 
2649
        repo_token = tree.branch.repository.lock_write().repository_token
 
2650
 
 
2651
        self.assertIs(None, request.execute('', repo_token, False))
 
2652
 
 
2653
        self.assertEqual(
 
2654
            smart_req.SuccessfulSmartServerResponse(('ok', ), ),
 
2655
            request.do_body(''))
 
2656
 
 
2657
 
 
2658
class TestSmartServerRepositoryGetInventories(tests.TestCaseWithTransport):
 
2659
 
 
2660
    def _get_serialized_inventory_delta(self, repository, base_revid, revid):
 
2661
        base_inv = repository.revision_tree(base_revid).root_inventory
 
2662
        inv = repository.revision_tree(revid).root_inventory
 
2663
        inv_delta = inv._make_delta(base_inv)
 
2664
        serializer = inventory_delta.InventoryDeltaSerializer(True, False)
 
2665
        return "".join(serializer.delta_to_lines(base_revid, revid, inv_delta))
 
2666
 
 
2667
    def test_single(self):
 
2668
        backing = self.get_transport()
 
2669
        request = smart_repo.SmartServerRepositoryGetInventories(backing)
 
2670
        t = self.make_branch_and_tree('.', format='2a')
 
2671
        self.addCleanup(t.lock_write().unlock)
 
2672
        self.build_tree_contents([("file", "somecontents")])
 
2673
        t.add(["file"], ["thefileid"])
 
2674
        t.commit(rev_id='somerev', message="add file")
 
2675
        self.assertIs(None, request.execute('', 'unordered'))
 
2676
        response = request.do_body("somerev\n")
 
2677
        self.assertTrue(response.is_successful())
 
2678
        self.assertEqual(response.args, ("ok", ))
 
2679
        stream = [('inventory-deltas', [
 
2680
            versionedfile.FulltextContentFactory('somerev', None, None,
 
2681
                self._get_serialized_inventory_delta(
 
2682
                    t.branch.repository, 'null:', 'somerev'))])]
 
2683
        fmt = controldir.format_registry.get('2a')().repository_format
 
2684
        self.assertEqual(
 
2685
            "".join(response.body_stream),
 
2686
            "".join(smart_repo._stream_to_byte_stream(stream, fmt)))
 
2687
 
 
2688
    def test_empty(self):
 
2689
        backing = self.get_transport()
 
2690
        request = smart_repo.SmartServerRepositoryGetInventories(backing)
 
2691
        t = self.make_branch_and_tree('.', format='2a')
 
2692
        self.addCleanup(t.lock_write().unlock)
 
2693
        self.build_tree_contents([("file", "somecontents")])
 
2694
        t.add(["file"], ["thefileid"])
 
2695
        t.commit(rev_id='somerev', message="add file")
 
2696
        self.assertIs(None, request.execute('', 'unordered'))
 
2697
        response = request.do_body("")
 
2698
        self.assertTrue(response.is_successful())
 
2699
        self.assertEqual(response.args, ("ok", ))
 
2700
        self.assertEqual("".join(response.body_stream),
 
2701
            "Bazaar pack format 1 (introduced in 0.18)\nB54\n\nBazaar repository format 2a (needs bzr 1.16 or later)\nE")