~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_smart.py

Merge bzr.dev, update to use new hooks.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2006-2010 Canonical Ltd
 
1
# Copyright (C) 2006-2011 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
25
25
"""
26
26
 
27
27
import bz2
28
 
from cStringIO import StringIO
29
 
import tarfile
 
28
import zlib
30
29
 
31
30
from bzrlib import (
32
 
    bencode,
33
31
    branch as _mod_branch,
34
32
    bzrdir,
35
33
    errors,
36
 
    pack,
 
34
    gpg,
37
35
    tests,
38
36
    transport,
39
37
    urlutils,
48
46
    server,
49
47
    vfs,
50
48
    )
 
49
from bzrlib.testament import Testament
51
50
from bzrlib.tests import test_server
52
51
from bzrlib.transport import (
53
52
    chroot,
89
88
            backing_transport = tests.TestCaseWithTransport.get_transport(self)
90
89
            self._chroot_server = chroot.ChrootServer(backing_transport)
91
90
            self.start_server(self._chroot_server)
92
 
        t = transport.get_transport(self._chroot_server.get_url())
 
91
        t = transport.get_transport_from_url(self._chroot_server.get_url())
93
92
        if relpath is not None:
94
93
            t = t.clone(relpath)
95
94
        return t
103
102
        # the default or a parameterized class, but rather use the
104
103
        # TestCaseWithTransport infrastructure to set up a smart server and
105
104
        # transport.
106
 
        self.transport_server = self.make_transport_server
 
105
        self.overrideAttr(self, "transport_server", self.make_transport_server)
107
106
 
108
107
    def make_transport_server(self):
109
108
        return test_server.SmartTCPServer_for_testing('-' + self.id())
225
224
        self.assertEqual(expected, request.execute('', 'False'))
226
225
 
227
226
 
 
227
class TestSmartServerBzrDirRequestDestroyBranch(
 
228
    tests.TestCaseWithMemoryTransport):
 
229
    """Tests for BzrDir.destroy_branch."""
 
230
 
 
231
    def test_destroy_branch_default(self):
 
232
        """The default branch can be removed."""
 
233
        backing = self.get_transport()
 
234
        dir = self.make_branch('.').bzrdir
 
235
        request_class = smart_dir.SmartServerBzrDirRequestDestroyBranch
 
236
        request = request_class(backing)
 
237
        expected = smart_req.SuccessfulSmartServerResponse(('ok',))
 
238
        self.assertEqual(expected, request.execute('', None))
 
239
 
 
240
    def test_destroy_branch_named(self):
 
241
        """A named branch can be removed."""
 
242
        backing = self.get_transport()
 
243
        dir = self.make_repository('.', format="development-colo").bzrdir
 
244
        dir.create_branch(name="branchname")
 
245
        request_class = smart_dir.SmartServerBzrDirRequestDestroyBranch
 
246
        request = request_class(backing)
 
247
        expected = smart_req.SuccessfulSmartServerResponse(('ok',))
 
248
        self.assertEqual(expected, request.execute('', "branchname"))
 
249
 
 
250
    def test_destroy_branch_missing(self):
 
251
        """An error is raised if the branch didn't exist."""
 
252
        backing = self.get_transport()
 
253
        dir = self.make_bzrdir('.', format="development-colo")
 
254
        request_class = smart_dir.SmartServerBzrDirRequestDestroyBranch
 
255
        request = request_class(backing)
 
256
        expected = smart_req.FailedSmartServerResponse(('nobranch',), None)
 
257
        self.assertEqual(expected, request.execute('', "branchname"))
 
258
 
 
259
 
 
260
class TestSmartServerBzrDirRequestHasWorkingTree(
 
261
    tests.TestCaseWithTransport):
 
262
    """Tests for BzrDir.has_workingtree."""
 
263
 
 
264
    def test_has_workingtree_yes(self):
 
265
        """A working tree is present."""
 
266
        backing = self.get_transport()
 
267
        dir = self.make_branch_and_tree('.').bzrdir
 
268
        request_class = smart_dir.SmartServerBzrDirRequestHasWorkingTree
 
269
        request = request_class(backing)
 
270
        expected = smart_req.SuccessfulSmartServerResponse(('yes',))
 
271
        self.assertEqual(expected, request.execute(''))
 
272
 
 
273
    def test_has_workingtree_no(self):
 
274
        """A working tree is missing."""
 
275
        backing = self.get_transport()
 
276
        dir = self.make_bzrdir('.')
 
277
        request_class = smart_dir.SmartServerBzrDirRequestHasWorkingTree
 
278
        request = request_class(backing)
 
279
        expected = smart_req.SuccessfulSmartServerResponse(('no',))
 
280
        self.assertEqual(expected, request.execute(''))
 
281
 
 
282
 
 
283
class TestSmartServerBzrDirRequestDestroyRepository(
 
284
    tests.TestCaseWithMemoryTransport):
 
285
    """Tests for BzrDir.destroy_repository."""
 
286
 
 
287
    def test_destroy_repository_default(self):
 
288
        """The repository can be removed."""
 
289
        backing = self.get_transport()
 
290
        dir = self.make_repository('.').bzrdir
 
291
        request_class = smart_dir.SmartServerBzrDirRequestDestroyRepository
 
292
        request = request_class(backing)
 
293
        expected = smart_req.SuccessfulSmartServerResponse(('ok',))
 
294
        self.assertEqual(expected, request.execute(''))
 
295
 
 
296
    def test_destroy_repository_missing(self):
 
297
        """An error is raised if the repository didn't exist."""
 
298
        backing = self.get_transport()
 
299
        dir = self.make_bzrdir('.')
 
300
        request_class = smart_dir.SmartServerBzrDirRequestDestroyRepository
 
301
        request = request_class(backing)
 
