~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_smart.py

  • Committer: Martin Pool
  • Date: 2010-02-25 06:17:27 UTC
  • mfrom: (5055 +trunk)
  • mto: This revision was merged to the branch mainline in revision 5057.
  • Revision ID: mbp@sourcefrog.net-20100225061727-4sd9lt0qmdc6087t
merge news

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2006-2011 Canonical Ltd
 
1
# Copyright (C) 2006-2010 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
25
25
"""
26
26
 
27
27
import bz2
 
28
from cStringIO import StringIO
 
29
import tarfile
28
30
 
29
31
from bzrlib import (
 
32
    bencode,
30
33
    branch as _mod_branch,
31
34
    bzrdir,
32
35
    errors,
 
36
    pack,
33
37
    tests,
34
38
    transport,
35
39
    urlutils,
85
89
            backing_transport = tests.TestCaseWithTransport.get_transport(self)
86
90
            self._chroot_server = chroot.ChrootServer(backing_transport)
87
91
            self.start_server(self._chroot_server)
88
 
        t = transport.get_transport_from_url(self._chroot_server.get_url())
 
92
        t = transport.get_transport(self._chroot_server.get_url())
89
93
        if relpath is not None:
90
94
            t = t.clone(relpath)
91
95
        return t
99
103
        # the default or a parameterized class, but rather use the
100
104
        # TestCaseWithTransport infrastructure to set up a smart server and
101
105
        # transport.
102
 
        self.overrideAttr(self, "transport_server", self.make_transport_server)
 
106
        self.transport_server = self.make_transport_server
103
107
 
104
108
    def make_transport_server(self):
105
109
        return test_server.SmartTCPServer_for_testing('-' + self.id())
210
214
        dir = self.make_bzrdir('.')
211
215
        local_result = dir.cloning_metadir()
212
216
        reference = _mod_branch.BranchReferenceFormat().initialize(
213
 
            dir, target_branch=referenced_branch)
 
217
            dir, referenced_branch)
214
218
        reference_url = _mod_branch.BranchReferenceFormat().get_reference(dir)
215
219
        # The server shouldn't try to follow the branch reference, so it's fine
216
220
        # if the referenced branch isn't reachable.
763
767
class TestLockedBranch(tests.TestCaseWithMemoryTransport):
764
768
 
765
769
    def get_lock_tokens(self, branch):
766
 
        branch_token = branch.lock_write().branch_token
767
 
        repo_token = branch.repository.lock_write().repository_token
 
770
        branch_token = branch.lock_write()
 
771
        repo_token = branch.repository.lock_write()
768
772
        branch.repository.unlock()
769
773
        return branch_token, repo_token
770
774
 
798
802
        branch.unlock()
799
803
 
800
804
 
801
 
class TestSmartServerBranchRequestSetConfigOptionDict(TestLockedBranch):
802
 
 
803
 
    def setUp(self):
804
 
        TestLockedBranch.setUp(self)
805
 
        # A dict with non-ascii keys and values to exercise unicode
806
 
        # roundtripping.
807
 
        self.encoded_value_dict = (
808
 
            'd5:ascii1:a11:unicode \xe2\x8c\x9a3:\xe2\x80\xbde')
809
 
        self.value_dict = {
810
 
            'ascii': 'a', u'unicode \N{WATCH}': u'\N{INTERROBANG}'}
811
 
 
812
 
    def test_value_name(self):
813
 
        branch = self.make_branch('.')
814
 
        request = smart_branch.SmartServerBranchRequestSetConfigOptionDict(
815
 
            branch.bzrdir.root_transport)
816
 
        branch_token, repo_token = self.get_lock_tokens(branch)
817
 
        config = branch._get_config()
818
 
        result = request.execute('', branch_token, repo_token,
819
 
            self.encoded_value_dict, 'foo', '')
820
 
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(()), result)
821
 
        self.assertEqual(self.value_dict, config.get_option('foo'))
822
 
        # Cleanup
823
 
        branch.unlock()
824
 
 
825
 
    def test_value_name_section(self):
826
 
        branch = self.make_branch('.')
827
 
        request = smart_branch.SmartServerBranchRequestSetConfigOptionDict(
828
 
            branch.bzrdir.root_transport)
829
 
        branch_token, repo_token = self.get_lock_tokens(branch)
830
 
        config = branch._get_config()
831
 
        result = request.execute('', branch_token, repo_token,
832
 
            self.encoded_value_dict, 'foo', 'gam')
833
 
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(()), result)
834
 
        self.assertEqual(self.value_dict, config.get_option('foo', 'gam'))
835
 
        # Cleanup
836
 
        branch.unlock()
837
 
 
838
 
 
839
805
class TestSmartServerBranchRequestSetTagsBytes(TestLockedBranch):
840
806
    # Only called when the branch format and tags match [yay factory
841
807
    # methods] so only need to test straight forward cases.
932
898
        # its repository.
933
899
        self.make_tree_with_two_commits()
934
900
        rev_id_utf8 = u'\xc8'.encode('utf-8')
935
 
        self.tree.branch.set_last_revision_info(0, 'null:')
 
901
        self.tree.branch.set_revision_history([])
936
902
        self.assertEqual(
937
903
            (0, 'null:'), self.tree.branch.last_revision_info())
938
904
        # We can update the branch to a revision that is present in the
1107
1073
            response)
1108
1074
 
1109
1075
 
1110
 
class TestSmartServerBranchRequestSetParent(TestLockedBranch):
 
1076
class TestSmartServerBranchRequestSetParent(tests.TestCaseWithMemoryTransport):
1111
1077
 
1112
1078
    def test_set_parent_none(self):
1113
1079
        branch = self.make_branch('base', format="1.9")
1116
1082
        branch.unlock()
1117
1083
        request = smart_branch.SmartServerBranchRequestSetParentLocation(
1118
1084
            self.get_transport())
1119
 
        branch_token, repo_token = self.get_lock_tokens(branch)
 
1085
        branch_token = branch.lock_write()
 
1086
        repo_token = branch.repository.lock_write()
1120
1087
        try:
1121
1088
            response = request.execute('base', branch_token, repo_token, '')
1122
1089
        finally:
 
1090
            branch.repository.unlock()
1123
1091
            branch.unlock()
1124
1092
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(()), response)
1125
1093
        self.assertEqual(None, branch.get_parent())
1128
1096
        branch = self.make_branch('base', format="1.9")
1129
1097
        request = smart_branch.SmartServerBranchRequestSetParentLocation(
1130
1098
            self.get_transport())
1131
 
        branch_token, repo_token = self.get_lock_tokens(branch)
 
1099
        branch_token = branch.lock_write()
 
1100
        repo_token = branch.repository.lock_write()
1132
1101
        try:
1133
1102
            response = request.execute('base', branch_token, repo_token,
1134
1103
            'http://bar/')
1135
1104
        finally:
 
1105
            branch.repository.unlock()
1136
1106
            branch.unlock()
1137
1107
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(()), response)
1138
1108
        self.assertEqual('http://bar/', branch.get_parent())
1167
1137
            response)
1168
1138
 
1169
1139
 
1170
 
class TestSmartServerBranchRequestLockWrite(TestLockedBranch):
 
1140
class TestSmartServerBranchRequestLockWrite(tests.TestCaseWithMemoryTransport):
1171
1141
 
1172
1142
    def setUp(self):
1173
1143
        tests.TestCaseWithMemoryTransport.setUp(self)
1195
1165
        backing = self.get_transport()
1196
1166
        request = smart_branch.SmartServerBranchRequestLockWrite(backing)
1197
1167
        branch = self.make_branch('.')
1198
 
        branch_token = branch.lock_write().branch_token
 
1168
        branch_token = branch.lock_write()
1199
1169
        branch.leave_lock_in_place()
1200
1170
        branch.unlock()
1201
1171
        response = request.execute('')
1210
1180
        backing = self.get_transport()
1211
1181
        request = smart_branch.SmartServerBranchRequestLockWrite(backing)
1212
1182
        branch = self.make_branch('.', format='knit')
1213
 
        branch_token, repo_token = self.get_lock_tokens(branch)
 
1183
        branch_token = branch.lock_write()
 
1184
        repo_token = branch.repository.lock_write()
 
1185
        branch.repository.unlock()
1214
1186
        branch.leave_lock_in_place()
1215
1187
        branch.repository.leave_lock_in_place()
1216
1188
        branch.unlock()
1231
1203
        backing = self.get_transport()
1232
1204
        request = smart_branch.SmartServerBranchRequestLockWrite(backing)
1233
1205
        branch = self.make_branch('.', format='knit')
1234
 
        branch_token, repo_token = self.get_lock_tokens(branch)
 
1206
        branch_token = branch.lock_write()
 
1207
        repo_token = branch.repository.lock_write()
 
1208
        branch.repository.unlock()
1235
1209
        branch.leave_lock_in_place()
1236
1210
        branch.repository.leave_lock_in_place()
1237
1211
        branch.unlock()
1252
1226
        request = smart_branch.SmartServerBranchRequestLockWrite(backing)
1253
1227
        branch = self.make_branch('.', format='knit')
1254
1228
        repo = branch.repository
1255
 
        repo_token = repo.lock_write().repository_token
 
1229
        repo_token = repo.lock_write()
1256
1230
        repo.leave_lock_in_place()
1257
1231
        repo.unlock()
1258
1232
        response = request.execute('')
1275
1249
        self.assertEqual('LockFailed', error_name)
1276
1250
 
1277
1251
 
1278
 
class TestSmartServerBranchRequestUnlock(TestLockedBranch):
 
1252
class TestSmartServerBranchRequestUnlock(tests.TestCaseWithMemoryTransport):
1279
1253
 
1280
1254
    def setUp(self):
1281
1255
        tests.TestCaseWithMemoryTransport.setUp(self)
1285
1259
        request = smart_branch.SmartServerBranchRequestUnlock(backing)
1286
1260
        branch = self.make_branch('.', format='knit')
1287
1261
        # Lock the branch
1288
 
        branch_token, repo_token = self.get_lock_tokens(branch)
 
1262
        branch_token = branch.lock_write()
 
1263
        repo_token = branch.repository.lock_write()
 
1264
        branch.repository.unlock()
1289
1265
        # Unlock the branch (and repo) object, leaving the physical locks
1290
1266
        # in place.
1291
1267
        branch.leave_lock_in_place()
1315
1291
        request = smart_branch.SmartServerBranchRequestUnlock(backing)
1316
1292
        branch = self.make_branch('.', format='knit')
1317
1293
        # Lock the repository.
1318
 
        repo_token = branch.repository.lock_write().repository_token
 
1294
        repo_token = branch.repository.lock_write()
1319
1295
        branch.repository.leave_lock_in_place()
1320
1296
        branch.repository.unlock()
1321
1297
        # Issue branch lock_write request on the unlocked branch (with locked
1322
1298
        # repo).
1323
 
        response = request.execute('', 'branch token', repo_token)
 
1299
        response = request.execute(
 
1300
            '', 'branch token', repo_token)
1324
1301
        self.assertEqual(
1325
1302
            smart_req.SmartServerResponse(('TokenMismatch',)), response)
1326
1303
        # Cleanup
1470
1447
            request.execute('stacked', 1, (3, r3)))
1471
1448
 
1472
1449
 
1473
 
class GetStreamTestBase(tests.TestCaseWithMemoryTransport):
 
1450
class TestSmartServerRepositoryGetStream(tests.TestCaseWithMemoryTransport):
1474
1451
 
1475
1452
    def make_two_commit_repo(self):
1476
1453
        tree = self.make_branch_and_memory_tree('.')
1482
1459
        repo = tree.branch.repository
1483
1460
        return repo, r1, r2
1484
1461
 
1485
 
 
1486
 
class TestSmartServerRepositoryGetStream(GetStreamTestBase):
1487
 
 
1488
1462
    def test_ancestry_of(self):
1489
1463
        """The search argument may be a 'ancestry-of' some heads'."""
