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 (
40
from bzrlib.branch import Branch, BranchReferenceFormat
41
import bzrlib.smart.branch
42
import bzrlib.smart.bzrdir, bzrlib.smart.bzrdir as smart_dir
43
import bzrlib.smart.packrepository
44
import bzrlib.smart.repository
45
from bzrlib.smart.request import (
46
FailedSmartServerResponse,
49
SuccessfulSmartServerResponse,
51
from bzrlib.tests import (
54
from bzrlib.transport import chroot, get_transport
58
57
def load_tests(standard_tests, module, loader):
59
58
"""Multiply tests version and protocol consistency."""
60
59
# FindRepository tests.
60
bzrdir_mod = bzrlib.smart.bzrdir
62
62
("find_repository", {
63
"_request_class": smart_dir.SmartServerRequestFindRepositoryV1}),
63
"_request_class":bzrdir_mod.SmartServerRequestFindRepositoryV1}),
64
64
("find_repositoryV2", {
65
"_request_class": smart_dir.SmartServerRequestFindRepositoryV2}),
65
"_request_class":bzrdir_mod.SmartServerRequestFindRepositoryV2}),
66
66
("find_repositoryV3", {
67
"_request_class": smart_dir.SmartServerRequestFindRepositoryV3}),
67
"_request_class":bzrdir_mod.SmartServerRequestFindRepositoryV3}),
69
to_adapt, result = tests.split_suite_by_re(standard_tests,
69
to_adapt, result = split_suite_by_re(standard_tests,
70
70
"TestSmartServerRequestFindRepository")
71
v2_only, v1_and_2 = tests.split_suite_by_re(to_adapt,
71
v2_only, v1_and_2 = split_suite_by_re(to_adapt,
73
73
tests.multiply_tests(v1_and_2, scenarios, result)
74
74
# The first scenario is only applicable to v1 protocols, it is deleted
106
106
self.transport_server = self.make_transport_server
108
108
def make_transport_server(self):
109
return test_server.SmartTCPServer_for_testing('-' + self.id())
109
return smart.server.SmartTCPServer_for_testing('-' + self.id())
111
111
def get_smart_medium(self):
112
112
"""Get a smart medium to use in tests."""
113
113
return self.get_transport().get_smart_medium()
116
class TestByteStreamToStream(tests.TestCase):
118
def test_repeated_substreams_same_kind_are_one_stream(self):
119
# Make a stream - an iterable of bytestrings.
120
stream = [('text', [versionedfile.FulltextContentFactory(('k1',), None,
121
None, 'foo')]),('text', [
122
versionedfile.FulltextContentFactory(('k2',), None, None, 'bar')])]
123
fmt = bzrdir.format_registry.get('pack-0.92')().repository_format
124
bytes = smart_repo._stream_to_byte_stream(stream, fmt)
126
# Iterate the resulting iterable; checking that we get only one stream
128
fmt, stream = smart_repo._byte_stream_to_stream(bytes)
129
for kind, substream in stream:
130
streams.append((kind, list(substream)))
131
self.assertLength(1, streams)
132
self.assertLength(2, streams[0][1])
135
116
class TestSmartServerResponse(tests.TestCase):
137
118
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', )))
119
self.assertEqual(SmartServerResponse(('ok', )),
120
SmartServerResponse(('ok', )))
121
self.assertEqual(SmartServerResponse(('ok', ), 'body'),
122
SmartServerResponse(('ok', ), 'body'))
123
self.assertNotEqual(SmartServerResponse(('ok', )),
124
SmartServerResponse(('notok', )))
125
self.assertNotEqual(SmartServerResponse(('ok', ), 'body'),
126
SmartServerResponse(('ok', )))
146
127
self.assertNotEqual(None,
147
smart_req.SmartServerResponse(('ok', )))
128
SmartServerResponse(('ok', )))
149
130
def test__str__(self):
150
131
"""SmartServerResponses can be stringified."""
151
132
self.assertEqual(
152
133
"<SuccessfulSmartServerResponse args=('args',) body='body'>",
153
str(smart_req.SuccessfulSmartServerResponse(('args',), 'body')))
134
str(SuccessfulSmartServerResponse(('args',), 'body')))
154
135
self.assertEqual(
155
136
"<FailedSmartServerResponse args=('args',) body='body'>",
156
str(smart_req.FailedSmartServerResponse(('args',), 'body')))
137
str(FailedSmartServerResponse(('args',), 'body')))
159
140
class TestSmartServerRequest(tests.TestCaseWithMemoryTransport):
161
142
def test_translate_client_path(self):
162
143
transport = self.get_transport()
163
request = smart_req.SmartServerRequest(transport, 'foo/')
144
request = SmartServerRequest(transport, 'foo/')
164
145
self.assertEqual('./', request.translate_client_path('foo/'))
165
146
self.assertRaises(
166
147
errors.InvalidURLJoin, request.translate_client_path, 'foo/..')
282
if repo._format.supports_external_lookups:
286
if (smart_dir.SmartServerRequestFindRepositoryV3 ==
250
if (smart.bzrdir.SmartServerRequestFindRepositoryV3 ==
287
251
self._request_class):
288
return smart_req.SuccessfulSmartServerResponse(
289
('ok', '', rich_root, subtrees, external,
252
return SuccessfulSmartServerResponse(
253
('ok', '', rich_root, subtrees, 'no',
290
254
repo._format.network_name()))
291
elif (smart_dir.SmartServerRequestFindRepositoryV2 ==
255
elif (smart.bzrdir.SmartServerRequestFindRepositoryV2 ==
292
256
self._request_class):
293
257
# All tests so far are on formats, and for non-external
295
return smart_req.SuccessfulSmartServerResponse(
296
('ok', '', rich_root, subtrees, external))
259
return SuccessfulSmartServerResponse(
260
('ok', '', rich_root, subtrees, 'no'))
298
return smart_req.SuccessfulSmartServerResponse(
299
('ok', '', rich_root, subtrees))
262
return SuccessfulSmartServerResponse(('ok', '', rich_root, subtrees))
301
264
def test_shared_repository(self):
302
265
"""When there is a shared repository, we get 'ok', 'relpath-to-repo'."""
427
384
"""Initializing an extant directory should fail like the bzrdir api."""
428
385
backing = self.get_transport()
429
386
name = self.make_bzrdir('reference')._format.network_name()
430
request = smart_dir.SmartServerRequestBzrDirInitializeEx(backing)
387
request = smart.bzrdir.SmartServerRequestBzrDirInitializeEx(backing)
431
388
self.make_bzrdir('subdir')
432
389
self.assertRaises(errors.FileExists, request.execute, name, 'subdir',
433
390
'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
393
class TestSmartServerRequestOpenBranch(TestCaseWithChrootedTransport):
505
395
def test_no_branch(self):
506
396
"""When there is no branch, ('nobranch', ) is returned."""
507
397
backing = self.get_transport()
508
request = smart_dir.SmartServerRequestOpenBranch(backing)
398
request = smart.bzrdir.SmartServerRequestOpenBranch(backing)
509
399
self.make_bzrdir('.')
510
self.assertEqual(smart_req.SmartServerResponse(('nobranch', )),
400
self.assertEqual(SmartServerResponse(('nobranch', )),
511
401
request.execute(''))
513
403
def test_branch(self):
514
404
"""When there is a branch, 'ok' is returned."""
515
405
backing = self.get_transport()
516
request = smart_dir.SmartServerRequestOpenBranch(backing)
406
request = smart.bzrdir.SmartServerRequestOpenBranch(backing)
517
407
self.make_branch('.')
518
self.assertEqual(smart_req.SmartServerResponse(('ok', '')),
408
self.assertEqual(SmartServerResponse(('ok', '')),
519
409
request.execute(''))
521
411
def test_branch_reference(self):
522
412
"""When there is a branch reference, the reference URL is returned."""
523
self.vfs_transport_factory = test_server.LocalURLServer
524
413
backing = self.get_transport()
525
request = smart_dir.SmartServerRequestOpenBranch(backing)
414
request = smart.bzrdir.SmartServerRequestOpenBranch(backing)
526
415
branch = self.make_branch('branch')
527
416
checkout = branch.create_checkout('reference',lightweight=True)
528
reference_url = _mod_branch.BranchReferenceFormat().get_reference(
417
reference_url = BranchReferenceFormat().get_reference(checkout.bzrdir)
530
418
self.assertFileEqual(reference_url, 'reference/.bzr/branch/location')
531
self.assertEqual(smart_req.SmartServerResponse(('ok', reference_url)),
419
self.assertEqual(SmartServerResponse(('ok', reference_url)),
532
420
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
423
class TestSmartServerRequestOpenBranchV2(TestCaseWithChrootedTransport):
546
426
"""When there is no branch, ('nobranch', ) is returned."""
547
427
backing = self.get_transport()
548
428
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')),
429
request = smart.bzrdir.SmartServerRequestOpenBranchV2(backing)
430
self.assertEqual(SmartServerResponse(('nobranch', )),
433
def test_branch(self):
434
"""When there is a branch, 'ok' is returned."""
435
backing = self.get_transport()
436
expected = self.make_branch('.')._format.network_name()
437
request = smart.bzrdir.SmartServerRequestOpenBranchV2(backing)
438
self.assertEqual(SuccessfulSmartServerResponse(('branch', expected)),
441
def test_branch_reference(self):
442
"""When there is a branch reference, the reference URL is returned."""
443
backing = self.get_transport()
444
request = smart.bzrdir.SmartServerRequestOpenBranchV2(backing)
445
branch = self.make_branch('branch')
446
checkout = branch.create_checkout('reference',lightweight=True)
447
reference_url = BranchReferenceFormat().get_reference(checkout.bzrdir)
448
self.assertFileEqual(reference_url, 'reference/.bzr/branch/location')
449
self.assertEqual(SuccessfulSmartServerResponse(('ref', reference_url)),
450
request.execute('reference'))
452
def test_stacked_branch(self):
453
"""Opening a stacked branch does not open the stacked-on branch."""
454
trunk = self.make_branch('trunk')
455
feature = self.make_branch('feature', format='1.9')
456
feature.set_stacked_on_url(trunk.base)
458
Branch.hooks.install_named_hook('open', opened_branches.append, None)
459
backing = self.get_transport()
460
request = smart.bzrdir.SmartServerRequestOpenBranchV2(backing)
463
response = request.execute('feature')
465
request.teardown_jail()
466
expected_format = feature._format.network_name()
468
SuccessfulSmartServerResponse(('branch', expected_format)),
470
self.assertLength(1, opened_branches)
670
473
class TestSmartServerRequestRevisionHistory(tests.TestCaseWithMemoryTransport):
705
508
def test_branch_reference(self):
706
509
"""When there is a branch reference, NotBranchError is raised."""
707
510
backing = self.get_transport()
708
request = smart_branch.SmartServerBranchRequest(backing)
511
request = smart.branch.SmartServerBranchRequest(backing)
709
512
branch = self.make_branch('branch')
710
513
checkout = branch.create_checkout('reference',lightweight=True)
711
514
self.assertRaises(errors.NotBranchError,
712
515
request.execute, 'checkout')
715
class TestSmartServerBranchRequestLastRevisionInfo(
716
tests.TestCaseWithMemoryTransport):
518
class TestSmartServerBranchRequestLastRevisionInfo(tests.TestCaseWithMemoryTransport):
718
520
def test_empty(self):
719
521
"""For an empty branch, the result is ('ok', '0', 'null:')."""
720
522
backing = self.get_transport()
721
request = smart_branch.SmartServerBranchRequestLastRevisionInfo(backing)
523
request = smart.branch.SmartServerBranchRequestLastRevisionInfo(backing)
722
524
self.make_branch('.')
723
self.assertEqual(smart_req.SmartServerResponse(('ok', '0', 'null:')),
525
self.assertEqual(SmartServerResponse(('ok', '0', 'null:')),
724
526
request.execute(''))
726
528
def test_not_empty(self):
727
529
"""For a non-empty branch, the result is ('ok', 'revno', 'revid')."""
728
530
backing = self.get_transport()
729
request = smart_branch.SmartServerBranchRequestLastRevisionInfo(backing)
531
request = smart.branch.SmartServerBranchRequestLastRevisionInfo(backing)
730
532
tree = self.make_branch_and_memory_tree('.')
731
533
tree.lock_write()
778
579
def test_value_name(self):
779
580
branch = self.make_branch('.')
780
request = smart_branch.SmartServerBranchRequestSetConfigOption(
581
request = smart.branch.SmartServerBranchRequestSetConfigOption(
781
582
branch.bzrdir.root_transport)
782
583
branch_token, repo_token = self.get_lock_tokens(branch)
783
584
config = branch._get_config()
784
585
result = request.execute('', branch_token, repo_token, 'bar', 'foo',
786
self.assertEqual(smart_req.SuccessfulSmartServerResponse(()), result)
587
self.assertEqual(SuccessfulSmartServerResponse(()), result)
787
588
self.assertEqual('bar', config.get_option('foo'))
791
592
def test_value_name_section(self):
792
593
branch = self.make_branch('.')
793
request = smart_branch.SmartServerBranchRequestSetConfigOption(
594
request = smart.branch.SmartServerBranchRequestSetConfigOption(
794
595
branch.bzrdir.root_transport)
795
596
branch_token, repo_token = self.get_lock_tokens(branch)
796
597
config = branch._get_config()
797
598
result = request.execute('', branch_token, repo_token, 'bar', 'foo',
799
self.assertEqual(smart_req.SuccessfulSmartServerResponse(()), result)
600
self.assertEqual(SuccessfulSmartServerResponse(()), result)
800
601
self.assertEqual('bar', config.get_option('foo', 'gam'))
805
class TestSmartServerBranchRequestSetTagsBytes(TestLockedBranch):
806
# Only called when the branch format and tags match [yay factory
807
# methods] so only need to test straight forward cases.
809
def test_set_bytes(self):
810
base_branch = self.make_branch('base')
811
tag_bytes = base_branch._get_tags_bytes()
812
# get_lock_tokens takes out a lock.
813
branch_token, repo_token = self.get_lock_tokens(base_branch)
814
request = smart_branch.SmartServerBranchSetTagsBytes(
815
self.get_transport())
816
response = request.execute('base', branch_token, repo_token)
817
self.assertEqual(None, response)
818
response = request.do_chunk(tag_bytes)
819
self.assertEqual(None, response)
820
response = request.do_end()
822
smart_req.SuccessfulSmartServerResponse(()), response)
825
def test_lock_failed(self):
826
base_branch = self.make_branch('base')
827
base_branch.lock_write()
828
tag_bytes = base_branch._get_tags_bytes()
829
request = smart_branch.SmartServerBranchSetTagsBytes(
830
self.get_transport())
831
self.assertRaises(errors.TokenMismatch, request.execute,
832
'base', 'wrong token', 'wrong token')
833
# The request handler will keep processing the message parts, so even
834
# if the request fails immediately do_chunk and do_end are still
836
request.do_chunk(tag_bytes)
842
606
class SetLastRevisionTestBase(TestLockedBranch):
843
607
"""Base test case for verbs that implement set_last_revision."""
1059
822
def test_get_parent_none(self):
1060
823
base_branch = self.make_branch('base')
1061
request = smart_branch.SmartServerBranchGetParent(self.get_transport())
824
request = smart.branch.SmartServerBranchGetParent(self.get_transport())
1062
825
response = request.execute('base')
1063
826
self.assertEquals(
1064
smart_req.SuccessfulSmartServerResponse(('',)), response)
827
SuccessfulSmartServerResponse(('',)), response)
1066
829
def test_get_parent_something(self):
1067
830
base_branch = self.make_branch('base')
1068
831
base_branch.set_parent(self.get_url('foo'))
1069
request = smart_branch.SmartServerBranchGetParent(self.get_transport())
832
request = smart.branch.SmartServerBranchGetParent(self.get_transport())
1070
833
response = request.execute('base')
1071
834
self.assertEquals(
1072
smart_req.SuccessfulSmartServerResponse(("../foo",)),
835
SuccessfulSmartServerResponse(("../foo",)),
1076
class TestSmartServerBranchRequestSetParent(TestLockedBranch):
839
class TestSmartServerBranchRequestSetParent(tests.TestCaseWithMemoryTransport):
1078
841
def test_set_parent_none(self):
1079
842
branch = self.make_branch('base', format="1.9")
1080
843
branch.lock_write()
1081
844
branch._set_parent_location('foo')
1083
request = smart_branch.SmartServerBranchRequestSetParentLocation(
846
request = smart.branch.SmartServerBranchRequestSetParentLocation(
1084
847
self.get_transport())
1085
branch_token, repo_token = self.get_lock_tokens(branch)
848
branch_token = branch.lock_write()
849
repo_token = branch.repository.lock_write()
1087
851
response = request.execute('base', branch_token, repo_token, '')
853
branch.repository.unlock()
1090
self.assertEqual(smart_req.SuccessfulSmartServerResponse(()), response)
855
self.assertEqual(SuccessfulSmartServerResponse(()), response)
1091
856
self.assertEqual(None, branch.get_parent())
1093
858
def test_set_parent_something(self):
1094
859
branch = self.make_branch('base', format="1.9")
1095
request = smart_branch.SmartServerBranchRequestSetParentLocation(
860
request = smart.branch.SmartServerBranchRequestSetParentLocation(
1096
861
self.get_transport())
1097
branch_token, repo_token = self.get_lock_tokens(branch)
862
branch_token = branch.lock_write()
863
repo_token = branch.repository.lock_write()
1099
865
response = request.execute('base', branch_token, repo_token,
868
branch.repository.unlock()
1103
self.assertEqual(smart_req.SuccessfulSmartServerResponse(()), response)
870
self.assertEqual(SuccessfulSmartServerResponse(()), response)
1104
871
self.assertEqual('http://bar/', branch.get_parent())
1107
class TestSmartServerBranchRequestGetTagsBytes(
1108
tests.TestCaseWithMemoryTransport):
1109
# Only called when the branch format and tags match [yay factory
1110
# methods] so only need to test straight forward cases.
874
class TestSmartServerBranchRequestGetTagsBytes(tests.TestCaseWithMemoryTransport):
875
# Only called when the branch format and tags match [yay factory
876
# methods] so only need to test straight forward cases.
1112
878
def test_get_bytes(self):
1113
879
base_branch = self.make_branch('base')
1114
request = smart_branch.SmartServerBranchGetTagsBytes(
880
request = smart.branch.SmartServerBranchGetTagsBytes(
1115
881
self.get_transport())
1116
882
response = request.execute('base')
1117
883
self.assertEquals(
1118
smart_req.SuccessfulSmartServerResponse(('',)), response)
884
SuccessfulSmartServerResponse(('',)), response)
1121
887
class TestSmartServerBranchRequestGetStackedOnURL(tests.TestCaseWithMemoryTransport):
1125
891
stacked_branch = self.make_branch('stacked', format='1.6')
1126
892
# typically should be relative
1127
893
stacked_branch.set_stacked_on_url('../base')
1128
request = smart_branch.SmartServerBranchRequestGetStackedOnURL(
894
request = smart.branch.SmartServerBranchRequestGetStackedOnURL(
1129
895
self.get_transport())
1130
896
response = request.execute('stacked')
1131
897
self.assertEquals(
1132
smart_req.SmartServerResponse(('ok', '../base')),
898
SmartServerResponse(('ok', '../base')),
1136
class TestSmartServerBranchRequestLockWrite(TestLockedBranch):
902
class TestSmartServerBranchRequestLockWrite(tests.TestCaseWithMemoryTransport):
1138
904
def setUp(self):
1139
905
tests.TestCaseWithMemoryTransport.setUp(self)
1141
907
def test_lock_write_on_unlocked_branch(self):
1142
908
backing = self.get_transport()
1143
request = smart_branch.SmartServerBranchRequestLockWrite(backing)
909
request = smart.branch.SmartServerBranchRequestLockWrite(backing)
1144
910
branch = self.make_branch('.', format='knit')
1145
911
repository = branch.repository
1146
912
response = request.execute('')
1147
913
branch_nonce = branch.control_files._lock.peek().get('nonce')
1148
914
repository_nonce = repository.control_files._lock.peek().get('nonce')
1149
self.assertEqual(smart_req.SmartServerResponse(
1150
('ok', branch_nonce, repository_nonce)),
916
SmartServerResponse(('ok', branch_nonce, repository_nonce)),
1152
918
# The branch (and associated repository) is now locked. Verify that
1153
919
# with a new branch object.
1154
920
new_branch = repository.bzrdir.open_branch()
1155
921
self.assertRaises(errors.LockContention, new_branch.lock_write)
1157
request = smart_branch.SmartServerBranchRequestUnlock(backing)
923
request = smart.branch.SmartServerBranchRequestUnlock(backing)
1158
924
response = request.execute('', branch_nonce, repository_nonce)
1160
926
def test_lock_write_on_locked_branch(self):
1161
927
backing = self.get_transport()
1162
request = smart_branch.SmartServerBranchRequestLockWrite(backing)
928
request = smart.branch.SmartServerBranchRequestLockWrite(backing)
1163
929
branch = self.make_branch('.')
1164
branch_token = branch.lock_write().branch_token
930
branch_token = branch.lock_write()
1165
931
branch.leave_lock_in_place()
1167
933
response = request.execute('')
1168
934
self.assertEqual(
1169
smart_req.SmartServerResponse(('LockContention',)), response)
935
SmartServerResponse(('LockContention',)), response)
1171
937
branch.lock_write(branch_token)
1172
938
branch.dont_leave_lock_in_place()
1270
1041
def test_unlock_on_unlocked_branch_unlocked_repo(self):
1271
1042
backing = self.get_transport()
1272
request = smart_branch.SmartServerBranchRequestUnlock(backing)
1043
request = smart.branch.SmartServerBranchRequestUnlock(backing)
1273
1044
branch = self.make_branch('.', format='knit')
1274
1045
response = request.execute(
1275
1046
'', 'branch token', 'repo token')
1276
1047
self.assertEqual(
1277
smart_req.SmartServerResponse(('TokenMismatch',)), response)
1048
SmartServerResponse(('TokenMismatch',)), response)
1279
1050
def test_unlock_on_unlocked_branch_locked_repo(self):
1280
1051
backing = self.get_transport()
1281
request = smart_branch.SmartServerBranchRequestUnlock(backing)
1052
request = smart.branch.SmartServerBranchRequestUnlock(backing)
1282
1053
branch = self.make_branch('.', format='knit')
1283
1054
# Lock the repository.
1284
repo_token = branch.repository.lock_write().repository_token
1055
repo_token = branch.repository.lock_write()
1285
1056
branch.repository.leave_lock_in_place()
1286
1057
branch.repository.unlock()
1287
1058
# Issue branch lock_write request on the unlocked branch (with locked
1289
response = request.execute('', 'branch token', repo_token)
1060
response = request.execute(
1061
'', 'branch token', repo_token)
1290
1062
self.assertEqual(
1291
smart_req.SmartServerResponse(('TokenMismatch',)), response)
1063
SmartServerResponse(('TokenMismatch',)), response)
1293
1065
branch.repository.lock_write(repo_token)
1294
1066
branch.repository.dont_leave_lock_in_place()
1316
1088
def test_trivial_bzipped(self):
1317
1089
# This tests that the wire encoding is actually bzipped
1318
1090
backing = self.get_transport()
1319
request = smart_repo.SmartServerRepositoryGetParentMap(backing)
1091
request = smart.repository.SmartServerRepositoryGetParentMap(backing)
1320
1092
tree = self.make_branch_and_memory_tree('.')
1322
1094
self.assertEqual(None,
1323
1095
request.execute('', 'missing-id'))
1324
1096
# Note that it returns a body that is bzipped.
1325
1097
self.assertEqual(
1326
smart_req.SuccessfulSmartServerResponse(('ok', ), bz2.compress('')),
1098
SuccessfulSmartServerResponse(('ok', ), bz2.compress('')),
1327
1099
request.do_body('\n\n0\n'))
1329
1101
def test_trivial_include_missing(self):
1330
1102
backing = self.get_transport()
1331
request = smart_repo.SmartServerRepositoryGetParentMap(backing)
1103
request = smart.repository.SmartServerRepositoryGetParentMap(backing)
1332
1104
tree = self.make_branch_and_memory_tree('.')
1334
1106
self.assertEqual(None,
1335
1107
request.execute('', 'missing-id', 'include-missing:'))
1336
1108
self.assertEqual(
1337
smart_req.SuccessfulSmartServerResponse(('ok', ),
1109
SuccessfulSmartServerResponse(('ok', ),
1338
1110
bz2.compress('missing:missing-id')),
1339
1111
request.do_body('\n\n0\n'))
1342
class TestSmartServerRepositoryGetRevisionGraph(
1343
tests.TestCaseWithMemoryTransport):
1114
class TestSmartServerRepositoryGetRevisionGraph(tests.TestCaseWithMemoryTransport):
1345
1116
def test_none_argument(self):
1346
1117
backing = self.get_transport()
1347
request = smart_repo.SmartServerRepositoryGetRevisionGraph(backing)
1118
request = smart.repository.SmartServerRepositoryGetRevisionGraph(backing)
1348
1119
tree = self.make_branch_and_memory_tree('.')
1349
1120
tree.lock_write()
1405
1175
tree.commit('2nd commit', rev_id=rev2_id_utf8)
1408
self.assertEqual(smart_req.SmartServerResponse(('ok', rev1_id_utf8)),
1178
self.assertEqual(SmartServerResponse(('ok', rev1_id_utf8)),
1409
1179
request.execute('', 1, (2, rev2_id_utf8)))
1411
1181
def test_known_revid_missing(self):
1412
1182
backing = self.get_transport()
1413
request = smart_repo.SmartServerRepositoryGetRevIdForRevno(backing)
1183
request = smart.repository.SmartServerRepositoryGetRevIdForRevno(backing)
1414
1184
repo = self.make_repository('.')
1415
1185
self.assertEqual(
1416
smart_req.FailedSmartServerResponse(('nosuchrevision', 'ghost')),
1186
FailedSmartServerResponse(('nosuchrevision', 'ghost')),
1417
1187
request.execute('', 1, (2, 'ghost')))
1419
1189
def test_history_incomplete(self):
1420
1190
backing = self.get_transport()
1421
request = smart_repo.SmartServerRepositoryGetRevIdForRevno(backing)
1191
request = smart.repository.SmartServerRepositoryGetRevIdForRevno(backing)
1422
1192
parent = self.make_branch_and_memory_tree('parent', format='1.9')
1424
parent.add([''], ['TREE_ROOT'])
1425
1193
r1 = parent.commit(message='first commit')
1426
1194
r2 = parent.commit(message='second commit')
1428
1195
local = self.make_branch_and_memory_tree('local', format='1.9')
1429
1196
local.branch.pull(parent.branch)
1430
1197
local.set_parent_ids([r2])
1583
1349
def test_lock_write_on_unlocked_repo(self):
1584
1350
backing = self.get_transport()
1585
request = smart_repo.SmartServerRepositoryLockWrite(backing)
1351
request = smart.repository.SmartServerRepositoryLockWrite(backing)
1586
1352
repository = self.make_repository('.', format='knit')
1587
1353
response = request.execute('')
1588
1354
nonce = repository.control_files._lock.peek().get('nonce')
1589
self.assertEqual(smart_req.SmartServerResponse(('ok', nonce)), response)
1355
self.assertEqual(SmartServerResponse(('ok', nonce)), response)
1590
1356
# The repository is now locked. Verify that with a new repository
1592
1358
new_repo = repository.bzrdir.open_repository()
1593
1359
self.assertRaises(errors.LockContention, new_repo.lock_write)
1595
request = smart_repo.SmartServerRepositoryUnlock(backing)
1361
request = smart.repository.SmartServerRepositoryUnlock(backing)
1596
1362
response = request.execute('', nonce)
1598
1364
def test_lock_write_on_locked_repo(self):
1599
1365
backing = self.get_transport()
1600
request = smart_repo.SmartServerRepositoryLockWrite(backing)
1366
request = smart.repository.SmartServerRepositoryLockWrite(backing)
1601
1367
repository = self.make_repository('.', format='knit')
1602
repo_token = repository.lock_write().repository_token
1368
repo_token = repository.lock_write()
1603
1369
repository.leave_lock_in_place()
1604
1370
repository.unlock()
1605
1371
response = request.execute('')
1606
1372
self.assertEqual(
1607
smart_req.SmartServerResponse(('LockContention',)), response)
1373
SmartServerResponse(('LockContention',)), response)
1609
1375
repository.lock_write(repo_token)
1610
1376
repository.dont_leave_lock_in_place()
1631
1397
def test_insert_stream_empty(self):
1632
1398
backing = self.get_transport()
1633
request = smart_repo.SmartServerRepositoryInsertStream(backing)
1399
request = smart.repository.SmartServerRepositoryInsertStream(backing)
1634
1400
repository = self.make_repository('.')
1635
1401
response = request.execute('', '')
1636
1402
self.assertEqual(None, response)
1637
1403
response = request.do_chunk(self.make_empty_byte_stream(repository))
1638
1404
self.assertEqual(None, response)
1639
1405
response = request.do_end()
1640
self.assertEqual(smart_req.SmartServerResponse(('ok', )), response)
1406
self.assertEqual(SmartServerResponse(('ok', )), response)
1643
1409
class TestSmartServerRepositoryInsertStreamLocked(TestInsertStreamBase):
1645
1411
def test_insert_stream_empty(self):
1646
1412
backing = self.get_transport()
1647
request = smart_repo.SmartServerRepositoryInsertStreamLocked(
1413
request = smart.repository.SmartServerRepositoryInsertStreamLocked(
1649
1415
repository = self.make_repository('.', format='knit')
1650
lock_token = repository.lock_write().repository_token
1416
lock_token = repository.lock_write()
1651
1417
response = request.execute('', '', lock_token)
1652
1418
self.assertEqual(None, response)
1653
1419
response = request.do_chunk(self.make_empty_byte_stream(repository))
1654
1420
self.assertEqual(None, response)
1655
1421
response = request.do_end()
1656
self.assertEqual(smart_req.SmartServerResponse(('ok', )), response)
1422
self.assertEqual(SmartServerResponse(('ok', )), response)
1657
1423
repository.unlock()
1659
1425
def test_insert_stream_with_wrong_lock_token(self):
1660
1426
backing = self.get_transport()
1661
request = smart_repo.SmartServerRepositoryInsertStreamLocked(
1427
request = smart.repository.SmartServerRepositoryInsertStreamLocked(
1663
1429
repository = self.make_repository('.', format='knit')
1664
lock_token = repository.lock_write().repository_token
1430
lock_token = repository.lock_write()
1665
1431
self.assertRaises(
1666
1432
errors.TokenMismatch, request.execute, '', '', 'wrong-token')
1667
1433
repository.unlock()
1691
1457
def test_unlock_on_unlocked_repo(self):
1692
1458
backing = self.get_transport()
1693
request = smart_repo.SmartServerRepositoryUnlock(backing)
1459
request = smart.repository.SmartServerRepositoryUnlock(backing)
1694
1460
repository = self.make_repository('.', format='knit')
1695
1461
response = request.execute('', 'some token')
1696
1462
self.assertEqual(
1697
smart_req.SmartServerResponse(('TokenMismatch',)), response)
1463
SmartServerResponse(('TokenMismatch',)), response)
1700
1466
class TestSmartServerIsReadonly(tests.TestCaseWithMemoryTransport):
1702
1468
def test_is_readonly_no(self):
1703
1469
backing = self.get_transport()
1704
request = smart_req.SmartServerIsReadonly(backing)
1470
request = smart.request.SmartServerIsReadonly(backing)
1705
1471
response = request.execute()
1706
1472
self.assertEqual(
1707
smart_req.SmartServerResponse(('no',)), response)
1473
SmartServerResponse(('no',)), response)
1709
1475
def test_is_readonly_yes(self):
1710
1476
backing = self.get_readonly_transport()
1711
request = smart_req.SmartServerIsReadonly(backing)
1477
request = smart.request.SmartServerIsReadonly(backing)
1712
1478
response = request.execute()
1713
1479
self.assertEqual(
1714
smart_req.SmartServerResponse(('yes',)), response)
1717
class TestSmartServerRepositorySetMakeWorkingTrees(
1718
tests.TestCaseWithMemoryTransport):
1480
SmartServerResponse(('yes',)), response)
1483
class TestSmartServerRepositorySetMakeWorkingTrees(tests.TestCaseWithMemoryTransport):
1720
1485
def test_set_false(self):
1721
1486
backing = self.get_transport()
1722
1487
repo = self.make_repository('.', shared=True)
1723
1488
repo.set_make_working_trees(True)
1724
request_class = smart_repo.SmartServerRepositorySetMakeWorkingTrees
1489
request_class = smart.repository.SmartServerRepositorySetMakeWorkingTrees
1725
1490
request = request_class(backing)
1726
self.assertEqual(smart_req.SuccessfulSmartServerResponse(('ok',)),
1491
self.assertEqual(SuccessfulSmartServerResponse(('ok',)),
1727
1492
request.execute('', 'False'))
1728
1493
repo = repo.bzrdir.open_repository()
1729
1494
self.assertFalse(repo.make_working_trees())
1811
1563
"""All registered request_handlers can be found."""
1812
1564
# If there's a typo in a register_lazy call, this loop will fail with
1813
1565
# an AttributeError.
1814
for key, item in smart_req.request_handlers.iteritems():
1566
for key, item in smart.request.request_handlers.iteritems():
1817
1569
def assertHandlerEqual(self, verb, handler):
1818
self.assertEqual(smart_req.request_handlers.get(verb), handler)
1570
self.assertEqual(smart.request.request_handlers.get(verb), handler)
1820
1572
def test_registered_methods(self):
1821
1573
"""Test that known methods are registered to the correct object."""
1822
1574
self.assertHandlerEqual('Branch.get_config_file',
1823
smart_branch.SmartServerBranchGetConfigFile)
1575
smart.branch.SmartServerBranchGetConfigFile)
1824
1576
self.assertHandlerEqual('Branch.get_parent',
1825
smart_branch.SmartServerBranchGetParent)
1577
smart.branch.SmartServerBranchGetParent)
1826
1578
self.assertHandlerEqual('Branch.get_tags_bytes',
1827
smart_branch.SmartServerBranchGetTagsBytes)
1579
smart.branch.SmartServerBranchGetTagsBytes)
1828
1580
self.assertHandlerEqual('Branch.lock_write',
1829
smart_branch.SmartServerBranchRequestLockWrite)
1581
smart.branch.SmartServerBranchRequestLockWrite)
1830
1582
self.assertHandlerEqual('Branch.last_revision_info',
1831
smart_branch.SmartServerBranchRequestLastRevisionInfo)
1583
smart.branch.SmartServerBranchRequestLastRevisionInfo)
1832
1584
self.assertHandlerEqual('Branch.revision_history',
1833
smart_branch.SmartServerRequestRevisionHistory)
1585
smart.branch.SmartServerRequestRevisionHistory)
1834
1586
self.assertHandlerEqual('Branch.set_config_option',
1835
smart_branch.SmartServerBranchRequestSetConfigOption)
1587
smart.branch.SmartServerBranchRequestSetConfigOption)
1836
1588
self.assertHandlerEqual('Branch.set_last_revision',
1837
smart_branch.SmartServerBranchRequestSetLastRevision)
1589
smart.branch.SmartServerBranchRequestSetLastRevision)
1838
1590
self.assertHandlerEqual('Branch.set_last_revision_info',
1839
smart_branch.SmartServerBranchRequestSetLastRevisionInfo)
1591
smart.branch.SmartServerBranchRequestSetLastRevisionInfo)
1840
1592
self.assertHandlerEqual('Branch.set_last_revision_ex',
1841
smart_branch.SmartServerBranchRequestSetLastRevisionEx)
1593
smart.branch.SmartServerBranchRequestSetLastRevisionEx)
1842
1594
self.assertHandlerEqual('Branch.set_parent_location',
1843
smart_branch.SmartServerBranchRequestSetParentLocation)
1595
smart.branch.SmartServerBranchRequestSetParentLocation)
1844
1596
self.assertHandlerEqual('Branch.unlock',
1845
smart_branch.SmartServerBranchRequestUnlock)
1597
smart.branch.SmartServerBranchRequestUnlock)
1846
1598
self.assertHandlerEqual('BzrDir.find_repository',
1847
smart_dir.SmartServerRequestFindRepositoryV1)
1599
smart.bzrdir.SmartServerRequestFindRepositoryV1)
1848
1600
self.assertHandlerEqual('BzrDir.find_repositoryV2',
1849
smart_dir.SmartServerRequestFindRepositoryV2)
1601
smart.bzrdir.SmartServerRequestFindRepositoryV2)
1850
1602
self.assertHandlerEqual('BzrDirFormat.initialize',
1851
smart_dir.SmartServerRequestInitializeBzrDir)
1603
smart.bzrdir.SmartServerRequestInitializeBzrDir)
1852
1604
self.assertHandlerEqual('BzrDirFormat.initialize_ex_1.16',
1853
smart_dir.SmartServerRequestBzrDirInitializeEx)
1605
smart.bzrdir.SmartServerRequestBzrDirInitializeEx)
1854
1606
self.assertHandlerEqual('BzrDir.cloning_metadir',
1855
smart_dir.SmartServerBzrDirRequestCloningMetaDir)
1607
smart.bzrdir.SmartServerBzrDirRequestCloningMetaDir)
1856
1608
self.assertHandlerEqual('BzrDir.get_config_file',
1857
smart_dir.SmartServerBzrDirRequestConfigFile)
1609
smart.bzrdir.SmartServerBzrDirRequestConfigFile)
1858
1610
self.assertHandlerEqual('BzrDir.open_branch',
1859
smart_dir.SmartServerRequestOpenBranch)
1611
smart.bzrdir.SmartServerRequestOpenBranch)
1860
1612
self.assertHandlerEqual('BzrDir.open_branchV2',
1861
smart_dir.SmartServerRequestOpenBranchV2)
1862
self.assertHandlerEqual('BzrDir.open_branchV3',
1863
smart_dir.SmartServerRequestOpenBranchV3)
1613
smart.bzrdir.SmartServerRequestOpenBranchV2)
1864
1614
self.assertHandlerEqual('PackRepository.autopack',
1865
smart_packrepo.SmartServerPackRepositoryAutopack)
1615
smart.packrepository.SmartServerPackRepositoryAutopack)
1866
1616
self.assertHandlerEqual('Repository.gather_stats',
1867
smart_repo.SmartServerRepositoryGatherStats)
1617
smart.repository.SmartServerRepositoryGatherStats)
1868
1618
self.assertHandlerEqual('Repository.get_parent_map',
1869
smart_repo.SmartServerRepositoryGetParentMap)
1619
smart.repository.SmartServerRepositoryGetParentMap)
1870
1620
self.assertHandlerEqual('Repository.get_rev_id_for_revno',
1871
smart_repo.SmartServerRepositoryGetRevIdForRevno)
1621
smart.repository.SmartServerRepositoryGetRevIdForRevno)
1872
1622
self.assertHandlerEqual('Repository.get_revision_graph',
1873
smart_repo.SmartServerRepositoryGetRevisionGraph)
1623
smart.repository.SmartServerRepositoryGetRevisionGraph)
1874
1624
self.assertHandlerEqual('Repository.get_stream',
1875
smart_repo.SmartServerRepositoryGetStream)
1625
smart.repository.SmartServerRepositoryGetStream)
1876
1626
self.assertHandlerEqual('Repository.has_revision',
1877
smart_repo.SmartServerRequestHasRevision)
1627
smart.repository.SmartServerRequestHasRevision)
1878
1628
self.assertHandlerEqual('Repository.insert_stream',
1879
smart_repo.SmartServerRepositoryInsertStream)
1629
smart.repository.SmartServerRepositoryInsertStream)
1880
1630
self.assertHandlerEqual('Repository.insert_stream_locked',
1881
smart_repo.SmartServerRepositoryInsertStreamLocked)
1631
smart.repository.SmartServerRepositoryInsertStreamLocked)
1882
1632
self.assertHandlerEqual('Repository.is_shared',
1883
smart_repo.SmartServerRepositoryIsShared)
1633
smart.repository.SmartServerRepositoryIsShared)
1884
1634
self.assertHandlerEqual('Repository.lock_write',
1885
smart_repo.SmartServerRepositoryLockWrite)
1635
smart.repository.SmartServerRepositoryLockWrite)
1886
1636
self.assertHandlerEqual('Repository.tarball',
1887
smart_repo.SmartServerRepositoryTarball)
1637
smart.repository.SmartServerRepositoryTarball)
1888
1638
self.assertHandlerEqual('Repository.unlock',
1889
smart_repo.SmartServerRepositoryUnlock)
1639
smart.repository.SmartServerRepositoryUnlock)
1890
1640
self.assertHandlerEqual('Transport.is_readonly',
1891
smart_req.SmartServerIsReadonly)
1641
smart.request.SmartServerIsReadonly)