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 (
39
from bzrlib.branch import Branch, BranchReferenceFormat
40
import bzrlib.smart.branch
41
import bzrlib.smart.bzrdir, bzrlib.smart.bzrdir as smart_dir
42
import bzrlib.smart.packrepository
43
import bzrlib.smart.repository
44
from bzrlib.smart.request import (
45
FailedSmartServerResponse,
48
SuccessfulSmartServerResponse,
50
from bzrlib.tests import (
53
from bzrlib.transport import chroot, get_transport
54
from bzrlib.util import bencode
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'."""
378
337
def test_missing_dir(self):
379
338
"""Initializing a missing directory should fail like the bzrdir api."""
380
339
backing = self.get_transport()
381
request = smart_dir.SmartServerRequestInitializeBzrDir(backing)
340
request = smart.bzrdir.SmartServerRequestInitializeBzrDir(backing)
382
341
self.assertRaises(errors.NoSuchFile,
383
342
request.execute, 'subdir')
385
344
def test_initialized_dir(self):
386
345
"""Initializing an extant bzrdir should fail like the bzrdir api."""
387
346
backing = self.get_transport()
388
request = smart_dir.SmartServerRequestInitializeBzrDir(backing)
347
request = smart.bzrdir.SmartServerRequestInitializeBzrDir(backing)
389
348
self.make_bzrdir('subdir')
390
349
self.assertRaises(errors.FileExists,
391
350
request.execute, 'subdir')
394
class TestSmartServerRequestBzrDirInitializeEx(
395
tests.TestCaseWithMemoryTransport):
396
"""Basic tests for BzrDir.initialize_ex_1.16 in the smart server.
398
The main unit tests in test_bzrdir exercise the API comprehensively.
401
def test_empty_dir(self):
402
"""Initializing an empty dir should succeed and do it."""
403
backing = self.get_transport()
404
name = self.make_bzrdir('reference')._format.network_name()
405
request = smart_dir.SmartServerRequestBzrDirInitializeEx(backing)
407
smart_req.SmartServerResponse(('', '', '', '', '', '', name,
408
'False', '', '', '')),
409
request.execute(name, '', 'True', 'False', 'False', '', '', '', '',
411
made_dir = bzrdir.BzrDir.open_from_transport(backing)
412
# no branch, tree or repository is expected with the current
414
self.assertRaises(errors.NoWorkingTree, made_dir.open_workingtree)
415
self.assertRaises(errors.NotBranchError, made_dir.open_branch)
416
self.assertRaises(errors.NoRepositoryPresent, made_dir.open_repository)
418
def test_missing_dir(self):
419
"""Initializing a missing directory should fail like the bzrdir api."""
420
backing = self.get_transport()
421
name = self.make_bzrdir('reference')._format.network_name()
422
request = smart_dir.SmartServerRequestBzrDirInitializeEx(backing)
423
self.assertRaises(errors.NoSuchFile, request.execute, name,
424
'subdir/dir', 'False', 'False', 'False', '', '', '', '', 'False')
426
def test_initialized_dir(self):
427
"""Initializing an extant directory should fail like the bzrdir api."""
428
backing = self.get_transport()
429
name = self.make_bzrdir('reference')._format.network_name()
430
request = smart_dir.SmartServerRequestBzrDirInitializeEx(backing)
431
self.make_bzrdir('subdir')
432
self.assertRaises(errors.FileExists, request.execute, name, 'subdir',
433
'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
353
class TestSmartServerRequestOpenBranch(TestCaseWithChrootedTransport):
505
355
def test_no_branch(self):
506
356
"""When there is no branch, ('nobranch', ) is returned."""
507
357
backing = self.get_transport()
508
request = smart_dir.SmartServerRequestOpenBranch(backing)
358
request = smart.bzrdir.SmartServerRequestOpenBranch(backing)
509
359
self.make_bzrdir('.')
510
self.assertEqual(smart_req.SmartServerResponse(('nobranch', )),
360
self.assertEqual(SmartServerResponse(('nobranch', )),
511
361
request.execute(''))
513
363
def test_branch(self):
514
364
"""When there is a branch, 'ok' is returned."""
515
365
backing = self.get_transport()
516
request = smart_dir.SmartServerRequestOpenBranch(backing)
366
request = smart.bzrdir.SmartServerRequestOpenBranch(backing)
517
367
self.make_branch('.')
518
self.assertEqual(smart_req.SmartServerResponse(('ok', '')),
368
self.assertEqual(SmartServerResponse(('ok', '')),
519
369
request.execute(''))
521
371
def test_branch_reference(self):
522
372
"""When there is a branch reference, the reference URL is returned."""
523
self.vfs_transport_factory = test_server.LocalURLServer
524
373
backing = self.get_transport()
525
request = smart_dir.SmartServerRequestOpenBranch(backing)
374
request = smart.bzrdir.SmartServerRequestOpenBranch(backing)
526
375
branch = self.make_branch('branch')
527
376
checkout = branch.create_checkout('reference',lightweight=True)
528
reference_url = _mod_branch.BranchReferenceFormat().get_reference(
377
reference_url = BranchReferenceFormat().get_reference(checkout.bzrdir)
530
378
self.assertFileEqual(reference_url, 'reference/.bzr/branch/location')
531
self.assertEqual(smart_req.SmartServerResponse(('ok', reference_url)),
379
self.assertEqual(SmartServerResponse(('ok', reference_url)),
532
380
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
383
class TestSmartServerRequestOpenBranchV2(TestCaseWithChrootedTransport):
546
386
"""When there is no branch, ('nobranch', ) is returned."""
547
387
backing = self.get_transport()
548
388
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')),
389
request = smart.bzrdir.SmartServerRequestOpenBranchV2(backing)
390
self.assertEqual(SmartServerResponse(('nobranch', )),
393
def test_branch(self):
394
"""When there is a branch, 'ok' is returned."""
395
backing = self.get_transport()
396
expected = self.make_branch('.')._format.network_name()
397
request = smart.bzrdir.SmartServerRequestOpenBranchV2(backing)
398
self.assertEqual(SuccessfulSmartServerResponse(('branch', expected)),
401
def test_branch_reference(self):
402
"""When there is a branch reference, the reference URL is returned."""
403
backing = self.get_transport()
404
request = smart.bzrdir.SmartServerRequestOpenBranchV2(backing)
405
branch = self.make_branch('branch')
406
checkout = branch.create_checkout('reference',lightweight=True)
407
reference_url = BranchReferenceFormat().get_reference(checkout.bzrdir)
408
self.assertFileEqual(reference_url, 'reference/.bzr/branch/location')
409
self.assertEqual(SuccessfulSmartServerResponse(('ref', reference_url)),
410
request.execute('reference'))
412
def test_stacked_branch(self):
413
"""Opening a stacked branch does not open the stacked-on branch."""
414
trunk = self.make_branch('trunk')
415
feature = self.make_branch('feature', format='1.9')
416
feature.set_stacked_on_url(trunk.base)
418
Branch.hooks.install_named_hook('open', opened_branches.append, None)
419
backing = self.get_transport()
420
request = smart.bzrdir.SmartServerRequestOpenBranchV2(backing)
423
response = request.execute('feature')
425
request.teardown_jail()
426
expected_format = feature._format.network_name()
428
SuccessfulSmartServerResponse(('branch', expected_format)),
430
self.assertLength(1, opened_branches)
670
433
class TestSmartServerRequestRevisionHistory(tests.TestCaseWithMemoryTransport):
705
468
def test_branch_reference(self):
706
469
"""When there is a branch reference, NotBranchError is raised."""
707
470
backing = self.get_transport()
708
request = smart_branch.SmartServerBranchRequest(backing)
471
request = smart.branch.SmartServerBranchRequest(backing)
709
472
branch = self.make_branch('branch')
710
473
checkout = branch.create_checkout('reference',lightweight=True)
711
474
self.assertRaises(errors.NotBranchError,
712
475
request.execute, 'checkout')
715
class TestSmartServerBranchRequestLastRevisionInfo(
716
tests.TestCaseWithMemoryTransport):
478
class TestSmartServerBranchRequestLastRevisionInfo(tests.TestCaseWithMemoryTransport):
718
480
def test_empty(self):
719
481
"""For an empty branch, the result is ('ok', '0', 'null:')."""
720
482
backing = self.get_transport()
721
request = smart_branch.SmartServerBranchRequestLastRevisionInfo(backing)
483
request = smart.branch.SmartServerBranchRequestLastRevisionInfo(backing)
722
484
self.make_branch('.')
723
self.assertEqual(smart_req.SmartServerResponse(('ok', '0', 'null:')),
485
self.assertEqual(SmartServerResponse(('ok', '0', 'null:')),
724
486
request.execute(''))
726
488
def test_not_empty(self):
727
489
"""For a non-empty branch, the result is ('ok', 'revno', 'revid')."""
728
490
backing = self.get_transport()
729
request = smart_branch.SmartServerBranchRequestLastRevisionInfo(backing)
491
request = smart.branch.SmartServerBranchRequestLastRevisionInfo(backing)
730
492
tree = self.make_branch_and_memory_tree('.')
731
493
tree.lock_write()
778
539
def test_value_name(self):
779
540
branch = self.make_branch('.')
780
request = smart_branch.SmartServerBranchRequestSetConfigOption(
541
request = smart.branch.SmartServerBranchRequestSetConfigOption(
781
542
branch.bzrdir.root_transport)
782
543
branch_token, repo_token = self.get_lock_tokens(branch)
783
544
config = branch._get_config()
784
545
result = request.execute('', branch_token, repo_token, 'bar', 'foo',
786
self.assertEqual(smart_req.SuccessfulSmartServerResponse(()), result)
547
self.assertEqual(SuccessfulSmartServerResponse(()), result)
787
548
self.assertEqual('bar', config.get_option('foo'))
791
550
def test_value_name_section(self):
792
551
branch = self.make_branch('.')
793
request = smart_branch.SmartServerBranchRequestSetConfigOption(
552
request = smart.branch.SmartServerBranchRequestSetConfigOption(
794
553
branch.bzrdir.root_transport)
795
554
branch_token, repo_token = self.get_lock_tokens(branch)
796
555
config = branch._get_config()
797
556
result = request.execute('', branch_token, repo_token, 'bar', 'foo',
799
self.assertEqual(smart_req.SuccessfulSmartServerResponse(()), result)
558
self.assertEqual(SuccessfulSmartServerResponse(()), result)
800
559
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
562
class SetLastRevisionTestBase(TestLockedBranch):
1145
863
def test_lock_write_on_unlocked_branch(self):
1146
864
backing = self.get_transport()
1147
request = smart_branch.SmartServerBranchRequestLockWrite(backing)
865
request = smart.branch.SmartServerBranchRequestLockWrite(backing)
1148
866
branch = self.make_branch('.', format='knit')
1149
867
repository = branch.repository
1150
868
response = request.execute('')
1151
869
branch_nonce = branch.control_files._lock.peek().get('nonce')
1152
870
repository_nonce = repository.control_files._lock.peek().get('nonce')
1153
self.assertEqual(smart_req.SmartServerResponse(
1154
('ok', branch_nonce, repository_nonce)),
872
SmartServerResponse(('ok', branch_nonce, repository_nonce)),
1156
874
# The branch (and associated repository) is now locked. Verify that
1157
875
# with a new branch object.
1158
876
new_branch = repository.bzrdir.open_branch()
1159
877
self.assertRaises(errors.LockContention, new_branch.lock_write)
1161
request = smart_branch.SmartServerBranchRequestUnlock(backing)
1162
response = request.execute('', branch_nonce, repository_nonce)
1164
879
def test_lock_write_on_locked_branch(self):
1165
880
backing = self.get_transport()
1166
request = smart_branch.SmartServerBranchRequestLockWrite(backing)
881
request = smart.branch.SmartServerBranchRequestLockWrite(backing)
1167
882
branch = self.make_branch('.')
1168
branch_token = branch.lock_write()
1169
884
branch.leave_lock_in_place()
1171
886
response = request.execute('')
1172
887
self.assertEqual(
1173
smart_req.SmartServerResponse(('LockContention',)), response)
1175
branch.lock_write(branch_token)
1176
branch.dont_leave_lock_in_place()
888
SmartServerResponse(('LockContention',)), response)
1179
890
def test_lock_write_with_tokens_on_locked_branch(self):
1180
891
backing = self.get_transport()
1181
request = smart_branch.SmartServerBranchRequestLockWrite(backing)
892
request = smart.branch.SmartServerBranchRequestLockWrite(backing)
1182
893
branch = self.make_branch('.', format='knit')
1183
894
branch_token = branch.lock_write()
1184
895
repo_token = branch.repository.lock_write()
1212
915
response = request.execute('',
1213
916
branch_token+'xxx', repo_token)
1214
917
self.assertEqual(
1215
smart_req.SmartServerResponse(('TokenMismatch',)), response)
1217
branch.repository.lock_write(repo_token)
1218
branch.repository.dont_leave_lock_in_place()
1219
branch.repository.unlock()
1220
branch.lock_write(branch_token)
1221
branch.dont_leave_lock_in_place()
918
SmartServerResponse(('TokenMismatch',)), response)
1224
920
def test_lock_write_on_locked_repo(self):
1225
921
backing = self.get_transport()
1226
request = smart_branch.SmartServerBranchRequestLockWrite(backing)
922
request = smart.branch.SmartServerBranchRequestLockWrite(backing)
1227
923
branch = self.make_branch('.', format='knit')
1228
repo = branch.repository
1229
repo_token = repo.lock_write()
1230
repo.leave_lock_in_place()
924
branch.repository.lock_write()
925
branch.repository.leave_lock_in_place()
926
branch.repository.unlock()
1232
927
response = request.execute('')
1233
928
self.assertEqual(
1234
smart_req.SmartServerResponse(('LockContention',)), response)
1236
repo.lock_write(repo_token)
1237
repo.dont_leave_lock_in_place()
929
SmartServerResponse(('LockContention',)), response)
1240
931
def test_lock_write_on_readonly_transport(self):
1241
932
backing = self.get_readonly_transport()
1242
request = smart_branch.SmartServerBranchRequestLockWrite(backing)
933
request = smart.branch.SmartServerBranchRequestLockWrite(backing)
1243
934
branch = self.make_branch('.')
1244
935
root = self.get_transport().clone('/')
1245
936
path = urlutils.relative_url(root.base, self.get_transport().base)
1327
1014
def test_trivial_bzipped(self):
1328
1015
# This tests that the wire encoding is actually bzipped
1329
1016
backing = self.get_transport()
1330
request = smart_repo.SmartServerRepositoryGetParentMap(backing)
1017
request = smart.repository.SmartServerRepositoryGetParentMap(backing)
1331
1018
tree = self.make_branch_and_memory_tree('.')
1333
1020
self.assertEqual(None,
1334
1021
request.execute('', 'missing-id'))
1335
1022
# Note that it returns a body that is bzipped.
1336
1023
self.assertEqual(
1337
smart_req.SuccessfulSmartServerResponse(('ok', ), bz2.compress('')),
1024
SuccessfulSmartServerResponse(('ok', ), bz2.compress('')),
1338
1025
request.do_body('\n\n0\n'))
1340
1027
def test_trivial_include_missing(self):
1341
1028
backing = self.get_transport()
1342
request = smart_repo.SmartServerRepositoryGetParentMap(backing)
1029
request = smart.repository.SmartServerRepositoryGetParentMap(backing)
1343
1030
tree = self.make_branch_and_memory_tree('.')
1345
1032
self.assertEqual(None,
1346
1033
request.execute('', 'missing-id', 'include-missing:'))
1347
1034
self.assertEqual(
1348
smart_req.SuccessfulSmartServerResponse(('ok', ),
1035
SuccessfulSmartServerResponse(('ok', ),
1349
1036
bz2.compress('missing:missing-id')),
1350
1037
request.do_body('\n\n0\n'))
1353
class TestSmartServerRepositoryGetRevisionGraph(
1354
tests.TestCaseWithMemoryTransport):
1040
class TestSmartServerRepositoryGetRevisionGraph(tests.TestCaseWithMemoryTransport):
1356
1042
def test_none_argument(self):
1357
1043
backing = self.get_transport()
1358
request = smart_repo.SmartServerRepositoryGetRevisionGraph(backing)
1044
request = smart.repository.SmartServerRepositoryGetRevisionGraph(backing)
1359
1045
tree = self.make_branch_and_memory_tree('.')
1360
1046
tree.lock_write()
1398
1084
# Note that it still returns body (of zero bytes).
1399
self.assertEqual(smart_req.SmartServerResponse(
1400
('nosuchrevision', 'missingrevision', ), ''),
1401
request.execute('', 'missingrevision'))
1404
class TestSmartServerRepositoryGetRevIdForRevno(
1405
tests.TestCaseWithMemoryTransport):
1407
def test_revno_found(self):
1408
backing = self.get_transport()
1409
request = smart_repo.SmartServerRepositoryGetRevIdForRevno(backing)
1410
tree = self.make_branch_and_memory_tree('.')
1413
rev1_id_utf8 = u'\xc8'.encode('utf-8')
1414
rev2_id_utf8 = u'\xc9'.encode('utf-8')
1415
tree.commit('1st commit', rev_id=rev1_id_utf8)
1416
tree.commit('2nd commit', rev_id=rev2_id_utf8)
1419
self.assertEqual(smart_req.SmartServerResponse(('ok', rev1_id_utf8)),
1420
request.execute('', 1, (2, rev2_id_utf8)))
1422
def test_known_revid_missing(self):
1423
backing = self.get_transport()
1424
request = smart_repo.SmartServerRepositoryGetRevIdForRevno(backing)
1425
repo = self.make_repository('.')
1427
smart_req.FailedSmartServerResponse(('nosuchrevision', 'ghost')),
1428
request.execute('', 1, (2, 'ghost')))
1430
def test_history_incomplete(self):
1431
backing = self.get_transport()
1432
request = smart_repo.SmartServerRepositoryGetRevIdForRevno(backing)
1433
parent = self.make_branch_and_memory_tree('parent', format='1.9')
1435
parent.add([''], ['TREE_ROOT'])
1436
r1 = parent.commit(message='first commit')
1437
r2 = parent.commit(message='second commit')
1439
local = self.make_branch_and_memory_tree('local', format='1.9')
1440
local.branch.pull(parent.branch)
1441
local.set_parent_ids([r2])
1442
r3 = local.commit(message='local commit')
1443
local.branch.create_clone_on_transport(
1444
self.get_transport('stacked'), stacked_on=self.get_url('parent'))
1446
smart_req.SmartServerResponse(('history-incomplete', 2, r2)),
1447
request.execute('stacked', 1, (3, r3)))
1086
SmartServerResponse(('nosuchrevision', 'missingrevision', ), ''),
1087
request.execute('', 'missingrevision'))
1450
1090
class TestSmartServerRepositoryGetStream(tests.TestCaseWithMemoryTransport):
1594
1234
def test_lock_write_on_unlocked_repo(self):
1595
1235
backing = self.get_transport()
1596
request = smart_repo.SmartServerRepositoryLockWrite(backing)
1236
request = smart.repository.SmartServerRepositoryLockWrite(backing)
1597
1237
repository = self.make_repository('.', format='knit')
1598
1238
response = request.execute('')
1599
1239
nonce = repository.control_files._lock.peek().get('nonce')
1600
self.assertEqual(smart_req.SmartServerResponse(('ok', nonce)), response)
1240
self.assertEqual(SmartServerResponse(('ok', nonce)), response)
1601
1241
# The repository is now locked. Verify that with a new repository
1603
1243
new_repo = repository.bzrdir.open_repository()
1604
1244
self.assertRaises(errors.LockContention, new_repo.lock_write)
1606
request = smart_repo.SmartServerRepositoryUnlock(backing)
1607
response = request.execute('', nonce)
1609
1246
def test_lock_write_on_locked_repo(self):
1610
1247
backing = self.get_transport()
1611
request = smart_repo.SmartServerRepositoryLockWrite(backing)
1248
request = smart.repository.SmartServerRepositoryLockWrite(backing)
1612
1249
repository = self.make_repository('.', format='knit')
1613
repo_token = repository.lock_write()
1250
repository.lock_write()
1614
1251
repository.leave_lock_in_place()
1615
1252
repository.unlock()
1616
1253
response = request.execute('')
1617
1254
self.assertEqual(
1618
smart_req.SmartServerResponse(('LockContention',)), response)
1620
repository.lock_write(repo_token)
1621
repository.dont_leave_lock_in_place()
1255
SmartServerResponse(('LockContention',)), response)
1624
1257
def test_lock_write_on_readonly_transport(self):
1625
1258
backing = self.get_readonly_transport()
1626
request = smart_repo.SmartServerRepositoryLockWrite(backing)
1259
request = smart.repository.SmartServerRepositoryLockWrite(backing)
1627
1260
repository = self.make_repository('.', format='knit')
1628
1261
response = request.execute('')
1629
1262
self.assertFalse(response.is_successful())
1702
1335
def test_unlock_on_unlocked_repo(self):
1703
1336
backing = self.get_transport()
1704
request = smart_repo.SmartServerRepositoryUnlock(backing)
1337
request = smart.repository.SmartServerRepositoryUnlock(backing)
1705
1338
repository = self.make_repository('.', format='knit')
1706
1339
response = request.execute('', 'some token')
1707
1340
self.assertEqual(
1708
smart_req.SmartServerResponse(('TokenMismatch',)), response)
1341
SmartServerResponse(('TokenMismatch',)), response)
1711
1344
class TestSmartServerIsReadonly(tests.TestCaseWithMemoryTransport):
1713
1346
def test_is_readonly_no(self):
1714
1347
backing = self.get_transport()
1715
request = smart_req.SmartServerIsReadonly(backing)
1348
request = smart.request.SmartServerIsReadonly(backing)
1716
1349
response = request.execute()
1717
1350
self.assertEqual(
1718
smart_req.SmartServerResponse(('no',)), response)
1351
SmartServerResponse(('no',)), response)
1720
1353
def test_is_readonly_yes(self):
1721
1354
backing = self.get_readonly_transport()
1722
request = smart_req.SmartServerIsReadonly(backing)
1355
request = smart.request.SmartServerIsReadonly(backing)
1723
1356
response = request.execute()
1724
1357
self.assertEqual(
1725
smart_req.SmartServerResponse(('yes',)), response)
1728
class TestSmartServerRepositorySetMakeWorkingTrees(
1729
tests.TestCaseWithMemoryTransport):
1358
SmartServerResponse(('yes',)), response)
1361
class TestSmartServerRepositorySetMakeWorkingTrees(tests.TestCaseWithMemoryTransport):
1731
1363
def test_set_false(self):
1732
1364
backing = self.get_transport()
1733
1365
repo = self.make_repository('.', shared=True)
1734
1366
repo.set_make_working_trees(True)
1735
request_class = smart_repo.SmartServerRepositorySetMakeWorkingTrees
1367
request_class = smart.repository.SmartServerRepositorySetMakeWorkingTrees
1736
1368
request = request_class(backing)
1737
self.assertEqual(smart_req.SuccessfulSmartServerResponse(('ok',)),
1369
self.assertEqual(SuccessfulSmartServerResponse(('ok',)),
1738
1370
request.execute('', 'False'))
1739
1371
repo = repo.bzrdir.open_repository()
1740
1372
self.assertFalse(repo.make_working_trees())
1822
1441
"""All registered request_handlers can be found."""
1823
1442
# If there's a typo in a register_lazy call, this loop will fail with
1824
1443
# an AttributeError.
1825
for key, item in smart_req.request_handlers.iteritems():
1444
for key, item in smart.request.request_handlers.iteritems():
1828
1447
def assertHandlerEqual(self, verb, handler):
1829
self.assertEqual(smart_req.request_handlers.get(verb), handler)
1448
self.assertEqual(smart.request.request_handlers.get(verb), handler)
1831
1450
def test_registered_methods(self):
1832
1451
"""Test that known methods are registered to the correct object."""
1833
1452
self.assertHandlerEqual('Branch.get_config_file',
1834
smart_branch.SmartServerBranchGetConfigFile)
1453
smart.branch.SmartServerBranchGetConfigFile)
1835
1454
self.assertHandlerEqual('Branch.get_parent',
1836
smart_branch.SmartServerBranchGetParent)
1455
smart.branch.SmartServerBranchGetParent)
1837
1456
self.assertHandlerEqual('Branch.get_tags_bytes',
1838
smart_branch.SmartServerBranchGetTagsBytes)
1457
smart.branch.SmartServerBranchGetTagsBytes)
1839
1458
self.assertHandlerEqual('Branch.lock_write',
1840
smart_branch.SmartServerBranchRequestLockWrite)
1459
smart.branch.SmartServerBranchRequestLockWrite)
1841
1460
self.assertHandlerEqual('Branch.last_revision_info',
1842
smart_branch.SmartServerBranchRequestLastRevisionInfo)
1461
smart.branch.SmartServerBranchRequestLastRevisionInfo)
1843
1462
self.assertHandlerEqual('Branch.revision_history',
1844
smart_branch.SmartServerRequestRevisionHistory)
1463
smart.branch.SmartServerRequestRevisionHistory)
1845
1464
self.assertHandlerEqual('Branch.set_config_option',
1846
smart_branch.SmartServerBranchRequestSetConfigOption)
1465
smart.branch.SmartServerBranchRequestSetConfigOption)
1847
1466
self.assertHandlerEqual('Branch.set_last_revision',
1848
smart_branch.SmartServerBranchRequestSetLastRevision)
1467
smart.branch.SmartServerBranchRequestSetLastRevision)
1849
1468
self.assertHandlerEqual('Branch.set_last_revision_info',
1850
smart_branch.SmartServerBranchRequestSetLastRevisionInfo)
1469
smart.branch.SmartServerBranchRequestSetLastRevisionInfo)
1851
1470
self.assertHandlerEqual('Branch.set_last_revision_ex',
1852
smart_branch.SmartServerBranchRequestSetLastRevisionEx)
1471
smart.branch.SmartServerBranchRequestSetLastRevisionEx)
1853
1472
self.assertHandlerEqual('Branch.set_parent_location',
1854
smart_branch.SmartServerBranchRequestSetParentLocation)
1473
smart.branch.SmartServerBranchRequestSetParentLocation)
1855
1474
self.assertHandlerEqual('Branch.unlock',
1856
smart_branch.SmartServerBranchRequestUnlock)
1475
smart.branch.SmartServerBranchRequestUnlock)
1857
1476
self.assertHandlerEqual('BzrDir.find_repository',
1858
smart_dir.SmartServerRequestFindRepositoryV1)
1477
smart.bzrdir.SmartServerRequestFindRepositoryV1)
1859
1478
self.assertHandlerEqual('BzrDir.find_repositoryV2',
1860
smart_dir.SmartServerRequestFindRepositoryV2)
1479
smart.bzrdir.SmartServerRequestFindRepositoryV2)
1861
1480
self.assertHandlerEqual('BzrDirFormat.initialize',
1862
smart_dir.SmartServerRequestInitializeBzrDir)
1863
self.assertHandlerEqual('BzrDirFormat.initialize_ex_1.16',
1864
smart_dir.SmartServerRequestBzrDirInitializeEx)
1481
smart.bzrdir.SmartServerRequestInitializeBzrDir)
1865
1482
self.assertHandlerEqual('BzrDir.cloning_metadir',
1866
smart_dir.SmartServerBzrDirRequestCloningMetaDir)
1483
smart.bzrdir.SmartServerBzrDirRequestCloningMetaDir)
1867
1484
self.assertHandlerEqual('BzrDir.get_config_file',
1868
smart_dir.SmartServerBzrDirRequestConfigFile)
1485
smart.bzrdir.SmartServerBzrDirRequestConfigFile)
1869
1486
self.assertHandlerEqual('BzrDir.open_branch',
1870
smart_dir.SmartServerRequestOpenBranch)
1487
smart.bzrdir.SmartServerRequestOpenBranch)
1871
1488
self.assertHandlerEqual('BzrDir.open_branchV2',
1872
smart_dir.SmartServerRequestOpenBranchV2)
1873
self.assertHandlerEqual('BzrDir.open_branchV3',
1874
smart_dir.SmartServerRequestOpenBranchV3)
1489
smart.bzrdir.SmartServerRequestOpenBranchV2)
1875
1490
self.assertHandlerEqual('PackRepository.autopack',
1876
smart_packrepo.SmartServerPackRepositoryAutopack)
1491
smart.packrepository.SmartServerPackRepositoryAutopack)
1877
1492
self.assertHandlerEqual('Repository.gather_stats',
1878
smart_repo.SmartServerRepositoryGatherStats)
1493
smart.repository.SmartServerRepositoryGatherStats)
1879
1494
self.assertHandlerEqual('Repository.get_parent_map',
1880
smart_repo.SmartServerRepositoryGetParentMap)
1881
self.assertHandlerEqual('Repository.get_rev_id_for_revno',
1882
smart_repo.SmartServerRepositoryGetRevIdForRevno)
1495
smart.repository.SmartServerRepositoryGetParentMap)
1883
1496
self.assertHandlerEqual('Repository.get_revision_graph',
1884
smart_repo.SmartServerRepositoryGetRevisionGraph)
1497
smart.repository.SmartServerRepositoryGetRevisionGraph)
1885
1498
self.assertHandlerEqual('Repository.get_stream',
1886
smart_repo.SmartServerRepositoryGetStream)
1499
smart.repository.SmartServerRepositoryGetStream)
1887
1500
self.assertHandlerEqual('Repository.has_revision',
1888
smart_repo.SmartServerRequestHasRevision)
1501
smart.repository.SmartServerRequestHasRevision)
1889
1502
self.assertHandlerEqual('Repository.insert_stream',
1890
smart_repo.SmartServerRepositoryInsertStream)
1503
smart.repository.SmartServerRepositoryInsertStream)
1891
1504
self.assertHandlerEqual('Repository.insert_stream_locked',
1892
smart_repo.SmartServerRepositoryInsertStreamLocked)
1505
smart.repository.SmartServerRepositoryInsertStreamLocked)
1893
1506
self.assertHandlerEqual('Repository.is_shared',
1894
smart_repo.SmartServerRepositoryIsShared)
1507
smart.repository.SmartServerRepositoryIsShared)
1895
1508
self.assertHandlerEqual('Repository.lock_write',
1896
smart_repo.SmartServerRepositoryLockWrite)
1509
smart.repository.SmartServerRepositoryLockWrite)
1897
1510
self.assertHandlerEqual('Repository.tarball',
1898
smart_repo.SmartServerRepositoryTarball)
1511
smart.repository.SmartServerRepositoryTarball)
1899
1512
self.assertHandlerEqual('Repository.unlock',
1900
smart_repo.SmartServerRepositoryUnlock)
1513
smart.repository.SmartServerRepositoryUnlock)
1901
1514
self.assertHandlerEqual('Transport.is_readonly',
1902
smart_req.SmartServerIsReadonly)
1515
smart.request.SmartServerIsReadonly)