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_ghost_revision(self):
909
backing = self.get_transport()
910
request = smart_branch.SmartServerBranchRequestRevisionIdToRevno(
912
branch = self.make_branch('.')
913
def revision_id_to_dotted_revno(revid):
914
raise errors.GhostRevisionsHaveNoRevno(revid, b'ghost-revid')
915
self.overrideAttr(branch, 'revision_id_to_dotted_revno', revision_id_to_dotted_revno)
917
smart_req.FailedSmartServerResponse(
918
(b'GhostRevisionsHaveNoRevno', b'revid', b'ghost-revid')),
919
request.do_with_branch(branch, b'revid'))
921
def test_simple(self):
922
backing = self.get_transport()
923
request = smart_branch.SmartServerBranchRequestRevisionIdToRevno(
925
tree = self.make_branch_and_memory_tree('.')
734
928
r1 = tree.commit('1st commit')
735
r2 = tree.commit('2nd commit', rev_id=rev_id_utf8)
737
930
self.assertEqual(
738
smart_req.SmartServerResponse(('ok', '2', rev_id_utf8)),
931
smart_req.SmartServerResponse((b'ok', b'1')),
932
request.execute(b'', r1))
934
def test_not_found(self):
935
backing = self.get_transport()
936
request = smart_branch.SmartServerBranchRequestRevisionIdToRevno(
938
self.make_branch('.')
940
smart_req.FailedSmartServerResponse(
941
(b'NoSuchRevision', b'idontexist')),
942
request.execute(b'', b'idontexist'))
742
945
class TestSmartServerBranchRequestGetConfigFile(
743
tests.TestCaseWithMemoryTransport):
946
tests.TestCaseWithMemoryTransport):
745
948
def test_default(self):
746
949
"""With no file, we get empty content."""
747
950
backing = self.get_transport()
748
951
request = smart_branch.SmartServerBranchGetConfigFile(backing)
749
branch = self.make_branch('.')
952
self.make_branch('.')
750
953
# there should be no file by default
752
self.assertEqual(smart_req.SmartServerResponse(('ok', ), content),
955
self.assertEqual(smart_req.SmartServerResponse((b'ok', ), content),
956
request.execute(b''))
755
958
def test_with_content(self):
756
959
# 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.
960
# branch.control_files.get('branch.conf') for now - in the future it
961
# may perform more complex processing.
759
962
backing = self.get_transport()
760
963
request = smart_branch.SmartServerBranchGetConfigFile(backing)
761
964
branch = self.make_branch('.')
762
branch._transport.put_bytes('branch.conf', 'foo bar baz')
763
self.assertEqual(smart_req.SmartServerResponse(('ok', ), 'foo bar baz'),
965
branch._transport.put_bytes('branch.conf', b'foo bar baz')
967
smart_req.SmartServerResponse((b'ok', ), b'foo bar baz'),
968
request.execute(b''))
767
971
class TestLockedBranch(tests.TestCaseWithMemoryTransport):
769
973
def get_lock_tokens(self, branch):
770
branch_token = branch.lock_write().branch_token
974
branch_token = branch.lock_write().token
771
975
repo_token = branch.repository.lock_write().repository_token
772
976
branch.repository.unlock()
773
977
return branch_token, repo_token
980
class TestSmartServerBranchRequestPutConfigFile(TestLockedBranch):
982
def test_with_content(self):
983
backing = self.get_transport()
984
request = smart_branch.SmartServerBranchPutConfigFile(backing)
985
branch = self.make_branch('.')
986
branch_token, repo_token = self.get_lock_tokens(branch)
987
self.assertIs(None, request.execute(b'', branch_token, repo_token))
989
smart_req.SmartServerResponse((b'ok', )),
990
request.do_body(b'foo bar baz'))
992
branch.control_transport.get_bytes('branch.conf'),
776
997
class TestSmartServerBranchRequestSetConfigOption(TestLockedBranch):
778
999
def test_value_name(self):
779
1000
branch = self.make_branch('.')
780
1001
request = smart_branch.SmartServerBranchRequestSetConfigOption(
781
branch.bzrdir.root_transport)
1002
branch.controldir.root_transport)
782
1003
branch_token, repo_token = self.get_lock_tokens(branch)
783
1004
config = branch._get_config()
784
result = request.execute('', branch_token, repo_token, 'bar', 'foo',
1005
result = request.execute(b'', branch_token, repo_token, b'bar', b'foo',
786
1007
self.assertEqual(smart_req.SuccessfulSmartServerResponse(()), result)
787
1008
self.assertEqual('bar', config.get_option('foo'))
1096
1379
self.get_transport())
1097
1380
branch_token, repo_token = self.get_lock_tokens(branch)
1099
response = request.execute('base', branch_token, repo_token,
1382
response = request.execute(b'base', branch_token, repo_token,
1102
1385
branch.unlock()
1103
1386
self.assertEqual(smart_req.SuccessfulSmartServerResponse(()), response)
1104
self.assertEqual('http://bar/', branch.get_parent())
1387
refreshed = _mod_branch.Branch.open(branch.base)
1388
self.assertEqual('http://bar/', refreshed.get_parent())
1107
1391
class TestSmartServerBranchRequestGetTagsBytes(
1108
tests.TestCaseWithMemoryTransport):
1392
tests.TestCaseWithMemoryTransport):
1109
1393
# Only called when the branch format and tags match [yay factory
1110
1394
# methods] so only need to test straight forward cases.
1112
1396
def test_get_bytes(self):
1113
base_branch = self.make_branch('base')
1397
self.make_branch('base')
1114
1398
request = smart_branch.SmartServerBranchGetTagsBytes(
1115
1399
self.get_transport())
1116
response = request.execute('base')
1118
smart_req.SuccessfulSmartServerResponse(('',)), response)
1121
class TestSmartServerBranchRequestGetStackedOnURL(tests.TestCaseWithMemoryTransport):
1400
response = request.execute(b'base')
1402
smart_req.SuccessfulSmartServerResponse((b'',)), response)
1405
class TestSmartServerBranchRequestGetStackedOnURL(
1406
tests.TestCaseWithMemoryTransport):
1123
1408
def test_get_stacked_on_url(self):
1124
base_branch = self.make_branch('base', format='1.6')
1409
self.make_branch('base', format='1.6')
1125
1410
stacked_branch = self.make_branch('stacked', format='1.6')
1126
1411
# typically should be relative
1127
1412
stacked_branch.set_stacked_on_url('../base')
1128
1413
request = smart_branch.SmartServerBranchRequestGetStackedOnURL(
1129
1414
self.get_transport())
1130
response = request.execute('stacked')
1132
smart_req.SmartServerResponse(('ok', '../base')),
1415
response = request.execute(b'stacked')
1417
smart_req.SmartServerResponse((b'ok', b'../base')),
1136
1421
class TestSmartServerBranchRequestLockWrite(TestLockedBranch):
1139
tests.TestCaseWithMemoryTransport.setUp(self)
1141
1423
def test_lock_write_on_unlocked_branch(self):
1142
1424
backing = self.get_transport()
1143
1425
request = smart_branch.SmartServerBranchRequestLockWrite(backing)
1144
1426
branch = self.make_branch('.', format='knit')
1145
1427
repository = branch.repository
1146
response = request.execute('')
1428
response = request.execute(b'')
1147
1429
branch_nonce = branch.control_files._lock.peek().get('nonce')
1148
1430
repository_nonce = repository.control_files._lock.peek().get('nonce')
1149
1431
self.assertEqual(smart_req.SmartServerResponse(
1150
('ok', branch_nonce, repository_nonce)),
1432
(b'ok', branch_nonce, repository_nonce)),
1152
1434
# The branch (and associated repository) is now locked. Verify that
1153
1435
# with a new branch object.
1154
new_branch = repository.bzrdir.open_branch()
1436
new_branch = repository.controldir.open_branch()
1155
1437
self.assertRaises(errors.LockContention, new_branch.lock_write)
1157
1439
request = smart_branch.SmartServerBranchRequestUnlock(backing)
1158
response = request.execute('', branch_nonce, repository_nonce)
1440
response = request.execute(b'', branch_nonce, repository_nonce)
1160
1442
def test_lock_write_on_locked_branch(self):
1161
1443
backing = self.get_transport()
1162
1444
request = smart_branch.SmartServerBranchRequestLockWrite(backing)
1163
1445
branch = self.make_branch('.')
1164
branch_token = branch.lock_write().branch_token
1446
branch_token = branch.lock_write().token
1165
1447
branch.leave_lock_in_place()
1166
1448
branch.unlock()
1167
response = request.execute('')
1449
response = request.execute(b'')
1168
1450
self.assertEqual(
1169
smart_req.SmartServerResponse(('LockContention',)), response)
1451
smart_req.SmartServerResponse((b'LockContention',)), response)
1171
1453
branch.lock_write(branch_token)
1172
1454
branch.dont_leave_lock_in_place()
1493
1937
tree.lock_write()
1495
1939
rev_id_utf8 = u'\xc8abc'.encode('utf-8')
1496
r1 = tree.commit('a commit', rev_id=rev_id_utf8)
1940
tree.commit('a commit', rev_id=rev_id_utf8)
1498
1942
self.assertTrue(tree.branch.repository.has_revision(rev_id_utf8))
1499
self.assertEqual(smart_req.SmartServerResponse(('yes', )),
1500
request.execute('', rev_id_utf8))
1943
self.assertEqual(smart_req.SmartServerResponse((b'yes', )),
1944
request.execute(b'', rev_id_utf8))
1947
class TestSmartServerRepositoryIterFilesBytes(tests.TestCaseWithTransport):
1949
def test_single(self):
1950
backing = self.get_transport()
1951
request = smart_repo.SmartServerRepositoryIterFilesBytes(backing)
1952
t = self.make_branch_and_tree('.')
1953
self.addCleanup(t.lock_write().unlock)
1954
self.build_tree_contents([("file", b"somecontents")])
1955
t.add(["file"], [b"thefileid"])
1956
t.commit(rev_id=b'somerev', message="add file")
1957
self.assertIs(None, request.execute(b''))
1958
response = request.do_body(b"thefileid\0somerev\n")
1959
self.assertTrue(response.is_successful())
1960
self.assertEqual(response.args, (b"ok", ))
1961
self.assertEqual(b"".join(response.body_stream),
1962
b"ok\x000\n" + zlib.compress(b"somecontents"))
1964
def test_missing(self):
1965
backing = self.get_transport()
1966
request = smart_repo.SmartServerRepositoryIterFilesBytes(backing)
1967
t = self.make_branch_and_tree('.')
1968
self.addCleanup(t.lock_write().unlock)
1969
self.assertIs(None, request.execute(b''))
1970
response = request.do_body(b"thefileid\0revision\n")
1971
self.assertTrue(response.is_successful())
1972
self.assertEqual(response.args, (b"ok", ))
1973
self.assertEqual(b"".join(response.body_stream),
1974
b"absent\x00thefileid\x00revision\x000\n")
1977
class TestSmartServerRequestHasSignatureForRevisionId(
1978
tests.TestCaseWithMemoryTransport):
1980
def test_missing_revision(self):
1981
"""For a missing revision, NoSuchRevision is returned."""
1982
backing = self.get_transport()
1983
request = smart_repo.SmartServerRequestHasSignatureForRevisionId(
1985
self.make_repository('.')
1987
smart_req.FailedSmartServerResponse(
1988
(b'nosuchrevision', b'revid'), None),
1989
request.execute(b'', b'revid'))
1991
def test_missing_signature(self):
1992
"""For a missing signature, ('no', ) is returned."""
1993
backing = self.get_transport()
1994
request = smart_repo.SmartServerRequestHasSignatureForRevisionId(
1996
tree = self.make_branch_and_memory_tree('.')
1999
tree.commit('a commit', rev_id=b'A')
2001
self.assertTrue(tree.branch.repository.has_revision(b'A'))
2002
self.assertEqual(smart_req.SmartServerResponse((b'no', )),
2003
request.execute(b'', b'A'))
2005
def test_present_signature(self):
2006
"""For a present signature, ('yes', ) is returned."""
2007
backing = self.get_transport()
2008
request = smart_repo.SmartServerRequestHasSignatureForRevisionId(
2010
strategy = gpg.LoopbackGPGStrategy(None)
2011
tree = self.make_branch_and_memory_tree('.')
2014
tree.commit('a commit', rev_id=b'A')
2015
tree.branch.repository.start_write_group()
2016
tree.branch.repository.sign_revision(b'A', strategy)
2017
tree.branch.repository.commit_write_group()
2019
self.assertTrue(tree.branch.repository.has_revision(b'A'))
2020
self.assertEqual(smart_req.SmartServerResponse((b'yes', )),
2021
request.execute(b'', b'A'))
1503
2024
class TestSmartServerRepositoryGatherStats(tests.TestCaseWithMemoryTransport):
1734
2354
repo.set_make_working_trees(False)
1735
2355
request_class = smart_repo.SmartServerRepositorySetMakeWorkingTrees
1736
2356
request = request_class(backing)
1737
self.assertEqual(smart_req.SuccessfulSmartServerResponse(('ok',)),
1738
request.execute('', 'True'))
1739
repo = repo.bzrdir.open_repository()
2357
self.assertEqual(smart_req.SuccessfulSmartServerResponse((b'ok',)),
2358
request.execute(b'', b'True'))
2359
repo = repo.controldir.open_repository()
1740
2360
self.assertTrue(repo.make_working_trees())
2363
class TestSmartServerRepositoryGetSerializerFormat(
2364
tests.TestCaseWithMemoryTransport):
2366
def test_get_serializer_format(self):
2367
backing = self.get_transport()
2368
repo = self.make_repository('.', format='2a')
2369
request_class = smart_repo.SmartServerRepositoryGetSerializerFormat
2370
request = request_class(backing)
2372
smart_req.SuccessfulSmartServerResponse((b'ok', b'10')),
2373
request.execute(b''))
2376
class TestSmartServerRepositoryWriteGroup(
2377
tests.TestCaseWithMemoryTransport):
2379
def test_start_write_group(self):
2380
backing = self.get_transport()
2381
repo = self.make_repository('.')
2382
lock_token = repo.lock_write().repository_token
2383
self.addCleanup(repo.unlock)
2384
request_class = smart_repo.SmartServerRepositoryStartWriteGroup
2385
request = request_class(backing)
2386
self.assertEqual(smart_req.SuccessfulSmartServerResponse((b'ok', [])),
2387
request.execute(b'', lock_token))
2389
def test_start_write_group_unsuspendable(self):
2390
backing = self.get_transport()
2391
repo = self.make_repository('.', format='knit')
2392
lock_token = repo.lock_write().repository_token
2393
self.addCleanup(repo.unlock)
2394
request_class = smart_repo.SmartServerRepositoryStartWriteGroup
2395
request = request_class(backing)
2397
smart_req.FailedSmartServerResponse((b'UnsuspendableWriteGroup',)),
2398
request.execute(b'', lock_token))
2400
def test_commit_write_group(self):
2401
backing = self.get_transport()
2402
repo = self.make_repository('.')
2403
lock_token = repo.lock_write().repository_token
2404
self.addCleanup(repo.unlock)
2405
repo.start_write_group()
2406
tokens = repo.suspend_write_group()
2407
request_class = smart_repo.SmartServerRepositoryCommitWriteGroup
2408
request = request_class(backing)
2409
self.assertEqual(smart_req.SuccessfulSmartServerResponse((b'ok',)),
2410
request.execute(b'', lock_token, tokens))
2412
def test_abort_write_group(self):
2413
backing = self.get_transport()
2414
repo = self.make_repository('.')
2415
lock_token = repo.lock_write().repository_token
2416
repo.start_write_group()
2417
tokens = repo.suspend_write_group()
2418
self.addCleanup(repo.unlock)
2419
request_class = smart_repo.SmartServerRepositoryAbortWriteGroup
2420
request = request_class(backing)
2421
self.assertEqual(smart_req.SuccessfulSmartServerResponse((b'ok',)),
2422
request.execute(b'', lock_token, tokens))
2424
def test_check_write_group(self):
2425
backing = self.get_transport()
2426
repo = self.make_repository('.')
2427
lock_token = repo.lock_write().repository_token
2428
repo.start_write_group()
2429
tokens = repo.suspend_write_group()
2430
self.addCleanup(repo.unlock)
2431
request_class = smart_repo.SmartServerRepositoryCheckWriteGroup
2432
request = request_class(backing)
2433
self.assertEqual(smart_req.SuccessfulSmartServerResponse((b'ok',)),
2434
request.execute(b'', lock_token, tokens))
2436
def test_check_write_group_invalid(self):
2437
backing = self.get_transport()
2438
repo = self.make_repository('.')
2439
lock_token = repo.lock_write().repository_token
2440
self.addCleanup(repo.unlock)
2441
request_class = smart_repo.SmartServerRepositoryCheckWriteGroup
2442
request = request_class(backing)
2443
self.assertEqual(smart_req.FailedSmartServerResponse(
2444
(b'UnresumableWriteGroup', [b'random'],
2445
b'Malformed write group token')),
2446
request.execute(b'', lock_token, [b"random"]))
1743
2449
class TestSmartServerPackRepositoryAutopack(tests.TestCaseWithTransport):
1745
2451
def make_repo_needing_autopacking(self, path='.'):
1811
2517
"""All registered request_handlers can be found."""
1812
2518
# If there's a typo in a register_lazy call, this loop will fail with
1813
2519
# an AttributeError.
1814
for key, item in smart_req.request_handlers.iteritems():
2520
for key in smart_req.request_handlers.keys():
2522
item = smart_req.request_handlers.get(key)
2523
except AttributeError as e:
2524
raise AttributeError('failed to get %s: %s' % (key, e))
1817
2526
def assertHandlerEqual(self, verb, handler):
1818
2527
self.assertEqual(smart_req.request_handlers.get(verb), handler)
1820
2529
def test_registered_methods(self):
1821
2530
"""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)
2531
self.assertHandlerEqual(b'Branch.break_lock',
2532
smart_branch.SmartServerBranchBreakLock)
2533
self.assertHandlerEqual(b'Branch.get_config_file',
2534
smart_branch.SmartServerBranchGetConfigFile)
2535
self.assertHandlerEqual(b'Branch.put_config_file',
2536
smart_branch.SmartServerBranchPutConfigFile)
2537
self.assertHandlerEqual(b'Branch.get_parent',
2538
smart_branch.SmartServerBranchGetParent)
2539
self.assertHandlerEqual(b'Branch.get_physical_lock_status',
2540
smart_branch.SmartServerBranchRequestGetPhysicalLockStatus)
2541
self.assertHandlerEqual(b'Branch.get_tags_bytes',
2542
smart_branch.SmartServerBranchGetTagsBytes)
2543
self.assertHandlerEqual(b'Branch.lock_write',
2544
smart_branch.SmartServerBranchRequestLockWrite)
2545
self.assertHandlerEqual(b'Branch.last_revision_info',
2546
smart_branch.SmartServerBranchRequestLastRevisionInfo)
2547
self.assertHandlerEqual(b'Branch.revision_history',
2548
smart_branch.SmartServerRequestRevisionHistory)
2549
self.assertHandlerEqual(b'Branch.revision_id_to_revno',
2550
smart_branch.SmartServerBranchRequestRevisionIdToRevno)
2551
self.assertHandlerEqual(b'Branch.set_config_option',
2552
smart_branch.SmartServerBranchRequestSetConfigOption)
2553
self.assertHandlerEqual(b'Branch.set_last_revision',
2554
smart_branch.SmartServerBranchRequestSetLastRevision)
2555
self.assertHandlerEqual(b'Branch.set_last_revision_info',
2556
smart_branch.SmartServerBranchRequestSetLastRevisionInfo)
2557
self.assertHandlerEqual(b'Branch.set_last_revision_ex',
2558
smart_branch.SmartServerBranchRequestSetLastRevisionEx)
2559
self.assertHandlerEqual(b'Branch.set_parent_location',
2560
smart_branch.SmartServerBranchRequestSetParentLocation)
2561
self.assertHandlerEqual(b'Branch.unlock',
2562
smart_branch.SmartServerBranchRequestUnlock)
2563
self.assertHandlerEqual(b'BzrDir.destroy_branch',
2564
smart_dir.SmartServerBzrDirRequestDestroyBranch)
2565
self.assertHandlerEqual(b'BzrDir.find_repository',
2566
smart_dir.SmartServerRequestFindRepositoryV1)
2567
self.assertHandlerEqual(b'BzrDir.find_repositoryV2',
2568
smart_dir.SmartServerRequestFindRepositoryV2)
2569
self.assertHandlerEqual(b'BzrDirFormat.initialize',
2570
smart_dir.SmartServerRequestInitializeBzrDir)
2571
self.assertHandlerEqual(b'BzrDirFormat.initialize_ex_1.16',
2572
smart_dir.SmartServerRequestBzrDirInitializeEx)
2573
self.assertHandlerEqual(b'BzrDir.checkout_metadir',
2574
smart_dir.SmartServerBzrDirRequestCheckoutMetaDir)
2575
self.assertHandlerEqual(b'BzrDir.cloning_metadir',
2576
smart_dir.SmartServerBzrDirRequestCloningMetaDir)
2577
self.assertHandlerEqual(b'BzrDir.get_branches',
2578
smart_dir.SmartServerBzrDirRequestGetBranches)
2579
self.assertHandlerEqual(b'BzrDir.get_config_file',
2580
smart_dir.SmartServerBzrDirRequestConfigFile)
2581
self.assertHandlerEqual(b'BzrDir.open_branch',
2582
smart_dir.SmartServerRequestOpenBranch)
2583
self.assertHandlerEqual(b'BzrDir.open_branchV2',
2584
smart_dir.SmartServerRequestOpenBranchV2)
2585
self.assertHandlerEqual(b'BzrDir.open_branchV3',
2586
smart_dir.SmartServerRequestOpenBranchV3)
2587
self.assertHandlerEqual(b'PackRepository.autopack',
2588
smart_packrepo.SmartServerPackRepositoryAutopack)
2589
self.assertHandlerEqual(b'Repository.add_signature_text',
2590
smart_repo.SmartServerRepositoryAddSignatureText)
2591
self.assertHandlerEqual(b'Repository.all_revision_ids',
2592
smart_repo.SmartServerRepositoryAllRevisionIds)
2593
self.assertHandlerEqual(b'Repository.break_lock',
2594
smart_repo.SmartServerRepositoryBreakLock)
2595
self.assertHandlerEqual(b'Repository.gather_stats',
2596
smart_repo.SmartServerRepositoryGatherStats)
2597
self.assertHandlerEqual(b'Repository.get_parent_map',
2598
smart_repo.SmartServerRepositoryGetParentMap)
2599
self.assertHandlerEqual(b'Repository.get_physical_lock_status',
2600
smart_repo.SmartServerRepositoryGetPhysicalLockStatus)
2601
self.assertHandlerEqual(b'Repository.get_rev_id_for_revno',
2602
smart_repo.SmartServerRepositoryGetRevIdForRevno)
2603
self.assertHandlerEqual(b'Repository.get_revision_graph',
2604
smart_repo.SmartServerRepositoryGetRevisionGraph)
2605
self.assertHandlerEqual(b'Repository.get_revision_signature_text',
2606
smart_repo.SmartServerRepositoryGetRevisionSignatureText)
2607
self.assertHandlerEqual(b'Repository.get_stream',
2608
smart_repo.SmartServerRepositoryGetStream)
2609
self.assertHandlerEqual(b'Repository.get_stream_1.19',
2610
smart_repo.SmartServerRepositoryGetStream_1_19)
2611
self.assertHandlerEqual(b'Repository.iter_revisions',
2612
smart_repo.SmartServerRepositoryIterRevisions)
2613
self.assertHandlerEqual(b'Repository.has_revision',
2614
smart_repo.SmartServerRequestHasRevision)
2615
self.assertHandlerEqual(b'Repository.insert_stream',
2616
smart_repo.SmartServerRepositoryInsertStream)
2617
self.assertHandlerEqual(b'Repository.insert_stream_locked',
2618
smart_repo.SmartServerRepositoryInsertStreamLocked)
2619
self.assertHandlerEqual(b'Repository.is_shared',
2620
smart_repo.SmartServerRepositoryIsShared)
2621
self.assertHandlerEqual(b'Repository.iter_files_bytes',
2622
smart_repo.SmartServerRepositoryIterFilesBytes)
2623
self.assertHandlerEqual(b'Repository.lock_write',
2624
smart_repo.SmartServerRepositoryLockWrite)
2625
self.assertHandlerEqual(b'Repository.make_working_trees',
2626
smart_repo.SmartServerRepositoryMakeWorkingTrees)
2627
self.assertHandlerEqual(b'Repository.pack',
2628
smart_repo.SmartServerRepositoryPack)
2629
self.assertHandlerEqual(b'Repository.reconcile',
2630
smart_repo.SmartServerRepositoryReconcile)
2631
self.assertHandlerEqual(b'Repository.tarball',
2632
smart_repo.SmartServerRepositoryTarball)
2633
self.assertHandlerEqual(b'Repository.unlock',
2634
smart_repo.SmartServerRepositoryUnlock)
2635
self.assertHandlerEqual(b'Repository.start_write_group',
2636
smart_repo.SmartServerRepositoryStartWriteGroup)
2637
self.assertHandlerEqual(b'Repository.check_write_group',
2638
smart_repo.SmartServerRepositoryCheckWriteGroup)
2639
self.assertHandlerEqual(b'Repository.commit_write_group',
2640
smart_repo.SmartServerRepositoryCommitWriteGroup)
2641
self.assertHandlerEqual(b'Repository.abort_write_group',
2642
smart_repo.SmartServerRepositoryAbortWriteGroup)
2643
self.assertHandlerEqual(b'VersionedFileRepository.get_serializer_format',
2644
smart_repo.SmartServerRepositoryGetSerializerFormat)
2645
self.assertHandlerEqual(b'VersionedFileRepository.get_inventories',
2646
smart_repo.SmartServerRepositoryGetInventories)
2647
self.assertHandlerEqual(b'Transport.is_readonly',
2648
smart_req.SmartServerIsReadonly)
2651
class SmartTCPServerHookTests(tests.TestCaseWithMemoryTransport):
2652
"""Tests for SmartTCPServer hooks."""
2655
super(SmartTCPServerHookTests, self).setUp()
2656
self.server = server.SmartTCPServer(self.get_transport())
2658
def test_run_server_started_hooks(self):
2659
"""Test the server started hooks get fired properly."""
2661
server.SmartTCPServer.hooks.install_named_hook('server_started',
2662
lambda backing_urls, url: started_calls.append(
2663
(backing_urls, url)),
2665
started_ex_calls = []
2666
server.SmartTCPServer.hooks.install_named_hook('server_started_ex',
2667
lambda backing_urls, url: started_ex_calls.append(
2668
(backing_urls, url)),
2670
self.server._sockname = ('example.com', 42)
2671
self.server.run_server_started_hooks()
2672
self.assertEqual(started_calls,
2673
[([self.get_transport().base], 'bzr://example.com:42/')])
2674
self.assertEqual(started_ex_calls,
2675
[([self.get_transport().base], self.server)])
2677
def test_run_server_started_hooks_ipv6(self):
2678
"""Test that socknames can contain 4-tuples."""
2679
self.server._sockname = ('::', 42, 0, 0)
2681
server.SmartTCPServer.hooks.install_named_hook('server_started',
2682
lambda backing_urls, url: started_calls.append(
2683
(backing_urls, url)),
2685
self.server.run_server_started_hooks()
2686
self.assertEqual(started_calls,
2687
[([self.get_transport().base], 'bzr://:::42/')])
2689
def test_run_server_stopped_hooks(self):
2690
"""Test the server stopped hooks."""
2691
self.server._sockname = ('example.com', 42)
2693
server.SmartTCPServer.hooks.install_named_hook('server_stopped',
2694
lambda backing_urls, url: stopped_calls.append(
2695
(backing_urls, url)),
2697
self.server.run_server_stopped_hooks()
2698
self.assertEqual(stopped_calls,
2699
[([self.get_transport().base], 'bzr://example.com:42/')])
2702
class TestSmartServerRepositoryPack(tests.TestCaseWithMemoryTransport):
2704
def test_pack(self):
2705
backing = self.get_transport()
2706
request = smart_repo.SmartServerRepositoryPack(backing)
2707
tree = self.make_branch_and_memory_tree('.')
2708
repo_token = tree.branch.repository.lock_write().repository_token
2710
self.assertIs(None, request.execute(b'', repo_token, False))
2713
smart_req.SuccessfulSmartServerResponse((b'ok', ), ),
2714
request.do_body(b''))
2717
class TestSmartServerRepositoryGetInventories(tests.TestCaseWithTransport):
2719
def _get_serialized_inventory_delta(self, repository, base_revid, revid):
2720
base_inv = repository.revision_tree(base_revid).root_inventory
2721
inv = repository.revision_tree(revid).root_inventory
2722
inv_delta = inv._make_delta(base_inv)
2723
serializer = inventory_delta.InventoryDeltaSerializer(True, False)
2724
return b"".join(serializer.delta_to_lines(base_revid, revid, inv_delta))
2726
def test_single(self):
2727
backing = self.get_transport()
2728
request = smart_repo.SmartServerRepositoryGetInventories(backing)
2729
t = self.make_branch_and_tree('.', format='2a')
2730
self.addCleanup(t.lock_write().unlock)
2731
self.build_tree_contents([("file", b"somecontents")])
2732
t.add(["file"], [b"thefileid"])
2733
t.commit(rev_id=b'somerev', message="add file")
2734
self.assertIs(None, request.execute(b'', b'unordered'))
2735
response = request.do_body(b"somerev\n")
2736
self.assertTrue(response.is_successful())
2737
self.assertEqual(response.args, (b"ok", ))
2738
stream = [('inventory-deltas', [
2739
versionedfile.FulltextContentFactory(b'somerev', None, None,
2740
self._get_serialized_inventory_delta(
2741
t.branch.repository, b'null:', b'somerev'))])]
2742
fmt = controldir.format_registry.get('2a')().repository_format
2744
b"".join(response.body_stream),
2745
b"".join(smart_repo._stream_to_byte_stream(stream, fmt)))
2747
def test_empty(self):
2748
backing = self.get_transport()
2749
request = smart_repo.SmartServerRepositoryGetInventories(backing)
2750
t = self.make_branch_and_tree('.', format='2a')
2751
self.addCleanup(t.lock_write().unlock)
2752
self.build_tree_contents([("file", b"somecontents")])
2753
t.add(["file"], [b"thefileid"])
2754
t.commit(rev_id=b'somerev', message="add file")
2755
self.assertIs(None, request.execute(b'', b'unordered'))
2756
response = request.do_body(b"")
2757
self.assertTrue(response.is_successful())
2758
self.assertEqual(response.args, (b"ok", ))
2759
self.assertEqual(b"".join(response.body_stream),
2760
b"Bazaar pack format 1 (introduced in 0.18)\nB54\n\nBazaar repository format 2a (needs bzr 1.16 or later)\nE")
2763
class TestSmartServerRepositoryGetStreamForMissingKeys(GetStreamTestBase):
2765
def test_missing(self):
2766
"""The search argument may be a 'ancestry-of' some heads'."""
2767
backing = self.get_transport()
2768
request = smart_repo.SmartServerRepositoryGetStreamForMissingKeys(
2770
repo, r1, r2 = self.make_two_commit_repo()
2771
request.execute(b'', repo._format.network_name())
2772
lines = b'inventories\t' + r1
2773
response = request.do_body(lines)
2774
self.assertEqual((b'ok',), response.args)
2775
stream_bytes = b''.join(response.body_stream)
2776
self.assertStartsWith(stream_bytes, b'Bazaar pack format 1')
2778
def test_unknown_format(self):
2779
"""The format may not be known by the remote server."""
2780
backing = self.get_transport()
2781
request = smart_repo.SmartServerRepositoryGetStreamForMissingKeys(
2783
repo, r1, r2 = self.make_two_commit_repo()
2784
request.execute(b'', b'yada yada yada')
2785
expected = smart_req.FailedSmartServerResponse(
2786
(b'UnknownFormat', b'repository', b'yada yada yada'))
2789
class TestSmartServerRepositoryRevisionArchive(tests.TestCaseWithTransport):
2791
backing = self.get_transport()
2792
request = smart_repo.SmartServerRepositoryRevisionArchive(backing)
2793
t = self.make_branch_and_tree('.')
2794
self.addCleanup(t.lock_write().unlock)
2795
self.build_tree_contents([("file", b"somecontents")])
2796
t.add(["file"], [b"thefileid"])
2797
t.commit(rev_id=b'somerev', message="add file")
2798
response = request.execute(b'', b"somerev", b"tar", b"foo.tar", b"foo")
2799
self.assertTrue(response.is_successful())
2800
self.assertEqual(response.args, (b"ok", ))
2801
b = BytesIO(b"".join(response.body_stream))
2802
with tarfile.open(mode='r', fileobj=b) as tf:
2803
self.assertEqual(['foo/file'], tf.getnames())
2806
class TestSmartServerRepositoryAnnotateFileRevision(tests.TestCaseWithTransport):
2809
backing = self.get_transport()
2810
request = smart_repo.SmartServerRepositoryAnnotateFileRevision(backing)
2811
t = self.make_branch_and_tree('.')
2812
self.addCleanup(t.lock_write().unlock)
2813
self.build_tree_contents([("file", b"somecontents\nmorecontents\n")])
2814
t.add(["file"], [b"thefileid"])
2815
t.commit(rev_id=b'somerev', message="add file")
2816
response = request.execute(b'', b"somerev", b"file")
2817
self.assertTrue(response.is_successful())
2818
self.assertEqual(response.args, (b"ok", ))
2820
[[b'somerev', b'somecontents\n'], [b'somerev', b'morecontents\n']],
2821
bencode.bdecode(response.body))