~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_smart.py

  • Committer: Jelmer Vernooij
  • Date: 2011-12-05 14:12:23 UTC
  • mto: This revision was merged to the branch mainline in revision 6348.
  • Revision ID: jelmer@samba.org-20111205141223-8qxae4h37satlzgq
Move more functionality to vf_search.

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
 
28
import zlib
30
29
 
31
30
from bzrlib import (
32
 
    bencode,
33
31
    branch as _mod_branch,
34
32
    bzrdir,
35
33
    errors,
36
 
    pack,
 
34
    gpg,
37
35
    tests,
38
36
    transport,
39
37
    urlutils,
48
46
    server,
49
47
    vfs,
50
48
    )
 
49
from bzrlib.testament import Testament
51
50
from bzrlib.tests import test_server
52
51
from bzrlib.transport import (
53
52
    chroot,
89
88
            backing_transport = tests.TestCaseWithTransport.get_transport(self)
90
89
            self._chroot_server = chroot.ChrootServer(backing_transport)
91
90
            self.start_server(self._chroot_server)
92
 
        t = transport.get_transport(self._chroot_server.get_url())
 
91
        t = transport.get_transport_from_url(self._chroot_server.get_url())
93
92
        if relpath is not None:
94
93
            t = t.clone(relpath)
95
94
        return t
103
102
        # the default or a parameterized class, but rather use the
104
103
        # TestCaseWithTransport infrastructure to set up a smart server and
105
104
        # transport.
106
 
        self.transport_server = self.make_transport_server
 
105
        self.overrideAttr(self, "transport_server", self.make_transport_server)
107
106
 
108
107
    def make_transport_server(self):
109
108
        return test_server.SmartTCPServer_for_testing('-' + self.id())
225
224
        self.assertEqual(expected, request.execute('', 'False'))
226
225
 
227
226
 
 
227
class TestSmartServerBzrDirRequestDestroyBranch(
 
228
    tests.TestCaseWithMemoryTransport):
 
229
    """Tests for BzrDir.destroy_branch."""
 
230
 
 
231
    def test_destroy_branch_default(self):
 
232
        """The default branch can be removed."""
 
233
        backing = self.get_transport()
 
234
        dir = self.make_branch('.').bzrdir
 
235
        request_class = smart_dir.SmartServerBzrDirRequestDestroyBranch
 
236
        request = request_class(backing)
 
237
        expected = smart_req.SuccessfulSmartServerResponse(('ok',))
 
238
        self.assertEqual(expected, request.execute('', None))
 
239
 
 
240
    def test_destroy_branch_named(self):
 
241
        """A named branch can be removed."""
 
242
        backing = self.get_transport()
 
243
        dir = self.make_repository('.', format="development-colo").bzrdir
 
244
        dir.create_branch(name="branchname")
 
245
        request_class = smart_dir.SmartServerBzrDirRequestDestroyBranch
 
246
        request = request_class(backing)
 
247
        expected = smart_req.SuccessfulSmartServerResponse(('ok',))
 
248
        self.assertEqual(expected, request.execute('', "branchname"))
 
249
 
 
250
    def test_destroy_branch_missing(self):
 
251
        """An error is raised if the branch didn't exist."""
 
252
        backing = self.get_transport()
 
253
        dir = self.make_bzrdir('.', format="development-colo")
 
254
        request_class = smart_dir.SmartServerBzrDirRequestDestroyBranch
 
255
        request = request_class(backing)
 
256
        expected = smart_req.FailedSmartServerResponse(('nobranch',), None)
 
257
        self.assertEqual(expected, request.execute('', "branchname"))
 
258
 
 
259
 
 
260
class TestSmartServerBzrDirRequestHasWorkingTree(
 
261
    tests.TestCaseWithTransport):
 
262
    """Tests for BzrDir.has_workingtree."""
 
263
 
 
264
    def test_has_workingtree_yes(self):
 
265
        """A working tree is present."""
 
266
        backing = self.get_transport()
 
267
        dir = self.make_branch_and_tree('.').bzrdir
 
268
        request_class = smart_dir.SmartServerBzrDirRequestHasWorkingTree
 
269
        request = request_class(backing)
 
270
        expected = smart_req.SuccessfulSmartServerResponse(('yes',))
 
271
        self.assertEqual(expected, request.execute(''))
 
272
 
 
273
    def test_has_workingtree_no(self):
 
274
        """A working tree is missing."""
 
275
        backing = self.get_transport()
 
276
        dir = self.make_bzrdir('.')
 
277
        request_class = smart_dir.SmartServerBzrDirRequestHasWorkingTree
 
278
        request = request_class(backing)
 
279
        expected = smart_req.SuccessfulSmartServerResponse(('no',))
 
280
        self.assertEqual(expected, request.execute(''))
 
281
 
 
282
 
 
283
class TestSmartServerBzrDirRequestDestroyRepository(
 
284
    tests.TestCaseWithMemoryTransport):
 
285
    """Tests for BzrDir.destroy_repository."""
 
286
 
 
287
    def test_destroy_repository_default(self):
 
288
        """The repository can be removed."""
 
289
        backing = self.get_transport()
 
290
        dir = self.make_repository('.').bzrdir
 
291
        request_class = smart_dir.SmartServerBzrDirRequestDestroyRepository
 
292
        request = request_class(backing)
 
293
        expected = smart_req.SuccessfulSmartServerResponse(('ok',))
 
294
        self.assertEqual(expected, request.execute(''))
 
295
 
 
296
    def test_destroy_repository_missing(self):
 
297
        """An error is raised if the repository didn't exist."""
 
298
        backing = self.get_transport()
 
299
        dir = self.make_bzrdir('.')
 
300
        request_class = smart_dir.SmartServerBzrDirRequestDestroyRepository
 
301
        request = request_class(backing)
 
302
        expected = smart_req.FailedSmartServerResponse(
 
303
            ('norepository',), None)
 
304
        self.assertEqual(expected, request.execute(''))
 
305
 
 
306
 
228
307
class TestSmartServerRequestCreateRepository(tests.TestCaseWithMemoryTransport):
229
308
    """Tests for BzrDir.create_repository."""
230
309
 
739
818
            request.execute(''))
740
819
 
741
820
 
 
821
class TestSmartServerBranchRequestRevisionIdToRevno(
 
822
    tests.TestCaseWithMemoryTransport):
 
823
 
 
824
    def test_null(self):
 
825
        backing = self.get_transport()
 
826
        request = smart_branch.SmartServerBranchRequestRevisionIdToRevno(
 
827
            backing)
 
828
        self.make_branch('.')
 
829
        self.assertEqual(smart_req.SmartServerResponse(('ok', '0')),
 
830
            request.execute('', 'null:'))
 
831
 
 
832
    def test_simple(self):
 
833
        backing = self.get_transport()
 
834
        request = smart_branch.SmartServerBranchRequestRevisionIdToRevno(
 
835
            backing)
 
