~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_smart.py

  • Committer: Andrew Bennetts
  • Date: 2011-02-25 08:45:27 UTC
  • mto: This revision was merged to the branch mainline in revision 5695.
  • Revision ID: andrew.bennetts@canonical.com-20110225084527-0ucp7p00d00hoqon
Add another test.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2006-2010 Canonical Ltd
 
1
# Copyright (C) 2006-2011 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
30
28
 
31
29
from bzrlib import (
32
 
    bencode,
33
30
    branch as _mod_branch,
34
31
    bzrdir,
35
32
    errors,
36
 
    pack,
37
33
    tests,
38
34
    transport,
39
35
    urlutils,
767
763
class TestLockedBranch(tests.TestCaseWithMemoryTransport):
768
764
 
769
765
    def get_lock_tokens(self, branch):
770
 
        branch_token = branch.lock_write()
771
 
        repo_token = branch.repository.lock_write()
 
766
        branch_token = branch.lock_write().branch_token
 
767
        repo_token = branch.repository.lock_write().repository_token
772
768
        branch.repository.unlock()
773
769
        return branch_token, repo_token
774
770
 
802
798
        branch.unlock()
803
799
 
804
800
 
 
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
 
805
839
class TestSmartServerBranchRequestSetTagsBytes(TestLockedBranch):
806
840
    # Only called when the branch format and tags match [yay factory
807
841
    # methods] so only need to test straight forward cases.
1073
1107
            response)
1074
1108
 
1075
1109
 
1076
 
class TestSmartServerBranchRequestSetParent(tests.TestCaseWithMemoryTransport):
 
1110
class TestSmartServerBranchRequestSetParent(TestLockedBranch):
1077
1111
 
1078
1112
    def test_set_parent_none(self):
1079
1113
        branch = self.make_branch('base', format="1.9")
1082
1116
        branch.unlock()
1083
1117
        request = smart_branch.SmartServerBranchRequestSetParentLocation(
1084
1118
            self.get_transport())
1085
 
        branch_token = branch.lock_write()
1086
 
        repo_token = branch.repository.lock_write()
 
1119
        branch_token, repo_token = self.get_lock_tokens(branch)
1087
1120
        try:
1088
1121
            response = request.execute('base', branch_token, repo_token, '')
1089
1122
        finally:
1090
 
            branch.repository.unlock()
1091
1123
            branch.unlock()
1092
1124
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(()), response)
1093
1125
        self.assertEqual(None, branch.get_parent())
1096
1128
        branch = self.make_branch('base', format="1.9")
1097
1129
        request = smart_branch.SmartServerBranchRequestSetParentLocation(
1098
1130
            self.get_transport())
1099
 
        branch_token = branch.lock_write()
1100
 
        repo_token = branch.repository.lock_write()
 
1131
        branch_token, repo_token = self.get_lock_tokens(branch)
1101
1132
        try:
1102
1133
            response = request.execute('base', branch_token, repo_token,
1103
1134
            'http://bar/')
1104
1135
        finally:
1105
 
            branch.repository.unlock()
1106
1136
            branch.unlock()
1107
1137
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(()), response)
1108
1138
        self.assertEqual('http://bar/', branch.get_parent())
1137
1167
            response)
1138
1168
 
1139
1169
 
1140
 
class TestSmartServerBranchRequestLockWrite(tests.TestCaseWithMemoryTransport):
 
1170
class TestSmartServerBranchRequestLockWrite(TestLockedBranch):
1141
1171
 
1142
1172
    def setUp(self):
1143
1173
        tests.TestCaseWithMemoryTransport.setUp(self)
1165
1195
        backing = self.get_transport()
1166
1196
        request = smart_branch.SmartServerBranchRequestLockWrite(backing)
1167
1197
        branch = self.make_branch('.')
1168
 
        branch_token = branch.lock_write()
 
1198
        branch_token = branch.lock_write().branch_token
1169
1199
        branch.leave_lock_in_place()
1170
1200
        branch.unlock()
1171
1201
        response = request.execute('')
1180
1210
        backing = self.get_transport()
1181
1211
        request = smart_branch.SmartServerBranchRequestLockWrite(backing)
1182
1212
        branch = self.make_branch('.', format='knit')
1183
 
        branch_token = branch.lock_write()
1184
 
        repo_token = branch.repository.lock_write()
1185
 
        branch.repository.unlock()
 
1213
        branch_token, repo_token = self.get_lock_tokens(branch)
1186
1214
        branch.leave_lock_in_place()
1187
1215
        branch.repository.leave_lock_in_place()
1188
1216
        branch.unlock()
1203
1231
        backing = self.get_transport()
1204
1232
        request = smart_branch.SmartServerBranchRequestLockWrite(backing)
1205
1233
        branch = self.make_branch('.', format='knit')
1206
 
        branch_token = branch.lock_write()
1207
 
        repo_token = branch.repository.lock_write()
1208
 
        branch.repository.unlock()
 
1234
        branch_token, repo_token = self.get_lock_tokens(branch)
1209
1235
        branch.leave_lock_in_place()
1210
1236
        branch.repository.leave_lock_in_place()
1211
1237
        branch.unlock()
1226
1252
        request = smart_branch.SmartServerBranchRequestLockWrite(backing)
1227
1253
        branch = self.make_branch('.', format='knit')
1228
1254
        repo = branch.repository
1229
 
        repo_token = repo.lock_write()
 
1255
        repo_token = repo.lock_write().repository_token
1230
1256
        repo.leave_lock_in_place()
1231
1257
        repo.unlock()
1232
1258
        response = request.execute('')
