/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_smart.py

  • Committer: Vincent Ladeuil
  • Date: 2011-11-24 15:48:29 UTC
  • mfrom: (6289 +trunk)
  • mto: This revision was merged to the branch mainline in revision 6337.
  • Revision ID: v.ladeuil+lp@free.fr-20111124154829-avowjpsxdl8yp2vz
merge trunk resolving conflicts

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2006-2010 Canonical Ltd
 
1
# Copyright (C) 2006-2011 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
25
25
"""
26
26
 
27
27
import bz2
28
 
from cStringIO import StringIO
29
 
import tarfile
30
28
 
31
29
from bzrlib import (
32
 
    bencode,
33
30
    branch as _mod_branch,
34
31
    bzrdir,
35
32
    errors,
36
 
    pack,
 
33
    gpg,
37
34
    tests,
38
35
    transport,
39
36
    urlutils,
89
86
            backing_transport = tests.TestCaseWithTransport.get_transport(self)
90
87
            self._chroot_server = chroot.ChrootServer(backing_transport)
91
88
            self.start_server(self._chroot_server)
92
 
        t = transport.get_transport(self._chroot_server.get_url())
 
89
        t = transport.get_transport_from_url(self._chroot_server.get_url())
93
90
        if relpath is not None:
94
91
            t = t.clone(relpath)
95
92
        return t
103
100
        # the default or a parameterized class, but rather use the
104
101
        # TestCaseWithTransport infrastructure to set up a smart server and
105
102
        # transport.
106
 
        self.transport_server = self.make_transport_server
 
103
        self.overrideAttr(self, "transport_server", self.make_transport_server)
107
104
 
108
105
    def make_transport_server(self):
109
106
        return test_server.SmartTCPServer_for_testing('-' + self.id())
225
222
        self.assertEqual(expected, request.execute('', 'False'))
226
223
 
227
224
 
 
225
class TestSmartServerBzrDirRequestHasWorkingTree(
 
226
    tests.TestCaseWithTransport):
 
227
    """Tests for BzrDir.has_workingtree."""
 
228
 
 
229
    def test_has_workingtree_yes(self):
 
230
        """A working tree is present."""
 
231
        backing = self.get_transport()
 
232
        dir = self.make_branch_and_tree('.').bzrdir
 
233
        request_class = smart_dir.SmartServerBzrDirRequestHasWorkingTree
 
234
        request = request_class(backing)
 
235
        expected = smart_req.SuccessfulSmartServerResponse(('yes',))
 
236
        self.assertEqual(expected, request.execute(''))
 
237
 
 
238
    def test_has_workingtree_no(self):
 
239
        """A working tree is missing."""
 
240
        backing = self.get_transport()
 
241
        dir = self.make_bzrdir('.')
 
242
        request_class = smart_dir.SmartServerBzrDirRequestHasWorkingTree
 
243
        request = request_class(backing)
 
244
        expected = smart_req.SuccessfulSmartServerResponse(('no',))
 
245
        self.assertEqual(expected, request.execute(''))
 
246
 
 
247
 
 
248
class TestSmartServerBzrDirRequestDestroyRepository(
 
249
    tests.TestCaseWithMemoryTransport):
 
250
    """Tests for BzrDir.destroy_repository."""
 
251
 
 
252
    def test_destroy_repository_default(self):
 
253
        """The repository can be removed."""
 
254
        backing = self.get_transport()
 
255
        dir = self.make_repository('.').bzrdir
 
256
        request_class = smart_dir.SmartServerBzrDirRequestDestroyRepository
 
257
        request = request_class(backing)
 
258
        expected = smart_req.SuccessfulSmartServerResponse(('ok',))
 
259
        self.assertEqual(expected, request.execute(''))
 
260
 
 
261
    def test_destroy_repository_missing(self):
 
262
        """An error is raised if the repository didn't exist."""
 
263
        backing = self.get_transport()
 