836
        tree = self.make_branch_and_memory_tree('.')
 
837
        tree.lock_write()
 
838
        tree.add('')
 
839
        r1 = tree.commit('1st commit')
 
840
        tree.unlock()
 
841
        self.assertEqual(
 
842
            smart_req.SmartServerResponse(('ok', '1')),
 
843
            request.execute('', r1))
 
844
 
 
845
    def test_not_found(self):
 
846
        backing = self.get_transport()
 
847
        request = smart_branch.SmartServerBranchRequestRevisionIdToRevno(
 
848
            backing)
 
849
        branch = self.make_branch('.')
 
850
        self.assertEqual(
 
851
            smart_req.FailedSmartServerResponse(
 
852
                ('NoSuchRevision', 'idontexist')),
 
853
            request.execute('', 'idontexist'))
 
854
 
 
855
 
742
856
class TestSmartServerBranchRequestGetConfigFile(
743
857
    tests.TestCaseWithMemoryTransport):
744
858
 
767
881
class TestLockedBranch(tests.TestCaseWithMemoryTransport):
768
882
 
769
883
    def get_lock_tokens(self, branch):
770
 
        branch_token = branch.lock_write()
771
 
        repo_token = branch.repository.lock_write()
 
884
        branch_token = branch.lock_write().branch_token
 
885
        repo_token = branch.repository.lock_write().repository_token
772
886
        branch.repository.unlock()
773
887
        return branch_token, repo_token
774
888
 
775
889
 
 
890
class TestSmartServerBranchRequestPutConfigFile(TestLockedBranch):
 
891
 
 
892
    def test_with_content(self):
 
893
        backing = self.get_transport()
 
894
        request = smart_branch.SmartServerBranchPutConfigFile(backing)
 
895
        branch = self.make_branch('.')
 
896
        branch_token, repo_token = self.get_lock_tokens(branch)
 
897
        self.assertIs(None, request.execute('', branch_token, repo_token))
 
898
        self.assertEqual(
 
899
            smart_req.SmartServerResponse(('ok', )),
 
900
            request.do_body('foo bar baz'))
 
901
        self.assertEquals(
 
902
            branch.control_transport.get_bytes('branch.conf'),
 
903
            'foo bar baz')
 
904
        branch.unlock()
 
905
 
 
906
 
776
907
class TestSmartServerBranchRequestSetConfigOption(TestLockedBranch):
777
908
 
778
909
    def test_value_name(self):
802
933
        branch.unlock()
803
934
 
804
935
 
 
936
class TestSmartServerBranchRequestSetConfigOptionDict(TestLockedBranch):
 
937
 
 
938
    def setUp(self):
 
939
        TestLockedBranch.setUp(self)
 
940
        # A dict with non-ascii keys and values to exercise unicode
 
941
        # roundtripping.
 
942
        self.encoded_value_dict = (
 
943
            'd5:ascii1:a11:unicode \xe2\x8c\x9a3:\xe2\x80\xbde')
 
944
        self.value_dict = {
 
945
            'ascii': 'a', u'unicode \N{WATCH}': u'\N{INTERROBANG}'}
 
946
 
 
947
    def test_value_name(self):
 
948
        branch = self.make_branch('.')
 
949
        request = smart_branch.SmartServerBranchRequestSetConfigOptionDict(
 
950
            branch.bzrdir.root_transport)
 
951
        branch_token, repo_token = self.get_lock_tokens(branch)
 
952
        config = branch._get_config()
 
953
        result = request.execute('', branch_token, repo_token,
 
954
            self.encoded_value_dict, 'foo', '')
 
955
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(()), result)
 
956
        self.assertEqual(self.value_dict, config.get_option('foo'))
 
957
        # Cleanup
 
958
        branch.unlock()
 
959
 
 
960
    def test_value_name_section(self):
 
961
        branch = self.make_branch('.')
 
962
        request = smart_branch.SmartServerBranchRequestSetConfigOptionDict(
 
963
            branch.bzrdir.root_transport)
 
964
        branch_token, repo_token = self.get_lock_tokens(branch)
 
965
        config = branch._get_config()
 
966
        result = request.execute('', branch_token, repo_token,
 
967
            self.encoded_value_dict, 'foo', 'gam')
 
968
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(()), result)
 
969
        self.assertEqual(self.value_dict, config.get_option('foo', 'gam'))
 
970
        # Cleanup
 
971
        branch.unlock()
 
972
 
 
973
 
805
974
class TestSmartServerBranchRequestSetTagsBytes(TestLockedBranch):
806
975
    # Only called when the branch format and tags match [yay factory
807
976
    # methods] so only need to test straight forward cases.
898
1067
        # its repository.
899
1068
        self.make_tree_with_two_commits()
900
1069
        rev_id_utf8 = u'\xc8'.encode('utf-8')
901
 
        self.tree.branch.set_revision_history([])
 
1070
        self.tree.branch.set_last_revision_info(0, 'null:')
902
1071
        self.assertEqual(
903
1072
            (0, 'null:'), self.tree.branch.last_revision_info())
904
1073
        # We can update the branch to a revision that is present in the
1054
1223
        self.assertEqual('child-1', self.tree.branch.last_revision())
1055
1224
 
1056
1225
 
 
1226
class TestSmartServerBranchBreakLock(tests.TestCaseWithMemoryTransport):
 
1227
 
 
1228
    def test_lock_to_break(self):
 
1229
        base_branch = self.make_branch('base')
 
1230
        request = smart_branch.SmartServerBranchBreakLock(
 
1231
            self.get_transport())
 
1232
        base_branch.lock_write()
 
1233
        self.assertEqual(
 
1234
            smart_req.SuccessfulSmartServerResponse(('ok', ), None),
 
1235
            request.execute('base'))
 
1236
 
 
1237
    def test_nothing_to_break(self):
 
1238
        base_branch = self.make_branch('base')
 
1239
        request = smart_branch.SmartServerBranchBreakLock(
 
1240
            self.get_transport())
 
1241
        self.assertEqual(
 
1242
            smart_req.SuccessfulSmartServerResponse(('ok', ), None),
 
1243
            request.execute('base'))
 
1244
 
 
1245
 
1057
1246
class TestSmartServerBranchRequestGetParent(tests.TestCaseWithMemoryTransport):
1058
1247
 
1059
1248
    def test_get_parent_none(self):
1073
1262
            response)
1074
1263
 
1075
1264
 
1076
 
class TestSmartServerBranchRequestSetParent(tests.TestCaseWithMemoryTransport):
 
1265
class TestSmartServerBranchRequestSetParent(TestLockedBranch):
1077
1266
 
1078
1267
    def test_set_parent_none(self):
1079
1268
        branch = self.make_branch('base', format="1.9")
1082
1271
        branch.unlock()
1083
1272
        request = smart_branch.SmartServerBranchRequestSetParentLocation(
1084
1273
            self.get_transport())
1085
 
        branch_token = branch.lock_write()
1086
 
        repo_token = branch.repository.lock_write()
 
