~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_smart.py

  • Committer: Patch Queue Manager
  • Date: 2016-01-31 13:36:59 UTC
  • mfrom: (6613.1.5 1538480-match-hostname)
  • Revision ID: pqm@pqm.ubuntu.com-20160131133659-ouy92ee2wlv9xz8m
(vila) Use ssl.match_hostname instead of our own. (Vincent Ladeuil)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2006-2010 Canonical Ltd
 
1
# Copyright (C) 2006-2012 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
31
    bencode,
33
32
    branch as _mod_branch,
34
 
    bzrdir,
 
33
    controldir,
35
34
    errors,
36
 
    pack,
 
35
    gpg,
 
36
    inventory_delta,
37
37
    tests,
38
38
    transport,
39
39
    urlutils,
48
48
    server,
49
49
    vfs,
50
50
    )
 
51
from bzrlib.testament import Testament
51
52
from bzrlib.tests import test_server
52
53
from bzrlib.transport import (
53
54
    chroot,
81
82
 
82
83
    def setUp(self):
83
84
        self.vfs_transport_factory = memory.MemoryServer
84
 
        tests.TestCaseWithTransport.setUp(self)
 
85
        super(TestCaseWithChrootedTransport, self).setUp()
85
86
        self._chroot_server = None
86
87
 
87
88
    def get_transport(self, relpath=None):
89
90
            backing_transport = tests.TestCaseWithTransport.get_transport(self)
90
91
            self._chroot_server = chroot.ChrootServer(backing_transport)
91
92
            self.start_server(self._chroot_server)
92
 
        t = transport.get_transport(self._chroot_server.get_url())
 
93
        t = transport.get_transport_from_url(self._chroot_server.get_url())
93
94
        if relpath is not None:
94
95
            t = t.clone(relpath)
95
96
        return t
103
104
        # the default or a parameterized class, but rather use the
104
105
        # TestCaseWithTransport infrastructure to set up a smart server and
105
106
        # transport.
106
 
        self.transport_server = self.make_transport_server
 
107
        self.overrideAttr(self, "transport_server", self.make_transport_server)
107
108
 
108
109
    def make_transport_server(self):
109
110
        return test_server.SmartTCPServer_for_testing('-' + self.id())
120
121
        stream = [('text', [versionedfile.FulltextContentFactory(('k1',), None,
121
122
            None, 'foo')]),('text', [
122
123
            versionedfile.FulltextContentFactory(('k2',), None, None, 'bar')])]
123
 
        fmt = bzrdir.format_registry.get('pack-0.92')().repository_format
 
124
        fmt = controldir.format_registry.get('pack-0.92')().repository_format
124
125
        bytes = smart_repo._stream_to_byte_stream(stream, fmt)
125
126
        streams = []
126
127
        # Iterate the resulting iterable; checking that we get only one stream
225
226
        self.assertEqual(expected, request.execute('', 'False'))
226
227
 
227
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
 
228
327
class TestSmartServerRequestCreateRepository(tests.TestCaseWithMemoryTransport):
229
328
    """Tests for BzrDir.create_repository."""
230
329
 
234
333
        self.make_bzrdir('.')
235
334
        request_class = smart_dir.SmartServerRequestCreateRepository
236
335
        request = request_class(backing)
237
 
        reference_bzrdir_format = bzrdir.format_registry.get('pack-0.92')()
 
336
        reference_bzrdir_format = controldir.format_registry.get('pack-0.92')()
238
337
        reference_format = reference_bzrdir_format.repository_format
239
338
        network_name = reference_format.network_name()
240
339
        expected = smart_req.SuccessfulSmartServerResponse(
320
419
        backing = self.get_transport()
321
420
        request = self._request_class(backing)
322
421
        result = self._make_repository_and_result(
323
 
            format='dirstate-with-subtree')
 
422
            format='development-subtree')
324
423
        # check the test will be valid
325
424
        self.assertEqual('yes', result.args[2])
326
425
        self.assertEqual('yes', result.args[3])
331
430
        backing = self.get_transport()
332
431
        request = self._request_class(backing)
333
432
        result = self._make_repository_and_result(
334
 
            format='dirstate-with-subtree')
 
433
            format='development-subtree')
