~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_smart.py

  • Committer: Tarmac
  • Author(s): Vincent Ladeuil
  • Date: 2017-01-30 14:42:05 UTC
  • mfrom: (6620.1.1 trunk)
  • Revision ID: tarmac-20170130144205-r8fh2xpmiuxyozpv
Merge  2.7 into trunk including fix for bug #1657238 [r=vila]

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2006-2011 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
import zlib
28
29
 
29
30
from bzrlib import (
 
31
    bencode,
30
32
    branch as _mod_branch,
31
 
    bzrdir,
 
33
    controldir,
32
34
    errors,
 
35
    gpg,
 
36
    inventory_delta,
33
37
    tests,
34
38
    transport,
35
39
    urlutils,
44
48
    server,
45
49
    vfs,
46
50
    )
 
51
from bzrlib.testament import Testament
47
52
from bzrlib.tests import test_server
48
53
from bzrlib.transport import (
49
54
    chroot,
77
82
 
78
83
    def setUp(self):
79
84
        self.vfs_transport_factory = memory.MemoryServer
80
 
        tests.TestCaseWithTransport.setUp(self)
 
85
        super(TestCaseWithChrootedTransport, self).setUp()
81
86
        self._chroot_server = None
82
87
 
83
88
    def get_transport(self, relpath=None):
85
90
            backing_transport = tests.TestCaseWithTransport.get_transport(self)
86
91
            self._chroot_server = chroot.ChrootServer(backing_transport)
87
92
            self.start_server(self._chroot_server)
88
 
        t = transport.get_transport(self._chroot_server.get_url())
 
93
        t = transport.get_transport_from_url(self._chroot_server.get_url())
89
94
        if relpath is not None:
90
95
            t = t.clone(relpath)
91
96
        return t
116
121
        stream = [('text', [versionedfile.FulltextContentFactory(('k1',), None,
117
122
            None, 'foo')]),('text', [
118
123
            versionedfile.FulltextContentFactory(('k2',), None, None, 'bar')])]
119
 
        fmt = bzrdir.format_registry.get('pack-0.92')().repository_format
 
124
        fmt = controldir.format_registry.get('pack-0.92')().repository_format
120
125
        bytes = smart_repo._stream_to_byte_stream(stream, fmt)
121
126
        streams = []
122
127
        # Iterate the resulting iterable; checking that we get only one stream
221
226
        self.assertEqual(expected, request.execute('', 'False'))
222
227
 
223
228
 
 
229
class TestSmartServerBzrDirRequestCloningMetaDir(
 
230
    tests.TestCaseWithMemoryTransport):
 
231
    """Tests for BzrDir.checkout_metadir."""
 
232
 
 
233
    def test_checkout_metadir(self):
 
234
        backing = self.get_transport()
 
235
        request = smart_dir.SmartServerBzrDirRequestCheckoutMetaDir(
 
236
            backing)
 
237
        branch = self.make_branch('.', format='2a')
 
238
        response = request.execute('')
 
239
        self.assertEqual(
 
240
            smart_req.SmartServerResponse(
 
241
                ('Bazaar-NG meta directory, format 1\n',
 
242
                 'Bazaar repository format 2a (needs bzr 1.16 or later)\n',
 
243
                 'Bazaar Branch Format 7 (needs bzr 1.6)\n')),
 
244
            response)
 
245
 
 
246
 
 
247
class TestSmartServerBzrDirRequestDestroyBranch(
 
248
    tests.TestCaseWithMemoryTransport):
 
249
    """Tests for BzrDir.destroy_branch."""
 
250
 
 
251
    def test_destroy_branch_default(self):
 
252
        """The default branch can be removed."""
 
253
        backing = self.get_transport()
 
254
        dir = self.make_branch('.').bzrdir
 
255
        request_class = smart_dir.SmartServerBzrDirRequestDestroyBranch
 
256
        request = request_class(backing)
 
257
        expected = smart_req.SuccessfulSmartServerResponse(('ok',))
 
258
        self.assertEqual(expected, request.execute('', None))
 
259
 
 
260
    def test_destroy_branch_named(self):
 
261
        """A named branch can be removed."""
 
262
        backing = self.get_transport()
 
263
        dir = self.make_repository('.', format="development-colo").bzrdir
 
264
        dir.create_branch(name="branchname")
 
265
        request_class = smart_dir.SmartServerBzrDirRequestDestroyBranch
 
266
        request = request_class(backing)
 
267
        expected = smart_req.SuccessfulSmartServerResponse(('ok',))
 
268
        self.assertEqual(expected, request.execute('', "branchname"))
 
269
 
 
270
    def test_destroy_branch_missing(self):
 
271
        """An error is raised if the branch didn't exist."""
 
272
        backing = self.get_transport()
 
273
        dir = self.make_bzrdir('.', format="development-colo")
 
274
        request_class = smart_dir.SmartServerBzrDirRequestDestroyBranch
 
275
        request = request_class(backing)
 
276
        expected = smart_req.FailedSmartServerResponse(('nobranch',), None)
 
277
        self.assertEqual(expected, request.execute('', "branchname"))
 
278
 
 
279
 
 
280
class TestSmartServerBzrDirRequestHasWorkingTree(
 
281
    tests.TestCaseWithTransport):
 
282
    """Tests for BzrDir.has_workingtree."""
 
283
 
 
284
    def test_has_workingtree_yes(self):
 
285
        """A working tree is present."""
 
286
        backing = self.get_transport()
 
287
        dir = self.make_branch_and_tree('.').bzrdir
 
288
        request_class = smart_dir.SmartServerBzrDirRequestHasWorkingTree
 
289
        request = request_class(backing)
 
290
        expected = smart_req.SuccessfulSmartServerResponse(('yes',))
 
291
        self.assertEqual(expected, request.execute(''))
 
292
 
 
293
    def test_has_workingtree_no(self):
 
294
        """A working tree is missing."""
 
295
        backing = self.get_transport()
 
296
        dir = self.make_bzrdir('.')
 
297
        request_class = smart_dir.SmartServerBzrDirRequestHasWorkingTree
 
298
        request = request_class(backing)
 
299
        expected = smart_req.SuccessfulSmartServerResponse(('no',))
 
300
        self.assertEqual(expected, request.execute(''))
 
301
 
 
302
 
 
303
class TestSmartServerBzrDirRequestDestroyRepository(
 
304
    tests.TestCaseWithMemoryTransport):
 
305
    """Tests for BzrDir.destroy_repository."""
 
306
 
 
307
    def test_destroy_repository_default(self):
 
308
        """The repository can be removed."""
 
309
        backing = self.get_transport()
 
310
        dir = self.make_repository('.').bzrdir
 
311
        request_class = smart_dir.SmartServerBzrDirRequestDestroyRepository
 
312
        request = request_class(backing)
 
313
        expected = smart_req.SuccessfulSmartServerResponse(('ok',))
 
314
        self.assertEqual(expected, request.execute(''))
 
315
 
 
316
    def test_destroy_repository_missing(self):
 
317
        """An error is raised if the repository didn't exist."""
 
318
        backing = self.get_transport()
 
319
        dir = self.make_bzrdir('.')
 
320
        request_class = smart_dir.SmartServerBzrDirRequestDestroyRepository
 
321
        request = request_class(backing)
 
322
        expected = smart_req.FailedSmartServerResponse(
 
323
            ('norepository',), None)
 
324
        self.assertEqual(expected, request.execute(''))
 
325
 
 
326
 
224
327
class TestSmartServerRequestCreateRepository(tests.TestCaseWithMemoryTransport):
225
328
    """Tests for BzrDir.create_repository."""
226
329
 
230
333
        self.make_bzrdir('.')
231
334
        request_class = smart_dir.SmartServerRequestCreateRepository
232
335
        request = request_class(backing)
233
 
        reference_bzrdir_format = bzrdir.format_registry.get('pack-0.92')()
 
336
        reference_bzrdir_format = controldir.format_registry.get('pack-0.92')()
234
337
        reference_format = reference_bzrdir_format.repository_format
235
338
        network_name = reference_format.network_name()
236
339
        expected = smart_req.SuccessfulSmartServerResponse(
316
419
        backing = self.get_transport()
317
420
        request = self._request_class(backing)
318
421
        result = self._make_repository_and_result(
319
 
            format='dirstate-with-subtree')
 
422
            format='development-subtree')
320
423
        # check the test will be valid
321
424
        self.assertEqual('yes', result.args[2])
322
425
        self.assertEqual('yes', result.args[3])
327
430
        backing = self.get_transport()
328
431
        request = self._request_class(backing)
329
432
        result = self._make_repository_and_result(
330
 
            format='dirstate-with-subtree')
 
433
            format='development-subtree')