1274
        branch_token, repo_token = self.get_lock_tokens(branch)
1087
1275
        try:
1088
1276
            response = request.execute('base', branch_token, repo_token, '')
1089
1277
        finally:
1090
 
            branch.repository.unlock()
1091
1278
            branch.unlock()
1092
1279
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(()), response)
1093
1280
        self.assertEqual(None, branch.get_parent())
1096
1283
        branch = self.make_branch('base', format="1.9")
1097
1284
        request = smart_branch.SmartServerBranchRequestSetParentLocation(
1098
1285
            self.get_transport())
1099
 
        branch_token = branch.lock_write()
1100
 
        repo_token = branch.repository.lock_write()
 
1286
        branch_token, repo_token = self.get_lock_tokens(branch)
1101
1287
        try:
1102
1288
            response = request.execute('base', branch_token, repo_token,
1103
1289
            'http://bar/')
1104
1290
        finally:
1105
 
            branch.repository.unlock()
1106
1291
            branch.unlock()
1107
1292
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(()), response)
1108
1293
        self.assertEqual('http://bar/', branch.get_parent())
1137
1322
            response)
1138
1323
 
1139
1324
 
1140
 
class TestSmartServerBranchRequestLockWrite(tests.TestCaseWithMemoryTransport):
 
1325
class TestSmartServerBranchRequestLockWrite(TestLockedBranch):
1141
1326
 
1142
1327
    def setUp(self):
1143
1328
        tests.TestCaseWithMemoryTransport.setUp(self)
1165
1350
        backing = self.get_transport()
1166
1351
        request = smart_branch.SmartServerBranchRequestLockWrite(backing)
1167
1352
        branch = self.make_branch('.')
1168
 
        branch_token = branch.lock_write()
 
1353
        branch_token = branch.lock_write().branch_token
1169
1354
        branch.leave_lock_in_place()
1170
1355
        branch.unlock()
1171
1356
        response = request.execute('')
1180
1365
        backing = self.get_transport()
1181
1366
        request = smart_branch.SmartServerBranchRequestLockWrite(backing)
1182
1367
        branch = self.make_branch('.', format='knit')
1183
 
        branch_token = branch.lock_write()
1184
 
        repo_token = branch.repository.lock_write()
1185
 
        branch.repository.unlock()
 
1368
        branch_token, repo_token = self.get_lock_tokens(branch)
1186
1369
        branch.leave_lock_in_place()
1187
1370
        branch.repository.leave_lock_in_place()
1188
1371
        branch.unlock()
1203
1386
        backing = self.get_transport()
1204
1387
        request = smart_branch.SmartServerBranchRequestLockWrite(backing)
1205
1388
        branch = self.make_branch('.', format='knit')
1206
 
        branch_token = branch.lock_write()
1207
 
        repo_token = branch.repository.lock_write()
1208
 
        branch.repository.unlock()
 
1389
        branch_token, repo_token = self.get_lock_tokens(branch)
1209
1390
        branch.leave_lock_in_place()
1210
1391
        branch.repository.leave_lock_in_place()
1211
1392
        branch.unlock()
1226
1407
        request = smart_branch.SmartServerBranchRequestLockWrite(backing)
1227
1408
        branch = self.make_branch('.', format='knit')
1228
1409
        repo = branch.repository
1229
 
        repo_token = repo.lock_write()
 
1410
        repo_token = repo.lock_write().repository_token
1230
1411
        repo.leave_lock_in_place()
1231
1412
        repo.unlock()
1232
1413
        response = request.execute('')
1249
1430
        self.assertEqual('LockFailed', error_name)
1250
1431
 
1251
1432
 
1252
 
class TestSmartServerBranchRequestUnlock(tests.TestCaseWithMemoryTransport):
 
1433
class TestSmartServerBranchRequestGetPhysicalLockStatus(TestLockedBranch):
 
1434
 
 
1435
    def setUp(self):
 
1436
        tests.TestCaseWithMemoryTransport.setUp(self)
 
1437
 
 
1438
    def test_true(self):
 
1439
        backing = self.get_transport()
 
1440
        request = smart_branch.SmartServerBranchRequestGetPhysicalLockStatus(
 
1441
            backing)
 
1442
        branch = self.make_branch('.')
 
1443
        branch_token, repo_token = self.get_lock_tokens(branch)
 
1444
        self.assertEquals(True, branch.get_physical_lock_status())
 
1445
        response = request.execute('')
 
1446
        self.assertEqual(
 
1447
            smart_req.SmartServerResponse(('yes',)), response)
 
1448
        branch.unlock()
 
1449
 
 
1450
    def test_false(self):
 
1451
        backing = self.get_transport()
 
1452
        request = smart_branch.SmartServerBranchRequestGetPhysicalLockStatus(
 
1453
            backing)
 
1454
        branch = self.make_branch('.')
 
1455
        self.assertEquals(False, branch.get_physical_lock_status())
 
1456
        response = request.execute('')
 
1457
        self.assertEqual(
 
1458
            smart_req.SmartServerResponse(('no',)), response)
 
1459
 
 
1460
 
 
1461
class TestSmartServerBranchRequestUnlock(TestLockedBranch):
1253
1462
 
1254
1463
    def setUp(self):
1255
1464
        tests.TestCaseWithMemoryTransport.setUp(self)
1259
1468
        request = smart_branch.SmartServerBranchRequestUnlock(backing)
1260
1469
        branch = self.make_branch('.', format='knit')
1261
1470
        # Lock the branch
1262
 
        branch_token = branch.lock_write()
1263
 
        repo_token = branch.repository.lock_write()
1264
 
        branch.repository.unlock()
 
1471
        branch_token, repo_token = self.get_lock_tokens(branch)
1265
1472
        # Unlock the branch (and repo) object, leaving the physical locks
1266
1473
        # in place.
1267
1474
        branch.leave_lock_in_place()
1291
1498
        request = smart_branch.SmartServerBranchRequestUnlock(backing)
1292
1499
        branch = self.make_branch('.', format='knit')
1293
1500
        # Lock the repository.
1294
 
        repo_token = branch.repository.lock_write()
 
1501
        repo_token = branch.repository.lock_write().repository_token
1295
1502
        branch.repository.leave_lock_in_place()
1296
1503
        branch.repository.unlock()
1297
1504
        # Issue branch lock_write request on the unlocked branch (with locked
1298
1505
        # repo).
1299
 
        response = request.execute(
1300
 
            '', 'branch token', repo_token)
 
1506
        response = request.execute('', 'branch token', repo_token)
1301
1507
        self.assertEqual(
1302
1508
            smart_req.SmartServerResponse(('TokenMismatch',)), response)
1303
1509
        # Cleanup
1322
1528
            request.execute, 'subdir')
1323
1529
 
1324
1530
 
 
1531
class TestSmartServerRepositoryAddSignatureText(tests.TestCaseWithMemoryTransport):
 