335
434
        # check the test will be valid
336
 
        self.assertEqual('no', result.args[4])
 
435
        self.assertEqual('yes', result.args[4])
337
436
        self.assertEqual(result, request.execute(''))
338
437
 
339
438
 
360
459
        self.assertEqual(expected, request.execute(''))
361
460
 
362
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
 
363
488
class TestSmartServerRequestInitializeBzrDir(tests.TestCaseWithMemoryTransport):
364
489
 
365
490
    def test_empty_dir(self):
368
493
        request = smart_dir.SmartServerRequestInitializeBzrDir(backing)
369
494
        self.assertEqual(smart_req.SmartServerResponse(('ok', )),
370
495
            request.execute(''))
371
 
        made_dir = bzrdir.BzrDir.open_from_transport(backing)
 
496
        made_dir = controldir.ControlDir.open_from_transport(backing)
372
497
        # no branch, tree or repository is expected with the current
373
498
        # default formart.
374
499
        self.assertRaises(errors.NoWorkingTree, made_dir.open_workingtree)
387
512
        backing = self.get_transport()
388
513
        request = smart_dir.SmartServerRequestInitializeBzrDir(backing)
389
514
        self.make_bzrdir('subdir')
390
 
        self.assertRaises(errors.FileExists,
 
515
        self.assertRaises(errors.AlreadyControlDirError,
391
516
            request.execute, 'subdir')
392
517
 
393
518
 
408
533
                                           'False', '', '', '')),
409
534
            request.execute(name, '', 'True', 'False', 'False', '', '', '', '',
410
535
                            'False'))
411
 
        made_dir = bzrdir.BzrDir.open_from_transport(backing)
 
536
        made_dir = controldir.ControlDir.open_from_transport(backing)
412
537
        # no branch, tree or repository is expected with the current
413
538
        # default format.
414
539
        self.assertRaises(errors.NoWorkingTree, made_dir.open_workingtree)
739
864
            request.execute(''))
740
865
 
741
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
 
742
902
class TestSmartServerBranchRequestGetConfigFile(
743
903
    tests.TestCaseWithMemoryTransport):
744
904
 
773
933
        return branch_token, repo_token
774
934
 
775
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.assertEquals(
 
948
            branch.control_transport.get_bytes('branch.conf'),
 
949
            'foo bar baz')
 
950
        branch.unlock()
 
951
 
 
952
 
776
953
class TestSmartServerBranchRequestSetConfigOption(TestLockedBranch):
777
954
 
778
955
    def test_value_name(self):
881
1058
    """Base test case for verbs that implement set_last_revision."""
882
1059
 
883
1060
    def setUp(self):
884
 
        tests.TestCaseWithMemoryTransport.setUp(self)
 
1061
        super(SetLastRevisionTestBase, self).setUp()
885
1062
        backing_transport = self.get_transport()
886
1063
        self.request = self.request_class(backing_transport)
887
1064
        self.tree = self.make_branch_and_memory_tree('.')
936
1113
        # its repository.
937
1114
        self.make_tree_with_two_commits()
938
1115
        rev_id_utf8 = u'\xc8'.encode('utf-8')
939
 
        self.tree.branch.set_revision_history([])
 
1116
        self.tree.branch.set_last_revision_info(0, 'null:')
940
1117
        self.assertEqual(
941
1118
            (0, 'null:'), self.tree.branch.last_revision_info())
942
1119
        # We can update the branch to a revision that is present in the
1092
1269
        self.assertEqual('child-1', self.tree.branch.last_revision())
1093
1270
 
1094
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
 
1095
1292
class TestSmartServerBranchRequestGetParent(tests.TestCaseWithMemoryTransport):
1096
1293
 
1097
1294
    def test_get_parent_none(self):
1126
1323
        finally:
1127
1324
            branch.unlock()