302
        expected = smart_req.FailedSmartServerResponse(
 
303
            ('norepository',), None)
 
304
        self.assertEqual(expected, request.execute(''))
 
305
 
 
306
 
228
307
class TestSmartServerRequestCreateRepository(tests.TestCaseWithMemoryTransport):
229
308
    """Tests for BzrDir.create_repository."""
230
309
 
739
818
            request.execute(''))
740
819
 
741
820
 
 
821
class TestSmartServerBranchRequestRevisionIdToRevno(
 
822
    tests.TestCaseWithMemoryTransport):
 
823
 
 
824
    def test_null(self):
 
825
        backing = self.get_transport()
 
826
        request = smart_branch.SmartServerBranchRequestRevisionIdToRevno(
 
827
            backing)
 
828
        self.make_branch('.')
 
829
        self.assertEqual(smart_req.SmartServerResponse(('ok', '0')),
 
830
            request.execute('', 'null:'))
 
831
 
 
832
    def test_simple(self):
 
833
        backing = self.get_transport()
 
834
        request = smart_branch.SmartServerBranchRequestRevisionIdToRevno(
 
835
            backing)
 
836
        tree = self.make_branch_and_memory_tree('.')
 
837
        tree.lock_write()
 
838
        tree.add('')
 
839
        r1 = tree.commit('1st commit')
 
840
        tree.unlock()
 
841
        self.assertEqual(
 
842
            smart_req.SmartServerResponse(('ok', '1')),
 
843
            request.execute('', r1))
 
844
 
 
845
    def test_not_found(self):
 
846
        backing = self.get_transport()
 
847
        request = smart_branch.SmartServerBranchRequestRevisionIdToRevno(
 
848
            backing)
 
849
        branch = self.make_branch('.')
 
850
        self.assertEqual(
 
851
            smart_req.FailedSmartServerResponse(
 
852
                ('NoSuchRevision', 'idontexist')),
 
853
            request.execute('', 'idontexist'))
 
854
 
 
855
 
742
856
class TestSmartServerBranchRequestGetConfigFile(
743
857
    tests.TestCaseWithMemoryTransport):
744
858
 
773
887
        return branch_token, repo_token
774
888
 
775
889
 
 
890
class TestSmartServerBranchRequestPutConfigFile(TestLockedBranch):
 
891
 
 
892
    def test_with_content(self):
 
893
        backing = self.get_transport()
 
894
        request = smart_branch.SmartServerBranchPutConfigFile(backing)
 
895
        branch = self.make_branch('.')
 
896
        branch_token, repo_token = self.get_lock_tokens(branch)
 
897
        self.assertIs(None, request.execute('', branch_token, repo_token))
 
898
        self.assertEqual(
 
899
            smart_req.SmartServerResponse(('ok', )),
 
900
            request.do_body('foo bar baz'))
 
901
        self.assertEquals(
 
902
            branch.control_transport.get_bytes('branch.conf'),
 
903
            'foo bar baz')
 
904
        branch.unlock()
 
905
 
 
906
 
776
907
class TestSmartServerBranchRequestSetConfigOption(TestLockedBranch):
777
908
 
778
909
    def test_value_name(self):
936
1067
        # its repository.
937
1068
        self.make_tree_with_two_commits()
938
1069
        rev_id_utf8 = u'\xc8'.encode('utf-8')
939
 
        self.tree.branch.set_revision_history([])
 
1070
        self.tree.branch.set_last_revision_info(0, 'null:')
940
1071
        self.assertEqual(
941
1072
            (0, 'null:'), self.tree.branch.last_revision_info())
942
1073
        # We can update the branch to a revision that is present in the
1092
1223
        self.assertEqual('child-1', self.tree.branch.last_revision())
1093
1224
 
1094
1225
 
 
1226
class TestSmartServerBranchBreakLock(tests.TestCaseWithMemoryTransport):
 
1227
 
 
1228
    def test_lock_to_break(self):
 
1229
        base_branch = self.make_branch('base')
 
1230
        request = smart_branch.SmartServerBranchBreakLock(
 
1231
            self.get_transport())
 
1232
        base_branch.lock_write()
 
1233
        self.assertEqual(
 
1234
            smart_req.SuccessfulSmartServerResponse(('ok', ), None),
 
1235
            request.execute('base'))
 
1236
 
 
1237
    def test_nothing_to_break(self):
 
1238
        base_branch = self.make_branch('base')
 
1239
        request = smart_branch.SmartServerBranchBreakLock(
 
1240
            self.get_transport())
 
1241
        self.assertEqual(
 
1242
            smart_req.SuccessfulSmartServerResponse(('ok', ), None),
 
1243
            request.execute('base'))
 
1244
 
 
1245
 
1095
1246
class TestSmartServerBranchRequestGetParent(tests.TestCaseWithMemoryTransport):
1096
1247
 
1097
1248
    def test_get_parent_none(self):
1279
1430
        self.assertEqual('LockFailed', error_name)
1280
1431
 
1281
1432
 
 
1433
class TestSmartServerBranchRequestGetPhysicalLockStatus(TestLockedBranch):
 
1434
 
 
1435
    def setUp(self):
 
1436
        tests.TestCaseWithMemoryTransport.setUp(self)
 
1437
 
 
1438
    def test_true(self):
 
1439
        backing = self.get_transport()
 
1440
        request = smart_branch.SmartServerBranchRequestGetPhysicalLockStatus(
 
1441
            backing)
 
1442
        branch = self.make_branch('.')
 
1443
        branch_token, repo_token = self.get_lock_tokens(branch)
 
1444
        self.assertEquals(True, branch.get_physical_lock_status())
 
1445
        response = request.execute('')
 
1446
        self.assertEqual(
 
1447
            smart_req.SmartServerResponse(('yes',)), response)
 
1448
        branch.unlock()
 