1532
 
 
1533
    def test_add_text(self):
 
1534
        backing = self.get_transport()
 
1535
        request = smart_repo.SmartServerRepositoryAddSignatureText(backing)
 
1536
        tree = self.make_branch_and_memory_tree('.')
 
1537
        write_token = tree.lock_write()
 
1538
        self.addCleanup(tree.unlock)
 
1539
        tree.add('')
 
1540
        tree.commit("Message", rev_id='rev1')
 
1541
        tree.branch.repository.start_write_group()
 
1542
        write_group_tokens = tree.branch.repository.suspend_write_group()
 
1543
        self.assertEqual(None, request.execute('', write_token,
 
1544
            'rev1', *write_group_tokens))
 
1545
        response = request.do_body('somesignature')
 
1546
        self.assertTrue(response.is_successful())
 
1547
        self.assertEqual(response.args[0], 'ok')
 
1548
        write_group_tokens = response.args[1:]
 
1549
        tree.branch.repository.resume_write_group(write_group_tokens)
 
1550
        tree.branch.repository.commit_write_group()
 
1551
        tree.unlock()
 
1552
        self.assertEqual("somesignature",
 
1553
            tree.branch.repository.get_signature_text("rev1"))
 
1554
 
 
1555
 
 
1556
class TestSmartServerRepositoryAllRevisionIds(
 
1557
    tests.TestCaseWithMemoryTransport):
 
1558
 
 
1559
    def test_empty(self):
 
1560
        """An empty body should be returned for an empty repository."""
 
1561
        backing = self.get_transport()
 
1562
        request = smart_repo.SmartServerRepositoryAllRevisionIds(backing)
 
1563
        self.make_repository('.')
 
1564
        self.assertEquals(
 
1565
            smart_req.SuccessfulSmartServerResponse(("ok", ), ""),
 
1566
            request.execute(''))
 
1567
 
 
1568
    def test_some_revisions(self):
 
1569
        """An empty body should be returned for an empty repository."""
 
1570
        backing = self.get_transport()
 
1571
        request = smart_repo.SmartServerRepositoryAllRevisionIds(backing)
 
1572
        tree = self.make_branch_and_memory_tree('.')
 
1573
        tree.lock_write()
 
1574
        tree.add('')
 
1575
        tree.commit(rev_id='origineel', message="message")
 
1576
        tree.commit(rev_id='nog-een-revisie', message="message")
 
1577
        tree.unlock()
 
1578
        self.assertEquals(
 
1579
            smart_req.SuccessfulSmartServerResponse(("ok", ),
 
1580
                "origineel\nnog-een-revisie"),
 
1581
            request.execute(''))
 
1582
 
 
1583
 
 
1584
class TestSmartServerRepositoryBreakLock(tests.TestCaseWithMemoryTransport):
 
1585
 
 
1586
    def test_lock_to_break(self):
 
1587
        backing = self.get_transport()
 
1588
        request = smart_repo.SmartServerRepositoryBreakLock(backing)
 
1589
        tree = self.make_branch_and_memory_tree('.')
 
1590
        tree.branch.repository.lock_write()
 
1591
        self.assertEqual(
 
1592
            smart_req.SuccessfulSmartServerResponse(('ok', ), None),
 
1593
            request.execute(''))
 
1594
 
 
1595
    def test_nothing_to_break(self):
 
1596
        backing = self.get_transport()
 
1597
        request = smart_repo.SmartServerRepositoryBreakLock(backing)
 
1598
        tree = self.make_branch_and_memory_tree('.')
 
1599
        self.assertEqual(
 
1600
            smart_req.SuccessfulSmartServerResponse(('ok', ), None),
 
1601
            request.execute(''))
 
1602
 
 
1603
 
1325
1604
class TestSmartServerRepositoryGetParentMap(tests.TestCaseWithMemoryTransport):
1326
1605
 
1327
1606
    def test_trivial_bzipped(self):
1447
1726
            request.execute('stacked', 1, (3, r3)))
1448
1727
 
1449
1728
 
1450
 
class TestSmartServerRepositoryGetStream(tests.TestCaseWithMemoryTransport):
 
1729
class TestSmartServerRepositoryIterRevisions(
 
1730
    tests.TestCaseWithMemoryTransport):
 
1731
 
 
1732
    def test_basic(self):
 
1733
        backing = self.get_transport()
 
1734
        request = smart_repo.SmartServerRepositoryIterRevisions(backing)
 
1735
        tree = self.make_branch_and_memory_tree('.', format='2a')
 
1736
        tree.lock_write()
 
1737
        tree.add('')
 
1738
        tree.commit('1st commit', rev_id="rev1")
 
1739
        tree.commit('2nd commit', rev_id="rev2")
 
1740
        tree.unlock()
 
1741
 
 
1742
        self.assertIs(None, request.execute(''))
 
1743
        response = request.do_body("rev1\nrev2")
 
1744
        self.assertTrue(response.is_successful())
 
1745
        # Format 2a uses serializer format 10
 
1746
        self.assertEquals(response.args, ("ok", "10"))
 
1747
 
 
1748
        self.addCleanup(tree.branch.lock_read().unlock)
 
1749
        entries = [zlib.compress(record.get_bytes_as("fulltext")) for record in
 
1750
            tree.branch.repository.revisions.get_record_stream(
 
1751
            [("rev1", ), ("rev2", )], "unordered", True)]
 
1752
 
 
1753
        contents = "".join(response.body_stream)
 
1754
        self.assertTrue(contents in (
 
1755
            "".join([entries[0], entries[1]]),
 
1756
            "".join([entries[1], entries[0]])))
 
1757
 
 
1758
    def test_missing(self):
 
1759
        backing = self.get_transport()
 
1760
        request = smart_repo.SmartServerRepositoryIterRevisions(backing)
 
1761
        tree = self.make_branch_and_memory_tree('.', format='2a')
 
1762
 
 
1763
        self.assertIs(None, request.execute(''))
 
1764
        response = request.do_body("rev1\nrev2")
 
1765
        self.assertTrue(response.is_successful())
 
1766
        # Format 2a uses serializer format 10
 
1767
        self.assertEquals(response.args, ("ok", "10"))
 
1768
 
 
1769
        contents = "".join(response.body_stream)
 
1770
        self.assertEquals(contents, "")
 
1771
 
 
1772
 
 
1773
class GetStreamTestBase(tests.TestCaseWithMemoryTransport):
1451
1774
 
1452
1775
    def make_two_commit_repo(self):
1453
1776
        tree = self.make_branch_and_memory_tree('.')
1459
1782
        repo = tree.branch.repository
1460
1783
        return repo, r1, r2
1461
1784
 
 
1785
 
 
1786
class TestSmartServerRepositoryGetStream(GetStreamTestBase):
 
1787
 
1462
1788
    def test_ancestry_of(self):
1463
1789
        """The search argument may be a 'ancestry-of' some heads'."""
1464
1790
        backing = self.get_transport()