1128
1325
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(()), response)
 
1326
        # Refresh branch as SetParentLocation modified it
 
1327
        branch = branch.bzrdir.open_branch()
1129
1328
        self.assertEqual(None, branch.get_parent())
1130
1329
 
1131
1330
    def test_set_parent_something(self):
1135
1334
        branch_token, repo_token = self.get_lock_tokens(branch)
1136
1335
        try:
1137
1336
            response = request.execute('base', branch_token, repo_token,
1138
 
            'http://bar/')
 
1337
                                       'http://bar/')
1139
1338
        finally:
1140
1339
            branch.unlock()
1141
1340
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(()), response)
1142
 
        self.assertEqual('http://bar/', branch.get_parent())
 
1341
        refreshed = _mod_branch.Branch.open(branch.base)
 
1342
        self.assertEqual('http://bar/', refreshed.get_parent())
1143
1343
 
1144
1344
 
1145
1345
class TestSmartServerBranchRequestGetTagsBytes(
1173
1373
 
1174
1374
class TestSmartServerBranchRequestLockWrite(TestLockedBranch):
1175
1375
 
1176
 
    def setUp(self):
1177
 
        tests.TestCaseWithMemoryTransport.setUp(self)
1178
 
 
1179
1376
    def test_lock_write_on_unlocked_branch(self):
1180
1377
        backing = self.get_transport()
1181
1378
        request = smart_branch.SmartServerBranchRequestLockWrite(backing)
1279
1476
        self.assertEqual('LockFailed', error_name)
1280
1477
 
1281
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.assertEquals(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.assertEquals(False, branch.get_physical_lock_status())
 
1499
        response = request.execute('')
 
1500
        self.assertEqual(
 
1501
            smart_req.SmartServerResponse(('no',)), response)
 
1502
 
 
1503
 
1282
1504
class TestSmartServerBranchRequestUnlock(TestLockedBranch):
1283
1505
 
1284
 
    def setUp(self):
1285
 
        tests.TestCaseWithMemoryTransport.setUp(self)
1286
 
 
1287
1506
    def test_unlock_on_locked_branch_and_repo(self):
1288
1507
        backing = self.get_transport()
1289
1508
        request = smart_branch.SmartServerBranchRequestUnlock(backing)
1349
1568
            request.execute, 'subdir')
1350
1569
 
1351
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.assertEquals(
 
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.assertEquals(
 
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
 
1352
1644
class TestSmartServerRepositoryGetParentMap(tests.TestCaseWithMemoryTransport):
1353
1645
 
1354
1646
    def test_trivial_bzipped(self):
1474
1766
            request.execute('stacked', 1, (3, r3)))
1475
1767
 
1476
1768
 
1477
 
class TestSmartServerRepositoryGetStream(tests.TestCaseWithMemoryTransport):
 
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.assertEquals(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.assertEquals(response.args, ("ok", "10"))
 
1808
 
 
1809
        contents = "".join(response.body_stream)
 
1810
        self.assertEquals(contents, "")
 
1811
 
 
1812
 
 
1813
class GetStreamTestBase(tests.TestCaseWithMemoryTransport):
1478
1814
 
1479
1815
    def make_two_commit_repo(self):
1480
1816
        tree = self.make_branch_and_memory_tree('.')
1486
1822
        repo = tree.branch.repository
1487
1823
        return repo, r1, r2
1488
1824
 
 
1825
 
 
1826
class TestSmartServerRepositoryGetStream(GetStreamTestBase):
 
1827
 
1489
1828
    def test_ancestry_of(self):
1490
1829
        """The search argument may be a 'ancestry-of' some heads'."""
1491
1830
        backing = self.get_transport()
1512
1851
        stream_bytes = ''.join(response.body_stream)
1513
1852
        self.assertStartsWith(stream_bytes, 'Bazaar pack format 1')
1514
1853
 
 
1854
    def test_search_everything(self):
 
1855
        """A search of 'everything' returns a stream."""
 
1856
        backing = self.get_transport()
 
1857
        request = smart_repo.SmartServerRepositoryGetStream_1_19(backing)
 
1858
        repo, r1, r2 = self.make_two_commit_repo()
 
1859
        serialised_fetch_spec = 'everything'
 
1860
        request.execute('', repo._format.network_name())
 
1861
        response = request.do_body(serialised_fetch_spec)
 
1862
        self.assertEqual(('ok',), response.args)
 
1863
        stream_bytes = ''.join(response.body_stream)
 
1864
        self.assertStartsWith(stream_bytes, 'Bazaar pack format 1')
 
1865
 
1515
1866
 
1516
1867
class TestSmartServerRequestHasRevision(tests.TestCaseWithMemoryTransport):
1517
1868
 
1538
1889
            request.execute('', rev_id_utf8))
1539
1890
 
1540
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.assertEquals(response.args, ("ok", ))
 
1906
        self.assertEquals("".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.assertEquals(response.args, ("ok", ))
 
1918
        self.assertEquals("".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
 
1541
1969
class TestSmartServerRepositoryGatherStats(tests.TestCaseWithMemoryTransport):
1542
1970
 
1543
1971
    def test_empty_revid(self):
1596
2024
                         request.execute('',
1597
2025
                                         rev_id_utf8, 'yes'))
1598
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
 
1599
2038
 
1600
2039
class TestSmartServerRepositoryIsShared(tests.TestCaseWithMemoryTransport):
1601
2040
 
1616
2055
            request.execute('', ))
1617
2056
 
1618
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
 
1619
2104
class TestSmartServerRepositoryLockWrite(tests.TestCaseWithMemoryTransport):
1620
2105
 
1621
2106
    def test_lock_write_on_unlocked_repo(self):
1707
2192
 
1708
2193
class TestSmartServerRepositoryUnlock(tests.TestCaseWithMemoryTransport):
1709
2194
 
1710
 
    def setUp(self):
1711
 
        tests.TestCaseWithMemoryTransport.setUp(self)
1712
 
 
1713
2195
    def test_unlock_on_locked_repo(self):
1714
2196
        backing = self.get_transport()
1715
2197
        request = smart_repo.SmartServerRepositoryUnlock(backing)
1735
2217
            smart_req.SmartServerResponse(('TokenMismatch',)), response)
1736
2218
 
1737
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.assertEquals(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
 
1738
2264
class TestSmartServerIsReadonly(tests.TestCaseWithMemoryTransport):
1739
2265
 
1740
2266
    def test_is_readonly_no(self):
1778
2304
        self.assertTrue(repo.make_working_trees())
1779
2305
 
1780
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
 
1781
2393
class TestSmartServerPackRepositoryAutopack(tests.TestCaseWithTransport):
1782
2394
 
1783
2395
    def make_repo_needing_autopacking(self, path='.'):
1849
2461
        """All registered request_handlers can be found."""
1850
2462
        # If there's a typo in a register_lazy call, this loop will fail with
1851
2463
        # an AttributeError.
1852
 
        for key, item in smart_req.request_handlers.iteritems():
1853
 
            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))