264
        dir = self.make_bzrdir('.')
 
265
        request_class = smart_dir.SmartServerBzrDirRequestDestroyRepository
 
266
        request = request_class(backing)
 
267
        expected = smart_req.FailedSmartServerResponse(
 
268
            ('norepository',), None)
 
269
        self.assertEqual(expected, request.execute(''))
 
270
 
 
271
 
228
272
class TestSmartServerRequestCreateRepository(tests.TestCaseWithMemoryTransport):
229
273
    """Tests for BzrDir.create_repository."""
230
274
 
767
811
class TestLockedBranch(tests.TestCaseWithMemoryTransport):
768
812
 
769
813
    def get_lock_tokens(self, branch):
770
 
        branch_token = branch.lock_write()
771
 
        repo_token = branch.repository.lock_write()
 
814
        branch_token = branch.lock_write().branch_token
 
815
        repo_token = branch.repository.lock_write().repository_token
772
816
        branch.repository.unlock()
773
817
        return branch_token, repo_token
774
818
 
775
819
 
 
820
class TestSmartServerBranchRequestPutConfigFile(TestLockedBranch):
 
821
 
 
822
    def test_with_content(self):
 
823
        backing = self.get_transport()
 
824
        request = smart_branch.SmartServerBranchPutConfigFile(backing)
 
825
        branch = self.make_branch('.')
 
826
        branch_token, repo_token = self.get_lock_tokens(branch)
 
827
        self.assertIs(None, request.execute('', branch_token, repo_token))
 
828
        self.assertEqual(
 
829
            smart_req.SmartServerResponse(('ok', )),
 
830
            request.do_body('foo bar baz'))
 
831
        self.assertEquals(
 
832
            branch.control_transport.get_bytes('branch.conf'),
 
833
            'foo bar baz')
 
834
        branch.unlock()
 
835
 
 
836
 
776
837
class TestSmartServerBranchRequestSetConfigOption(TestLockedBranch):
777
838
 
778
839
    def test_value_name(self):
802
863
        branch.unlock()
803
864
 
804
865
 
 
866
class TestSmartServerBranchRequestSetConfigOptionDict(TestLockedBranch):
 
867
 
 
868
    def setUp(self):
 
869
        TestLockedBranch.setUp(self)
 
870
        # A dict with non-ascii keys and values to exercise unicode
 
871
        # roundtripping.
 
872
        self.encoded_value_dict = (
 
873
            'd5:ascii1:a11:unicode \xe2\x8c\x9a3:\xe2\x80\xbde')
 
874
        self.value_dict = {
 
875
            'ascii': 'a', u'unicode \N{WATCH}': u'\N{INTERROBANG}'}
 
876
 
 
877
    def test_value_name(self):
 
878
        branch = self.make_branch('.')
 
879
        request = smart_branch.SmartServerBranchRequestSetConfigOptionDict(
 
880
            branch.bzrdir.root_transport)
 
881
        branch_token, repo_token = self.get_lock_tokens(branch)
 
882
        config = branch._get_config()
 
883
        result = request.execute('', branch_token, repo_token,
 
884
            self.encoded_value_dict, 'foo', '')
 
885
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(()), result)
 
886
        self.assertEqual(self.value_dict, config.get_option('foo'))
 
887
        # Cleanup
 
888
        branch.unlock()
 
889
 
 
890
    def test_value_name_section(self):
 
891
        branch = self.make_branch('.')
 
892
        request = smart_branch.SmartServerBranchRequestSetConfigOptionDict(
 
893
            branch.bzrdir.root_transport)
 
894
        branch_token, repo_token = self.get_lock_tokens(branch)
 
895
        config = branch._get_config()
 
896
        result = request.execute('', branch_token, repo_token,
 
897
            self.encoded_value_dict, 'foo', 'gam')
 
898
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(()), result)
 
899
        self.assertEqual(self.value_dict, config.get_option('foo', 'gam'))
 