1485
1811
        stream_bytes = ''.join(response.body_stream)
1486
1812
        self.assertStartsWith(stream_bytes, 'Bazaar pack format 1')
1487
1813
 
 
1814
    def test_search_everything(self):
 
1815
        """A search of 'everything' returns a stream."""
 
1816
        backing = self.get_transport()
 
1817
        request = smart_repo.SmartServerRepositoryGetStream_1_19(backing)
 
1818
        repo, r1, r2 = self.make_two_commit_repo()
 
1819
        serialised_fetch_spec = 'everything'
 
1820
        request.execute('', repo._format.network_name())
 
1821
        response = request.do_body(serialised_fetch_spec)
 
1822
        self.assertEqual(('ok',), response.args)
 
1823
        stream_bytes = ''.join(response.body_stream)
 
1824
        self.assertStartsWith(stream_bytes, 'Bazaar pack format 1')
 
1825
 
1488
1826
 
1489
1827
class TestSmartServerRequestHasRevision(tests.TestCaseWithMemoryTransport):
1490
1828
 
1511
1849
            request.execute('', rev_id_utf8))
1512
1850
 
1513
1851
 
 
1852
class TestSmartServerRepositoryIterFilesBytes(tests.TestCaseWithTransport):
 
1853
 
 
1854
    def test_single(self):
 
1855
        backing = self.get_transport()
 
1856
        request = smart_repo.SmartServerRepositoryIterFilesBytes(backing)
 
1857
        t = self.make_branch_and_tree('.')
 
1858
        self.addCleanup(t.lock_write().unlock)
 
1859
        self.build_tree_contents([("file", "somecontents")])
 
1860
        t.add(["file"], ["thefileid"])
 
1861
        t.commit(rev_id='somerev', message="add file")
 
1862
        self.assertIs(None, request.execute(''))
 
1863
        response = request.do_body("thefileid\0somerev\n")
 
1864
        self.assertTrue(response.is_successful())
 
1865
        self.assertEquals(response.args, ("ok", ))
 
1866
        self.assertEquals("".join(response.body_stream),
 
1867
            "ok\x000\n" + zlib.compress("somecontents"))
 
1868
 
 
1869
    def test_missing(self):
 
1870
        backing = self.get_transport()
 
1871
        request = smart_repo.SmartServerRepositoryIterFilesBytes(backing)
 
1872
        t = self.make_branch_and_tree('.')
 
1873
        self.addCleanup(t.lock_write().unlock)
 
1874
        self.assertIs(None, request.execute(''))
 
1875
        response = request.do_body("thefileid\0revision\n")
 
1876
        self.assertTrue(response.is_successful())
 
1877
        self.assertEquals(response.args, ("ok", ))
 
1878
        self.assertEquals("".join(response.body_stream),
 
1879
            "absent\x00thefileid\x00revision\x000\n")
 
1880
 
 
1881
 
 
1882
class TestSmartServerRequestHasSignatureForRevisionId(
 
1883
        tests.TestCaseWithMemoryTransport):
 
1884
 
 
1885
    def test_missing_revision(self):
 
1886
        """For a missing revision, NoSuchRevision is returned."""
 
1887
        backing = self.get_transport()
 
1888
        request = smart_repo.SmartServerRequestHasSignatureForRevisionId(
 
1889
            backing)
 
1890
        self.make_repository('.')
 
1891
        self.assertEqual(
 
1892
            smart_req.FailedSmartServerResponse(
 
1893
                ('nosuchrevision', 'revid'), None),
 
1894
            request.execute('', 'revid'))
 
1895
 
 
1896
    def test_missing_signature(self):
 
1897
        """For a missing signature, ('no', ) is returned."""
 
1898
        backing = self.get_transport()
 
1899
        request = smart_repo.SmartServerRequestHasSignatureForRevisionId(
 
1900
            backing)
 
1901
        tree = self.make_branch_and_memory_tree('.')
 
1902
        tree.lock_write()
 
1903
        tree.add('')
 
1904
        r1 = tree.commit('a commit', rev_id='A')
 
1905
        tree.unlock()
 
1906
        self.assertTrue(tree.branch.repository.has_revision('A'))
 
1907
        self.assertEqual(smart_req.SmartServerResponse(('no', )),
 
1908
            request.execute('', 'A'))
 
1909
 
 
1910
    def test_present_signature(self):
 
1911
        """For a present signature, ('yes', ) is returned."""
 
1912
        backing = self.get_transport()
 
1913
        request = smart_repo.SmartServerRequestHasSignatureForRevisionId(
 
1914
            backing)
 
1915
        strategy = gpg.LoopbackGPGStrategy(None)
 
1916
        tree = self.make_branch_and_memory_tree('.')
 
1917
        tree.lock_write()
 
1918
        tree.add('')
 
1919
        r1 = tree.commit('a commit', rev_id='A')
 
1920
        tree.branch.repository.start_write_group()
 
1921
        tree.branch.repository.sign_revision('A', strategy)
 
1922
        tree.branch.repository.commit_write_group()
 
1923
        tree.unlock()
 
1924
        self.assertTrue(tree.branch.repository.has_revision('A'))
 
1925
        self.assertEqual(smart_req.SmartServerResponse(('yes', )),
 
1926
            request.execute('', 'A'))
 
1927
 
 
1928
 
1514
1929
class TestSmartServerRepositoryGatherStats(tests.TestCaseWithMemoryTransport):
1515
1930
 
1516
1931
    def test_empty_revid(self):
1569
1984
                         request.execute('',
1570
1985
                                         rev_id_utf8, 'yes'))
1571
1986
 
 
1987
    def test_unknown_revid(self):
 
1988
        """An unknown revision id causes a 'nosuchrevision' error."""
 
1989
        backing = self.get_transport()
 
1990
        request = smart_repo.SmartServerRepositoryGatherStats(backing)
 
1991
        repository = self.make_repository('.')
 
1992
        expected_body = 'revisions: 0\n'
 
1993
        self.assertEqual(
 
1994
            smart_req.FailedSmartServerResponse(
 
1995
                ('nosuchrevision', 'mia'), None),
 
1996
            request.execute('', 'mia', 'yes'))
 
1997
 
1572
1998
 
1573
1999
class TestSmartServerRepositoryIsShared(tests.TestCaseWithMemoryTransport):
1574
2000
 
1589
2015
            request.execute('', ))
1590
2016
 
1591
2017
 
 
2018
class TestSmartServerRepositoryGetRevisionSignatureText(
 
2019
        tests.TestCaseWithMemoryTransport):
 
2020
 
 
2021
    def test_get_signature(self):
 
2022
        backing = self.get_transport()
 
2023
        request = smart_repo.SmartServerRepositoryGetRevisionSignatureText(
 
2024
            backing)
 
2025
        bb = self.make_branch_builder('.')
 
2026
        bb.build_commit(rev_id='A')
 
2027
        repo = bb.get_branch().repository
 
2028
        strategy = gpg.LoopbackGPGStrategy(None)
 
