28
from cStringIO import StringIO
30
31
from bzrlib import (
32
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.testament import Testament
52
from bzrlib.tests import test_server
53
from bzrlib.transport import (
39
from bzrlib.branch import Branch, BranchReferenceFormat
40
import bzrlib.smart.branch
41
import bzrlib.smart.bzrdir
42
import bzrlib.smart.repository
43
from bzrlib.smart.request import (
44
FailedSmartServerResponse,
47
SuccessfulSmartServerResponse,
49
from bzrlib.tests import (
54
from bzrlib.transport import chroot, get_transport
55
from bzrlib.util import bencode
59
58
def load_tests(standard_tests, module, loader):
60
59
"""Multiply tests version and protocol consistency."""
61
60
# FindRepository tests.
61
bzrdir_mod = bzrlib.smart.bzrdir
62
applier = TestScenarioApplier()
63
64
("find_repository", {
64
"_request_class": smart_dir.SmartServerRequestFindRepositoryV1}),
65
"_request_class":bzrdir_mod.SmartServerRequestFindRepositoryV1}),
65
66
("find_repositoryV2", {
66
"_request_class": smart_dir.SmartServerRequestFindRepositoryV2}),
67
("find_repositoryV3", {
68
"_request_class": smart_dir.SmartServerRequestFindRepositoryV3}),
67
"_request_class":bzrdir_mod.SmartServerRequestFindRepositoryV2}),
70
to_adapt, result = tests.split_suite_by_re(standard_tests,
69
to_adapt, result = split_suite_by_re(standard_tests,
71
70
"TestSmartServerRequestFindRepository")
72
v2_only, v1_and_2 = tests.split_suite_by_re(to_adapt,
71
v2_only, v1_and_2 = split_suite_by_re(to_adapt,
74
tests.multiply_tests(v1_and_2, scenarios, result)
75
# The first scenario is only applicable to v1 protocols, it is deleted
77
tests.multiply_tests(v2_only, scenarios[1:], result)
73
for test in iter_suite_tests(v1_and_2):
74
result.addTests(applier.adapt(test))
75
del applier.scenarios[0]
76
for test in iter_suite_tests(v2_only):
77
result.addTests(applier.adapt(test))
81
81
class TestCaseWithChrootedTransport(tests.TestCaseWithTransport):
84
self.vfs_transport_factory = memory.MemoryServer
85
super(TestCaseWithChrootedTransport, self).setUp()
84
tests.TestCaseWithTransport.setUp(self)
86
85
self._chroot_server = None
88
87
def get_transport(self, relpath=None):
89
88
if self._chroot_server is None:
90
89
backing_transport = tests.TestCaseWithTransport.get_transport(self)
91
90
self._chroot_server = chroot.ChrootServer(backing_transport)
92
self.start_server(self._chroot_server)
93
t = transport.get_transport_from_url(self._chroot_server.get_url())
91
self._chroot_server.setUp()
92
self.addCleanup(self._chroot_server.tearDown)
93
t = get_transport(self._chroot_server.get_url())
94
94
if relpath is not None:
95
95
t = t.clone(relpath)
99
class TestCaseWithSmartMedium(tests.TestCaseWithMemoryTransport):
99
class TestCaseWithSmartMedium(tests.TestCaseWithTransport):
102
102
super(TestCaseWithSmartMedium, self).setUp()
104
104
# the default or a parameterized class, but rather use the
105
105
# TestCaseWithTransport infrastructure to set up a smart server and
107
self.overrideAttr(self, "transport_server", self.make_transport_server)
107
self.transport_server = self.make_transport_server
109
109
def make_transport_server(self):
110
return test_server.SmartTCPServer_for_testing('-' + self.id())
110
return smart.server.SmartTCPServer_for_testing('-' + self.id())
112
112
def get_smart_medium(self):
113
113
"""Get a smart medium to use in tests."""
114
114
return self.get_transport().get_smart_medium()
117
class TestByteStreamToStream(tests.TestCase):
119
def test_repeated_substreams_same_kind_are_one_stream(self):
120
# Make a stream - an iterable of bytestrings.
121
stream = [('text', [versionedfile.FulltextContentFactory(('k1',), None,
122
None, 'foo')]),('text', [
123
versionedfile.FulltextContentFactory(('k2',), None, None, 'bar')])]
124
fmt = controldir.format_registry.get('pack-0.92')().repository_format
125
bytes = smart_repo._stream_to_byte_stream(stream, fmt)
127
# Iterate the resulting iterable; checking that we get only one stream
129
fmt, stream = smart_repo._byte_stream_to_stream(bytes)
130
for kind, substream in stream:
131
streams.append((kind, list(substream)))
132
self.assertLength(1, streams)
133
self.assertLength(2, streams[0][1])
136
117
class TestSmartServerResponse(tests.TestCase):
138
119
def test__eq__(self):
139
self.assertEqual(smart_req.SmartServerResponse(('ok', )),
140
smart_req.SmartServerResponse(('ok', )))
141
self.assertEqual(smart_req.SmartServerResponse(('ok', ), 'body'),
142
smart_req.SmartServerResponse(('ok', ), 'body'))
143
self.assertNotEqual(smart_req.SmartServerResponse(('ok', )),
144
smart_req.SmartServerResponse(('notok', )))
145
self.assertNotEqual(smart_req.SmartServerResponse(('ok', ), 'body'),
146
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', )))
147
128
self.assertNotEqual(None,
148
smart_req.SmartServerResponse(('ok', )))
129
SmartServerResponse(('ok', )))
150
131
def test__str__(self):
151
132
"""SmartServerResponses can be stringified."""
152
133
self.assertEqual(
153
134
"<SuccessfulSmartServerResponse args=('args',) body='body'>",
154
str(smart_req.SuccessfulSmartServerResponse(('args',), 'body')))
135
str(SuccessfulSmartServerResponse(('args',), 'body')))
155
136
self.assertEqual(
156
137
"<FailedSmartServerResponse args=('args',) body='body'>",
157
str(smart_req.FailedSmartServerResponse(('args',), 'body')))
138
str(FailedSmartServerResponse(('args',), 'body')))
160
141
class TestSmartServerRequest(tests.TestCaseWithMemoryTransport):
162
143
def test_translate_client_path(self):
163
144
transport = self.get_transport()
164
request = smart_req.SmartServerRequest(transport, 'foo/')
145
request = SmartServerRequest(transport, 'foo/')
165
146
self.assertEqual('./', request.translate_client_path('foo/'))
166
147
self.assertRaises(
167
148
errors.InvalidURLJoin, request.translate_client_path, 'foo/..')
170
151
self.assertRaises(
171
152
errors.PathNotChild, request.translate_client_path, 'bar/')
172
153
self.assertEqual('./baz', request.translate_client_path('foo/baz'))
173
e_acute = u'\N{LATIN SMALL LETTER E WITH ACUTE}'.encode('utf-8')
174
self.assertEqual('./' + urlutils.escape(e_acute),
175
request.translate_client_path('foo/' + e_acute))
177
def test_translate_client_path_vfs(self):
178
"""VfsRequests receive escaped paths rather than raw UTF-8."""
179
transport = self.get_transport()
180
request = vfs.VfsRequest(transport, 'foo/')
181
e_acute = u'\N{LATIN SMALL LETTER E WITH ACUTE}'.encode('utf-8')
182
escaped = urlutils.escape('foo/' + e_acute)
183
self.assertEqual('./' + urlutils.escape(e_acute),
184
request.translate_client_path(escaped))
186
155
def test_transport_from_client_path(self):
187
156
transport = self.get_transport()
188
request = smart_req.SmartServerRequest(transport, 'foo/')
157
request = SmartServerRequest(transport, 'foo/')
189
158
self.assertEqual(
191
160
request.transport_from_client_path('foo/').base)
194
class TestSmartServerBzrDirRequestCloningMetaDir(
195
tests.TestCaseWithMemoryTransport):
196
"""Tests for BzrDir.cloning_metadir."""
198
def test_cloning_metadir(self):
199
"""When there is a bzrdir present, the call succeeds."""
200
backing = self.get_transport()
201
dir = self.make_bzrdir('.')
202
local_result = dir.cloning_metadir()
203
request_class = smart_dir.SmartServerBzrDirRequestCloningMetaDir
204
request = request_class(backing)
205
expected = smart_req.SuccessfulSmartServerResponse(
206
(local_result.network_name(),
207
local_result.repository_format.network_name(),
208
('branch', local_result.get_branch_format().network_name())))
209
self.assertEqual(expected, request.execute('', 'False'))
211
def test_cloning_metadir_reference(self):
212
"""The request fails when bzrdir contains a branch reference."""
213
backing = self.get_transport()
214
referenced_branch = self.make_branch('referenced')
215
dir = self.make_bzrdir('.')
216
local_result = dir.cloning_metadir()
217
reference = _mod_branch.BranchReferenceFormat().initialize(
218
dir, target_branch=referenced_branch)
219
reference_url = _mod_branch.BranchReferenceFormat().get_reference(dir)
220
# The server shouldn't try to follow the branch reference, so it's fine
221
# if the referenced branch isn't reachable.
222
backing.rename('referenced', 'moved')
223
request_class = smart_dir.SmartServerBzrDirRequestCloningMetaDir
224
request = request_class(backing)
225
expected = smart_req.FailedSmartServerResponse(('BranchReference',))
226
self.assertEqual(expected, request.execute('', 'False'))
229
class TestSmartServerBzrDirRequestCloningMetaDir(
230
tests.TestCaseWithMemoryTransport):
231
"""Tests for BzrDir.checkout_metadir."""
233
def test_checkout_metadir(self):
234
backing = self.get_transport()
235
request = smart_dir.SmartServerBzrDirRequestCheckoutMetaDir(
237
branch = self.make_branch('.', format='2a')
238
response = request.execute('')
240
smart_req.SmartServerResponse(
241
('Bazaar-NG meta directory, format 1\n',
242
'Bazaar repository format 2a (needs bzr 1.16 or later)\n',
243
'Bazaar Branch Format 7 (needs bzr 1.6)\n')),
247
class TestSmartServerBzrDirRequestDestroyBranch(
248
tests.TestCaseWithMemoryTransport):
249
"""Tests for BzrDir.destroy_branch."""
251
def test_destroy_branch_default(self):
252
"""The default branch can be removed."""
253
backing = self.get_transport()
254
dir = self.make_branch('.').bzrdir
255
request_class = smart_dir.SmartServerBzrDirRequestDestroyBranch
256
request = request_class(backing)
257
expected = smart_req.SuccessfulSmartServerResponse(('ok',))
258
self.assertEqual(expected, request.execute('', None))
260
def test_destroy_branch_named(self):
261
"""A named branch can be removed."""
262
backing = self.get_transport()
263
dir = self.make_repository('.', format="development-colo").bzrdir
264
dir.create_branch(name="branchname")
265
request_class = smart_dir.SmartServerBzrDirRequestDestroyBranch
266
request = request_class(backing)
267
expected = smart_req.SuccessfulSmartServerResponse(('ok',))
268
self.assertEqual(expected, request.execute('', "branchname"))
270
def test_destroy_branch_missing(self):
271
"""An error is raised if the branch didn't exist."""
272
backing = self.get_transport()
273
dir = self.make_bzrdir('.', format="development-colo")
274
request_class = smart_dir.SmartServerBzrDirRequestDestroyBranch
275
request = request_class(backing)
276
expected = smart_req.FailedSmartServerResponse(('nobranch',), None)
277
self.assertEqual(expected, request.execute('', "branchname"))
280
class TestSmartServerBzrDirRequestHasWorkingTree(
281
tests.TestCaseWithTransport):
282
"""Tests for BzrDir.has_workingtree."""
284
def test_has_workingtree_yes(self):
285
"""A working tree is present."""
286
backing = self.get_transport()
287
dir = self.make_branch_and_tree('.').bzrdir
288
request_class = smart_dir.SmartServerBzrDirRequestHasWorkingTree
289
request = request_class(backing)
290
expected = smart_req.SuccessfulSmartServerResponse(('yes',))
291
self.assertEqual(expected, request.execute(''))
293
def test_has_workingtree_no(self):
294
"""A working tree is missing."""
295
backing = self.get_transport()
296
dir = self.make_bzrdir('.')
297
request_class = smart_dir.SmartServerBzrDirRequestHasWorkingTree
298
request = request_class(backing)
299
expected = smart_req.SuccessfulSmartServerResponse(('no',))
300
self.assertEqual(expected, request.execute(''))
303
class TestSmartServerBzrDirRequestDestroyRepository(
304
tests.TestCaseWithMemoryTransport):
305
"""Tests for BzrDir.destroy_repository."""
307
def test_destroy_repository_default(self):
308
"""The repository can be removed."""
309
backing = self.get_transport()
310
dir = self.make_repository('.').bzrdir
311
request_class = smart_dir.SmartServerBzrDirRequestDestroyRepository
312
request = request_class(backing)
313
expected = smart_req.SuccessfulSmartServerResponse(('ok',))
314
self.assertEqual(expected, request.execute(''))
316
def test_destroy_repository_missing(self):
317
"""An error is raised if the repository didn't exist."""
318
backing = self.get_transport()
319
dir = self.make_bzrdir('.')
320
request_class = smart_dir.SmartServerBzrDirRequestDestroyRepository
321
request = request_class(backing)
322
expected = smart_req.FailedSmartServerResponse(
323
('norepository',), None)
324
self.assertEqual(expected, request.execute(''))
327
class TestSmartServerRequestCreateRepository(tests.TestCaseWithMemoryTransport):
328
"""Tests for BzrDir.create_repository."""
330
def test_makes_repository(self):
331
"""When there is a bzrdir present, the call succeeds."""
332
backing = self.get_transport()
333
self.make_bzrdir('.')
334
request_class = smart_dir.SmartServerRequestCreateRepository
335
request = request_class(backing)
336
reference_bzrdir_format = controldir.format_registry.get('pack-0.92')()
337
reference_format = reference_bzrdir_format.repository_format
338
network_name = reference_format.network_name()
339
expected = smart_req.SuccessfulSmartServerResponse(
340
('ok', 'no', 'no', 'no', network_name))
341
self.assertEqual(expected, request.execute('', network_name, 'True'))
344
163
class TestSmartServerRequestFindRepository(tests.TestCaseWithMemoryTransport):
345
164
"""Tests for BzrDir.find_repository."""
429
235
"""Test for the supports_external_lookups attribute."""
430
236
backing = self.get_transport()
431
237
request = self._request_class(backing)
432
result = self._make_repository_and_result(
433
format='development-subtree')
238
result = self._make_repository_and_result(format='dirstate-with-subtree')
434
239
# check the test will be valid
435
self.assertEqual('yes', result.args[4])
240
self.assertEqual('no', result.args[4])
436
241
self.assertEqual(result, request.execute(''))
439
class TestSmartServerBzrDirRequestGetConfigFile(
440
tests.TestCaseWithMemoryTransport):
441
"""Tests for BzrDir.get_config_file."""
443
def test_present(self):
444
backing = self.get_transport()
445
dir = self.make_bzrdir('.')
446
dir.get_config().set_default_stack_on("/")
447
local_result = dir._get_config()._get_config_file().read()
448
request_class = smart_dir.SmartServerBzrDirRequestConfigFile
449
request = request_class(backing)
450
expected = smart_req.SuccessfulSmartServerResponse((), local_result)
451
self.assertEqual(expected, request.execute(''))
453
def test_missing(self):
454
backing = self.get_transport()
455
dir = self.make_bzrdir('.')
456
request_class = smart_dir.SmartServerBzrDirRequestConfigFile
457
request = request_class(backing)
458
expected = smart_req.SuccessfulSmartServerResponse((), '')
459
self.assertEqual(expected, request.execute(''))
462
class TestSmartServerBzrDirRequestGetBranches(
463
tests.TestCaseWithMemoryTransport):
464
"""Tests for BzrDir.get_branches."""
466
def test_simple(self):
467
backing = self.get_transport()
468
branch = self.make_branch('.')
469
request_class = smart_dir.SmartServerBzrDirRequestGetBranches
470
request = request_class(backing)
471
local_result = bencode.bencode(
472
{"": ("branch", branch._format.network_name())})
473
expected = smart_req.SuccessfulSmartServerResponse(
474
("success", ), local_result)
475
self.assertEqual(expected, request.execute(''))
477
def test_empty(self):
478
backing = self.get_transport()
479
dir = self.make_bzrdir('.')
480
request_class = smart_dir.SmartServerBzrDirRequestGetBranches
481
request = request_class(backing)
482
local_result = bencode.bencode({})
483
expected = smart_req.SuccessfulSmartServerResponse(
484
('success',), local_result)
485
self.assertEqual(expected, request.execute(''))
488
244
class TestSmartServerRequestInitializeBzrDir(tests.TestCaseWithMemoryTransport):
490
246
def test_empty_dir(self):
491
247
"""Initializing an empty dir should succeed and do it."""
492
248
backing = self.get_transport()
493
request = smart_dir.SmartServerRequestInitializeBzrDir(backing)
494
self.assertEqual(smart_req.SmartServerResponse(('ok', )),
249
request = smart.bzrdir.SmartServerRequestInitializeBzrDir(backing)
250
self.assertEqual(SmartServerResponse(('ok', )),
495
251
request.execute(''))
496
made_dir = controldir.ControlDir.open_from_transport(backing)
497
# no branch, tree or repository is expected with the current
252
made_dir = bzrdir.BzrDir.open_from_transport(backing)
253
# no branch, tree or repository is expected with the current
498
254
# default formart.
499
255
self.assertRaises(errors.NoWorkingTree, made_dir.open_workingtree)
500
256
self.assertRaises(errors.NotBranchError, made_dir.open_branch)
503
259
def test_missing_dir(self):
504
260
"""Initializing a missing directory should fail like the bzrdir api."""
505
261
backing = self.get_transport()
506
request = smart_dir.SmartServerRequestInitializeBzrDir(backing)
262
request = smart.bzrdir.SmartServerRequestInitializeBzrDir(backing)
507
263
self.assertRaises(errors.NoSuchFile,
508
264
request.execute, 'subdir')
510
266
def test_initialized_dir(self):
511
267
"""Initializing an extant bzrdir should fail like the bzrdir api."""
512
268
backing = self.get_transport()
513
request = smart_dir.SmartServerRequestInitializeBzrDir(backing)
269
request = smart.bzrdir.SmartServerRequestInitializeBzrDir(backing)
514
270
self.make_bzrdir('subdir')
515
self.assertRaises(errors.AlreadyControlDirError,
271
self.assertRaises(errors.FileExists,
516
272
request.execute, 'subdir')
519
class TestSmartServerRequestBzrDirInitializeEx(
520
tests.TestCaseWithMemoryTransport):
521
"""Basic tests for BzrDir.initialize_ex_1.16 in the smart server.
523
The main unit tests in test_bzrdir exercise the API comprehensively.
526
def test_empty_dir(self):
527
"""Initializing an empty dir should succeed and do it."""
528
backing = self.get_transport()
529
name = self.make_bzrdir('reference')._format.network_name()
530
request = smart_dir.SmartServerRequestBzrDirInitializeEx(backing)
532
smart_req.SmartServerResponse(('', '', '', '', '', '', name,
533
'False', '', '', '')),
534
request.execute(name, '', 'True', 'False', 'False', '', '', '', '',
536
made_dir = controldir.ControlDir.open_from_transport(backing)
537
# no branch, tree or repository is expected with the current
539
self.assertRaises(errors.NoWorkingTree, made_dir.open_workingtree)
540
self.assertRaises(errors.NotBranchError, made_dir.open_branch)
541
self.assertRaises(errors.NoRepositoryPresent, made_dir.open_repository)
543
def test_missing_dir(self):
544
"""Initializing a missing directory should fail like the bzrdir api."""
545
backing = self.get_transport()
546
name = self.make_bzrdir('reference')._format.network_name()
547
request = smart_dir.SmartServerRequestBzrDirInitializeEx(backing)
548
self.assertRaises(errors.NoSuchFile, request.execute, name,
549
'subdir/dir', 'False', 'False', 'False', '', '', '', '', 'False')
551
def test_initialized_dir(self):
552
"""Initializing an extant directory should fail like the bzrdir api."""
553
backing = self.get_transport()
554
name = self.make_bzrdir('reference')._format.network_name()
555
request = smart_dir.SmartServerRequestBzrDirInitializeEx(backing)
556
self.make_bzrdir('subdir')
557
self.assertRaises(errors.FileExists, request.execute, name, 'subdir',
558
'False', 'False', 'False', '', '', '', '', 'False')
561
class TestSmartServerRequestOpenBzrDir(tests.TestCaseWithMemoryTransport):
563
def test_no_directory(self):
564
backing = self.get_transport()
565
request = smart_dir.SmartServerRequestOpenBzrDir(backing)
566
self.assertEqual(smart_req.SmartServerResponse(('no', )),
567
request.execute('does-not-exist'))
569
def test_empty_directory(self):
570
backing = self.get_transport()
571
backing.mkdir('empty')
572
request = smart_dir.SmartServerRequestOpenBzrDir(backing)
573
self.assertEqual(smart_req.SmartServerResponse(('no', )),
574
request.execute('empty'))
576
def test_outside_root_client_path(self):
577
backing = self.get_transport()
578
request = smart_dir.SmartServerRequestOpenBzrDir(backing,
579
root_client_path='root')
580
self.assertEqual(smart_req.SmartServerResponse(('no', )),
581
request.execute('not-root'))
584
class TestSmartServerRequestOpenBzrDir_2_1(tests.TestCaseWithMemoryTransport):
586
def test_no_directory(self):
587
backing = self.get_transport()
588
request = smart_dir.SmartServerRequestOpenBzrDir_2_1(backing)
589
self.assertEqual(smart_req.SmartServerResponse(('no', )),
590
request.execute('does-not-exist'))
592
def test_empty_directory(self):
593
backing = self.get_transport()
594
backing.mkdir('empty')
595
request = smart_dir.SmartServerRequestOpenBzrDir_2_1(backing)
596
self.assertEqual(smart_req.SmartServerResponse(('no', )),
597
request.execute('empty'))
599
def test_present_without_workingtree(self):
600
backing = self.get_transport()
601
request = smart_dir.SmartServerRequestOpenBzrDir_2_1(backing)
602
self.make_bzrdir('.')
603
self.assertEqual(smart_req.SmartServerResponse(('yes', 'no')),
606
def test_outside_root_client_path(self):
607
backing = self.get_transport()
608
request = smart_dir.SmartServerRequestOpenBzrDir_2_1(backing,
609
root_client_path='root')
610
self.assertEqual(smart_req.SmartServerResponse(('no',)),
611
request.execute('not-root'))
614
class TestSmartServerRequestOpenBzrDir_2_1_disk(TestCaseWithChrootedTransport):
616
def test_present_with_workingtree(self):
617
self.vfs_transport_factory = test_server.LocalURLServer
618
backing = self.get_transport()
619
request = smart_dir.SmartServerRequestOpenBzrDir_2_1(backing)
620
bd = self.make_bzrdir('.')
621
bd.create_repository()
623
bd.create_workingtree()
624
self.assertEqual(smart_req.SmartServerResponse(('yes', 'yes')),
628
275
class TestSmartServerRequestOpenBranch(TestCaseWithChrootedTransport):
630
277
def test_no_branch(self):
631
278
"""When there is no branch, ('nobranch', ) is returned."""
632
279
backing = self.get_transport()
633
request = smart_dir.SmartServerRequestOpenBranch(backing)
280
request = smart.bzrdir.SmartServerRequestOpenBranch(backing)
634
281
self.make_bzrdir('.')
635
self.assertEqual(smart_req.SmartServerResponse(('nobranch', )),
282
self.assertEqual(SmartServerResponse(('nobranch', )),
636
283
request.execute(''))
638
285
def test_branch(self):
639
286
"""When there is a branch, 'ok' is returned."""
640
287
backing = self.get_transport()
641
request = smart_dir.SmartServerRequestOpenBranch(backing)
288
request = smart.bzrdir.SmartServerRequestOpenBranch(backing)
642
289
self.make_branch('.')
643
self.assertEqual(smart_req.SmartServerResponse(('ok', '')),
290
self.assertEqual(SmartServerResponse(('ok', '')),
644
291
request.execute(''))
646
293
def test_branch_reference(self):
647
294
"""When there is a branch reference, the reference URL is returned."""
648
self.vfs_transport_factory = test_server.LocalURLServer
649
295
backing = self.get_transport()
650
request = smart_dir.SmartServerRequestOpenBranch(backing)
296
request = smart.bzrdir.SmartServerRequestOpenBranch(backing)
651
297
branch = self.make_branch('branch')
652
298
checkout = branch.create_checkout('reference',lightweight=True)
653
reference_url = _mod_branch.BranchReferenceFormat().get_reference(
299
reference_url = BranchReferenceFormat().get_reference(checkout.bzrdir)
655
300
self.assertFileEqual(reference_url, 'reference/.bzr/branch/location')
656
self.assertEqual(smart_req.SmartServerResponse(('ok', reference_url)),
301
self.assertEqual(SmartServerResponse(('ok', reference_url)),
657
302
request.execute('reference'))
659
def test_notification_on_branch_from_repository(self):
660
"""When there is a repository, the error should return details."""
661
backing = self.get_transport()
662
request = smart_dir.SmartServerRequestOpenBranch(backing)
663
repo = self.make_repository('.')
664
self.assertEqual(smart_req.SmartServerResponse(('nobranch',)),
668
class TestSmartServerRequestOpenBranchV2(TestCaseWithChrootedTransport):
670
def test_no_branch(self):
671
"""When there is no branch, ('nobranch', ) is returned."""
672
backing = self.get_transport()
673
self.make_bzrdir('.')
674
request = smart_dir.SmartServerRequestOpenBranchV2(backing)
675
self.assertEqual(smart_req.SmartServerResponse(('nobranch', )),
678
def test_branch(self):
679
"""When there is a branch, 'ok' is returned."""
680
backing = self.get_transport()
681
expected = self.make_branch('.')._format.network_name()
682
request = smart_dir.SmartServerRequestOpenBranchV2(backing)
683
self.assertEqual(smart_req.SuccessfulSmartServerResponse(
684
('branch', expected)),
687
def test_branch_reference(self):
688
"""When there is a branch reference, the reference URL is returned."""
689
self.vfs_transport_factory = test_server.LocalURLServer
690
backing = self.get_transport()
691
request = smart_dir.SmartServerRequestOpenBranchV2(backing)
692
branch = self.make_branch('branch')
693
checkout = branch.create_checkout('reference',lightweight=True)
694
reference_url = _mod_branch.BranchReferenceFormat().get_reference(
696
self.assertFileEqual(reference_url, 'reference/.bzr/branch/location')
697
self.assertEqual(smart_req.SuccessfulSmartServerResponse(
698
('ref', reference_url)),
699
request.execute('reference'))
701
def test_stacked_branch(self):
702
"""Opening a stacked branch does not open the stacked-on branch."""
703
trunk = self.make_branch('trunk')
704
feature = self.make_branch('feature')
705
feature.set_stacked_on_url(trunk.base)
707
_mod_branch.Branch.hooks.install_named_hook(
708
'open', opened_branches.append, None)
709
backing = self.get_transport()
710
request = smart_dir.SmartServerRequestOpenBranchV2(backing)
713
response = request.execute('feature')
715
request.teardown_jail()
716
expected_format = feature._format.network_name()
717
self.assertEqual(smart_req.SuccessfulSmartServerResponse(
718
('branch', expected_format)),
720
self.assertLength(1, opened_branches)
722
def test_notification_on_branch_from_repository(self):
723
"""When there is a repository, the error should return details."""
724
backing = self.get_transport()
725
request = smart_dir.SmartServerRequestOpenBranchV2(backing)
726
repo = self.make_repository('.')
727
self.assertEqual(smart_req.SmartServerResponse(('nobranch',)),
731
class TestSmartServerRequestOpenBranchV3(TestCaseWithChrootedTransport):
733
def test_no_branch(self):
734
"""When there is no branch, ('nobranch', ) is returned."""
735
backing = self.get_transport()
736
self.make_bzrdir('.')
737
request = smart_dir.SmartServerRequestOpenBranchV3(backing)
738
self.assertEqual(smart_req.SmartServerResponse(('nobranch',)),
741
def test_branch(self):
742
"""When there is a branch, 'ok' is returned."""
743
backing = self.get_transport()
744
expected = self.make_branch('.')._format.network_name()
745
request = smart_dir.SmartServerRequestOpenBranchV3(backing)
746
self.assertEqual(smart_req.SuccessfulSmartServerResponse(
747
('branch', expected)),
750
def test_branch_reference(self):
751
"""When there is a branch reference, the reference URL is returned."""
752
self.vfs_transport_factory = test_server.LocalURLServer
753
backing = self.get_transport()
754
request = smart_dir.SmartServerRequestOpenBranchV3(backing)
755
branch = self.make_branch('branch')
756
checkout = branch.create_checkout('reference',lightweight=True)
757
reference_url = _mod_branch.BranchReferenceFormat().get_reference(
759
self.assertFileEqual(reference_url, 'reference/.bzr/branch/location')
760
self.assertEqual(smart_req.SuccessfulSmartServerResponse(
761
('ref', reference_url)),
762
request.execute('reference'))
764
def test_stacked_branch(self):
765
"""Opening a stacked branch does not open the stacked-on branch."""
766
trunk = self.make_branch('trunk')
767
feature = self.make_branch('feature')
768
feature.set_stacked_on_url(trunk.base)
770
_mod_branch.Branch.hooks.install_named_hook(
771
'open', opened_branches.append, None)
772
backing = self.get_transport()
773
request = smart_dir.SmartServerRequestOpenBranchV3(backing)
776
response = request.execute('feature')
778
request.teardown_jail()
779
expected_format = feature._format.network_name()
780
self.assertEqual(smart_req.SuccessfulSmartServerResponse(
781
('branch', expected_format)),
783
self.assertLength(1, opened_branches)
785
def test_notification_on_branch_from_repository(self):
786
"""When there is a repository, the error should return details."""
787
backing = self.get_transport()
788
request = smart_dir.SmartServerRequestOpenBranchV3(backing)
789
repo = self.make_repository('.')
790
self.assertEqual(smart_req.SmartServerResponse(
791
('nobranch', 'location is a repository')),
795
305
class TestSmartServerRequestRevisionHistory(tests.TestCaseWithMemoryTransport):
797
307
def test_empty(self):
798
308
"""For an empty branch, the body is empty."""
799
309
backing = self.get_transport()
800
request = smart_branch.SmartServerRequestRevisionHistory(backing)
310
request = smart.branch.SmartServerRequestRevisionHistory(backing)
801
311
self.make_branch('.')
802
self.assertEqual(smart_req.SmartServerResponse(('ok', ), ''),
312
self.assertEqual(SmartServerResponse(('ok', ), ''),
803
313
request.execute(''))
805
315
def test_not_empty(self):
806
316
"""For a non-empty branch, the body is empty."""
807
317
backing = self.get_transport()
808
request = smart_branch.SmartServerRequestRevisionHistory(backing)
318
request = smart.branch.SmartServerRequestRevisionHistory(backing)
809
319
tree = self.make_branch_and_memory_tree('.')
810
320
tree.lock_write()
860
369
r2 = tree.commit('2nd commit', rev_id=rev_id_utf8)
862
371
self.assertEqual(
863
smart_req.SmartServerResponse(('ok', '2', rev_id_utf8)),
372
SmartServerResponse(('ok', '2', rev_id_utf8)),
864
373
request.execute(''))
867
class TestSmartServerBranchRequestRevisionIdToRevno(
868
tests.TestCaseWithMemoryTransport):
871
backing = self.get_transport()
872
request = smart_branch.SmartServerBranchRequestRevisionIdToRevno(
874
self.make_branch('.')
875
self.assertEqual(smart_req.SmartServerResponse(('ok', '0')),
876
request.execute('', 'null:'))
878
def test_simple(self):
879
backing = self.get_transport()
880
request = smart_branch.SmartServerBranchRequestRevisionIdToRevno(
882
tree = self.make_branch_and_memory_tree('.')
885
r1 = tree.commit('1st commit')
888
smart_req.SmartServerResponse(('ok', '1')),
889
request.execute('', r1))
891
def test_not_found(self):
892
backing = self.get_transport()
893
request = smart_branch.SmartServerBranchRequestRevisionIdToRevno(
895
branch = self.make_branch('.')
897
smart_req.FailedSmartServerResponse(
898
('NoSuchRevision', 'idontexist')),
899
request.execute('', 'idontexist'))
902
class TestSmartServerBranchRequestGetConfigFile(
903
tests.TestCaseWithMemoryTransport):
376
class TestSmartServerBranchRequestGetConfigFile(tests.TestCaseWithMemoryTransport):
905
378
def test_default(self):
906
379
"""With no file, we get empty content."""
907
380
backing = self.get_transport()
908
request = smart_branch.SmartServerBranchGetConfigFile(backing)
381
request = smart.branch.SmartServerBranchGetConfigFile(backing)
909
382
branch = self.make_branch('.')
910
383
# there should be no file by default
912
self.assertEqual(smart_req.SmartServerResponse(('ok', ), content),
385
self.assertEqual(SmartServerResponse(('ok', ), content),
913
386
request.execute(''))
915
388
def test_with_content(self):
916
389
# SmartServerBranchGetConfigFile should return the content from
917
390
# branch.control_files.get('branch.conf') for now - in the future it may
918
# perform more complex processing.
391
# perform more complex processing.
919
392
backing = self.get_transport()
920
request = smart_branch.SmartServerBranchGetConfigFile(backing)
393
request = smart.branch.SmartServerBranchGetConfigFile(backing)
921
394
branch = self.make_branch('.')
922
395
branch._transport.put_bytes('branch.conf', 'foo bar baz')
923
self.assertEqual(smart_req.SmartServerResponse(('ok', ), 'foo bar baz'),
396
self.assertEqual(SmartServerResponse(('ok', ), 'foo bar baz'),
924
397
request.execute(''))
927
class TestLockedBranch(tests.TestCaseWithMemoryTransport):
929
def get_lock_tokens(self, branch):
930
branch_token = branch.lock_write().branch_token
931
repo_token = branch.repository.lock_write().repository_token
932
branch.repository.unlock()
933
return branch_token, repo_token
936
class TestSmartServerBranchRequestPutConfigFile(TestLockedBranch):
938
def test_with_content(self):
939
backing = self.get_transport()
940
request = smart_branch.SmartServerBranchPutConfigFile(backing)
941
branch = self.make_branch('.')
942
branch_token, repo_token = self.get_lock_tokens(branch)
943
self.assertIs(None, request.execute('', branch_token, repo_token))
945
smart_req.SmartServerResponse(('ok', )),
946
request.do_body('foo bar baz'))
948
branch.control_transport.get_bytes('branch.conf'),
953
class TestSmartServerBranchRequestSetConfigOption(TestLockedBranch):
955
def test_value_name(self):
956
branch = self.make_branch('.')
957
request = smart_branch.SmartServerBranchRequestSetConfigOption(
958
branch.bzrdir.root_transport)
959
branch_token, repo_token = self.get_lock_tokens(branch)
960
config = branch._get_config()
961
result = request.execute('', branch_token, repo_token, 'bar', 'foo',
963
self.assertEqual(smart_req.SuccessfulSmartServerResponse(()), result)
964
self.assertEqual('bar', config.get_option('foo'))
968
def test_value_name_section(self):
969
branch = self.make_branch('.')
970
request = smart_branch.SmartServerBranchRequestSetConfigOption(
971
branch.bzrdir.root_transport)
972
branch_token, repo_token = self.get_lock_tokens(branch)
973
config = branch._get_config()
974
result = request.execute('', branch_token, repo_token, 'bar', 'foo',
976
self.assertEqual(smart_req.SuccessfulSmartServerResponse(()), result)
977
self.assertEqual('bar', config.get_option('foo', 'gam'))
982
class TestSmartServerBranchRequestSetConfigOptionDict(TestLockedBranch):
985
TestLockedBranch.setUp(self)
986
# A dict with non-ascii keys and values to exercise unicode
988
self.encoded_value_dict = (
989
'd5:ascii1:a11:unicode \xe2\x8c\x9a3:\xe2\x80\xbde')
991
'ascii': 'a', u'unicode \N{WATCH}': u'\N{INTERROBANG}'}
993
def test_value_name(self):
994
branch = self.make_branch('.')
995
request = smart_branch.SmartServerBranchRequestSetConfigOptionDict(
996
branch.bzrdir.root_transport)
997
branch_token, repo_token = self.get_lock_tokens(branch)
998
config = branch._get_config()
999
result = request.execute('', branch_token, repo_token,
1000
self.encoded_value_dict, 'foo', '')
1001
self.assertEqual(smart_req.SuccessfulSmartServerResponse(()), result)
1002
self.assertEqual(self.value_dict, config.get_option('foo'))
1006
def test_value_name_section(self):
1007
branch = self.make_branch('.')
1008
request = smart_branch.SmartServerBranchRequestSetConfigOptionDict(
1009
branch.bzrdir.root_transport)
1010
branch_token, repo_token = self.get_lock_tokens(branch)
1011
config = branch._get_config()
1012
result = request.execute('', branch_token, repo_token,
1013
self.encoded_value_dict, 'foo', 'gam')
1014
self.assertEqual(smart_req.SuccessfulSmartServerResponse(()), result)
1015
self.assertEqual(self.value_dict, config.get_option('foo', 'gam'))
1020
class TestSmartServerBranchRequestSetTagsBytes(TestLockedBranch):
1021
# Only called when the branch format and tags match [yay factory
1022
# methods] so only need to test straight forward cases.
1024
def test_set_bytes(self):
1025
base_branch = self.make_branch('base')
1026
tag_bytes = base_branch._get_tags_bytes()
1027
# get_lock_tokens takes out a lock.
1028
branch_token, repo_token = self.get_lock_tokens(base_branch)
1029
request = smart_branch.SmartServerBranchSetTagsBytes(
1030
self.get_transport())
1031
response = request.execute('base', branch_token, repo_token)
1032
self.assertEqual(None, response)
1033
response = request.do_chunk(tag_bytes)
1034
self.assertEqual(None, response)
1035
response = request.do_end()
1037
smart_req.SuccessfulSmartServerResponse(()), response)
1038
base_branch.unlock()
1040
def test_lock_failed(self):
1041
base_branch = self.make_branch('base')
1042
base_branch.lock_write()
1043
tag_bytes = base_branch._get_tags_bytes()
1044
request = smart_branch.SmartServerBranchSetTagsBytes(
1045
self.get_transport())
1046
self.assertRaises(errors.TokenMismatch, request.execute,
1047
'base', 'wrong token', 'wrong token')
1048
# The request handler will keep processing the message parts, so even
1049
# if the request fails immediately do_chunk and do_end are still
1051
request.do_chunk(tag_bytes)
1053
base_branch.unlock()
1057
class SetLastRevisionTestBase(TestLockedBranch):
400
class SetLastRevisionTestBase(tests.TestCaseWithMemoryTransport):
1058
401
"""Base test case for verbs that implement set_last_revision."""
1060
403
def setUp(self):
1061
super(SetLastRevisionTestBase, self).setUp()
404
tests.TestCaseWithMemoryTransport.setUp(self)
1062
405
backing_transport = self.get_transport()
1063
406
self.request = self.request_class(backing_transport)
1064
407
self.tree = self.make_branch_and_memory_tree('.')
1066
409
def lock_branch(self):
1067
return self.get_lock_tokens(self.tree.branch)
411
branch_token = b.lock_write()
412
repo_token = b.repository.lock_write()
413
b.repository.unlock()
414
return branch_token, repo_token
1069
416
def unlock_branch(self):
1070
417
self.tree.branch.unlock()
1072
419
def set_last_revision(self, revision_id, revno):
1073
420
branch_token, repo_token = self.lock_branch()
1074
421
response = self._set_last_revision(
1262
608
response = self.request.execute(
1263
609
'', branch_token, repo_token, 'child-1', 1, 0)
1264
610
self.assertEqual(
1265
smart_req.SuccessfulSmartServerResponse(('ok', 2, 'child-1')),
611
SuccessfulSmartServerResponse(('ok', 2, 'child-1')),
1267
613
self.unlock_branch()
1268
614
# The branch tip was changed.
1269
615
self.assertEqual('child-1', self.tree.branch.last_revision())
1272
class TestSmartServerBranchBreakLock(tests.TestCaseWithMemoryTransport):
1274
def test_lock_to_break(self):
1275
base_branch = self.make_branch('base')
1276
request = smart_branch.SmartServerBranchBreakLock(
1277
self.get_transport())
1278
base_branch.lock_write()
1280
smart_req.SuccessfulSmartServerResponse(('ok', ), None),
1281
request.execute('base'))
1283
def test_nothing_to_break(self):
1284
base_branch = self.make_branch('base')
1285
request = smart_branch.SmartServerBranchBreakLock(
1286
self.get_transport())
1288
smart_req.SuccessfulSmartServerResponse(('ok', ), None),
1289
request.execute('base'))
1292
class TestSmartServerBranchRequestGetParent(tests.TestCaseWithMemoryTransport):
1294
def test_get_parent_none(self):
1295
base_branch = self.make_branch('base')
1296
request = smart_branch.SmartServerBranchGetParent(self.get_transport())
1297
response = request.execute('base')
1299
smart_req.SuccessfulSmartServerResponse(('',)), response)
1301
def test_get_parent_something(self):
1302
base_branch = self.make_branch('base')
1303
base_branch.set_parent(self.get_url('foo'))
1304
request = smart_branch.SmartServerBranchGetParent(self.get_transport())
1305
response = request.execute('base')
1307
smart_req.SuccessfulSmartServerResponse(("../foo",)),
1311
class TestSmartServerBranchRequestSetParent(TestLockedBranch):
1313
def test_set_parent_none(self):
1314
branch = self.make_branch('base', format="1.9")
1316
branch._set_parent_location('foo')
1318
request = smart_branch.SmartServerBranchRequestSetParentLocation(
1319
self.get_transport())
1320
branch_token, repo_token = self.get_lock_tokens(branch)
1322
response = request.execute('base', branch_token, repo_token, '')
1325
self.assertEqual(smart_req.SuccessfulSmartServerResponse(()), response)
1326
# Refresh branch as SetParentLocation modified it
1327
branch = branch.bzrdir.open_branch()
1328
self.assertEqual(None, branch.get_parent())
1330
def test_set_parent_something(self):
1331
branch = self.make_branch('base', format="1.9")
1332
request = smart_branch.SmartServerBranchRequestSetParentLocation(
1333
self.get_transport())
1334
branch_token, repo_token = self.get_lock_tokens(branch)
1336
response = request.execute('base', branch_token, repo_token,
1340
self.assertEqual(smart_req.SuccessfulSmartServerResponse(()), response)
1341
refreshed = _mod_branch.Branch.open(branch.base)
1342
self.assertEqual('http://bar/', refreshed.get_parent())
1345
class TestSmartServerBranchRequestGetTagsBytes(
1346
tests.TestCaseWithMemoryTransport):
1347
# Only called when the branch format and tags match [yay factory
1348
# methods] so only need to test straight forward cases.
1350
def test_get_bytes(self):
1351
base_branch = self.make_branch('base')
1352
request = smart_branch.SmartServerBranchGetTagsBytes(
1353
self.get_transport())
1354
response = request.execute('base')
1356
smart_req.SuccessfulSmartServerResponse(('',)), response)
1359
618
class TestSmartServerBranchRequestGetStackedOnURL(tests.TestCaseWithMemoryTransport):
1361
620
def test_get_stacked_on_url(self):
1363
622
stacked_branch = self.make_branch('stacked', format='1.6')
1364
623
# typically should be relative
1365
624
stacked_branch.set_stacked_on_url('../base')
1366
request = smart_branch.SmartServerBranchRequestGetStackedOnURL(
625
request = smart.branch.SmartServerBranchRequestGetStackedOnURL(
1367
626
self.get_transport())
1368
627
response = request.execute('stacked')
1369
628
self.assertEquals(
1370
smart_req.SmartServerResponse(('ok', '../base')),
629
SmartServerResponse(('ok', '../base')),
1374
class TestSmartServerBranchRequestLockWrite(TestLockedBranch):
633
class TestSmartServerBranchRequestLockWrite(tests.TestCaseWithMemoryTransport):
636
tests.TestCaseWithMemoryTransport.setUp(self)
1376
638
def test_lock_write_on_unlocked_branch(self):
1377
639
backing = self.get_transport()
1378
request = smart_branch.SmartServerBranchRequestLockWrite(backing)
640
request = smart.branch.SmartServerBranchRequestLockWrite(backing)
1379
641
branch = self.make_branch('.', format='knit')
1380
642
repository = branch.repository
1381
643
response = request.execute('')
1382
644
branch_nonce = branch.control_files._lock.peek().get('nonce')
1383
645
repository_nonce = repository.control_files._lock.peek().get('nonce')
1384
self.assertEqual(smart_req.SmartServerResponse(
1385
('ok', branch_nonce, repository_nonce)),
647
SmartServerResponse(('ok', branch_nonce, repository_nonce)),
1387
649
# The branch (and associated repository) is now locked. Verify that
1388
650
# with a new branch object.
1389
651
new_branch = repository.bzrdir.open_branch()
1390
652
self.assertRaises(errors.LockContention, new_branch.lock_write)
1392
request = smart_branch.SmartServerBranchRequestUnlock(backing)
1393
response = request.execute('', branch_nonce, repository_nonce)
1395
654
def test_lock_write_on_locked_branch(self):
1396
655
backing = self.get_transport()
1397
request = smart_branch.SmartServerBranchRequestLockWrite(backing)
656
request = smart.branch.SmartServerBranchRequestLockWrite(backing)
1398
657
branch = self.make_branch('.')
1399
branch_token = branch.lock_write().branch_token
1400
659
branch.leave_lock_in_place()
1402
661
response = request.execute('')
1403
662
self.assertEqual(
1404
smart_req.SmartServerResponse(('LockContention',)), response)
1406
branch.lock_write(branch_token)
1407
branch.dont_leave_lock_in_place()
663
SmartServerResponse(('LockContention',)), response)
1410
665
def test_lock_write_with_tokens_on_locked_branch(self):
1411
666
backing = self.get_transport()
1412
request = smart_branch.SmartServerBranchRequestLockWrite(backing)
667
request = smart.branch.SmartServerBranchRequestLockWrite(backing)
1413
668
branch = self.make_branch('.', format='knit')
1414
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()
1415
672
branch.leave_lock_in_place()
1416
673
branch.repository.leave_lock_in_place()
1418
675
response = request.execute('',
1419
676
branch_token, repo_token)
1420
677
self.assertEqual(
1421
smart_req.SmartServerResponse(('ok', branch_token, repo_token)),
1424
branch.repository.lock_write(repo_token)
1425
branch.repository.dont_leave_lock_in_place()
1426
branch.repository.unlock()
1427
branch.lock_write(branch_token)
1428
branch.dont_leave_lock_in_place()
678
SmartServerResponse(('ok', branch_token, repo_token)), response)
1431
680
def test_lock_write_with_mismatched_tokens_on_locked_branch(self):
1432
681
backing = self.get_transport()
1433
request = smart_branch.SmartServerBranchRequestLockWrite(backing)
682
request = smart.branch.SmartServerBranchRequestLockWrite(backing)
1434
683
branch = self.make_branch('.', format='knit')
1435
branch_token, repo_token = self.get_lock_tokens(branch)
684
branch_token = branch.lock_write()
685
repo_token = branch.repository.lock_write()
686
branch.repository.unlock()
1436
687
branch.leave_lock_in_place()
1437
688
branch.repository.leave_lock_in_place()
1439
690
response = request.execute('',
1440
691
branch_token+'xxx', repo_token)
1441
692
self.assertEqual(
1442
smart_req.SmartServerResponse(('TokenMismatch',)), response)
1444
branch.repository.lock_write(repo_token)
1445
branch.repository.dont_leave_lock_in_place()
1446
branch.repository.unlock()
1447
branch.lock_write(branch_token)
1448
branch.dont_leave_lock_in_place()
693
SmartServerResponse(('TokenMismatch',)), response)
1451
695
def test_lock_write_on_locked_repo(self):
1452
696
backing = self.get_transport()
1453
request = smart_branch.SmartServerBranchRequestLockWrite(backing)
697
request = smart.branch.SmartServerBranchRequestLockWrite(backing)
1454
698
branch = self.make_branch('.', format='knit')
1455
repo = branch.repository
1456
repo_token = repo.lock_write().repository_token
1457
repo.leave_lock_in_place()
699
branch.repository.lock_write()
700
branch.repository.leave_lock_in_place()
701
branch.repository.unlock()
1459
702
response = request.execute('')
1460
703
self.assertEqual(
1461
smart_req.SmartServerResponse(('LockContention',)), response)
1463
repo.lock_write(repo_token)
1464
repo.dont_leave_lock_in_place()
704
SmartServerResponse(('LockContention',)), response)
1467
706
def test_lock_write_on_readonly_transport(self):
1468
707
backing = self.get_readonly_transport()
1469
request = smart_branch.SmartServerBranchRequestLockWrite(backing)
708
request = smart.branch.SmartServerBranchRequestLockWrite(backing)
1470
709
branch = self.make_branch('.')
1471
710
root = self.get_transport().clone('/')
1472
711
path = urlutils.relative_url(root.base, self.get_transport().base)
1561
777
# its the exact path being looked at and the server is not
1563
779
backing = self.get_transport()
1564
request = smart_repo.SmartServerRepositoryRequest(backing)
780
request = smart.repository.SmartServerRepositoryRequest(backing)
1565
781
self.make_repository('.', shared=True)
1566
782
self.make_bzrdir('subdir')
1567
783
self.assertRaises(errors.NoRepositoryPresent,
1568
784
request.execute, 'subdir')
1571
class TestSmartServerRepositoryAddSignatureText(tests.TestCaseWithMemoryTransport):
1573
def test_add_text(self):
1574
backing = self.get_transport()
1575
request = smart_repo.SmartServerRepositoryAddSignatureText(backing)
1576
tree = self.make_branch_and_memory_tree('.')
1577
write_token = tree.lock_write()
1578
self.addCleanup(tree.unlock)
1580
tree.commit("Message", rev_id='rev1')
1581
tree.branch.repository.start_write_group()
1582
write_group_tokens = tree.branch.repository.suspend_write_group()
1583
self.assertEqual(None, request.execute('', write_token,
1584
'rev1', *write_group_tokens))
1585
response = request.do_body('somesignature')
1586
self.assertTrue(response.is_successful())
1587
self.assertEqual(response.args[0], 'ok')
1588
write_group_tokens = response.args[1:]
1589
tree.branch.repository.resume_write_group(write_group_tokens)
1590
tree.branch.repository.commit_write_group()
1592
self.assertEqual("somesignature",
1593
tree.branch.repository.get_signature_text("rev1"))
1596
class TestSmartServerRepositoryAllRevisionIds(
1597
tests.TestCaseWithMemoryTransport):
1599
def test_empty(self):
1600
"""An empty body should be returned for an empty repository."""
1601
backing = self.get_transport()
1602
request = smart_repo.SmartServerRepositoryAllRevisionIds(backing)
1603
self.make_repository('.')
1605
smart_req.SuccessfulSmartServerResponse(("ok", ), ""),
1606
request.execute(''))
1608
def test_some_revisions(self):
1609
"""An empty body should be returned for an empty repository."""
1610
backing = self.get_transport()
1611
request = smart_repo.SmartServerRepositoryAllRevisionIds(backing)
1612
tree = self.make_branch_and_memory_tree('.')
1615
tree.commit(rev_id='origineel', message="message")
1616
tree.commit(rev_id='nog-een-revisie', message="message")
1619
smart_req.SuccessfulSmartServerResponse(("ok", ),
1620
"origineel\nnog-een-revisie"),
1621
request.execute(''))
1624
class TestSmartServerRepositoryBreakLock(tests.TestCaseWithMemoryTransport):
1626
def test_lock_to_break(self):
1627
backing = self.get_transport()
1628
request = smart_repo.SmartServerRepositoryBreakLock(backing)
1629
tree = self.make_branch_and_memory_tree('.')
1630
tree.branch.repository.lock_write()
1632
smart_req.SuccessfulSmartServerResponse(('ok', ), None),
1633
request.execute(''))
1635
def test_nothing_to_break(self):
1636
backing = self.get_transport()
1637
request = smart_repo.SmartServerRepositoryBreakLock(backing)
1638
tree = self.make_branch_and_memory_tree('.')
1640
smart_req.SuccessfulSmartServerResponse(('ok', ), None),
1641
request.execute(''))
1644
787
class TestSmartServerRepositoryGetParentMap(tests.TestCaseWithMemoryTransport):
1646
789
def test_trivial_bzipped(self):
1647
790
# This tests that the wire encoding is actually bzipped
1648
791
backing = self.get_transport()
1649
request = smart_repo.SmartServerRepositoryGetParentMap(backing)
792
request = smart.repository.SmartServerRepositoryGetParentMap(backing)
1650
793
tree = self.make_branch_and_memory_tree('.')
1652
795
self.assertEqual(None,
1653
796
request.execute('', 'missing-id'))
1654
# Note that it returns a body that is bzipped.
1656
smart_req.SuccessfulSmartServerResponse(('ok', ), bz2.compress('')),
1657
request.do_body('\n\n0\n'))
1659
def test_trivial_include_missing(self):
1660
backing = self.get_transport()
1661
request = smart_repo.SmartServerRepositoryGetParentMap(backing)
1662
tree = self.make_branch_and_memory_tree('.')
1664
self.assertEqual(None,
1665
request.execute('', 'missing-id', 'include-missing:'))
1667
smart_req.SuccessfulSmartServerResponse(('ok', ),
1668
bz2.compress('missing:missing-id')),
1669
request.do_body('\n\n0\n'))
1672
class TestSmartServerRepositoryGetRevisionGraph(
1673
tests.TestCaseWithMemoryTransport):
797
# Note that it returns a body (of '' bzipped).
799
SuccessfulSmartServerResponse(('ok', ), bz2.compress('')),
800
request.do_body('\n\n0\n'))
803
class TestSmartServerRepositoryGetRevisionGraph(tests.TestCaseWithMemoryTransport):
1675
805
def test_none_argument(self):
1676
806
backing = self.get_transport()
1677
request = smart_repo.SmartServerRepositoryGetRevisionGraph(backing)
807
request = smart.repository.SmartServerRepositoryGetRevisionGraph(backing)
1678
808
tree = self.make_branch_and_memory_tree('.')
1679
809
tree.lock_write()
1717
847
# Note that it still returns body (of zero bytes).
1718
self.assertEqual(smart_req.SmartServerResponse(
1719
('nosuchrevision', 'missingrevision', ), ''),
1720
request.execute('', 'missingrevision'))
1723
class TestSmartServerRepositoryGetRevIdForRevno(
1724
tests.TestCaseWithMemoryTransport):
1726
def test_revno_found(self):
1727
backing = self.get_transport()
1728
request = smart_repo.SmartServerRepositoryGetRevIdForRevno(backing)
1729
tree = self.make_branch_and_memory_tree('.')
1732
rev1_id_utf8 = u'\xc8'.encode('utf-8')
1733
rev2_id_utf8 = u'\xc9'.encode('utf-8')
1734
tree.commit('1st commit', rev_id=rev1_id_utf8)
1735
tree.commit('2nd commit', rev_id=rev2_id_utf8)
1738
self.assertEqual(smart_req.SmartServerResponse(('ok', rev1_id_utf8)),
1739
request.execute('', 1, (2, rev2_id_utf8)))
1741
def test_known_revid_missing(self):
1742
backing = self.get_transport()
1743
request = smart_repo.SmartServerRepositoryGetRevIdForRevno(backing)
1744
repo = self.make_repository('.')
1746
smart_req.FailedSmartServerResponse(('nosuchrevision', 'ghost')),
1747
request.execute('', 1, (2, 'ghost')))
1749
def test_history_incomplete(self):
1750
backing = self.get_transport()
1751
request = smart_repo.SmartServerRepositoryGetRevIdForRevno(backing)
1752
parent = self.make_branch_and_memory_tree('parent', format='1.9')
1754
parent.add([''], ['TREE_ROOT'])
1755
r1 = parent.commit(message='first commit')
1756
r2 = parent.commit(message='second commit')
1758
local = self.make_branch_and_memory_tree('local', format='1.9')
1759
local.branch.pull(parent.branch)
1760
local.set_parent_ids([r2])
1761
r3 = local.commit(message='local commit')
1762
local.branch.create_clone_on_transport(
1763
self.get_transport('stacked'), stacked_on=self.get_url('parent'))
1765
smart_req.SmartServerResponse(('history-incomplete', 2, r2)),
1766
request.execute('stacked', 1, (3, r3)))
1769
class TestSmartServerRepositoryIterRevisions(
1770
tests.TestCaseWithMemoryTransport):
1772
def test_basic(self):
1773
backing = self.get_transport()
1774
request = smart_repo.SmartServerRepositoryIterRevisions(backing)
1775
tree = self.make_branch_and_memory_tree('.', format='2a')
1778
tree.commit('1st commit', rev_id="rev1")
1779
tree.commit('2nd commit', rev_id="rev2")
1782
self.assertIs(None, request.execute(''))
1783
response = request.do_body("rev1\nrev2")
1784
self.assertTrue(response.is_successful())
1785
# Format 2a uses serializer format 10
1786
self.assertEquals(response.args, ("ok", "10"))
1788
self.addCleanup(tree.branch.lock_read().unlock)
1789
entries = [zlib.compress(record.get_bytes_as("fulltext")) for record in
1790
tree.branch.repository.revisions.get_record_stream(
1791
[("rev1", ), ("rev2", )], "unordered", True)]
1793
contents = "".join(response.body_stream)
1794
self.assertTrue(contents in (
1795
"".join([entries[0], entries[1]]),
1796
"".join([entries[1], entries[0]])))
1798
def test_missing(self):
1799
backing = self.get_transport()
1800
request = smart_repo.SmartServerRepositoryIterRevisions(backing)
1801
tree = self.make_branch_and_memory_tree('.', format='2a')
1803
self.assertIs(None, request.execute(''))
1804
response = request.do_body("rev1\nrev2")
1805
self.assertTrue(response.is_successful())
1806
# Format 2a uses serializer format 10
1807
self.assertEquals(response.args, ("ok", "10"))
1809
contents = "".join(response.body_stream)
1810
self.assertEquals(contents, "")
1813
class GetStreamTestBase(tests.TestCaseWithMemoryTransport):
1815
def make_two_commit_repo(self):
1816
tree = self.make_branch_and_memory_tree('.')
1819
r1 = tree.commit('1st commit')
1820
r2 = tree.commit('2nd commit', rev_id=u'\xc8'.encode('utf-8'))
1822
repo = tree.branch.repository
1826
class TestSmartServerRepositoryGetStream(GetStreamTestBase):
1828
def test_ancestry_of(self):
1829
"""The search argument may be a 'ancestry-of' some heads'."""
1830
backing = self.get_transport()
1831
request = smart_repo.SmartServerRepositoryGetStream(backing)
1832
repo, r1, r2 = self.make_two_commit_repo()
1833
fetch_spec = ['ancestry-of', r2]
1834
lines = '\n'.join(fetch_spec)
1835
request.execute('', repo._format.network_name())
1836
response = request.do_body(lines)
1837
self.assertEqual(('ok',), response.args)
1838
stream_bytes = ''.join(response.body_stream)
1839
self.assertStartsWith(stream_bytes, 'Bazaar pack format 1')
1841
def test_search(self):
1842
"""The search argument may be a 'search' of some explicit keys."""
1843
backing = self.get_transport()
1844
request = smart_repo.SmartServerRepositoryGetStream(backing)
1845
repo, r1, r2 = self.make_two_commit_repo()
1846
fetch_spec = ['search', '%s %s' % (r1, r2), 'null:', '2']
1847
lines = '\n'.join(fetch_spec)
1848
request.execute('', repo._format.network_name())
1849
response = request.do_body(lines)
1850
self.assertEqual(('ok',), response.args)
1851
stream_bytes = ''.join(response.body_stream)
1852
self.assertStartsWith(stream_bytes, 'Bazaar pack format 1')
1854
def test_search_everything(self):
1855
"""A search of 'everything' returns a stream."""
1856
backing = self.get_transport()
1857
request = smart_repo.SmartServerRepositoryGetStream_1_19(backing)
1858
repo, r1, r2 = self.make_two_commit_repo()
1859
serialised_fetch_spec = 'everything'
1860
request.execute('', repo._format.network_name())
1861
response = request.do_body(serialised_fetch_spec)
1862
self.assertEqual(('ok',), response.args)
1863
stream_bytes = ''.join(response.body_stream)
1864
self.assertStartsWith(stream_bytes, 'Bazaar pack format 1')
849
SmartServerResponse(('nosuchrevision', 'missingrevision', ), ''),
850
request.execute('', 'missingrevision'))
1867
853
class TestSmartServerRequestHasRevision(tests.TestCaseWithMemoryTransport):
1885
871
r1 = tree.commit('a commit', rev_id=rev_id_utf8)
1887
873
self.assertTrue(tree.branch.repository.has_revision(rev_id_utf8))
1888
self.assertEqual(smart_req.SmartServerResponse(('yes', )),
874
self.assertEqual(SmartServerResponse(('yes', )),
1889
875
request.execute('', rev_id_utf8))
1892
class TestSmartServerRepositoryIterFilesBytes(tests.TestCaseWithTransport):
1894
def test_single(self):
1895
backing = self.get_transport()
1896
request = smart_repo.SmartServerRepositoryIterFilesBytes(backing)
1897
t = self.make_branch_and_tree('.')
1898
self.addCleanup(t.lock_write().unlock)
1899
self.build_tree_contents([("file", "somecontents")])
1900
t.add(["file"], ["thefileid"])
1901
t.commit(rev_id='somerev', message="add file")
1902
self.assertIs(None, request.execute(''))
1903
response = request.do_body("thefileid\0somerev\n")
1904
self.assertTrue(response.is_successful())
1905
self.assertEquals(response.args, ("ok", ))
1906
self.assertEquals("".join(response.body_stream),
1907
"ok\x000\n" + zlib.compress("somecontents"))
1909
def test_missing(self):
1910
backing = self.get_transport()
1911
request = smart_repo.SmartServerRepositoryIterFilesBytes(backing)
1912
t = self.make_branch_and_tree('.')
1913
self.addCleanup(t.lock_write().unlock)
1914
self.assertIs(None, request.execute(''))
1915
response = request.do_body("thefileid\0revision\n")
1916
self.assertTrue(response.is_successful())
1917
self.assertEquals(response.args, ("ok", ))
1918
self.assertEquals("".join(response.body_stream),
1919
"absent\x00thefileid\x00revision\x000\n")
1922
class TestSmartServerRequestHasSignatureForRevisionId(
1923
tests.TestCaseWithMemoryTransport):
1925
def test_missing_revision(self):
1926
"""For a missing revision, NoSuchRevision is returned."""
1927
backing = self.get_transport()
1928
request = smart_repo.SmartServerRequestHasSignatureForRevisionId(
1930
self.make_repository('.')
1932
smart_req.FailedSmartServerResponse(
1933
('nosuchrevision', 'revid'), None),
1934
request.execute('', 'revid'))
1936
def test_missing_signature(self):
1937
"""For a missing signature, ('no', ) is returned."""
1938
backing = self.get_transport()
1939
request = smart_repo.SmartServerRequestHasSignatureForRevisionId(
1941
tree = self.make_branch_and_memory_tree('.')
1944
r1 = tree.commit('a commit', rev_id='A')
1946
self.assertTrue(tree.branch.repository.has_revision('A'))
1947
self.assertEqual(smart_req.SmartServerResponse(('no', )),
1948
request.execute('', 'A'))
1950
def test_present_signature(self):
1951
"""For a present signature, ('yes', ) is returned."""
1952
backing = self.get_transport()
1953
request = smart_repo.SmartServerRequestHasSignatureForRevisionId(
1955
strategy = gpg.LoopbackGPGStrategy(None)
1956
tree = self.make_branch_and_memory_tree('.')
1959
r1 = tree.commit('a commit', rev_id='A')
1960
tree.branch.repository.start_write_group()
1961
tree.branch.repository.sign_revision('A', strategy)
1962
tree.branch.repository.commit_write_group()
1964
self.assertTrue(tree.branch.repository.has_revision('A'))
1965
self.assertEqual(smart_req.SmartServerResponse(('yes', )),
1966
request.execute('', 'A'))
1969
878
class TestSmartServerRepositoryGatherStats(tests.TestCaseWithMemoryTransport):
1971
880
def test_empty_revid(self):
1972
881
"""With an empty revid, we get only size an number and revisions"""
1973
882
backing = self.get_transport()
1974
request = smart_repo.SmartServerRepositoryGatherStats(backing)
883
request = smart.repository.SmartServerRepositoryGatherStats(backing)
1975
884
repository = self.make_repository('.')
1976
885
stats = repository.gather_stats()
1977
886
expected_body = 'revisions: 0\n'
1978
self.assertEqual(smart_req.SmartServerResponse(('ok', ), expected_body),
887
self.assertEqual(SmartServerResponse(('ok', ), expected_body),
1979
888
request.execute('', '', 'no'))
1981
890
def test_revid_with_committers(self):
1982
891
"""For a revid we get more infos."""
1983
892
backing = self.get_transport()
1984
893
rev_id_utf8 = u'\xc8abc'.encode('utf-8')
1985
request = smart_repo.SmartServerRepositoryGatherStats(backing)
894
request = smart.repository.SmartServerRepositoryGatherStats(backing)
1986
895
tree = self.make_branch_and_memory_tree('.')
1987
896
tree.lock_write()
2020
929
'firstrev: 123456.200 3600\n'
2021
930
'latestrev: 654321.400 0\n'
2022
931
'revisions: 2\n')
2023
self.assertEqual(smart_req.SmartServerResponse(('ok', ), expected_body),
932
self.assertEqual(SmartServerResponse(('ok', ), expected_body),
2024
933
request.execute('',
2025
934
rev_id_utf8, 'yes'))
2027
def test_unknown_revid(self):
2028
"""An unknown revision id causes a 'nosuchrevision' error."""
2029
backing = self.get_transport()
2030
request = smart_repo.SmartServerRepositoryGatherStats(backing)
2031
repository = self.make_repository('.')
2032
expected_body = 'revisions: 0\n'
2034
smart_req.FailedSmartServerResponse(
2035
('nosuchrevision', 'mia'), None),
2036
request.execute('', 'mia', 'yes'))
2039
937
class TestSmartServerRepositoryIsShared(tests.TestCaseWithMemoryTransport):
2041
939
def test_is_shared(self):
2042
940
"""For a shared repository, ('yes', ) is returned."""
2043
941
backing = self.get_transport()
2044
request = smart_repo.SmartServerRepositoryIsShared(backing)
942
request = smart.repository.SmartServerRepositoryIsShared(backing)
2045
943
self.make_repository('.', shared=True)
2046
self.assertEqual(smart_req.SmartServerResponse(('yes', )),
944
self.assertEqual(SmartServerResponse(('yes', )),
2047
945
request.execute('', ))
2049
947
def test_is_not_shared(self):
2050
948
"""For a shared repository, ('no', ) is returned."""
2051
949
backing = self.get_transport()
2052
request = smart_repo.SmartServerRepositoryIsShared(backing)
950
request = smart.repository.SmartServerRepositoryIsShared(backing)
2053
951
self.make_repository('.', shared=False)
2054
self.assertEqual(smart_req.SmartServerResponse(('no', )),
2055
request.execute('', ))
2058
class TestSmartServerRepositoryGetRevisionSignatureText(
2059
tests.TestCaseWithMemoryTransport):
2061
def test_get_signature(self):
2062
backing = self.get_transport()
2063
request = smart_repo.SmartServerRepositoryGetRevisionSignatureText(
2065
bb = self.make_branch_builder('.')
2066
bb.build_commit(rev_id='A')
2067
repo = bb.get_branch().repository
2068
strategy = gpg.LoopbackGPGStrategy(None)
2069
self.addCleanup(repo.lock_write().unlock)
2070
repo.start_write_group()
2071
repo.sign_revision('A', strategy)
2072
repo.commit_write_group()
2074
'-----BEGIN PSEUDO-SIGNED CONTENT-----\n' +
2075
Testament.from_revision(repo, 'A').as_short_text() +
2076
'-----END PSEUDO-SIGNED CONTENT-----\n')
2078
smart_req.SmartServerResponse(('ok', ), expected_body),
2079
request.execute('', 'A'))
2082
class TestSmartServerRepositoryMakeWorkingTrees(
2083
tests.TestCaseWithMemoryTransport):
2085
def test_make_working_trees(self):
2086
"""For a repository with working trees, ('yes', ) is returned."""
2087
backing = self.get_transport()
2088
request = smart_repo.SmartServerRepositoryMakeWorkingTrees(backing)
2089
r = self.make_repository('.')
2090
r.set_make_working_trees(True)
2091
self.assertEqual(smart_req.SmartServerResponse(('yes', )),
2092
request.execute('', ))
2094
def test_is_not_shared(self):
2095
"""For a repository with working trees, ('no', ) is returned."""
2096
backing = self.get_transport()
2097
request = smart_repo.SmartServerRepositoryMakeWorkingTrees(backing)
2098
r = self.make_repository('.')
2099
r.set_make_working_trees(False)
2100
self.assertEqual(smart_req.SmartServerResponse(('no', )),
952
self.assertEqual(SmartServerResponse(('no', )),
2101
953
request.execute('', ))
2104
956
class TestSmartServerRepositoryLockWrite(tests.TestCaseWithMemoryTransport):
959
tests.TestCaseWithMemoryTransport.setUp(self)
2106
961
def test_lock_write_on_unlocked_repo(self):
2107
962
backing = self.get_transport()
2108
request = smart_repo.SmartServerRepositoryLockWrite(backing)
963
request = smart.repository.SmartServerRepositoryLockWrite(backing)
2109
964
repository = self.make_repository('.', format='knit')
2110
965
response = request.execute('')
2111
966
nonce = repository.control_files._lock.peek().get('nonce')
2112
self.assertEqual(smart_req.SmartServerResponse(('ok', nonce)), response)
967
self.assertEqual(SmartServerResponse(('ok', nonce)), response)
2113
968
# The repository is now locked. Verify that with a new repository
2115
970
new_repo = repository.bzrdir.open_repository()
2116
971
self.assertRaises(errors.LockContention, new_repo.lock_write)
2118
request = smart_repo.SmartServerRepositoryUnlock(backing)
2119
response = request.execute('', nonce)
2121
973
def test_lock_write_on_locked_repo(self):
2122
974
backing = self.get_transport()
2123
request = smart_repo.SmartServerRepositoryLockWrite(backing)
975
request = smart.repository.SmartServerRepositoryLockWrite(backing)
2124
976
repository = self.make_repository('.', format='knit')
2125
repo_token = repository.lock_write().repository_token
977
repository.lock_write()
2126
978
repository.leave_lock_in_place()
2127
979
repository.unlock()
2128
980
response = request.execute('')
2129
981
self.assertEqual(
2130
smart_req.SmartServerResponse(('LockContention',)), response)
2132
repository.lock_write(repo_token)
2133
repository.dont_leave_lock_in_place()
982
SmartServerResponse(('LockContention',)), response)
2136
984
def test_lock_write_on_readonly_transport(self):
2137
985
backing = self.get_readonly_transport()
2138
request = smart_repo.SmartServerRepositoryLockWrite(backing)
986
request = smart.repository.SmartServerRepositoryLockWrite(backing)
2139
987
repository = self.make_repository('.', format='knit')
2140
988
response = request.execute('')
2141
989
self.assertFalse(response.is_successful())
2142
990
self.assertEqual('LockFailed', response.args[0])
2145
class TestInsertStreamBase(tests.TestCaseWithMemoryTransport):
2147
def make_empty_byte_stream(self, repo):
2148
byte_stream = smart_repo._stream_to_byte_stream([], repo._format)
2149
return ''.join(byte_stream)
2152
class TestSmartServerRepositoryInsertStream(TestInsertStreamBase):
2154
def test_insert_stream_empty(self):
2155
backing = self.get_transport()
2156
request = smart_repo.SmartServerRepositoryInsertStream(backing)
2157
repository = self.make_repository('.')
2158
response = request.execute('', '')
2159
self.assertEqual(None, response)
2160
response = request.do_chunk(self.make_empty_byte_stream(repository))
2161
self.assertEqual(None, response)
2162
response = request.do_end()
2163
self.assertEqual(smart_req.SmartServerResponse(('ok', )), response)
2166
class TestSmartServerRepositoryInsertStreamLocked(TestInsertStreamBase):
2168
def test_insert_stream_empty(self):
2169
backing = self.get_transport()
2170
request = smart_repo.SmartServerRepositoryInsertStreamLocked(
2172
repository = self.make_repository('.', format='knit')
2173
lock_token = repository.lock_write().repository_token
2174
response = request.execute('', '', lock_token)
2175
self.assertEqual(None, response)
2176
response = request.do_chunk(self.make_empty_byte_stream(repository))
2177
self.assertEqual(None, response)
2178
response = request.do_end()
2179
self.assertEqual(smart_req.SmartServerResponse(('ok', )), response)
2182
def test_insert_stream_with_wrong_lock_token(self):
2183
backing = self.get_transport()
2184
request = smart_repo.SmartServerRepositoryInsertStreamLocked(
2186
repository = self.make_repository('.', format='knit')
2187
lock_token = repository.lock_write().repository_token
2189
errors.TokenMismatch, request.execute, '', '', 'wrong-token')
2193
993
class TestSmartServerRepositoryUnlock(tests.TestCaseWithMemoryTransport):
996
tests.TestCaseWithMemoryTransport.setUp(self)
2195
998
def test_unlock_on_locked_repo(self):
2196
999
backing = self.get_transport()
2197
request = smart_repo.SmartServerRepositoryUnlock(backing)
1000
request = smart.repository.SmartServerRepositoryUnlock(backing)
2198
1001
repository = self.make_repository('.', format='knit')
2199
token = repository.lock_write().repository_token
1002
token = repository.lock_write()
2200
1003
repository.leave_lock_in_place()
2201
1004
repository.unlock()
2202
1005
response = request.execute('', token)
2203
1006
self.assertEqual(
2204
smart_req.SmartServerResponse(('ok',)), response)
1007
SmartServerResponse(('ok',)), response)
2205
1008
# The repository is now unlocked. Verify that with a new repository
2207
1010
new_repo = repository.bzrdir.open_repository()
2211
1014
def test_unlock_on_unlocked_repo(self):
2212
1015
backing = self.get_transport()
2213
request = smart_repo.SmartServerRepositoryUnlock(backing)
1016
request = smart.repository.SmartServerRepositoryUnlock(backing)
2214
1017
repository = self.make_repository('.', format='knit')
2215
1018
response = request.execute('', 'some token')
2216
1019
self.assertEqual(
2217
smart_req.SmartServerResponse(('TokenMismatch',)), response)
2220
class TestSmartServerRepositoryGetPhysicalLockStatus(
2221
tests.TestCaseWithTransport):
2223
def test_with_write_lock(self):
2224
backing = self.get_transport()
2225
repo = self.make_repository('.')
2226
self.addCleanup(repo.lock_write().unlock)
2227
# lock_write() doesn't necessarily actually take a physical
2229
if repo.get_physical_lock_status():
2233
request_class = smart_repo.SmartServerRepositoryGetPhysicalLockStatus
2234
request = request_class(backing)
2235
self.assertEqual(smart_req.SuccessfulSmartServerResponse((expected,)),
2236
request.execute('', ))
2238
def test_without_write_lock(self):
2239
backing = self.get_transport()
2240
repo = self.make_repository('.')
2241
self.assertEquals(False, repo.get_physical_lock_status())
2242
request_class = smart_repo.SmartServerRepositoryGetPhysicalLockStatus
2243
request = request_class(backing)
2244
self.assertEqual(smart_req.SuccessfulSmartServerResponse(('no',)),
2245
request.execute('', ))
2248
class TestSmartServerRepositoryReconcile(tests.TestCaseWithTransport):
2250
def test_reconcile(self):
2251
backing = self.get_transport()
2252
repo = self.make_repository('.')
2253
token = repo.lock_write().repository_token
2254
self.addCleanup(repo.unlock)
2255
request_class = smart_repo.SmartServerRepositoryReconcile
2256
request = request_class(backing)
2257
self.assertEqual(smart_req.SuccessfulSmartServerResponse(
2259
'garbage_inventories: 0\n'
2260
'inconsistent_parents: 0\n'),
2261
request.execute('', token))
1020
SmartServerResponse(('TokenMismatch',)), response)
2264
1023
class TestSmartServerIsReadonly(tests.TestCaseWithMemoryTransport):
2266
1025
def test_is_readonly_no(self):
2267
1026
backing = self.get_transport()
2268
request = smart_req.SmartServerIsReadonly(backing)
1027
request = smart.request.SmartServerIsReadonly(backing)
2269
1028
response = request.execute()
2270
1029
self.assertEqual(
2271
smart_req.SmartServerResponse(('no',)), response)
1030
SmartServerResponse(('no',)), response)
2273
1032
def test_is_readonly_yes(self):
2274
1033
backing = self.get_readonly_transport()
2275
request = smart_req.SmartServerIsReadonly(backing)
1034
request = smart.request.SmartServerIsReadonly(backing)
2276
1035
response = request.execute()
2277
1036
self.assertEqual(
2278
smart_req.SmartServerResponse(('yes',)), response)
2281
class TestSmartServerRepositorySetMakeWorkingTrees(
2282
tests.TestCaseWithMemoryTransport):
2284
def test_set_false(self):
2285
backing = self.get_transport()
2286
repo = self.make_repository('.', shared=True)
2287
repo.set_make_working_trees(True)
2288
request_class = smart_repo.SmartServerRepositorySetMakeWorkingTrees
2289
request = request_class(backing)
2290
self.assertEqual(smart_req.SuccessfulSmartServerResponse(('ok',)),
2291
request.execute('', 'False'))
2292
repo = repo.bzrdir.open_repository()
2293
self.assertFalse(repo.make_working_trees())
2295
def test_set_true(self):
2296
backing = self.get_transport()
2297
repo = self.make_repository('.', shared=True)
2298
repo.set_make_working_trees(False)
2299
request_class = smart_repo.SmartServerRepositorySetMakeWorkingTrees
2300
request = request_class(backing)
2301
self.assertEqual(smart_req.SuccessfulSmartServerResponse(('ok',)),
2302
request.execute('', 'True'))
2303
repo = repo.bzrdir.open_repository()
2304
self.assertTrue(repo.make_working_trees())
2307
class TestSmartServerRepositoryGetSerializerFormat(
2308
tests.TestCaseWithMemoryTransport):
2310
def test_get_serializer_format(self):
2311
backing = self.get_transport()
2312
repo = self.make_repository('.', format='2a')
2313
request_class = smart_repo.SmartServerRepositoryGetSerializerFormat
2314
request = request_class(backing)
2316
smart_req.SuccessfulSmartServerResponse(('ok', '10')),
2317
request.execute(''))
2320
class TestSmartServerRepositoryWriteGroup(
2321
tests.TestCaseWithMemoryTransport):
2323
def test_start_write_group(self):
2324
backing = self.get_transport()
2325
repo = self.make_repository('.')
2326
lock_token = repo.lock_write().repository_token
2327
self.addCleanup(repo.unlock)
2328
request_class = smart_repo.SmartServerRepositoryStartWriteGroup
2329
request = request_class(backing)
2330
self.assertEqual(smart_req.SuccessfulSmartServerResponse(('ok', [])),
2331
request.execute('', lock_token))
2333
def test_start_write_group_unsuspendable(self):
2334
backing = self.get_transport()
2335
repo = self.make_repository('.', format='knit')
2336
lock_token = repo.lock_write().repository_token
2337
self.addCleanup(repo.unlock)
2338
request_class = smart_repo.SmartServerRepositoryStartWriteGroup
2339
request = request_class(backing)
2341
smart_req.FailedSmartServerResponse(('UnsuspendableWriteGroup',)),
2342
request.execute('', lock_token))
2344
def test_commit_write_group(self):
2345
backing = self.get_transport()
2346
repo = self.make_repository('.')
2347
lock_token = repo.lock_write().repository_token
2348
self.addCleanup(repo.unlock)
2349
repo.start_write_group()
2350
tokens = repo.suspend_write_group()
2351
request_class = smart_repo.SmartServerRepositoryCommitWriteGroup
2352
request = request_class(backing)
2353
self.assertEqual(smart_req.SuccessfulSmartServerResponse(('ok',)),
2354
request.execute('', lock_token, tokens))
2356
def test_abort_write_group(self):
2357
backing = self.get_transport()
2358
repo = self.make_repository('.')
2359
lock_token = repo.lock_write().repository_token
2360
repo.start_write_group()
2361
tokens = repo.suspend_write_group()
2362
self.addCleanup(repo.unlock)
2363
request_class = smart_repo.SmartServerRepositoryAbortWriteGroup
2364
request = request_class(backing)
2365
self.assertEqual(smart_req.SuccessfulSmartServerResponse(('ok',)),
2366
request.execute('', lock_token, tokens))
2368
def test_check_write_group(self):
2369
backing = self.get_transport()
2370
repo = self.make_repository('.')
2371
lock_token = repo.lock_write().repository_token
2372
repo.start_write_group()
2373
tokens = repo.suspend_write_group()
2374
self.addCleanup(repo.unlock)
2375
request_class = smart_repo.SmartServerRepositoryCheckWriteGroup
2376
request = request_class(backing)
2377
self.assertEqual(smart_req.SuccessfulSmartServerResponse(('ok',)),
2378
request.execute('', lock_token, tokens))
2380
def test_check_write_group_invalid(self):
2381
backing = self.get_transport()
2382
repo = self.make_repository('.')
2383
lock_token = repo.lock_write().repository_token
2384
self.addCleanup(repo.unlock)
2385
request_class = smart_repo.SmartServerRepositoryCheckWriteGroup
2386
request = request_class(backing)
2387
self.assertEqual(smart_req.FailedSmartServerResponse(
2388
('UnresumableWriteGroup', ['random'],
2389
'Malformed write group token')),
2390
request.execute('', lock_token, ["random"]))
1037
SmartServerResponse(('yes',)), response)
2393
1040
class TestSmartServerPackRepositoryAutopack(tests.TestCaseWithTransport):
2461
1091
"""All registered request_handlers can be found."""
2462
1092
# If there's a typo in a register_lazy call, this loop will fail with
2463
1093
# an AttributeError.
2464
for key in smart_req.request_handlers.keys():
2466
item = smart_req.request_handlers.get(key)
2467
except AttributeError, e:
2468
raise AttributeError('failed to get %s: %s' % (key, e))
2470
def assertHandlerEqual(self, verb, handler):
2471
self.assertEqual(smart_req.request_handlers.get(verb), handler)
1094
for key, item in smart.request.request_handlers.iteritems():
2473
1097
def test_registered_methods(self):
2474
1098
"""Test that known methods are registered to the correct object."""
2475
self.assertHandlerEqual('Branch.break_lock',
2476
smart_branch.SmartServerBranchBreakLock)
2477
self.assertHandlerEqual('Branch.get_config_file',
2478
smart_branch.SmartServerBranchGetConfigFile)
2479
self.assertHandlerEqual('Branch.put_config_file',
2480
smart_branch.SmartServerBranchPutConfigFile)
2481
self.assertHandlerEqual('Branch.get_parent',
2482
smart_branch.SmartServerBranchGetParent)
2483
self.assertHandlerEqual('Branch.get_physical_lock_status',
2484
smart_branch.SmartServerBranchRequestGetPhysicalLockStatus)
2485
self.assertHandlerEqual('Branch.get_tags_bytes',
2486
smart_branch.SmartServerBranchGetTagsBytes)
2487
self.assertHandlerEqual('Branch.lock_write',
2488
smart_branch.SmartServerBranchRequestLockWrite)
2489
self.assertHandlerEqual('Branch.last_revision_info',
2490
smart_branch.SmartServerBranchRequestLastRevisionInfo)
2491
self.assertHandlerEqual('Branch.revision_history',
2492
smart_branch.SmartServerRequestRevisionHistory)
2493
self.assertHandlerEqual('Branch.revision_id_to_revno',
2494
smart_branch.SmartServerBranchRequestRevisionIdToRevno)
2495
self.assertHandlerEqual('Branch.set_config_option',
2496
smart_branch.SmartServerBranchRequestSetConfigOption)
2497
self.assertHandlerEqual('Branch.set_last_revision',
2498
smart_branch.SmartServerBranchRequestSetLastRevision)
2499
self.assertHandlerEqual('Branch.set_last_revision_info',
2500
smart_branch.SmartServerBranchRequestSetLastRevisionInfo)
2501
self.assertHandlerEqual('Branch.set_last_revision_ex',
2502
smart_branch.SmartServerBranchRequestSetLastRevisionEx)
2503
self.assertHandlerEqual('Branch.set_parent_location',
2504
smart_branch.SmartServerBranchRequestSetParentLocation)
2505
self.assertHandlerEqual('Branch.unlock',
2506
smart_branch.SmartServerBranchRequestUnlock)
2507
self.assertHandlerEqual('BzrDir.destroy_branch',
2508
smart_dir.SmartServerBzrDirRequestDestroyBranch)
2509
self.assertHandlerEqual('BzrDir.find_repository',
2510
smart_dir.SmartServerRequestFindRepositoryV1)
2511
self.assertHandlerEqual('BzrDir.find_repositoryV2',
2512
smart_dir.SmartServerRequestFindRepositoryV2)
2513
self.assertHandlerEqual('BzrDirFormat.initialize',
2514
smart_dir.SmartServerRequestInitializeBzrDir)
2515
self.assertHandlerEqual('BzrDirFormat.initialize_ex_1.16',
2516
smart_dir.SmartServerRequestBzrDirInitializeEx)
2517
self.assertHandlerEqual('BzrDir.checkout_metadir',
2518
smart_dir.SmartServerBzrDirRequestCheckoutMetaDir)
2519
self.assertHandlerEqual('BzrDir.cloning_metadir',
2520
smart_dir.SmartServerBzrDirRequestCloningMetaDir)
2521
self.assertHandlerEqual('BzrDir.get_branches',
2522
smart_dir.SmartServerBzrDirRequestGetBranches)
2523
self.assertHandlerEqual('BzrDir.get_config_file',
2524
smart_dir.SmartServerBzrDirRequestConfigFile)
2525
self.assertHandlerEqual('BzrDir.open_branch',
2526
smart_dir.SmartServerRequestOpenBranch)
2527
self.assertHandlerEqual('BzrDir.open_branchV2',
2528
smart_dir.SmartServerRequestOpenBranchV2)
2529
self.assertHandlerEqual('BzrDir.open_branchV3',
2530
smart_dir.SmartServerRequestOpenBranchV3)
2531
self.assertHandlerEqual('PackRepository.autopack',
2532
smart_packrepo.SmartServerPackRepositoryAutopack)
2533
self.assertHandlerEqual('Repository.add_signature_text',
2534
smart_repo.SmartServerRepositoryAddSignatureText)
2535
self.assertHandlerEqual('Repository.all_revision_ids',
2536
smart_repo.SmartServerRepositoryAllRevisionIds)
2537
self.assertHandlerEqual('Repository.break_lock',
2538
smart_repo.SmartServerRepositoryBreakLock)
2539
self.assertHandlerEqual('Repository.gather_stats',
2540
smart_repo.SmartServerRepositoryGatherStats)
2541
self.assertHandlerEqual('Repository.get_parent_map',
2542
smart_repo.SmartServerRepositoryGetParentMap)
2543
self.assertHandlerEqual('Repository.get_physical_lock_status',
2544
smart_repo.SmartServerRepositoryGetPhysicalLockStatus)
2545
self.assertHandlerEqual('Repository.get_rev_id_for_revno',
2546
smart_repo.SmartServerRepositoryGetRevIdForRevno)
2547
self.assertHandlerEqual('Repository.get_revision_graph',
2548
smart_repo.SmartServerRepositoryGetRevisionGraph)
2549
self.assertHandlerEqual('Repository.get_revision_signature_text',
2550
smart_repo.SmartServerRepositoryGetRevisionSignatureText)
2551
self.assertHandlerEqual('Repository.get_stream',
2552
smart_repo.SmartServerRepositoryGetStream)
2553
self.assertHandlerEqual('Repository.get_stream_1.19',
2554
smart_repo.SmartServerRepositoryGetStream_1_19)
2555
self.assertHandlerEqual('Repository.iter_revisions',
2556
smart_repo.SmartServerRepositoryIterRevisions)
2557
self.assertHandlerEqual('Repository.has_revision',
2558
smart_repo.SmartServerRequestHasRevision)
2559
self.assertHandlerEqual('Repository.insert_stream',
2560
smart_repo.SmartServerRepositoryInsertStream)
2561
self.assertHandlerEqual('Repository.insert_stream_locked',
2562
smart_repo.SmartServerRepositoryInsertStreamLocked)
2563
self.assertHandlerEqual('Repository.is_shared',
2564
smart_repo.SmartServerRepositoryIsShared)
2565
self.assertHandlerEqual('Repository.iter_files_bytes',
2566
smart_repo.SmartServerRepositoryIterFilesBytes)
2567
self.assertHandlerEqual('Repository.lock_write',
2568
smart_repo.SmartServerRepositoryLockWrite)
2569
self.assertHandlerEqual('Repository.make_working_trees',
2570
smart_repo.SmartServerRepositoryMakeWorkingTrees)
2571
self.assertHandlerEqual('Repository.pack',
2572
smart_repo.SmartServerRepositoryPack)
2573
self.assertHandlerEqual('Repository.reconcile',
2574
smart_repo.SmartServerRepositoryReconcile)
2575
self.assertHandlerEqual('Repository.tarball',
2576
smart_repo.SmartServerRepositoryTarball)
2577
self.assertHandlerEqual('Repository.unlock',
2578
smart_repo.SmartServerRepositoryUnlock)
2579
self.assertHandlerEqual('Repository.start_write_group',
2580
smart_repo.SmartServerRepositoryStartWriteGroup)
2581
self.assertHandlerEqual('Repository.check_write_group',
2582
smart_repo.SmartServerRepositoryCheckWriteGroup)
2583
self.assertHandlerEqual('Repository.commit_write_group',
2584
smart_repo.SmartServerRepositoryCommitWriteGroup)
2585
self.assertHandlerEqual('Repository.abort_write_group',
2586
smart_repo.SmartServerRepositoryAbortWriteGroup)
2587
self.assertHandlerEqual('VersionedFileRepository.get_serializer_format',
2588
smart_repo.SmartServerRepositoryGetSerializerFormat)
2589
self.assertHandlerEqual('VersionedFileRepository.get_inventories',
2590
smart_repo.SmartServerRepositoryGetInventories)
2591
self.assertHandlerEqual('Transport.is_readonly',
2592
smart_req.SmartServerIsReadonly)
2595
class SmartTCPServerHookTests(tests.TestCaseWithMemoryTransport):
2596
"""Tests for SmartTCPServer hooks."""
2599
super(SmartTCPServerHookTests, self).setUp()
2600
self.server = server.SmartTCPServer(self.get_transport())
2602
def test_run_server_started_hooks(self):
2603
"""Test the server started hooks get fired properly."""
2605
server.SmartTCPServer.hooks.install_named_hook('server_started',
2606
lambda backing_urls, url: started_calls.append((backing_urls, url)),
2608
started_ex_calls = []
2609
server.SmartTCPServer.hooks.install_named_hook('server_started_ex',
2610
lambda backing_urls, url: started_ex_calls.append((backing_urls, url)),
2612
self.server._sockname = ('example.com', 42)
2613
self.server.run_server_started_hooks()
2614
self.assertEquals(started_calls,
2615
[([self.get_transport().base], 'bzr://example.com:42/')])
2616
self.assertEquals(started_ex_calls,
2617
[([self.get_transport().base], self.server)])
2619
def test_run_server_started_hooks_ipv6(self):
2620
"""Test that socknames can contain 4-tuples."""
2621
self.server._sockname = ('::', 42, 0, 0)
2623
server.SmartTCPServer.hooks.install_named_hook('server_started',
2624
lambda backing_urls, url: started_calls.append((backing_urls, url)),
2626
self.server.run_server_started_hooks()
2627
self.assertEquals(started_calls,
2628
[([self.get_transport().base], 'bzr://:::42/')])
2630
def test_run_server_stopped_hooks(self):
2631
"""Test the server stopped hooks."""
2632
self.server._sockname = ('example.com', 42)
2634
server.SmartTCPServer.hooks.install_named_hook('server_stopped',
2635
lambda backing_urls, url: stopped_calls.append((backing_urls, url)),
2637
self.server.run_server_stopped_hooks()
2638
self.assertEquals(stopped_calls,
2639
[([self.get_transport().base], 'bzr://example.com:42/')])
2642
class TestSmartServerRepositoryPack(tests.TestCaseWithMemoryTransport):
2644
def test_pack(self):
2645
backing = self.get_transport()
2646
request = smart_repo.SmartServerRepositoryPack(backing)
2647
tree = self.make_branch_and_memory_tree('.')
2648
repo_token = tree.branch.repository.lock_write().repository_token
2650
self.assertIs(None, request.execute('', repo_token, False))
2653
smart_req.SuccessfulSmartServerResponse(('ok', ), ),
2654
request.do_body(''))
2657
class TestSmartServerRepositoryGetInventories(tests.TestCaseWithTransport):
2659
def _get_serialized_inventory_delta(self, repository, base_revid, revid):
2660
base_inv = repository.revision_tree(base_revid).root_inventory
2661
inv = repository.revision_tree(revid).root_inventory
2662
inv_delta = inv._make_delta(base_inv)
2663
serializer = inventory_delta.InventoryDeltaSerializer(True, False)
2664
return "".join(serializer.delta_to_lines(base_revid, revid, inv_delta))
2666
def test_single(self):
2667
backing = self.get_transport()
2668
request = smart_repo.SmartServerRepositoryGetInventories(backing)
2669
t = self.make_branch_and_tree('.', format='2a')
2670
self.addCleanup(t.lock_write().unlock)
2671
self.build_tree_contents([("file", "somecontents")])
2672
t.add(["file"], ["thefileid"])
2673
t.commit(rev_id='somerev', message="add file")
2674
self.assertIs(None, request.execute('', 'unordered'))
2675
response = request.do_body("somerev\n")
2676
self.assertTrue(response.is_successful())
2677
self.assertEquals(response.args, ("ok", ))
2678
stream = [('inventory-deltas', [
2679
versionedfile.FulltextContentFactory('somerev', None, None,
2680
self._get_serialized_inventory_delta(
2681
t.branch.repository, 'null:', 'somerev'))])]
2682
fmt = controldir.format_registry.get('2a')().repository_format
2684
"".join(response.body_stream),
2685
"".join(smart_repo._stream_to_byte_stream(stream, fmt)))
2687
def test_empty(self):
2688
backing = self.get_transport()
2689
request = smart_repo.SmartServerRepositoryGetInventories(backing)
2690
t = self.make_branch_and_tree('.', format='2a')
2691
self.addCleanup(t.lock_write().unlock)
2692
self.build_tree_contents([("file", "somecontents")])
2693
t.add(["file"], ["thefileid"])
2694
t.commit(rev_id='somerev', message="add file")
2695
self.assertIs(None, request.execute('', 'unordered'))
2696
response = request.do_body("")
2697
self.assertTrue(response.is_successful())
2698
self.assertEquals(response.args, ("ok", ))
2699
self.assertEquals("".join(response.body_stream),
2700
"Bazaar pack format 1 (introduced in 0.18)\nB54\n\nBazaar repository format 2a (needs bzr 1.16 or later)\nE")
1100
smart.request.request_handlers.get('Branch.get_config_file'),
1101
smart.branch.SmartServerBranchGetConfigFile)
1103
smart.request.request_handlers.get('Branch.lock_write'),
1104
smart.branch.SmartServerBranchRequestLockWrite)
1106
smart.request.request_handlers.get('Branch.last_revision_info'),
1107
smart.branch.SmartServerBranchRequestLastRevisionInfo)
1109
smart.request.request_handlers.get('Branch.revision_history'),
1110
smart.branch.SmartServerRequestRevisionHistory)
1112
smart.request.request_handlers.get('Branch.set_last_revision'),
1113
smart.branch.SmartServerBranchRequestSetLastRevision)
1115
smart.request.request_handlers.get('Branch.set_last_revision_info'),
1116
smart.branch.SmartServerBranchRequestSetLastRevisionInfo)
1118
smart.request.request_handlers.get('Branch.unlock'),
1119
smart.branch.SmartServerBranchRequestUnlock)
1121
smart.request.request_handlers.get('BzrDir.find_repository'),
1122
smart.bzrdir.SmartServerRequestFindRepositoryV1)
1124
smart.request.request_handlers.get('BzrDir.find_repositoryV2'),
1125
smart.bzrdir.SmartServerRequestFindRepositoryV2)
1127
smart.request.request_handlers.get('BzrDirFormat.initialize'),
1128
smart.bzrdir.SmartServerRequestInitializeBzrDir)
1130
smart.request.request_handlers.get('BzrDir.open_branch'),
1131
smart.bzrdir.SmartServerRequestOpenBranch)
1133
smart.request.request_handlers.get('PackRepository.autopack'),
1134
smart.packrepository.SmartServerPackRepositoryAutopack)
1136
smart.request.request_handlers.get('Repository.gather_stats'),
1137
smart.repository.SmartServerRepositoryGatherStats)
1139
smart.request.request_handlers.get('Repository.get_parent_map'),
1140
smart.repository.SmartServerRepositoryGetParentMap)
1142
smart.request.request_handlers.get(
1143
'Repository.get_revision_graph'),
1144
smart.repository.SmartServerRepositoryGetRevisionGraph)
1146
smart.request.request_handlers.get('Repository.has_revision'),
1147
smart.repository.SmartServerRequestHasRevision)
1149
smart.request.request_handlers.get('Repository.is_shared'),
1150
smart.repository.SmartServerRepositoryIsShared)
1152
smart.request.request_handlers.get('Repository.lock_write'),
1153
smart.repository.SmartServerRepositoryLockWrite)
1155
smart.request.request_handlers.get('Repository.tarball'),
1156
smart.repository.SmartServerRepositoryTarball)
1158
smart.request.request_handlers.get('Repository.unlock'),
1159
smart.repository.SmartServerRepositoryUnlock)
1161
smart.request.request_handlers.get('Transport.is_readonly'),
1162
smart.request.SmartServerIsReadonly)