1449
 
 
1450
    def test_false(self):
 
1451
        backing = self.get_transport()
 
1452
        request = smart_branch.SmartServerBranchRequestGetPhysicalLockStatus(
 
1453
            backing)
 
1454
        branch = self.make_branch('.')
 
1455
        self.assertEquals(False, branch.get_physical_lock_status())
 
1456
        response = request.execute('')
 
1457
        self.assertEqual(
 
1458
            smart_req.SmartServerResponse(('no',)), response)
 
1459
 
 
1460
 
1282
1461
class TestSmartServerBranchRequestUnlock(TestLockedBranch):
1283
1462
 
1284
1463
    def setUp(self):
1349
1528
            request.execute, 'subdir')
1350
1529
 
1351
1530
 
 
1531
class TestSmartServerRepositoryAddSignatureText(tests.TestCaseWithMemoryTransport):
 
1532
 
 
1533
    def test_add_text(self):
 
1534
        backing = self.get_transport()
 
1535
        request = smart_repo.SmartServerRepositoryAddSignatureText(backing)
 
1536
        tree = self.make_branch_and_memory_tree('.')
 
1537
        write_token = tree.lock_write()
 
1538
        self.addCleanup(tree.unlock)
 
1539
        tree.add('')
 
1540
        tree.commit("Message", rev_id='rev1')
 
1541
        tree.branch.repository.start_write_group()
 
1542
        write_group_tokens = tree.branch.repository.suspend_write_group()
 
1543
        self.assertEqual(None, request.execute('', write_token,
 
1544
            'rev1', *write_group_tokens))
 
1545
        response = request.do_body('somesignature')
 
1546
        self.assertTrue(response.is_successful())
 
1547
        self.assertEqual(response.args[0], 'ok')
 
1548
        write_group_tokens = response.args[1:]
 
1549
        tree.branch.repository.resume_write_group(write_group_tokens)
 
1550
        tree.branch.repository.commit_write_group()
 
1551
        tree.unlock()
 
1552
        self.assertEqual("somesignature",
 
1553
            tree.branch.repository.get_signature_text("rev1"))
 
1554
 
 
1555
 
 
1556
class TestSmartServerRepositoryAllRevisionIds(
 
1557
    tests.TestCaseWithMemoryTransport):
 
1558
 
 
1559
    def test_empty(self):
 
1560
        """An empty body should be returned for an empty repository."""
 
1561
        backing = self.get_transport()
 
1562
        request = smart_repo.SmartServerRepositoryAllRevisionIds(backing)
 
1563
        self.make_repository('.')
 
1564
        self.assertEquals(
 
1565
            smart_req.SuccessfulSmartServerResponse(("ok", ), ""),
 
1566
            request.execute(''))
 
1567
 
 
1568
    def test_some_revisions(self):
 
1569
        """An empty body should be returned for an empty repository."""
 
1570
        backing = self.get_transport()
 
1571
        request = smart_repo.SmartServerRepositoryAllRevisionIds(backing)
 
1572
        tree = self.make_branch_and_memory_tree('.')
 
1573
        tree.lock_write()
 
1574
        tree.add('')
 
1575
        tree.commit(rev_id='origineel', message="message")
 
1576
        tree.commit(rev_id='nog-een-revisie', message="message")
 
1577
        tree.unlock()
 
1578
        self.assertEquals(
 
1579
            smart_req.SuccessfulSmartServerResponse(("ok", ),
 
1580
                "origineel\nnog-een-revisie"),
 
1581
            request.execute(''))
 
1582
 
 
1583
 
 
1584
class TestSmartServerRepositoryBreakLock(tests.TestCaseWithMemoryTransport):
 
1585
 
 
1586
    def test_lock_to_break(self):
 
1587
        backing = self.get_transport()
 
1588
        request = smart_repo.SmartServerRepositoryBreakLock(backing)
 
1589
        tree = self.make_branch_and_memory_tree('.')
 
1590
        tree.branch.repository.lock_write()
 
1591
        self.assertEqual(
 
1592
            smart_req.SuccessfulSmartServerResponse(('ok', ), None),
 
1593
            request.execute(''))
 
1594
 
 
1595
    def test_nothing_to_break(self):
 
1596
        backing = self.get_transport()
 
1597
        request = smart_repo.SmartServerRepositoryBreakLock(backing)
 
1598
        tree = self.make_branch_and_memory_tree('.')
 
1599
        self.assertEqual(
 
1600
            smart_req.SuccessfulSmartServerResponse(('ok', ), None),
 
1601
            request.execute(''))
 
1602
 
 
1603
 
1352
1604
class TestSmartServerRepositoryGetParentMap(tests.TestCaseWithMemoryTransport):
1353
1605
 
1354
1606
    def test_trivial_bzipped(self):
1474
1726
            request.execute('stacked', 1, (3, r3)))
1475
1727
 
1476
1728
 
1477
 
class TestSmartServerRepositoryGetStream(tests.TestCaseWithMemoryTransport):
 
1729
class TestSmartServerRepositoryIterRevisions(
 
1730
    tests.TestCaseWithMemoryTransport):
 
1731
 
 
1732
    def test_basic(self):
 
1733
        backing = self.get_transport()
 
1734
        request = smart_repo.SmartServerRepositoryIterRevisions(backing)
 
1735
        tree = self.make_branch_and_memory_tree('.', format='2a')
 
1736
        tree.lock_write()
 
1737
        tree.add('')
 
1738
        tree.commit('1st commit', rev_id="rev1")
 
1739
        tree.commit('2nd commit', rev_id="rev2")
 
1740
        tree.unlock()
 
1741
 
 
1742
        self.assertIs(None, request.execute(''))
 
1743
        response = request.do_body("rev1\nrev2")
 
1744
        self.assertTrue(response.is_successful())
 