2029
        self.addCleanup(repo.lock_write().unlock)
 
2030
        repo.start_write_group()
 
2031
        repo.sign_revision('A', strategy)
 
2032
        repo.commit_write_group()
 
2033
        expected_body = (
 
2034
            '-----BEGIN PSEUDO-SIGNED CONTENT-----\n' +
 
2035
            Testament.from_revision(repo, 'A').as_short_text() +
 
2036
            '-----END PSEUDO-SIGNED CONTENT-----\n')
 
2037
        self.assertEqual(
 
2038
            smart_req.SmartServerResponse(('ok', ), expected_body),
 
2039
            request.execute('', 'A'))
 
2040
 
 
2041
 
 
2042
class TestSmartServerRepositoryMakeWorkingTrees(
 
2043
        tests.TestCaseWithMemoryTransport):
 
2044
 
 
2045
    def test_make_working_trees(self):
 
2046
        """For a repository with working trees, ('yes', ) is returned."""
 
2047
        backing = self.get_transport()
 
2048
        request = smart_repo.SmartServerRepositoryMakeWorkingTrees(backing)
 
2049
        r = self.make_repository('.')
 
2050
        r.set_make_working_trees(True)
 
2051
        self.assertEqual(smart_req.SmartServerResponse(('yes', )),
 
2052
            request.execute('', ))
 
2053
 
 
2054
    def test_is_not_shared(self):
 
2055
        """For a repository with working trees, ('no', ) is returned."""
 
2056
        backing = self.get_transport()
 
2057
        request = smart_repo.SmartServerRepositoryMakeWorkingTrees(backing)
 
2058
        r = self.make_repository('.')
 
2059
        r.set_make_working_trees(False)
 
2060
        self.assertEqual(smart_req.SmartServerResponse(('no', )),
 
2061
            request.execute('', ))
 
2062
 
 
2063
 
1592
2064
class TestSmartServerRepositoryLockWrite(tests.TestCaseWithMemoryTransport):
1593
2065
 
1594
2066
    def test_lock_write_on_unlocked_repo(self):
1610
2082
        backing = self.get_transport()
1611
2083
        request = smart_repo.SmartServerRepositoryLockWrite(backing)
1612
2084
        repository = self.make_repository('.', format='knit')
1613
 
        repo_token = repository.lock_write()
 
2085
        repo_token = repository.lock_write().repository_token
1614
2086
        repository.leave_lock_in_place()
1615
2087
        repository.unlock()
1616
2088
        response = request.execute('')
1658
2130
        request = smart_repo.SmartServerRepositoryInsertStreamLocked(
1659
2131
            backing)
1660
2132
        repository = self.make_repository('.', format='knit')
1661
 
        lock_token = repository.lock_write()
 
2133
        lock_token = repository.lock_write().repository_token
1662
2134
        response = request.execute('', '', lock_token)
1663
2135
        self.assertEqual(None, response)
1664
2136
        response = request.do_chunk(self.make_empty_byte_stream(repository))
1672
2144
        request = smart_repo.SmartServerRepositoryInsertStreamLocked(
1673
2145
            backing)
1674
2146
        repository = self.make_repository('.', format='knit')
1675
 
        lock_token = repository.lock_write()
 
2147
        lock_token = repository.lock_write().repository_token
1676
2148
        self.assertRaises(
1677
2149
            errors.TokenMismatch, request.execute, '', '', 'wrong-token')
1678
2150
        repository.unlock()
1687
2159
        backing = self.get_transport()
1688
2160
        request = smart_repo.SmartServerRepositoryUnlock(backing)
1689
2161
        repository = self.make_repository('.', format='knit')
1690
 
        token = repository.lock_write()
 
2162
        token = repository.lock_write().repository_token
1691
2163
        repository.leave_lock_in_place()
1692
2164
        repository.unlock()
1693
2165
        response = request.execute('', token)
1708
2180
            smart_req.SmartServerResponse(('TokenMismatch',)), response)
1709
2181
 
1710
2182
 
 
2183
class TestSmartServerRepositoryGetPhysicalLockStatus(
 
2184
    tests.TestCaseWithTransport):
 
2185
 
 
2186
    def test_with_write_lock(self):
 
2187
        backing = self.get_transport()
 
2188
        repo = self.make_repository('.')
 
2189
        self.addCleanup(repo.lock_write().unlock)
 
2190
        # lock_write() doesn't necessarily actually take a physical
 
2191
        # lock out.
 
2192
        if repo.get_physical_lock_status():
 
2193
            expected = 'yes'
 
2194
        else:
 
2195
            expected = 'no'
 
2196
        request_class = smart_repo.SmartServerRepositoryGetPhysicalLockStatus
 
2197
        request = request_class(backing)
 
2198
        self.assertEqual(smart_req.SuccessfulSmartServerResponse((expected,)),
 
2199
            request.execute('', ))
 
2200
 
 
2201
    def test_without_write_lock(self):
 
2202
        backing = self.get_transport()
 
2203
        repo = self.make_repository('.')
 
2204
        self.assertEquals(False, repo.get_physical_lock_status())
 
2205
        request_class = smart_repo.SmartServerRepositoryGetPhysicalLockStatus
 
2206
        request = request_class(backing)
 
2207
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(('no',)),
 
2208
            request.execute('', ))
 
2209
 
 
2210
 
1711
2211
class TestSmartServerIsReadonly(tests.TestCaseWithMemoryTransport):
1712
2212
 
1713
2213
    def test_is_readonly_no(self):
1751
2251
        self.assertTrue(repo.make_working_trees())
1752
2252
 
1753
2253
 
 
2254
class TestSmartServerRepositoryGetSerializerFormat(
 
2255
    tests.TestCaseWithMemoryTransport):
 
2256
 
 
2257
    def test_get_serializer_format(self):
 
2258
        backing = self.get_transport()
 
2259
        repo = self.make_repository('.', format='2a')
 
2260
        request_class = smart_repo.SmartServerRepositoryGetSerializerFormat
 
2261
        request = request_class(backing)
 
2262
        self.assertEqual(
 
2263
            smart_req.SuccessfulSmartServerResponse(('ok', '10')),
 
2264
            request.execute(''))
 
2265
 
 
2266
 
 
2267
class TestSmartServerRepositoryWriteGroup(
 
2268
    tests.TestCaseWithMemoryTransport):
 
2269
 
 
2270
    def test_start_write_group(self):
 
2271
        backing = self.get_transport()
 
2272
        repo = self.make_repository('.')
 
2273
        lock_token = repo.lock_write().repository_token
 
2274
        self.addCleanup(repo.unlock)
 
2275
        request_class = smart_repo.SmartServerRepositoryStartWriteGroup
 
2276
        request = request_class(backing)
 
2277
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(('ok', [])),
 
2278
            request.execute('', lock_token))
 
2279
 
 
2280
    def test_start_write_group_unsuspendable(self):
 