1490
1464
        backing = self.get_transport()
1511
1485
        stream_bytes = ''.join(response.body_stream)
1512
1486
        self.assertStartsWith(stream_bytes, 'Bazaar pack format 1')
1513
1487
 
1514
 
    def test_search_everything(self):
1515
 
        """A search of 'everything' returns a stream."""
1516
 
        backing = self.get_transport()
1517
 
        request = smart_repo.SmartServerRepositoryGetStream_1_19(backing)
1518
 
        repo, r1, r2 = self.make_two_commit_repo()
1519
 
        serialised_fetch_spec = 'everything'
1520
 
        request.execute('', repo._format.network_name())
1521
 
        response = request.do_body(serialised_fetch_spec)
1522
 
        self.assertEqual(('ok',), response.args)
1523
 
        stream_bytes = ''.join(response.body_stream)
1524
 
        self.assertStartsWith(stream_bytes, 'Bazaar pack format 1')
1525
 
 
1526
1488
 
1527
1489
class TestSmartServerRequestHasRevision(tests.TestCaseWithMemoryTransport):
1528
1490
 
1648
1610
        backing = self.get_transport()
1649
1611
        request = smart_repo.SmartServerRepositoryLockWrite(backing)
1650
1612
        repository = self.make_repository('.', format='knit')