331
434
        # check the test will be valid
332
 
        self.assertEqual('no', result.args[4])
 
435
        self.assertEqual('yes', result.args[4])
333
436
        self.assertEqual(result, request.execute(''))
334
437
 
335
438
 
356
459
        self.assertEqual(expected, request.execute(''))
357
460
 
358
461
 
 
462
class TestSmartServerBzrDirRequestGetBranches(
 
463
    tests.TestCaseWithMemoryTransport):
 
464
    """Tests for BzrDir.get_branches."""
 
465
 
 
466
    def test_simple(self):
 
467
        backing = self.get_transport()
 
468
        branch = self.make_branch('.')
 
469
        request_class = smart_dir.SmartServerBzrDirRequestGetBranches
 
470
        request = request_class(backing)
 
471
        local_result = bencode.bencode(
 
472
            {"": ("branch", branch._format.network_name())})
 
473
        expected = smart_req.SuccessfulSmartServerResponse(
 
474
            ("success", ), local_result)
 
475
        self.assertEqual(expected, request.execute(''))
 
476
 
 
477
    def test_empty(self):
 
478
        backing = self.get_transport()
 
479
        dir = self.make_bzrdir('.')
 
480
        request_class = smart_dir.SmartServerBzrDirRequestGetBranches
 
481
        request = request_class(backing)
 
482
        local_result = bencode.bencode({})
 
483
        expected = smart_req.SuccessfulSmartServerResponse(
 
484
            ('success',), local_result)
 
485
        self.assertEqual(expected, request.execute(''))
 
486
 
 
487
 
359
488
class TestSmartServerRequestInitializeBzrDir(tests.TestCaseWithMemoryTransport):
360
489
 
361
490
    def test_empty_dir(self):
364
493
        request = smart_dir.SmartServerRequestInitializeBzrDir(backing)
365
494
        self.assertEqual(smart_req.SmartServerResponse(('ok', )),
366
495
            request.execute(''))
367
 
        made_dir = bzrdir.BzrDir.open_from_transport(backing)
 
496
        made_dir = controldir.ControlDir.open_from_transport(backing)
368
497
        # no branch, tree or repository is expected with the current
369
498
        # default formart.
370
499
        self.assertRaises(errors.NoWorkingTree, made_dir.open_workingtree)
383
512
        backing = self.get_transport()
384
513
        request = smart_dir.SmartServerRequestInitializeBzrDir(backing)
385
514
        self.make_bzrdir('subdir')
386
 
        self.assertRaises(errors.FileExists,
 
515
        self.assertRaises(errors.AlreadyControlDirError,
387
516
            request.execute, 'subdir')
388
517
 
389
518
 
404
533
                                           'False', '', '', '')),
405
534
            request.execute(name, '', 'True', 'False', 'False', '', '', '', '',
406
535
                            'False'))
407
 
        made_dir = bzrdir.BzrDir.open_from_transport(backing)
 
536
        made_dir = controldir.ControlDir.open_from_transport(backing)
408
537
        # no branch, tree or repository is expected with the current
409
538
        # default format.
410
539
        self.assertRaises(errors.NoWorkingTree, made_dir.open_workingtree)
735
864
            request.execute(''))
736
865
 
737
866
 
 
867
class TestSmartServerBranchRequestRevisionIdToRevno(
 
868
    tests.TestCaseWithMemoryTransport):
 
869
 
 
870
    def test_null(self):
 
871
        backing = self.get_transport()
 
872
        request = smart_branch.SmartServerBranchRequestRevisionIdToRevno(
 
873
            backing)
 
874
        self.make_branch('.')
 
875
        self.assertEqual(smart_req.SmartServerResponse(('ok', '0')),
 
876
            request.execute('', 'null:'))
 
877
 
 
878
    def test_simple(self):
 
879
        backing = self.get_transport()
 
880
        request = smart_branch.SmartServerBranchRequestRevisionIdToRevno(
 
881
            backing)
 
882
        tree = self.make_branch_and_memory_tree('.')
 
883
        tree.lock_write()
 
884
        tree.add('')
 
885
        r1 = tree.commit('1st commit')
 
886
        tree.unlock()
 
887
        self.assertEqual(
 
888
            smart_req.SmartServerResponse(('ok', '1')),
 
889
            request.execute('', r1))
 
890
 
 
891
    def test_not_found(self):
 
892
        backing = self.get_transport()
 
893
        request = smart_branch.SmartServerBranchRequestRevisionIdToRevno(
 
894
            backing)
 
895
        branch = self.make_branch('.')
 
896
        self.assertEqual(
 
897
            smart_req.FailedSmartServerResponse(
 
898
                ('NoSuchRevision', 'idontexist')),
 
899
            request.execute('', 'idontexist'))
 
900
 
 
901
 
738
902
class TestSmartServerBranchRequestGetConfigFile(
739
903
    tests.TestCaseWithMemoryTransport):
740
904
 
769
933
        return branch_token, repo_token
770
934
 
771
935
 
 
936
class TestSmartServerBranchRequestPutConfigFile(TestLockedBranch):
 
937
 
 
938
    def test_with_content(self):
 
939
        backing = self.get_transport()
 
940
        request = smart_branch.SmartServerBranchPutConfigFile(backing)
 
941
        branch = self.make_branch('.')
 
942
        branch_token, repo_token = self.get_lock_tokens(branch)
 
943
        self.assertIs(None, request.execute('', branch_token, repo_token))
 
944
        self.assertEqual(
 
945
            smart_req.SmartServerResponse(('ok', )),
 
946
            request.do_body('foo bar baz'))
 