2281
        backing = self.get_transport()
 
2282
        repo = self.make_repository('.', format='knit')
 
2283
        lock_token = repo.lock_write().repository_token
 
2284
        self.addCleanup(repo.unlock)
 
2285
        request_class = smart_repo.SmartServerRepositoryStartWriteGroup
 
2286
        request = request_class(backing)
 
2287
        self.assertEqual(
 
2288
            smart_req.FailedSmartServerResponse(('UnsuspendableWriteGroup',)),
 
2289
            request.execute('', lock_token))
 
2290
 
 
2291
    def test_commit_write_group(self):
 
2292
        backing = self.get_transport()
 
2293
        repo = self.make_repository('.')
 
2294
        lock_token = repo.lock_write().repository_token
 
2295
        self.addCleanup(repo.unlock)
 
2296
        repo.start_write_group()
 
2297
        tokens = repo.suspend_write_group()
 
2298
        request_class = smart_repo.SmartServerRepositoryCommitWriteGroup
 
2299
        request = request_class(backing)
 
2300
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(('ok',)),
 
2301
            request.execute('', lock_token, tokens))
 
2302
 
 
2303
    def test_abort_write_group(self):
 
2304
        backing = self.get_transport()
 
2305
        repo = self.make_repository('.')
 
2306
        lock_token = repo.lock_write().repository_token
 
2307
        repo.start_write_group()
 
2308
        tokens = repo.suspend_write_group()
 
2309
        self.addCleanup(repo.unlock)
 
2310
        request_class = smart_repo.SmartServerRepositoryAbortWriteGroup
 
2311
        request = request_class(backing)
 
2312
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(('ok',)),
 
2313
            request.execute('', lock_token, tokens))
 
2314
 
 
2315
    def test_check_write_group(self):
 
2316
        backing = self.get_transport()
 
2317
        repo = self.make_repository('.')
 
2318
        lock_token = repo.lock_write().repository_token
 
2319
        repo.start_write_group()
 
2320
        tokens = repo.suspend_write_group()
 
2321
        self.addCleanup(repo.unlock)
 
2322
        request_class = smart_repo.SmartServerRepositoryCheckWriteGroup
 
2323
        request = request_class(backing)
 
2324
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(('ok',)),
 
2325
            request.execute('', lock_token, tokens))
 
2326
 
 
2327
    def test_check_write_group_invalid(self):
 
2328
        backing = self.get_transport()
 
2329
        repo = self.make_repository('.')
 
2330
        lock_token = repo.lock_write().repository_token
 
2331
        self.addCleanup(repo.unlock)
 
2332
        request_class = smart_repo.SmartServerRepositoryCheckWriteGroup
 
2333
        request = request_class(backing)
 
2334
        self.assertEqual(smart_req.FailedSmartServerResponse(
 
2335
            ('UnresumableWriteGroup', ['random'],
 
2336
                'Malformed write group token')),
 
2337
            request.execute('', lock_token, ["random"]))
 
2338
 
 
2339
 
1754
2340
class TestSmartServerPackRepositoryAutopack(tests.TestCaseWithTransport):
1755
2341
 
1756
2342
    def make_repo_needing_autopacking(self, path='.'):
1822
2408
        """All registered request_handlers can be found."""
1823
2409
        # If there's a typo in a register_lazy call, this loop will fail with
1824
2410
        # an AttributeError.
1825
 
        for key, item in smart_req.request_handlers.iteritems():
1826
 
            pass
 
2411
        for key in smart_req.request_handlers.keys():
 
2412
            try:
 
2413
                item = smart_req.request_handlers.get(key)
 
2414
            except AttributeError, e:
 
2415
                raise AttributeError('failed to get %s: %s' % (key, e))
1827
2416
 
1828
2417
    def assertHandlerEqual(self, verb, handler):
1829
2418
        self.assertEqual(smart_req.request_handlers.get(verb), handler)
1830
2419
 
1831
2420
    def test_registered_methods(self):
1832
2421
        """Test that known methods are registered to the correct object."""
 
2422
        self.assertHandlerEqual('Branch.break_lock',
 
2423
            smart_branch.SmartServerBranchBreakLock)
1833
2424
        self.assertHandlerEqual('Branch.get_config_file',
1834
2425
            smart_branch.SmartServerBranchGetConfigFile)
 
2426
        self.assertHandlerEqual('Branch.put_config_file',
 
2427
            smart_branch.SmartServerBranchPutConfigFile)
1835
2428
        self.assertHandlerEqual('Branch.get_parent',
1836
2429
            smart_branch.SmartServerBranchGetParent)
 
2430
        self.assertHandlerEqual('Branch.get_physical_lock_status',
 
2431
            smart_branch.SmartServerBranchRequestGetPhysicalLockStatus)
1837
2432
        self.assertHandlerEqual('Branch.get_tags_bytes',
1838
2433
            smart_branch.SmartServerBranchGetTagsBytes)
1839
2434
        self.assertHandlerEqual('Branch.lock_write',
1842
2437
            smart_branch.SmartServerBranchRequestLastRevisionInfo)
1843
2438
        self.assertHandlerEqual('Branch.revision_history',
1844
2439
            smart_branch.SmartServerRequestRevisionHistory)
 
2440
        self.assertHandlerEqual('Branch.revision_id_to_revno',
 
2441
            smart_branch.SmartServerBranchRequestRevisionIdToRevno)
1845
2442
        self.assertHandlerEqual('Branch.set_config_option',
1846
2443
            smart_branch.SmartServerBranchRequestSetConfigOption)
1847
2444
        self.assertHandlerEqual('Branch.set_last_revision',
1854
2451
            smart_branch.SmartServerBranchRequestSetParentLocation)
1855
2452
        self.assertHandlerEqual('Branch.unlock',
1856
2453
            smart_branch.SmartServerBranchRequestUnlock)
 
2454
        self.assertHandlerEqual('BzrDir.destroy_branch',
 
2455
            smart_dir.SmartServerBzrDirRequestDestroyBranch)
1857
2456
        self.assertHandlerEqual('BzrDir.find_repository',
1858
2457
            smart_dir.SmartServerRequestFindRepositoryV1)
1859
2458
        self.assertHandlerEqual('BzrDir.find_repositoryV2',
1874
2473
            smart_dir.SmartServerRequestOpenBranchV3)
1875
2474
        self.assertHandlerEqual('PackRepository.autopack',
1876
2475
            smart_packrepo.SmartServerPackRepositoryAutopack)
 
2476
        self.assertHandlerEqual('Repository.add_signature_text',
 
2477
            smart_repo.SmartServerRepositoryAddSignatureText)
 
2478
        self.assertHandlerEqual('Repository.all_revision_ids',
 
2479
            smart_repo.SmartServerRepositoryAllRevisionIds)
 
2480
        self.assertHandlerEqual('Repository.break_lock',
 
2481
            smart_repo.SmartServerRepositoryBreakLock)