1854
2469
 
1855
2470
    def assertHandlerEqual(self, verb, handler):
1856
2471
        self.assertEqual(smart_req.request_handlers.get(verb), handler)
1857
2472
 
1858
2473
    def test_registered_methods(self):
1859
2474
        """Test that known methods are registered to the correct object."""
 
2475
        self.assertHandlerEqual('Branch.break_lock',
 
2476
            smart_branch.SmartServerBranchBreakLock)
1860
2477
        self.assertHandlerEqual('Branch.get_config_file',
1861
2478
            smart_branch.SmartServerBranchGetConfigFile)
 
2479
        self.assertHandlerEqual('Branch.put_config_file',
 
2480
            smart_branch.SmartServerBranchPutConfigFile)
1862
2481
        self.assertHandlerEqual('Branch.get_parent',
1863
2482
            smart_branch.SmartServerBranchGetParent)
 
2483
        self.assertHandlerEqual('Branch.get_physical_lock_status',
 
2484
            smart_branch.SmartServerBranchRequestGetPhysicalLockStatus)
1864
2485
        self.assertHandlerEqual('Branch.get_tags_bytes',
1865
2486
            smart_branch.SmartServerBranchGetTagsBytes)
1866
2487
        self.assertHandlerEqual('Branch.lock_write',
1869
2490
            smart_branch.SmartServerBranchRequestLastRevisionInfo)