1745
        # Format 2a uses serializer format 10
 
1746
        self.assertEquals(response.args, ("ok", "10"))
 
1747
 
 
1748
        self.addCleanup(tree.branch.lock_read().unlock)
 
1749
        entries = [zlib.compress(record.get_bytes_as("fulltext")) for record in
 
1750
            tree.branch.repository.revisions.get_record_stream(
 
1751
            [("rev1", ), ("rev2", )], "unordered", True)]
 
1752
 
 
1753
        contents = "".join(response.body_stream)
 
1754
        self.assertTrue(contents in (
 
1755
            "".join([entries[0], entries[1]]),
 
1756
            "".join([entries[1], entries[0]])))
 
1757
 
 
1758
    def test_missing(self):
 
1759
        backing = self.get_transport()
 
1760
        request = smart_repo.SmartServerRepositoryIterRevisions(backing)
 
1761
        tree = self.make_branch_and_memory_tree('.', format='2a')
 
1762
 
 
1763
        self.assertIs(None, request.execute(''))
 
1764
        response = request.do_body("rev1\nrev2")
 
1765
        self.assertTrue(response.is_successful())
 
1766
        # Format 2a uses serializer format 10
 
1767
        self.assertEquals(response.args, ("ok", "10"))
 
1768
 
 
1769
        contents = "".join(response.body_stream)
 
1770
        self.assertEquals(contents, "")
 
1771
 
 
1772
 
 
1773
class GetStreamTestBase(tests.TestCaseWithMemoryTransport):
1478
1774
 
1479
1775
    def make_two_commit_repo(self):
1480
1776
        tree = self.make_branch_and_memory_tree('.')
1486
1782
        repo = tree.branch.repository
1487
1783
        return repo, r1, r2
1488
1784
 
 
1785
 
 
1786
class TestSmartServerRepositoryGetStream(GetStreamTestBase):
 
1787
 
1489
1788
    def test_ancestry_of(self):
1490
1789
        """The search argument may be a 'ancestry-of' some heads'."""
1491
1790
        backing = self.get_transport()
1512
1811
        stream_bytes = ''.join(response.body_stream)
1513
1812
        self.assertStartsWith(stream_bytes, 'Bazaar pack format 1')
1514
1813
 
 
1814
    def test_search_everything(self):
 
1815
        """A search of 'everything' returns a stream."""
 
1816
        backing = self.get_transport()
 
1817
        request = smart_repo.SmartServerRepositoryGetStream_1_19(backing)
 
1818
        repo, r1, r2 = self.make_two_commit_repo()
 
1819
        serialised_fetch_spec = 'everything'
 
1820
        request.execute('', repo._format.network_name())
 
1821
        response = request.do_body(serialised_fetch_spec)
 
1822
        self.assertEqual(('ok',), response.args)
 
1823
        stream_bytes = ''.join(response.body_stream)
 
1824
        self.assertStartsWith(stream_bytes, 'Bazaar pack format 1')
 
1825
 
1515
1826
 
1516
1827
class TestSmartServerRequestHasRevision(tests.TestCaseWithMemoryTransport):
1517
1828
 
1538
1849
            request.execute('', rev_id_utf8))
1539
1850
 
1540
1851
 
 
1852
class TestSmartServerRepositoryIterFilesBytes(tests.TestCaseWithTransport):
 
1853
 
 
1854
    def test_single(self):
 
1855
        backing = self.get_transport()
 
1856
        request = smart_repo.SmartServerRepositoryIterFilesBytes(backing)
 
1857
        t = self.make_branch_and_tree('.')
 
1858
        self.addCleanup(t.lock_write().unlock)
 
1859
        self.build_tree_contents([("file", "somecontents")])
 
1860
        t.add(["file"], ["thefileid"])
 
1861
        t.commit(rev_id='somerev', message="add file")
 
1862
        self.assertIs(None, request.execute(''))
 
1863
        response = request.do_body("thefileid\0somerev\n")
 
1864
        self.assertTrue(response.is_successful())
 
1865
        self.assertEquals(response.args, ("ok", ))
 
1866
        self.assertEquals("".join(response.body_stream),
 
1867
            "ok\x000\n" + zlib.compress("somecontents"))
 
1868
 
 
1869
    def test_missing(self):
 
1870
        backing = self.get_transport()
 
1871
        request = smart_repo.SmartServerRepositoryIterFilesBytes(backing)
 
1872
        t = self.make_branch_and_tree('.')
 
1873
        self.addCleanup(t.lock_write().unlock)
 
1874
        self.assertIs(None, request.execute(''))
 
1875
        response = request.do_body("thefileid\0revision\n")
 
1876
        self.assertTrue(response.is_successful())
 
1877
        self.assertEquals(response.args, ("ok", ))
 
1878
        self.assertEquals("".join(response.body_stream),
 
1879
            "absent\x00thefileid\x00revision\x000\n")
 
1880
 
 
1881
 
 
1882
class TestSmartServerRequestHasSignatureForRevisionId(
 
1883
        tests.TestCaseWithMemoryTransport):
 
1884
 
 
1885
    def test_missing_revision(self):
 
1886
        """For a missing revision, NoSuchRevision is returned."""
 
1887
        backing = self.get_transport()
 
1888
        request = smart_repo.SmartServerRequestHasSignatureForRevisionId(
 
1889
            backing)
 
1890
        self.make_repository('.')
 
1891
        self.assertEqual(
 
1892
            smart_req.FailedSmartServerResponse(
 
1893
                ('nosuchrevision', 'revid'), None),
 
1894
            request.execute('', 'revid'))
 
1895
 
 
1896
    def test_missing_signature(self):
 
1897
        """For a missing signature, ('no', ) is returned."""
 
1898
        backing = self.get_transport()
 
