99
104
# the default or a parameterized class, but rather use the
100
105
# TestCaseWithTransport infrastructure to set up a smart server and
102
self.overrideAttr(self, "transport_server", self.make_transport_server)
107
self.transport_server = self.make_transport_server
104
109
def make_transport_server(self):
105
return test_server.SmartTCPServer_for_testing('-' + self.id())
110
return smart.server.SmartTCPServer_for_testing('-' + self.id())
107
112
def get_smart_medium(self):
108
113
"""Get a smart medium to use in tests."""
109
114
return self.get_transport().get_smart_medium()
112
class TestByteStreamToStream(tests.TestCase):
114
def test_repeated_substreams_same_kind_are_one_stream(self):
115
# Make a stream - an iterable of bytestrings.
116
stream = [('text', [versionedfile.FulltextContentFactory(('k1',), None,
117
None, 'foo')]),('text', [
118
versionedfile.FulltextContentFactory(('k2',), None, None, 'bar')])]
119
fmt = bzrdir.format_registry.get('pack-0.92')().repository_format
120
bytes = smart_repo._stream_to_byte_stream(stream, fmt)
122
# Iterate the resulting iterable; checking that we get only one stream
124
fmt, stream = smart_repo._byte_stream_to_stream(bytes)
125
for kind, substream in stream:
126
streams.append((kind, list(substream)))
127
self.assertLength(1, streams)
128
self.assertLength(2, streams[0][1])
131
117
class TestSmartServerResponse(tests.TestCase):
133
119
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', )))
120
self.assertEqual(SmartServerResponse(('ok', )),
121
SmartServerResponse(('ok', )))
122
self.assertEqual(SmartServerResponse(('ok', ), 'body'),
123
SmartServerResponse(('ok', ), 'body'))
124
self.assertNotEqual(SmartServerResponse(('ok', )),
125
SmartServerResponse(('notok', )))
126
self.assertNotEqual(SmartServerResponse(('ok', ), 'body'),
127
SmartServerResponse(('ok', )))
142
128
self.assertNotEqual(None,
143
smart_req.SmartServerResponse(('ok', )))
129
SmartServerResponse(('ok', )))
145
131
def test__str__(self):
146
132
"""SmartServerResponses can be stringified."""
147
133
self.assertEqual(
148
"<SuccessfulSmartServerResponse args=('args',) body='body'>",
149
str(smart_req.SuccessfulSmartServerResponse(('args',), 'body')))
134
"<SmartServerResponse status=OK args=('args',) body='body'>",
135
str(SuccessfulSmartServerResponse(('args',), 'body')))
150
136
self.assertEqual(
151
"<FailedSmartServerResponse args=('args',) body='body'>",
152
str(smart_req.FailedSmartServerResponse(('args',), 'body')))
137
"<SmartServerResponse status=ERR args=('args',) body='body'>",
138
str(FailedSmartServerResponse(('args',), 'body')))
155
141
class TestSmartServerRequest(tests.TestCaseWithMemoryTransport):
157
143
def test_translate_client_path(self):
158
144
transport = self.get_transport()
159
request = smart_req.SmartServerRequest(transport, 'foo/')
145
request = SmartServerRequest(transport, 'foo/')
160
146
self.assertEqual('./', request.translate_client_path('foo/'))
161
147
self.assertRaises(
162
148
errors.InvalidURLJoin, request.translate_client_path, 'foo/..')
165
151
self.assertRaises(
166
152
errors.PathNotChild, request.translate_client_path, 'bar/')
167
153
self.assertEqual('./baz', request.translate_client_path('foo/baz'))
168
e_acute = u'\N{LATIN SMALL LETTER E WITH ACUTE}'.encode('utf-8')
169
self.assertEqual('./' + urlutils.escape(e_acute),
170
request.translate_client_path('foo/' + e_acute))
172
def test_translate_client_path_vfs(self):
173
"""VfsRequests receive escaped paths rather than raw UTF-8."""
174
transport = self.get_transport()
175
request = vfs.VfsRequest(transport, 'foo/')
176
e_acute = u'\N{LATIN SMALL LETTER E WITH ACUTE}'.encode('utf-8')
177
escaped = urlutils.escape('foo/' + e_acute)
178
self.assertEqual('./' + urlutils.escape(e_acute),
179
request.translate_client_path(escaped))
181
155
def test_transport_from_client_path(self):
182
156
transport = self.get_transport()
183
request = smart_req.SmartServerRequest(transport, 'foo/')
157
request = SmartServerRequest(transport, 'foo/')
184
158
self.assertEqual(
186
160
request.transport_from_client_path('foo/').base)
189
class TestSmartServerBzrDirRequestCloningMetaDir(
190
tests.TestCaseWithMemoryTransport):
191
"""Tests for BzrDir.cloning_metadir."""
193
def test_cloning_metadir(self):
194
"""When there is a bzrdir present, the call succeeds."""
195
backing = self.get_transport()
196
dir = self.make_bzrdir('.')
197
local_result = dir.cloning_metadir()
198
request_class = smart_dir.SmartServerBzrDirRequestCloningMetaDir
199
request = request_class(backing)
200
expected = smart_req.SuccessfulSmartServerResponse(
201
(local_result.network_name(),
202
local_result.repository_format.network_name(),
203
('branch', local_result.get_branch_format().network_name())))
204
self.assertEqual(expected, request.execute('', 'False'))
206
def test_cloning_metadir_reference(self):
207
"""The request fails when bzrdir contains a branch reference."""
208
backing = self.get_transport()
209
referenced_branch = self.make_branch('referenced')
210
dir = self.make_bzrdir('.')
211
local_result = dir.cloning_metadir()
212
reference = _mod_branch.BranchReferenceFormat().initialize(
213
dir, target_branch=referenced_branch)
214
reference_url = _mod_branch.BranchReferenceFormat().get_reference(dir)
215
# The server shouldn't try to follow the branch reference, so it's fine
216
# if the referenced branch isn't reachable.
217
backing.rename('referenced', 'moved')
218
request_class = smart_dir.SmartServerBzrDirRequestCloningMetaDir
219
request = request_class(backing)
220
expected = smart_req.FailedSmartServerResponse(('BranchReference',))
221
self.assertEqual(expected, request.execute('', 'False'))
224
class TestSmartServerRequestCreateRepository(tests.TestCaseWithMemoryTransport):
225
"""Tests for BzrDir.create_repository."""
227
def test_makes_repository(self):
228
"""When there is a bzrdir present, the call succeeds."""
229
backing = self.get_transport()
230
self.make_bzrdir('.')
231
request_class = smart_dir.SmartServerRequestCreateRepository
232
request = request_class(backing)
233
reference_bzrdir_format = bzrdir.format_registry.get('pack-0.92')()
234
reference_format = reference_bzrdir_format.repository_format
235
network_name = reference_format.network_name()
236
expected = smart_req.SuccessfulSmartServerResponse(
237
('ok', 'no', 'no', 'no', network_name))
238
self.assertEqual(expected, request.execute('', network_name, 'True'))
241
163
class TestSmartServerRequestFindRepository(tests.TestCaseWithMemoryTransport):
242
164
"""Tests for BzrDir.find_repository."""
374
259
def test_missing_dir(self):
375
260
"""Initializing a missing directory should fail like the bzrdir api."""
376
261
backing = self.get_transport()
377
request = smart_dir.SmartServerRequestInitializeBzrDir(backing)
262
request = smart.bzrdir.SmartServerRequestInitializeBzrDir(backing)
378
263
self.assertRaises(errors.NoSuchFile,
379
264
request.execute, 'subdir')
381
266
def test_initialized_dir(self):
382
267
"""Initializing an extant bzrdir should fail like the bzrdir api."""
383
268
backing = self.get_transport()
384
request = smart_dir.SmartServerRequestInitializeBzrDir(backing)
269
request = smart.bzrdir.SmartServerRequestInitializeBzrDir(backing)
385
270
self.make_bzrdir('subdir')
386
271
self.assertRaises(errors.FileExists,
387
272
request.execute, 'subdir')
390
class TestSmartServerRequestBzrDirInitializeEx(
391
tests.TestCaseWithMemoryTransport):
392
"""Basic tests for BzrDir.initialize_ex_1.16 in the smart server.
394
The main unit tests in test_bzrdir exercise the API comprehensively.
397
def test_empty_dir(self):
398
"""Initializing an empty dir should succeed and do it."""
399
backing = self.get_transport()
400
name = self.make_bzrdir('reference')._format.network_name()
401
request = smart_dir.SmartServerRequestBzrDirInitializeEx(backing)
403
smart_req.SmartServerResponse(('', '', '', '', '', '', name,
404
'False', '', '', '')),
405
request.execute(name, '', 'True', 'False', 'False', '', '', '', '',
407
made_dir = bzrdir.BzrDir.open_from_transport(backing)
408
# no branch, tree or repository is expected with the current
410
self.assertRaises(errors.NoWorkingTree, made_dir.open_workingtree)
411
self.assertRaises(errors.NotBranchError, made_dir.open_branch)
412
self.assertRaises(errors.NoRepositoryPresent, made_dir.open_repository)
414
def test_missing_dir(self):
415
"""Initializing a missing directory should fail like the bzrdir api."""
416
backing = self.get_transport()
417
name = self.make_bzrdir('reference')._format.network_name()
418
request = smart_dir.SmartServerRequestBzrDirInitializeEx(backing)
419
self.assertRaises(errors.NoSuchFile, request.execute, name,
420
'subdir/dir', 'False', 'False', 'False', '', '', '', '', 'False')
422
def test_initialized_dir(self):
423
"""Initializing an extant directory should fail like the bzrdir api."""
424
backing = self.get_transport()
425
name = self.make_bzrdir('reference')._format.network_name()
426
request = smart_dir.SmartServerRequestBzrDirInitializeEx(backing)
427
self.make_bzrdir('subdir')
428
self.assertRaises(errors.FileExists, request.execute, name, 'subdir',
429
'False', 'False', 'False', '', '', '', '', 'False')
432
class TestSmartServerRequestOpenBzrDir(tests.TestCaseWithMemoryTransport):
434
def test_no_directory(self):
435
backing = self.get_transport()
436
request = smart_dir.SmartServerRequestOpenBzrDir(backing)
437
self.assertEqual(smart_req.SmartServerResponse(('no', )),
438
request.execute('does-not-exist'))
440
def test_empty_directory(self):
441
backing = self.get_transport()
442
backing.mkdir('empty')
443
request = smart_dir.SmartServerRequestOpenBzrDir(backing)
444
self.assertEqual(smart_req.SmartServerResponse(('no', )),
445
request.execute('empty'))
447
def test_outside_root_client_path(self):
448
backing = self.get_transport()
449
request = smart_dir.SmartServerRequestOpenBzrDir(backing,
450
root_client_path='root')
451
self.assertEqual(smart_req.SmartServerResponse(('no', )),
452
request.execute('not-root'))
455
class TestSmartServerRequestOpenBzrDir_2_1(tests.TestCaseWithMemoryTransport):
457
def test_no_directory(self):
458
backing = self.get_transport()
459
request = smart_dir.SmartServerRequestOpenBzrDir_2_1(backing)
460
self.assertEqual(smart_req.SmartServerResponse(('no', )),
461
request.execute('does-not-exist'))
463
def test_empty_directory(self):
464
backing = self.get_transport()
465
backing.mkdir('empty')
466
request = smart_dir.SmartServerRequestOpenBzrDir_2_1(backing)
467
self.assertEqual(smart_req.SmartServerResponse(('no', )),
468
request.execute('empty'))
470
def test_present_without_workingtree(self):
471
backing = self.get_transport()
472
request = smart_dir.SmartServerRequestOpenBzrDir_2_1(backing)
473
self.make_bzrdir('.')
474
self.assertEqual(smart_req.SmartServerResponse(('yes', 'no')),
477
def test_outside_root_client_path(self):
478
backing = self.get_transport()
479
request = smart_dir.SmartServerRequestOpenBzrDir_2_1(backing,
480
root_client_path='root')
481
self.assertEqual(smart_req.SmartServerResponse(('no',)),
482
request.execute('not-root'))
485
class TestSmartServerRequestOpenBzrDir_2_1_disk(TestCaseWithChrootedTransport):
487
def test_present_with_workingtree(self):
488
self.vfs_transport_factory = test_server.LocalURLServer
489
backing = self.get_transport()
490
request = smart_dir.SmartServerRequestOpenBzrDir_2_1(backing)
491
bd = self.make_bzrdir('.')
492
bd.create_repository()
494
bd.create_workingtree()
495
self.assertEqual(smart_req.SmartServerResponse(('yes', 'yes')),
499
275
class TestSmartServerRequestOpenBranch(TestCaseWithChrootedTransport):
501
277
def test_no_branch(self):
502
278
"""When there is no branch, ('nobranch', ) is returned."""
503
279
backing = self.get_transport()
504
request = smart_dir.SmartServerRequestOpenBranch(backing)
280
request = smart.bzrdir.SmartServerRequestOpenBranch(backing)
505
281
self.make_bzrdir('.')
506
self.assertEqual(smart_req.SmartServerResponse(('nobranch', )),
282
self.assertEqual(SmartServerResponse(('nobranch', )),
507
283
request.execute(''))
509
285
def test_branch(self):
510
286
"""When there is a branch, 'ok' is returned."""
511
287
backing = self.get_transport()
512
request = smart_dir.SmartServerRequestOpenBranch(backing)
288
request = smart.bzrdir.SmartServerRequestOpenBranch(backing)
513
289
self.make_branch('.')
514
self.assertEqual(smart_req.SmartServerResponse(('ok', '')),
290
self.assertEqual(SmartServerResponse(('ok', '')),
515
291
request.execute(''))
517
293
def test_branch_reference(self):
518
294
"""When there is a branch reference, the reference URL is returned."""
519
self.vfs_transport_factory = test_server.LocalURLServer
520
295
backing = self.get_transport()
521
request = smart_dir.SmartServerRequestOpenBranch(backing)
296
request = smart.bzrdir.SmartServerRequestOpenBranch(backing)
522
297
branch = self.make_branch('branch')
523
298
checkout = branch.create_checkout('reference',lightweight=True)
524
reference_url = _mod_branch.BranchReferenceFormat().get_reference(
299
reference_url = BranchReferenceFormat().get_reference(checkout.bzrdir)
526
300
self.assertFileEqual(reference_url, 'reference/.bzr/branch/location')
527
self.assertEqual(smart_req.SmartServerResponse(('ok', reference_url)),
301
self.assertEqual(SmartServerResponse(('ok', reference_url)),
528
302
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
class TestSmartServerRequestOpenBranchV2(TestCaseWithChrootedTransport):
541
def test_no_branch(self):
542
"""When there is no branch, ('nobranch', ) is returned."""
543
backing = self.get_transport()
544
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')),
666
305
class TestSmartServerRequestRevisionHistory(tests.TestCaseWithMemoryTransport):
668
307
def test_empty(self):
669
308
"""For an empty branch, the body is empty."""
670
309
backing = self.get_transport()
671
request = smart_branch.SmartServerRequestRevisionHistory(backing)
310
request = smart.branch.SmartServerRequestRevisionHistory(backing)
672
311
self.make_branch('.')
673
self.assertEqual(smart_req.SmartServerResponse(('ok', ), ''),
312
self.assertEqual(SmartServerResponse(('ok', ), ''),
674
313
request.execute(''))
676
315
def test_not_empty(self):
677
316
"""For a non-empty branch, the body is empty."""
678
317
backing = self.get_transport()
679
request = smart_branch.SmartServerRequestRevisionHistory(backing)
318
request = smart.branch.SmartServerRequestRevisionHistory(backing)
680
319
tree = self.make_branch_and_memory_tree('.')
681
320
tree.lock_write()
731
369
r2 = tree.commit('2nd commit', rev_id=rev_id_utf8)
733
371
self.assertEqual(
734
smart_req.SmartServerResponse(('ok', '2', rev_id_utf8)),
372
SmartServerResponse(('ok', '2', rev_id_utf8)),
735
373
request.execute(''))
738
class TestSmartServerBranchRequestGetConfigFile(
739
tests.TestCaseWithMemoryTransport):
376
class TestSmartServerBranchRequestGetConfigFile(tests.TestCaseWithMemoryTransport):
741
378
def test_default(self):
742
379
"""With no file, we get empty content."""
743
380
backing = self.get_transport()
744
request = smart_branch.SmartServerBranchGetConfigFile(backing)
381
request = smart.branch.SmartServerBranchGetConfigFile(backing)
745
382
branch = self.make_branch('.')
746
383
# there should be no file by default
748
self.assertEqual(smart_req.SmartServerResponse(('ok', ), content),
385
self.assertEqual(SmartServerResponse(('ok', ), content),
749
386
request.execute(''))
751
388
def test_with_content(self):
752
389
# SmartServerBranchGetConfigFile should return the content from
753
390
# branch.control_files.get('branch.conf') for now - in the future it may
754
# perform more complex processing.
391
# perform more complex processing.
755
392
backing = self.get_transport()
756
request = smart_branch.SmartServerBranchGetConfigFile(backing)
393
request = smart.branch.SmartServerBranchGetConfigFile(backing)
757
394
branch = self.make_branch('.')
758
395
branch._transport.put_bytes('branch.conf', 'foo bar baz')
759
self.assertEqual(smart_req.SmartServerResponse(('ok', ), 'foo bar baz'),
396
self.assertEqual(SmartServerResponse(('ok', ), 'foo bar baz'),
760
397
request.execute(''))
763
class TestLockedBranch(tests.TestCaseWithMemoryTransport):
765
def get_lock_tokens(self, branch):
766
branch_token = branch.lock_write().branch_token
767
repo_token = branch.repository.lock_write().repository_token
768
branch.repository.unlock()
769
return branch_token, repo_token
772
class TestSmartServerBranchRequestSetConfigOption(TestLockedBranch):
774
def test_value_name(self):
775
branch = self.make_branch('.')
776
request = smart_branch.SmartServerBranchRequestSetConfigOption(
777
branch.bzrdir.root_transport)
778
branch_token, repo_token = self.get_lock_tokens(branch)
779
config = branch._get_config()
780
result = request.execute('', branch_token, repo_token, 'bar', 'foo',
782
self.assertEqual(smart_req.SuccessfulSmartServerResponse(()), result)
783
self.assertEqual('bar', config.get_option('foo'))
787
def test_value_name_section(self):
788
branch = self.make_branch('.')
789
request = smart_branch.SmartServerBranchRequestSetConfigOption(
790
branch.bzrdir.root_transport)
791
branch_token, repo_token = self.get_lock_tokens(branch)
792
config = branch._get_config()
793
result = request.execute('', branch_token, repo_token, 'bar', 'foo',
795
self.assertEqual(smart_req.SuccessfulSmartServerResponse(()), result)
796
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
class TestSmartServerBranchRequestSetTagsBytes(TestLockedBranch):
840
# Only called when the branch format and tags match [yay factory
841
# methods] so only need to test straight forward cases.
843
def test_set_bytes(self):
844
base_branch = self.make_branch('base')
845
tag_bytes = base_branch._get_tags_bytes()
846
# get_lock_tokens takes out a lock.
847
branch_token, repo_token = self.get_lock_tokens(base_branch)
848
request = smart_branch.SmartServerBranchSetTagsBytes(
849
self.get_transport())
850
response = request.execute('base', branch_token, repo_token)
851
self.assertEqual(None, response)
852
response = request.do_chunk(tag_bytes)
853
self.assertEqual(None, response)
854
response = request.do_end()
856
smart_req.SuccessfulSmartServerResponse(()), response)
859
def test_lock_failed(self):
860
base_branch = self.make_branch('base')
861
base_branch.lock_write()
862
tag_bytes = base_branch._get_tags_bytes()
863
request = smart_branch.SmartServerBranchSetTagsBytes(
864
self.get_transport())
865
self.assertRaises(errors.TokenMismatch, request.execute,
866
'base', 'wrong token', 'wrong token')
867
# The request handler will keep processing the message parts, so even
868
# if the request fails immediately do_chunk and do_end are still
870
request.do_chunk(tag_bytes)
876
class SetLastRevisionTestBase(TestLockedBranch):
400
class SetLastRevisionTestBase(tests.TestCaseWithMemoryTransport):
877
401
"""Base test case for verbs that implement set_last_revision."""
1081
608
response = self.request.execute(
1082
609
'', branch_token, repo_token, 'child-1', 1, 0)
1083
610
self.assertEqual(
1084
smart_req.SuccessfulSmartServerResponse(('ok', 2, 'child-1')),
611
SuccessfulSmartServerResponse(('ok', 2, 'child-1')),
1086
613
self.unlock_branch()
1087
614
# The branch tip was changed.
1088
615
self.assertEqual('child-1', self.tree.branch.last_revision())
1091
class TestSmartServerBranchRequestGetParent(tests.TestCaseWithMemoryTransport):
1093
def test_get_parent_none(self):
1094
base_branch = self.make_branch('base')
1095
request = smart_branch.SmartServerBranchGetParent(self.get_transport())
1096
response = request.execute('base')
1098
smart_req.SuccessfulSmartServerResponse(('',)), response)
1100
def test_get_parent_something(self):
1101
base_branch = self.make_branch('base')
1102
base_branch.set_parent(self.get_url('foo'))
1103
request = smart_branch.SmartServerBranchGetParent(self.get_transport())
1104
response = request.execute('base')
1106
smart_req.SuccessfulSmartServerResponse(("../foo",)),
1110
class TestSmartServerBranchRequestSetParent(TestLockedBranch):
1112
def test_set_parent_none(self):
1113
branch = self.make_branch('base', format="1.9")
1115
branch._set_parent_location('foo')
1117
request = smart_branch.SmartServerBranchRequestSetParentLocation(
1118
self.get_transport())
1119
branch_token, repo_token = self.get_lock_tokens(branch)
1121
response = request.execute('base', branch_token, repo_token, '')
1124
self.assertEqual(smart_req.SuccessfulSmartServerResponse(()), response)
1125
self.assertEqual(None, branch.get_parent())
1127
def test_set_parent_something(self):
1128
branch = self.make_branch('base', format="1.9")
1129
request = smart_branch.SmartServerBranchRequestSetParentLocation(
1130
self.get_transport())
1131
branch_token, repo_token = self.get_lock_tokens(branch)
1133
response = request.execute('base', branch_token, repo_token,
1137
self.assertEqual(smart_req.SuccessfulSmartServerResponse(()), response)
1138
self.assertEqual('http://bar/', branch.get_parent())
1141
class TestSmartServerBranchRequestGetTagsBytes(
1142
tests.TestCaseWithMemoryTransport):
1143
# Only called when the branch format and tags match [yay factory
1144
# methods] so only need to test straight forward cases.
1146
def test_get_bytes(self):
1147
base_branch = self.make_branch('base')
1148
request = smart_branch.SmartServerBranchGetTagsBytes(
1149
self.get_transport())
1150
response = request.execute('base')
1152
smart_req.SuccessfulSmartServerResponse(('',)), response)
1155
class TestSmartServerBranchRequestGetStackedOnURL(tests.TestCaseWithMemoryTransport):
1157
def test_get_stacked_on_url(self):
1158
base_branch = self.make_branch('base', format='1.6')
1159
stacked_branch = self.make_branch('stacked', format='1.6')
1160
# typically should be relative
1161
stacked_branch.set_stacked_on_url('../base')
1162
request = smart_branch.SmartServerBranchRequestGetStackedOnURL(
1163
self.get_transport())
1164
response = request.execute('stacked')
1166
smart_req.SmartServerResponse(('ok', '../base')),
1170
class TestSmartServerBranchRequestLockWrite(TestLockedBranch):
618
class TestSmartServerBranchRequestLockWrite(tests.TestCaseWithMemoryTransport):
1172
620
def setUp(self):
1173
621
tests.TestCaseWithMemoryTransport.setUp(self)
1175
623
def test_lock_write_on_unlocked_branch(self):
1176
624
backing = self.get_transport()
1177
request = smart_branch.SmartServerBranchRequestLockWrite(backing)
625
request = smart.branch.SmartServerBranchRequestLockWrite(backing)
1178
626
branch = self.make_branch('.', format='knit')
1179
627
repository = branch.repository
1180
628
response = request.execute('')
1181
629
branch_nonce = branch.control_files._lock.peek().get('nonce')
1182
630
repository_nonce = repository.control_files._lock.peek().get('nonce')
1183
self.assertEqual(smart_req.SmartServerResponse(
1184
('ok', branch_nonce, repository_nonce)),
632
SmartServerResponse(('ok', branch_nonce, repository_nonce)),
1186
634
# The branch (and associated repository) is now locked. Verify that
1187
635
# with a new branch object.
1188
636
new_branch = repository.bzrdir.open_branch()
1189
637
self.assertRaises(errors.LockContention, new_branch.lock_write)
1191
request = smart_branch.SmartServerBranchRequestUnlock(backing)
1192
response = request.execute('', branch_nonce, repository_nonce)
1194
639
def test_lock_write_on_locked_branch(self):
1195
640
backing = self.get_transport()
1196
request = smart_branch.SmartServerBranchRequestLockWrite(backing)
641
request = smart.branch.SmartServerBranchRequestLockWrite(backing)
1197
642
branch = self.make_branch('.')
1198
branch_token = branch.lock_write().branch_token
1199
644
branch.leave_lock_in_place()
1201
646
response = request.execute('')
1202
647
self.assertEqual(
1203
smart_req.SmartServerResponse(('LockContention',)), response)
1205
branch.lock_write(branch_token)
1206
branch.dont_leave_lock_in_place()
648
SmartServerResponse(('LockContention',)), response)
1209
650
def test_lock_write_with_tokens_on_locked_branch(self):
1210
651
backing = self.get_transport()
1211
request = smart_branch.SmartServerBranchRequestLockWrite(backing)
652
request = smart.branch.SmartServerBranchRequestLockWrite(backing)
1212
653
branch = self.make_branch('.', format='knit')
1213
branch_token, repo_token = self.get_lock_tokens(branch)
654
branch_token = branch.lock_write()
655
repo_token = branch.repository.lock_write()
656
branch.repository.unlock()
1214
657
branch.leave_lock_in_place()
1215
658
branch.repository.leave_lock_in_place()
1217
660
response = request.execute('',
1218
661
branch_token, repo_token)
1219
662
self.assertEqual(
1220
smart_req.SmartServerResponse(('ok', branch_token, repo_token)),
1223
branch.repository.lock_write(repo_token)
1224
branch.repository.dont_leave_lock_in_place()
1225
branch.repository.unlock()
1226
branch.lock_write(branch_token)
1227
branch.dont_leave_lock_in_place()
663
SmartServerResponse(('ok', branch_token, repo_token)), response)
1230
665
def test_lock_write_with_mismatched_tokens_on_locked_branch(self):
1231
666
backing = self.get_transport()
1232
request = smart_branch.SmartServerBranchRequestLockWrite(backing)
667
request = smart.branch.SmartServerBranchRequestLockWrite(backing)
1233
668
branch = self.make_branch('.', format='knit')
1234
branch_token, repo_token = self.get_lock_tokens(branch)
669
branch_token = branch.lock_write()
670
repo_token = branch.repository.lock_write()
671
branch.repository.unlock()
1235
672
branch.leave_lock_in_place()
1236
673
branch.repository.leave_lock_in_place()
1238
675
response = request.execute('',
1239
676
branch_token+'xxx', repo_token)
1240
677
self.assertEqual(
1241
smart_req.SmartServerResponse(('TokenMismatch',)), response)
1243
branch.repository.lock_write(repo_token)
1244
branch.repository.dont_leave_lock_in_place()
1245
branch.repository.unlock()
1246
branch.lock_write(branch_token)
1247
branch.dont_leave_lock_in_place()
678
SmartServerResponse(('TokenMismatch',)), response)
1250
680
def test_lock_write_on_locked_repo(self):
1251
681
backing = self.get_transport()
1252
request = smart_branch.SmartServerBranchRequestLockWrite(backing)
682
request = smart.branch.SmartServerBranchRequestLockWrite(backing)
1253
683
branch = self.make_branch('.', format='knit')
1254
repo = branch.repository
1255
repo_token = repo.lock_write().repository_token
1256
repo.leave_lock_in_place()
684
branch.repository.lock_write()
685
branch.repository.leave_lock_in_place()
686
branch.repository.unlock()
1258
687
response = request.execute('')
1259
688
self.assertEqual(
1260
smart_req.SmartServerResponse(('LockContention',)), response)
1262
repo.lock_write(repo_token)
1263
repo.dont_leave_lock_in_place()
689
SmartServerResponse(('LockContention',)), response)
1266
691
def test_lock_write_on_readonly_transport(self):
1267
692
backing = self.get_readonly_transport()
1268
request = smart_branch.SmartServerBranchRequestLockWrite(backing)
693
request = smart.branch.SmartServerBranchRequestLockWrite(backing)
1269
694
branch = self.make_branch('.')
1270
695
root = self.get_transport().clone('/')
1271
696
path = urlutils.relative_url(root.base, self.get_transport().base)
1421
832
# Note that it still returns body (of zero bytes).
1422
self.assertEqual(smart_req.SmartServerResponse(
1423
('nosuchrevision', 'missingrevision', ), ''),
1424
request.execute('', 'missingrevision'))
1427
class TestSmartServerRepositoryGetRevIdForRevno(
1428
tests.TestCaseWithMemoryTransport):
1430
def test_revno_found(self):
1431
backing = self.get_transport()
1432
request = smart_repo.SmartServerRepositoryGetRevIdForRevno(backing)
1433
tree = self.make_branch_and_memory_tree('.')
1436
rev1_id_utf8 = u'\xc8'.encode('utf-8')
1437
rev2_id_utf8 = u'\xc9'.encode('utf-8')
1438
tree.commit('1st commit', rev_id=rev1_id_utf8)
1439
tree.commit('2nd commit', rev_id=rev2_id_utf8)
1442
self.assertEqual(smart_req.SmartServerResponse(('ok', rev1_id_utf8)),
1443
request.execute('', 1, (2, rev2_id_utf8)))
1445
def test_known_revid_missing(self):
1446
backing = self.get_transport()
1447
request = smart_repo.SmartServerRepositoryGetRevIdForRevno(backing)
1448
repo = self.make_repository('.')
1450
smart_req.FailedSmartServerResponse(('nosuchrevision', 'ghost')),
1451
request.execute('', 1, (2, 'ghost')))
1453
def test_history_incomplete(self):
1454
backing = self.get_transport()
1455
request = smart_repo.SmartServerRepositoryGetRevIdForRevno(backing)
1456
parent = self.make_branch_and_memory_tree('parent', format='1.9')
1458
parent.add([''], ['TREE_ROOT'])
1459
r1 = parent.commit(message='first commit')
1460
r2 = parent.commit(message='second commit')
1462
local = self.make_branch_and_memory_tree('local', format='1.9')
1463
local.branch.pull(parent.branch)
1464
local.set_parent_ids([r2])
1465
r3 = local.commit(message='local commit')
1466
local.branch.create_clone_on_transport(
1467
self.get_transport('stacked'), stacked_on=self.get_url('parent'))
1469
smart_req.SmartServerResponse(('history-incomplete', 2, r2)),
1470
request.execute('stacked', 1, (3, r3)))
1473
class GetStreamTestBase(tests.TestCaseWithMemoryTransport):
1475
def make_two_commit_repo(self):
1476
tree = self.make_branch_and_memory_tree('.')
1479
r1 = tree.commit('1st commit')
1480
r2 = tree.commit('2nd commit', rev_id=u'\xc8'.encode('utf-8'))
1482
repo = tree.branch.repository
1486
class TestSmartServerRepositoryGetStream(GetStreamTestBase):
1488
def test_ancestry_of(self):
1489
"""The search argument may be a 'ancestry-of' some heads'."""
1490
backing = self.get_transport()
1491
request = smart_repo.SmartServerRepositoryGetStream(backing)
1492
repo, r1, r2 = self.make_two_commit_repo()
1493
fetch_spec = ['ancestry-of', r2]
1494
lines = '\n'.join(fetch_spec)
1495
request.execute('', repo._format.network_name())
1496
response = request.do_body(lines)
1497
self.assertEqual(('ok',), response.args)
1498
stream_bytes = ''.join(response.body_stream)
1499
self.assertStartsWith(stream_bytes, 'Bazaar pack format 1')
1501
def test_search(self):
1502
"""The search argument may be a 'search' of some explicit keys."""
1503
backing = self.get_transport()
1504
request = smart_repo.SmartServerRepositoryGetStream(backing)
1505
repo, r1, r2 = self.make_two_commit_repo()
1506
fetch_spec = ['search', '%s %s' % (r1, r2), 'null:', '2']
1507
lines = '\n'.join(fetch_spec)
1508
request.execute('', repo._format.network_name())
1509
response = request.do_body(lines)
1510
self.assertEqual(('ok',), response.args)
1511
stream_bytes = ''.join(response.body_stream)
1512
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')
834
SmartServerResponse(('nosuchrevision', 'missingrevision', ), ''),
835
request.execute('', 'missingrevision'))
1527
838
class TestSmartServerRequestHasRevision(tests.TestCaseWithMemoryTransport):
1613
924
def test_is_shared(self):
1614
925
"""For a shared repository, ('yes', ) is returned."""
1615
926
backing = self.get_transport()
1616
request = smart_repo.SmartServerRepositoryIsShared(backing)
927
request = smart.repository.SmartServerRepositoryIsShared(backing)
1617
928
self.make_repository('.', shared=True)
1618
self.assertEqual(smart_req.SmartServerResponse(('yes', )),
929
self.assertEqual(SmartServerResponse(('yes', )),
1619
930
request.execute('', ))
1621
932
def test_is_not_shared(self):
1622
933
"""For a shared repository, ('no', ) is returned."""
1623
934
backing = self.get_transport()
1624
request = smart_repo.SmartServerRepositoryIsShared(backing)
935
request = smart.repository.SmartServerRepositoryIsShared(backing)
1625
936
self.make_repository('.', shared=False)
1626
self.assertEqual(smart_req.SmartServerResponse(('no', )),
937
self.assertEqual(SmartServerResponse(('no', )),
1627
938
request.execute('', ))
1630
941
class TestSmartServerRepositoryLockWrite(tests.TestCaseWithMemoryTransport):
944
tests.TestCaseWithMemoryTransport.setUp(self)
1632
946
def test_lock_write_on_unlocked_repo(self):
1633
947
backing = self.get_transport()
1634
request = smart_repo.SmartServerRepositoryLockWrite(backing)
948
request = smart.repository.SmartServerRepositoryLockWrite(backing)
1635
949
repository = self.make_repository('.', format='knit')
1636
950
response = request.execute('')
1637
951
nonce = repository.control_files._lock.peek().get('nonce')
1638
self.assertEqual(smart_req.SmartServerResponse(('ok', nonce)), response)
952
self.assertEqual(SmartServerResponse(('ok', nonce)), response)
1639
953
# The repository is now locked. Verify that with a new repository
1641
955
new_repo = repository.bzrdir.open_repository()
1642
956
self.assertRaises(errors.LockContention, new_repo.lock_write)
1644
request = smart_repo.SmartServerRepositoryUnlock(backing)
1645
response = request.execute('', nonce)
1647
958
def test_lock_write_on_locked_repo(self):
1648
959
backing = self.get_transport()
1649
request = smart_repo.SmartServerRepositoryLockWrite(backing)
960
request = smart.repository.SmartServerRepositoryLockWrite(backing)
1650
961
repository = self.make_repository('.', format='knit')
1651
repo_token = repository.lock_write().repository_token
962
repository.lock_write()
1652
963
repository.leave_lock_in_place()
1653
964
repository.unlock()
1654
965
response = request.execute('')
1655
966
self.assertEqual(
1656
smart_req.SmartServerResponse(('LockContention',)), response)
1658
repository.lock_write(repo_token)
1659
repository.dont_leave_lock_in_place()
967
SmartServerResponse(('LockContention',)), response)
1662
969
def test_lock_write_on_readonly_transport(self):
1663
970
backing = self.get_readonly_transport()
1664
request = smart_repo.SmartServerRepositoryLockWrite(backing)
971
request = smart.repository.SmartServerRepositoryLockWrite(backing)
1665
972
repository = self.make_repository('.', format='knit')
1666
973
response = request.execute('')
1667
974
self.assertFalse(response.is_successful())
1668
975
self.assertEqual('LockFailed', response.args[0])
1671
class TestInsertStreamBase(tests.TestCaseWithMemoryTransport):
1673
def make_empty_byte_stream(self, repo):
1674
byte_stream = smart_repo._stream_to_byte_stream([], repo._format)
1675
return ''.join(byte_stream)
1678
class TestSmartServerRepositoryInsertStream(TestInsertStreamBase):
1680
def test_insert_stream_empty(self):
1681
backing = self.get_transport()
1682
request = smart_repo.SmartServerRepositoryInsertStream(backing)
1683
repository = self.make_repository('.')
1684
response = request.execute('', '')
1685
self.assertEqual(None, response)
1686
response = request.do_chunk(self.make_empty_byte_stream(repository))
1687
self.assertEqual(None, response)
1688
response = request.do_end()
1689
self.assertEqual(smart_req.SmartServerResponse(('ok', )), response)
1692
class TestSmartServerRepositoryInsertStreamLocked(TestInsertStreamBase):
1694
def test_insert_stream_empty(self):
1695
backing = self.get_transport()
1696
request = smart_repo.SmartServerRepositoryInsertStreamLocked(
1698
repository = self.make_repository('.', format='knit')
1699
lock_token = repository.lock_write().repository_token
1700
response = request.execute('', '', lock_token)
1701
self.assertEqual(None, response)
1702
response = request.do_chunk(self.make_empty_byte_stream(repository))
1703
self.assertEqual(None, response)
1704
response = request.do_end()
1705
self.assertEqual(smart_req.SmartServerResponse(('ok', )), response)
1708
def test_insert_stream_with_wrong_lock_token(self):
1709
backing = self.get_transport()
1710
request = smart_repo.SmartServerRepositoryInsertStreamLocked(
1712
repository = self.make_repository('.', format='knit')
1713
lock_token = repository.lock_write().repository_token
1715
errors.TokenMismatch, request.execute, '', '', 'wrong-token')
1719
978
class TestSmartServerRepositoryUnlock(tests.TestCaseWithMemoryTransport):
1721
980
def setUp(self):
1740
999
def test_unlock_on_unlocked_repo(self):
1741
1000
backing = self.get_transport()
1742
request = smart_repo.SmartServerRepositoryUnlock(backing)
1001
request = smart.repository.SmartServerRepositoryUnlock(backing)
1743
1002
repository = self.make_repository('.', format='knit')
1744
1003
response = request.execute('', 'some token')
1745
1004
self.assertEqual(
1746
smart_req.SmartServerResponse(('TokenMismatch',)), response)
1005
SmartServerResponse(('TokenMismatch',)), response)
1749
1008
class TestSmartServerIsReadonly(tests.TestCaseWithMemoryTransport):
1751
1010
def test_is_readonly_no(self):
1752
1011
backing = self.get_transport()
1753
request = smart_req.SmartServerIsReadonly(backing)
1012
request = smart.request.SmartServerIsReadonly(backing)
1754
1013
response = request.execute()
1755
1014
self.assertEqual(
1756
smart_req.SmartServerResponse(('no',)), response)
1015
SmartServerResponse(('no',)), response)
1758
1017
def test_is_readonly_yes(self):
1759
1018
backing = self.get_readonly_transport()
1760
request = smart_req.SmartServerIsReadonly(backing)
1019
request = smart.request.SmartServerIsReadonly(backing)
1761
1020
response = request.execute()
1762
1021
self.assertEqual(
1763
smart_req.SmartServerResponse(('yes',)), response)
1766
class TestSmartServerRepositorySetMakeWorkingTrees(
1767
tests.TestCaseWithMemoryTransport):
1769
def test_set_false(self):
1770
backing = self.get_transport()
1771
repo = self.make_repository('.', shared=True)
1772
repo.set_make_working_trees(True)
1773
request_class = smart_repo.SmartServerRepositorySetMakeWorkingTrees
1774
request = request_class(backing)
1775
self.assertEqual(smart_req.SuccessfulSmartServerResponse(('ok',)),
1776
request.execute('', 'False'))
1777
repo = repo.bzrdir.open_repository()
1778
self.assertFalse(repo.make_working_trees())
1780
def test_set_true(self):
1781
backing = self.get_transport()
1782
repo = self.make_repository('.', shared=True)
1783
repo.set_make_working_trees(False)
1784
request_class = smart_repo.SmartServerRepositorySetMakeWorkingTrees
1785
request = request_class(backing)
1786
self.assertEqual(smart_req.SuccessfulSmartServerResponse(('ok',)),
1787
request.execute('', 'True'))
1788
repo = repo.bzrdir.open_repository()
1789
self.assertTrue(repo.make_working_trees())
1792
class TestSmartServerPackRepositoryAutopack(tests.TestCaseWithTransport):
1794
def make_repo_needing_autopacking(self, path='.'):
1795
# Make a repo in need of autopacking.
1796
tree = self.make_branch_and_tree('.', format='pack-0.92')
1797
repo = tree.branch.repository
1798
# monkey-patch the pack collection to disable autopacking
1799
repo._pack_collection._max_pack_count = lambda count: count
1801
tree.commit('commit %s' % x)
1802
self.assertEqual(10, len(repo._pack_collection.names()))
1803
del repo._pack_collection._max_pack_count
1806
def test_autopack_needed(self):
1807
repo = self.make_repo_needing_autopacking()
1809
self.addCleanup(repo.unlock)
1810
backing = self.get_transport()
1811
request = smart_packrepo.SmartServerPackRepositoryAutopack(
1813
response = request.execute('')
1814
self.assertEqual(smart_req.SmartServerResponse(('ok',)), response)
1815
repo._pack_collection.reload_pack_names()
1816
self.assertEqual(1, len(repo._pack_collection.names()))
1818
def test_autopack_not_needed(self):
1819
tree = self.make_branch_and_tree('.', format='pack-0.92')
1820
repo = tree.branch.repository
1822
self.addCleanup(repo.unlock)
1824
tree.commit('commit %s' % x)
1825
backing = self.get_transport()
1826
request = smart_packrepo.SmartServerPackRepositoryAutopack(
1828
response = request.execute('')
1829
self.assertEqual(smart_req.SmartServerResponse(('ok',)), response)
1830
repo._pack_collection.reload_pack_names()
1831
self.assertEqual(9, len(repo._pack_collection.names()))
1833
def test_autopack_on_nonpack_format(self):
1834
"""A request to autopack a non-pack repo is a no-op."""
1835
repo = self.make_repository('.', format='knit')
1836
backing = self.get_transport()
1837
request = smart_packrepo.SmartServerPackRepositoryAutopack(
1839
response = request.execute('')
1840
self.assertEqual(smart_req.SmartServerResponse(('ok',)), response)
1843
class TestSmartServerVfsGet(tests.TestCaseWithMemoryTransport):
1845
def test_unicode_path(self):
1846
"""VFS requests expect unicode paths to be escaped."""
1847
filename = u'foo\N{INTERROBANG}'
1848
filename_escaped = urlutils.escape(filename)
1849
backing = self.get_transport()
1850
request = vfs.GetRequest(backing)
1851
backing.put_bytes_non_atomic(filename_escaped, 'contents')
1852
self.assertEqual(smart_req.SmartServerResponse(('ok', ), 'contents'),
1853
request.execute(filename_escaped))
1022
SmartServerResponse(('yes',)), response)
1856
1025
class TestHandlers(tests.TestCase):
1860
1029
"""All registered request_handlers can be found."""
1861
1030
# If there's a typo in a register_lazy call, this loop will fail with
1862
1031
# an AttributeError.
1863
for key, item in smart_req.request_handlers.iteritems():
1032
for key, item in smart.request.request_handlers.iteritems():
1866
def assertHandlerEqual(self, verb, handler):
1867
self.assertEqual(smart_req.request_handlers.get(verb), handler)
1869
1035
def test_registered_methods(self):
1870
1036
"""Test that known methods are registered to the correct object."""
1871
self.assertHandlerEqual('Branch.get_config_file',
1872
smart_branch.SmartServerBranchGetConfigFile)
1873
self.assertHandlerEqual('Branch.get_parent',
1874
smart_branch.SmartServerBranchGetParent)
1875
self.assertHandlerEqual('Branch.get_tags_bytes',
1876
smart_branch.SmartServerBranchGetTagsBytes)
1877
self.assertHandlerEqual('Branch.lock_write',
1878
smart_branch.SmartServerBranchRequestLockWrite)
1879
self.assertHandlerEqual('Branch.last_revision_info',
1880
smart_branch.SmartServerBranchRequestLastRevisionInfo)
1881
self.assertHandlerEqual('Branch.revision_history',
1882
smart_branch.SmartServerRequestRevisionHistory)
1883
self.assertHandlerEqual('Branch.set_config_option',
1884
smart_branch.SmartServerBranchRequestSetConfigOption)
1885
self.assertHandlerEqual('Branch.set_last_revision',
1886
smart_branch.SmartServerBranchRequestSetLastRevision)
1887
self.assertHandlerEqual('Branch.set_last_revision_info',
1888
smart_branch.SmartServerBranchRequestSetLastRevisionInfo)
1889
self.assertHandlerEqual('Branch.set_last_revision_ex',
1890
smart_branch.SmartServerBranchRequestSetLastRevisionEx)
1891
self.assertHandlerEqual('Branch.set_parent_location',
1892
smart_branch.SmartServerBranchRequestSetParentLocation)
1893
self.assertHandlerEqual('Branch.unlock',
1894
smart_branch.SmartServerBranchRequestUnlock)
1895
self.assertHandlerEqual('BzrDir.find_repository',
1896
smart_dir.SmartServerRequestFindRepositoryV1)
1897
self.assertHandlerEqual('BzrDir.find_repositoryV2',
1898
smart_dir.SmartServerRequestFindRepositoryV2)
1899
self.assertHandlerEqual('BzrDirFormat.initialize',
1900
smart_dir.SmartServerRequestInitializeBzrDir)
1901
self.assertHandlerEqual('BzrDirFormat.initialize_ex_1.16',
1902
smart_dir.SmartServerRequestBzrDirInitializeEx)
1903
self.assertHandlerEqual('BzrDir.cloning_metadir',
1904
smart_dir.SmartServerBzrDirRequestCloningMetaDir)
1905
self.assertHandlerEqual('BzrDir.get_config_file',
1906
smart_dir.SmartServerBzrDirRequestConfigFile)
1907
self.assertHandlerEqual('BzrDir.open_branch',
1908
smart_dir.SmartServerRequestOpenBranch)
1909
self.assertHandlerEqual('BzrDir.open_branchV2',
1910
smart_dir.SmartServerRequestOpenBranchV2)
1911
self.assertHandlerEqual('BzrDir.open_branchV3',
1912
smart_dir.SmartServerRequestOpenBranchV3)
1913
self.assertHandlerEqual('PackRepository.autopack',
1914
smart_packrepo.SmartServerPackRepositoryAutopack)
1915
self.assertHandlerEqual('Repository.gather_stats',
1916
smart_repo.SmartServerRepositoryGatherStats)
1917
self.assertHandlerEqual('Repository.get_parent_map',
1918
smart_repo.SmartServerRepositoryGetParentMap)
1919
self.assertHandlerEqual('Repository.get_rev_id_for_revno',
1920
smart_repo.SmartServerRepositoryGetRevIdForRevno)
1921
self.assertHandlerEqual('Repository.get_revision_graph',
1922
smart_repo.SmartServerRepositoryGetRevisionGraph)
1923
self.assertHandlerEqual('Repository.get_stream',
1924
smart_repo.SmartServerRepositoryGetStream)
1925
self.assertHandlerEqual('Repository.get_stream_1.19',
1926
smart_repo.SmartServerRepositoryGetStream_1_19)
1927
self.assertHandlerEqual('Repository.has_revision',
1928
smart_repo.SmartServerRequestHasRevision)
1929
self.assertHandlerEqual('Repository.insert_stream',
1930
smart_repo.SmartServerRepositoryInsertStream)
1931
self.assertHandlerEqual('Repository.insert_stream_locked',
1932
smart_repo.SmartServerRepositoryInsertStreamLocked)
1933
self.assertHandlerEqual('Repository.is_shared',
1934
smart_repo.SmartServerRepositoryIsShared)
1935
self.assertHandlerEqual('Repository.lock_write',
1936
smart_repo.SmartServerRepositoryLockWrite)
1937
self.assertHandlerEqual('Repository.tarball',
1938
smart_repo.SmartServerRepositoryTarball)
1939
self.assertHandlerEqual('Repository.unlock',
1940
smart_repo.SmartServerRepositoryUnlock)
1941
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/')])
1038
smart.request.request_handlers.get('Branch.get_config_file'),
1039
smart.branch.SmartServerBranchGetConfigFile)
1041
smart.request.request_handlers.get('Branch.lock_write'),
1042
smart.branch.SmartServerBranchRequestLockWrite)
1044
smart.request.request_handlers.get('Branch.last_revision_info'),
1045
smart.branch.SmartServerBranchRequestLastRevisionInfo)
1047
smart.request.request_handlers.get('Branch.revision_history'),
1048
smart.branch.SmartServerRequestRevisionHistory)
1050
smart.request.request_handlers.get('Branch.set_last_revision'),
1051
smart.branch.SmartServerBranchRequestSetLastRevision)
1053
smart.request.request_handlers.get('Branch.set_last_revision_info'),
1054
smart.branch.SmartServerBranchRequestSetLastRevisionInfo)
1056
smart.request.request_handlers.get('Branch.unlock'),
1057
smart.branch.SmartServerBranchRequestUnlock)
1059
smart.request.request_handlers.get('BzrDir.find_repository'),
1060
smart.bzrdir.SmartServerRequestFindRepositoryV1)
1062
smart.request.request_handlers.get('BzrDir.find_repositoryV2'),
1063
smart.bzrdir.SmartServerRequestFindRepositoryV2)
1065
smart.request.request_handlers.get('BzrDirFormat.initialize'),
1066
smart.bzrdir.SmartServerRequestInitializeBzrDir)
1068
smart.request.request_handlers.get('BzrDir.open_branch'),
1069
smart.bzrdir.SmartServerRequestOpenBranch)
1071
smart.request.request_handlers.get('Repository.gather_stats'),
1072
smart.repository.SmartServerRepositoryGatherStats)
1074
smart.request.request_handlers.get('Repository.get_parent_map'),
1075
smart.repository.SmartServerRepositoryGetParentMap)
1077
smart.request.request_handlers.get(
1078
'Repository.get_revision_graph'),
1079
smart.repository.SmartServerRepositoryGetRevisionGraph)
1081
smart.request.request_handlers.get('Repository.has_revision'),
1082
smart.repository.SmartServerRequestHasRevision)
1084
smart.request.request_handlers.get('Repository.is_shared'),
1085
smart.repository.SmartServerRepositoryIsShared)
1087
smart.request.request_handlers.get('Repository.lock_write'),
1088
smart.repository.SmartServerRepositoryLockWrite)
1090
smart.request.request_handlers.get('Repository.tarball'),
1091
smart.repository.SmartServerRepositoryTarball)
1093
smart.request.request_handlers.get('Repository.unlock'),
1094
smart.repository.SmartServerRepositoryUnlock)
1096
smart.request.request_handlers.get('Transport.is_readonly'),
1097
smart.request.SmartServerIsReadonly)