900
        # Cleanup
 
901
        branch.unlock()
 
902
 
 
903
 
805
904
class TestSmartServerBranchRequestSetTagsBytes(TestLockedBranch):
806
905
    # Only called when the branch format and tags match [yay factory
807
906
    # methods] so only need to test straight forward cases.
898
997
        # its repository.
899
998
        self.make_tree_with_two_commits()
900
999
        rev_id_utf8 = u'\xc8'.encode('utf-8')
901
 
        self.tree.branch.set_revision_history([])
 
1000
        self.tree.branch.set_last_revision_info(0, 'null:')
902
1001
        self.assertEqual(
903
1002
            (0, 'null:'), self.tree.branch.last_revision_info())
904
1003
        # We can update the branch to a revision that is present in the
1073
1172
            response)
1074
1173
 
1075
1174
 
1076
 
class TestSmartServerBranchRequestSetParent(tests.TestCaseWithMemoryTransport):
 
1175
class TestSmartServerBranchRequestSetParent(TestLockedBranch):
1077
1176
 
1078
1177
    def test_set_parent_none(self):
1079
1178
        branch = self.make_branch('base', format="1.9")
1082
1181
        branch.unlock()
1083
1182
        request = smart_branch.SmartServerBranchRequestSetParentLocation(
1084
1183
            self.get_transport())
1085
 
        branch_token = branch.lock_write()
1086
 
        repo_token = branch.repository.lock_write()
 
1184
        branch_token, repo_token = self.get_lock_tokens(branch)
1087
1185
        try:
1088
1186
            response = request.execute('base', branch_token, repo_token, '')
1089
1187
        finally:
1090
 
            branch.repository.unlock()
1091
1188
            branch.unlock()
1092
1189
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(()), response)
1093
1190
        self.assertEqual(None, branch.get_parent())
1096
1193
        branch = self.make_branch('base', format="1.9")
1097
1194
        request = smart_branch.SmartServerBranchRequestSetParentLocation(
1098
1195
            self.get_transport())
1099
 
        branch_token = branch.lock_write()
1100
 
        repo_token = branch.repository.lock_write()
 
1196
        branch_token, repo_token = self.get_lock_tokens(branch)
1101
1197
        try:
1102
1198
            response = request.execute('base', branch_token, repo_token,
1103
1199
            'http://bar/')
1104
1200
        finally:
1105
 
            branch.repository.unlock()
1106
1201
            branch.unlock()
1107
1202
        self.assertEqual(smart_req.SuccessfulSmartServerResponse(()), response)
1108
1203
        self.assertEqual('http://bar/', branch.get_parent())
1137
1232
            response)
1138
1233
 
1139
1234
 
1140
 
class TestSmartServerBranchRequestLockWrite(tests.TestCaseWithMemoryTransport):
 
1235
class TestSmartServerBranchRequestLockWrite(TestLockedBranch):
1141
1236
 
1142
1237
    def setUp(self):
1143
1238
        tests.TestCaseWithMemoryTransport.setUp(self)
1165
1260
        backing = self.get_transport()
1166
1261
        request = smart_branch.SmartServerBranchRequestLockWrite(backing)
1167
1262
        branch = self.make_branch('.')
1168
 
        branch_token = branch.lock_write()
 
1263
        branch_token = branch.lock_write().branch_token
1169
1264
        branch.leave_lock_in_place()
1170
1265
        branch.unlock()
1171
1266
        response = request.execute('')
1180
1275
        backing = self.get_transport()
1181
1276
        request = smart_branch.SmartServerBranchRequestLockWrite(backing)
1182
1277
        branch = self.make_branch('.', format='knit')
1183
 
        branch_token = branch.lock_write()
1184
 
        repo_token = branch.repository.lock_write()
1185
 
        branch.repository.unlock()
 
1278
        branch_token, repo_token = self.get_lock_tokens(branch)