1870
2491
        self.assertHandlerEqual('Branch.revision_history',
1871
2492
            smart_branch.SmartServerRequestRevisionHistory)
 
2493
        self.assertHandlerEqual('Branch.revision_id_to_revno',
 
2494
            smart_branch.SmartServerBranchRequestRevisionIdToRevno)
1872
2495
        self.assertHandlerEqual('Branch.set_config_option',
1873
2496
            smart_branch.SmartServerBranchRequestSetConfigOption)
1874
2497
        self.assertHandlerEqual('Branch.set_last_revision',
1881
2504
            smart_branch.SmartServerBranchRequestSetParentLocation)
1882
2505
        self.assertHandlerEqual('Branch.unlock',
1883
2506
            smart_branch.SmartServerBranchRequestUnlock)
 
2507
        self.assertHandlerEqual('BzrDir.destroy_branch',
 
2508
            smart_dir.SmartServerBzrDirRequestDestroyBranch)
1884
2509
        self.assertHandlerEqual('BzrDir.find_repository',
1885
2510
            smart_dir.SmartServerRequestFindRepositoryV1)
1886
2511
        self.assertHandlerEqual('BzrDir.find_repositoryV2',
1889
2514
            smart_dir.SmartServerRequestInitializeBzrDir)
1890
2515
        self.assertHandlerEqual('BzrDirFormat.initialize_ex_1.16',
1891
2516
            smart_dir.SmartServerRequestBzrDirInitializeEx)
 
2517
        self.assertHandlerEqual('BzrDir.checkout_metadir',
 
2518
            smart_dir.SmartServerBzrDirRequestCheckoutMetaDir)
1892
2519
        self.assertHandlerEqual('BzrDir.cloning_metadir',
1893
2520
            smart_dir.SmartServerBzrDirRequestCloningMetaDir)
 
2521
        self.assertHandlerEqual('BzrDir.get_branches',
 
2522
            smart_dir.SmartServerBzrDirRequestGetBranches)
1894
2523
        self.assertHandlerEqual('BzrDir.get_config_file',
1895
2524
            smart_dir.SmartServerBzrDirRequestConfigFile)
1896
2525
        self.assertHandlerEqual('BzrDir.open_branch',
1901
2530
            smart_dir.SmartServerRequestOpenBranchV3)
1902
2531
        self.assertHandlerEqual('PackRepository.autopack',
1903
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)
1904
2539
        self.assertHandlerEqual('Repository.gather_stats',
1905
2540
            smart_repo.SmartServerRepositoryGatherStats)
1906
2541
        self.assertHandlerEqual('Repository.get_parent_map',
1907
2542
            smart_repo.SmartServerRepositoryGetParentMap)
 
2543
        self.assertHandlerEqual('Repository.get_physical_lock_status',
 
2544
            smart_repo.SmartServerRepositoryGetPhysicalLockStatus)
1908
2545
        self.assertHandlerEqual('Repository.get_rev_id_for_revno',
1909
2546
            smart_repo.SmartServerRepositoryGetRevIdForRevno)
1910
2547
        self.assertHandlerEqual('Repository.get_revision_graph',
1911
2548
            smart_repo.SmartServerRepositoryGetRevisionGraph)
 
2549
        self.assertHandlerEqual('Repository.get_revision_signature_text',
 
2550
            smart_repo.SmartServerRepositoryGetRevisionSignatureText)
1912
2551
        self.assertHandlerEqual('Repository.get_stream',
1913
2552
            smart_repo.SmartServerRepositoryGetStream)
 
