31
31
from bzrlib import (
33
branch as _mod_branch,
42
from bzrlib.smart import (
43
branch as smart_branch,
45
repository as smart_repo,
46
packrepository as smart_packrepo,
51
from bzrlib.tests import test_server
52
from bzrlib.transport import (
41
from bzrlib.branch import Branch, BranchReferenceFormat
42
import bzrlib.smart.branch
43
import bzrlib.smart.bzrdir, bzrlib.smart.bzrdir as smart_dir
44
import bzrlib.smart.packrepository
45
import bzrlib.smart.repository
46
from bzrlib.smart.request import (
47
FailedSmartServerResponse,
50
SuccessfulSmartServerResponse,
52
from bzrlib.tests import (
55
from bzrlib.transport import chroot, get_transport
58
58
def load_tests(standard_tests, module, loader):
59
59
"""Multiply tests version and protocol consistency."""
60
60
# FindRepository tests.
61
bzrdir_mod = bzrlib.smart.bzrdir
62
63
("find_repository", {
63
"_request_class": smart_dir.SmartServerRequestFindRepositoryV1}),
64
"_request_class":bzrdir_mod.SmartServerRequestFindRepositoryV1}),
64
65
("find_repositoryV2", {
65
"_request_class": smart_dir.SmartServerRequestFindRepositoryV2}),
66
"_request_class":bzrdir_mod.SmartServerRequestFindRepositoryV2}),
66
67
("find_repositoryV3", {
67
"_request_class": smart_dir.SmartServerRequestFindRepositoryV3}),
68
"_request_class":bzrdir_mod.SmartServerRequestFindRepositoryV3}),
69
to_adapt, result = tests.split_suite_by_re(standard_tests,
70
to_adapt, result = split_suite_by_re(standard_tests,
70
71
"TestSmartServerRequestFindRepository")
71
v2_only, v1_and_2 = tests.split_suite_by_re(to_adapt,
72
v2_only, v1_and_2 = split_suite_by_re(to_adapt,
73
74
tests.multiply_tests(v1_and_2, scenarios, result)
74
75
# The first scenario is only applicable to v1 protocols, it is deleted
135
135
class TestSmartServerResponse(tests.TestCase):
137
137
def test__eq__(self):
138
self.assertEqual(smart_req.SmartServerResponse(('ok', )),
139
smart_req.SmartServerResponse(('ok', )))
140
self.assertEqual(smart_req.SmartServerResponse(('ok', ), 'body'),
141
smart_req.SmartServerResponse(('ok', ), 'body'))
142
self.assertNotEqual(smart_req.SmartServerResponse(('ok', )),
143
smart_req.SmartServerResponse(('notok', )))
144
self.assertNotEqual(smart_req.SmartServerResponse(('ok', ), 'body'),
145
smart_req.SmartServerResponse(('ok', )))
138
self.assertEqual(SmartServerResponse(('ok', )),
139
SmartServerResponse(('ok', )))
140
self.assertEqual(SmartServerResponse(('ok', ), 'body'),
141
SmartServerResponse(('ok', ), 'body'))
142
self.assertNotEqual(SmartServerResponse(('ok', )),
143
SmartServerResponse(('notok', )))
144
self.assertNotEqual(SmartServerResponse(('ok', ), 'body'),
145
SmartServerResponse(('ok', )))
146
146
self.assertNotEqual(None,
147
smart_req.SmartServerResponse(('ok', )))
147
SmartServerResponse(('ok', )))
149
149
def test__str__(self):
150
150
"""SmartServerResponses can be stringified."""
151
151
self.assertEqual(
152
152
"<SuccessfulSmartServerResponse args=('args',) body='body'>",
153
str(smart_req.SuccessfulSmartServerResponse(('args',), 'body')))
153
str(SuccessfulSmartServerResponse(('args',), 'body')))
154
154
self.assertEqual(
155
155
"<FailedSmartServerResponse args=('args',) body='body'>",
156
str(smart_req.FailedSmartServerResponse(('args',), 'body')))
156
str(FailedSmartServerResponse(('args',), 'body')))
159
159
class TestSmartServerRequest(tests.TestCaseWithMemoryTransport):
161
161
def test_translate_client_path(self):
162
162
transport = self.get_transport()
163
request = smart_req.SmartServerRequest(transport, 'foo/')
163
request = SmartServerRequest(transport, 'foo/')
164
164
self.assertEqual('./', request.translate_client_path('foo/'))
165
165
self.assertRaises(
166
166
errors.InvalidURLJoin, request.translate_client_path, 'foo/..')
286
if (smart_dir.SmartServerRequestFindRepositoryV3 ==
273
if (smart.bzrdir.SmartServerRequestFindRepositoryV3 ==
287
274
self._request_class):
288
return smart_req.SuccessfulSmartServerResponse(
275
return SuccessfulSmartServerResponse(
289
276
('ok', '', rich_root, subtrees, external,
290
277
repo._format.network_name()))
291
elif (smart_dir.SmartServerRequestFindRepositoryV2 ==
278
elif (smart.bzrdir.SmartServerRequestFindRepositoryV2 ==
292
279
self._request_class):
293
280
# All tests so far are on formats, and for non-external
295
return smart_req.SuccessfulSmartServerResponse(
282
return SuccessfulSmartServerResponse(
296
283
('ok', '', rich_root, subtrees, external))
298
return smart_req.SuccessfulSmartServerResponse(
299
('ok', '', rich_root, subtrees))
285
return SuccessfulSmartServerResponse(('ok', '', rich_root, subtrees))
301
287
def test_shared_repository(self):
302
288
"""When there is a shared repository, we get 'ok', 'relpath-to-repo'."""
427
407
"""Initializing an extant directory should fail like the bzrdir api."""
428
408
backing = self.get_transport()
429
409
name = self.make_bzrdir('reference')._format.network_name()
430
request = smart_dir.SmartServerRequestBzrDirInitializeEx(backing)
410
request = smart.bzrdir.SmartServerRequestBzrDirInitializeEx(backing)
431
411
self.make_bzrdir('subdir')
432
412
self.assertRaises(errors.FileExists, request.execute, name, 'subdir',
433
413
'False', 'False', 'False', '', '', '', '', 'False')
436
class TestSmartServerRequestOpenBzrDir(tests.TestCaseWithMemoryTransport):
438
def test_no_directory(self):
439
backing = self.get_transport()
440
request = smart_dir.SmartServerRequestOpenBzrDir(backing)
441
self.assertEqual(smart_req.SmartServerResponse(('no', )),
442
request.execute('does-not-exist'))
444
def test_empty_directory(self):
445
backing = self.get_transport()
446
backing.mkdir('empty')
447
request = smart_dir.SmartServerRequestOpenBzrDir(backing)
448
self.assertEqual(smart_req.SmartServerResponse(('no', )),
449
request.execute('empty'))
451
def test_outside_root_client_path(self):
452
backing = self.get_transport()
453
request = smart_dir.SmartServerRequestOpenBzrDir(backing,
454
root_client_path='root')
455
self.assertEqual(smart_req.SmartServerResponse(('no', )),
456
request.execute('not-root'))
459
class TestSmartServerRequestOpenBzrDir_2_1(tests.TestCaseWithMemoryTransport):
461
def test_no_directory(self):
462
backing = self.get_transport()
463
request = smart_dir.SmartServerRequestOpenBzrDir_2_1(backing)
464
self.assertEqual(smart_req.SmartServerResponse(('no', )),
465
request.execute('does-not-exist'))
467
def test_empty_directory(self):
468
backing = self.get_transport()
469
backing.mkdir('empty')
470
request = smart_dir.SmartServerRequestOpenBzrDir_2_1(backing)
471
self.assertEqual(smart_req.SmartServerResponse(('no', )),
472
request.execute('empty'))
474
def test_present_without_workingtree(self):
475
backing = self.get_transport()
476
request = smart_dir.SmartServerRequestOpenBzrDir_2_1(backing)
477
self.make_bzrdir('.')
478
self.assertEqual(smart_req.SmartServerResponse(('yes', 'no')),
481
def test_outside_root_client_path(self):
482
backing = self.get_transport()
483
request = smart_dir.SmartServerRequestOpenBzrDir_2_1(backing,
484
root_client_path='root')
485
self.assertEqual(smart_req.SmartServerResponse(('no',)),
486
request.execute('not-root'))
489
class TestSmartServerRequestOpenBzrDir_2_1_disk(TestCaseWithChrootedTransport):
491
def test_present_with_workingtree(self):
492
self.vfs_transport_factory = test_server.LocalURLServer
493
backing = self.get_transport()
494
request = smart_dir.SmartServerRequestOpenBzrDir_2_1(backing)
495
bd = self.make_bzrdir('.')
496
bd.create_repository()
498
bd.create_workingtree()
499
self.assertEqual(smart_req.SmartServerResponse(('yes', 'yes')),
503
416
class TestSmartServerRequestOpenBranch(TestCaseWithChrootedTransport):
505
418
def test_no_branch(self):
506
419
"""When there is no branch, ('nobranch', ) is returned."""
507
420
backing = self.get_transport()
508
request = smart_dir.SmartServerRequestOpenBranch(backing)
421
request = smart.bzrdir.SmartServerRequestOpenBranch(backing)
509
422
self.make_bzrdir('.')
510
self.assertEqual(smart_req.SmartServerResponse(('nobranch', )),
423
self.assertEqual(SmartServerResponse(('nobranch', )),
511
424
request.execute(''))
513
426
def test_branch(self):
514
427
"""When there is a branch, 'ok' is returned."""
515
428
backing = self.get_transport()
516
request = smart_dir.SmartServerRequestOpenBranch(backing)
429
request = smart.bzrdir.SmartServerRequestOpenBranch(backing)
517
430
self.make_branch('.')
518
self.assertEqual(smart_req.SmartServerResponse(('ok', '')),
431
self.assertEqual(SmartServerResponse(('ok', '')),
519
432
request.execute(''))
521
434
def test_branch_reference(self):
522
435
"""When there is a branch reference, the reference URL is returned."""
523
self.vfs_transport_factory = test_server.LocalURLServer
524
436
backing = self.get_transport()
525
request = smart_dir.SmartServerRequestOpenBranch(backing)
437
request = smart.bzrdir.SmartServerRequestOpenBranch(backing)
526
438
branch = self.make_branch('branch')
527
439
checkout = branch.create_checkout('reference',lightweight=True)
528
reference_url = _mod_branch.BranchReferenceFormat().get_reference(
440
reference_url = BranchReferenceFormat().get_reference(checkout.bzrdir)
530
441
self.assertFileEqual(reference_url, 'reference/.bzr/branch/location')
531
self.assertEqual(smart_req.SmartServerResponse(('ok', reference_url)),
442
self.assertEqual(SmartServerResponse(('ok', reference_url)),
532
443
request.execute('reference'))
534
def test_notification_on_branch_from_repository(self):
535
"""When there is a repository, the error should return details."""
536
backing = self.get_transport()
537
request = smart_dir.SmartServerRequestOpenBranch(backing)
538
repo = self.make_repository('.')
539
self.assertEqual(smart_req.SmartServerResponse(('nobranch',)),
543
446
class TestSmartServerRequestOpenBranchV2(TestCaseWithChrootedTransport):
546
449
"""When there is no branch, ('nobranch', ) is returned."""
547
450
backing = self.get_transport()
548
451
self.make_bzrdir('.')
549
request = smart_dir.SmartServerRequestOpenBranchV2(backing)
550
self.assertEqual(smart_req.SmartServerResponse(('nobranch', )),
553
def test_branch(self):
554
"""When there is a branch, 'ok' is returned."""
555
backing = self.get_transport()
556
expected = self.make_branch('.')._format.network_name()
557
request = smart_dir.SmartServerRequestOpenBranchV2(backing)
558
self.assertEqual(smart_req.SuccessfulSmartServerResponse(
559
('branch', expected)),
562
def test_branch_reference(self):
563
"""When there is a branch reference, the reference URL is returned."""
564
self.vfs_transport_factory = test_server.LocalURLServer
565
backing = self.get_transport()
566
request = smart_dir.SmartServerRequestOpenBranchV2(backing)
567
branch = self.make_branch('branch')
568
checkout = branch.create_checkout('reference',lightweight=True)
569
reference_url = _mod_branch.BranchReferenceFormat().get_reference(
571
self.assertFileEqual(reference_url, 'reference/.bzr/branch/location')
572
self.assertEqual(smart_req.SuccessfulSmartServerResponse(
573
('ref', reference_url)),
574
request.execute('reference'))
576
def test_stacked_branch(self):
577
"""Opening a stacked branch does not open the stacked-on branch."""
578
trunk = self.make_branch('trunk')
579
feature = self.make_branch('feature')
580
feature.set_stacked_on_url(trunk.base)
582
_mod_branch.Branch.hooks.install_named_hook(
583
'open', opened_branches.append, None)
584
backing = self.get_transport()
585
request = smart_dir.SmartServerRequestOpenBranchV2(backing)
588
response = request.execute('feature')
590
request.teardown_jail()
591
expected_format = feature._format.network_name()
592
self.assertEqual(smart_req.SuccessfulSmartServerResponse(
593
('branch', expected_format)),
595
self.assertLength(1, opened_branches)
597
def test_notification_on_branch_from_repository(self):
598
"""When there is a repository, the error should return details."""
599
backing = self.get_transport()
600
request = smart_dir.SmartServerRequestOpenBranchV2(backing)
601
repo = self.make_repository('.')
602
self.assertEqual(smart_req.SmartServerResponse(('nobranch',)),
606
class TestSmartServerRequestOpenBranchV3(TestCaseWithChrootedTransport):
608
def test_no_branch(self):
609
"""When there is no branch, ('nobranch', ) is returned."""
610
backing = self.get_transport()
611
self.make_bzrdir('.')
612
request = smart_dir.SmartServerRequestOpenBranchV3(backing)
613
self.assertEqual(smart_req.SmartServerResponse(('nobranch',)),
616
def test_branch(self):
617
"""When there is a branch, 'ok' is returned."""
618
backing = self.get_transport()
619
expected = self.make_branch('.')._format.network_name()
620
request = smart_dir.SmartServerRequestOpenBranchV3(backing)
621
self.assertEqual(smart_req.SuccessfulSmartServerResponse(
622
('branch', expected)),
625
def test_branch_reference(self):
626
"""When there is a branch reference, the reference URL is returned."""
627
self.vfs_transport_factory = test_server.LocalURLServer
628
backing = self.get_transport()
629
request = smart_dir.SmartServerRequestOpenBranchV3(backing)
630
branch = self.make_branch('branch')
631
checkout = branch.create_checkout('reference',lightweight=True)
632
reference_url = _mod_branch.BranchReferenceFormat().get_reference(
634
self.assertFileEqual(reference_url, 'reference/.bzr/branch/location')
635
self.assertEqual(smart_req.SuccessfulSmartServerResponse(
636
('ref', reference_url)),
637
request.execute('reference'))
639
def test_stacked_branch(self):
640
"""Opening a stacked branch does not open the stacked-on branch."""
641
trunk = self.make_branch('trunk')
642
feature = self.make_branch('feature')
643
feature.set_stacked_on_url(trunk.base)
645
_mod_branch.Branch.hooks.install_named_hook(
646
'open', opened_branches.append, None)
647
backing = self.get_transport()
648
request = smart_dir.SmartServerRequestOpenBranchV3(backing)
651
response = request.execute('feature')
653
request.teardown_jail()
654
expected_format = feature._format.network_name()
655
self.assertEqual(smart_req.SuccessfulSmartServerResponse(
656
('branch', expected_format)),
658
self.assertLength(1, opened_branches)
660
def test_notification_on_branch_from_repository(self):
661
"""When there is a repository, the error should return details."""
662
backing = self.get_transport()
663
request = smart_dir.SmartServerRequestOpenBranchV3(backing)
664
repo = self.make_repository('.')
665
self.assertEqual(smart_req.SmartServerResponse(
666
('nobranch', 'location is a repository')),
452
request = smart.bzrdir.SmartServerRequestOpenBranchV2(backing)
453
self.assertEqual(SmartServerResponse(('nobranch', )),
456
def test_branch(self):
457
"""When there is a branch, 'ok' is returned."""
458
backing = self.get_transport()
459
expected = self.make_branch('.')._format.network_name()
460
request = smart.bzrdir.SmartServerRequestOpenBranchV2(backing)
461
self.assertEqual(SuccessfulSmartServerResponse(('branch', expected)),
464
def test_branch_reference(self):
465
"""When there is a branch reference, the reference URL is returned."""
466
backing = self.get_transport()
467
request = smart.bzrdir.SmartServerRequestOpenBranchV2(backing)
468
branch = self.make_branch('branch')
469
checkout = branch.create_checkout('reference',lightweight=True)
470
reference_url = BranchReferenceFormat().get_reference(checkout.bzrdir)
471
self.assertFileEqual(reference_url, 'reference/.bzr/branch/location')
472
self.assertEqual(SuccessfulSmartServerResponse(('ref', reference_url)),
473
request.execute('reference'))
475
def test_stacked_branch(self):
476
"""Opening a stacked branch does not open the stacked-on branch."""
477
trunk = self.make_branch('trunk')
478
feature = self.make_branch('feature')
479
feature.set_stacked_on_url(trunk.base)
481
Branch.hooks.install_named_hook('open', opened_branches.append, None)
482
backing = self.get_transport()
483
request = smart.bzrdir.SmartServerRequestOpenBranchV2(backing)
486
response = request.execute('feature')
488
request.teardown_jail()
489
expected_format = feature._format.network_name()
491
SuccessfulSmartServerResponse(('branch', expected_format)),
493
self.assertLength(1, opened_branches)
670
496
class TestSmartServerRequestRevisionHistory(tests.TestCaseWithMemoryTransport):
705
531
def test_branch_reference(self):
706
532
"""When there is a branch reference, NotBranchError is raised."""
707
533
backing = self.get_transport()
708
request = smart_branch.SmartServerBranchRequest(backing)
534
request = smart.branch.SmartServerBranchRequest(backing)
709
535
branch = self.make_branch('branch')
710
536
checkout = branch.create_checkout('reference',lightweight=True)
711
537
self.assertRaises(errors.NotBranchError,
712
538
request.execute, 'checkout')
715
class TestSmartServerBranchRequestLastRevisionInfo(
716
tests.TestCaseWithMemoryTransport):
541
class TestSmartServerBranchRequestLastRevisionInfo(tests.TestCaseWithMemoryTransport):
718
543
def test_empty(self):
719
544
"""For an empty branch, the result is ('ok', '0', 'null:')."""
720
545
backing = self.get_transport()
721
request = smart_branch.SmartServerBranchRequestLastRevisionInfo(backing)
546
request = smart.branch.SmartServerBranchRequestLastRevisionInfo(backing)
722
547
self.make_branch('.')
723
self.assertEqual(smart_req.SmartServerResponse(('ok', '0', 'null:')),
548
self.assertEqual(SmartServerResponse(('ok', '0', 'null:')),
724
549
request.execute(''))
726
551
def test_not_empty(self):
727
552
"""For a non-empty branch, the result is ('ok', 'revno', 'revid')."""
728
553
backing = self.get_transport()
729
request = smart_branch.SmartServerBranchRequestLastRevisionInfo(backing)
554
request = smart.branch.SmartServerBranchRequestLastRevisionInfo(backing)
730
555
tree = self.make_branch_and_memory_tree('.')
731
556
tree.lock_write()
778
602
def test_value_name(self):
779
603
branch = self.make_branch('.')
780
request = smart_branch.SmartServerBranchRequestSetConfigOption(
604
request = smart.branch.SmartServerBranchRequestSetConfigOption(
781
605
branch.bzrdir.root_transport)
782
606
branch_token, repo_token = self.get_lock_tokens(branch)
783
607
config = branch._get_config()
784
608
result = request.execute('', branch_token, repo_token, 'bar', 'foo',
786
self.assertEqual(smart_req.SuccessfulSmartServerResponse(()), result)
610
self.assertEqual(SuccessfulSmartServerResponse(()), result)
787
611
self.assertEqual('bar', config.get_option('foo'))
791
615
def test_value_name_section(self):
792
616
branch = self.make_branch('.')
793
request = smart_branch.SmartServerBranchRequestSetConfigOption(
617
request = smart.branch.SmartServerBranchRequestSetConfigOption(
794
618
branch.bzrdir.root_transport)
795
619
branch_token, repo_token = self.get_lock_tokens(branch)
796
620
config = branch._get_config()
797
621
result = request.execute('', branch_token, repo_token, 'bar', 'foo',
799
self.assertEqual(smart_req.SuccessfulSmartServerResponse(()), result)
623
self.assertEqual(SuccessfulSmartServerResponse(()), result)
800
624
self.assertEqual('bar', config.get_option('foo', 'gam'))
805
class TestSmartServerBranchRequestSetConfigOptionDict(TestLockedBranch):
808
TestLockedBranch.setUp(self)
809
# A dict with non-ascii keys and values to exercise unicode
811
self.encoded_value_dict = (
812
'd5:ascii1:a11:unicode \xe2\x8c\x9a3:\xe2\x80\xbde')
814
'ascii': 'a', u'unicode \N{WATCH}': u'\N{INTERROBANG}'}
816
def test_value_name(self):
817
branch = self.make_branch('.')
818
request = smart_branch.SmartServerBranchRequestSetConfigOptionDict(
819
branch.bzrdir.root_transport)
820
branch_token, repo_token = self.get_lock_tokens(branch)
821
config = branch._get_config()
822
result = request.execute('', branch_token, repo_token,
823
self.encoded_value_dict, 'foo', '')
824
self.assertEqual(smart_req.SuccessfulSmartServerResponse(()), result)
825
self.assertEqual(self.value_dict, config.get_option('foo'))
829
def test_value_name_section(self):
830
branch = self.make_branch('.')
831
request = smart_branch.SmartServerBranchRequestSetConfigOptionDict(
832
branch.bzrdir.root_transport)
833
branch_token, repo_token = self.get_lock_tokens(branch)
834
config = branch._get_config()
835
result = request.execute('', branch_token, repo_token,
836
self.encoded_value_dict, 'foo', 'gam')
837
self.assertEqual(smart_req.SuccessfulSmartServerResponse(()), result)
838
self.assertEqual(self.value_dict, config.get_option('foo', 'gam'))
843
629
class TestSmartServerBranchRequestSetTagsBytes(TestLockedBranch):
844
630
# Only called when the branch format and tags match [yay factory
845
631
# methods] so only need to test straight forward cases.
1097
882
def test_get_parent_none(self):
1098
883
base_branch = self.make_branch('base')
1099
request = smart_branch.SmartServerBranchGetParent(self.get_transport())
884
request = smart.branch.SmartServerBranchGetParent(self.get_transport())
1100
885
response = request.execute('base')
1101
886
self.assertEquals(
1102
smart_req.SuccessfulSmartServerResponse(('',)), response)
887
SuccessfulSmartServerResponse(('',)), response)
1104
889
def test_get_parent_something(self):
1105
890
base_branch = self.make_branch('base')
1106
891
base_branch.set_parent(self.get_url('foo'))
1107
request = smart_branch.SmartServerBranchGetParent(self.get_transport())
892
request = smart.branch.SmartServerBranchGetParent(self.get_transport())
1108
893
response = request.execute('base')
1109
894
self.assertEquals(
1110
smart_req.SuccessfulSmartServerResponse(("../foo",)),
895
SuccessfulSmartServerResponse(("../foo",)),
1114
class TestSmartServerBranchRequestSetParent(TestLockedBranch):
899
class TestSmartServerBranchRequestSetParent(tests.TestCaseWithMemoryTransport):
1116
901
def test_set_parent_none(self):
1117
902
branch = self.make_branch('base', format="1.9")
1118
903
branch.lock_write()
1119
904
branch._set_parent_location('foo')
1121
request = smart_branch.SmartServerBranchRequestSetParentLocation(
906
request = smart.branch.SmartServerBranchRequestSetParentLocation(
1122
907
self.get_transport())
1123
branch_token, repo_token = self.get_lock_tokens(branch)
908
branch_token = branch.lock_write()
909
repo_token = branch.repository.lock_write()
1125
911
response = request.execute('base', branch_token, repo_token, '')
913
branch.repository.unlock()
1128
self.assertEqual(smart_req.SuccessfulSmartServerResponse(()), response)
915
self.assertEqual(SuccessfulSmartServerResponse(()), response)
1129
916
self.assertEqual(None, branch.get_parent())
1131
918
def test_set_parent_something(self):
1132
919
branch = self.make_branch('base', format="1.9")
1133
request = smart_branch.SmartServerBranchRequestSetParentLocation(
920
request = smart.branch.SmartServerBranchRequestSetParentLocation(
1134
921
self.get_transport())
1135
branch_token, repo_token = self.get_lock_tokens(branch)
922
branch_token = branch.lock_write()
923
repo_token = branch.repository.lock_write()
1137
925
response = request.execute('base', branch_token, repo_token,
928
branch.repository.unlock()
1141
self.assertEqual(smart_req.SuccessfulSmartServerResponse(()), response)
930
self.assertEqual(SuccessfulSmartServerResponse(()), response)
1142
931
self.assertEqual('http://bar/', branch.get_parent())
1145
class TestSmartServerBranchRequestGetTagsBytes(
1146
tests.TestCaseWithMemoryTransport):
934
class TestSmartServerBranchRequestGetTagsBytes(tests.TestCaseWithMemoryTransport):
1147
935
# Only called when the branch format and tags match [yay factory
1148
936
# methods] so only need to test straight forward cases.
1150
938
def test_get_bytes(self):
1151
939
base_branch = self.make_branch('base')
1152
request = smart_branch.SmartServerBranchGetTagsBytes(
940
request = smart.branch.SmartServerBranchGetTagsBytes(
1153
941
self.get_transport())
1154
942
response = request.execute('base')
1155
943
self.assertEquals(
1156
smart_req.SuccessfulSmartServerResponse(('',)), response)
944
SuccessfulSmartServerResponse(('',)), response)
1159
947
class TestSmartServerBranchRequestGetStackedOnURL(tests.TestCaseWithMemoryTransport):
1163
951
stacked_branch = self.make_branch('stacked', format='1.6')
1164
952
# typically should be relative
1165
953
stacked_branch.set_stacked_on_url('../base')
1166
request = smart_branch.SmartServerBranchRequestGetStackedOnURL(
954
request = smart.branch.SmartServerBranchRequestGetStackedOnURL(
1167
955
self.get_transport())
1168
956
response = request.execute('stacked')
1169
957
self.assertEquals(
1170
smart_req.SmartServerResponse(('ok', '../base')),
958
SmartServerResponse(('ok', '../base')),
1174
class TestSmartServerBranchRequestLockWrite(TestLockedBranch):
962
class TestSmartServerBranchRequestLockWrite(tests.TestCaseWithMemoryTransport):
1176
964
def setUp(self):
1177
965
tests.TestCaseWithMemoryTransport.setUp(self)
1179
967
def test_lock_write_on_unlocked_branch(self):
1180
968
backing = self.get_transport()
1181
request = smart_branch.SmartServerBranchRequestLockWrite(backing)
969
request = smart.branch.SmartServerBranchRequestLockWrite(backing)
1182
970
branch = self.make_branch('.', format='knit')
1183
971
repository = branch.repository
1184
972
response = request.execute('')
1185
973
branch_nonce = branch.control_files._lock.peek().get('nonce')
1186
974
repository_nonce = repository.control_files._lock.peek().get('nonce')
1187
self.assertEqual(smart_req.SmartServerResponse(
1188
('ok', branch_nonce, repository_nonce)),
976
SmartServerResponse(('ok', branch_nonce, repository_nonce)),
1190
978
# The branch (and associated repository) is now locked. Verify that
1191
979
# with a new branch object.
1192
980
new_branch = repository.bzrdir.open_branch()
1193
981
self.assertRaises(errors.LockContention, new_branch.lock_write)
1195
request = smart_branch.SmartServerBranchRequestUnlock(backing)
983
request = smart.branch.SmartServerBranchRequestUnlock(backing)
1196
984
response = request.execute('', branch_nonce, repository_nonce)
1198
986
def test_lock_write_on_locked_branch(self):
1199
987
backing = self.get_transport()
1200
request = smart_branch.SmartServerBranchRequestLockWrite(backing)
988
request = smart.branch.SmartServerBranchRequestLockWrite(backing)
1201
989
branch = self.make_branch('.')
1202
branch_token = branch.lock_write().branch_token
990
branch_token = branch.lock_write()
1203
991
branch.leave_lock_in_place()
1205
993
response = request.execute('')
1206
994
self.assertEqual(
1207
smart_req.SmartServerResponse(('LockContention',)), response)
995
SmartServerResponse(('LockContention',)), response)
1209
997
branch.lock_write(branch_token)
1210
998
branch.dont_leave_lock_in_place()
1308
1101
def test_unlock_on_unlocked_branch_unlocked_repo(self):
1309
1102
backing = self.get_transport()
1310
request = smart_branch.SmartServerBranchRequestUnlock(backing)
1103
request = smart.branch.SmartServerBranchRequestUnlock(backing)
1311
1104
branch = self.make_branch('.', format='knit')
1312
1105
response = request.execute(
1313
1106
'', 'branch token', 'repo token')
1314
1107
self.assertEqual(
1315
smart_req.SmartServerResponse(('TokenMismatch',)), response)
1108
SmartServerResponse(('TokenMismatch',)), response)
1317
1110
def test_unlock_on_unlocked_branch_locked_repo(self):
1318
1111
backing = self.get_transport()
1319
request = smart_branch.SmartServerBranchRequestUnlock(backing)
1112
request = smart.branch.SmartServerBranchRequestUnlock(backing)
1320
1113
branch = self.make_branch('.', format='knit')
1321
1114
# Lock the repository.
1322
repo_token = branch.repository.lock_write().repository_token
1115
repo_token = branch.repository.lock_write()
1323
1116
branch.repository.leave_lock_in_place()
1324
1117
branch.repository.unlock()
1325
1118
# Issue branch lock_write request on the unlocked branch (with locked
1327
response = request.execute('', 'branch token', repo_token)
1120
response = request.execute(
1121
'', 'branch token', repo_token)
1328
1122
self.assertEqual(
1329
smart_req.SmartServerResponse(('TokenMismatch',)), response)
1123
SmartServerResponse(('TokenMismatch',)), response)
1331
1125
branch.repository.lock_write(repo_token)
1332
1126
branch.repository.dont_leave_lock_in_place()
1354
1148
def test_trivial_bzipped(self):
1355
1149
# This tests that the wire encoding is actually bzipped
1356
1150
backing = self.get_transport()
1357
request = smart_repo.SmartServerRepositoryGetParentMap(backing)
1151
request = smart.repository.SmartServerRepositoryGetParentMap(backing)
1358
1152
tree = self.make_branch_and_memory_tree('.')
1360
1154
self.assertEqual(None,
1361
1155
request.execute('', 'missing-id'))
1362
1156
# Note that it returns a body that is bzipped.
1363
1157
self.assertEqual(
1364
smart_req.SuccessfulSmartServerResponse(('ok', ), bz2.compress('')),
1158
SuccessfulSmartServerResponse(('ok', ), bz2.compress('')),
1365
1159
request.do_body('\n\n0\n'))
1367
1161
def test_trivial_include_missing(self):
1368
1162
backing = self.get_transport()
1369
request = smart_repo.SmartServerRepositoryGetParentMap(backing)
1163
request = smart.repository.SmartServerRepositoryGetParentMap(backing)
1370
1164
tree = self.make_branch_and_memory_tree('.')
1372
1166
self.assertEqual(None,
1373
1167
request.execute('', 'missing-id', 'include-missing:'))
1374
1168
self.assertEqual(
1375
smart_req.SuccessfulSmartServerResponse(('ok', ),
1169
SuccessfulSmartServerResponse(('ok', ),
1376
1170
bz2.compress('missing:missing-id')),
1377
1171
request.do_body('\n\n0\n'))
1380
class TestSmartServerRepositoryGetRevisionGraph(
1381
tests.TestCaseWithMemoryTransport):
1174
class TestSmartServerRepositoryGetRevisionGraph(tests.TestCaseWithMemoryTransport):
1383
1176
def test_none_argument(self):
1384
1177
backing = self.get_transport()
1385
request = smart_repo.SmartServerRepositoryGetRevisionGraph(backing)
1178
request = smart.repository.SmartServerRepositoryGetRevisionGraph(backing)
1386
1179
tree = self.make_branch_and_memory_tree('.')
1387
1180
tree.lock_write()
1443
1235
tree.commit('2nd commit', rev_id=rev2_id_utf8)
1446
self.assertEqual(smart_req.SmartServerResponse(('ok', rev1_id_utf8)),
1238
self.assertEqual(SmartServerResponse(('ok', rev1_id_utf8)),
1447
1239
request.execute('', 1, (2, rev2_id_utf8)))
1449
1241
def test_known_revid_missing(self):
1450
1242
backing = self.get_transport()
1451
request = smart_repo.SmartServerRepositoryGetRevIdForRevno(backing)
1243
request = smart.repository.SmartServerRepositoryGetRevIdForRevno(backing)
1452
1244
repo = self.make_repository('.')
1453
1245
self.assertEqual(
1454
smart_req.FailedSmartServerResponse(('nosuchrevision', 'ghost')),
1246
FailedSmartServerResponse(('nosuchrevision', 'ghost')),
1455
1247
request.execute('', 1, (2, 'ghost')))
1457
1249
def test_history_incomplete(self):
1458
1250
backing = self.get_transport()
1459
request = smart_repo.SmartServerRepositoryGetRevIdForRevno(backing)
1251
request = smart.repository.SmartServerRepositoryGetRevIdForRevno(backing)
1460
1252
parent = self.make_branch_and_memory_tree('parent', format='1.9')
1461
1253
parent.lock_write()
1462
1254
parent.add([''], ['TREE_ROOT'])
1621
1413
def test_lock_write_on_unlocked_repo(self):
1622
1414
backing = self.get_transport()
1623
request = smart_repo.SmartServerRepositoryLockWrite(backing)
1415
request = smart.repository.SmartServerRepositoryLockWrite(backing)
1624
1416
repository = self.make_repository('.', format='knit')
1625
1417
response = request.execute('')
1626
1418
nonce = repository.control_files._lock.peek().get('nonce')
1627
self.assertEqual(smart_req.SmartServerResponse(('ok', nonce)), response)
1419
self.assertEqual(SmartServerResponse(('ok', nonce)), response)
1628
1420
# The repository is now locked. Verify that with a new repository
1630
1422
new_repo = repository.bzrdir.open_repository()
1631
1423
self.assertRaises(errors.LockContention, new_repo.lock_write)
1633
request = smart_repo.SmartServerRepositoryUnlock(backing)
1425
request = smart.repository.SmartServerRepositoryUnlock(backing)
1634
1426
response = request.execute('', nonce)
1636
1428
def test_lock_write_on_locked_repo(self):
1637
1429
backing = self.get_transport()
1638
request = smart_repo.SmartServerRepositoryLockWrite(backing)
1430
request = smart.repository.SmartServerRepositoryLockWrite(backing)
1639
1431
repository = self.make_repository('.', format='knit')
1640
repo_token = repository.lock_write().repository_token
1432
repo_token = repository.lock_write()
1641
1433
repository.leave_lock_in_place()
1642
1434
repository.unlock()
1643
1435
response = request.execute('')
1644
1436
self.assertEqual(
1645
smart_req.SmartServerResponse(('LockContention',)), response)
1437
SmartServerResponse(('LockContention',)), response)
1647
1439
repository.lock_write(repo_token)
1648
1440
repository.dont_leave_lock_in_place()
1669
1461
def test_insert_stream_empty(self):
1670
1462
backing = self.get_transport()
1671
request = smart_repo.SmartServerRepositoryInsertStream(backing)
1463
request = smart.repository.SmartServerRepositoryInsertStream(backing)
1672
1464
repository = self.make_repository('.')
1673
1465
response = request.execute('', '')
1674
1466
self.assertEqual(None, response)
1675
1467
response = request.do_chunk(self.make_empty_byte_stream(repository))
1676
1468
self.assertEqual(None, response)
1677
1469
response = request.do_end()
1678
self.assertEqual(smart_req.SmartServerResponse(('ok', )), response)
1470
self.assertEqual(SmartServerResponse(('ok', )), response)
1681
1473
class TestSmartServerRepositoryInsertStreamLocked(TestInsertStreamBase):
1683
1475
def test_insert_stream_empty(self):
1684
1476
backing = self.get_transport()
1685
request = smart_repo.SmartServerRepositoryInsertStreamLocked(
1477
request = smart.repository.SmartServerRepositoryInsertStreamLocked(
1687
1479
repository = self.make_repository('.', format='knit')
1688
lock_token = repository.lock_write().repository_token
1480
lock_token = repository.lock_write()
1689
1481
response = request.execute('', '', lock_token)
1690
1482
self.assertEqual(None, response)
1691
1483
response = request.do_chunk(self.make_empty_byte_stream(repository))
1692
1484
self.assertEqual(None, response)
1693
1485
response = request.do_end()
1694
self.assertEqual(smart_req.SmartServerResponse(('ok', )), response)
1486
self.assertEqual(SmartServerResponse(('ok', )), response)
1695
1487
repository.unlock()
1697
1489
def test_insert_stream_with_wrong_lock_token(self):
1698
1490
backing = self.get_transport()
1699
request = smart_repo.SmartServerRepositoryInsertStreamLocked(
1491
request = smart.repository.SmartServerRepositoryInsertStreamLocked(
1701
1493
repository = self.make_repository('.', format='knit')
1702
lock_token = repository.lock_write().repository_token
1494
lock_token = repository.lock_write()
1703
1495
self.assertRaises(
1704
1496
errors.TokenMismatch, request.execute, '', '', 'wrong-token')
1705
1497
repository.unlock()
1729
1521
def test_unlock_on_unlocked_repo(self):
1730
1522
backing = self.get_transport()
1731
request = smart_repo.SmartServerRepositoryUnlock(backing)
1523
request = smart.repository.SmartServerRepositoryUnlock(backing)
1732
1524
repository = self.make_repository('.', format='knit')
1733
1525
response = request.execute('', 'some token')
1734
1526
self.assertEqual(
1735
smart_req.SmartServerResponse(('TokenMismatch',)), response)
1527
SmartServerResponse(('TokenMismatch',)), response)
1738
1530
class TestSmartServerIsReadonly(tests.TestCaseWithMemoryTransport):
1740
1532
def test_is_readonly_no(self):
1741
1533
backing = self.get_transport()
1742
request = smart_req.SmartServerIsReadonly(backing)
1534
request = smart.request.SmartServerIsReadonly(backing)
1743
1535
response = request.execute()
1744
1536
self.assertEqual(
1745
smart_req.SmartServerResponse(('no',)), response)
1537
SmartServerResponse(('no',)), response)
1747
1539
def test_is_readonly_yes(self):
1748
1540
backing = self.get_readonly_transport()
1749
request = smart_req.SmartServerIsReadonly(backing)
1541
request = smart.request.SmartServerIsReadonly(backing)
1750
1542
response = request.execute()
1751
1543
self.assertEqual(
1752
smart_req.SmartServerResponse(('yes',)), response)
1755
class TestSmartServerRepositorySetMakeWorkingTrees(
1756
tests.TestCaseWithMemoryTransport):
1544
SmartServerResponse(('yes',)), response)
1547
class TestSmartServerRepositorySetMakeWorkingTrees(tests.TestCaseWithMemoryTransport):
1758
1549
def test_set_false(self):
1759
1550
backing = self.get_transport()
1760
1551
repo = self.make_repository('.', shared=True)
1761
1552
repo.set_make_working_trees(True)
1762
request_class = smart_repo.SmartServerRepositorySetMakeWorkingTrees
1553
request_class = smart.repository.SmartServerRepositorySetMakeWorkingTrees
1763
1554
request = request_class(backing)
1764
self.assertEqual(smart_req.SuccessfulSmartServerResponse(('ok',)),
1555
self.assertEqual(SuccessfulSmartServerResponse(('ok',)),
1765
1556
request.execute('', 'False'))
1766
1557
repo = repo.bzrdir.open_repository()
1767
1558
self.assertFalse(repo.make_working_trees())
1849
1627
"""All registered request_handlers can be found."""
1850
1628
# If there's a typo in a register_lazy call, this loop will fail with
1851
1629
# an AttributeError.
1852
for key, item in smart_req.request_handlers.iteritems():
1630
for key, item in smart.request.request_handlers.iteritems():
1855
1633
def assertHandlerEqual(self, verb, handler):
1856
self.assertEqual(smart_req.request_handlers.get(verb), handler)
1634
self.assertEqual(smart.request.request_handlers.get(verb), handler)
1858
1636
def test_registered_methods(self):
1859
1637
"""Test that known methods are registered to the correct object."""
1860
1638
self.assertHandlerEqual('Branch.get_config_file',
1861
smart_branch.SmartServerBranchGetConfigFile)
1639
smart.branch.SmartServerBranchGetConfigFile)
1862
1640
self.assertHandlerEqual('Branch.get_parent',
1863
smart_branch.SmartServerBranchGetParent)
1641
smart.branch.SmartServerBranchGetParent)
1864
1642
self.assertHandlerEqual('Branch.get_tags_bytes',
1865
smart_branch.SmartServerBranchGetTagsBytes)
1643
smart.branch.SmartServerBranchGetTagsBytes)
1866
1644
self.assertHandlerEqual('Branch.lock_write',
1867
smart_branch.SmartServerBranchRequestLockWrite)
1645
smart.branch.SmartServerBranchRequestLockWrite)
1868
1646
self.assertHandlerEqual('Branch.last_revision_info',
1869
smart_branch.SmartServerBranchRequestLastRevisionInfo)
1647
smart.branch.SmartServerBranchRequestLastRevisionInfo)
1870
1648
self.assertHandlerEqual('Branch.revision_history',
1871
smart_branch.SmartServerRequestRevisionHistory)
1649
smart.branch.SmartServerRequestRevisionHistory)
1872
1650
self.assertHandlerEqual('Branch.set_config_option',
1873
smart_branch.SmartServerBranchRequestSetConfigOption)
1651
smart.branch.SmartServerBranchRequestSetConfigOption)
1874
1652
self.assertHandlerEqual('Branch.set_last_revision',
1875
smart_branch.SmartServerBranchRequestSetLastRevision)
1653
smart.branch.SmartServerBranchRequestSetLastRevision)
1876
1654
self.assertHandlerEqual('Branch.set_last_revision_info',
1877
smart_branch.SmartServerBranchRequestSetLastRevisionInfo)
1655
smart.branch.SmartServerBranchRequestSetLastRevisionInfo)
1878
1656
self.assertHandlerEqual('Branch.set_last_revision_ex',
1879
smart_branch.SmartServerBranchRequestSetLastRevisionEx)
1657
smart.branch.SmartServerBranchRequestSetLastRevisionEx)
1880
1658
self.assertHandlerEqual('Branch.set_parent_location',
1881
smart_branch.SmartServerBranchRequestSetParentLocation)
1659
smart.branch.SmartServerBranchRequestSetParentLocation)
1882
1660
self.assertHandlerEqual('Branch.unlock',
1883
smart_branch.SmartServerBranchRequestUnlock)
1661
smart.branch.SmartServerBranchRequestUnlock)
1884
1662
self.assertHandlerEqual('BzrDir.find_repository',
1885
smart_dir.SmartServerRequestFindRepositoryV1)
1663
smart.bzrdir.SmartServerRequestFindRepositoryV1)
1886
1664
self.assertHandlerEqual('BzrDir.find_repositoryV2',
1887
smart_dir.SmartServerRequestFindRepositoryV2)
1665
smart.bzrdir.SmartServerRequestFindRepositoryV2)
1888
1666
self.assertHandlerEqual('BzrDirFormat.initialize',
1889
smart_dir.SmartServerRequestInitializeBzrDir)
1667
smart.bzrdir.SmartServerRequestInitializeBzrDir)
1890
1668
self.assertHandlerEqual('BzrDirFormat.initialize_ex_1.16',
1891
smart_dir.SmartServerRequestBzrDirInitializeEx)
1669
smart.bzrdir.SmartServerRequestBzrDirInitializeEx)
1892
1670
self.assertHandlerEqual('BzrDir.cloning_metadir',
1893
smart_dir.SmartServerBzrDirRequestCloningMetaDir)
1671
smart.bzrdir.SmartServerBzrDirRequestCloningMetaDir)
1894
1672
self.assertHandlerEqual('BzrDir.get_config_file',
1895
smart_dir.SmartServerBzrDirRequestConfigFile)
1673
smart.bzrdir.SmartServerBzrDirRequestConfigFile)
1896
1674
self.assertHandlerEqual('BzrDir.open_branch',
1897
smart_dir.SmartServerRequestOpenBranch)
1675
smart.bzrdir.SmartServerRequestOpenBranch)
1898
1676
self.assertHandlerEqual('BzrDir.open_branchV2',
1899
smart_dir.SmartServerRequestOpenBranchV2)
1900
self.assertHandlerEqual('BzrDir.open_branchV3',
1901
smart_dir.SmartServerRequestOpenBranchV3)
1677
smart.bzrdir.SmartServerRequestOpenBranchV2)
1902
1678
self.assertHandlerEqual('PackRepository.autopack',
1903
smart_packrepo.SmartServerPackRepositoryAutopack)
1679
smart.packrepository.SmartServerPackRepositoryAutopack)
1904
1680
self.assertHandlerEqual('Repository.gather_stats',
1905
smart_repo.SmartServerRepositoryGatherStats)
1681
smart.repository.SmartServerRepositoryGatherStats)
1906
1682
self.assertHandlerEqual('Repository.get_parent_map',
1907
smart_repo.SmartServerRepositoryGetParentMap)
1683
smart.repository.SmartServerRepositoryGetParentMap)
1908
1684
self.assertHandlerEqual('Repository.get_rev_id_for_revno',
1909
smart_repo.SmartServerRepositoryGetRevIdForRevno)
1685
smart.repository.SmartServerRepositoryGetRevIdForRevno)
1910
1686
self.assertHandlerEqual('Repository.get_revision_graph',
1911
smart_repo.SmartServerRepositoryGetRevisionGraph)
1687
smart.repository.SmartServerRepositoryGetRevisionGraph)
1912
1688
self.assertHandlerEqual('Repository.get_stream',
1913
smart_repo.SmartServerRepositoryGetStream)
1689
smart.repository.SmartServerRepositoryGetStream)
1914
1690
self.assertHandlerEqual('Repository.has_revision',
1915
smart_repo.SmartServerRequestHasRevision)
1691
smart.repository.SmartServerRequestHasRevision)
1916
1692
self.assertHandlerEqual('Repository.insert_stream',
1917
smart_repo.SmartServerRepositoryInsertStream)
1693
smart.repository.SmartServerRepositoryInsertStream)
1918
1694
self.assertHandlerEqual('Repository.insert_stream_locked',
1919
smart_repo.SmartServerRepositoryInsertStreamLocked)
1695
smart.repository.SmartServerRepositoryInsertStreamLocked)
1920
1696
self.assertHandlerEqual('Repository.is_shared',
1921
smart_repo.SmartServerRepositoryIsShared)
1697
smart.repository.SmartServerRepositoryIsShared)
1922
1698
self.assertHandlerEqual('Repository.lock_write',
1923
smart_repo.SmartServerRepositoryLockWrite)
1699
smart.repository.SmartServerRepositoryLockWrite)
1924
1700
self.assertHandlerEqual('Repository.tarball',
1925
smart_repo.SmartServerRepositoryTarball)
1701
smart.repository.SmartServerRepositoryTarball)
1926
1702
self.assertHandlerEqual('Repository.unlock',
1927
smart_repo.SmartServerRepositoryUnlock)
1703
smart.repository.SmartServerRepositoryUnlock)
1928
1704
self.assertHandlerEqual('Transport.is_readonly',
1929
smart_req.SmartServerIsReadonly)
1705
smart.request.SmartServerIsReadonly)