1186
1279
        branch.leave_lock_in_place()
1187
1280
        branch.repository.leave_lock_in_place()
1188
1281
        branch.unlock()
1203
1296
        backing = self.get_transport()
1204
1297
        request = smart_branch.SmartServerBranchRequestLockWrite(backing)
1205
1298
        branch = self.make_branch('.', format='knit')
1206
 
        branch_token = branch.lock_write()
1207
 
        repo_token = branch.repository.lock_write()
1208
 
        branch.repository.unlock()
 
1299
        branch_token, repo_token = self.get_lock_tokens(branch)
1209
1300
        branch.leave_lock_in_place()
1210
1301
        branch.repository.leave_lock_in_place()
1211
1302
        branch.unlock()
1226
1317
        request = smart_branch.SmartServerBranchRequestLockWrite(backing)
1227
1318
        branch = self.make_branch('.', format='knit')
1228
1319
        repo = branch.repository
1229
 
        repo_token = repo.lock_write()
 
1320
        repo_token = repo.lock_write().repository_token
1230
1321
        repo.leave_lock_in_place()
1231
1322
        repo.unlock()
1232
1323
        response = request.execute('')
1249
1340
        self.assertEqual('LockFailed', error_name)
1250
1341
 
1251
1342
 
1252
 
class TestSmartServerBranchRequestUnlock(tests.TestCaseWithMemoryTransport):
 
1343
class TestSmartServerBranchRequestUnlock(TestLockedBranch):
1253
1344
 
1254
1345
    def setUp(self):
1255
1346
        tests.TestCaseWithMemoryTransport.setUp(self)
1259
1350
        request = smart_branch.SmartServerBranchRequestUnlock(backing)
1260
1351
        branch = self.make_branch('.', format='knit')
1261
1352
        # Lock the branch
1262
 
        branch_token = branch.lock_write()
1263
 
        repo_token = branch.repository.lock_write()
1264
 
        branch.repository.unlock()
 
1353
        branch_token, repo_token = self.get_lock_tokens(branch)
1265
1354
        # Unlock the branch (and repo) object, leaving the physical locks
1266
1355
        # in place.
1267
1356
        branch.leave_lock_in_place()
1291
1380
        request = smart_branch.SmartServerBranchRequestUnlock(backing)
1292
1381
        branch = self.make_branch('.', format='knit')
1293
1382
        # Lock the repository.
1294
 
        repo_token = branch.repository.lock_write()
 
1383
        repo_token = branch.repository.lock_write().repository_token
1295
1384
        branch.repository.leave_lock_in_place()
1296
1385
        branch.repository.unlock()
1297
1386
        # Issue branch lock_write request on the unlocked branch (with locked
1298
1387
        # repo).
1299
 
        response = request.execute(
1300
 
            '', 'branch token', repo_token)
 
1388
        response = request.execute('', 'branch token', repo_token)
1301
1389
        self.assertEqual(
1302
1390
            smart_req.SmartServerResponse(('TokenMismatch',)), response)
1303
1391
        # Cleanup
1447
1535
            request.execute('stacked', 1, (3, r3)))
1448
1536
 
1449
1537
 
1450
 
class TestSmartServerRepositoryGetStream(tests.TestCaseWithMemoryTransport):
 
1538
class GetStreamTestBase(tests.TestCaseWithMemoryTransport):
1451
1539
 
1452
1540
    def make_two_commit_repo(self):
1453
1541
        tree = self.make_branch_and_memory_tree('.')
1459
1547
        repo = tree.branch.repository
1460
1548
        return repo, r1, r2
1461
1549
 
 
1550
 
 
1551
class TestSmartServerRepositoryGetStream(GetStreamTestBase):
 
1552
 
1462
1553
    def test_ancestry_of(self):
1463
1554
        """The search argument may be a 'ancestry-of' some heads'."""
1464
1555
        backing = self.get_transport()