1899
        request = smart_repo.SmartServerRequestHasSignatureForRevisionId(
 
1900
            backing)
 
1901
        tree = self.make_branch_and_memory_tree('.')
 
1902
        tree.lock_write()
 
1903
        tree.add('')
 
1904
        r1 = tree.commit('a commit', rev_id='A')
 
1905
        tree.unlock()
 
1906
        self.assertTrue(tree.branch.repository.has_revision('A'))
 
1907
        self.assertEqual(smart_req.SmartServerResponse(('no', )),
 
1908
            request.execute('', 'A'))
 
1909
 
 
1910
    def test_present_signature(self):
 
1911
        """For a present signature, ('yes', ) is returned."""
 
1912
        backing = self.get_transport()
 
1913
        request = smart_repo.SmartServerRequestHasSignatureForRevisionId(
 
1914
            backing)
 
1915
        strategy = gpg.LoopbackGPGStrategy(None)
 
1916
        tree = self.make_branch_and_memory_tree('.')
 
1917
        tree.lock_write()
 
1918
        tree.add('')
 
1919
        r1 = tree.commit('a commit', rev_id='A')
 
1920
        tree.branch.repository.start_write_group()
 
1921
        tree.branch.repository.sign_revision('A', strategy)
 
1922
        tree.branch.repository.commit_write_group()
 
1923
        tree.unlock()
 
1924
        self.assertTrue(tree.branch.repository.has_revision('A'))
 
1925
        self.assertEqual(smart_req.SmartServerResponse(('yes', )),
 
1926
            request.execute('', 'A'))
 
1927
 
 
1928
 
1541
1929
class TestSmartServerRepositoryGatherStats(tests.TestCaseWithMemoryTransport):
1542
1930
 
1543
1931
    def test_empty_revid(self):
1596
1984
                         request.execute('',
1597
1985
                                         rev_id_utf8, 'yes'))
1598
1986
 
 
1987
    def test_unknown_revid(self):
 
1988
        """An unknown revision id causes a 'nosuchrevision' error."""
 
1989
        backing = self.get_transport()
 
1990
        request = smart_repo.SmartServerRepositoryGatherStats(backing)
 
1991
        repository = self.make_repository('.')
 
1992
        expected_body = 'revisions: 0\n'
 
1993
        self.assertEqual(
 
1994
            smart_req.FailedSmartServerResponse(
 
1995
                ('nosuchrevision', 'mia'), None),
 
1996
            request.execute('', 'mia', 'yes'))
 
1997
 
1599
1998
 
1600
1999
class TestSmartServerRepositoryIsShared(tests.TestCaseWithMemoryTransport):
1601
2000
 
1616
2015
            request.execute('', ))
1617
2016
 
1618
2017
 
 
2018
class TestSmartServerRepositoryGetRevisionSignatureText(
 
2019
        tests.TestCaseWithMemoryTransport):
 
2020
 
 
2021
    def test_get_signature(self):
 
2022
        backing = self.get_transport()
 
2023
        request = smart_repo.SmartServerRepositoryGetRevisionSignatureText(
 
2024
            backing)
 
2025
        bb = self.make_branch_builder('.')
 
2026
        bb.build_commit(rev_id='A')
 
2027
        repo = bb.get_branch().repository
 
2028
        strategy = gpg.LoopbackGPGStrategy(None)
 
2029
        self.addCleanup(repo.lock_write().unlock)
 
2030
        repo.start_write_group()
 
2031
        repo.sign_revision('A', strategy)
 
2032
        repo.commit_write_group()
 
2033
        expected_body = (
 
2034
            '-----BEGIN PSEUDO-SIGNED CONTENT-----\n' +
 
2035
            Testament.from_revision(repo, 'A').as_short_text() +
 
2036
            '-----END PSEUDO-SIGNED CONTENT-----\n')
 
2037
        self.assertEqual(
 
2038
            smart_req.SmartServerResponse(('ok', ), expected_body),
 
2039
            request.execute('', 'A'))
 
2040
 
 
2041
 
 
2042
class TestSmartServerRepositoryMakeWorkingTrees(
 
2043
        tests.TestCaseWithMemoryTransport):
 
2044
 
 
2045
    def test_make_working_trees(self):
 
2046
        """For a repository with working trees, ('yes', ) is returned."""
 
2047
        backing = self.get_transport()
 
2048
        request = smart_repo.SmartServerRepositoryMakeWorkingTrees(backing)
 
2049
        r = self.make_repository('.')
 
2050
        r.set_make_working_trees(True)
 
2051
        self.assertEqual(smart_req.SmartServerResponse(('yes', )),
 
2052
            request.execute('', ))
 
2053
 
 
2054
    def test_is_not_shared(self):
 
2055
        """For a repository with working trees, ('no', ) is returned."""
 
2056
        backing = self.get_transport()
 
2057
        request = smart_repo.SmartServerRepositoryMakeWorkingTrees(backing)
 
2058
        r = self.make_repository('.')
 
2059
        r.set_make_working_trees(False)
 
2060
        self.assertEqual(smart_req.SmartServerResponse(('no', )),
 
2061
            request.execute('', ))
 
2062
 
 
2063
 
1619
2064
class TestSmartServerRepositoryLockWrite(tests.TestCaseWithMemoryTransport):
1620
2065
 
1621
2066
    def test_lock_write_on_unlocked_repo(self):
1735
2180
            smart_req.SmartServerResponse(('TokenMismatch',)), response)
1736
2181
 
1737
2182
 
 
2183
class TestSmartServerRepositoryGetPhysicalLockStatus(
 
2184
    tests.TestCaseWithTransport):
 
2185
 
 
2186
    def test_with_write_lock(self):
 
2187
        backing = self.get_transport()
 
2188
        repo = self.make_repository('.')
 
2189
        self.addCleanup(repo.lock_write().unlock)
 