947
        self.assertEqual(
 
948
            branch.control_transport.get_bytes('branch.conf'),
 
949
            'foo bar baz')
 
950
        branch.unlock()
 
951
 
 
952
 
772
953
class TestSmartServerBranchRequestSetConfigOption(TestLockedBranch):
773
954
 
774
955
    def test_value_name(self):
852
1033
        response = request.do_chunk(tag_bytes)
853
1034
        self.assertEqual(None, response)
854
1035
        response = request.do_end()
855
 
        self.assertEquals(
 
1036
        self.assertEqual(
856
1037
            smart_req.SuccessfulSmartServerResponse(()), response)
857
1038
        base_branch.unlock()
858
1039
 
877
1058
    """Base test case for verbs that implement set_last_revision."""
878
1059
 
879
1060
    def setUp(self):
880
 
        tests.TestCaseWithMemoryTransport.setUp(self)
 
1061
        super(SetLastRevisionTestBase, self).setUp()
881
1062
        backing_transport = self.get_transport()
882
1063
        self.request = self.request_class(backing_transport)
883
1064
        self.tree = self.make_branch_and_memory_tree('.')
1088
1269
        self.assertEqual('child-1', self.tree.branch.last_revision())
1089
1270
 
1090
1271
 
 
1272
class TestSmartServerBranchBreakLock(tests.TestCaseWithMemoryTransport):
 
1273
 
 
1274
    def test_lock_to_break(self):
 
1275
        base_branch = self.make_branch('base')
 
1276
        request = smart_branch.SmartServerBranchBreakLock(
 
1277
            self.get_transport())
 
1278
        base_branch.lock_write()
 
1279
        self.assertEqual(
 
1280
            smart_req.SuccessfulSmartServerResponse(('ok', ), None),
 
1281
            request.execute('base'))
 
1282
 
 
1283
    def test_nothing_to_break(self):
 
1284
        base_branch = self.make_branch('base')
 
1285
        request = smart_branch.SmartServerBranchBreakLock(
 
1286
            self.get_transport())
 
1287
        self.assertEqual(
 
1288
            smart_req.SuccessfulSmartServerResponse(('ok', ), None),
 
1289
            request.execute('base'))
 
1290
 
 
1291
 
1091
1292
class TestSmartServerBranchRequestGetParent(tests.TestCaseWithMemoryTransport):
1092
1293
 
1093
1294
    def test_get_parent_none(self):
1094
1295
        base_branch = self.make_branch('base')
1095
1296
        request = smart_branch.SmartServerBranchGetParent(self.get_transport())
1096
1297
        response = request.execute('base')
1097
 
        self.assertEquals(
 
1298
        self.assertEqual(
1098
1299
            smart_req.SuccessfulSmartServerResponse(('',)), response)
1099
1300
 
1100
1301
    def test_get_parent_something(self):
1102
1303
        base_branch.set_parent(self.get_url('foo'))
1103
1304
        request = smart_branch.SmartServerBranchGetParent(self.get_transport())
1104
1305
        response = request.execute('base')
1105
 
        self.assertEquals(
 
1306
        self.assertEqual(
1106
1307
            smart_req.SuccessfulSmartServerResponse(("../foo",)),
1107
1308
            response)
1108
1309
 
1122
1323
        finally:
1123
1324
            branch.unlock()
1124
1325
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(()), response)
 
1326
        # Refresh branch as SetParentLocation modified it
 
1327
        branch = branch.bzrdir.open_branch()
1125
1328
        self.assertEqual(None, branch.get_parent())
1126
1329
 
1127
1330
    def test_set_parent_something(self):
1131
1334
        branch_token, repo_token = self.get_lock_tokens(branch)
1132
1335
        try:
1133
1336
            response = request.execute('base', branch_token, repo_token,
1134
 
            'http://bar/')
 
1337
                                       'http://bar/')
1135
1338
        finally:
1136
1339
            branch.unlock()
1137
1340
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(()), response)
1138
 
        self.assertEqual('http://bar/', branch.get_parent())
 
1341
        refreshed = _mod_branch.Branch.open(branch.base)
 
1342
        self.assertEqual('http://bar/', refreshed.get_parent())
1139
1343
 
1140
1344
 