1485
1576
        stream_bytes = ''.join(response.body_stream)
1486
1577
        self.assertStartsWith(stream_bytes, 'Bazaar pack format 1')
1487
1578
 
 
1579
    def test_search_everything(self):
 
1580
        """A search of 'everything' returns a stream."""
 
1581
        backing = self.get_transport()
 
1582
        request = smart_repo.SmartServerRepositoryGetStream_1_19(backing)
 
1583
        repo, r1, r2 = self.make_two_commit_repo()
 
1584
        serialised_fetch_spec = 'everything'
 
1585
        request.execute('', repo._format.network_name())
 
1586
        response = request.do_body(serialised_fetch_spec)
 
1587
        self.assertEqual(('ok',), response.args)
 
1588
        stream_bytes = ''.join(response.body_stream)
 
1589
        self.assertStartsWith(stream_bytes, 'Bazaar pack format 1')
 
1590
 
1488
1591
 
1489
1592
class TestSmartServerRequestHasRevision(tests.TestCaseWithMemoryTransport):
1490
1593
 
1511
1614
            request.execute('', rev_id_utf8))
1512
1615
 
1513
1616
 
 
1617
class TestSmartServerRequestHasSignatureForRevisionId(
 
1618
        tests.TestCaseWithMemoryTransport):
 
1619
 
 
1620
    def test_missing_revision(self):
 
1621
        """For a missing revision, NoSuchRevision is returned."""
 
1622
        backing = self.get_transport()
 
1623
        request = smart_repo.SmartServerRequestHasSignatureForRevisionId(
 
1624
            backing)
 
1625
        self.make_repository('.')
 
1626
        self.assertEqual(
 
1627
            smart_req.FailedSmartServerResponse(
 
1628
                ('nosuchrevision', 'revid'), None),
 
1629
            request.execute('', 'revid'))
 
1630
 
 
1631
    def test_missing_signature(self):
 
1632
        """For a missing signature, ('no', ) is returned."""
 
1633
        backing = self.get_transport()
 
1634
        request = smart_repo.SmartServerRequestHasSignatureForRevisionId(
 
1635
            backing)
 
1636
        tree = self.make_branch_and_memory_tree('.')
 
1637
        tree.lock_write()
 
1638
        tree.add('')
 
1639
        r1 = tree.commit('a commit', rev_id='A')
 
1640
        tree.unlock()
 
1641
        self.assertTrue(tree.branch.repository.has_revision('A'))
 
1642
        self.assertEqual(smart_req.SmartServerResponse(('no', )),
 
1643
            request.execute('', 'A'))
 
1644
 
 
1645
    def test_present_signature(self):
 
1646
        """For a present signature, ('yes', ) is returned."""
 
1647
        backing = self.get_transport()
 
1648
        request = smart_repo.SmartServerRequestHasSignatureForRevisionId(
 
1649
            backing)
 
1650
        strategy = gpg.LoopbackGPGStrategy(None)
 
1651
        tree = self.make_branch_and_memory_tree('.')
 
1652
        tree.lock_write()
 
1653
        tree.add('')
 
1654
        r1 = tree.commit('a commit', rev_id='A')
 
1655
        tree.branch.repository.start_write_group()
 
1656
        tree.branch.repository.sign_revision('A', strategy)
 
1657
        tree.branch.repository.commit_write_group()
 
1658
        tree.unlock()
 
1659
        self.assertTrue(tree.branch.repository.has_revision('A'))
 
1660
        self.assertEqual(smart_req.SmartServerResponse(('yes', )),
 
1661
            request.execute('', 'A'))
 
1662
 
 
1663
 
1514
1664
class TestSmartServerRepositoryGatherStats(tests.TestCaseWithMemoryTransport):
1515
1665
 
1516
1666
    def test_empty_revid(self):
1589
1739
            request.execute('', ))
1590
1740
 