1249
1275
        self.assertEqual('LockFailed', error_name)
1250
1276
 
1251
1277
 
1252
 
class TestSmartServerBranchRequestUnlock(tests.TestCaseWithMemoryTransport):
 
1278
class TestSmartServerBranchRequestUnlock(TestLockedBranch):
1253
1279
 
1254
1280
    def setUp(self):
1255
1281
        tests.TestCaseWithMemoryTransport.setUp(self)
1259
1285
        request = smart_branch.SmartServerBranchRequestUnlock(backing)
1260
1286
        branch = self.make_branch('.', format='knit')
1261
1287
        # Lock the branch
1262
 
        branch_token = branch.lock_write()
1263
 
        repo_token = branch.repository.lock_write()
1264
 
        branch.repository.unlock()
 
1288
        branch_token, repo_token = self.get_lock_tokens(branch)
1265
1289
        # Unlock the branch (and repo) object, leaving the physical locks
1266
1290
        # in place.
1267
1291
        branch.leave_lock_in_place()
1291
1315
        request = smart_branch.SmartServerBranchRequestUnlock(backing)
1292
1316
        branch = self.make_branch('.', format='knit')
1293
1317
        # Lock the repository.
1294
 
        repo_token = branch.repository.lock_write()
 
1318
        repo_token = branch.repository.lock_write().repository_token
1295
1319
        branch.repository.leave_lock_in_place()
1296
1320
        branch.repository.unlock()
1297
1321
        # Issue branch lock_write request on the unlocked branch (with locked
1298
1322
        # repo).
1299
 
        response = request.execute(
1300
 
            '', 'branch token', repo_token)
 
1323
        response = request.execute('', 'branch token', repo_token)
1301
1324
        self.assertEqual(
1302
1325
            smart_req.SmartServerResponse(('TokenMismatch',)), response)
1303
1326
        # Cleanup
1447
1470
            request.execute('stacked', 1, (3, r3)))
1448
1471
 
1449
1472
 
1450
 
class TestSmartServerRepositoryGetStream(tests.TestCaseWithMemoryTransport):
 
1473
class GetStreamTestBase(tests.TestCaseWithMemoryTransport):
1451
1474
 
1452
1475
    def make_two_commit_repo(self):
1453
1476
        tree = self.make_branch_and_memory_tree('.')
1459
1482
        repo = tree.branch.repository
1460
1483
        return repo, r1, r2
1461
1484
 
 
1485
 
 
1486
class TestSmartServerRepositoryGetStream(GetStreamTestBase):
 
1487
 
1462
1488
    def test_ancestry_of(self):
1463
1489
        """The search argument may be a 'ancestry-of' some heads'."""
1464
1490
        backing = self.get_transport()
1485
1511
        stream_bytes = ''.join(response.body_stream)
1486
1512
        self.assertStartsWith(stream_bytes, 'Bazaar pack format 1')
1487
1513
 
 
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
 
1488
1526
 
1489
1527
class TestSmartServerRequestHasRevision(tests.TestCaseWithMemoryTransport):
1490
1528
 
1610
1648
        backing = self.get_transport()
1611
1649
        request = smart_repo.SmartServerRepositoryLockWrite(backing)
1612
1650
        repository = self.make_repository('.', format='knit')
1613
 
        repo_token = repository.lock_write()
 
1651
        repo_token = repository.lock_write().repository_token
1614
1652
        repository.leave_lock_in_place()
1615
1653
        repository.unlock()
1616
1654
        response = request.execute('')
1658
1696
        request = smart_repo.SmartServerRepositoryInsertStreamLocked(
1659
1697
            backing)
1660
1698
        repository = self.make_repository('.', format='knit')
1661
 
        lock_token = repository.lock_write()
 
1699
        lock_token = repository.lock_write().repository_token
1662
1700
        response = request.execute('', '', lock_token)
1663
1701
        self.assertEqual(None, response)
1664
1702
        response = request.do_chunk(self.make_empty_byte_stream(repository))
1672
1710
        request = smart_repo.SmartServerRepositoryInsertStreamLocked(
1673
1711
            backing)
1674
1712
        repository = self.make_repository('.', format='knit')
1675
 
        lock_token = repository.lock_write()
 
1713
        lock_token = repository.lock_write().repository_token
1676
1714
        self.assertRaises(
1677
1715
            errors.TokenMismatch, request.execute, '', '', 'wrong-token')
1678
1716
        repository.unlock()
1687
1725
        backing = self.get_transport()
1688
1726
        request = smart_repo.SmartServerRepositoryUnlock(backing)
1689
1727
        repository = self.make_repository('.', format='knit')
1690
 
        token = repository.lock_write()
 
1728
        token = repository.lock_write().repository_token
1691
1729
        repository.leave_lock_in_place()
1692
1730
        repository.unlock()
1693
1731
        response = request.execute('', token)
1884
1922
            smart_repo.SmartServerRepositoryGetRevisionGraph)
1885
1923
        self.assertHandlerEqual('Repository.get_stream',
1886
1924
            smart_repo.SmartServerRepositoryGetStream)
 
1925
        self.assertHandlerEqual('Repository.get_stream_1.19',
 
1926
            smart_repo.SmartServerRepositoryGetStream_1_19)
1887
1927
        self.assertHandlerEqual('Repository.has_revision',
1888
1928
            smart_repo.SmartServerRequestHasRevision)
1889
1929
        self.assertHandlerEqual('Repository.insert_stream',
1900
1940
            smart_repo.SmartServerRepositoryUnlock)
1901
1941
        self.assertHandlerEqual('Transport.is_readonly',
1902
1942
            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/')])