1141
1345
class TestSmartServerBranchRequestGetTagsBytes(
1148
1352
        request = smart_branch.SmartServerBranchGetTagsBytes(
1149
1353
            self.get_transport())
1150
1354
        response = request.execute('base')
1151
 
        self.assertEquals(
 
1355
        self.assertEqual(
1152
1356
            smart_req.SuccessfulSmartServerResponse(('',)), response)
1153
1357
 
1154
1358
 
1162
1366
        request = smart_branch.SmartServerBranchRequestGetStackedOnURL(
1163
1367
            self.get_transport())
1164
1368
        response = request.execute('stacked')
1165
 
        self.assertEquals(
 
1369
        self.assertEqual(
1166
1370
            smart_req.SmartServerResponse(('ok', '../base')),
1167
1371
            response)
1168
1372
 
1169
1373
 
1170
1374
class TestSmartServerBranchRequestLockWrite(TestLockedBranch):
1171
1375
 
1172
 
    def setUp(self):
1173
 
        tests.TestCaseWithMemoryTransport.setUp(self)
1174
 
 
1175
1376
    def test_lock_write_on_unlocked_branch(self):
1176
1377
        backing = self.get_transport()
1177
1378
        request = smart_branch.SmartServerBranchRequestLockWrite(backing)
1275
1476
        self.assertEqual('LockFailed', error_name)
1276
1477
 
1277
1478
 
 
1479
class TestSmartServerBranchRequestGetPhysicalLockStatus(TestLockedBranch):
 
1480
 
 
1481
    def test_true(self):
 
1482
        backing = self.get_transport()
 
1483
        request = smart_branch.SmartServerBranchRequestGetPhysicalLockStatus(
 
1484
            backing)
 
1485
        branch = self.make_branch('.')
 
1486
        branch_token, repo_token = self.get_lock_tokens(branch)
 
1487
        self.assertEqual(True, branch.get_physical_lock_status())
 
1488
        response = request.execute('')
 
1489
        self.assertEqual(
 
1490
            smart_req.SmartServerResponse(('yes',)), response)
 
1491
        branch.unlock()
 
1492
 
 
1493
    def test_false(self):
 
1494
        backing = self.get_transport()
 
1495
        request = smart_branch.SmartServerBranchRequestGetPhysicalLockStatus(
 
1496
            backing)
 
1497
        branch = self.make_branch('.')
 
1498
        self.assertEqual(False, branch.get_physical_lock_status())
 
1499
        response = request.execute('')
 
1500
        self.assertEqual(
 
1501
            smart_req.SmartServerResponse(('no',)), response)
 
1502
 
 
1503
 
1278
1504
class TestSmartServerBranchRequestUnlock(TestLockedBranch):
1279
1505
 
1280
 
    def setUp(self):
1281
 
        tests.TestCaseWithMemoryTransport.setUp(self)
1282
 
 
1283
1506
    def test_unlock_on_locked_branch_and_repo(self):
1284
1507
        backing = self.get_transport()
1285
1508
        request = smart_branch.SmartServerBranchRequestUnlock(backing)
1345
1568
            request.execute, 'subdir')
1346
1569
 
1347
1570
 
 
1571
class TestSmartServerRepositoryAddSignatureText(tests.TestCaseWithMemoryTransport):
 
1572
 
 
1573
    def test_add_text(self):
 
1574
        backing = self.get_transport()
 
1575
        request = smart_repo.SmartServerRepositoryAddSignatureText(backing)
 
1576
        tree = self.make_branch_and_memory_tree('.')
 
1577
        write_token = tree.lock_write()
 
1578
        self.addCleanup(tree.unlock)
 
1579
        tree.add('')
 
1580
        tree.commit("Message", rev_id='rev1')
 
1581
        tree.branch.repository.start_write_group()
 
1582
        write_group_tokens = tree.branch.repository.suspend_write_group()
 
1583
        self.assertEqual(None, request.execute('', write_token,
 
1584
            'rev1', *write_group_tokens))
 
1585
        response = request.do_body('somesignature')
 
1586
        self.assertTrue(response.is_successful())
 
1587
        self.assertEqual(response.args[0], 'ok')
 
1588
        write_group_tokens = response.args[1:]
 
1589
        tree.branch.repository.resume_write_group(write_group_tokens)
 
1590
        tree.branch.repository.commit_write_group()
 
1591
        tree.unlock()
 
1592
        self.assertEqual("somesignature",
 
1593
            tree.branch.repository.get_signature_text("rev1"))
 
1594
 
 
1595
 
 
1596
class TestSmartServerRepositoryAllRevisionIds(
 
1597
    tests.TestCaseWithMemoryTransport):
 
1598
 
 
1599
    def test_empty(self):
 
1600
        """An empty body should be returned for an empty repository."""
 
1601
        backing = self.get_transport()
 
1602
        request = smart_repo.SmartServerRepositoryAllRevisionIds(backing)
 
1603
        self.make_repository('.')
 
1604
        self.assertEqual(
 
1605
            smart_req.SuccessfulSmartServerResponse(("ok", ), ""),
 
1606
            request.execute(''))
 
1607
 
 
1608
    def test_some_revisions(self):
 
1609
        """An empty body should be returned for an empty repository."""
 
1610
        backing = self.get_transport()
 
1611
        request = smart_repo.SmartServerRepositoryAllRevisionIds(backing)
 
1612
        tree = self.make_branch_and_memory_tree('.')
 
1613
        tree.lock_write()
 
1614
        tree.add('')
 
1615
        tree.commit(rev_id='origineel', message="message")
 
1616
        tree.commit(rev_id='nog-een-revisie', message="message")
 
1617
        tree.unlock()
 
1618
        self.assertEqual(
 
1619
            smart_req.SuccessfulSmartServerResponse(("ok", ),
 
1620
                "origineel\nnog-een-revisie"),
 
1621
            request.execute(''))
 
1622
 
 
1623
 
 
1624
class TestSmartServerRepositoryBreakLock(tests.TestCaseWithMemoryTransport):
 
1625
 
 
1626
    def test_lock_to_break(self):
 
1627
        backing = self.get_transport()
 
1628
        request = smart_repo.SmartServerRepositoryBreakLock(backing)
 
1629
        tree = self.make_branch_and_memory_tree('.')
 
1630
        tree.branch.repository.lock_write()
 
1631
        self.assertEqual(
 
1632
            smart_req.SuccessfulSmartServerResponse(('ok', ), None),
 
1633
            request.execute(''))
 
1634
 
 
1635
    def test_nothing_to_break(self):
 
1636
        backing = self.get_transport()
 
1637
        request = smart_repo.SmartServerRepositoryBreakLock(backing)
 
1638
        tree = self.make_branch_and_memory_tree('.')
 
1639
        self.assertEqual(
 
1640
            smart_req.SuccessfulSmartServerResponse(('ok', ), None),
 
1641
            request.execute(''))
 
1642
 
 
1643
 
1348
1644
class TestSmartServerRepositoryGetParentMap(tests.TestCaseWithMemoryTransport):
1349
1645
 
1350
1646
    def test_trivial_bzipped(self):
1470
1766
            request.execute('stacked', 1, (3, r3)))
1471
1767
 
1472
1768
 
 
1769
class TestSmartServerRepositoryIterRevisions(
 
1770
    tests.TestCaseWithMemoryTransport):
 
1771
 
 
1772
    def test_basic(self):
 
1773
        backing = self.get_transport()
 
1774
        request = smart_repo.SmartServerRepositoryIterRevisions(backing)
 
1775
        tree = self.make_branch_and_memory_tree('.', format='2a')
 
1776
        tree.lock_write()
 
1777
        tree.add('')
 
1778
        tree.commit('1st commit', rev_id="rev1")
 
1779
        tree.commit('2nd commit', rev_id="rev2")
 
1780
        tree.unlock()
 
1781
 
 
1782
        self.assertIs(None, request.execute(''))
 
1783
        response = request.do_body("rev1\nrev2")
 
1784
        self.assertTrue(response.is_successful())
 
1785
        # Format 2a uses serializer format 10
 
1786
        self.assertEqual(response.args, ("ok", "10"))
 
1787
 
 
1788
        self.addCleanup(tree.branch.lock_read().unlock)
 
1789
        entries = [zlib.compress(record.get_bytes_as("fulltext")) for record in
 
1790
            tree.branch.repository.revisions.get_record_stream(
 
1791
            [("rev1", ), ("rev2", )], "unordered", True)]
 
1792
 
 
1793
        contents = "".join(response.body_stream)
 
1794
        self.assertTrue(contents in (
 
1795
            "".join([entries[0], entries[1]]),
 
1796
            "".join([entries[1], entries[0]])))
 
1797
 
 
1798
    def test_missing(self):
 
1799
        backing = self.get_transport()
 
1800
        request = smart_repo.SmartServerRepositoryIterRevisions(backing)
 
1801
        tree = self.make_branch_and_memory_tree('.', format='2a')
 
1802
 
 
1803
        self.assertIs(None, request.execute(''))
 
1804
        response = request.do_body("rev1\nrev2")
 
1805
        self.assertTrue(response.is_successful())
 
1806
        # Format 2a uses serializer format 10
 
1807
        self.assertEqual(response.args, ("ok", "10"))
 
1808
 
 
1809
        contents = "".join(response.body_stream)
 
1810
        self.assertEqual(contents, "")
 
1811
 
 
1812
 
1473
1813
class GetStreamTestBase(tests.TestCaseWithMemoryTransport):
1474
1814
 
1475
1815
    def make_two_commit_repo(self):
1549
1889
            request.execute('', rev_id_utf8))
1550
1890
 
1551
1891
 
 
1892
class TestSmartServerRepositoryIterFilesBytes(tests.TestCaseWithTransport):
 
1893
 
 
1894
    def test_single(self):
 
1895
        backing = self.get_transport()
 
1896
        request = smart_repo.SmartServerRepositoryIterFilesBytes(backing)
 
1897
        t = self.make_branch_and_tree('.')
 
1898
        self.addCleanup(t.lock_write().unlock)
 