1591
1741
 
 
1742
class TestSmartServerRepositoryMakeWorkingTrees(
 
1743
        tests.TestCaseWithMemoryTransport):
 
1744
 
 
1745
    def test_make_working_trees(self):
 
1746
        """For a repository with working trees, ('yes', ) is returned."""
 
1747
        backing = self.get_transport()
 
1748
        request = smart_repo.SmartServerRepositoryMakeWorkingTrees(backing)
 
1749
        r = self.make_repository('.')
 
1750
        r.set_make_working_trees(True)
 
1751
        self.assertEqual(smart_req.SmartServerResponse(('yes', )),
 
1752
            request.execute('', ))
 
1753
 
 
1754
    def test_is_not_shared(self):
 
1755
        """For a repository with working trees, ('no', ) is returned."""
 
1756
        backing = self.get_transport()
 
1757
        request = smart_repo.SmartServerRepositoryMakeWorkingTrees(backing)
 
1758
        r = self.make_repository('.')
 
1759
        r.set_make_working_trees(False)
 
1760
        self.assertEqual(smart_req.SmartServerResponse(('no', )),
 
1761
            request.execute('', ))
 
1762
 
 
1763
 
1592
1764
class TestSmartServerRepositoryLockWrite(tests.TestCaseWithMemoryTransport):
1593
1765
 
1594
1766
    def test_lock_write_on_unlocked_repo(self):
1610
1782
        backing = self.get_transport()
1611
1783
        request = smart_repo.SmartServerRepositoryLockWrite(backing)
1612
1784
        repository = self.make_repository('.', format='knit')
1613
 
        repo_token = repository.lock_write()
 
1785
        repo_token = repository.lock_write().repository_token
1614
1786
        repository.leave_lock_in_place()
1615
1787
        repository.unlock()
1616
1788
        response = request.execute('')
1658
1830
        request = smart_repo.SmartServerRepositoryInsertStreamLocked(
1659
1831
            backing)
1660
1832
        repository = self.make_repository('.', format='knit')
1661
 
        lock_token = repository.lock_write()
 
1833
        lock_token = repository.lock_write().repository_token
1662
1834
        response = request.execute('', '', lock_token)
1663
1835
        self.assertEqual(None, response)
1664
1836
        response = request.do_chunk(self.make_empty_byte_stream(repository))
1672
1844
        request = smart_repo.SmartServerRepositoryInsertStreamLocked(
1673
1845
            backing)
1674
1846
        repository = self.make_repository('.', format='knit')
1675
 
        lock_token = repository.lock_write()
 
1847
        lock_token = repository.lock_write().repository_token
1676
1848
        self.assertRaises(
1677
1849
            errors.TokenMismatch, request.execute, '', '', 'wrong-token')
1678
1850
        repository.unlock()
1687
1859
        backing = self.get_transport()
1688
1860
        request = smart_repo.SmartServerRepositoryUnlock(backing)
1689
1861
        repository = self.make_repository('.', format='knit')
1690
 
        token = repository.lock_write()
 
1862
        token = repository.lock_write().repository_token
1691
1863
        repository.leave_lock_in_place()
1692
1864
        repository.unlock()
1693
1865
        response = request.execute('', token)
1832
2004
        """Test that known methods are registered to the correct object."""
1833
2005
        self.assertHandlerEqual('Branch.get_config_file',
1834
2006
            smart_branch.SmartServerBranchGetConfigFile)
 
2007
        self.assertHandlerEqual('Branch.put_config_file',
 
2008
            smart_branch.SmartServerBranchPutConfigFile)
1835
2009
        self.assertHandlerEqual('Branch.get_parent',
1836
2010
            smart_branch.SmartServerBranchGetParent)
1837
2011
        self.assertHandlerEqual('Branch.get_tags_bytes',
1884
2058
            smart_repo.SmartServerRepositoryGetRevisionGraph)