1651
 
        repo_token = repository.lock_write().repository_token
 
1613
        repo_token = repository.lock_write()
1652
1614
        repository.leave_lock_in_place()
1653
1615
        repository.unlock()
1654
1616
        response = request.execute('')
1696
1658
        request = smart_repo.SmartServerRepositoryInsertStreamLocked(
1697
1659
            backing)
1698
1660
        repository = self.make_repository('.', format='knit')
1699
 
        lock_token = repository.lock_write().repository_token
 
1661
        lock_token = repository.lock_write()
1700
1662
        response = request.execute('', '', lock_token)
1701
1663
        self.assertEqual(None, response)
1702
1664
        response = request.do_chunk(self.make_empty_byte_stream(repository))
1710
1672
        request = smart_repo.SmartServerRepositoryInsertStreamLocked(
1711
1673
            backing)
1712
1674
        repository = self.make_repository('.', format='knit')
1713
 
        lock_token = repository.lock_write().repository_token
 
1675
        lock_token = repository.lock_write()
1714
1676
        self.assertRaises(
1715
1677
            errors.TokenMismatch, request.execute, '', '', 'wrong-token')
1716
1678
        repository.unlock()
1725
1687
        backing = self.get_transport()
1726
1688
        request = smart_repo.SmartServerRepositoryUnlock(backing)