2190
        # lock_write() doesn't necessarily actually take a physical
 
2191
        # lock out.
 
2192
        if repo.get_physical_lock_status():
 
2193
            expected = 'yes'
 
2194
        else:
 
2195
            expected = 'no'
 
2196
        request_class = smart_repo.SmartServerRepositoryGetPhysicalLockStatus
 
2197
        request = request_class(backing)
 
2198
        self.assertEqual(smart_req.SuccessfulSmartServerResponse((expected,)),
 
2199
            request.execute('', ))
 
2200
 
 
2201
    def test_without_write_lock(self):
 
2202
        backing = self.get_transport()
 
2203
        repo = self.make_repository('.')
 
2204
        self.assertEquals(False, repo.get_physical_lock_status())
 
2205
        request_class = smart_repo.SmartServerRepositoryGetPhysicalLockStatus
 
2206
        request = request_class(backing)
 
2207
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(('no',)),
 
2208
            request.execute('', ))
 
2209
 
 
2210
 
 
2211
class TestSmartServerRepositoryReconcile(tests.TestCaseWithTransport):
 
2212
 
 
2213
    def test_reconcile(self):
 
2214
        backing = self.get_transport()
 
2215
        repo = self.make_repository('.')
 
2216
        token = repo.lock_write().repository_token
 
2217
        self.addCleanup(repo.unlock)
 
2218
        request_class = smart_repo.SmartServerRepositoryReconcile
 
2219
        request = request_class(backing)
 
2220
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(
 
2221
            ('ok', ),
 
2222
             'garbage_inventories: 0\n'
 
2223
             'inconsistent_parents: 0\n'),
 
2224
            request.execute('', token))
 
2225
 
 
2226
 
1738
2227
class TestSmartServerIsReadonly(tests.TestCaseWithMemoryTransport):
1739
2228
 
1740
2229
    def test_is_readonly_no(self):
1778
2267
        self.assertTrue(repo.make_working_trees())
1779
2268
 
1780
2269
 
 
2270
class TestSmartServerRepositoryGetSerializerFormat(
 
2271
    tests.TestCaseWithMemoryTransport):
 
2272
 
 
2273
    def test_get_serializer_format(self):
 
2274
        backing = self.get_transport()
 
2275
        repo = self.make_repository('.', format='2a')
 
2276
        request_class = smart_repo.SmartServerRepositoryGetSerializerFormat
 
2277
        request = request_class(backing)
 
2278
        self.assertEqual(
 
2279
            smart_req.SuccessfulSmartServerResponse(('ok', '10')),
 
2280
            request.execute(''))
 
2281
 
 
2282
 
 
2283
class TestSmartServerRepositoryWriteGroup(
 
2284
    tests.TestCaseWithMemoryTransport):
 
2285
 
 
2286
    def test_start_write_group(self):
 
2287
        backing = self.get_transport()
 
2288
        repo = self.make_repository('.')
 
2289
        lock_token = repo.lock_write().repository_token
 
2290
        self.addCleanup(repo.unlock)
 
2291
        request_class = smart_repo.SmartServerRepositoryStartWriteGroup
 
2292
        request = request_class(backing)
 
2293
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(('ok', [])),
 
2294
            request.execute('', lock_token))
 
2295
 
 
2296
    def test_start_write_group_unsuspendable(self):
 
2297
        backing = self.get_transport()
 
2298
        repo = self.make_repository('.', format='knit')
 
2299
        lock_token = repo.lock_write().repository_token
 
2300
        self.addCleanup(repo.unlock)
 
2301
        request_class = smart_repo.SmartServerRepositoryStartWriteGroup
 
2302
        request = request_class(backing)
 
2303
        self.assertEqual(
 
2304
            smart_req.FailedSmartServerResponse(('UnsuspendableWriteGroup',)),
 
2305
            request.execute('', lock_token))
 
2306
 
 
2307
    def test_commit_write_group(self):
 
2308
        backing = self.get_transport()
 
2309
        repo = self.make_repository('.')
 
2310
        lock_token = repo.lock_write().repository_token
 
2311
        self.addCleanup(repo.unlock)
 
2312
        repo.start_write_group()
 
2313
        tokens = repo.suspend_write_group()
 
2314
        request_class = smart_repo.SmartServerRepositoryCommitWriteGroup
 
2315
        request = request_class(backing)
 
2316
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(('ok',)),
 
2317
            request.execute('', lock_token, tokens))
 
2318
 
 
2319
    def test_abort_write_group(self):
 
2320
        backing = self.get_transport()
 
2321
        repo = self.make_repository('.')
 
2322
        lock_token = repo.lock_write().repository_token
 
2323
        repo.start_write_group()
 
2324
        tokens = repo.suspend_write_group()
 
2325
        self.addCleanup(repo.unlock)
 
2326
        request_class = smart_repo.SmartServerRepositoryAbortWriteGroup
 
2327
        request = request_class(backing)
 
2328
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(('ok',)),
 
2329
            request.execute('', lock_token, tokens))
 
2330
 
 
2331
    def test_check_write_group(self):
 
2332
        backing = self.get_transport()
 
2333
        repo = self.make_repository('.')
 
2334
        lock_token = repo.lock_write().repository_token
 
2335
        repo.start_write_group()
 
2336
        tokens = repo.suspend_write_group()
 
2337
        self.addCleanup(repo.unlock)
 
2338
        request_class = smart_repo.SmartServerRepositoryCheckWriteGroup
 
2339
        request = request_class(backing)
 
2340
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(('ok',)),
 
2341
            request.execute('', lock_token, tokens))
 
2342
 
 
2343
    def test_check_write_group_invalid(self):
 
2344
        backing = self.get_transport()
 
2345
        repo = self.make_repository('.')
 
2346
        lock_token = repo.lock_write().repository_token
 
