28
from cStringIO import StringIO
29
31
from bzrlib import (
30
branch as _mod_branch,
38
from bzrlib.smart import (
39
branch as smart_branch,
41
repository as smart_repo,
42
packrepository as smart_packrepo,
47
from bzrlib.tests import test_server
48
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
import bzrlib.smart.vfs
47
from bzrlib.smart.request import (
48
FailedSmartServerResponse,
51
SuccessfulSmartServerResponse,
53
from bzrlib.tests import (
56
from bzrlib.transport import chroot, get_transport, local, memory
54
59
def load_tests(standard_tests, module, loader):
55
60
"""Multiply tests version and protocol consistency."""
56
61
# FindRepository tests.
62
bzrdir_mod = bzrlib.smart.bzrdir
58
64
("find_repository", {
59
"_request_class": smart_dir.SmartServerRequestFindRepositoryV1}),
65
"_request_class":bzrdir_mod.SmartServerRequestFindRepositoryV1}),
60
66
("find_repositoryV2", {
61
"_request_class": smart_dir.SmartServerRequestFindRepositoryV2}),
67
"_request_class":bzrdir_mod.SmartServerRequestFindRepositoryV2}),
62
68
("find_repositoryV3", {
63
"_request_class": smart_dir.SmartServerRequestFindRepositoryV3}),
69
"_request_class":bzrdir_mod.SmartServerRequestFindRepositoryV3}),
65
to_adapt, result = tests.split_suite_by_re(standard_tests,
71
to_adapt, result = split_suite_by_re(standard_tests,
66
72
"TestSmartServerRequestFindRepository")
67
v2_only, v1_and_2 = tests.split_suite_by_re(to_adapt,
73
v2_only, v1_and_2 = split_suite_by_re(to_adapt,
69
75
tests.multiply_tests(v1_and_2, scenarios, result)
70
76
# The first scenario is only applicable to v1 protocols, it is deleted
131
137
class TestSmartServerResponse(tests.TestCase):
133
139
def test__eq__(self):
134
self.assertEqual(smart_req.SmartServerResponse(('ok', )),
135
smart_req.SmartServerResponse(('ok', )))
136
self.assertEqual(smart_req.SmartServerResponse(('ok', ), 'body'),
137
smart_req.SmartServerResponse(('ok', ), 'body'))
138
self.assertNotEqual(smart_req.SmartServerResponse(('ok', )),
139
smart_req.SmartServerResponse(('notok', )))
140
self.assertNotEqual(smart_req.SmartServerResponse(('ok', ), 'body'),
141
smart_req.SmartServerResponse(('ok', )))
140
self.assertEqual(SmartServerResponse(('ok', )),
141
SmartServerResponse(('ok', )))
142
self.assertEqual(SmartServerResponse(('ok', ), 'body'),
143
SmartServerResponse(('ok', ), 'body'))
144
self.assertNotEqual(SmartServerResponse(('ok', )),
145
SmartServerResponse(('notok', )))
146
self.assertNotEqual(SmartServerResponse(('ok', ), 'body'),
147
SmartServerResponse(('ok', )))
142
148
self.assertNotEqual(None,
143
smart_req.SmartServerResponse(('ok', )))
149
SmartServerResponse(('ok', )))
145
151
def test__str__(self):
146
152
"""SmartServerResponses can be stringified."""
147
153
self.assertEqual(
148
154
"<SuccessfulSmartServerResponse args=('args',) body='body'>",
149
str(smart_req.SuccessfulSmartServerResponse(('args',), 'body')))
155
str(SuccessfulSmartServerResponse(('args',), 'body')))
150
156
self.assertEqual(
151
157
"<FailedSmartServerResponse args=('args',) body='body'>",
152
str(smart_req.FailedSmartServerResponse(('args',), 'body')))
158
str(FailedSmartServerResponse(('args',), 'body')))
155
161
class TestSmartServerRequest(tests.TestCaseWithMemoryTransport):
157
163
def test_translate_client_path(self):
158
164
transport = self.get_transport()
159
request = smart_req.SmartServerRequest(transport, 'foo/')
165
request = SmartServerRequest(transport, 'foo/')
160
166
self.assertEqual('./', request.translate_client_path('foo/'))
161
167
self.assertRaises(
162
168
errors.InvalidURLJoin, request.translate_client_path, 'foo/..')
423
421
"""Initializing an extant directory should fail like the bzrdir api."""
424
422
backing = self.get_transport()
425
423
name = self.make_bzrdir('reference')._format.network_name()
426
request = smart_dir.SmartServerRequestBzrDirInitializeEx(backing)
424
request = smart.bzrdir.SmartServerRequestBzrDirInitializeEx(backing)
427
425
self.make_bzrdir('subdir')
428
426
self.assertRaises(errors.FileExists, request.execute, name, 'subdir',
429
427
'False', 'False', 'False', '', '', '', '', 'False')
432
430
class TestSmartServerRequestOpenBzrDir(tests.TestCaseWithMemoryTransport):
434
432
def test_no_directory(self):
435
433
backing = self.get_transport()
436
request = smart_dir.SmartServerRequestOpenBzrDir(backing)
437
self.assertEqual(smart_req.SmartServerResponse(('no', )),
434
request = smart.bzrdir.SmartServerRequestOpenBzrDir(backing)
435
self.assertEqual(SmartServerResponse(('no', )),
438
436
request.execute('does-not-exist'))
440
438
def test_empty_directory(self):
441
439
backing = self.get_transport()
442
440
backing.mkdir('empty')
443
request = smart_dir.SmartServerRequestOpenBzrDir(backing)
444
self.assertEqual(smart_req.SmartServerResponse(('no', )),
441
request = smart.bzrdir.SmartServerRequestOpenBzrDir(backing)
442
self.assertEqual(SmartServerResponse(('no', )),
445
443
request.execute('empty'))
447
445
def test_outside_root_client_path(self):
448
446
backing = self.get_transport()
449
request = smart_dir.SmartServerRequestOpenBzrDir(backing,
447
request = smart.bzrdir.SmartServerRequestOpenBzrDir(backing,
450
448
root_client_path='root')
451
self.assertEqual(smart_req.SmartServerResponse(('no', )),
449
self.assertEqual(SmartServerResponse(('no', )),
452
450
request.execute('not-root'))
455
453
class TestSmartServerRequestOpenBzrDir_2_1(tests.TestCaseWithMemoryTransport):
457
455
def test_no_directory(self):
458
456
backing = self.get_transport()
459
request = smart_dir.SmartServerRequestOpenBzrDir_2_1(backing)
460
self.assertEqual(smart_req.SmartServerResponse(('no', )),
457
request = smart.bzrdir.SmartServerRequestOpenBzrDir_2_1(backing)
458
self.assertEqual(SmartServerResponse(('no', )),
461
459
request.execute('does-not-exist'))
463
461
def test_empty_directory(self):
464
462
backing = self.get_transport()
465
463
backing.mkdir('empty')
466
request = smart_dir.SmartServerRequestOpenBzrDir_2_1(backing)
467
self.assertEqual(smart_req.SmartServerResponse(('no', )),
464
request = smart.bzrdir.SmartServerRequestOpenBzrDir_2_1(backing)
465
self.assertEqual(SmartServerResponse(('no', )),
468
466
request.execute('empty'))
470
468
def test_present_without_workingtree(self):
471
469
backing = self.get_transport()
472
request = smart_dir.SmartServerRequestOpenBzrDir_2_1(backing)
470
request = smart.bzrdir.SmartServerRequestOpenBzrDir_2_1(backing)
473
471
self.make_bzrdir('.')
474
self.assertEqual(smart_req.SmartServerResponse(('yes', 'no')),
472
self.assertEqual(SmartServerResponse(('yes', 'no')),
475
473
request.execute(''))
477
475
def test_outside_root_client_path(self):
478
476
backing = self.get_transport()
479
request = smart_dir.SmartServerRequestOpenBzrDir_2_1(backing,
477
request = smart.bzrdir.SmartServerRequestOpenBzrDir_2_1(backing,
480
478
root_client_path='root')
481
self.assertEqual(smart_req.SmartServerResponse(('no',)),
479
self.assertEqual(SmartServerResponse(('no',)),
482
480
request.execute('not-root'))
485
483
class TestSmartServerRequestOpenBzrDir_2_1_disk(TestCaseWithChrootedTransport):
487
485
def test_present_with_workingtree(self):
488
self.vfs_transport_factory = test_server.LocalURLServer
486
self.vfs_transport_factory = local.LocalURLServer
489
487
backing = self.get_transport()
490
request = smart_dir.SmartServerRequestOpenBzrDir_2_1(backing)
488
request = smart.bzrdir.SmartServerRequestOpenBzrDir_2_1(backing)
491
489
bd = self.make_bzrdir('.')
492
490
bd.create_repository()
493
491
bd.create_branch()
494
492
bd.create_workingtree()
495
self.assertEqual(smart_req.SmartServerResponse(('yes', 'yes')),
493
self.assertEqual(SmartServerResponse(('yes', 'yes')),
496
494
request.execute(''))
501
499
def test_no_branch(self):
502
500
"""When there is no branch, ('nobranch', ) is returned."""
503
501
backing = self.get_transport()
504
request = smart_dir.SmartServerRequestOpenBranch(backing)
502
request = smart.bzrdir.SmartServerRequestOpenBranch(backing)
505
503
self.make_bzrdir('.')
506
self.assertEqual(smart_req.SmartServerResponse(('nobranch', )),
504
self.assertEqual(SmartServerResponse(('nobranch', )),
507
505
request.execute(''))
509
507
def test_branch(self):
510
508
"""When there is a branch, 'ok' is returned."""
511
509
backing = self.get_transport()
512
request = smart_dir.SmartServerRequestOpenBranch(backing)
510
request = smart.bzrdir.SmartServerRequestOpenBranch(backing)
513
511
self.make_branch('.')
514
self.assertEqual(smart_req.SmartServerResponse(('ok', '')),
512
self.assertEqual(SmartServerResponse(('ok', '')),
515
513
request.execute(''))
517
515
def test_branch_reference(self):
518
516
"""When there is a branch reference, the reference URL is returned."""
519
self.vfs_transport_factory = test_server.LocalURLServer
517
self.vfs_transport_factory = local.LocalURLServer
520
518
backing = self.get_transport()
521
request = smart_dir.SmartServerRequestOpenBranch(backing)
519
request = smart.bzrdir.SmartServerRequestOpenBranch(backing)
522
520
branch = self.make_branch('branch')
523
521
checkout = branch.create_checkout('reference',lightweight=True)
524
reference_url = _mod_branch.BranchReferenceFormat().get_reference(
522
reference_url = BranchReferenceFormat().get_reference(checkout.bzrdir)
526
523
self.assertFileEqual(reference_url, 'reference/.bzr/branch/location')
527
self.assertEqual(smart_req.SmartServerResponse(('ok', reference_url)),
524
self.assertEqual(SmartServerResponse(('ok', reference_url)),
528
525
request.execute('reference'))
530
def test_notification_on_branch_from_repository(self):
531
"""When there is a repository, the error should return details."""
532
backing = self.get_transport()
533
request = smart_dir.SmartServerRequestOpenBranch(backing)
534
repo = self.make_repository('.')
535
self.assertEqual(smart_req.SmartServerResponse(('nobranch',)),
539
528
class TestSmartServerRequestOpenBranchV2(TestCaseWithChrootedTransport):
542
531
"""When there is no branch, ('nobranch', ) is returned."""
543
532
backing = self.get_transport()
544
533
self.make_bzrdir('.')
545
request = smart_dir.SmartServerRequestOpenBranchV2(backing)
546
self.assertEqual(smart_req.SmartServerResponse(('nobranch', )),
549
def test_branch(self):
550
"""When there is a branch, 'ok' is returned."""
551
backing = self.get_transport()
552
expected = self.make_branch('.')._format.network_name()
553
request = smart_dir.SmartServerRequestOpenBranchV2(backing)
554
self.assertEqual(smart_req.SuccessfulSmartServerResponse(
555
('branch', expected)),
558
def test_branch_reference(self):
559
"""When there is a branch reference, the reference URL is returned."""
560
self.vfs_transport_factory = test_server.LocalURLServer
561
backing = self.get_transport()
562
request = smart_dir.SmartServerRequestOpenBranchV2(backing)
563
branch = self.make_branch('branch')
564
checkout = branch.create_checkout('reference',lightweight=True)
565
reference_url = _mod_branch.BranchReferenceFormat().get_reference(
567
self.assertFileEqual(reference_url, 'reference/.bzr/branch/location')
568
self.assertEqual(smart_req.SuccessfulSmartServerResponse(
569
('ref', reference_url)),
570
request.execute('reference'))
572
def test_stacked_branch(self):
573
"""Opening a stacked branch does not open the stacked-on branch."""
574
trunk = self.make_branch('trunk')
575
feature = self.make_branch('feature')
576
feature.set_stacked_on_url(trunk.base)
578
_mod_branch.Branch.hooks.install_named_hook(
579
'open', opened_branches.append, None)
580
backing = self.get_transport()
581
request = smart_dir.SmartServerRequestOpenBranchV2(backing)
584
response = request.execute('feature')
586
request.teardown_jail()
587
expected_format = feature._format.network_name()
588
self.assertEqual(smart_req.SuccessfulSmartServerResponse(
589
('branch', expected_format)),
591
self.assertLength(1, opened_branches)
593
def test_notification_on_branch_from_repository(self):
594
"""When there is a repository, the error should return details."""
595
backing = self.get_transport()
596
request = smart_dir.SmartServerRequestOpenBranchV2(backing)
597
repo = self.make_repository('.')
598
self.assertEqual(smart_req.SmartServerResponse(('nobranch',)),
602
class TestSmartServerRequestOpenBranchV3(TestCaseWithChrootedTransport):
604
def test_no_branch(self):
605
"""When there is no branch, ('nobranch', ) is returned."""
606
backing = self.get_transport()
607
self.make_bzrdir('.')
608
request = smart_dir.SmartServerRequestOpenBranchV3(backing)
609
self.assertEqual(smart_req.SmartServerResponse(('nobranch',)),
612
def test_branch(self):
613
"""When there is a branch, 'ok' is returned."""
614
backing = self.get_transport()
615
expected = self.make_branch('.')._format.network_name()
616
request = smart_dir.SmartServerRequestOpenBranchV3(backing)
617
self.assertEqual(smart_req.SuccessfulSmartServerResponse(
618
('branch', expected)),
621
def test_branch_reference(self):
622
"""When there is a branch reference, the reference URL is returned."""
623
self.vfs_transport_factory = test_server.LocalURLServer
624
backing = self.get_transport()
625
request = smart_dir.SmartServerRequestOpenBranchV3(backing)
626
branch = self.make_branch('branch')
627
checkout = branch.create_checkout('reference',lightweight=True)
628
reference_url = _mod_branch.BranchReferenceFormat().get_reference(
630
self.assertFileEqual(reference_url, 'reference/.bzr/branch/location')
631
self.assertEqual(smart_req.SuccessfulSmartServerResponse(
632
('ref', reference_url)),
633
request.execute('reference'))
635
def test_stacked_branch(self):
636
"""Opening a stacked branch does not open the stacked-on branch."""
637
trunk = self.make_branch('trunk')
638
feature = self.make_branch('feature')
639
feature.set_stacked_on_url(trunk.base)
641
_mod_branch.Branch.hooks.install_named_hook(
642
'open', opened_branches.append, None)
643
backing = self.get_transport()
644
request = smart_dir.SmartServerRequestOpenBranchV3(backing)
647
response = request.execute('feature')
649
request.teardown_jail()
650
expected_format = feature._format.network_name()
651
self.assertEqual(smart_req.SuccessfulSmartServerResponse(
652
('branch', expected_format)),
654
self.assertLength(1, opened_branches)
656
def test_notification_on_branch_from_repository(self):
657
"""When there is a repository, the error should return details."""
658
backing = self.get_transport()
659
request = smart_dir.SmartServerRequestOpenBranchV3(backing)
660
repo = self.make_repository('.')
661
self.assertEqual(smart_req.SmartServerResponse(
662
('nobranch', 'location is a repository')),
534
request = smart.bzrdir.SmartServerRequestOpenBranchV2(backing)
535
self.assertEqual(SmartServerResponse(('nobranch', )),
538
def test_branch(self):
539
"""When there is a branch, 'ok' is returned."""
540
backing = self.get_transport()
541
expected = self.make_branch('.')._format.network_name()
542
request = smart.bzrdir.SmartServerRequestOpenBranchV2(backing)
543
self.assertEqual(SuccessfulSmartServerResponse(('branch', expected)),
546
def test_branch_reference(self):
547
"""When there is a branch reference, the reference URL is returned."""
548
self.vfs_transport_factory = local.LocalURLServer
549
backing = self.get_transport()
550
request = smart.bzrdir.SmartServerRequestOpenBranchV2(backing)
551
branch = self.make_branch('branch')
552
checkout = branch.create_checkout('reference',lightweight=True)
553
reference_url = BranchReferenceFormat().get_reference(checkout.bzrdir)
554
self.assertFileEqual(reference_url, 'reference/.bzr/branch/location')
555
self.assertEqual(SuccessfulSmartServerResponse(('ref', reference_url)),
556
request.execute('reference'))
558
def test_stacked_branch(self):
559
"""Opening a stacked branch does not open the stacked-on branch."""
560
trunk = self.make_branch('trunk')
561
feature = self.make_branch('feature')
562
feature.set_stacked_on_url(trunk.base)
564
Branch.hooks.install_named_hook('open', opened_branches.append, None)
565
backing = self.get_transport()
566
request = smart.bzrdir.SmartServerRequestOpenBranchV2(backing)
569
response = request.execute('feature')
571
request.teardown_jail()
572
expected_format = feature._format.network_name()
574
SuccessfulSmartServerResponse(('branch', expected_format)),
576
self.assertLength(1, opened_branches)
666
579
class TestSmartServerRequestRevisionHistory(tests.TestCaseWithMemoryTransport):
774
685
def test_value_name(self):
775
686
branch = self.make_branch('.')
776
request = smart_branch.SmartServerBranchRequestSetConfigOption(
687
request = smart.branch.SmartServerBranchRequestSetConfigOption(
777
688
branch.bzrdir.root_transport)
778
689
branch_token, repo_token = self.get_lock_tokens(branch)
779
690
config = branch._get_config()
780
691
result = request.execute('', branch_token, repo_token, 'bar', 'foo',
782
self.assertEqual(smart_req.SuccessfulSmartServerResponse(()), result)
693
self.assertEqual(SuccessfulSmartServerResponse(()), result)
783
694
self.assertEqual('bar', config.get_option('foo'))
787
698
def test_value_name_section(self):
788
699
branch = self.make_branch('.')
789
request = smart_branch.SmartServerBranchRequestSetConfigOption(
700
request = smart.branch.SmartServerBranchRequestSetConfigOption(
790
701
branch.bzrdir.root_transport)
791
702
branch_token, repo_token = self.get_lock_tokens(branch)
792
703
config = branch._get_config()
793
704
result = request.execute('', branch_token, repo_token, 'bar', 'foo',
795
self.assertEqual(smart_req.SuccessfulSmartServerResponse(()), result)
706
self.assertEqual(SuccessfulSmartServerResponse(()), result)
796
707
self.assertEqual('bar', config.get_option('foo', 'gam'))
801
class TestSmartServerBranchRequestSetConfigOptionDict(TestLockedBranch):
804
TestLockedBranch.setUp(self)
805
# A dict with non-ascii keys and values to exercise unicode
807
self.encoded_value_dict = (
808
'd5:ascii1:a11:unicode \xe2\x8c\x9a3:\xe2\x80\xbde')
810
'ascii': 'a', u'unicode \N{WATCH}': u'\N{INTERROBANG}'}
812
def test_value_name(self):
813
branch = self.make_branch('.')
814
request = smart_branch.SmartServerBranchRequestSetConfigOptionDict(
815
branch.bzrdir.root_transport)
816
branch_token, repo_token = self.get_lock_tokens(branch)
817
config = branch._get_config()
818
result = request.execute('', branch_token, repo_token,
819
self.encoded_value_dict, 'foo', '')
820
self.assertEqual(smart_req.SuccessfulSmartServerResponse(()), result)
821
self.assertEqual(self.value_dict, config.get_option('foo'))
825
def test_value_name_section(self):
826
branch = self.make_branch('.')
827
request = smart_branch.SmartServerBranchRequestSetConfigOptionDict(
828
branch.bzrdir.root_transport)
829
branch_token, repo_token = self.get_lock_tokens(branch)
830
config = branch._get_config()
831
result = request.execute('', branch_token, repo_token,
832
self.encoded_value_dict, 'foo', 'gam')
833
self.assertEqual(smart_req.SuccessfulSmartServerResponse(()), result)
834
self.assertEqual(self.value_dict, config.get_option('foo', 'gam'))
839
712
class TestSmartServerBranchRequestSetTagsBytes(TestLockedBranch):
840
713
# Only called when the branch format and tags match [yay factory
841
714
# methods] so only need to test straight forward cases.
1093
965
def test_get_parent_none(self):
1094
966
base_branch = self.make_branch('base')
1095
request = smart_branch.SmartServerBranchGetParent(self.get_transport())
967
request = smart.branch.SmartServerBranchGetParent(self.get_transport())
1096
968
response = request.execute('base')
1097
969
self.assertEquals(
1098
smart_req.SuccessfulSmartServerResponse(('',)), response)
970
SuccessfulSmartServerResponse(('',)), response)
1100
972
def test_get_parent_something(self):
1101
973
base_branch = self.make_branch('base')
1102
974
base_branch.set_parent(self.get_url('foo'))
1103
request = smart_branch.SmartServerBranchGetParent(self.get_transport())
975
request = smart.branch.SmartServerBranchGetParent(self.get_transport())
1104
976
response = request.execute('base')
1105
977
self.assertEquals(
1106
smart_req.SuccessfulSmartServerResponse(("../foo",)),
978
SuccessfulSmartServerResponse(("../foo",)),
1110
class TestSmartServerBranchRequestSetParent(TestLockedBranch):
982
class TestSmartServerBranchRequestSetParent(tests.TestCaseWithMemoryTransport):
1112
984
def test_set_parent_none(self):
1113
985
branch = self.make_branch('base', format="1.9")
1114
986
branch.lock_write()
1115
987
branch._set_parent_location('foo')
1117
request = smart_branch.SmartServerBranchRequestSetParentLocation(
989
request = smart.branch.SmartServerBranchRequestSetParentLocation(
1118
990
self.get_transport())
1119
branch_token, repo_token = self.get_lock_tokens(branch)
991
branch_token = branch.lock_write()
992
repo_token = branch.repository.lock_write()
1121
994
response = request.execute('base', branch_token, repo_token, '')
996
branch.repository.unlock()
1124
self.assertEqual(smart_req.SuccessfulSmartServerResponse(()), response)
998
self.assertEqual(SuccessfulSmartServerResponse(()), response)
1125
999
self.assertEqual(None, branch.get_parent())
1127
1001
def test_set_parent_something(self):
1128
1002
branch = self.make_branch('base', format="1.9")
1129
request = smart_branch.SmartServerBranchRequestSetParentLocation(
1003
request = smart.branch.SmartServerBranchRequestSetParentLocation(
1130
1004
self.get_transport())
1131
branch_token, repo_token = self.get_lock_tokens(branch)
1005
branch_token = branch.lock_write()
1006
repo_token = branch.repository.lock_write()
1133
1008
response = request.execute('base', branch_token, repo_token,
1011
branch.repository.unlock()
1136
1012
branch.unlock()
1137
self.assertEqual(smart_req.SuccessfulSmartServerResponse(()), response)
1013
self.assertEqual(SuccessfulSmartServerResponse(()), response)
1138
1014
self.assertEqual('http://bar/', branch.get_parent())
1141
class TestSmartServerBranchRequestGetTagsBytes(
1142
tests.TestCaseWithMemoryTransport):
1017
class TestSmartServerBranchRequestGetTagsBytes(tests.TestCaseWithMemoryTransport):
1143
1018
# Only called when the branch format and tags match [yay factory
1144
1019
# methods] so only need to test straight forward cases.
1146
1021
def test_get_bytes(self):
1147
1022
base_branch = self.make_branch('base')
1148
request = smart_branch.SmartServerBranchGetTagsBytes(
1023
request = smart.branch.SmartServerBranchGetTagsBytes(
1149
1024
self.get_transport())
1150
1025
response = request.execute('base')
1151
1026
self.assertEquals(
1152
smart_req.SuccessfulSmartServerResponse(('',)), response)
1027
SuccessfulSmartServerResponse(('',)), response)
1155
1030
class TestSmartServerBranchRequestGetStackedOnURL(tests.TestCaseWithMemoryTransport):
1159
1034
stacked_branch = self.make_branch('stacked', format='1.6')
1160
1035
# typically should be relative
1161
1036
stacked_branch.set_stacked_on_url('../base')
1162
request = smart_branch.SmartServerBranchRequestGetStackedOnURL(
1037
request = smart.branch.SmartServerBranchRequestGetStackedOnURL(
1163
1038
self.get_transport())
1164
1039
response = request.execute('stacked')
1165
1040
self.assertEquals(
1166
smart_req.SmartServerResponse(('ok', '../base')),
1041
SmartServerResponse(('ok', '../base')),
1170
class TestSmartServerBranchRequestLockWrite(TestLockedBranch):
1045
class TestSmartServerBranchRequestLockWrite(tests.TestCaseWithMemoryTransport):
1172
1047
def setUp(self):
1173
1048
tests.TestCaseWithMemoryTransport.setUp(self)
1175
1050
def test_lock_write_on_unlocked_branch(self):
1176
1051
backing = self.get_transport()
1177
request = smart_branch.SmartServerBranchRequestLockWrite(backing)
1052
request = smart.branch.SmartServerBranchRequestLockWrite(backing)
1178
1053
branch = self.make_branch('.', format='knit')
1179
1054
repository = branch.repository
1180
1055
response = request.execute('')
1181
1056
branch_nonce = branch.control_files._lock.peek().get('nonce')
1182
1057
repository_nonce = repository.control_files._lock.peek().get('nonce')
1183
self.assertEqual(smart_req.SmartServerResponse(
1184
('ok', branch_nonce, repository_nonce)),
1059
SmartServerResponse(('ok', branch_nonce, repository_nonce)),
1186
1061
# The branch (and associated repository) is now locked. Verify that
1187
1062
# with a new branch object.
1188
1063
new_branch = repository.bzrdir.open_branch()
1189
1064
self.assertRaises(errors.LockContention, new_branch.lock_write)
1191
request = smart_branch.SmartServerBranchRequestUnlock(backing)
1066
request = smart.branch.SmartServerBranchRequestUnlock(backing)
1192
1067
response = request.execute('', branch_nonce, repository_nonce)
1194
1069
def test_lock_write_on_locked_branch(self):
1195
1070
backing = self.get_transport()
1196
request = smart_branch.SmartServerBranchRequestLockWrite(backing)
1071
request = smart.branch.SmartServerBranchRequestLockWrite(backing)
1197
1072
branch = self.make_branch('.')
1198
branch_token = branch.lock_write().branch_token
1073
branch_token = branch.lock_write()
1199
1074
branch.leave_lock_in_place()
1200
1075
branch.unlock()
1201
1076
response = request.execute('')
1202
1077
self.assertEqual(
1203
smart_req.SmartServerResponse(('LockContention',)), response)
1078
SmartServerResponse(('LockContention',)), response)
1205
1080
branch.lock_write(branch_token)
1206
1081
branch.dont_leave_lock_in_place()
1304
1184
def test_unlock_on_unlocked_branch_unlocked_repo(self):
1305
1185
backing = self.get_transport()
1306
request = smart_branch.SmartServerBranchRequestUnlock(backing)
1186
request = smart.branch.SmartServerBranchRequestUnlock(backing)
1307
1187
branch = self.make_branch('.', format='knit')
1308
1188
response = request.execute(
1309
1189
'', 'branch token', 'repo token')
1310
1190
self.assertEqual(
1311
smart_req.SmartServerResponse(('TokenMismatch',)), response)
1191
SmartServerResponse(('TokenMismatch',)), response)
1313
1193
def test_unlock_on_unlocked_branch_locked_repo(self):
1314
1194
backing = self.get_transport()
1315
request = smart_branch.SmartServerBranchRequestUnlock(backing)
1195
request = smart.branch.SmartServerBranchRequestUnlock(backing)
1316
1196
branch = self.make_branch('.', format='knit')
1317
1197
# Lock the repository.
1318
repo_token = branch.repository.lock_write().repository_token
1198
repo_token = branch.repository.lock_write()
1319
1199
branch.repository.leave_lock_in_place()
1320
1200
branch.repository.unlock()
1321
1201
# Issue branch lock_write request on the unlocked branch (with locked
1323
response = request.execute('', 'branch token', repo_token)
1203
response = request.execute(
1204
'', 'branch token', repo_token)
1324
1205
self.assertEqual(
1325
smart_req.SmartServerResponse(('TokenMismatch',)), response)
1206
SmartServerResponse(('TokenMismatch',)), response)
1327
1208
branch.repository.lock_write(repo_token)
1328
1209
branch.repository.dont_leave_lock_in_place()
1350
1231
def test_trivial_bzipped(self):
1351
1232
# This tests that the wire encoding is actually bzipped
1352
1233
backing = self.get_transport()
1353
request = smart_repo.SmartServerRepositoryGetParentMap(backing)
1234
request = smart.repository.SmartServerRepositoryGetParentMap(backing)
1354
1235
tree = self.make_branch_and_memory_tree('.')
1356
1237
self.assertEqual(None,
1357
1238
request.execute('', 'missing-id'))
1358
1239
# Note that it returns a body that is bzipped.
1359
1240
self.assertEqual(
1360
smart_req.SuccessfulSmartServerResponse(('ok', ), bz2.compress('')),
1241
SuccessfulSmartServerResponse(('ok', ), bz2.compress('')),
1361
1242
request.do_body('\n\n0\n'))
1363
1244
def test_trivial_include_missing(self):
1364
1245
backing = self.get_transport()
1365
request = smart_repo.SmartServerRepositoryGetParentMap(backing)
1246
request = smart.repository.SmartServerRepositoryGetParentMap(backing)
1366
1247
tree = self.make_branch_and_memory_tree('.')
1368
1249
self.assertEqual(None,
1369
1250
request.execute('', 'missing-id', 'include-missing:'))
1370
1251
self.assertEqual(
1371
smart_req.SuccessfulSmartServerResponse(('ok', ),
1252
SuccessfulSmartServerResponse(('ok', ),
1372
1253
bz2.compress('missing:missing-id')),
1373
1254
request.do_body('\n\n0\n'))
1376
class TestSmartServerRepositoryGetRevisionGraph(
1377
tests.TestCaseWithMemoryTransport):
1257
class TestSmartServerRepositoryGetRevisionGraph(tests.TestCaseWithMemoryTransport):
1379
1259
def test_none_argument(self):
1380
1260
backing = self.get_transport()
1381
request = smart_repo.SmartServerRepositoryGetRevisionGraph(backing)
1261
request = smart.repository.SmartServerRepositoryGetRevisionGraph(backing)
1382
1262
tree = self.make_branch_and_memory_tree('.')
1383
1263
tree.lock_write()
1511
1387
stream_bytes = ''.join(response.body_stream)
1512
1388
self.assertStartsWith(stream_bytes, 'Bazaar pack format 1')
1514
def test_search_everything(self):
1515
"""A search of 'everything' returns a stream."""
1516
backing = self.get_transport()
1517
request = smart_repo.SmartServerRepositoryGetStream_1_19(backing)
1518
repo, r1, r2 = self.make_two_commit_repo()
1519
serialised_fetch_spec = 'everything'
1520
request.execute('', repo._format.network_name())
1521
response = request.do_body(serialised_fetch_spec)
1522
self.assertEqual(('ok',), response.args)
1523
stream_bytes = ''.join(response.body_stream)
1524
self.assertStartsWith(stream_bytes, 'Bazaar pack format 1')
1527
1391
class TestSmartServerRequestHasRevision(tests.TestCaseWithMemoryTransport):
1529
1393
def test_missing_revision(self):
1530
1394
"""For a missing revision, ('no', ) is returned."""
1531
1395
backing = self.get_transport()
1532
request = smart_repo.SmartServerRequestHasRevision(backing)
1396
request = smart.repository.SmartServerRequestHasRevision(backing)
1533
1397
self.make_repository('.')
1534
self.assertEqual(smart_req.SmartServerResponse(('no', )),
1398
self.assertEqual(SmartServerResponse(('no', )),
1535
1399
request.execute('', 'revid'))
1537
1401
def test_present_revision(self):
1538
1402
"""For a present revision, ('yes', ) is returned."""
1539
1403
backing = self.get_transport()
1540
request = smart_repo.SmartServerRequestHasRevision(backing)
1404
request = smart.repository.SmartServerRequestHasRevision(backing)
1541
1405
tree = self.make_branch_and_memory_tree('.')
1542
1406
tree.lock_write()
1632
1496
def test_lock_write_on_unlocked_repo(self):
1633
1497
backing = self.get_transport()
1634
request = smart_repo.SmartServerRepositoryLockWrite(backing)
1498
request = smart.repository.SmartServerRepositoryLockWrite(backing)
1635
1499
repository = self.make_repository('.', format='knit')
1636
1500
response = request.execute('')
1637
1501
nonce = repository.control_files._lock.peek().get('nonce')
1638
self.assertEqual(smart_req.SmartServerResponse(('ok', nonce)), response)
1502
self.assertEqual(SmartServerResponse(('ok', nonce)), response)
1639
1503
# The repository is now locked. Verify that with a new repository
1641
1505
new_repo = repository.bzrdir.open_repository()
1642
1506
self.assertRaises(errors.LockContention, new_repo.lock_write)
1644
request = smart_repo.SmartServerRepositoryUnlock(backing)
1508
request = smart.repository.SmartServerRepositoryUnlock(backing)
1645
1509
response = request.execute('', nonce)
1647
1511
def test_lock_write_on_locked_repo(self):
1648
1512
backing = self.get_transport()
1649
request = smart_repo.SmartServerRepositoryLockWrite(backing)
1513
request = smart.repository.SmartServerRepositoryLockWrite(backing)
1650
1514
repository = self.make_repository('.', format='knit')
1651
repo_token = repository.lock_write().repository_token
1515
repo_token = repository.lock_write()
1652
1516
repository.leave_lock_in_place()
1653
1517
repository.unlock()
1654
1518
response = request.execute('')
1655
1519
self.assertEqual(
1656
smart_req.SmartServerResponse(('LockContention',)), response)
1520
SmartServerResponse(('LockContention',)), response)
1658
1522
repository.lock_write(repo_token)
1659
1523
repository.dont_leave_lock_in_place()
1680
1544
def test_insert_stream_empty(self):
1681
1545
backing = self.get_transport()
1682
request = smart_repo.SmartServerRepositoryInsertStream(backing)
1546
request = smart.repository.SmartServerRepositoryInsertStream(backing)
1683
1547
repository = self.make_repository('.')
1684
1548
response = request.execute('', '')
1685
1549
self.assertEqual(None, response)
1686
1550
response = request.do_chunk(self.make_empty_byte_stream(repository))
1687
1551
self.assertEqual(None, response)
1688
1552
response = request.do_end()
1689
self.assertEqual(smart_req.SmartServerResponse(('ok', )), response)
1553
self.assertEqual(SmartServerResponse(('ok', )), response)
1692
1556
class TestSmartServerRepositoryInsertStreamLocked(TestInsertStreamBase):
1694
1558
def test_insert_stream_empty(self):
1695
1559
backing = self.get_transport()
1696
request = smart_repo.SmartServerRepositoryInsertStreamLocked(
1560
request = smart.repository.SmartServerRepositoryInsertStreamLocked(
1698
1562
repository = self.make_repository('.', format='knit')
1699
lock_token = repository.lock_write().repository_token
1563
lock_token = repository.lock_write()
1700
1564
response = request.execute('', '', lock_token)
1701
1565
self.assertEqual(None, response)
1702
1566
response = request.do_chunk(self.make_empty_byte_stream(repository))
1703
1567
self.assertEqual(None, response)
1704
1568
response = request.do_end()
1705
self.assertEqual(smart_req.SmartServerResponse(('ok', )), response)
1569
self.assertEqual(SmartServerResponse(('ok', )), response)
1706
1570
repository.unlock()
1708
1572
def test_insert_stream_with_wrong_lock_token(self):
1709
1573
backing = self.get_transport()
1710
request = smart_repo.SmartServerRepositoryInsertStreamLocked(
1574
request = smart.repository.SmartServerRepositoryInsertStreamLocked(
1712
1576
repository = self.make_repository('.', format='knit')
1713
lock_token = repository.lock_write().repository_token
1577
lock_token = repository.lock_write()
1714
1578
self.assertRaises(
1715
1579
errors.TokenMismatch, request.execute, '', '', 'wrong-token')
1716
1580
repository.unlock()
1740
1604
def test_unlock_on_unlocked_repo(self):
1741
1605
backing = self.get_transport()
1742
request = smart_repo.SmartServerRepositoryUnlock(backing)
1606
request = smart.repository.SmartServerRepositoryUnlock(backing)
1743
1607
repository = self.make_repository('.', format='knit')
1744
1608
response = request.execute('', 'some token')
1745
1609
self.assertEqual(
1746
smart_req.SmartServerResponse(('TokenMismatch',)), response)
1610
SmartServerResponse(('TokenMismatch',)), response)
1749
1613
class TestSmartServerIsReadonly(tests.TestCaseWithMemoryTransport):
1751
1615
def test_is_readonly_no(self):
1752
1616
backing = self.get_transport()
1753
request = smart_req.SmartServerIsReadonly(backing)
1617
request = smart.request.SmartServerIsReadonly(backing)
1754
1618
response = request.execute()
1755
1619
self.assertEqual(
1756
smart_req.SmartServerResponse(('no',)), response)
1620
SmartServerResponse(('no',)), response)
1758
1622
def test_is_readonly_yes(self):
1759
1623
backing = self.get_readonly_transport()
1760
request = smart_req.SmartServerIsReadonly(backing)
1624
request = smart.request.SmartServerIsReadonly(backing)
1761
1625
response = request.execute()
1762
1626
self.assertEqual(
1763
smart_req.SmartServerResponse(('yes',)), response)
1766
class TestSmartServerRepositorySetMakeWorkingTrees(
1767
tests.TestCaseWithMemoryTransport):
1627
SmartServerResponse(('yes',)), response)
1630
class TestSmartServerRepositorySetMakeWorkingTrees(tests.TestCaseWithMemoryTransport):
1769
1632
def test_set_false(self):
1770
1633
backing = self.get_transport()
1771
1634
repo = self.make_repository('.', shared=True)
1772
1635
repo.set_make_working_trees(True)
1773
request_class = smart_repo.SmartServerRepositorySetMakeWorkingTrees
1636
request_class = smart.repository.SmartServerRepositorySetMakeWorkingTrees
1774
1637
request = request_class(backing)
1775
self.assertEqual(smart_req.SuccessfulSmartServerResponse(('ok',)),
1638
self.assertEqual(SuccessfulSmartServerResponse(('ok',)),
1776
1639
request.execute('', 'False'))
1777
1640
repo = repo.bzrdir.open_repository()
1778
1641
self.assertFalse(repo.make_working_trees())
1860
1723
"""All registered request_handlers can be found."""
1861
1724
# If there's a typo in a register_lazy call, this loop will fail with
1862
1725
# an AttributeError.
1863
for key, item in smart_req.request_handlers.iteritems():
1726
for key, item in smart.request.request_handlers.iteritems():
1866
1729
def assertHandlerEqual(self, verb, handler):
1867
self.assertEqual(smart_req.request_handlers.get(verb), handler)
1730
self.assertEqual(smart.request.request_handlers.get(verb), handler)
1869
1732
def test_registered_methods(self):
1870
1733
"""Test that known methods are registered to the correct object."""
1871
1734
self.assertHandlerEqual('Branch.get_config_file',
1872
smart_branch.SmartServerBranchGetConfigFile)
1735
smart.branch.SmartServerBranchGetConfigFile)
1873
1736
self.assertHandlerEqual('Branch.get_parent',
1874
smart_branch.SmartServerBranchGetParent)
1737
smart.branch.SmartServerBranchGetParent)
1875
1738
self.assertHandlerEqual('Branch.get_tags_bytes',
1876
smart_branch.SmartServerBranchGetTagsBytes)
1739
smart.branch.SmartServerBranchGetTagsBytes)
1877
1740
self.assertHandlerEqual('Branch.lock_write',
1878
smart_branch.SmartServerBranchRequestLockWrite)
1741
smart.branch.SmartServerBranchRequestLockWrite)
1879
1742
self.assertHandlerEqual('Branch.last_revision_info',
1880
smart_branch.SmartServerBranchRequestLastRevisionInfo)
1743
smart.branch.SmartServerBranchRequestLastRevisionInfo)
1881
1744
self.assertHandlerEqual('Branch.revision_history',
1882
smart_branch.SmartServerRequestRevisionHistory)
1745
smart.branch.SmartServerRequestRevisionHistory)
1883
1746
self.assertHandlerEqual('Branch.set_config_option',
1884
smart_branch.SmartServerBranchRequestSetConfigOption)
1747
smart.branch.SmartServerBranchRequestSetConfigOption)
1885
1748
self.assertHandlerEqual('Branch.set_last_revision',
1886
smart_branch.SmartServerBranchRequestSetLastRevision)
1749
smart.branch.SmartServerBranchRequestSetLastRevision)
1887
1750
self.assertHandlerEqual('Branch.set_last_revision_info',
1888
smart_branch.SmartServerBranchRequestSetLastRevisionInfo)
1751
smart.branch.SmartServerBranchRequestSetLastRevisionInfo)
1889
1752
self.assertHandlerEqual('Branch.set_last_revision_ex',
1890
smart_branch.SmartServerBranchRequestSetLastRevisionEx)
1753
smart.branch.SmartServerBranchRequestSetLastRevisionEx)
1891
1754
self.assertHandlerEqual('Branch.set_parent_location',
1892
smart_branch.SmartServerBranchRequestSetParentLocation)
1755
smart.branch.SmartServerBranchRequestSetParentLocation)
1893
1756
self.assertHandlerEqual('Branch.unlock',
1894
smart_branch.SmartServerBranchRequestUnlock)
1757
smart.branch.SmartServerBranchRequestUnlock)
1895
1758
self.assertHandlerEqual('BzrDir.find_repository',
1896
smart_dir.SmartServerRequestFindRepositoryV1)
1759
smart.bzrdir.SmartServerRequestFindRepositoryV1)
1897
1760
self.assertHandlerEqual('BzrDir.find_repositoryV2',
1898
smart_dir.SmartServerRequestFindRepositoryV2)
1761
smart.bzrdir.SmartServerRequestFindRepositoryV2)
1899
1762
self.assertHandlerEqual('BzrDirFormat.initialize',
1900
smart_dir.SmartServerRequestInitializeBzrDir)
1763
smart.bzrdir.SmartServerRequestInitializeBzrDir)
1901
1764
self.assertHandlerEqual('BzrDirFormat.initialize_ex_1.16',
1902
smart_dir.SmartServerRequestBzrDirInitializeEx)
1765
smart.bzrdir.SmartServerRequestBzrDirInitializeEx)
1903
1766
self.assertHandlerEqual('BzrDir.cloning_metadir',
1904
smart_dir.SmartServerBzrDirRequestCloningMetaDir)
1767
smart.bzrdir.SmartServerBzrDirRequestCloningMetaDir)
1905
1768
self.assertHandlerEqual('BzrDir.get_config_file',
1906
smart_dir.SmartServerBzrDirRequestConfigFile)
1769
smart.bzrdir.SmartServerBzrDirRequestConfigFile)
1907
1770
self.assertHandlerEqual('BzrDir.open_branch',
1908
smart_dir.SmartServerRequestOpenBranch)
1771
smart.bzrdir.SmartServerRequestOpenBranch)
1909
1772
self.assertHandlerEqual('BzrDir.open_branchV2',
1910
smart_dir.SmartServerRequestOpenBranchV2)
1911
self.assertHandlerEqual('BzrDir.open_branchV3',
1912
smart_dir.SmartServerRequestOpenBranchV3)
1773
smart.bzrdir.SmartServerRequestOpenBranchV2)
1913
1774
self.assertHandlerEqual('PackRepository.autopack',
1914
smart_packrepo.SmartServerPackRepositoryAutopack)
1775
smart.packrepository.SmartServerPackRepositoryAutopack)
1915
1776
self.assertHandlerEqual('Repository.gather_stats',
1916
smart_repo.SmartServerRepositoryGatherStats)
1777
smart.repository.SmartServerRepositoryGatherStats)
1917
1778
self.assertHandlerEqual('Repository.get_parent_map',
1918
smart_repo.SmartServerRepositoryGetParentMap)
1779
smart.repository.SmartServerRepositoryGetParentMap)
1919
1780
self.assertHandlerEqual('Repository.get_rev_id_for_revno',
1920
smart_repo.SmartServerRepositoryGetRevIdForRevno)
1781
smart.repository.SmartServerRepositoryGetRevIdForRevno)
1921
1782
self.assertHandlerEqual('Repository.get_revision_graph',
1922
smart_repo.SmartServerRepositoryGetRevisionGraph)
1783
smart.repository.SmartServerRepositoryGetRevisionGraph)
1923
1784
self.assertHandlerEqual('Repository.get_stream',
1924
smart_repo.SmartServerRepositoryGetStream)
1925
self.assertHandlerEqual('Repository.get_stream_1.19',
1926
smart_repo.SmartServerRepositoryGetStream_1_19)
1785
smart.repository.SmartServerRepositoryGetStream)
1927
1786
self.assertHandlerEqual('Repository.has_revision',
1928
smart_repo.SmartServerRequestHasRevision)
1787
smart.repository.SmartServerRequestHasRevision)
1929
1788
self.assertHandlerEqual('Repository.insert_stream',
1930
smart_repo.SmartServerRepositoryInsertStream)
1789
smart.repository.SmartServerRepositoryInsertStream)
1931
1790
self.assertHandlerEqual('Repository.insert_stream_locked',
1932
smart_repo.SmartServerRepositoryInsertStreamLocked)
1791
smart.repository.SmartServerRepositoryInsertStreamLocked)
1933
1792
self.assertHandlerEqual('Repository.is_shared',
1934
smart_repo.SmartServerRepositoryIsShared)
1793
smart.repository.SmartServerRepositoryIsShared)
1935
1794
self.assertHandlerEqual('Repository.lock_write',
1936
smart_repo.SmartServerRepositoryLockWrite)
1795
smart.repository.SmartServerRepositoryLockWrite)
1937
1796
self.assertHandlerEqual('Repository.tarball',
1938
smart_repo.SmartServerRepositoryTarball)
1797
smart.repository.SmartServerRepositoryTarball)
1939
1798
self.assertHandlerEqual('Repository.unlock',
1940
smart_repo.SmartServerRepositoryUnlock)
1799
smart.repository.SmartServerRepositoryUnlock)
1941
1800
self.assertHandlerEqual('Transport.is_readonly',
1942
smart_req.SmartServerIsReadonly)
1945
class SmartTCPServerHookTests(tests.TestCaseWithMemoryTransport):
1946
"""Tests for SmartTCPServer hooks."""
1949
super(SmartTCPServerHookTests, self).setUp()
1950
self.server = server.SmartTCPServer(self.get_transport())
1952
def test_run_server_started_hooks(self):
1953
"""Test the server started hooks get fired properly."""
1955
server.SmartTCPServer.hooks.install_named_hook('server_started',
1956
lambda backing_urls, url: started_calls.append((backing_urls, url)),
1958
started_ex_calls = []
1959
server.SmartTCPServer.hooks.install_named_hook('server_started_ex',
1960
lambda backing_urls, url: started_ex_calls.append((backing_urls, url)),
1962
self.server._sockname = ('example.com', 42)
1963
self.server.run_server_started_hooks()
1964
self.assertEquals(started_calls,
1965
[([self.get_transport().base], 'bzr://example.com:42/')])
1966
self.assertEquals(started_ex_calls,
1967
[([self.get_transport().base], self.server)])
1969
def test_run_server_started_hooks_ipv6(self):
1970
"""Test that socknames can contain 4-tuples."""
1971
self.server._sockname = ('::', 42, 0, 0)
1973
server.SmartTCPServer.hooks.install_named_hook('server_started',
1974
lambda backing_urls, url: started_calls.append((backing_urls, url)),
1976
self.server.run_server_started_hooks()
1977
self.assertEquals(started_calls,
1978
[([self.get_transport().base], 'bzr://:::42/')])
1980
def test_run_server_stopped_hooks(self):
1981
"""Test the server stopped hooks."""
1982
self.server._sockname = ('example.com', 42)
1984
server.SmartTCPServer.hooks.install_named_hook('server_stopped',
1985
lambda backing_urls, url: stopped_calls.append((backing_urls, url)),
1987
self.server.run_server_stopped_hooks()
1988
self.assertEquals(stopped_calls,
1989
[([self.get_transport().base], 'bzr://example.com:42/')])
1801
smart.request.SmartServerIsReadonly)