1899
        self.build_tree_contents([("file", "somecontents")])
 
1900
        t.add(["file"], ["thefileid"])
 
1901
        t.commit(rev_id='somerev', message="add file")
 
1902
        self.assertIs(None, request.execute(''))
 
1903
        response = request.do_body("thefileid\0somerev\n")
 
1904
        self.assertTrue(response.is_successful())
 
1905
        self.assertEqual(response.args, ("ok", ))
 
1906
        self.assertEqual("".join(response.body_stream),
 
1907
            "ok\x000\n" + zlib.compress("somecontents"))
 
1908
 
 
1909
    def test_missing(self):
 
1910
        backing = self.get_transport()
 
1911
        request = smart_repo.SmartServerRepositoryIterFilesBytes(backing)
 
1912
        t = self.make_branch_and_tree('.')
 
1913
        self.addCleanup(t.lock_write().unlock)
 
1914
        self.assertIs(None, request.execute(''))
 
1915
        response = request.do_body("thefileid\0revision\n")
 
1916
        self.assertTrue(response.is_successful())
 
1917
        self.assertEqual(response.args, ("ok", ))
 
1918
        self.assertEqual("".join(response.body_stream),
 
1919
            "absent\x00thefileid\x00revision\x000\n")
 
1920
 
 
1921
 
 
1922
class TestSmartServerRequestHasSignatureForRevisionId(
 
1923
        tests.TestCaseWithMemoryTransport):
 
1924
 
 
1925
    def test_missing_revision(self):
 
1926
        """For a missing revision, NoSuchRevision is returned."""
 
1927
        backing = self.get_transport()
 
1928
        request = smart_repo.SmartServerRequestHasSignatureForRevisionId(
 
1929
            backing)
 
1930
        self.make_repository('.')
 
1931
        self.assertEqual(
 
1932
            smart_req.FailedSmartServerResponse(
 
1933
                ('nosuchrevision', 'revid'), None),
 
1934
            request.execute('', 'revid'))
 
1935
 
 
1936
    def test_missing_signature(self):
 
1937
        """For a missing signature, ('no', ) is returned."""
 
1938
        backing = self.get_transport()
 
1939
        request = smart_repo.SmartServerRequestHasSignatureForRevisionId(
 
1940
            backing)
 
1941
        tree = self.make_branch_and_memory_tree('.')
 
1942
        tree.lock_write()
 
1943
        tree.add('')
 
1944
        r1 = tree.commit('a commit', rev_id='A')
 
1945
        tree.unlock()
 
1946
        self.assertTrue(tree.branch.repository.has_revision('A'))
 
1947
        self.assertEqual(smart_req.SmartServerResponse(('no', )),
 
1948
            request.execute('', 'A'))
 
1949
 
 
1950
    def test_present_signature(self):
 
1951
        """For a present signature, ('yes', ) is returned."""
 
1952
        backing = self.get_transport()
 
1953
        request = smart_repo.SmartServerRequestHasSignatureForRevisionId(
 
1954
            backing)
 
1955
        strategy = gpg.LoopbackGPGStrategy(None)
 
1956
        tree = self.make_branch_and_memory_tree('.')
 
1957
        tree.lock_write()
 
1958
        tree.add('')
 
1959
        r1 = tree.commit('a commit', rev_id='A')
 
1960
        tree.branch.repository.start_write_group()
 
1961
        tree.branch.repository.sign_revision('A', strategy)
 
1962
        tree.branch.repository.commit_write_group()
 
1963
        tree.unlock()
 
1964
        self.assertTrue(tree.branch.repository.has_revision('A'))
 
1965
        self.assertEqual(smart_req.SmartServerResponse(('yes', )),
 
1966
            request.execute('', 'A'))
 
1967
 
 
1968
 
1552
1969
class TestSmartServerRepositoryGatherStats(tests.TestCaseWithMemoryTransport):
1553
1970
 
1554
1971
    def test_empty_revid(self):
1607
2024
                         request.execute('',
1608
2025
                                         rev_id_utf8, 'yes'))
1609
2026
 
 
2027
    def test_unknown_revid(self):
 
2028
        """An unknown revision id causes a 'nosuchrevision' error."""
 
2029
        backing = self.get_transport()
 
2030
        request = smart_repo.SmartServerRepositoryGatherStats(backing)
 
2031
        repository = self.make_repository('.')
 
2032
        expected_body = 'revisions: 0\n'
 
2033
        self.assertEqual(
 
2034
            smart_req.FailedSmartServerResponse(
 
2035
                ('nosuchrevision', 'mia'), None),
 
2036
            request.execute('', 'mia', 'yes'))
 
2037
 
1610
2038
 
1611
2039
class TestSmartServerRepositoryIsShared(tests.TestCaseWithMemoryTransport):
1612
2040
 
1627
2055
            request.execute('', ))
1628
2056
 
1629
2057
 
 
2058
class TestSmartServerRepositoryGetRevisionSignatureText(
 
2059
        tests.TestCaseWithMemoryTransport):
 
2060
 
 
2061
    def test_get_signature(self):
 
2062
        backing = self.get_transport()
 
2063
        request = smart_repo.SmartServerRepositoryGetRevisionSignatureText(
 
2064
            backing)
 
2065
        bb = self.make_branch_builder('.')
 
2066
        bb.build_commit(rev_id='A')
 
2067
        repo = bb.get_branch().repository
 
2068
        strategy = gpg.LoopbackGPGStrategy(None)
 
2069
        self.addCleanup(repo.lock_write().unlock)
 
2070
        repo.start_write_group()
 
2071
        repo.sign_revision('A', strategy)
 
2072
        repo.commit_write_group()
 
2073
        expected_body = (
 
2074
            '-----BEGIN PSEUDO-SIGNED CONTENT-----\n' +
 
2075
            Testament.from_revision(repo, 'A').as_short_text() +
 
2076
            '-----END PSEUDO-SIGNED CONTENT-----\n')
 
2077
        self.assertEqual(
 
2078
            smart_req.SmartServerResponse(('ok', ), expected_body),
 
2079
            request.execute('', 'A'))
 
2080
 
 
2081
 
 
2082
class TestSmartServerRepositoryMakeWorkingTrees(
 
2083
        tests.TestCaseWithMemoryTransport):
 
2084
 
 
2085
    def test_make_working_trees(self):
 
2086
        """For a repository with working trees, ('yes', ) is returned."""
 
2087
        backing = self.get_transport()
 
2088
        request = smart_repo.SmartServerRepositoryMakeWorkingTrees(backing)
 
2089
        r = self.make_repository('.')
 
2090
        r.set_make_working_trees(True)
 
2091
        self.assertEqual(smart_req.SmartServerResponse(('yes', )),
 
2092
            request.execute('', ))
 
2093
 
 
2094
    def test_is_not_shared(self):
 
2095
        """For a repository with working trees, ('no', ) is returned."""
 
2096
        backing = self.get_transport()
 
2097
        request = smart_repo.SmartServerRepositoryMakeWorkingTrees(backing)
 
2098
        r = self.make_repository('.')
 
2099
        r.set_make_working_trees(False)
 