2347
        self.addCleanup(repo.unlock)
 
2348
        request_class = smart_repo.SmartServerRepositoryCheckWriteGroup
 
2349
        request = request_class(backing)
 
2350
        self.assertEqual(smart_req.FailedSmartServerResponse(
 
2351
            ('UnresumableWriteGroup', ['random'],
 
2352
                'Malformed write group token')),
 
2353
            request.execute('', lock_token, ["random"]))
 
2354
 
 
2355
 
1781
2356
class TestSmartServerPackRepositoryAutopack(tests.TestCaseWithTransport):
1782
2357
 
1783
2358
    def make_repo_needing_autopacking(self, path='.'):
1849
2424
        """All registered request_handlers can be found."""
1850
2425
        # If there's a typo in a register_lazy call, this loop will fail with
1851
2426
        # an AttributeError.
1852
 
        for key, item in smart_req.request_handlers.iteritems():
1853
 
            pass
 
2427
        for key in smart_req.request_handlers.keys():
 
2428
            try:
 
2429
                item = smart_req.request_handlers.get(key)
 
2430
            except AttributeError, e:
 
2431
                raise AttributeError('failed to get %s: %s' % (key, e))
1854
2432
 
1855
2433
    def assertHandlerEqual(self, verb, handler):
1856
2434
        self.assertEqual(smart_req.request_handlers.get(verb), handler)
1857
2435
 
1858
2436
    def test_registered_methods(self):
1859
2437
        """Test that known methods are registered to the correct object."""
 
2438
        self.assertHandlerEqual('Branch.break_lock',
 
2439
            smart_branch.SmartServerBranchBreakLock)
1860
2440
        self.assertHandlerEqual('Branch.get_config_file',
1861
2441
            smart_branch.SmartServerBranchGetConfigFile)
 
2442
        self.assertHandlerEqual('Branch.put_config_file',
 
2443
            smart_branch.SmartServerBranchPutConfigFile)
1862
2444
        self.assertHandlerEqual('Branch.get_parent',
1863
2445
            smart_branch.SmartServerBranchGetParent)
 
2446
        self.assertHandlerEqual('Branch.get_physical_lock_status',
 
2447
            smart_branch.SmartServerBranchRequestGetPhysicalLockStatus)
1864
2448
        self.assertHandlerEqual('Branch.get_tags_bytes',
1865
2449
            smart_branch.SmartServerBranchGetTagsBytes)
1866
2450
        self.assertHandlerEqual('Branch.lock_write',
1869
2453
            smart_branch.SmartServerBranchRequestLastRevisionInfo)
1870
2454
        self.assertHandlerEqual('Branch.revision_history',
1871
2455
            smart_branch.SmartServerRequestRevisionHistory)
 
2456
        self.assertHandlerEqual('Branch.revision_id_to_revno',
 
2457
            smart_branch.SmartServerBranchRequestRevisionIdToRevno)
1872
2458
        self.assertHandlerEqual('Branch.set_config_option',
1873
2459
            smart_branch.SmartServerBranchRequestSetConfigOption)
1874
2460
        self.assertHandlerEqual('Branch.set_last_revision',
1881
2467
            smart_branch.SmartServerBranchRequestSetParentLocation)
1882
2468
        self.assertHandlerEqual('Branch.unlock',
1883
2469
            smart_branch.SmartServerBranchRequestUnlock)
 
2470
        self.assertHandlerEqual('BzrDir.destroy_branch',
 
2471
            smart_dir.SmartServerBzrDirRequestDestroyBranch)
1884
2472
        self.assertHandlerEqual('BzrDir.find_repository',
1885
2473
            smart_dir.SmartServerRequestFindRepositoryV1)
1886
2474
        self.assertHandlerEqual('BzrDir.find_repositoryV2',
1901
2489
            smart_dir.SmartServerRequestOpenBranchV3)
1902
2490
        self.assertHandlerEqual('PackRepository.autopack',
1903
2491
            smart_packrepo.SmartServerPackRepositoryAutopack)
 
2492
        self.assertHandlerEqual('Repository.add_signature_text',
 
2493
            smart_repo.SmartServerRepositoryAddSignatureText)
 
2494
        self.assertHandlerEqual('Repository.all_revision_ids',
 
2495
            smart_repo.SmartServerRepositoryAllRevisionIds)
 
2496
        self.assertHandlerEqual('Repository.break_lock',
 
2497
            smart_repo.SmartServerRepositoryBreakLock)
1904
2498
        self.assertHandlerEqual('Repository.gather_stats',
1905
2499
            smart_repo.SmartServerRepositoryGatherStats)
1906
2500
        self.assertHandlerEqual('Repository.get_parent_map',
1907
2501
            smart_repo.SmartServerRepositoryGetParentMap)
 
2502
        self.assertHandlerEqual('Repository.get_physical_lock_status',
 
2503
            smart_repo.SmartServerRepositoryGetPhysicalLockStatus)
1908
2504
        self.assertHandlerEqual('Repository.get_rev_id_for_revno',
1909
2505
            smart_repo.SmartServerRepositoryGetRevIdForRevno)
1910
2506
        self.assertHandlerEqual('Repository.get_revision_graph',
1911
2507
            smart_repo.SmartServerRepositoryGetRevisionGraph)
 
2508
        self.assertHandlerEqual('Repository.get_revision_signature_text',
 
2509
            smart_repo.SmartServerRepositoryGetRevisionSignatureText)
1912
2510
        self.assertHandlerEqual('Repository.get_stream',
1913
2511
            smart_repo.SmartServerRepositoryGetStream)
 
2512
        self.assertHandlerEqual('Repository.get_stream_1.19',
 
2513
            smart_repo.SmartServerRepositoryGetStream_1_19)
 