1877
2482
        self.assertHandlerEqual('Repository.gather_stats',
1878
2483
            smart_repo.SmartServerRepositoryGatherStats)
1879
2484
        self.assertHandlerEqual('Repository.get_parent_map',
1880
2485
            smart_repo.SmartServerRepositoryGetParentMap)
 
2486
        self.assertHandlerEqual('Repository.get_physical_lock_status',
 
2487
            smart_repo.SmartServerRepositoryGetPhysicalLockStatus)
1881
2488
        self.assertHandlerEqual('Repository.get_rev_id_for_revno',
1882
2489
            smart_repo.SmartServerRepositoryGetRevIdForRevno)
1883
2490
        self.assertHandlerEqual('Repository.get_revision_graph',
1884
2491
            smart_repo.SmartServerRepositoryGetRevisionGraph)
 
2492
        self.assertHandlerEqual('Repository.get_revision_signature_text',
 
2493
            smart_repo.SmartServerRepositoryGetRevisionSignatureText)
1885
2494
        self.assertHandlerEqual('Repository.get_stream',
1886
2495
            smart_repo.SmartServerRepositoryGetStream)
 
2496
        self.assertHandlerEqual('Repository.get_stream_1.19',
 
2497
            smart_repo.SmartServerRepositoryGetStream_1_19)
 
2498
        self.assertHandlerEqual('Repository.iter_revisions',
 
2499
            smart_repo.SmartServerRepositoryIterRevisions)
1887
2500
        self.assertHandlerEqual('Repository.has_revision',
1888
2501
            smart_repo.SmartServerRequestHasRevision)
1889
2502
        self.assertHandlerEqual('Repository.insert_stream',
1892
2505
            smart_repo.SmartServerRepositoryInsertStreamLocked)
1893
2506
        self.assertHandlerEqual('Repository.is_shared',
1894
2507
            smart_repo.SmartServerRepositoryIsShared)
 
2508
        self.assertHandlerEqual('Repository.iter_files_bytes',
 
2509
            smart_repo.SmartServerRepositoryIterFilesBytes)
1895
2510
        self.assertHandlerEqual('Repository.lock_write',
1896
2511
            smart_repo.SmartServerRepositoryLockWrite)
 
2512
        self.assertHandlerEqual('Repository.make_working_trees',
 
2513
            smart_repo.SmartServerRepositoryMakeWorkingTrees)
 
2514
        self.assertHandlerEqual('Repository.pack',
 
2515
            smart_repo.SmartServerRepositoryPack)
1897
2516
        self.assertHandlerEqual('Repository.tarball',
1898
2517
            smart_repo.SmartServerRepositoryTarball)
1899
2518
        self.assertHandlerEqual('Repository.unlock',
1900
2519
            smart_repo.SmartServerRepositoryUnlock)
 
2520
        self.assertHandlerEqual('Repository.start_write_group',
 
2521
            smart_repo.SmartServerRepositoryStartWriteGroup)
 
2522
        self.assertHandlerEqual('Repository.check_write_group',
 
2523
            smart_repo.SmartServerRepositoryCheckWriteGroup)
 
2524
        self.assertHandlerEqual('Repository.commit_write_group',
 
2525
            smart_repo.SmartServerRepositoryCommitWriteGroup)
 
2526
        self.assertHandlerEqual('Repository.abort_write_group',
 
2527
            smart_repo.SmartServerRepositoryAbortWriteGroup)
 
2528
        self.assertHandlerEqual('VersionedFileRepository.get_serializer_format',
 
2529
            smart_repo.SmartServerRepositoryGetSerializerFormat)
1901
2530
        self.assertHandlerEqual('Transport.is_readonly',
1902
2531
            smart_req.SmartServerIsReadonly)
 
2532
 
 
2533
 
 
2534
class SmartTCPServerHookTests(tests.TestCaseWithMemoryTransport):
 
2535
    """Tests for SmartTCPServer hooks."""
 
2536
 
 
2537
    def setUp(self):
 
2538
        super(SmartTCPServerHookTests, self).setUp()
 
2539
        self.server = server.SmartTCPServer(self.get_transport())
 
2540
 
 
2541
    def test_run_server_started_hooks(self):
 
2542
        """Test the server started hooks get fired properly."""
 
2543
        started_calls = []
 
2544
        server.SmartTCPServer.hooks.install_named_hook('server_started',
 
2545
            lambda backing_urls, url: started_calls.append((backing_urls, url)),
 
2546
            None)
 
2547
        started_ex_calls = []
 
2548
        server.SmartTCPServer.hooks.install_named_hook('server_started_ex',
 
2549
            lambda backing_urls, url: started_ex_calls.append((backing_urls, url)),
 
2550
            None)
 
2551
        self.server._sockname = ('example.com', 42)
 
2552
        self.server.run_server_started_hooks()
 
2553
        self.assertEquals(started_calls,
 
2554
            [([self.get_transport().base], 'bzr://example.com:42/')])
 
2555
        self.assertEquals(started_ex_calls,
 
2556
            [([self.get_transport().base], self.server)])
 
2557
 
 
2558
    def test_run_server_started_hooks_ipv6(self):
 
2559
        """Test that socknames can contain 4-tuples."""
 
2560
        self.server._sockname = ('::', 42, 0, 0)
 
2561
        started_calls = []
 
2562
        server.SmartTCPServer.hooks.install_named_hook('server_started',
 
2563
            lambda backing_urls, url: started_calls.append((backing_urls, url)),
 
2564
            None)
 
2565
        self.server.run_server_started_hooks()
 
2566
        self.assertEquals(started_calls,
 
2567
                [([self.get_transport().base], 'bzr://:::42/')])
 
2568
 
 
2569
    def test_run_server_stopped_hooks(self):
 
2570
        """Test the server stopped hooks."""
 
2571
        self.server._sockname = ('example.com', 42)
 
2572
        stopped_calls = []
 
2573
        server.SmartTCPServer.hooks.install_named_hook('server_stopped',
 
2574
            lambda backing_urls, url: stopped_calls.append((backing_urls, url)),
 
2575
            None)
 
2576
        self.server.run_server_stopped_hooks()
 
2577
        self.assertEquals(stopped_calls,
 
2578
            [([self.get_transport().base], 'bzr://example.com:42/')])
 
2579
 
 
2580
 
 
2581
class TestSmartServerRepositoryPack(tests.TestCaseWithMemoryTransport):
 
2582
 
 
2583
    def test_pack(self):
 
2584
        backing = self.get_transport()
 
2585
        request = smart_repo.SmartServerRepositoryPack(backing)
 
2586
        tree = self.make_branch_and_memory_tree('.')
 
2587
        repo_token = tree.branch.repository.lock_write().repository_token
 
2588
 
 
2589
        self.assertIs(None, request.execute('', repo_token, False))
 
2590
 
 
2591
        self.assertEqual(
 
2592
            smart_req.SuccessfulSmartServerResponse(('ok', ), ),
 
2593
            request.do_body(''))
 
2594