2100
        self.assertEqual(smart_req.SmartServerResponse(('no', )),
 
2101
            request.execute('', ))
 
2102
 
 
2103
 
1630
2104
class TestSmartServerRepositoryLockWrite(tests.TestCaseWithMemoryTransport):
1631
2105
 
1632
2106
    def test_lock_write_on_unlocked_repo(self):
1718
2192
 
1719
2193
class TestSmartServerRepositoryUnlock(tests.TestCaseWithMemoryTransport):
1720
2194
 
1721
 
    def setUp(self):
1722
 
        tests.TestCaseWithMemoryTransport.setUp(self)
1723
 
 
1724
2195
    def test_unlock_on_locked_repo(self):
1725
2196
        backing = self.get_transport()
1726
2197
        request = smart_repo.SmartServerRepositoryUnlock(backing)
1746
2217
            smart_req.SmartServerResponse(('TokenMismatch',)), response)
1747
2218
 
1748
2219
 
 
2220
class TestSmartServerRepositoryGetPhysicalLockStatus(
 
2221
    tests.TestCaseWithTransport):
 
2222
 
 
2223
    def test_with_write_lock(self):
 
2224
        backing = self.get_transport()
 
2225
        repo = self.make_repository('.')
 
2226
        self.addCleanup(repo.lock_write().unlock)
 
2227
        # lock_write() doesn't necessarily actually take a physical
 
2228
        # lock out.
 
2229
        if repo.get_physical_lock_status():
 
2230
            expected = 'yes'
 
2231
        else:
 
2232
            expected = 'no'
 
2233
        request_class = smart_repo.SmartServerRepositoryGetPhysicalLockStatus
 
2234
        request = request_class(backing)
 
2235
        self.assertEqual(smart_req.SuccessfulSmartServerResponse((expected,)),
 
2236
            request.execute('', ))
 
2237
 
 
2238
    def test_without_write_lock(self):
 
2239
        backing = self.get_transport()
 
2240
        repo = self.make_repository('.')
 
2241
        self.assertEqual(False, repo.get_physical_lock_status())
 
2242
        request_class = smart_repo.SmartServerRepositoryGetPhysicalLockStatus
 
2243
        request = request_class(backing)
 
2244
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(('no',)),
 
2245
            request.execute('', ))
 
2246
 
 
2247
 
 
2248
class TestSmartServerRepositoryReconcile(tests.TestCaseWithTransport):
 
2249
 
 
2250
    def test_reconcile(self):
 
2251
        backing = self.get_transport()
 
2252
        repo = self.make_repository('.')
 
2253
        token = repo.lock_write().repository_token
 
2254
        self.addCleanup(repo.unlock)
 
2255
        request_class = smart_repo.SmartServerRepositoryReconcile
 
2256
        request = request_class(backing)
 
2257
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(
 
2258
            ('ok', ),
 
2259
             'garbage_inventories: 0\n'
 
2260
             'inconsistent_parents: 0\n'),
 
2261
            request.execute('', token))
 
2262
 
 
2263
 
1749
2264
class TestSmartServerIsReadonly(tests.TestCaseWithMemoryTransport):
1750
2265
 
1751
2266
    def test_is_readonly_no(self):
1789
2304
        self.assertTrue(repo.make_working_trees())
1790
2305
 
1791
2306
 
 
2307
class TestSmartServerRepositoryGetSerializerFormat(
 
2308
    tests.TestCaseWithMemoryTransport):
 
2309
 
 
2310
    def test_get_serializer_format(self):
 
2311
        backing = self.get_transport()
 
2312
        repo = self.make_repository('.', format='2a')
 
2313
        request_class = smart_repo.SmartServerRepositoryGetSerializerFormat
 
2314
        request = request_class(backing)
 
2315
        self.assertEqual(
 
2316
            smart_req.SuccessfulSmartServerResponse(('ok', '10')),
 
2317
            request.execute(''))
 
2318
 
 
2319
 
 
2320
class TestSmartServerRepositoryWriteGroup(
 
2321
    tests.TestCaseWithMemoryTransport):
 
2322
 
 
2323
    def test_start_write_group(self):
 
2324
        backing = self.get_transport()
 
2325
        repo = self.make_repository('.')
 
2326
        lock_token = repo.lock_write().repository_token
 
2327
        self.addCleanup(repo.unlock)
 
2328
        request_class = smart_repo.SmartServerRepositoryStartWriteGroup
 
2329
        request = request_class(backing)
 
2330
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(('ok', [])),
 
2331
            request.execute('', lock_token))
 
2332
 
 
2333
    def test_start_write_group_unsuspendable(self):
 
2334
        backing = self.get_transport()
 
2335
        repo = self.make_repository('.', format='knit')
 
2336
        lock_token = repo.lock_write().repository_token
 
2337
        self.addCleanup(repo.unlock)
 
2338
        request_class = smart_repo.SmartServerRepositoryStartWriteGroup
 
2339
        request = request_class(backing)
 
2340
        self.assertEqual(
 
2341
            smart_req.FailedSmartServerResponse(('UnsuspendableWriteGroup',)),
 
2342
            request.execute('', lock_token))
 
2343
 
 
2344
    def test_commit_write_group(self):
 
2345
        backing = self.get_transport()
 
2346
        repo = self.make_repository('.')
 
2347
        lock_token = repo.lock_write().repository_token
 
2348
        self.addCleanup(repo.unlock)
 
2349
        repo.start_write_group()
 
2350
        tokens = repo.suspend_write_group()
 
2351
        request_class = smart_repo.SmartServerRepositoryCommitWriteGroup
 
2352
        request = request_class(backing)
 
2353
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(('ok',)),
 
2354
            request.execute('', lock_token, tokens))
 
2355
 
 
2356
    def test_abort_write_group(self):
 
2357
        backing = self.get_transport()
 
2358
        repo = self.make_repository('.')
 
2359
        lock_token = repo.lock_write().repository_token
 
2360
        repo.start_write_group()
 
2361
        tokens = repo.suspend_write_group()
 
2362
        self.addCleanup(repo.unlock)
 
2363
        request_class = smart_repo.SmartServerRepositoryAbortWriteGroup
 
2364
        request = request_class(backing)
 
2365
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(('ok',)),
 
2366
            request.execute('', lock_token, tokens))
 
2367
 
 
2368
    def test_check_write_group(self):
 
2369
        backing = self.get_transport()
 
2370
        repo = self.make_repository('.')
 
2371
        lock_token = repo.lock_write().repository_token
 
2372
        repo.start_write_group()
 
2373
        tokens = repo.suspend_write_group()
 
2374
        self.addCleanup(repo.unlock)
 
2375
        request_class = smart_repo.SmartServerRepositoryCheckWriteGroup
 
2376
        request = request_class(backing)
 
2377
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(('ok',)),
 
2378
            request.execute('', lock_token, tokens))
 
2379
 
 
2380
    def test_check_write_group_invalid(self):
 
2381
        backing = self.get_transport()
 
2382
        repo = self.make_repository('.')
 
2383
        lock_token = repo.lock_write().repository_token
 
2384
        self.addCleanup(repo.unlock)
 