2514
        self.assertHandlerEqual('Repository.iter_revisions',
 
2515
            smart_repo.SmartServerRepositoryIterRevisions)
1914
2516
        self.assertHandlerEqual('Repository.has_revision',
1915
2517
            smart_repo.SmartServerRequestHasRevision)
1916
2518
        self.assertHandlerEqual('Repository.insert_stream',
1919
2521
            smart_repo.SmartServerRepositoryInsertStreamLocked)
1920
2522
        self.assertHandlerEqual('Repository.is_shared',
1921
2523
            smart_repo.SmartServerRepositoryIsShared)
 
2524
        self.assertHandlerEqual('Repository.iter_files_bytes',
 
2525
            smart_repo.SmartServerRepositoryIterFilesBytes)
1922
2526
        self.assertHandlerEqual('Repository.lock_write',
1923
2527
            smart_repo.SmartServerRepositoryLockWrite)
 
2528
        self.assertHandlerEqual('Repository.make_working_trees',
 
2529
            smart_repo.SmartServerRepositoryMakeWorkingTrees)
 
2530
        self.assertHandlerEqual('Repository.pack',
 
2531
            smart_repo.SmartServerRepositoryPack)
 
2532
        self.assertHandlerEqual('Repository.reconcile',
 
2533
            smart_repo.SmartServerRepositoryReconcile)
1924
2534
        self.assertHandlerEqual('Repository.tarball',
1925
2535
            smart_repo.SmartServerRepositoryTarball)
1926
2536
        self.assertHandlerEqual('Repository.unlock',
1927
2537
            smart_repo.SmartServerRepositoryUnlock)
 
2538
        self.assertHandlerEqual('Repository.start_write_group',
 
2539
            smart_repo.SmartServerRepositoryStartWriteGroup)
 
2540
        self.assertHandlerEqual('Repository.check_write_group',
 
2541
            smart_repo.SmartServerRepositoryCheckWriteGroup)
 
2542
        self.assertHandlerEqual('Repository.commit_write_group',
 
2543
            smart_repo.SmartServerRepositoryCommitWriteGroup)
 
2544
        self.assertHandlerEqual('Repository.abort_write_group',
 
2545
            smart_repo.SmartServerRepositoryAbortWriteGroup)
 
2546
        self.assertHandlerEqual('VersionedFileRepository.get_serializer_format',
 
2547
            smart_repo.SmartServerRepositoryGetSerializerFormat)
1928
2548
        self.assertHandlerEqual('Transport.is_readonly',
1929
2549
            smart_req.SmartServerIsReadonly)
 
2550
 
 
2551
 
 
2552
class SmartTCPServerHookTests(tests.TestCaseWithMemoryTransport):
 
2553
    """Tests for SmartTCPServer hooks."""
 
2554
 
 
2555
    def setUp(self):
 
2556
        super(SmartTCPServerHookTests, self).setUp()
 
2557
        self.server = server.SmartTCPServer(self.get_transport())
 
2558
 
 
2559
    def test_run_server_started_hooks(self):
 
2560
        """Test the server started hooks get fired properly."""
 
2561
        started_calls = []
 
2562
        server.SmartTCPServer.hooks.install_named_hook('server_started',
 
2563
            lambda backing_urls, url: started_calls.append((backing_urls, url)),
 
2564
            None)
 
2565
        started_ex_calls = []
 
2566
        server.SmartTCPServer.hooks.install_named_hook('server_started_ex',
 
2567
            lambda backing_urls, url: started_ex_calls.append((backing_urls, url)),
 
2568
            None)
 
2569
        self.server._sockname = ('example.com', 42)
 
2570
        self.server.run_server_started_hooks()
 
2571
        self.assertEquals(started_calls,
 
2572
            [([self.get_transport().base], 'bzr://example.com:42/')])
 
2573
        self.assertEquals(started_ex_calls,
 
2574
            [([self.get_transport().base], self.server)])
 
2575
 
 
2576
    def test_run_server_started_hooks_ipv6(self):
 
2577
        """Test that socknames can contain 4-tuples."""
 
2578
        self.server._sockname = ('::', 42, 0, 0)
 
2579
        started_calls = []
 
2580
        server.SmartTCPServer.hooks.install_named_hook('server_started',
 
2581
            lambda backing_urls, url: started_calls.append((backing_urls, url)),
 
2582
            None)
 
2583
        self.server.run_server_started_hooks()
 
2584
        self.assertEquals(started_calls,
 
2585
                [([self.get_transport().base], 'bzr://:::42/')])
 
2586
 
 
2587
    def test_run_server_stopped_hooks(self):
 
2588
        """Test the server stopped hooks."""
 
2589
        self.server._sockname = ('example.com', 42)
 
2590
        stopped_calls = []
 
2591
        server.SmartTCPServer.hooks.install_named_hook('server_stopped',
 
2592
            lambda backing_urls, url: stopped_calls.append((backing_urls, url)),
 
2593
            None)
 
2594
        self.server.run_server_stopped_hooks()
 
2595
        self.assertEquals(stopped_calls,
 
2596
            [([self.get_transport().base], 'bzr://example.com:42/')])
 
2597
 
 
2598
 
 
2599
class TestSmartServerRepositoryPack(tests.TestCaseWithMemoryTransport):
 
2600
 
 
2601
    def test_pack(self):
 
2602
        backing = self.get_transport()
 
2603
        request = smart_repo.SmartServerRepositoryPack(backing)
 
2604
        tree = self.make_branch_and_memory_tree('.')
 
2605
        repo_token = tree.branch.repository.lock_write().repository_token
 
2606
 
 
2607
        self.assertIs(None, request.execute('', repo_token, False))
 
2608
 
 
2609
        self.assertEqual(
 
2610
            smart_req.SuccessfulSmartServerResponse(('ok', ), ),
 
2611
            request.do_body(''))
 
2612