1885
2059
        self.assertHandlerEqual('Repository.get_stream',
1886
2060
            smart_repo.SmartServerRepositoryGetStream)
 
2061
        self.assertHandlerEqual('Repository.get_stream_1.19',
 
2062
            smart_repo.SmartServerRepositoryGetStream_1_19)
1887
2063
        self.assertHandlerEqual('Repository.has_revision',
1888
2064
            smart_repo.SmartServerRequestHasRevision)
1889
2065
        self.assertHandlerEqual('Repository.insert_stream',
1894
2070
            smart_repo.SmartServerRepositoryIsShared)
1895
2071
        self.assertHandlerEqual('Repository.lock_write',
1896
2072
            smart_repo.SmartServerRepositoryLockWrite)
 
2073
        self.assertHandlerEqual('Repository.make_working_trees',
 
2074
            smart_repo.SmartServerRepositoryMakeWorkingTrees)
1897
2075
        self.assertHandlerEqual('Repository.tarball',
1898
2076
            smart_repo.SmartServerRepositoryTarball)
1899
2077
        self.assertHandlerEqual('Repository.unlock',
1900
2078
            smart_repo.SmartServerRepositoryUnlock)
1901
2079
        self.assertHandlerEqual('Transport.is_readonly',
1902
2080
            smart_req.SmartServerIsReadonly)
 
2081
 
 
2082
 
 
2083
class SmartTCPServerHookTests(tests.TestCaseWithMemoryTransport):
 
2084
    """Tests for SmartTCPServer hooks."""
 
2085
 
 
2086
    def setUp(self):
 
2087
        super(SmartTCPServerHookTests, self).setUp()
 
2088
        self.server = server.SmartTCPServer(self.get_transport())
 
2089
 
 
2090
    def test_run_server_started_hooks(self):
 
2091
        """Test the server started hooks get fired properly."""
 
2092
        started_calls = []
 
2093
        server.SmartTCPServer.hooks.install_named_hook('server_started',
 
2094
            lambda backing_urls, url: started_calls.append((backing_urls, url)),
 
2095
            None)
 
2096
        started_ex_calls = []
 
2097
        server.SmartTCPServer.hooks.install_named_hook('server_started_ex',
 
2098
            lambda backing_urls, url: started_ex_calls.append((backing_urls, url)),
 
2099
            None)
 
2100
        self.server._sockname = ('example.com', 42)
 
2101
        self.server.run_server_started_hooks()
 
2102
        self.assertEquals(started_calls,
 
2103
            [([self.get_transport().base], 'bzr://example.com:42/')])
 
2104
        self.assertEquals(started_ex_calls,
 
2105
            [([self.get_transport().base], self.server)])
 
2106
 
 
2107
    def test_run_server_started_hooks_ipv6(self):
 
2108
        """Test that socknames can contain 4-tuples."""
 
2109
        self.server._sockname = ('::', 42, 0, 0)
 
2110
        started_calls = []
 
2111
        server.SmartTCPServer.hooks.install_named_hook('server_started',
 
2112
            lambda backing_urls, url: started_calls.append((backing_urls, url)),
 
2113
            None)
 
2114
        self.server.run_server_started_hooks()
 
2115
        self.assertEquals(started_calls,
 
2116
                [([self.get_transport().base], 'bzr://:::42/')])
 
2117
 
 
2118
    def test_run_server_stopped_hooks(self):
 
2119
        """Test the server stopped hooks."""
 
2120
        self.server._sockname = ('example.com', 42)
 
2121
        stopped_calls = []
 
2122
        server.SmartTCPServer.hooks.install_named_hook('server_stopped',
 
2123
            lambda backing_urls, url: stopped_calls.append((backing_urls, url)),
 
2124
            None)
 
2125
        self.server.run_server_stopped_hooks()
 
2126
        self.assertEquals(stopped_calls,
 
2127
            [([self.get_transport().base], 'bzr://example.com:42/')])