2385
        request_class = smart_repo.SmartServerRepositoryCheckWriteGroup
 
2386
        request = request_class(backing)
 
2387
        self.assertEqual(smart_req.FailedSmartServerResponse(
 
2388
            ('UnresumableWriteGroup', ['random'],
 
2389
                'Malformed write group token')),
 
2390
            request.execute('', lock_token, ["random"]))
 
2391
 
 
2392
 
1792
2393
class TestSmartServerPackRepositoryAutopack(tests.TestCaseWithTransport):
1793
2394
 
1794
2395
    def make_repo_needing_autopacking(self, path='.'):
1860
2461
        """All registered request_handlers can be found."""
1861
2462
        # If there's a typo in a register_lazy call, this loop will fail with
1862
2463
        # an AttributeError.
1863
 
        for key, item in smart_req.request_handlers.iteritems():
1864
 
            pass
 
2464
        for key in smart_req.request_handlers.keys():
 
2465
            try:
 
2466
                item = smart_req.request_handlers.get(key)
 
2467
            except AttributeError, e:
 
2468
                raise AttributeError('failed to get %s: %s' % (key, e))
1865
2469
 
1866
2470
    def assertHandlerEqual(self, verb, handler):
1867
2471
        self.assertEqual(smart_req.request_handlers.get(verb), handler)
1868
2472
 
1869
2473
    def test_registered_methods(self):
1870
2474
        """Test that known methods are registered to the correct object."""
 
2475
        self.assertHandlerEqual('Branch.break_lock',
 
2476
            smart_branch.SmartServerBranchBreakLock)
1871
2477
        self.assertHandlerEqual('Branch.get_config_file',
1872
2478
            smart_branch.SmartServerBranchGetConfigFile)
 
2479
        self.assertHandlerEqual('Branch.put_config_file',
 
2480
            smart_branch.SmartServerBranchPutConfigFile)
1873
2481
        self.assertHandlerEqual('Branch.get_parent',
1874
2482
            smart_branch.SmartServerBranchGetParent)
 
2483
        self.assertHandlerEqual('Branch.get_physical_lock_status',
 
2484
            smart_branch.SmartServerBranchRequestGetPhysicalLockStatus)
1875
2485
        self.assertHandlerEqual('Branch.get_tags_bytes',
1876
2486
            smart_branch.SmartServerBranchGetTagsBytes)
1877
2487
        self.assertHandlerEqual('Branch.lock_write',
1880
2490
            smart_branch.SmartServerBranchRequestLastRevisionInfo)
1881
2491
        self.assertHandlerEqual('Branch.revision_history',
1882
2492
            smart_branch.SmartServerRequestRevisionHistory)
 
2493
        self.assertHandlerEqual('Branch.revision_id_to_revno',
 
2494
            smart_branch.SmartServerBranchRequestRevisionIdToRevno)
1883
2495
        self.assertHandlerEqual('Branch.set_config_option',
1884
2496
            smart_branch.SmartServerBranchRequestSetConfigOption)
1885
2497
        self.assertHandlerEqual('Branch.set_last_revision',
1892
2504
            smart_branch.SmartServerBranchRequestSetParentLocation)
1893
2505
        self.assertHandlerEqual('Branch.unlock',
1894
2506
            smart_branch.SmartServerBranchRequestUnlock)
 
2507
        self.assertHandlerEqual('BzrDir.destroy_branch',
 
2508
            smart_dir.SmartServerBzrDirRequestDestroyBranch)
1895
2509
        self.assertHandlerEqual('BzrDir.find_repository',
1896
2510
            smart_dir.SmartServerRequestFindRepositoryV1)
1897
2511
        self.assertHandlerEqual('BzrDir.find_repositoryV2',
1900
2514
            smart_dir.SmartServerRequestInitializeBzrDir)
1901
2515
        self.assertHandlerEqual('BzrDirFormat.initialize_ex_1.16',
1902
2516
            smart_dir.SmartServerRequestBzrDirInitializeEx)
 
2517
        self.assertHandlerEqual('BzrDir.checkout_metadir',
 
2518
            smart_dir.SmartServerBzrDirRequestCheckoutMetaDir)
1903
2519
        self.assertHandlerEqual('BzrDir.cloning_metadir',
1904
2520
            smart_dir.SmartServerBzrDirRequestCloningMetaDir)
 
2521
        self.assertHandlerEqual('BzrDir.get_branches',
 
2522
            smart_dir.SmartServerBzrDirRequestGetBranches)
1905
2523
        self.assertHandlerEqual('BzrDir.get_config_file',
1906
2524
            smart_dir.SmartServerBzrDirRequestConfigFile)
1907
2525
        self.assertHandlerEqual('BzrDir.open_branch',
1912
2530
            smart_dir.SmartServerRequestOpenBranchV3)
1913
2531
        self.assertHandlerEqual('PackRepository.autopack',
1914
2532
            smart_packrepo.SmartServerPackRepositoryAutopack)
 
2533
        self.assertHandlerEqual('Repository.add_signature_text',
 
2534
            smart_repo.SmartServerRepositoryAddSignatureText)
 
2535
        self.assertHandlerEqual('Repository.all_revision_ids',
 
2536
            smart_repo.SmartServerRepositoryAllRevisionIds)
 
2537
        self.assertHandlerEqual('Repository.break_lock',
 
2538
            smart_repo.SmartServerRepositoryBreakLock)
1915
2539
        self.assertHandlerEqual('Repository.gather_stats',
1916
2540
            smart_repo.SmartServerRepositoryGatherStats)
1917
2541
        self.assertHandlerEqual('Repository.get_parent_map',
1918
2542
            smart_repo.SmartServerRepositoryGetParentMap)
 
2543
        self.assertHandlerEqual('Repository.get_physical_lock_status',
 
2544
            smart_repo.SmartServerRepositoryGetPhysicalLockStatus)
1919
2545
        self.assertHandlerEqual('Repository.get_rev_id_for_revno',
1920
2546
            smart_repo.SmartServerRepositoryGetRevIdForRevno)
1921
2547
        self.assertHandlerEqual('Repository.get_revision_graph',
1922
2548
            smart_repo.SmartServerRepositoryGetRevisionGraph)
 
2549
        self.assertHandlerEqual('Repository.get_revision_signature_text',
 
2550
            smart_repo.SmartServerRepositoryGetRevisionSignatureText)
1923
2551
        self.assertHandlerEqual('Repository.get_stream',
1924
2552
            smart_repo.SmartServerRepositoryGetStream)
1925
2553
        self.assertHandlerEqual('Repository.get_stream_1.19',
1926
2554
            smart_repo.SmartServerRepositoryGetStream_1_19)
 
2555
        self.assertHandlerEqual('Repository.iter_revisions',
 
2556
            smart_repo.SmartServerRepositoryIterRevisions)
1927
2557
        self.assertHandlerEqual('Repository.has_revision',
1928
2558
            smart_repo.SmartServerRequestHasRevision)
1929
2559
        self.assertHandlerEqual('Repository.insert_stream',
1932
2562
            smart_repo.SmartServerRepositoryInsertStreamLocked)
