225
229
self.assertEqual(expected, request.execute('', 'False'))
232
class TestSmartServerBzrDirRequestCloningMetaDir(
233
tests.TestCaseWithMemoryTransport):
234
"""Tests for BzrDir.checkout_metadir."""
236
def test_checkout_metadir(self):
237
backing = self.get_transport()
238
request = smart_dir.SmartServerBzrDirRequestCheckoutMetaDir(
240
branch = self.make_branch('.', format='2a')
241
response = request.execute('')
243
smart_req.SmartServerResponse(
244
('Bazaar-NG meta directory, format 1\n',
245
'Bazaar repository format 2a (needs bzr 1.16 or later)\n',
246
'Bazaar Branch Format 7 (needs bzr 1.6)\n')),
250
class TestSmartServerBzrDirRequestDestroyBranch(
251
tests.TestCaseWithMemoryTransport):
252
"""Tests for BzrDir.destroy_branch."""
254
def test_destroy_branch_default(self):
255
"""The default branch can be removed."""
256
backing = self.get_transport()
257
dir = self.make_branch('.').controldir
258
request_class = smart_dir.SmartServerBzrDirRequestDestroyBranch
259
request = request_class(backing)
260
expected = smart_req.SuccessfulSmartServerResponse(('ok',))
261
self.assertEqual(expected, request.execute('', None))
263
def test_destroy_branch_named(self):
264
"""A named branch can be removed."""
265
backing = self.get_transport()
266
dir = self.make_repository('.', format="development-colo").controldir
267
dir.create_branch(name="branchname")
268
request_class = smart_dir.SmartServerBzrDirRequestDestroyBranch
269
request = request_class(backing)
270
expected = smart_req.SuccessfulSmartServerResponse(('ok',))
271
self.assertEqual(expected, request.execute('', "branchname"))
273
def test_destroy_branch_missing(self):
274
"""An error is raised if the branch didn't exist."""
275
backing = self.get_transport()
276
dir = self.make_controldir('.', format="development-colo")
277
request_class = smart_dir.SmartServerBzrDirRequestDestroyBranch
278
request = request_class(backing)
279
expected = smart_req.FailedSmartServerResponse(('nobranch',), None)
280
self.assertEqual(expected, request.execute('', "branchname"))
283
class TestSmartServerBzrDirRequestHasWorkingTree(
284
tests.TestCaseWithTransport):
285
"""Tests for BzrDir.has_workingtree."""
287
def test_has_workingtree_yes(self):
288
"""A working tree is present."""
289
backing = self.get_transport()
290
dir = self.make_branch_and_tree('.').controldir
291
request_class = smart_dir.SmartServerBzrDirRequestHasWorkingTree
292
request = request_class(backing)
293
expected = smart_req.SuccessfulSmartServerResponse(('yes',))
294
self.assertEqual(expected, request.execute(''))
296
def test_has_workingtree_no(self):
297
"""A working tree is missing."""
298
backing = self.get_transport()
299
dir = self.make_controldir('.')
300
request_class = smart_dir.SmartServerBzrDirRequestHasWorkingTree
301
request = request_class(backing)
302
expected = smart_req.SuccessfulSmartServerResponse(('no',))
303
self.assertEqual(expected, request.execute(''))
306
class TestSmartServerBzrDirRequestDestroyRepository(
307
tests.TestCaseWithMemoryTransport):
308
"""Tests for BzrDir.destroy_repository."""
310
def test_destroy_repository_default(self):
311
"""The repository can be removed."""
312
backing = self.get_transport()
313
dir = self.make_repository('.').controldir
314
request_class = smart_dir.SmartServerBzrDirRequestDestroyRepository
315
request = request_class(backing)
316
expected = smart_req.SuccessfulSmartServerResponse(('ok',))
317
self.assertEqual(expected, request.execute(''))
319
def test_destroy_repository_missing(self):
320
"""An error is raised if the repository didn't exist."""
321
backing = self.get_transport()
322
dir = self.make_controldir('.')
323
request_class = smart_dir.SmartServerBzrDirRequestDestroyRepository
324
request = request_class(backing)
325
expected = smart_req.FailedSmartServerResponse(
326
('norepository',), None)
327
self.assertEqual(expected, request.execute(''))
228
330
class TestSmartServerRequestCreateRepository(tests.TestCaseWithMemoryTransport):
229
331
"""Tests for BzrDir.create_repository."""
231
333
def test_makes_repository(self):
232
334
"""When there is a bzrdir present, the call succeeds."""
233
335
backing = self.get_transport()
234
self.make_bzrdir('.')
336
self.make_controldir('.')
235
337
request_class = smart_dir.SmartServerRequestCreateRepository
236
338
request = request_class(backing)
237
reference_bzrdir_format = bzrdir.format_registry.get('pack-0.92')()
339
reference_bzrdir_format = controldir.format_registry.get('pack-0.92')()
238
340
reference_format = reference_bzrdir_format.repository_format
239
341
network_name = reference_format.network_name()
240
342
expected = smart_req.SuccessfulSmartServerResponse(
354
456
def test_missing(self):
355
457
backing = self.get_transport()
356
dir = self.make_bzrdir('.')
458
dir = self.make_controldir('.')
357
459
request_class = smart_dir.SmartServerBzrDirRequestConfigFile
358
460
request = request_class(backing)
359
461
expected = smart_req.SuccessfulSmartServerResponse((), '')
360
462
self.assertEqual(expected, request.execute(''))
465
class TestSmartServerBzrDirRequestGetBranches(
466
tests.TestCaseWithMemoryTransport):
467
"""Tests for BzrDir.get_branches."""
469
def test_simple(self):
470
backing = self.get_transport()
471
branch = self.make_branch('.')
472
request_class = smart_dir.SmartServerBzrDirRequestGetBranches
473
request = request_class(backing)
474
local_result = bencode.bencode(
475
{"": ("branch", branch._format.network_name())})
476
expected = smart_req.SuccessfulSmartServerResponse(
477
("success", ), local_result)
478
self.assertEqual(expected, request.execute(''))
480
def test_empty(self):
481
backing = self.get_transport()
482
dir = self.make_controldir('.')
483
request_class = smart_dir.SmartServerBzrDirRequestGetBranches
484
request = request_class(backing)
485
local_result = bencode.bencode({})
486
expected = smart_req.SuccessfulSmartServerResponse(
487
('success',), local_result)
488
self.assertEqual(expected, request.execute(''))
363
491
class TestSmartServerRequestInitializeBzrDir(tests.TestCaseWithMemoryTransport):
365
493
def test_empty_dir(self):
767
930
class TestLockedBranch(tests.TestCaseWithMemoryTransport):
769
932
def get_lock_tokens(self, branch):
770
branch_token = branch.lock_write()
771
repo_token = branch.repository.lock_write()
933
branch_token = branch.lock_write().token
934
repo_token = branch.repository.lock_write().repository_token
772
935
branch.repository.unlock()
773
936
return branch_token, repo_token
939
class TestSmartServerBranchRequestPutConfigFile(TestLockedBranch):
941
def test_with_content(self):
942
backing = self.get_transport()
943
request = smart_branch.SmartServerBranchPutConfigFile(backing)
944
branch = self.make_branch('.')
945
branch_token, repo_token = self.get_lock_tokens(branch)
946
self.assertIs(None, request.execute('', branch_token, repo_token))
948
smart_req.SmartServerResponse(('ok', )),
949
request.do_body('foo bar baz'))
951
branch.control_transport.get_bytes('branch.conf'),
776
956
class TestSmartServerBranchRequestSetConfigOption(TestLockedBranch):
778
958
def test_value_name(self):
779
959
branch = self.make_branch('.')
780
960
request = smart_branch.SmartServerBranchRequestSetConfigOption(
781
branch.bzrdir.root_transport)
961
branch.controldir.root_transport)
782
962
branch_token, repo_token = self.get_lock_tokens(branch)
783
963
config = branch._get_config()
784
964
result = request.execute('', branch_token, repo_token, 'bar', 'foo',
985
class TestSmartServerBranchRequestSetConfigOptionDict(TestLockedBranch):
988
TestLockedBranch.setUp(self)
989
# A dict with non-ascii keys and values to exercise unicode
991
self.encoded_value_dict = (
992
'd5:ascii1:a11:unicode \xe2\x8c\x9a3:\xe2\x80\xbde')
994
'ascii': 'a', u'unicode \N{WATCH}': u'\N{INTERROBANG}'}
996
def test_value_name(self):
997
branch = self.make_branch('.')
998
request = smart_branch.SmartServerBranchRequestSetConfigOptionDict(
999
branch.controldir.root_transport)
1000
branch_token, repo_token = self.get_lock_tokens(branch)
1001
config = branch._get_config()
1002
result = request.execute('', branch_token, repo_token,
1003
self.encoded_value_dict, 'foo', '')
1004
self.assertEqual(smart_req.SuccessfulSmartServerResponse(()), result)
1005
self.assertEqual(self.value_dict, config.get_option('foo'))
1009
def test_value_name_section(self):
1010
branch = self.make_branch('.')
1011
request = smart_branch.SmartServerBranchRequestSetConfigOptionDict(
1012
branch.controldir.root_transport)
1013
branch_token, repo_token = self.get_lock_tokens(branch)
1014
config = branch._get_config()
1015
result = request.execute('', branch_token, repo_token,
1016
self.encoded_value_dict, 'foo', 'gam')
1017
self.assertEqual(smart_req.SuccessfulSmartServerResponse(()), result)
1018
self.assertEqual(self.value_dict, config.get_option('foo', 'gam'))
805
1023
class TestSmartServerBranchRequestSetTagsBytes(TestLockedBranch):
806
1024
# Only called when the branch format and tags match [yay factory
807
1025
# methods] so only need to test straight forward cases.
1082
1320
branch.unlock()
1083
1321
request = smart_branch.SmartServerBranchRequestSetParentLocation(
1084
1322
self.get_transport())
1085
branch_token = branch.lock_write()
1086
repo_token = branch.repository.lock_write()
1323
branch_token, repo_token = self.get_lock_tokens(branch)
1088
1325
response = request.execute('base', branch_token, repo_token, '')
1090
branch.repository.unlock()
1091
1327
branch.unlock()
1092
1328
self.assertEqual(smart_req.SuccessfulSmartServerResponse(()), response)
1329
# Refresh branch as SetParentLocation modified it
1330
branch = branch.controldir.open_branch()
1093
1331
self.assertEqual(None, branch.get_parent())
1095
1333
def test_set_parent_something(self):
1096
1334
branch = self.make_branch('base', format="1.9")
1097
1335
request = smart_branch.SmartServerBranchRequestSetParentLocation(
1098
1336
self.get_transport())
1099
branch_token = branch.lock_write()
1100
repo_token = branch.repository.lock_write()
1337
branch_token, repo_token = self.get_lock_tokens(branch)
1102
1339
response = request.execute('base', branch_token, repo_token,
1105
branch.repository.unlock()
1106
1342
branch.unlock()
1107
1343
self.assertEqual(smart_req.SuccessfulSmartServerResponse(()), response)
1108
self.assertEqual('http://bar/', branch.get_parent())
1344
refreshed = _mod_branch.Branch.open(branch.base)
1345
self.assertEqual('http://bar/', refreshed.get_parent())
1111
1348
class TestSmartServerBranchRequestGetTagsBytes(
1249
1479
self.assertEqual('LockFailed', error_name)
1252
class TestSmartServerBranchRequestUnlock(tests.TestCaseWithMemoryTransport):
1255
tests.TestCaseWithMemoryTransport.setUp(self)
1482
class TestSmartServerBranchRequestGetPhysicalLockStatus(TestLockedBranch):
1484
def test_true(self):
1485
backing = self.get_transport()
1486
request = smart_branch.SmartServerBranchRequestGetPhysicalLockStatus(
1488
branch = self.make_branch('.')
1489
branch_token, repo_token = self.get_lock_tokens(branch)
1490
self.assertEqual(True, branch.get_physical_lock_status())
1491
response = request.execute('')
1493
smart_req.SmartServerResponse(('yes',)), response)
1496
def test_false(self):
1497
backing = self.get_transport()
1498
request = smart_branch.SmartServerBranchRequestGetPhysicalLockStatus(
1500
branch = self.make_branch('.')
1501
self.assertEqual(False, branch.get_physical_lock_status())
1502
response = request.execute('')
1504
smart_req.SmartServerResponse(('no',)), response)
1507
class TestSmartServerBranchRequestUnlock(TestLockedBranch):
1257
1509
def test_unlock_on_locked_branch_and_repo(self):
1258
1510
backing = self.get_transport()
1259
1511
request = smart_branch.SmartServerBranchRequestUnlock(backing)
1260
1512
branch = self.make_branch('.', format='knit')
1261
1513
# Lock the branch
1262
branch_token = branch.lock_write()
1263
repo_token = branch.repository.lock_write()
1264
branch.repository.unlock()
1514
branch_token, repo_token = self.get_lock_tokens(branch)
1265
1515
# Unlock the branch (and repo) object, leaving the physical locks
1267
1517
branch.leave_lock_in_place()
1317
1566
backing = self.get_transport()
1318
1567
request = smart_repo.SmartServerRepositoryRequest(backing)
1319
1568
self.make_repository('.', shared=True)
1320
self.make_bzrdir('subdir')
1569
self.make_controldir('subdir')
1321
1570
self.assertRaises(errors.NoRepositoryPresent,
1322
1571
request.execute, 'subdir')
1574
class TestSmartServerRepositoryAddSignatureText(tests.TestCaseWithMemoryTransport):
1576
def test_add_text(self):
1577
backing = self.get_transport()
1578
request = smart_repo.SmartServerRepositoryAddSignatureText(backing)
1579
tree = self.make_branch_and_memory_tree('.')
1580
write_token = tree.lock_write()
1581
self.addCleanup(tree.unlock)
1583
tree.commit("Message", rev_id=b'rev1')
1584
tree.branch.repository.start_write_group()
1585
write_group_tokens = tree.branch.repository.suspend_write_group()
1586
self.assertEqual(None, request.execute('', write_token,
1587
'rev1', *write_group_tokens))
1588
response = request.do_body('somesignature')
1589
self.assertTrue(response.is_successful())
1590
self.assertEqual(response.args[0], 'ok')
1591
write_group_tokens = response.args[1:]
1592
tree.branch.repository.resume_write_group(write_group_tokens)
1593
tree.branch.repository.commit_write_group()
1595
self.assertEqual("somesignature",
1596
tree.branch.repository.get_signature_text("rev1"))
1599
class TestSmartServerRepositoryAllRevisionIds(
1600
tests.TestCaseWithMemoryTransport):
1602
def test_empty(self):
1603
"""An empty body should be returned for an empty repository."""
1604
backing = self.get_transport()
1605
request = smart_repo.SmartServerRepositoryAllRevisionIds(backing)
1606
self.make_repository('.')
1608
smart_req.SuccessfulSmartServerResponse(("ok", ), ""),
1609
request.execute(''))
1611
def test_some_revisions(self):
1612
"""An empty body should be returned for an empty repository."""
1613
backing = self.get_transport()
1614
request = smart_repo.SmartServerRepositoryAllRevisionIds(backing)
1615
tree = self.make_branch_and_memory_tree('.')
1618
tree.commit(rev_id=b'origineel', message="message")
1619
tree.commit(rev_id=b'nog-een-revisie', message="message")
1622
smart_req.SuccessfulSmartServerResponse(("ok", ),
1623
"origineel\nnog-een-revisie"),
1624
request.execute(''))
1627
class TestSmartServerRepositoryBreakLock(tests.TestCaseWithMemoryTransport):
1629
def test_lock_to_break(self):
1630
backing = self.get_transport()
1631
request = smart_repo.SmartServerRepositoryBreakLock(backing)
1632
tree = self.make_branch_and_memory_tree('.')
1633
tree.branch.repository.lock_write()
1635
smart_req.SuccessfulSmartServerResponse(('ok', ), None),
1636
request.execute(''))
1638
def test_nothing_to_break(self):
1639
backing = self.get_transport()
1640
request = smart_repo.SmartServerRepositoryBreakLock(backing)
1641
tree = self.make_branch_and_memory_tree('.')
1643
smart_req.SuccessfulSmartServerResponse(('ok', ), None),
1644
request.execute(''))
1325
1647
class TestSmartServerRepositoryGetParentMap(tests.TestCaseWithMemoryTransport):
1327
1649
def test_trivial_bzipped(self):
1447
1769
request.execute('stacked', 1, (3, r3)))
1450
class TestSmartServerRepositoryGetStream(tests.TestCaseWithMemoryTransport):
1772
class TestSmartServerRepositoryIterRevisions(
1773
tests.TestCaseWithMemoryTransport):
1775
def test_basic(self):
1776
backing = self.get_transport()
1777
request = smart_repo.SmartServerRepositoryIterRevisions(backing)
1778
tree = self.make_branch_and_memory_tree('.', format='2a')
1781
tree.commit('1st commit', rev_id="rev1")
1782
tree.commit('2nd commit', rev_id="rev2")
1785
self.assertIs(None, request.execute(''))
1786
response = request.do_body("rev1\nrev2")
1787
self.assertTrue(response.is_successful())
1788
# Format 2a uses serializer format 10
1789
self.assertEqual(response.args, ("ok", "10"))
1791
self.addCleanup(tree.branch.lock_read().unlock)
1792
entries = [zlib.compress(record.get_bytes_as("fulltext")) for record in
1793
tree.branch.repository.revisions.get_record_stream(
1794
[("rev1", ), ("rev2", )], "unordered", True)]
1796
contents = "".join(response.body_stream)
1797
self.assertTrue(contents in (
1798
"".join([entries[0], entries[1]]),
1799
"".join([entries[1], entries[0]])))
1801
def test_missing(self):
1802
backing = self.get_transport()
1803
request = smart_repo.SmartServerRepositoryIterRevisions(backing)
1804
tree = self.make_branch_and_memory_tree('.', format='2a')
1806
self.assertIs(None, request.execute(''))
1807
response = request.do_body("rev1\nrev2")
1808
self.assertTrue(response.is_successful())
1809
# Format 2a uses serializer format 10
1810
self.assertEqual(response.args, ("ok", "10"))
1812
contents = "".join(response.body_stream)
1813
self.assertEqual(contents, "")
1816
class GetStreamTestBase(tests.TestCaseWithMemoryTransport):
1452
1818
def make_two_commit_repo(self):
1453
1819
tree = self.make_branch_and_memory_tree('.')
1511
1892
request.execute('', rev_id_utf8))
1895
class TestSmartServerRepositoryIterFilesBytes(tests.TestCaseWithTransport):
1897
def test_single(self):
1898
backing = self.get_transport()
1899
request = smart_repo.SmartServerRepositoryIterFilesBytes(backing)
1900
t = self.make_branch_and_tree('.')
1901
self.addCleanup(t.lock_write().unlock)
1902
self.build_tree_contents([("file", b"somecontents")])
1903
t.add(["file"], [b"thefileid"])
1904
t.commit(rev_id=b'somerev', message="add file")
1905
self.assertIs(None, request.execute(''))
1906
response = request.do_body("thefileid\0somerev\n")
1907
self.assertTrue(response.is_successful())
1908
self.assertEqual(response.args, ("ok", ))
1909
self.assertEqual("".join(response.body_stream),
1910
"ok\x000\n" + zlib.compress("somecontents"))
1912
def test_missing(self):
1913
backing = self.get_transport()
1914
request = smart_repo.SmartServerRepositoryIterFilesBytes(backing)
1915
t = self.make_branch_and_tree('.')
1916
self.addCleanup(t.lock_write().unlock)
1917
self.assertIs(None, request.execute(''))
1918
response = request.do_body("thefileid\0revision\n")
1919
self.assertTrue(response.is_successful())
1920
self.assertEqual(response.args, ("ok", ))
1921
self.assertEqual("".join(response.body_stream),
1922
"absent\x00thefileid\x00revision\x000\n")
1925
class TestSmartServerRequestHasSignatureForRevisionId(
1926
tests.TestCaseWithMemoryTransport):
1928
def test_missing_revision(self):
1929
"""For a missing revision, NoSuchRevision is returned."""
1930
backing = self.get_transport()
1931
request = smart_repo.SmartServerRequestHasSignatureForRevisionId(
1933
self.make_repository('.')
1935
smart_req.FailedSmartServerResponse(
1936
('nosuchrevision', 'revid'), None),
1937
request.execute('', 'revid'))
1939
def test_missing_signature(self):
1940
"""For a missing signature, ('no', ) is returned."""
1941
backing = self.get_transport()
1942
request = smart_repo.SmartServerRequestHasSignatureForRevisionId(
1944
tree = self.make_branch_and_memory_tree('.')
1947
r1 = tree.commit('a commit', rev_id=b'A')
1949
self.assertTrue(tree.branch.repository.has_revision('A'))
1950
self.assertEqual(smart_req.SmartServerResponse(('no', )),
1951
request.execute('', 'A'))
1953
def test_present_signature(self):
1954
"""For a present signature, ('yes', ) is returned."""
1955
backing = self.get_transport()
1956
request = smart_repo.SmartServerRequestHasSignatureForRevisionId(
1958
strategy = gpg.LoopbackGPGStrategy(None)
1959
tree = self.make_branch_and_memory_tree('.')
1962
r1 = tree.commit('a commit', rev_id=b'A')
1963
tree.branch.repository.start_write_group()
1964
tree.branch.repository.sign_revision('A', strategy)
1965
tree.branch.repository.commit_write_group()
1967
self.assertTrue(tree.branch.repository.has_revision('A'))
1968
self.assertEqual(smart_req.SmartServerResponse(('yes', )),
1969
request.execute('', 'A'))
1514
1972
class TestSmartServerRepositoryGatherStats(tests.TestCaseWithMemoryTransport):
1516
1974
def test_empty_revid(self):
1589
2058
request.execute('', ))
2061
class TestSmartServerRepositoryGetRevisionSignatureText(
2062
tests.TestCaseWithMemoryTransport):
2064
def test_get_signature(self):
2065
backing = self.get_transport()
2066
request = smart_repo.SmartServerRepositoryGetRevisionSignatureText(
2068
bb = self.make_branch_builder('.')
2069
bb.build_commit(rev_id=b'A')
2070
repo = bb.get_branch().repository
2071
strategy = gpg.LoopbackGPGStrategy(None)
2072
self.addCleanup(repo.lock_write().unlock)
2073
repo.start_write_group()
2074
repo.sign_revision('A', strategy)
2075
repo.commit_write_group()
2077
'-----BEGIN PSEUDO-SIGNED CONTENT-----\n' +
2078
Testament.from_revision(repo, 'A').as_short_text() +
2079
'-----END PSEUDO-SIGNED CONTENT-----\n')
2081
smart_req.SmartServerResponse(('ok', ), expected_body),
2082
request.execute('', 'A'))
2085
class TestSmartServerRepositoryMakeWorkingTrees(
2086
tests.TestCaseWithMemoryTransport):
2088
def test_make_working_trees(self):
2089
"""For a repository with working trees, ('yes', ) is returned."""
2090
backing = self.get_transport()
2091
request = smart_repo.SmartServerRepositoryMakeWorkingTrees(backing)
2092
r = self.make_repository('.')
2093
r.set_make_working_trees(True)
2094
self.assertEqual(smart_req.SmartServerResponse(('yes', )),
2095
request.execute('', ))
2097
def test_is_not_shared(self):
2098
"""For a repository with working trees, ('no', ) is returned."""
2099
backing = self.get_transport()
2100
request = smart_repo.SmartServerRepositoryMakeWorkingTrees(backing)
2101
r = self.make_repository('.')
2102
r.set_make_working_trees(False)
2103
self.assertEqual(smart_req.SmartServerResponse(('no', )),
2104
request.execute('', ))
1592
2107
class TestSmartServerRepositoryLockWrite(tests.TestCaseWithMemoryTransport):
1594
2109
def test_lock_write_on_unlocked_repo(self):
1708
2220
smart_req.SmartServerResponse(('TokenMismatch',)), response)
2223
class TestSmartServerRepositoryGetPhysicalLockStatus(
2224
tests.TestCaseWithTransport):
2226
def test_with_write_lock(self):
2227
backing = self.get_transport()
2228
repo = self.make_repository('.')
2229
self.addCleanup(repo.lock_write().unlock)
2230
# lock_write() doesn't necessarily actually take a physical
2232
if repo.get_physical_lock_status():
2236
request_class = smart_repo.SmartServerRepositoryGetPhysicalLockStatus
2237
request = request_class(backing)
2238
self.assertEqual(smart_req.SuccessfulSmartServerResponse((expected,)),
2239
request.execute('', ))
2241
def test_without_write_lock(self):
2242
backing = self.get_transport()
2243
repo = self.make_repository('.')
2244
self.assertEqual(False, repo.get_physical_lock_status())
2245
request_class = smart_repo.SmartServerRepositoryGetPhysicalLockStatus
2246
request = request_class(backing)
2247
self.assertEqual(smart_req.SuccessfulSmartServerResponse(('no',)),
2248
request.execute('', ))
2251
class TestSmartServerRepositoryReconcile(tests.TestCaseWithTransport):
2253
def test_reconcile(self):
2254
backing = self.get_transport()
2255
repo = self.make_repository('.')
2256
token = repo.lock_write().repository_token
2257
self.addCleanup(repo.unlock)
2258
request_class = smart_repo.SmartServerRepositoryReconcile
2259
request = request_class(backing)
2260
self.assertEqual(smart_req.SuccessfulSmartServerResponse(
2262
'garbage_inventories: 0\n'
2263
'inconsistent_parents: 0\n'),
2264
request.execute('', token))
1711
2267
class TestSmartServerIsReadonly(tests.TestCaseWithMemoryTransport):
1713
2269
def test_is_readonly_no(self):
1747
2303
request = request_class(backing)
1748
2304
self.assertEqual(smart_req.SuccessfulSmartServerResponse(('ok',)),
1749
2305
request.execute('', 'True'))
1750
repo = repo.bzrdir.open_repository()
2306
repo = repo.controldir.open_repository()
1751
2307
self.assertTrue(repo.make_working_trees())
2310
class TestSmartServerRepositoryGetSerializerFormat(
2311
tests.TestCaseWithMemoryTransport):
2313
def test_get_serializer_format(self):
2314
backing = self.get_transport()
2315
repo = self.make_repository('.', format='2a')
2316
request_class = smart_repo.SmartServerRepositoryGetSerializerFormat
2317
request = request_class(backing)
2319
smart_req.SuccessfulSmartServerResponse(('ok', '10')),
2320
request.execute(''))
2323
class TestSmartServerRepositoryWriteGroup(
2324
tests.TestCaseWithMemoryTransport):
2326
def test_start_write_group(self):
2327
backing = self.get_transport()
2328
repo = self.make_repository('.')
2329
lock_token = repo.lock_write().repository_token
2330
self.addCleanup(repo.unlock)
2331
request_class = smart_repo.SmartServerRepositoryStartWriteGroup
2332
request = request_class(backing)
2333
self.assertEqual(smart_req.SuccessfulSmartServerResponse(('ok', [])),
2334
request.execute('', lock_token))
2336
def test_start_write_group_unsuspendable(self):
2337
backing = self.get_transport()
2338
repo = self.make_repository('.', format='knit')
2339
lock_token = repo.lock_write().repository_token
2340
self.addCleanup(repo.unlock)
2341
request_class = smart_repo.SmartServerRepositoryStartWriteGroup
2342
request = request_class(backing)
2344
smart_req.FailedSmartServerResponse(('UnsuspendableWriteGroup',)),
2345
request.execute('', lock_token))
2347
def test_commit_write_group(self):
2348
backing = self.get_transport()
2349
repo = self.make_repository('.')
2350
lock_token = repo.lock_write().repository_token
2351
self.addCleanup(repo.unlock)
2352
repo.start_write_group()
2353
tokens = repo.suspend_write_group()
2354
request_class = smart_repo.SmartServerRepositoryCommitWriteGroup
2355
request = request_class(backing)
2356
self.assertEqual(smart_req.SuccessfulSmartServerResponse(('ok',)),
2357
request.execute('', lock_token, tokens))
2359
def test_abort_write_group(self):
2360
backing = self.get_transport()
2361
repo = self.make_repository('.')
2362
lock_token = repo.lock_write().repository_token
2363
repo.start_write_group()
2364
tokens = repo.suspend_write_group()
2365
self.addCleanup(repo.unlock)
2366
request_class = smart_repo.SmartServerRepositoryAbortWriteGroup
2367
request = request_class(backing)
2368
self.assertEqual(smart_req.SuccessfulSmartServerResponse(('ok',)),
2369
request.execute('', lock_token, tokens))
2371
def test_check_write_group(self):
2372
backing = self.get_transport()
2373
repo = self.make_repository('.')
2374
lock_token = repo.lock_write().repository_token
2375
repo.start_write_group()
2376
tokens = repo.suspend_write_group()
2377
self.addCleanup(repo.unlock)
2378
request_class = smart_repo.SmartServerRepositoryCheckWriteGroup
2379
request = request_class(backing)
2380
self.assertEqual(smart_req.SuccessfulSmartServerResponse(('ok',)),
2381
request.execute('', lock_token, tokens))
2383
def test_check_write_group_invalid(self):
2384
backing = self.get_transport()
2385
repo = self.make_repository('.')
2386
lock_token = repo.lock_write().repository_token
2387
self.addCleanup(repo.unlock)
2388
request_class = smart_repo.SmartServerRepositoryCheckWriteGroup
2389
request = request_class(backing)
2390
self.assertEqual(smart_req.FailedSmartServerResponse(
2391
('UnresumableWriteGroup', ['random'],
2392
'Malformed write group token')),
2393
request.execute('', lock_token, ["random"]))
1754
2396
class TestSmartServerPackRepositoryAutopack(tests.TestCaseWithTransport):
1756
2398
def make_repo_needing_autopacking(self, path='.'):
1822
2464
"""All registered request_handlers can be found."""
1823
2465
# If there's a typo in a register_lazy call, this loop will fail with
1824
2466
# an AttributeError.
1825
for key, item in smart_req.request_handlers.iteritems():
2467
for key in smart_req.request_handlers.keys():
2469
item = smart_req.request_handlers.get(key)
2470
except AttributeError as e:
2471
raise AttributeError('failed to get %s: %s' % (key, e))
1828
2473
def assertHandlerEqual(self, verb, handler):
1829
2474
self.assertEqual(smart_req.request_handlers.get(verb), handler)
1831
2476
def test_registered_methods(self):
1832
2477
"""Test that known methods are registered to the correct object."""
2478
self.assertHandlerEqual('Branch.break_lock',
2479
smart_branch.SmartServerBranchBreakLock)
1833
2480
self.assertHandlerEqual('Branch.get_config_file',
1834
2481
smart_branch.SmartServerBranchGetConfigFile)
2482
self.assertHandlerEqual('Branch.put_config_file',
2483
smart_branch.SmartServerBranchPutConfigFile)
1835
2484
self.assertHandlerEqual('Branch.get_parent',
1836
2485
smart_branch.SmartServerBranchGetParent)
2486
self.assertHandlerEqual('Branch.get_physical_lock_status',
2487
smart_branch.SmartServerBranchRequestGetPhysicalLockStatus)
1837
2488
self.assertHandlerEqual('Branch.get_tags_bytes',
1838
2489
smart_branch.SmartServerBranchGetTagsBytes)
1839
2490
self.assertHandlerEqual('Branch.lock_write',
1874
2533
smart_dir.SmartServerRequestOpenBranchV3)
1875
2534
self.assertHandlerEqual('PackRepository.autopack',
1876
2535
smart_packrepo.SmartServerPackRepositoryAutopack)
2536
self.assertHandlerEqual('Repository.add_signature_text',
2537
smart_repo.SmartServerRepositoryAddSignatureText)
2538
self.assertHandlerEqual('Repository.all_revision_ids',
2539
smart_repo.SmartServerRepositoryAllRevisionIds)
2540
self.assertHandlerEqual('Repository.break_lock',
2541
smart_repo.SmartServerRepositoryBreakLock)
1877
2542
self.assertHandlerEqual('Repository.gather_stats',
1878
2543
smart_repo.SmartServerRepositoryGatherStats)
1879
2544
self.assertHandlerEqual('Repository.get_parent_map',
1880
2545
smart_repo.SmartServerRepositoryGetParentMap)
2546
self.assertHandlerEqual('Repository.get_physical_lock_status',
2547
smart_repo.SmartServerRepositoryGetPhysicalLockStatus)
1881
2548
self.assertHandlerEqual('Repository.get_rev_id_for_revno',
1882
2549
smart_repo.SmartServerRepositoryGetRevIdForRevno)
1883
2550
self.assertHandlerEqual('Repository.get_revision_graph',
1884
2551
smart_repo.SmartServerRepositoryGetRevisionGraph)
2552
self.assertHandlerEqual('Repository.get_revision_signature_text',
2553
smart_repo.SmartServerRepositoryGetRevisionSignatureText)
1885
2554
self.assertHandlerEqual('Repository.get_stream',
1886
2555
smart_repo.SmartServerRepositoryGetStream)
2556
self.assertHandlerEqual('Repository.get_stream_1.19',
2557
smart_repo.SmartServerRepositoryGetStream_1_19)
2558
self.assertHandlerEqual('Repository.iter_revisions',
2559
smart_repo.SmartServerRepositoryIterRevisions)
1887
2560
self.assertHandlerEqual('Repository.has_revision',
1888
2561
smart_repo.SmartServerRequestHasRevision)
1889
2562
self.assertHandlerEqual('Repository.insert_stream',
1892
2565
smart_repo.SmartServerRepositoryInsertStreamLocked)
1893
2566
self.assertHandlerEqual('Repository.is_shared',
1894
2567
smart_repo.SmartServerRepositoryIsShared)
2568
self.assertHandlerEqual('Repository.iter_files_bytes',
2569
smart_repo.SmartServerRepositoryIterFilesBytes)
1895
2570
self.assertHandlerEqual('Repository.lock_write',
1896
2571
smart_repo.SmartServerRepositoryLockWrite)
2572
self.assertHandlerEqual('Repository.make_working_trees',
2573
smart_repo.SmartServerRepositoryMakeWorkingTrees)
2574
self.assertHandlerEqual('Repository.pack',
2575
smart_repo.SmartServerRepositoryPack)
2576
self.assertHandlerEqual('Repository.reconcile',
2577
smart_repo.SmartServerRepositoryReconcile)
1897
2578
self.assertHandlerEqual('Repository.tarball',
1898
2579
smart_repo.SmartServerRepositoryTarball)
1899
2580
self.assertHandlerEqual('Repository.unlock',
1900
2581
smart_repo.SmartServerRepositoryUnlock)
2582
self.assertHandlerEqual('Repository.start_write_group',
2583
smart_repo.SmartServerRepositoryStartWriteGroup)
2584
self.assertHandlerEqual('Repository.check_write_group',
2585
smart_repo.SmartServerRepositoryCheckWriteGroup)
2586
self.assertHandlerEqual('Repository.commit_write_group',
2587
smart_repo.SmartServerRepositoryCommitWriteGroup)
2588
self.assertHandlerEqual('Repository.abort_write_group',
2589
smart_repo.SmartServerRepositoryAbortWriteGroup)
2590
self.assertHandlerEqual('VersionedFileRepository.get_serializer_format',
2591
smart_repo.SmartServerRepositoryGetSerializerFormat)
2592
self.assertHandlerEqual('VersionedFileRepository.get_inventories',
2593
smart_repo.SmartServerRepositoryGetInventories)
1901
2594
self.assertHandlerEqual('Transport.is_readonly',
1902
2595
smart_req.SmartServerIsReadonly)
2598
class SmartTCPServerHookTests(tests.TestCaseWithMemoryTransport):
2599
"""Tests for SmartTCPServer hooks."""
2602
super(SmartTCPServerHookTests, self).setUp()
2603
self.server = server.SmartTCPServer(self.get_transport())
2605
def test_run_server_started_hooks(self):
2606
"""Test the server started hooks get fired properly."""
2608
server.SmartTCPServer.hooks.install_named_hook('server_started',
2609
lambda backing_urls, url: started_calls.append((backing_urls, url)),
2611
started_ex_calls = []
2612
server.SmartTCPServer.hooks.install_named_hook('server_started_ex',
2613
lambda backing_urls, url: started_ex_calls.append((backing_urls, url)),
2615
self.server._sockname = ('example.com', 42)
2616
self.server.run_server_started_hooks()
2617
self.assertEqual(started_calls,
2618
[([self.get_transport().base], 'bzr://example.com:42/')])
2619
self.assertEqual(started_ex_calls,
2620
[([self.get_transport().base], self.server)])
2622
def test_run_server_started_hooks_ipv6(self):
2623
"""Test that socknames can contain 4-tuples."""
2624
self.server._sockname = ('::', 42, 0, 0)
2626
server.SmartTCPServer.hooks.install_named_hook('server_started',
2627
lambda backing_urls, url: started_calls.append((backing_urls, url)),
2629
self.server.run_server_started_hooks()
2630
self.assertEqual(started_calls,
2631
[([self.get_transport().base], 'bzr://:::42/')])
2633
def test_run_server_stopped_hooks(self):
2634
"""Test the server stopped hooks."""
2635
self.server._sockname = ('example.com', 42)
2637
server.SmartTCPServer.hooks.install_named_hook('server_stopped',
2638
lambda backing_urls, url: stopped_calls.append((backing_urls, url)),
2640
self.server.run_server_stopped_hooks()
2641
self.assertEqual(stopped_calls,
2642
[([self.get_transport().base], 'bzr://example.com:42/')])
2645
class TestSmartServerRepositoryPack(tests.TestCaseWithMemoryTransport):
2647
def test_pack(self):
2648
backing = self.get_transport()
2649
request = smart_repo.SmartServerRepositoryPack(backing)
2650
tree = self.make_branch_and_memory_tree('.')
2651
repo_token = tree.branch.repository.lock_write().repository_token
2653
self.assertIs(None, request.execute('', repo_token, False))
2656
smart_req.SuccessfulSmartServerResponse(('ok', ), ),
2657
request.do_body(''))
2660
class TestSmartServerRepositoryGetInventories(tests.TestCaseWithTransport):
2662
def _get_serialized_inventory_delta(self, repository, base_revid, revid):
2663
base_inv = repository.revision_tree(base_revid).root_inventory
2664
inv = repository.revision_tree(revid).root_inventory
2665
inv_delta = inv._make_delta(base_inv)
2666
serializer = inventory_delta.InventoryDeltaSerializer(True, False)
2667
return "".join(serializer.delta_to_lines(base_revid, revid, inv_delta))
2669
def test_single(self):
2670
backing = self.get_transport()
2671
request = smart_repo.SmartServerRepositoryGetInventories(backing)
2672
t = self.make_branch_and_tree('.', format='2a')
2673
self.addCleanup(t.lock_write().unlock)
2674
self.build_tree_contents([("file", b"somecontents")])
2675
t.add(["file"], [b"thefileid"])
2676
t.commit(rev_id=b'somerev', message="add file")
2677
self.assertIs(None, request.execute('', 'unordered'))
2678
response = request.do_body("somerev\n")
2679
self.assertTrue(response.is_successful())
2680
self.assertEqual(response.args, ("ok", ))
2681
stream = [('inventory-deltas', [
2682
versionedfile.FulltextContentFactory('somerev', None, None,
2683
self._get_serialized_inventory_delta(
2684
t.branch.repository, 'null:', 'somerev'))])]
2685
fmt = controldir.format_registry.get('2a')().repository_format
2687
"".join(response.body_stream),
2688
"".join(smart_repo._stream_to_byte_stream(stream, fmt)))
2690
def test_empty(self):
2691
backing = self.get_transport()
2692
request = smart_repo.SmartServerRepositoryGetInventories(backing)
2693
t = self.make_branch_and_tree('.', format='2a')
2694
self.addCleanup(t.lock_write().unlock)
2695
self.build_tree_contents([("file", b"somecontents")])
2696
t.add(["file"], [b"thefileid"])
2697
t.commit(rev_id=b'somerev', message="add file")
2698
self.assertIs(None, request.execute('', 'unordered'))
2699
response = request.do_body("")
2700
self.assertTrue(response.is_successful())
2701
self.assertEqual(response.args, ("ok", ))
2702
self.assertEqual("".join(response.body_stream),
2703
"Bazaar pack format 1 (introduced in 0.18)\nB54\n\nBazaar repository format 2a (needs bzr 1.16 or later)\nE")