161
170
def test_translate_client_path(self):
162
171
transport = self.get_transport()
163
172
request = smart_req.SmartServerRequest(transport, 'foo/')
164
self.assertEqual('./', request.translate_client_path('foo/'))
166
errors.InvalidURLJoin, request.translate_client_path, 'foo/..')
168
errors.PathNotChild, request.translate_client_path, '/')
170
errors.PathNotChild, request.translate_client_path, 'bar/')
171
self.assertEqual('./baz', request.translate_client_path('foo/baz'))
172
e_acute = u'\N{LATIN SMALL LETTER E WITH ACUTE}'.encode('utf-8')
173
self.assertEqual('./' + urlutils.escape(e_acute),
174
request.translate_client_path('foo/' + e_acute))
173
self.assertEqual('./', request.translate_client_path(b'foo/'))
175
urlutils.InvalidURLJoin, request.translate_client_path, b'foo/..')
177
errors.PathNotChild, request.translate_client_path, b'/')
179
errors.PathNotChild, request.translate_client_path, b'bar/')
180
self.assertEqual('./baz', request.translate_client_path(b'foo/baz'))
181
e_acute = u'\N{LATIN SMALL LETTER E WITH ACUTE}'
183
u'./' + urlutils.escape(e_acute),
184
request.translate_client_path(b'foo/' + e_acute.encode('utf-8')))
176
186
def test_translate_client_path_vfs(self):
177
187
"""VfsRequests receive escaped paths rather than raw UTF-8."""
178
188
transport = self.get_transport()
179
189
request = vfs.VfsRequest(transport, 'foo/')
180
e_acute = u'\N{LATIN SMALL LETTER E WITH ACUTE}'.encode('utf-8')
181
escaped = urlutils.escape('foo/' + e_acute)
182
self.assertEqual('./' + urlutils.escape(e_acute),
183
request.translate_client_path(escaped))
190
e_acute = u'\N{LATIN SMALL LETTER E WITH ACUTE}'
191
escaped = urlutils.escape(u'foo/' + e_acute)
193
'./' + urlutils.escape(e_acute),
194
request.translate_client_path(escaped.encode('ascii')))
185
196
def test_transport_from_client_path(self):
186
197
transport = self.get_transport()
187
198
request = smart_req.SmartServerRequest(transport, 'foo/')
188
199
self.assertEqual(
190
request.transport_from_client_path('foo/').base)
201
request.transport_from_client_path(b'foo/').base)
193
204
class TestSmartServerBzrDirRequestCloningMetaDir(
194
tests.TestCaseWithMemoryTransport):
205
tests.TestCaseWithMemoryTransport):
195
206
"""Tests for BzrDir.cloning_metadir."""
197
208
def test_cloning_metadir(self):
198
209
"""When there is a bzrdir present, the call succeeds."""
199
210
backing = self.get_transport()
200
dir = self.make_bzrdir('.')
211
dir = self.make_controldir('.')
201
212
local_result = dir.cloning_metadir()
202
213
request_class = smart_dir.SmartServerBzrDirRequestCloningMetaDir
203
214
request = request_class(backing)
204
215
expected = smart_req.SuccessfulSmartServerResponse(
205
216
(local_result.network_name(),
206
local_result.repository_format.network_name(),
207
('branch', local_result.get_branch_format().network_name())))
208
self.assertEqual(expected, request.execute('', 'False'))
217
local_result.repository_format.network_name(),
218
(b'branch', local_result.get_branch_format().network_name())))
219
self.assertEqual(expected, request.execute(b'', b'False'))
210
221
def test_cloning_metadir_reference(self):
211
222
"""The request fails when bzrdir contains a branch reference."""
212
223
backing = self.get_transport()
213
224
referenced_branch = self.make_branch('referenced')
214
dir = self.make_bzrdir('.')
215
local_result = dir.cloning_metadir()
216
reference = _mod_branch.BranchReferenceFormat().initialize(
225
dir = self.make_controldir('.')
226
dir.cloning_metadir()
227
_mod_bzrbranch.BranchReferenceFormat().initialize(
217
228
dir, target_branch=referenced_branch)
218
reference_url = _mod_branch.BranchReferenceFormat().get_reference(dir)
229
_mod_bzrbranch.BranchReferenceFormat().get_reference(dir)
219
230
# The server shouldn't try to follow the branch reference, so it's fine
220
231
# if the referenced branch isn't reachable.
221
232
backing.rename('referenced', 'moved')
222
233
request_class = smart_dir.SmartServerBzrDirRequestCloningMetaDir
223
234
request = request_class(backing)
224
expected = smart_req.FailedSmartServerResponse(('BranchReference',))
225
self.assertEqual(expected, request.execute('', 'False'))
228
class TestSmartServerRequestCreateRepository(tests.TestCaseWithMemoryTransport):
235
expected = smart_req.FailedSmartServerResponse((b'BranchReference',))
236
self.assertEqual(expected, request.execute(b'', b'False'))
239
class TestSmartServerBzrDirRequestCheckoutMetaDir(
240
tests.TestCaseWithMemoryTransport):
241
"""Tests for BzrDir.checkout_metadir."""
243
def test_checkout_metadir(self):
244
backing = self.get_transport()
245
request = smart_dir.SmartServerBzrDirRequestCheckoutMetaDir(
247
self.make_branch('.', format='2a')
248
response = request.execute(b'')
250
smart_req.SmartServerResponse(
251
(b'Bazaar-NG meta directory, format 1\n',
252
b'Bazaar repository format 2a (needs bzr 1.16 or later)\n',
253
b'Bazaar Branch Format 7 (needs bzr 1.6)\n')),
257
class TestSmartServerBzrDirRequestDestroyBranch(
258
tests.TestCaseWithMemoryTransport):
259
"""Tests for BzrDir.destroy_branch."""
261
def test_destroy_branch_default(self):
262
"""The default branch can be removed."""
263
backing = self.get_transport()
264
self.make_branch('.')
265
request_class = smart_dir.SmartServerBzrDirRequestDestroyBranch
266
request = request_class(backing)
267
expected = smart_req.SuccessfulSmartServerResponse((b'ok',))
268
self.assertEqual(expected, request.execute(b'', None))
270
def test_destroy_branch_named(self):
271
"""A named branch can be removed."""
272
backing = self.get_transport()
273
dir = self.make_repository('.', format="development-colo").controldir
274
dir.create_branch(name="branchname")
275
request_class = smart_dir.SmartServerBzrDirRequestDestroyBranch
276
request = request_class(backing)
277
expected = smart_req.SuccessfulSmartServerResponse((b'ok',))
278
self.assertEqual(expected, request.execute(b'', b"branchname"))
280
def test_destroy_branch_missing(self):
281
"""An error is raised if the branch didn't exist."""
282
backing = self.get_transport()
283
self.make_controldir('.', format="development-colo")
284
request_class = smart_dir.SmartServerBzrDirRequestDestroyBranch
285
request = request_class(backing)
286
expected = smart_req.FailedSmartServerResponse((b'nobranch',), None)
287
self.assertEqual(expected, request.execute(b'', b"branchname"))
290
class TestSmartServerBzrDirRequestHasWorkingTree(
291
tests.TestCaseWithTransport):
292
"""Tests for BzrDir.has_workingtree."""
294
def test_has_workingtree_yes(self):
295
"""A working tree is present."""
296
backing = self.get_transport()
297
self.make_branch_and_tree('.')
298
request_class = smart_dir.SmartServerBzrDirRequestHasWorkingTree
299
request = request_class(backing)
300
expected = smart_req.SuccessfulSmartServerResponse((b'yes',))
301
self.assertEqual(expected, request.execute(b''))
303
def test_has_workingtree_no(self):
304
"""A working tree is missing."""
305
backing = self.get_transport()
306
self.make_controldir('.')
307
request_class = smart_dir.SmartServerBzrDirRequestHasWorkingTree
308
request = request_class(backing)
309
expected = smart_req.SuccessfulSmartServerResponse((b'no',))
310
self.assertEqual(expected, request.execute(b''))
313
class TestSmartServerBzrDirRequestDestroyRepository(
314
tests.TestCaseWithMemoryTransport):
315
"""Tests for BzrDir.destroy_repository."""
317
def test_destroy_repository_default(self):
318
"""The repository can be removed."""
319
backing = self.get_transport()
320
self.make_repository('.')
321
request_class = smart_dir.SmartServerBzrDirRequestDestroyRepository
322
request = request_class(backing)
323
expected = smart_req.SuccessfulSmartServerResponse((b'ok',))
324
self.assertEqual(expected, request.execute(b''))
326
def test_destroy_repository_missing(self):
327
"""An error is raised if the repository didn't exist."""
328
backing = self.get_transport()
329
self.make_controldir('.')
330
request_class = smart_dir.SmartServerBzrDirRequestDestroyRepository
331
request = request_class(backing)
332
expected = smart_req.FailedSmartServerResponse(
333
(b'norepository',), None)
334
self.assertEqual(expected, request.execute(b''))
337
class TestSmartServerRequestCreateRepository(
338
tests.TestCaseWithMemoryTransport):
229
339
"""Tests for BzrDir.create_repository."""
231
341
def test_makes_repository(self):
232
342
"""When there is a bzrdir present, the call succeeds."""
233
343
backing = self.get_transport()
234
self.make_bzrdir('.')
344
self.make_controldir('.')
235
345
request_class = smart_dir.SmartServerRequestCreateRepository
236
346
request = request_class(backing)
237
reference_bzrdir_format = bzrdir.format_registry.get('pack-0.92')()
347
reference_bzrdir_format = controldir.format_registry.get('pack-0.92')()
238
348
reference_format = reference_bzrdir_format.repository_format
239
349
network_name = reference_format.network_name()
240
350
expected = smart_req.SuccessfulSmartServerResponse(
241
('ok', 'no', 'no', 'no', network_name))
242
self.assertEqual(expected, request.execute('', network_name, 'True'))
351
(b'ok', b'no', b'no', b'no', network_name))
352
self.assertEqual(expected, request.execute(b'', network_name, b'True'))
245
355
class TestSmartServerRequestFindRepository(tests.TestCaseWithMemoryTransport):
246
356
"""Tests for BzrDir.find_repository."""
248
358
def test_no_repository(self):
249
"""When there is no repository to be found, ('norepository', ) is returned."""
359
"""If no repository is found, ('norepository', ) is returned."""
250
360
backing = self.get_transport()
251
361
request = self._request_class(backing)
252
self.make_bzrdir('.')
253
self.assertEqual(smart_req.SmartServerResponse(('norepository', )),
362
self.make_controldir('.')
363
self.assertEqual(smart_req.SmartServerResponse((b'norepository', )),
364
request.execute(b''))
256
366
def test_nonshared_repository(self):
257
367
# nonshared repositorys only allow 'find' to return a handle when the
273
383
repo = self.make_repository('.', shared=shared, format=format)
274
384
if repo.supports_rich_root():
278
388
if repo._format.supports_tree_reference:
282
392
if repo._format.supports_external_lookups:
286
396
if (smart_dir.SmartServerRequestFindRepositoryV3 ==
287
self._request_class):
397
self._request_class):
288
398
return smart_req.SuccessfulSmartServerResponse(
289
('ok', '', rich_root, subtrees, external,
399
(b'ok', b'', rich_root, subtrees, external,
290
400
repo._format.network_name()))
291
401
elif (smart_dir.SmartServerRequestFindRepositoryV2 ==
292
self._request_class):
402
self._request_class):
293
403
# All tests so far are on formats, and for non-external
295
405
return smart_req.SuccessfulSmartServerResponse(
296
('ok', '', rich_root, subtrees, external))
406
(b'ok', b'', rich_root, subtrees, external))
298
408
return smart_req.SuccessfulSmartServerResponse(
299
('ok', '', rich_root, subtrees))
409
(b'ok', b'', rich_root, subtrees))
301
411
def test_shared_repository(self):
302
"""When there is a shared repository, we get 'ok', 'relpath-to-repo'."""
412
"""for a shared repository, we get 'ok', 'relpath-to-repo'."""
303
413
backing = self.get_transport()
304
414
request = self._request_class(backing)
305
415
result = self._make_repository_and_result(shared=True)
306
self.assertEqual(result, request.execute(''))
307
self.make_bzrdir('subdir')
416
self.assertEqual(result, request.execute(b''))
417
self.make_controldir('subdir')
308
418
result2 = smart_req.SmartServerResponse(
309
result.args[0:1] + ('..', ) + result.args[2:])
419
result.args[0:1] + (b'..', ) + result.args[2:])
310
420
self.assertEqual(result2,
311
request.execute('subdir'))
312
self.make_bzrdir('subdir/deeper')
421
request.execute(b'subdir'))
422
self.make_controldir('subdir/deeper')
313
423
result3 = smart_req.SmartServerResponse(
314
result.args[0:1] + ('../..', ) + result.args[2:])
424
result.args[0:1] + (b'../..', ) + result.args[2:])
315
425
self.assertEqual(result3,
316
request.execute('subdir/deeper'))
426
request.execute(b'subdir/deeper'))
318
428
def test_rich_root_and_subtree_encoding(self):
319
429
"""Test for the format attributes for rich root and subtree support."""
320
430
backing = self.get_transport()
321
431
request = self._request_class(backing)
322
432
result = self._make_repository_and_result(
323
format='dirstate-with-subtree')
433
format='development-subtree')
324
434
# check the test will be valid
325
self.assertEqual('yes', result.args[2])
326
self.assertEqual('yes', result.args[3])
327
self.assertEqual(result, request.execute(''))
435
self.assertEqual(b'yes', result.args[2])
436
self.assertEqual(b'yes', result.args[3])
437
self.assertEqual(result, request.execute(b''))
329
439
def test_supports_external_lookups_no_v2(self):
330
440
"""Test for the supports_external_lookups attribute."""
331
441
backing = self.get_transport()
332
442
request = self._request_class(backing)
333
443
result = self._make_repository_and_result(
334
format='dirstate-with-subtree')
444
format='development-subtree')
335
445
# check the test will be valid
336
self.assertEqual('no', result.args[4])
337
self.assertEqual(result, request.execute(''))
446
self.assertEqual(b'yes', result.args[4])
447
self.assertEqual(result, request.execute(b''))
340
450
class TestSmartServerBzrDirRequestGetConfigFile(
341
tests.TestCaseWithMemoryTransport):
451
tests.TestCaseWithMemoryTransport):
342
452
"""Tests for BzrDir.get_config_file."""
344
454
def test_present(self):
345
455
backing = self.get_transport()
346
dir = self.make_bzrdir('.')
456
dir = self.make_controldir('.')
347
457
dir.get_config().set_default_stack_on("/")
348
458
local_result = dir._get_config()._get_config_file().read()
349
459
request_class = smart_dir.SmartServerBzrDirRequestConfigFile
350
460
request = request_class(backing)
351
461
expected = smart_req.SuccessfulSmartServerResponse((), local_result)
352
self.assertEqual(expected, request.execute(''))
462
self.assertEqual(expected, request.execute(b''))
354
464
def test_missing(self):
355
465
backing = self.get_transport()
356
dir = self.make_bzrdir('.')
466
self.make_controldir('.')
357
467
request_class = smart_dir.SmartServerBzrDirRequestConfigFile
358
468
request = request_class(backing)
359
expected = smart_req.SuccessfulSmartServerResponse((), '')
360
self.assertEqual(expected, request.execute(''))
363
class TestSmartServerRequestInitializeBzrDir(tests.TestCaseWithMemoryTransport):
469
expected = smart_req.SuccessfulSmartServerResponse((), b'')
470
self.assertEqual(expected, request.execute(b''))
473
class TestSmartServerBzrDirRequestGetBranches(
474
tests.TestCaseWithMemoryTransport):
475
"""Tests for BzrDir.get_branches."""
477
def test_simple(self):
478
backing = self.get_transport()
479
branch = self.make_branch('.')
480
request_class = smart_dir.SmartServerBzrDirRequestGetBranches
481
request = request_class(backing)
482
local_result = bencode.bencode(
483
{b"": (b"branch", branch._format.network_name())})
484
expected = smart_req.SuccessfulSmartServerResponse(
485
(b"success", ), local_result)
486
self.assertEqual(expected, request.execute(b''))
488
def test_empty(self):
489
backing = self.get_transport()
490
self.make_controldir('.')
491
request_class = smart_dir.SmartServerBzrDirRequestGetBranches
492
request = request_class(backing)
493
local_result = bencode.bencode({})
494
expected = smart_req.SuccessfulSmartServerResponse(
495
(b'success',), local_result)
496
self.assertEqual(expected, request.execute(b''))
499
class TestSmartServerRequestInitializeBzrDir(
500
tests.TestCaseWithMemoryTransport):
365
502
def test_empty_dir(self):
366
503
"""Initializing an empty dir should succeed and do it."""
367
504
backing = self.get_transport()
368
505
request = smart_dir.SmartServerRequestInitializeBzrDir(backing)
369
self.assertEqual(smart_req.SmartServerResponse(('ok', )),
371
made_dir = bzrdir.BzrDir.open_from_transport(backing)
506
self.assertEqual(smart_req.SmartServerResponse((b'ok', )),
507
request.execute(b''))
508
made_dir = controldir.ControlDir.open_from_transport(backing)
372
509
# no branch, tree or repository is expected with the current
373
510
# default formart.
374
511
self.assertRaises(errors.NoWorkingTree, made_dir.open_workingtree)
698
837
"""When there is a bzrdir and no branch, NotBranchError is raised."""
699
838
backing = self.get_transport()
700
839
request = smart_branch.SmartServerBranchRequest(backing)
701
self.make_bzrdir('.')
840
self.make_controldir('.')
702
841
self.assertRaises(errors.NotBranchError,
842
request.execute, b'')
705
844
def test_branch_reference(self):
706
845
"""When there is a branch reference, NotBranchError is raised."""
707
846
backing = self.get_transport()
708
847
request = smart_branch.SmartServerBranchRequest(backing)
709
848
branch = self.make_branch('branch')
710
checkout = branch.create_checkout('reference',lightweight=True)
849
branch.create_checkout('reference', lightweight=True)
711
850
self.assertRaises(errors.NotBranchError,
712
request.execute, 'checkout')
851
request.execute, b'checkout')
715
854
class TestSmartServerBranchRequestLastRevisionInfo(
716
tests.TestCaseWithMemoryTransport):
855
tests.TestCaseWithMemoryTransport):
718
857
def test_empty(self):
719
"""For an empty branch, the result is ('ok', '0', 'null:')."""
858
"""For an empty branch, the result is ('ok', '0', b'null:')."""
720
859
backing = self.get_transport()
721
request = smart_branch.SmartServerBranchRequestLastRevisionInfo(backing)
860
request = smart_branch.SmartServerBranchRequestLastRevisionInfo(
722
862
self.make_branch('.')
723
self.assertEqual(smart_req.SmartServerResponse(('ok', '0', 'null:')),
864
smart_req.SmartServerResponse((b'ok', b'0', b'null:')),
865
request.execute(b''))
867
def test_ghost(self):
868
"""For an empty branch, the result is ('ok', '0', b'null:')."""
869
backing = self.get_transport()
870
request = smart_branch.SmartServerBranchRequestLastRevisionInfo(
872
branch = self.make_branch('.')
874
def last_revision_info():
875
raise errors.GhostRevisionsHaveNoRevno(b'revid1', b'revid2')
876
self.overrideAttr(branch, 'last_revision_info', last_revision_info)
877
self.assertRaises(errors.GhostRevisionsHaveNoRevno,
878
request.do_with_branch, branch)
726
880
def test_not_empty(self):
727
881
"""For a non-empty branch, the result is ('ok', 'revno', 'revid')."""
728
882
backing = self.get_transport()
729
request = smart_branch.SmartServerBranchRequestLastRevisionInfo(backing)
883
request = smart_branch.SmartServerBranchRequestLastRevisionInfo(
730
885
tree = self.make_branch_and_memory_tree('.')
731
886
tree.lock_write()
733
888
rev_id_utf8 = u'\xc8'.encode('utf-8')
889
tree.commit('1st commit')
890
tree.commit('2nd commit', rev_id=rev_id_utf8)
893
smart_req.SmartServerResponse((b'ok', b'2', rev_id_utf8)),
894
request.execute(b''))
897
class TestSmartServerBranchRequestRevisionIdToRevno(
898
tests.TestCaseWithMemoryTransport):
901
backing = self.get_transport()
902
request = smart_branch.SmartServerBranchRequestRevisionIdToRevno(
904
self.make_branch('.')
905
self.assertEqual(smart_req.SmartServerResponse((b'ok', b'0')),
906
request.execute(b'', b'null:'))
908
def test_simple(self):
909
backing = self.get_transport()
910
request = smart_branch.SmartServerBranchRequestRevisionIdToRevno(
912
tree = self.make_branch_and_memory_tree('.')
734
915
r1 = tree.commit('1st commit')
735
r2 = tree.commit('2nd commit', rev_id=rev_id_utf8)
737
917
self.assertEqual(
738
smart_req.SmartServerResponse(('ok', '2', rev_id_utf8)),
918
smart_req.SmartServerResponse((b'ok', b'1')),
919
request.execute(b'', r1))
921
def test_not_found(self):
922
backing = self.get_transport()
923
request = smart_branch.SmartServerBranchRequestRevisionIdToRevno(
925
self.make_branch('.')
927
smart_req.FailedSmartServerResponse(
928
(b'NoSuchRevision', b'idontexist')),
929
request.execute(b'', b'idontexist'))
742
932
class TestSmartServerBranchRequestGetConfigFile(
743
tests.TestCaseWithMemoryTransport):
933
tests.TestCaseWithMemoryTransport):
745
935
def test_default(self):
746
936
"""With no file, we get empty content."""
747
937
backing = self.get_transport()
748
938
request = smart_branch.SmartServerBranchGetConfigFile(backing)
749
branch = self.make_branch('.')
939
self.make_branch('.')
750
940
# there should be no file by default
752
self.assertEqual(smart_req.SmartServerResponse(('ok', ), content),
942
self.assertEqual(smart_req.SmartServerResponse((b'ok', ), content),
943
request.execute(b''))
755
945
def test_with_content(self):
756
946
# SmartServerBranchGetConfigFile should return the content from
757
# branch.control_files.get('branch.conf') for now - in the future it may
758
# perform more complex processing.
947
# branch.control_files.get('branch.conf') for now - in the future it
948
# may perform more complex processing.
759
949
backing = self.get_transport()
760
950
request = smart_branch.SmartServerBranchGetConfigFile(backing)
761
951
branch = self.make_branch('.')
762
branch._transport.put_bytes('branch.conf', 'foo bar baz')
763
self.assertEqual(smart_req.SmartServerResponse(('ok', ), 'foo bar baz'),
952
branch._transport.put_bytes('branch.conf', b'foo bar baz')
954
smart_req.SmartServerResponse((b'ok', ), b'foo bar baz'),
955
request.execute(b''))
767
958
class TestLockedBranch(tests.TestCaseWithMemoryTransport):
769
960
def get_lock_tokens(self, branch):
770
branch_token = branch.lock_write().branch_token
961
branch_token = branch.lock_write().token
771
962
repo_token = branch.repository.lock_write().repository_token
772
963
branch.repository.unlock()
773
964
return branch_token, repo_token
967
class TestSmartServerBranchRequestPutConfigFile(TestLockedBranch):
969
def test_with_content(self):
970
backing = self.get_transport()
971
request = smart_branch.SmartServerBranchPutConfigFile(backing)
972
branch = self.make_branch('.')
973
branch_token, repo_token = self.get_lock_tokens(branch)
974
self.assertIs(None, request.execute(b'', branch_token, repo_token))
976
smart_req.SmartServerResponse((b'ok', )),
977
request.do_body(b'foo bar baz'))
979
branch.control_transport.get_bytes('branch.conf'),
776
984
class TestSmartServerBranchRequestSetConfigOption(TestLockedBranch):
778
986
def test_value_name(self):
779
987
branch = self.make_branch('.')
780
988
request = smart_branch.SmartServerBranchRequestSetConfigOption(
781
branch.bzrdir.root_transport)
989
branch.controldir.root_transport)
782
990
branch_token, repo_token = self.get_lock_tokens(branch)
783
991
config = branch._get_config()
784
result = request.execute('', branch_token, repo_token, 'bar', 'foo',
992
result = request.execute(b'', branch_token, repo_token, b'bar', b'foo',
786
994
self.assertEqual(smart_req.SuccessfulSmartServerResponse(()), result)
787
995
self.assertEqual('bar', config.get_option('foo'))
1096
1366
self.get_transport())
1097
1367
branch_token, repo_token = self.get_lock_tokens(branch)
1099
response = request.execute('base', branch_token, repo_token,
1369
response = request.execute(b'base', branch_token, repo_token,
1102
1372
branch.unlock()
1103
1373
self.assertEqual(smart_req.SuccessfulSmartServerResponse(()), response)
1104
self.assertEqual('http://bar/', branch.get_parent())
1374
refreshed = _mod_branch.Branch.open(branch.base)
1375
self.assertEqual('http://bar/', refreshed.get_parent())
1107
1378
class TestSmartServerBranchRequestGetTagsBytes(
1108
tests.TestCaseWithMemoryTransport):
1379
tests.TestCaseWithMemoryTransport):
1109
1380
# Only called when the branch format and tags match [yay factory
1110
1381
# methods] so only need to test straight forward cases.
1112
1383
def test_get_bytes(self):
1113
base_branch = self.make_branch('base')
1384
self.make_branch('base')
1114
1385
request = smart_branch.SmartServerBranchGetTagsBytes(
1115
1386
self.get_transport())
1116
response = request.execute('base')
1118
smart_req.SuccessfulSmartServerResponse(('',)), response)
1121
class TestSmartServerBranchRequestGetStackedOnURL(tests.TestCaseWithMemoryTransport):
1387
response = request.execute(b'base')
1389
smart_req.SuccessfulSmartServerResponse((b'',)), response)
1392
class TestSmartServerBranchRequestGetStackedOnURL(
1393
tests.TestCaseWithMemoryTransport):
1123
1395
def test_get_stacked_on_url(self):
1124
base_branch = self.make_branch('base', format='1.6')
1396
self.make_branch('base', format='1.6')
1125
1397
stacked_branch = self.make_branch('stacked', format='1.6')
1126
1398
# typically should be relative
1127
1399
stacked_branch.set_stacked_on_url('../base')
1128
1400
request = smart_branch.SmartServerBranchRequestGetStackedOnURL(
1129
1401
self.get_transport())
1130
response = request.execute('stacked')
1132
smart_req.SmartServerResponse(('ok', '../base')),
1402
response = request.execute(b'stacked')
1404
smart_req.SmartServerResponse((b'ok', b'../base')),
1136
1408
class TestSmartServerBranchRequestLockWrite(TestLockedBranch):
1139
tests.TestCaseWithMemoryTransport.setUp(self)
1141
1410
def test_lock_write_on_unlocked_branch(self):
1142
1411
backing = self.get_transport()
1143
1412
request = smart_branch.SmartServerBranchRequestLockWrite(backing)
1144
1413
branch = self.make_branch('.', format='knit')
1145
1414
repository = branch.repository
1146
response = request.execute('')
1415
response = request.execute(b'')
1147
1416
branch_nonce = branch.control_files._lock.peek().get('nonce')
1148
1417
repository_nonce = repository.control_files._lock.peek().get('nonce')
1149
1418
self.assertEqual(smart_req.SmartServerResponse(
1150
('ok', branch_nonce, repository_nonce)),
1419
(b'ok', branch_nonce, repository_nonce)),
1152
1421
# The branch (and associated repository) is now locked. Verify that
1153
1422
# with a new branch object.
1154
new_branch = repository.bzrdir.open_branch()
1423
new_branch = repository.controldir.open_branch()
1155
1424
self.assertRaises(errors.LockContention, new_branch.lock_write)
1157
1426
request = smart_branch.SmartServerBranchRequestUnlock(backing)
1158
response = request.execute('', branch_nonce, repository_nonce)
1427
response = request.execute(b'', branch_nonce, repository_nonce)
1160
1429
def test_lock_write_on_locked_branch(self):
1161
1430
backing = self.get_transport()
1162
1431
request = smart_branch.SmartServerBranchRequestLockWrite(backing)
1163
1432
branch = self.make_branch('.')
1164
branch_token = branch.lock_write().branch_token
1433
branch_token = branch.lock_write().token
1165
1434
branch.leave_lock_in_place()
1166
1435
branch.unlock()
1167
response = request.execute('')
1436
response = request.execute(b'')
1168
1437
self.assertEqual(
1169
smart_req.SmartServerResponse(('LockContention',)), response)
1438
smart_req.SmartServerResponse((b'LockContention',)), response)
1171
1440
branch.lock_write(branch_token)
1172
1441
branch.dont_leave_lock_in_place()
1493
1924
tree.lock_write()
1495
1926
rev_id_utf8 = u'\xc8abc'.encode('utf-8')
1496
r1 = tree.commit('a commit', rev_id=rev_id_utf8)
1927
tree.commit('a commit', rev_id=rev_id_utf8)
1498
1929
self.assertTrue(tree.branch.repository.has_revision(rev_id_utf8))
1499
self.assertEqual(smart_req.SmartServerResponse(('yes', )),
1500
request.execute('', rev_id_utf8))
1930
self.assertEqual(smart_req.SmartServerResponse((b'yes', )),
1931
request.execute(b'', rev_id_utf8))
1934
class TestSmartServerRepositoryIterFilesBytes(tests.TestCaseWithTransport):
1936
def test_single(self):
1937
backing = self.get_transport()
1938
request = smart_repo.SmartServerRepositoryIterFilesBytes(backing)
1939
t = self.make_branch_and_tree('.')
1940
self.addCleanup(t.lock_write().unlock)
1941
self.build_tree_contents([("file", b"somecontents")])
1942
t.add(["file"], [b"thefileid"])
1943
t.commit(rev_id=b'somerev', message="add file")
1944
self.assertIs(None, request.execute(b''))
1945
response = request.do_body(b"thefileid\0somerev\n")
1946
self.assertTrue(response.is_successful())
1947
self.assertEqual(response.args, (b"ok", ))
1948
self.assertEqual(b"".join(response.body_stream),
1949
b"ok\x000\n" + zlib.compress(b"somecontents"))
1951
def test_missing(self):
1952
backing = self.get_transport()
1953
request = smart_repo.SmartServerRepositoryIterFilesBytes(backing)
1954
t = self.make_branch_and_tree('.')
1955
self.addCleanup(t.lock_write().unlock)
1956
self.assertIs(None, request.execute(b''))
1957
response = request.do_body(b"thefileid\0revision\n")
1958
self.assertTrue(response.is_successful())
1959
self.assertEqual(response.args, (b"ok", ))
1960
self.assertEqual(b"".join(response.body_stream),
1961
b"absent\x00thefileid\x00revision\x000\n")
1964
class TestSmartServerRequestHasSignatureForRevisionId(
1965
tests.TestCaseWithMemoryTransport):
1967
def test_missing_revision(self):
1968
"""For a missing revision, NoSuchRevision is returned."""
1969
backing = self.get_transport()
1970
request = smart_repo.SmartServerRequestHasSignatureForRevisionId(
1972
self.make_repository('.')
1974
smart_req.FailedSmartServerResponse(
1975
(b'nosuchrevision', b'revid'), None),
1976
request.execute(b'', b'revid'))
1978
def test_missing_signature(self):
1979
"""For a missing signature, ('no', ) is returned."""
1980
backing = self.get_transport()
1981
request = smart_repo.SmartServerRequestHasSignatureForRevisionId(
1983
tree = self.make_branch_and_memory_tree('.')
1986
tree.commit('a commit', rev_id=b'A')
1988
self.assertTrue(tree.branch.repository.has_revision(b'A'))
1989
self.assertEqual(smart_req.SmartServerResponse((b'no', )),
1990
request.execute(b'', b'A'))
1992
def test_present_signature(self):
1993
"""For a present signature, ('yes', ) is returned."""
1994
backing = self.get_transport()
1995
request = smart_repo.SmartServerRequestHasSignatureForRevisionId(
1997
strategy = gpg.LoopbackGPGStrategy(None)
1998
tree = self.make_branch_and_memory_tree('.')
2001
tree.commit('a commit', rev_id=b'A')
2002
tree.branch.repository.start_write_group()
2003
tree.branch.repository.sign_revision(b'A', strategy)
2004
tree.branch.repository.commit_write_group()
2006
self.assertTrue(tree.branch.repository.has_revision(b'A'))
2007
self.assertEqual(smart_req.SmartServerResponse((b'yes', )),
2008
request.execute(b'', b'A'))
1503
2011
class TestSmartServerRepositoryGatherStats(tests.TestCaseWithMemoryTransport):
1734
2341
repo.set_make_working_trees(False)
1735
2342
request_class = smart_repo.SmartServerRepositorySetMakeWorkingTrees
1736
2343
request = request_class(backing)
1737
self.assertEqual(smart_req.SuccessfulSmartServerResponse(('ok',)),
1738
request.execute('', 'True'))
1739
repo = repo.bzrdir.open_repository()
2344
self.assertEqual(smart_req.SuccessfulSmartServerResponse((b'ok',)),
2345
request.execute(b'', b'True'))
2346
repo = repo.controldir.open_repository()
1740
2347
self.assertTrue(repo.make_working_trees())
2350
class TestSmartServerRepositoryGetSerializerFormat(
2351
tests.TestCaseWithMemoryTransport):
2353
def test_get_serializer_format(self):
2354
backing = self.get_transport()
2355
repo = self.make_repository('.', format='2a')
2356
request_class = smart_repo.SmartServerRepositoryGetSerializerFormat
2357
request = request_class(backing)
2359
smart_req.SuccessfulSmartServerResponse((b'ok', b'10')),
2360
request.execute(b''))
2363
class TestSmartServerRepositoryWriteGroup(
2364
tests.TestCaseWithMemoryTransport):
2366
def test_start_write_group(self):
2367
backing = self.get_transport()
2368
repo = self.make_repository('.')
2369
lock_token = repo.lock_write().repository_token
2370
self.addCleanup(repo.unlock)
2371
request_class = smart_repo.SmartServerRepositoryStartWriteGroup
2372
request = request_class(backing)
2373
self.assertEqual(smart_req.SuccessfulSmartServerResponse((b'ok', [])),
2374
request.execute(b'', lock_token))
2376
def test_start_write_group_unsuspendable(self):
2377
backing = self.get_transport()
2378
repo = self.make_repository('.', format='knit')
2379
lock_token = repo.lock_write().repository_token
2380
self.addCleanup(repo.unlock)
2381
request_class = smart_repo.SmartServerRepositoryStartWriteGroup
2382
request = request_class(backing)
2384
smart_req.FailedSmartServerResponse((b'UnsuspendableWriteGroup',)),
2385
request.execute(b'', lock_token))
2387
def test_commit_write_group(self):
2388
backing = self.get_transport()
2389
repo = self.make_repository('.')
2390
lock_token = repo.lock_write().repository_token
2391
self.addCleanup(repo.unlock)
2392
repo.start_write_group()
2393
tokens = repo.suspend_write_group()
2394
request_class = smart_repo.SmartServerRepositoryCommitWriteGroup
2395
request = request_class(backing)
2396
self.assertEqual(smart_req.SuccessfulSmartServerResponse((b'ok',)),
2397
request.execute(b'', lock_token, tokens))
2399
def test_abort_write_group(self):
2400
backing = self.get_transport()
2401
repo = self.make_repository('.')
2402
lock_token = repo.lock_write().repository_token
2403
repo.start_write_group()
2404
tokens = repo.suspend_write_group()
2405
self.addCleanup(repo.unlock)
2406
request_class = smart_repo.SmartServerRepositoryAbortWriteGroup
2407
request = request_class(backing)
2408
self.assertEqual(smart_req.SuccessfulSmartServerResponse((b'ok',)),
2409
request.execute(b'', lock_token, tokens))
2411
def test_check_write_group(self):
2412
backing = self.get_transport()
2413
repo = self.make_repository('.')
2414
lock_token = repo.lock_write().repository_token
2415
repo.start_write_group()
2416
tokens = repo.suspend_write_group()
2417
self.addCleanup(repo.unlock)
2418
request_class = smart_repo.SmartServerRepositoryCheckWriteGroup
2419
request = request_class(backing)
2420
self.assertEqual(smart_req.SuccessfulSmartServerResponse((b'ok',)),
2421
request.execute(b'', lock_token, tokens))
2423
def test_check_write_group_invalid(self):
2424
backing = self.get_transport()
2425
repo = self.make_repository('.')
2426
lock_token = repo.lock_write().repository_token
2427
self.addCleanup(repo.unlock)
2428
request_class = smart_repo.SmartServerRepositoryCheckWriteGroup
2429
request = request_class(backing)
2430
self.assertEqual(smart_req.FailedSmartServerResponse(
2431
(b'UnresumableWriteGroup', [b'random'],
2432
b'Malformed write group token')),
2433
request.execute(b'', lock_token, [b"random"]))
1743
2436
class TestSmartServerPackRepositoryAutopack(tests.TestCaseWithTransport):
1745
2438
def make_repo_needing_autopacking(self, path='.'):
1811
2504
"""All registered request_handlers can be found."""
1812
2505
# If there's a typo in a register_lazy call, this loop will fail with
1813
2506
# an AttributeError.
1814
for key, item in smart_req.request_handlers.iteritems():
2507
for key in smart_req.request_handlers.keys():
2509
item = smart_req.request_handlers.get(key)
2510
except AttributeError as e:
2511
raise AttributeError('failed to get %s: %s' % (key, e))
1817
2513
def assertHandlerEqual(self, verb, handler):
1818
2514
self.assertEqual(smart_req.request_handlers.get(verb), handler)
1820
2516
def test_registered_methods(self):
1821
2517
"""Test that known methods are registered to the correct object."""
1822
self.assertHandlerEqual('Branch.get_config_file',
1823
smart_branch.SmartServerBranchGetConfigFile)
1824
self.assertHandlerEqual('Branch.get_parent',
1825
smart_branch.SmartServerBranchGetParent)
1826
self.assertHandlerEqual('Branch.get_tags_bytes',
1827
smart_branch.SmartServerBranchGetTagsBytes)
1828
self.assertHandlerEqual('Branch.lock_write',
1829
smart_branch.SmartServerBranchRequestLockWrite)
1830
self.assertHandlerEqual('Branch.last_revision_info',
1831
smart_branch.SmartServerBranchRequestLastRevisionInfo)
1832
self.assertHandlerEqual('Branch.revision_history',
1833
smart_branch.SmartServerRequestRevisionHistory)
1834
self.assertHandlerEqual('Branch.set_config_option',
1835
smart_branch.SmartServerBranchRequestSetConfigOption)
1836
self.assertHandlerEqual('Branch.set_last_revision',
1837
smart_branch.SmartServerBranchRequestSetLastRevision)
1838
self.assertHandlerEqual('Branch.set_last_revision_info',
1839
smart_branch.SmartServerBranchRequestSetLastRevisionInfo)
1840
self.assertHandlerEqual('Branch.set_last_revision_ex',
1841
smart_branch.SmartServerBranchRequestSetLastRevisionEx)
1842
self.assertHandlerEqual('Branch.set_parent_location',
1843
smart_branch.SmartServerBranchRequestSetParentLocation)
1844
self.assertHandlerEqual('Branch.unlock',
1845
smart_branch.SmartServerBranchRequestUnlock)
1846
self.assertHandlerEqual('BzrDir.find_repository',
1847
smart_dir.SmartServerRequestFindRepositoryV1)
1848
self.assertHandlerEqual('BzrDir.find_repositoryV2',
1849
smart_dir.SmartServerRequestFindRepositoryV2)
1850
self.assertHandlerEqual('BzrDirFormat.initialize',
1851
smart_dir.SmartServerRequestInitializeBzrDir)
1852
self.assertHandlerEqual('BzrDirFormat.initialize_ex_1.16',
1853
smart_dir.SmartServerRequestBzrDirInitializeEx)
1854
self.assertHandlerEqual('BzrDir.cloning_metadir',
1855
smart_dir.SmartServerBzrDirRequestCloningMetaDir)
1856
self.assertHandlerEqual('BzrDir.get_config_file',
1857
smart_dir.SmartServerBzrDirRequestConfigFile)
1858
self.assertHandlerEqual('BzrDir.open_branch',
1859
smart_dir.SmartServerRequestOpenBranch)
1860
self.assertHandlerEqual('BzrDir.open_branchV2',
1861
smart_dir.SmartServerRequestOpenBranchV2)
1862
self.assertHandlerEqual('BzrDir.open_branchV3',
1863
smart_dir.SmartServerRequestOpenBranchV3)
1864
self.assertHandlerEqual('PackRepository.autopack',
1865
smart_packrepo.SmartServerPackRepositoryAutopack)
1866
self.assertHandlerEqual('Repository.gather_stats',
1867
smart_repo.SmartServerRepositoryGatherStats)
1868
self.assertHandlerEqual('Repository.get_parent_map',
1869
smart_repo.SmartServerRepositoryGetParentMap)
1870
self.assertHandlerEqual('Repository.get_rev_id_for_revno',
1871
smart_repo.SmartServerRepositoryGetRevIdForRevno)
1872
self.assertHandlerEqual('Repository.get_revision_graph',
1873
smart_repo.SmartServerRepositoryGetRevisionGraph)
1874
self.assertHandlerEqual('Repository.get_stream',
1875
smart_repo.SmartServerRepositoryGetStream)
1876
self.assertHandlerEqual('Repository.has_revision',
1877
smart_repo.SmartServerRequestHasRevision)
1878
self.assertHandlerEqual('Repository.insert_stream',
1879
smart_repo.SmartServerRepositoryInsertStream)
1880
self.assertHandlerEqual('Repository.insert_stream_locked',
1881
smart_repo.SmartServerRepositoryInsertStreamLocked)
1882
self.assertHandlerEqual('Repository.is_shared',
1883
smart_repo.SmartServerRepositoryIsShared)
1884
self.assertHandlerEqual('Repository.lock_write',
1885
smart_repo.SmartServerRepositoryLockWrite)
1886
self.assertHandlerEqual('Repository.tarball',
1887
smart_repo.SmartServerRepositoryTarball)
1888
self.assertHandlerEqual('Repository.unlock',
1889
smart_repo.SmartServerRepositoryUnlock)
1890
self.assertHandlerEqual('Transport.is_readonly',
1891
smart_req.SmartServerIsReadonly)
2518
self.assertHandlerEqual(b'Branch.break_lock',
2519
smart_branch.SmartServerBranchBreakLock)
2520
self.assertHandlerEqual(b'Branch.get_config_file',
2521
smart_branch.SmartServerBranchGetConfigFile)
2522
self.assertHandlerEqual(b'Branch.put_config_file',
2523
smart_branch.SmartServerBranchPutConfigFile)
2524
self.assertHandlerEqual(b'Branch.get_parent',
2525
smart_branch.SmartServerBranchGetParent)
2526
self.assertHandlerEqual(b'Branch.get_physical_lock_status',
2527
smart_branch.SmartServerBranchRequestGetPhysicalLockStatus)
2528
self.assertHandlerEqual(b'Branch.get_tags_bytes',
2529
smart_branch.SmartServerBranchGetTagsBytes)
2530
self.assertHandlerEqual(b'Branch.lock_write',
2531
smart_branch.SmartServerBranchRequestLockWrite)
2532
self.assertHandlerEqual(b'Branch.last_revision_info',
2533
smart_branch.SmartServerBranchRequestLastRevisionInfo)
2534
self.assertHandlerEqual(b'Branch.revision_history',
2535
smart_branch.SmartServerRequestRevisionHistory)
2536
self.assertHandlerEqual(b'Branch.revision_id_to_revno',
2537
smart_branch.SmartServerBranchRequestRevisionIdToRevno)
2538
self.assertHandlerEqual(b'Branch.set_config_option',
2539
smart_branch.SmartServerBranchRequestSetConfigOption)
2540
self.assertHandlerEqual(b'Branch.set_last_revision',
2541
smart_branch.SmartServerBranchRequestSetLastRevision)
2542
self.assertHandlerEqual(b'Branch.set_last_revision_info',
2543
smart_branch.SmartServerBranchRequestSetLastRevisionInfo)
2544
self.assertHandlerEqual(b'Branch.set_last_revision_ex',
2545
smart_branch.SmartServerBranchRequestSetLastRevisionEx)
2546
self.assertHandlerEqual(b'Branch.set_parent_location',
2547
smart_branch.SmartServerBranchRequestSetParentLocation)
2548
self.assertHandlerEqual(b'Branch.unlock',
2549
smart_branch.SmartServerBranchRequestUnlock)
2550
self.assertHandlerEqual(b'BzrDir.destroy_branch',
2551
smart_dir.SmartServerBzrDirRequestDestroyBranch)
2552
self.assertHandlerEqual(b'BzrDir.find_repository',
2553
smart_dir.SmartServerRequestFindRepositoryV1)
2554
self.assertHandlerEqual(b'BzrDir.find_repositoryV2',
2555
smart_dir.SmartServerRequestFindRepositoryV2)
2556
self.assertHandlerEqual(b'BzrDirFormat.initialize',
2557
smart_dir.SmartServerRequestInitializeBzrDir)
2558
self.assertHandlerEqual(b'BzrDirFormat.initialize_ex_1.16',
2559
smart_dir.SmartServerRequestBzrDirInitializeEx)
2560
self.assertHandlerEqual(b'BzrDir.checkout_metadir',
2561
smart_dir.SmartServerBzrDirRequestCheckoutMetaDir)
2562
self.assertHandlerEqual(b'BzrDir.cloning_metadir',
2563
smart_dir.SmartServerBzrDirRequestCloningMetaDir)
2564
self.assertHandlerEqual(b'BzrDir.get_branches',
2565
smart_dir.SmartServerBzrDirRequestGetBranches)
2566
self.assertHandlerEqual(b'BzrDir.get_config_file',
2567
smart_dir.SmartServerBzrDirRequestConfigFile)
2568
self.assertHandlerEqual(b'BzrDir.open_branch',
2569
smart_dir.SmartServerRequestOpenBranch)
2570
self.assertHandlerEqual(b'BzrDir.open_branchV2',
2571
smart_dir.SmartServerRequestOpenBranchV2)
2572
self.assertHandlerEqual(b'BzrDir.open_branchV3',
2573
smart_dir.SmartServerRequestOpenBranchV3)
2574
self.assertHandlerEqual(b'PackRepository.autopack',
2575
smart_packrepo.SmartServerPackRepositoryAutopack)
2576
self.assertHandlerEqual(b'Repository.add_signature_text',
2577
smart_repo.SmartServerRepositoryAddSignatureText)
2578
self.assertHandlerEqual(b'Repository.all_revision_ids',
2579
smart_repo.SmartServerRepositoryAllRevisionIds)
2580
self.assertHandlerEqual(b'Repository.break_lock',
2581
smart_repo.SmartServerRepositoryBreakLock)
2582
self.assertHandlerEqual(b'Repository.gather_stats',
2583
smart_repo.SmartServerRepositoryGatherStats)
2584
self.assertHandlerEqual(b'Repository.get_parent_map',
2585
smart_repo.SmartServerRepositoryGetParentMap)
2586
self.assertHandlerEqual(b'Repository.get_physical_lock_status',
2587
smart_repo.SmartServerRepositoryGetPhysicalLockStatus)
2588
self.assertHandlerEqual(b'Repository.get_rev_id_for_revno',
2589
smart_repo.SmartServerRepositoryGetRevIdForRevno)
2590
self.assertHandlerEqual(b'Repository.get_revision_graph',
2591
smart_repo.SmartServerRepositoryGetRevisionGraph)
2592
self.assertHandlerEqual(b'Repository.get_revision_signature_text',
2593
smart_repo.SmartServerRepositoryGetRevisionSignatureText)
2594
self.assertHandlerEqual(b'Repository.get_stream',
2595
smart_repo.SmartServerRepositoryGetStream)
2596
self.assertHandlerEqual(b'Repository.get_stream_1.19',
2597
smart_repo.SmartServerRepositoryGetStream_1_19)
2598
self.assertHandlerEqual(b'Repository.iter_revisions',
2599
smart_repo.SmartServerRepositoryIterRevisions)
2600
self.assertHandlerEqual(b'Repository.has_revision',
2601
smart_repo.SmartServerRequestHasRevision)
2602
self.assertHandlerEqual(b'Repository.insert_stream',
2603
smart_repo.SmartServerRepositoryInsertStream)
2604
self.assertHandlerEqual(b'Repository.insert_stream_locked',
2605
smart_repo.SmartServerRepositoryInsertStreamLocked)
2606
self.assertHandlerEqual(b'Repository.is_shared',
2607
smart_repo.SmartServerRepositoryIsShared)
2608
self.assertHandlerEqual(b'Repository.iter_files_bytes',
2609
smart_repo.SmartServerRepositoryIterFilesBytes)
2610
self.assertHandlerEqual(b'Repository.lock_write',
2611
smart_repo.SmartServerRepositoryLockWrite)
2612
self.assertHandlerEqual(b'Repository.make_working_trees',
2613
smart_repo.SmartServerRepositoryMakeWorkingTrees)
2614
self.assertHandlerEqual(b'Repository.pack',
2615
smart_repo.SmartServerRepositoryPack)
2616
self.assertHandlerEqual(b'Repository.reconcile',
2617
smart_repo.SmartServerRepositoryReconcile)
2618
self.assertHandlerEqual(b'Repository.tarball',
2619
smart_repo.SmartServerRepositoryTarball)
2620
self.assertHandlerEqual(b'Repository.unlock',
2621
smart_repo.SmartServerRepositoryUnlock)
2622
self.assertHandlerEqual(b'Repository.start_write_group',
2623
smart_repo.SmartServerRepositoryStartWriteGroup)
2624
self.assertHandlerEqual(b'Repository.check_write_group',
2625
smart_repo.SmartServerRepositoryCheckWriteGroup)
2626
self.assertHandlerEqual(b'Repository.commit_write_group',
2627
smart_repo.SmartServerRepositoryCommitWriteGroup)
2628
self.assertHandlerEqual(b'Repository.abort_write_group',
2629
smart_repo.SmartServerRepositoryAbortWriteGroup)
2630
self.assertHandlerEqual(b'VersionedFileRepository.get_serializer_format',
2631
smart_repo.SmartServerRepositoryGetSerializerFormat)
2632
self.assertHandlerEqual(b'VersionedFileRepository.get_inventories',
2633
smart_repo.SmartServerRepositoryGetInventories)
2634
self.assertHandlerEqual(b'Transport.is_readonly',
2635
smart_req.SmartServerIsReadonly)
2638
class SmartTCPServerHookTests(tests.TestCaseWithMemoryTransport):
2639
"""Tests for SmartTCPServer hooks."""
2642
super(SmartTCPServerHookTests, self).setUp()
2643
self.server = server.SmartTCPServer(self.get_transport())
2645
def test_run_server_started_hooks(self):
2646
"""Test the server started hooks get fired properly."""
2648
server.SmartTCPServer.hooks.install_named_hook('server_started',
2649
lambda backing_urls, url: started_calls.append(
2650
(backing_urls, url)),
2652
started_ex_calls = []
2653
server.SmartTCPServer.hooks.install_named_hook('server_started_ex',
2654
lambda backing_urls, url: started_ex_calls.append(
2655
(backing_urls, url)),
2657
self.server._sockname = ('example.com', 42)
2658
self.server.run_server_started_hooks()
2659
self.assertEqual(started_calls,
2660
[([self.get_transport().base], 'bzr://example.com:42/')])
2661
self.assertEqual(started_ex_calls,
2662
[([self.get_transport().base], self.server)])
2664
def test_run_server_started_hooks_ipv6(self):
2665
"""Test that socknames can contain 4-tuples."""
2666
self.server._sockname = ('::', 42, 0, 0)
2668
server.SmartTCPServer.hooks.install_named_hook('server_started',
2669
lambda backing_urls, url: started_calls.append(
2670
(backing_urls, url)),
2672
self.server.run_server_started_hooks()
2673
self.assertEqual(started_calls,
2674
[([self.get_transport().base], 'bzr://:::42/')])
2676
def test_run_server_stopped_hooks(self):
2677
"""Test the server stopped hooks."""
2678
self.server._sockname = ('example.com', 42)
2680
server.SmartTCPServer.hooks.install_named_hook('server_stopped',
2681
lambda backing_urls, url: stopped_calls.append(
2682
(backing_urls, url)),
2684
self.server.run_server_stopped_hooks()
2685
self.assertEqual(stopped_calls,
2686
[([self.get_transport().base], 'bzr://example.com:42/')])
2689
class TestSmartServerRepositoryPack(tests.TestCaseWithMemoryTransport):
2691
def test_pack(self):
2692
backing = self.get_transport()
2693
request = smart_repo.SmartServerRepositoryPack(backing)
2694
tree = self.make_branch_and_memory_tree('.')
2695
repo_token = tree.branch.repository.lock_write().repository_token
2697
self.assertIs(None, request.execute(b'', repo_token, False))
2700
smart_req.SuccessfulSmartServerResponse((b'ok', ), ),
2701
request.do_body(b''))
2704
class TestSmartServerRepositoryGetInventories(tests.TestCaseWithTransport):
2706
def _get_serialized_inventory_delta(self, repository, base_revid, revid):
2707
base_inv = repository.revision_tree(base_revid).root_inventory
2708
inv = repository.revision_tree(revid).root_inventory
2709
inv_delta = inv._make_delta(base_inv)
2710
serializer = inventory_delta.InventoryDeltaSerializer(True, False)
2711
return b"".join(serializer.delta_to_lines(base_revid, revid, inv_delta))
2713
def test_single(self):
2714
backing = self.get_transport()
2715
request = smart_repo.SmartServerRepositoryGetInventories(backing)
2716
t = self.make_branch_and_tree('.', format='2a')
2717
self.addCleanup(t.lock_write().unlock)
2718
self.build_tree_contents([("file", b"somecontents")])
2719
t.add(["file"], [b"thefileid"])
2720
t.commit(rev_id=b'somerev', message="add file")
2721
self.assertIs(None, request.execute(b'', b'unordered'))
2722
response = request.do_body(b"somerev\n")
2723
self.assertTrue(response.is_successful())
2724
self.assertEqual(response.args, (b"ok", ))
2725
stream = [('inventory-deltas', [
2726
versionedfile.FulltextContentFactory(b'somerev', None, None,
2727
self._get_serialized_inventory_delta(
2728
t.branch.repository, b'null:', b'somerev'))])]
2729
fmt = controldir.format_registry.get('2a')().repository_format
2731
b"".join(response.body_stream),
2732
b"".join(smart_repo._stream_to_byte_stream(stream, fmt)))
2734
def test_empty(self):
2735
backing = self.get_transport()
2736
request = smart_repo.SmartServerRepositoryGetInventories(backing)
2737
t = self.make_branch_and_tree('.', format='2a')
2738
self.addCleanup(t.lock_write().unlock)
2739
self.build_tree_contents([("file", b"somecontents")])
2740
t.add(["file"], [b"thefileid"])
2741
t.commit(rev_id=b'somerev', message="add file")
2742
self.assertIs(None, request.execute(b'', b'unordered'))
2743
response = request.do_body(b"")
2744
self.assertTrue(response.is_successful())
2745
self.assertEqual(response.args, (b"ok", ))
2746
self.assertEqual(b"".join(response.body_stream),
2747
b"Bazaar pack format 1 (introduced in 0.18)\nB54\n\nBazaar repository format 2a (needs bzr 1.16 or later)\nE")
2750
class TestSmartServerRepositoryGetStreamForMissingKeys(GetStreamTestBase):
2752
def test_missing(self):
2753
"""The search argument may be a 'ancestry-of' some heads'."""
2754
backing = self.get_transport()
2755
request = smart_repo.SmartServerRepositoryGetStreamForMissingKeys(
2757
repo, r1, r2 = self.make_two_commit_repo()
2758
request.execute(b'', repo._format.network_name())
2759
lines = b'inventories\t' + r1
2760
response = request.do_body(lines)
2761
self.assertEqual((b'ok',), response.args)
2762
stream_bytes = b''.join(response.body_stream)
2763
self.assertStartsWith(stream_bytes, b'Bazaar pack format 1')
2765
def test_unknown_format(self):
2766
"""The format may not be known by the remote server."""
2767
backing = self.get_transport()
2768
request = smart_repo.SmartServerRepositoryGetStreamForMissingKeys(
2770
repo, r1, r2 = self.make_two_commit_repo()
2771
request.execute(b'', b'yada yada yada')
2772
expected = smart_req.FailedSmartServerResponse(
2773
(b'UnknownFormat', b'repository', b'yada yada yada'))
2776
class TestSmartServerRepositoryRevisionArchive(tests.TestCaseWithTransport):
2778
backing = self.get_transport()
2779
request = smart_repo.SmartServerRepositoryRevisionArchive(backing)
2780
t = self.make_branch_and_tree('.')
2781
self.addCleanup(t.lock_write().unlock)
2782
self.build_tree_contents([("file", b"somecontents")])
2783
t.add(["file"], [b"thefileid"])
2784
t.commit(rev_id=b'somerev', message="add file")
2785
response = request.execute(b'', b"somerev", b"tar", b"foo.tar", b"foo")
2786
self.assertTrue(response.is_successful())
2787
self.assertEqual(response.args, (b"ok", ))
2788
b = BytesIO(b"".join(response.body_stream))
2789
with tarfile.open(mode='r', fileobj=b) as tf:
2790
self.assertEqual(['foo/file'], tf.getnames())
2793
class TestSmartServerRepositoryAnnotateFileRevision(tests.TestCaseWithTransport):
2796
backing = self.get_transport()
2797
request = smart_repo.SmartServerRepositoryAnnotateFileRevision(backing)
2798
t = self.make_branch_and_tree('.')
2799
self.addCleanup(t.lock_write().unlock)
2800
self.build_tree_contents([("file", b"somecontents\nmorecontents\n")])
2801
t.add(["file"], [b"thefileid"])
2802
t.commit(rev_id=b'somerev', message="add file")
2803
response = request.execute(b'', b"somerev", b"file")
2804
self.assertTrue(response.is_successful())
2805
self.assertEqual(response.args, (b"ok", ))
2807
[[b'somerev', b'somecontents\n'], [b'somerev', b'morecontents\n']],
2808
bencode.bdecode(response.body))