1933
2563
        self.assertHandlerEqual('Repository.is_shared',
1934
2564
            smart_repo.SmartServerRepositoryIsShared)
 
2565
        self.assertHandlerEqual('Repository.iter_files_bytes',
 
2566
            smart_repo.SmartServerRepositoryIterFilesBytes)
1935
2567
        self.assertHandlerEqual('Repository.lock_write',
1936
2568
            smart_repo.SmartServerRepositoryLockWrite)
 
2569
        self.assertHandlerEqual('Repository.make_working_trees',
 
2570
            smart_repo.SmartServerRepositoryMakeWorkingTrees)
 
2571
        self.assertHandlerEqual('Repository.pack',
 
2572
            smart_repo.SmartServerRepositoryPack)
 
2573
        self.assertHandlerEqual('Repository.reconcile',
 
2574
            smart_repo.SmartServerRepositoryReconcile)
1937
2575
        self.assertHandlerEqual('Repository.tarball',
1938
2576
            smart_repo.SmartServerRepositoryTarball)
1939
2577
        self.assertHandlerEqual('Repository.unlock',
1940
2578
            smart_repo.SmartServerRepositoryUnlock)
 
2579
        self.assertHandlerEqual('Repository.start_write_group',
 
2580
            smart_repo.SmartServerRepositoryStartWriteGroup)
 
2581
        self.assertHandlerEqual('Repository.check_write_group',
 
2582
            smart_repo.SmartServerRepositoryCheckWriteGroup)
 
2583
        self.assertHandlerEqual('Repository.commit_write_group',
 
2584
            smart_repo.SmartServerRepositoryCommitWriteGroup)
 
2585
        self.assertHandlerEqual('Repository.abort_write_group',
 
2586
            smart_repo.SmartServerRepositoryAbortWriteGroup)
 
2587
        self.assertHandlerEqual('VersionedFileRepository.get_serializer_format',
 
2588
            smart_repo.SmartServerRepositoryGetSerializerFormat)
 
2589
        self.assertHandlerEqual('VersionedFileRepository.get_inventories',
 
2590
            smart_repo.SmartServerRepositoryGetInventories)
1941
2591
        self.assertHandlerEqual('Transport.is_readonly',
1942
2592
            smart_req.SmartServerIsReadonly)
1943
2593
 
1961
2611
            None)
1962
2612
        self.server._sockname = ('example.com', 42)
1963
2613
        self.server.run_server_started_hooks()
1964
 
        self.assertEquals(started_calls,
 
2614
        self.assertEqual(started_calls,
1965
2615
            [([self.get_transport().base], 'bzr://example.com:42/')])
1966
 
        self.assertEquals(started_ex_calls,
 
2616
        self.assertEqual(started_ex_calls,
1967
2617
            [([self.get_transport().base], self.server)])
1968
2618
 
1969
2619
    def test_run_server_started_hooks_ipv6(self):
1974
2624
            lambda backing_urls, url: started_calls.append((backing_urls, url)),
1975
2625
            None)
1976
2626
        self.server.run_server_started_hooks()
1977
 
        self.assertEquals(started_calls,
 
2627
        self.assertEqual(started_calls,
1978
2628
                [([self.get_transport().base], 'bzr://:::42/')])
1979
2629
 
1980
2630
    def test_run_server_stopped_hooks(self):
1985
2635
            lambda backing_urls, url: stopped_calls.append((backing_urls, url)),
1986
2636
            None)
1987
2637
        self.server.run_server_stopped_hooks()
1988
 
        self.assertEquals(stopped_calls,
 
2638
        self.assertEqual(stopped_calls,
1989
2639
            [([self.get_transport().base], 'bzr://example.com:42/')])
 
2640
 
 
2641
 
 
2642
class TestSmartServerRepositoryPack(tests.TestCaseWithMemoryTransport):
 
2643
 
 
2644
    def test_pack(self):
 
2645
        backing = self.get_transport()
 
2646
        request = smart_repo.SmartServerRepositoryPack(backing)
 
2647
        tree = self.make_branch_and_memory_tree('.')
 
2648
        repo_token = tree.branch.repository.lock_write().repository_token
 
2649
 
 
2650
        self.assertIs(None, request.execute('', repo_token, False))
 
2651
 
 
2652
        self.assertEqual(
 
2653
            smart_req.SuccessfulSmartServerResponse(('ok', ), ),
 
2654
            request.do_body(''))
 
2655
 
 
2656
 
 
2657
class TestSmartServerRepositoryGetInventories(tests.TestCaseWithTransport):
 
2658
 
 
2659
    def _get_serialized_inventory_delta(self, repository, base_revid, revid):
 
2660
        base_inv = repository.revision_tree(base_revid).root_inventory
 
2661
        inv = repository.revision_tree(revid).root_inventory
 
2662
        inv_delta = inv._make_delta(base_inv)
 
2663
        serializer = inventory_delta.InventoryDeltaSerializer(True, False)
 
2664
        return "".join(serializer.delta_to_lines(base_revid, revid, inv_delta))
 
2665
 
 
2666
    def test_single(self):
 
2667
        backing = self.get_transport()
 
2668
        request = smart_repo.SmartServerRepositoryGetInventories(backing)
 
2669
        t = self.make_branch_and_tree('.', format='2a')
 
2670
        self.addCleanup(t.lock_write().unlock)
 
2671
        self.build_tree_contents([("file", "somecontents")])
 
2672
        t.add(["file"], ["thefileid"])
 
2673
        t.commit(rev_id='somerev', message="add file")
 
2674
        self.assertIs(None, request.execute('', 'unordered'))
 
2675
        response = request.do_body("somerev\n")
 
2676
        self.assertTrue(response.is_successful())
 
2677
        self.assertEqual(response.args, ("ok", ))
 
2678
        stream = [('inventory-deltas', [
 
2679
            versionedfile.FulltextContentFactory('somerev', None, None,
 
2680
                self._get_serialized_inventory_delta(
 
2681
                    t.branch.repository, 'null:', 'somerev'))])]
 
2682
        fmt = controldir.format_registry.get('2a')().repository_format
 
2683
        self.assertEqual(
 
2684
            "".join(response.body_stream),
 
2685
            "".join(smart_repo._stream_to_byte_stream(stream, fmt)))
 
2686
 
 
2687
    def test_empty(self):
 
2688
        backing = self.get_transport()
 
2689
        request = smart_repo.SmartServerRepositoryGetInventories(backing)
 
2690
        t = self.make_branch_and_tree('.', format='2a')
 
2691
        self.addCleanup(t.lock_write().unlock)
 
2692
        self.build_tree_contents([("file", "somecontents")])
 
2693
        t.add(["file"], ["thefileid"])
 
2694
        t.commit(rev_id='somerev', message="add file")
 
2695
        self.assertIs(None, request.execute('', 'unordered'))
 
2696
        response = request.do_body("")
 
2697
        self.assertTrue(response.is_successful())
 
2698
        self.assertEqual(response.args, ("ok", ))
 
2699
        self.assertEqual("".join(response.body_stream),
 
2700
            "Bazaar pack format 1 (introduced in 0.18)\nB54\n\nBazaar repository format 2a (needs bzr 1.16 or later)\nE")