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''))
489
backing = self.get_transport()
490
dir = self.make_controldir('foo')
491
b = self.make_branch('bar')
492
dir.set_branch_reference(b)
493
request_class = smart_dir.SmartServerBzrDirRequestGetBranches
494
request = request_class(backing)
495
local_result = bencode.bencode(
496
{b"": (b"ref", b'../bar/')})
497
expected = smart_req.SuccessfulSmartServerResponse(
498
(b"success", ), local_result)
499
self.assertEqual(expected, request.execute(b'foo'))
501
def test_empty(self):
502
backing = self.get_transport()
503
self.make_controldir('.')
504
request_class = smart_dir.SmartServerBzrDirRequestGetBranches
505
request = request_class(backing)
506
local_result = bencode.bencode({})
507
expected = smart_req.SuccessfulSmartServerResponse(
508
(b'success',), local_result)
509
self.assertEqual(expected, request.execute(b''))
512
class TestSmartServerRequestInitializeBzrDir(
513
tests.TestCaseWithMemoryTransport):
365
515
def test_empty_dir(self):
366
516
"""Initializing an empty dir should succeed and do it."""
367
517
backing = self.get_transport()
368
518
request = smart_dir.SmartServerRequestInitializeBzrDir(backing)
369
self.assertEqual(smart_req.SmartServerResponse(('ok', )),
371
made_dir = bzrdir.BzrDir.open_from_transport(backing)
519
self.assertEqual(smart_req.SmartServerResponse((b'ok', )),
520
request.execute(b''))
521
made_dir = controldir.ControlDir.open_from_transport(backing)
372
522
# no branch, tree or repository is expected with the current
373
523
# default formart.
374
524
self.assertRaises(errors.NoWorkingTree, made_dir.open_workingtree)
698
850
"""When there is a bzrdir and no branch, NotBranchError is raised."""
699
851
backing = self.get_transport()
700
852
request = smart_branch.SmartServerBranchRequest(backing)
701
self.make_bzrdir('.')
853
self.make_controldir('.')
702
854
self.assertRaises(errors.NotBranchError,
855
request.execute, b'')
705
857
def test_branch_reference(self):
706
858
"""When there is a branch reference, NotBranchError is raised."""
707
859
backing = self.get_transport()
708
860
request = smart_branch.SmartServerBranchRequest(backing)
709
861
branch = self.make_branch('branch')
710
checkout = branch.create_checkout('reference',lightweight=True)
862
branch.create_checkout('reference', lightweight=True)
711
863
self.assertRaises(errors.NotBranchError,
712
request.execute, 'checkout')
864
request.execute, b'checkout')
715
867
class TestSmartServerBranchRequestLastRevisionInfo(
716
tests.TestCaseWithMemoryTransport):
868
tests.TestCaseWithMemoryTransport):
718
870
def test_empty(self):
719
"""For an empty branch, the result is ('ok', '0', 'null:')."""
871
"""For an empty branch, the result is ('ok', '0', b'null:')."""
720
872
backing = self.get_transport()
721
request = smart_branch.SmartServerBranchRequestLastRevisionInfo(backing)
873
request = smart_branch.SmartServerBranchRequestLastRevisionInfo(
722
875
self.make_branch('.')
723
self.assertEqual(smart_req.SmartServerResponse(('ok', '0', 'null:')),
877
smart_req.SmartServerResponse((b'ok', b'0', b'null:')),
878
request.execute(b''))
880
def test_ghost(self):
881
"""For an empty branch, the result is ('ok', '0', b'null:')."""
882
backing = self.get_transport()
883
request = smart_branch.SmartServerBranchRequestLastRevisionInfo(
885
branch = self.make_branch('.')
887
def last_revision_info():
888
raise errors.GhostRevisionsHaveNoRevno(b'revid1', b'revid2')
889
self.overrideAttr(branch, 'last_revision_info', last_revision_info)
890
self.assertRaises(errors.GhostRevisionsHaveNoRevno,
891
request.do_with_branch, branch)
726
893
def test_not_empty(self):
727
894
"""For a non-empty branch, the result is ('ok', 'revno', 'revid')."""
728
895
backing = self.get_transport()
729
request = smart_branch.SmartServerBranchRequestLastRevisionInfo(backing)
896
request = smart_branch.SmartServerBranchRequestLastRevisionInfo(
730
898
tree = self.make_branch_and_memory_tree('.')
731
899
tree.lock_write()
733
901
rev_id_utf8 = u'\xc8'.encode('utf-8')
902
tree.commit('1st commit')
903
tree.commit('2nd commit', rev_id=rev_id_utf8)
906
smart_req.SmartServerResponse((b'ok', b'2', rev_id_utf8)),
907
request.execute(b''))
910
class TestSmartServerBranchRequestRevisionIdToRevno(
911
tests.TestCaseWithMemoryTransport):
914
backing = self.get_transport()
915
request = smart_branch.SmartServerBranchRequestRevisionIdToRevno(
917
self.make_branch('.')
918
self.assertEqual(smart_req.SmartServerResponse((b'ok', b'0')),
919
request.execute(b'', b'null:'))
921
def test_ghost_revision(self):
922
backing = self.get_transport()
923
request = smart_branch.SmartServerBranchRequestRevisionIdToRevno(
925
branch = self.make_branch('.')
926
def revision_id_to_dotted_revno(revid):
927
raise errors.GhostRevisionsHaveNoRevno(revid, b'ghost-revid')
928
self.overrideAttr(branch, 'revision_id_to_dotted_revno', revision_id_to_dotted_revno)
930
smart_req.FailedSmartServerResponse(
931
(b'GhostRevisionsHaveNoRevno', b'revid', b'ghost-revid')),
932
request.do_with_branch(branch, b'revid'))
934
def test_simple(self):
935
backing = self.get_transport()
936
request = smart_branch.SmartServerBranchRequestRevisionIdToRevno(
938
tree = self.make_branch_and_memory_tree('.')
734
941
r1 = tree.commit('1st commit')
735
r2 = tree.commit('2nd commit', rev_id=rev_id_utf8)
737
943
self.assertEqual(
738
smart_req.SmartServerResponse(('ok', '2', rev_id_utf8)),
944
smart_req.SmartServerResponse((b'ok', b'1')),
945
request.execute(b'', r1))
947
def test_not_found(self):
948
backing = self.get_transport()
949
request = smart_branch.SmartServerBranchRequestRevisionIdToRevno(
951
self.make_branch('.')
953
smart_req.FailedSmartServerResponse(
954
(b'NoSuchRevision', b'idontexist')),
955
request.execute(b'', b'idontexist'))
742
958
class TestSmartServerBranchRequestGetConfigFile(
743
tests.TestCaseWithMemoryTransport):
959
tests.TestCaseWithMemoryTransport):
745
961
def test_default(self):
746
962
"""With no file, we get empty content."""
747
963
backing = self.get_transport()
748
964
request = smart_branch.SmartServerBranchGetConfigFile(backing)
749
branch = self.make_branch('.')
965
self.make_branch('.')
750
966
# there should be no file by default
752
self.assertEqual(smart_req.SmartServerResponse(('ok', ), content),
968
self.assertEqual(smart_req.SmartServerResponse((b'ok', ), content),
969
request.execute(b''))
755
971
def test_with_content(self):
756
972
# 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.
973
# branch.control_files.get('branch.conf') for now - in the future it
974
# may perform more complex processing.
759
975
backing = self.get_transport()
760
976
request = smart_branch.SmartServerBranchGetConfigFile(backing)
761
977
branch = self.make_branch('.')
762
branch._transport.put_bytes('branch.conf', 'foo bar baz')
763
self.assertEqual(smart_req.SmartServerResponse(('ok', ), 'foo bar baz'),
978
branch._transport.put_bytes('branch.conf', b'foo bar baz')
980
smart_req.SmartServerResponse((b'ok', ), b'foo bar baz'),
981
request.execute(b''))
767
984
class TestLockedBranch(tests.TestCaseWithMemoryTransport):
769
986
def get_lock_tokens(self, branch):
770
branch_token = branch.lock_write().branch_token
987
branch_token = branch.lock_write().token
771
988
repo_token = branch.repository.lock_write().repository_token
772
989
branch.repository.unlock()
773
990
return branch_token, repo_token
993
class TestSmartServerBranchRequestPutConfigFile(TestLockedBranch):
995
def test_with_content(self):
996
backing = self.get_transport()
997
request = smart_branch.SmartServerBranchPutConfigFile(backing)
998
branch = self.make_branch('.')
999
branch_token, repo_token = self.get_lock_tokens(branch)
1000
self.assertIs(None, request.execute(b'', branch_token, repo_token))
1002
smart_req.SmartServerResponse((b'ok', )),
1003
request.do_body(b'foo bar baz'))
1005
branch.control_transport.get_bytes('branch.conf'),
776
1010
class TestSmartServerBranchRequestSetConfigOption(TestLockedBranch):
778
1012
def test_value_name(self):
779
1013
branch = self.make_branch('.')
780
1014
request = smart_branch.SmartServerBranchRequestSetConfigOption(
781
branch.bzrdir.root_transport)
1015
branch.controldir.root_transport)
782
1016
branch_token, repo_token = self.get_lock_tokens(branch)
783
1017
config = branch._get_config()
784
result = request.execute('', branch_token, repo_token, 'bar', 'foo',
1018
result = request.execute(b'', branch_token, repo_token, b'bar', b'foo',
786
1020
self.assertEqual(smart_req.SuccessfulSmartServerResponse(()), result)
787
1021
self.assertEqual('bar', config.get_option('foo'))
1096
1392
self.get_transport())
1097
1393
branch_token, repo_token = self.get_lock_tokens(branch)
1099
response = request.execute('base', branch_token, repo_token,
1395
response = request.execute(b'base', branch_token, repo_token,
1102
1398
branch.unlock()
1103
1399
self.assertEqual(smart_req.SuccessfulSmartServerResponse(()), response)
1104
self.assertEqual('http://bar/', branch.get_parent())
1400
refreshed = _mod_branch.Branch.open(branch.base)
1401
self.assertEqual('http://bar/', refreshed.get_parent())
1107
1404
class TestSmartServerBranchRequestGetTagsBytes(
1108
tests.TestCaseWithMemoryTransport):
1405
tests.TestCaseWithMemoryTransport):
1109
1406
# Only called when the branch format and tags match [yay factory
1110
1407
# methods] so only need to test straight forward cases.
1112
1409
def test_get_bytes(self):
1113
base_branch = self.make_branch('base')
1410
self.make_branch('base')
1114
1411
request = smart_branch.SmartServerBranchGetTagsBytes(
1115
1412
self.get_transport())
1116
response = request.execute('base')
1118
smart_req.SuccessfulSmartServerResponse(('',)), response)
1121
class TestSmartServerBranchRequestGetStackedOnURL(tests.TestCaseWithMemoryTransport):
1413
response = request.execute(b'base')
1415
smart_req.SuccessfulSmartServerResponse((b'',)), response)
1418
class TestSmartServerBranchRequestGetStackedOnURL(
1419
tests.TestCaseWithMemoryTransport):
1123
1421
def test_get_stacked_on_url(self):
1124
base_branch = self.make_branch('base', format='1.6')
1422
self.make_branch('base', format='1.6')
1125
1423
stacked_branch = self.make_branch('stacked', format='1.6')
1126
1424
# typically should be relative
1127
1425
stacked_branch.set_stacked_on_url('../base')
1128
1426
request = smart_branch.SmartServerBranchRequestGetStackedOnURL(
1129
1427
self.get_transport())
1130
response = request.execute('stacked')
1132
smart_req.SmartServerResponse(('ok', '../base')),
1428
response = request.execute(b'stacked')
1430
smart_req.SmartServerResponse((b'ok', b'../base')),
1136
1434
class TestSmartServerBranchRequestLockWrite(TestLockedBranch):
1139
tests.TestCaseWithMemoryTransport.setUp(self)
1141
1436
def test_lock_write_on_unlocked_branch(self):
1142
1437
backing = self.get_transport()
1143
1438
request = smart_branch.SmartServerBranchRequestLockWrite(backing)
1144
1439
branch = self.make_branch('.', format='knit')
1145
1440
repository = branch.repository
1146
response = request.execute('')
1441
response = request.execute(b'')
1147
1442
branch_nonce = branch.control_files._lock.peek().get('nonce')
1148
1443
repository_nonce = repository.control_files._lock.peek().get('nonce')
1149
1444
self.assertEqual(smart_req.SmartServerResponse(
1150
('ok', branch_nonce, repository_nonce)),
1445
(b'ok', branch_nonce, repository_nonce)),
1152
1447
# The branch (and associated repository) is now locked. Verify that
1153
1448
# with a new branch object.
1154
new_branch = repository.bzrdir.open_branch()
1449
new_branch = repository.controldir.open_branch()
1155
1450
self.assertRaises(errors.LockContention, new_branch.lock_write)
1157
1452
request = smart_branch.SmartServerBranchRequestUnlock(backing)
1158
response = request.execute('', branch_nonce, repository_nonce)
1453
response = request.execute(b'', branch_nonce, repository_nonce)
1160
1455
def test_lock_write_on_locked_branch(self):
1161
1456
backing = self.get_transport()
1162
1457
request = smart_branch.SmartServerBranchRequestLockWrite(backing)
1163
1458
branch = self.make_branch('.')
1164
branch_token = branch.lock_write().branch_token
1459
branch_token = branch.lock_write().token
1165
1460
branch.leave_lock_in_place()
1166
1461
branch.unlock()
1167
response = request.execute('')
1462
response = request.execute(b'')
1168
1463
self.assertEqual(
1169
smart_req.SmartServerResponse(('LockContention',)), response)
1464
smart_req.SmartServerResponse((b'LockContention',)), response)
1171
1466
branch.lock_write(branch_token)
1172
1467
branch.dont_leave_lock_in_place()
1734
2367
repo.set_make_working_trees(False)
1735
2368
request_class = smart_repo.SmartServerRepositorySetMakeWorkingTrees
1736
2369
request = request_class(backing)
1737
self.assertEqual(smart_req.SuccessfulSmartServerResponse(('ok',)),
1738
request.execute('', 'True'))
1739
repo = repo.bzrdir.open_repository()
2370
self.assertEqual(smart_req.SuccessfulSmartServerResponse((b'ok',)),
2371
request.execute(b'', b'True'))
2372
repo = repo.controldir.open_repository()
1740
2373
self.assertTrue(repo.make_working_trees())
2376
class TestSmartServerRepositoryGetSerializerFormat(
2377
tests.TestCaseWithMemoryTransport):
2379
def test_get_serializer_format(self):
2380
backing = self.get_transport()
2381
repo = self.make_repository('.', format='2a')
2382
request_class = smart_repo.SmartServerRepositoryGetSerializerFormat
2383
request = request_class(backing)
2385
smart_req.SuccessfulSmartServerResponse((b'ok', b'10')),
2386
request.execute(b''))
2389
class TestSmartServerRepositoryWriteGroup(
2390
tests.TestCaseWithMemoryTransport):
2392
def test_start_write_group(self):
2393
backing = self.get_transport()
2394
repo = self.make_repository('.')
2395
lock_token = repo.lock_write().repository_token
2396
self.addCleanup(repo.unlock)
2397
request_class = smart_repo.SmartServerRepositoryStartWriteGroup
2398
request = request_class(backing)
2399
self.assertEqual(smart_req.SuccessfulSmartServerResponse((b'ok', [])),
2400
request.execute(b'', lock_token))
2402
def test_start_write_group_unsuspendable(self):
2403
backing = self.get_transport()
2404
repo = self.make_repository('.', format='knit')
2405
lock_token = repo.lock_write().repository_token
2406
self.addCleanup(repo.unlock)
2407
request_class = smart_repo.SmartServerRepositoryStartWriteGroup
2408
request = request_class(backing)
2410
smart_req.FailedSmartServerResponse((b'UnsuspendableWriteGroup',)),
2411
request.execute(b'', lock_token))
2413
def test_commit_write_group(self):
2414
backing = self.get_transport()
2415
repo = self.make_repository('.')
2416
lock_token = repo.lock_write().repository_token
2417
self.addCleanup(repo.unlock)
2418
repo.start_write_group()
2419
tokens = repo.suspend_write_group()
2420
request_class = smart_repo.SmartServerRepositoryCommitWriteGroup
2421
request = request_class(backing)
2422
self.assertEqual(smart_req.SuccessfulSmartServerResponse((b'ok',)),
2423
request.execute(b'', lock_token, tokens))
2425
def test_abort_write_group(self):
2426
backing = self.get_transport()
2427
repo = self.make_repository('.')
2428
lock_token = repo.lock_write().repository_token
2429
repo.start_write_group()
2430
tokens = repo.suspend_write_group()
2431
self.addCleanup(repo.unlock)
2432
request_class = smart_repo.SmartServerRepositoryAbortWriteGroup
2433
request = request_class(backing)
2434
self.assertEqual(smart_req.SuccessfulSmartServerResponse((b'ok',)),
2435
request.execute(b'', lock_token, tokens))
2437
def test_check_write_group(self):
2438
backing = self.get_transport()
2439
repo = self.make_repository('.')
2440
lock_token = repo.lock_write().repository_token
2441
repo.start_write_group()
2442
tokens = repo.suspend_write_group()
2443
self.addCleanup(repo.unlock)
2444
request_class = smart_repo.SmartServerRepositoryCheckWriteGroup
2445
request = request_class(backing)
2446
self.assertEqual(smart_req.SuccessfulSmartServerResponse((b'ok',)),
2447
request.execute(b'', lock_token, tokens))
2449
def test_check_write_group_invalid(self):
2450
backing = self.get_transport()
2451
repo = self.make_repository('.')
2452
lock_token = repo.lock_write().repository_token
2453
self.addCleanup(repo.unlock)
2454
request_class = smart_repo.SmartServerRepositoryCheckWriteGroup
2455
request = request_class(backing)
2456
self.assertEqual(smart_req.FailedSmartServerResponse(
2457
(b'UnresumableWriteGroup', [b'random'],
2458
b'Malformed write group token')),
2459
request.execute(b'', lock_token, [b"random"]))
1743
2462
class TestSmartServerPackRepositoryAutopack(tests.TestCaseWithTransport):
1745
2464
def make_repo_needing_autopacking(self, path='.'):
1811
2530
"""All registered request_handlers can be found."""
1812
2531
# If there's a typo in a register_lazy call, this loop will fail with
1813
2532
# an AttributeError.
1814
for key, item in smart_req.request_handlers.iteritems():
2533
for key in smart_req.request_handlers.keys():
2535
item = smart_req.request_handlers.get(key)
2536
except AttributeError as e:
2537
raise AttributeError('failed to get %s: %s' % (key, e))
1817
2539
def assertHandlerEqual(self, verb, handler):
1818
2540
self.assertEqual(smart_req.request_handlers.get(verb), handler)
1820
2542
def test_registered_methods(self):
1821
2543
"""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)
2544
self.assertHandlerEqual(b'Branch.break_lock',
2545
smart_branch.SmartServerBranchBreakLock)
2546
self.assertHandlerEqual(b'Branch.get_config_file',
2547
smart_branch.SmartServerBranchGetConfigFile)
2548
self.assertHandlerEqual(b'Branch.put_config_file',
2549
smart_branch.SmartServerBranchPutConfigFile)
2550
self.assertHandlerEqual(b'Branch.get_parent',
2551
smart_branch.SmartServerBranchGetParent)
2552
self.assertHandlerEqual(b'Branch.get_physical_lock_status',
2553
smart_branch.SmartServerBranchRequestGetPhysicalLockStatus)
2554
self.assertHandlerEqual(b'Branch.get_tags_bytes',
2555
smart_branch.SmartServerBranchGetTagsBytes)
2556
self.assertHandlerEqual(b'Branch.lock_write',
2557
smart_branch.SmartServerBranchRequestLockWrite)
2558
self.assertHandlerEqual(b'Branch.last_revision_info',
2559
smart_branch.SmartServerBranchRequestLastRevisionInfo)
2560
self.assertHandlerEqual(b'Branch.revision_history',
2561
smart_branch.SmartServerRequestRevisionHistory)
2562
self.assertHandlerEqual(b'Branch.revision_id_to_revno',
2563
smart_branch.SmartServerBranchRequestRevisionIdToRevno)
2564
self.assertHandlerEqual(b'Branch.set_config_option',
2565
smart_branch.SmartServerBranchRequestSetConfigOption)
2566
self.assertHandlerEqual(b'Branch.set_last_revision',
2567
smart_branch.SmartServerBranchRequestSetLastRevision)
2568
self.assertHandlerEqual(b'Branch.set_last_revision_info',
2569
smart_branch.SmartServerBranchRequestSetLastRevisionInfo)
2570
self.assertHandlerEqual(b'Branch.set_last_revision_ex',
2571
smart_branch.SmartServerBranchRequestSetLastRevisionEx)
2572
self.assertHandlerEqual(b'Branch.set_parent_location',
2573
smart_branch.SmartServerBranchRequestSetParentLocation)
2574
self.assertHandlerEqual(b'Branch.unlock',
2575
smart_branch.SmartServerBranchRequestUnlock)
2576
self.assertHandlerEqual(b'BzrDir.destroy_branch',
2577
smart_dir.SmartServerBzrDirRequestDestroyBranch)
2578
self.assertHandlerEqual(b'BzrDir.find_repository',
2579
smart_dir.SmartServerRequestFindRepositoryV1)
2580
self.assertHandlerEqual(b'BzrDir.find_repositoryV2',
2581
smart_dir.SmartServerRequestFindRepositoryV2)
2582
self.assertHandlerEqual(b'BzrDirFormat.initialize',
2583
smart_dir.SmartServerRequestInitializeBzrDir)
2584
self.assertHandlerEqual(b'BzrDirFormat.initialize_ex_1.16',
2585
smart_dir.SmartServerRequestBzrDirInitializeEx)
2586
self.assertHandlerEqual(b'BzrDir.checkout_metadir',
2587
smart_dir.SmartServerBzrDirRequestCheckoutMetaDir)
2588
self.assertHandlerEqual(b'BzrDir.cloning_metadir',
2589
smart_dir.SmartServerBzrDirRequestCloningMetaDir)
2590
self.assertHandlerEqual(b'BzrDir.get_branches',
2591
smart_dir.SmartServerBzrDirRequestGetBranches)
2592
self.assertHandlerEqual(b'BzrDir.get_config_file',
2593
smart_dir.SmartServerBzrDirRequestConfigFile)
2594
self.assertHandlerEqual(b'BzrDir.open_branch',
2595
smart_dir.SmartServerRequestOpenBranch)
2596
self.assertHandlerEqual(b'BzrDir.open_branchV2',
2597
smart_dir.SmartServerRequestOpenBranchV2)
2598
self.assertHandlerEqual(b'BzrDir.open_branchV3',
2599
smart_dir.SmartServerRequestOpenBranchV3)
2600
self.assertHandlerEqual(b'PackRepository.autopack',
2601
smart_packrepo.SmartServerPackRepositoryAutopack)
2602
self.assertHandlerEqual(b'Repository.add_signature_text',
2603
smart_repo.SmartServerRepositoryAddSignatureText)
2604
self.assertHandlerEqual(b'Repository.all_revision_ids',
2605
smart_repo.SmartServerRepositoryAllRevisionIds)
2606
self.assertHandlerEqual(b'Repository.break_lock',
2607
smart_repo.SmartServerRepositoryBreakLock)
2608
self.assertHandlerEqual(b'Repository.gather_stats',
2609
smart_repo.SmartServerRepositoryGatherStats)
2610
self.assertHandlerEqual(b'Repository.get_parent_map',
2611
smart_repo.SmartServerRepositoryGetParentMap)
2612
self.assertHandlerEqual(b'Repository.get_physical_lock_status',
2613
smart_repo.SmartServerRepositoryGetPhysicalLockStatus)
2614
self.assertHandlerEqual(b'Repository.get_rev_id_for_revno',
2615
smart_repo.SmartServerRepositoryGetRevIdForRevno)
2616
self.assertHandlerEqual(b'Repository.get_revision_graph',
2617
smart_repo.SmartServerRepositoryGetRevisionGraph)
2618
self.assertHandlerEqual(b'Repository.get_revision_signature_text',
2619
smart_repo.SmartServerRepositoryGetRevisionSignatureText)
2620
self.assertHandlerEqual(b'Repository.get_stream',
2621
smart_repo.SmartServerRepositoryGetStream)
2622
self.assertHandlerEqual(b'Repository.get_stream_1.19',
2623
smart_repo.SmartServerRepositoryGetStream_1_19)
2624
self.assertHandlerEqual(b'Repository.iter_revisions',
2625
smart_repo.SmartServerRepositoryIterRevisions)
2626
self.assertHandlerEqual(b'Repository.has_revision',
2627
smart_repo.SmartServerRequestHasRevision)
2628
self.assertHandlerEqual(b'Repository.insert_stream',
2629
smart_repo.SmartServerRepositoryInsertStream)
2630
self.assertHandlerEqual(b'Repository.insert_stream_locked',
2631
smart_repo.SmartServerRepositoryInsertStreamLocked)
2632
self.assertHandlerEqual(b'Repository.is_shared',
2633
smart_repo.SmartServerRepositoryIsShared)
2634
self.assertHandlerEqual(b'Repository.iter_files_bytes',
2635
smart_repo.SmartServerRepositoryIterFilesBytes)
2636
self.assertHandlerEqual(b'Repository.lock_write',
2637
smart_repo.SmartServerRepositoryLockWrite)
2638
self.assertHandlerEqual(b'Repository.make_working_trees',
2639
smart_repo.SmartServerRepositoryMakeWorkingTrees)
2640
self.assertHandlerEqual(b'Repository.pack',
2641
smart_repo.SmartServerRepositoryPack)
2642
self.assertHandlerEqual(b'Repository.reconcile',
2643
smart_repo.SmartServerRepositoryReconcile)
2644
self.assertHandlerEqual(b'Repository.tarball',
2645
smart_repo.SmartServerRepositoryTarball)
2646
self.assertHandlerEqual(b'Repository.unlock',
2647
smart_repo.SmartServerRepositoryUnlock)
2648
self.assertHandlerEqual(b'Repository.start_write_group',
2649
smart_repo.SmartServerRepositoryStartWriteGroup)
2650
self.assertHandlerEqual(b'Repository.check_write_group',
2651
smart_repo.SmartServerRepositoryCheckWriteGroup)
2652
self.assertHandlerEqual(b'Repository.commit_write_group',
2653
smart_repo.SmartServerRepositoryCommitWriteGroup)
2654
self.assertHandlerEqual(b'Repository.abort_write_group',
2655
smart_repo.SmartServerRepositoryAbortWriteGroup)
2656
self.assertHandlerEqual(b'VersionedFileRepository.get_serializer_format',
2657
smart_repo.SmartServerRepositoryGetSerializerFormat)
2658
self.assertHandlerEqual(b'VersionedFileRepository.get_inventories',
2659
smart_repo.SmartServerRepositoryGetInventories)
2660
self.assertHandlerEqual(b'Transport.is_readonly',
2661
smart_req.SmartServerIsReadonly)
2664
class SmartTCPServerHookTests(tests.TestCaseWithMemoryTransport):
2665
"""Tests for SmartTCPServer hooks."""
2668
super(SmartTCPServerHookTests, self).setUp()
2669
self.server = server.SmartTCPServer(self.get_transport())
2671
def test_run_server_started_hooks(self):
2672
"""Test the server started hooks get fired properly."""
2674
server.SmartTCPServer.hooks.install_named_hook('server_started',
2675
lambda backing_urls, url: started_calls.append(
2676
(backing_urls, url)),
2678
started_ex_calls = []
2679
server.SmartTCPServer.hooks.install_named_hook('server_started_ex',
2680
lambda backing_urls, url: started_ex_calls.append(
2681
(backing_urls, url)),
2683
self.server._sockname = ('example.com', 42)
2684
self.server.run_server_started_hooks()
2685
self.assertEqual(started_calls,
2686
[([self.get_transport().base], 'bzr://example.com:42/')])
2687
self.assertEqual(started_ex_calls,
2688
[([self.get_transport().base], self.server)])
2690
def test_run_server_started_hooks_ipv6(self):
2691
"""Test that socknames can contain 4-tuples."""
2692
self.server._sockname = ('::', 42, 0, 0)
2694
server.SmartTCPServer.hooks.install_named_hook('server_started',
2695
lambda backing_urls, url: started_calls.append(
2696
(backing_urls, url)),
2698
self.server.run_server_started_hooks()
2699
self.assertEqual(started_calls,
2700
[([self.get_transport().base], 'bzr://:::42/')])
2702
def test_run_server_stopped_hooks(self):
2703
"""Test the server stopped hooks."""
2704
self.server._sockname = ('example.com', 42)
2706
server.SmartTCPServer.hooks.install_named_hook('server_stopped',
2707
lambda backing_urls, url: stopped_calls.append(
2708
(backing_urls, url)),
2710
self.server.run_server_stopped_hooks()
2711
self.assertEqual(stopped_calls,
2712
[([self.get_transport().base], 'bzr://example.com:42/')])
2715
class TestSmartServerRepositoryPack(tests.TestCaseWithMemoryTransport):
2717
def test_pack(self):
2718
backing = self.get_transport()
2719
request = smart_repo.SmartServerRepositoryPack(backing)
2720
tree = self.make_branch_and_memory_tree('.')
2721
repo_token = tree.branch.repository.lock_write().repository_token
2723
self.assertIs(None, request.execute(b'', repo_token, False))
2726
smart_req.SuccessfulSmartServerResponse((b'ok', ), ),
2727
request.do_body(b''))
2730
class TestSmartServerRepositoryGetInventories(tests.TestCaseWithTransport):
2732
def _get_serialized_inventory_delta(self, repository, base_revid, revid):
2733
base_inv = repository.revision_tree(base_revid).root_inventory
2734
inv = repository.revision_tree(revid).root_inventory
2735
inv_delta = inv._make_delta(base_inv)
2736
serializer = inventory_delta.InventoryDeltaSerializer(True, True)
2737
return b"".join(serializer.delta_to_lines(base_revid, revid, inv_delta))
2739
def test_single(self):
2740
backing = self.get_transport()
2741
request = smart_repo.SmartServerRepositoryGetInventories(backing)
2742
t = self.make_branch_and_tree('.', format='2a')
2743
self.addCleanup(t.lock_write().unlock)
2744
self.build_tree_contents([("file", b"somecontents")])
2745
t.add(["file"], [b"thefileid"])
2746
t.commit(rev_id=b'somerev', message="add file")
2747
self.assertIs(None, request.execute(b'', b'unordered'))
2748
response = request.do_body(b"somerev\n")
2749
self.assertTrue(response.is_successful())
2750
self.assertEqual(response.args, (b"ok", ))
2751
stream = [('inventory-deltas', [
2752
versionedfile.FulltextContentFactory(b'somerev', None, None,
2753
self._get_serialized_inventory_delta(
2754
t.branch.repository, b'null:', b'somerev'))])]
2755
fmt = controldir.format_registry.get('2a')().repository_format
2757
b"".join(response.body_stream),
2758
b"".join(smart_repo._stream_to_byte_stream(stream, fmt)))
2760
def test_empty(self):
2761
backing = self.get_transport()
2762
request = smart_repo.SmartServerRepositoryGetInventories(backing)
2763
t = self.make_branch_and_tree('.', format='2a')
2764
self.addCleanup(t.lock_write().unlock)
2765
self.build_tree_contents([("file", b"somecontents")])
2766
t.add(["file"], [b"thefileid"])
2767
t.commit(rev_id=b'somerev', message="add file")
2768
self.assertIs(None, request.execute(b'', b'unordered'))
2769
response = request.do_body(b"")
2770
self.assertTrue(response.is_successful())
2771
self.assertEqual(response.args, (b"ok", ))
2772
self.assertEqual(b"".join(response.body_stream),
2773
b"Bazaar pack format 1 (introduced in 0.18)\nB54\n\nBazaar repository format 2a (needs bzr 1.16 or later)\nE")
2776
class TestSmartServerRepositoryGetStreamForMissingKeys(GetStreamTestBase):
2778
def test_missing(self):
2779
"""The search argument may be a 'ancestry-of' some heads'."""
2780
backing = self.get_transport()
2781
request = smart_repo.SmartServerRepositoryGetStreamForMissingKeys(
2783
repo, r1, r2 = self.make_two_commit_repo()
2784
request.execute(b'', repo._format.network_name())
2785
lines = b'inventories\t' + r1
2786
response = request.do_body(lines)
2787
self.assertEqual((b'ok',), response.args)
2788
stream_bytes = b''.join(response.body_stream)
2789
self.assertStartsWith(stream_bytes, b'Bazaar pack format 1')
2791
def test_unknown_format(self):
2792
"""The format may not be known by the remote server."""
2793
backing = self.get_transport()
2794
request = smart_repo.SmartServerRepositoryGetStreamForMissingKeys(
2796
repo, r1, r2 = self.make_two_commit_repo()
2797
request.execute(b'', b'yada yada yada')
2798
expected = smart_req.FailedSmartServerResponse(
2799
(b'UnknownFormat', b'repository', b'yada yada yada'))
2802
class TestSmartServerRepositoryRevisionArchive(tests.TestCaseWithTransport):
2804
backing = self.get_transport()
2805
request = smart_repo.SmartServerRepositoryRevisionArchive(backing)
2806
t = self.make_branch_and_tree('.')
2807
self.addCleanup(t.lock_write().unlock)
2808
self.build_tree_contents([("file", b"somecontents")])
2809
t.add(["file"], [b"thefileid"])
2810
t.commit(rev_id=b'somerev', message="add file")
2811
response = request.execute(b'', b"somerev", b"tar", b"foo.tar", b"foo")
2812
self.assertTrue(response.is_successful())
2813
self.assertEqual(response.args, (b"ok", ))
2814
b = BytesIO(b"".join(response.body_stream))
2815
with tarfile.open(mode='r', fileobj=b) as tf:
2816
self.assertEqual(['foo/file'], tf.getnames())
2819
class TestSmartServerRepositoryAnnotateFileRevision(tests.TestCaseWithTransport):
2822
backing = self.get_transport()
2823
request = smart_repo.SmartServerRepositoryAnnotateFileRevision(backing)
2824
t = self.make_branch_and_tree('.')
2825
self.addCleanup(t.lock_write().unlock)
2826
self.build_tree_contents([("file", b"somecontents\nmorecontents\n")])
2827
t.add(["file"], [b"thefileid"])
2828
t.commit(rev_id=b'somerev', message="add file")
2829
response = request.execute(b'', b"somerev", b"file")
2830
self.assertTrue(response.is_successful())
2831
self.assertEqual(response.args, (b"ok", ))
2833
[[b'somerev', b'somecontents\n'], [b'somerev', b'morecontents\n']],
2834
bencode.bdecode(response.body))
2837
class TestSmartServerBranchRequestGetAllReferenceInfo(TestLockedBranch):
2839
def test_get_some(self):
2840
backing = self.get_transport()
2841
request = smart_branch.SmartServerBranchRequestGetAllReferenceInfo(backing)
2842
branch = self.make_branch('.')
2843
branch.set_reference_info('some/path', 'http://www.example.com/')
2844
response = request.execute(b'')
2845
self.assertTrue(response.is_successful())
2846
self.assertEqual(response.args, (b"ok", ))
2848
[[b'some/path', b'http://www.example.com/', b'']],
2849
bencode.bdecode(response.body))