2553
        self.assertHandlerEqual('Repository.get_stream_1.19',
 
2554
            smart_repo.SmartServerRepositoryGetStream_1_19)
 
2555
        self.assertHandlerEqual('Repository.iter_revisions',
 
2556
            smart_repo.SmartServerRepositoryIterRevisions)
1914
2557
        self.assertHandlerEqual('Repository.has_revision',
1915
2558
            smart_repo.SmartServerRequestHasRevision)
1916
2559
        self.assertHandlerEqual('Repository.insert_stream',
1919
2562
            smart_repo.SmartServerRepositoryInsertStreamLocked)
1920
2563
        self.assertHandlerEqual('Repository.is_shared',
1921
2564
            smart_repo.SmartServerRepositoryIsShared)
 
2565
        self.assertHandlerEqual('Repository.iter_files_bytes',
 
2566
            smart_repo.SmartServerRepositoryIterFilesBytes)
1922
2567
        self.assertHandlerEqual('Repository.lock_write',
1923
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)
1924
2575
        self.assertHandlerEqual('Repository.tarball',
1925
2576
            smart_repo.SmartServerRepositoryTarball)
1926
2577
        self.assertHandlerEqual('Repository.unlock',
1927
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)
1928
2591
        self.assertHandlerEqual('Transport.is_readonly',
1929
2592
            smart_req.SmartServerIsReadonly)
 
2593
 
 
2594
 
 
2595
class SmartTCPServerHookTests(tests.TestCaseWithMemoryTransport):
 
2596
    """Tests for SmartTCPServer hooks."""
 
2597
 
 
2598
    def setUp(self):
 
2599
        super(SmartTCPServerHookTests, self).setUp()
 
2600
        self.server = server.SmartTCPServer(self.get_transport())
 
2601
 
 
2602
    def test_run_server_started_hooks(self):
 
2603
        """Test the server started hooks get fired properly."""
 
2604
        started_calls = []
 
2605
        server.SmartTCPServer.hooks.install_named_hook('server_started',
 
2606
            lambda backing_urls, url: started_calls.append((backing_urls, url)),
 
2607
            None)
 
2608
        started_ex_calls = []
 
2609
        server.SmartTCPServer.hooks.install_named_hook('server_started_ex',
 
2610
            lambda backing_urls, url: started_ex_calls.append((backing_urls, url)),
 
2611
            None)
 
2612
        self.server._sockname = ('example.com', 42)
 
2613
        self.server.run_server_started_hooks()
 
2614
        self.assertEquals(started_calls,
 
2615
            [([self.get_transport().base], 'bzr://example.com:42/')])
 
2616
        self.assertEquals(started_ex_calls,
 
2617
            [([self.get_transport().base], self.server)])
 
2618
 
 
2619
    def test_run_server_started_hooks_ipv6(self):
 
2620
        """Test that socknames can contain 4-tuples."""
 
2621
        self.server._sockname = ('::', 42, 0, 0)
 
2622
        started_calls = []
 
2623
        server.SmartTCPServer.hooks.install_named_hook('server_started',
 
2624
            lambda backing_urls, url: started_calls.append((backing_urls, url)),
 
2625
            None)
 
2626
        self.server.run_server_started_hooks()
 
2627
        self.assertEquals(started_calls,
 
2628
                [([self.get_transport().base], 'bzr://:::42/')])
 
2629
 
 
2630
    def test_run_server_stopped_hooks(self):
 
2631
        """Test the server stopped hooks."""
 
2632
        self.server._sockname = ('example.com', 42)
 
2633
        stopped_calls = []
 
2634
        server.SmartTCPServer.hooks.install_named_hook('server_stopped',
 
2635
            lambda backing_urls, url: stopped_calls.append((backing_urls, url)),
 
2636
            None)
 
2637
        self.server.run_server_stopped_hooks()
 
2638
        self.assertEquals(stopped_calls,
 
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.assertEquals(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.assertEquals(
 
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.assertEquals(response.args, ("ok", ))
 
2699
        self.assertEquals("".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")