1727
1689
        repository = self.make_repository('.', format='knit')
1728
 
        token = repository.lock_write().repository_token
 
1690
        token = repository.lock_write()
1729
1691
        repository.leave_lock_in_place()
1730
1692
        repository.unlock()
1731
1693
        response = request.execute('', token)
1922
1884
            smart_repo.SmartServerRepositoryGetRevisionGraph)
1923
1885
        self.assertHandlerEqual('Repository.get_stream',
1924
1886
            smart_repo.SmartServerRepositoryGetStream)
1925
 
        self.assertHandlerEqual('Repository.get_stream_1.19',
1926
 
            smart_repo.SmartServerRepositoryGetStream_1_19)
1927
1887
        self.assertHandlerEqual('Repository.has_revision',
1928
1888
            smart_repo.SmartServerRequestHasRevision)
1929
1889
        self.assertHandlerEqual('Repository.insert_stream',
1940
1900
            smart_repo.SmartServerRepositoryUnlock)
1941
1901
        self.assertHandlerEqual('Transport.is_readonly',
1942
1902
            smart_req.SmartServerIsReadonly)
1943
 
 
1944
 
 
1945
 
class SmartTCPServerHookTests(tests.TestCaseWithMemoryTransport):
1946
 
    """Tests for SmartTCPServer hooks."""
1947
 
 
1948
 
    def setUp(self):
1949
 
        super(SmartTCPServerHookTests, self).setUp()
1950
 
        self.server = server.SmartTCPServer(self.get_transport())
1951
 
 
1952
 
    def test_run_server_started_hooks(self):
1953
 
        """Test the server started hooks get fired properly."""
1954
 
        started_calls = []
1955
 
        server.SmartTCPServer.hooks.install_named_hook('server_started',
1956
 
            lambda backing_urls, url: started_calls.append((backing_urls, url)),
1957
 
            None)
1958
 
        started_ex_calls = []
1959
 
        server.SmartTCPServer.hooks.install_named_hook('server_started_ex',
1960
 
            lambda backing_urls, url: started_ex_calls.append((backing_urls, url)),
1961
 
            None)
1962
 
        self.server._sockname = ('example.com', 42)
1963
 
        self.server.run_server_started_hooks()
1964
 
        self.assertEquals(started_calls,
1965
 
            [([self.get_transport().base], 'bzr://example.com:42/')])
1966
 
        self.assertEquals(started_ex_calls,
1967
 
            [([self.get_transport().base], self.server)])
1968
 
 
1969
 
    def test_run_server_started_hooks_ipv6(self):
1970
 
        """Test that socknames can contain 4-tuples."""
1971
 
        self.server._sockname = ('::', 42, 0, 0)
1972
 
        started_calls = []
1973
 
        server.SmartTCPServer.hooks.install_named_hook('server_started',
1974
 
            lambda backing_urls, url: started_calls.append((backing_urls, url)),
1975
 
            None)
1976
 
        self.server.run_server_started_hooks()
1977
 
        self.assertEquals(started_calls,
1978
 
                [([self.get_transport().base], 'bzr://:::42/')])
1979
 
 
1980
 
    def test_run_server_stopped_hooks(self):
1981
 
        """Test the server stopped hooks."""
1982
 
        self.server._sockname = ('example.com', 42)
1983
 
        stopped_calls = []
1984
 
        server.SmartTCPServer.hooks.install_named_hook('server_stopped',
1985
 
            lambda backing_urls, url: stopped_calls.append((backing_urls, url)),
1986
 
            None)
1987
 
        self.server.run_server_stopped_hooks()
1988
 
        self.assertEquals(stopped_calls,
1989
 
            [([self.get_transport().base], 'bzr://example.com:42/')])