28
from StringIO import StringIO
28
from cStringIO import StringIO
32
from bzrlib import bzrdir, errors, pack, smart, tests
39
from bzrlib.branch import BranchReferenceFormat
40
import bzrlib.smart.branch
41
import bzrlib.smart.bzrdir
42
import bzrlib.smart.repository
33
43
from bzrlib.smart.request import (
34
44
FailedSmartServerResponse,
35
46
SmartServerResponse,
36
47
SuccessfulSmartServerResponse,
38
import bzrlib.smart.bzrdir
39
import bzrlib.smart.branch
40
import bzrlib.smart.repository
41
49
from bzrlib.tests import (
44
52
TestScenarioApplier,
54
from bzrlib.transport import chroot, get_transport
46
55
from bzrlib.util import bencode
98
125
self.assertNotEqual(None,
99
126
SmartServerResponse(('ok', )))
102
class TestSmartServerRequestFindRepository(tests.TestCaseWithTransport):
128
def test__str__(self):
129
"""SmartServerResponses can be stringified."""
131
"<SmartServerResponse status=OK args=('args',) body='body'>",
132
str(SuccessfulSmartServerResponse(('args',), 'body')))
134
"<SmartServerResponse status=ERR args=('args',) body='body'>",
135
str(FailedSmartServerResponse(('args',), 'body')))
138
class TestSmartServerRequest(tests.TestCaseWithMemoryTransport):
140
def test_translate_client_path(self):
141
transport = self.get_transport()
142
request = SmartServerRequest(transport, 'foo/')
143
self.assertEqual('./', request.translate_client_path('foo/'))
145
errors.InvalidURLJoin, request.translate_client_path, 'foo/..')
147
errors.PathNotChild, request.translate_client_path, '/')
149
errors.PathNotChild, request.translate_client_path, 'bar/')
150
self.assertEqual('./baz', request.translate_client_path('foo/baz'))
152
def test_transport_from_client_path(self):
153
transport = self.get_transport()
154
request = SmartServerRequest(transport, 'foo/')
157
request.transport_from_client_path('foo/').base)
160
class TestSmartServerRequestFindRepository(tests.TestCaseWithMemoryTransport):
103
161
"""Tests for BzrDir.find_repository."""
105
163
def test_no_repository(self):
117
175
backing = self.get_transport()
118
176
request = self._request_class(backing)
119
177
result = self._make_repository_and_result()
120
self.assertEqual(result, request.execute(backing.local_abspath('')))
178
self.assertEqual(result, request.execute(''))
121
179
self.make_bzrdir('subdir')
122
180
self.assertEqual(SmartServerResponse(('norepository', )),
123
request.execute(backing.local_abspath('subdir')))
181
request.execute('subdir'))
125
183
def _make_repository_and_result(self, shared=False, format=None):
126
184
"""Convenience function to setup a repository.
150
208
backing = self.get_transport()
151
209
request = self._request_class(backing)
152
210
result = self._make_repository_and_result(shared=True)
153
self.assertEqual(result, request.execute(backing.local_abspath('')))
211
self.assertEqual(result, request.execute(''))
154
212
self.make_bzrdir('subdir')
155
213
result2 = SmartServerResponse(result.args[0:1] + ('..', ) + result.args[2:])
156
214
self.assertEqual(result2,
157
request.execute(backing.local_abspath('subdir')))
215
request.execute('subdir'))
158
216
self.make_bzrdir('subdir/deeper')
159
217
result3 = SmartServerResponse(result.args[0:1] + ('../..', ) + result.args[2:])
160
218
self.assertEqual(result3,
161
request.execute(backing.local_abspath('subdir/deeper')))
219
request.execute('subdir/deeper'))
163
221
def test_rich_root_and_subtree_encoding(self):
164
222
"""Test for the format attributes for rich root and subtree support."""
177
235
result = self._make_repository_and_result(format='dirstate-with-subtree')
178
236
# check the test will be valid
179
237
self.assertEqual('no', result.args[4])
180
self.assertEqual(result, request.execute(backing.local_abspath('')))
183
class TestSmartServerRequestInitializeBzrDir(tests.TestCaseWithTransport):
238
self.assertEqual(result, request.execute(''))
241
class TestSmartServerRequestInitializeBzrDir(tests.TestCaseWithMemoryTransport):
185
243
def test_empty_dir(self):
186
244
"""Initializing an empty dir should succeed and do it."""
187
245
backing = self.get_transport()
188
246
request = smart.bzrdir.SmartServerRequestInitializeBzrDir(backing)
189
247
self.assertEqual(SmartServerResponse(('ok', )),
190
request.execute(backing.local_abspath('.')))
191
249
made_dir = bzrdir.BzrDir.open_from_transport(backing)
192
250
# no branch, tree or repository is expected with the current
193
251
# default formart.
235
293
request = smart.bzrdir.SmartServerRequestOpenBranch(backing)
236
294
branch = self.make_branch('branch')
237
295
checkout = branch.create_checkout('reference',lightweight=True)
238
# TODO: once we have an API to probe for references of any sort, we
240
reference_url = backing.abspath('branch') + '/'
296
reference_url = BranchReferenceFormat().get_reference(checkout.bzrdir)
241
297
self.assertFileEqual(reference_url, 'reference/.bzr/branch/location')
242
298
self.assertEqual(SmartServerResponse(('ok', reference_url)),
243
request.execute(backing.local_abspath('reference')))
246
class TestSmartServerRequestRevisionHistory(tests.TestCaseWithTransport):
299
request.execute('reference'))
302
class TestSmartServerRequestRevisionHistory(tests.TestCaseWithMemoryTransport):
248
304
def test_empty(self):
249
305
"""For an empty branch, the body is empty."""
413
469
self.assertEqual(
414
470
SmartServerResponse(('ok',)),
416
backing.local_abspath(''), branch_token, repo_token,
472
'', branch_token, repo_token,
418
474
self.assertEqual([rev_id_utf8], tree.branch.revision_history())
420
476
tree.branch.unlock()
423
class TestSmartServerBranchRequestLockWrite(tests.TestCaseWithTransport):
479
class TestSmartServerBranchRequestSetLastRevisionInfo(tests.TestCaseWithTransport):
481
def lock_branch(self, branch):
482
branch_token = branch.lock_write()
483
repo_token = branch.repository.lock_write()
484
branch.repository.unlock()
485
self.addCleanup(branch.unlock)
486
return branch_token, repo_token
488
def make_locked_branch(self, format=None):
489
branch = self.make_branch('.', format=format)
490
branch_token, repo_token = self.lock_branch(branch)
491
return branch, branch_token, repo_token
493
def test_empty(self):
494
"""An empty branch can have its last revision set to 'null:'."""
495
b, branch_token, repo_token = self.make_locked_branch()
496
backing = self.get_transport()
497
request = smart.branch.SmartServerBranchRequestSetLastRevisionInfo(
499
response = request.execute('', branch_token, repo_token, '0', 'null:')
500
self.assertEqual(SmartServerResponse(('ok',)), response)
502
def assertBranchLastRevisionInfo(self, expected_info, branch_relpath):
503
branch = bzrdir.BzrDir.open(branch_relpath).open_branch()
504
self.assertEqual(expected_info, branch.last_revision_info())
506
def test_branch_revision_info_is_updated(self):
507
"""This method really does update the branch last revision info."""
508
tree = self.make_branch_and_memory_tree('.')
511
tree.commit('First commit', rev_id='revision-1')
512
tree.commit('Second commit', rev_id='revision-2')
516
branch_token, repo_token = self.lock_branch(branch)
517
backing = self.get_transport()
518
request = smart.branch.SmartServerBranchRequestSetLastRevisionInfo(
520
self.assertBranchLastRevisionInfo((2, 'revision-2'), '.')
521
response = request.execute(
522
'', branch_token, repo_token, '1', 'revision-1')
523
self.assertEqual(SmartServerResponse(('ok',)), response)
524
self.assertBranchLastRevisionInfo((1, 'revision-1'), '.')
526
def test_not_present_revid(self):
527
"""Some branch formats will check that the revision is present in the
528
repository. When that check fails, a NoSuchRevision error is returned
531
# Make a knit format branch, because that format checks the values
532
# given to set_last_revision_info.
533
b, branch_token, repo_token = self.make_locked_branch(format='knit')
534
backing = self.get_transport()
535
request = smart.branch.SmartServerBranchRequestSetLastRevisionInfo(
537
response = request.execute(
538
'', branch_token, repo_token, '1', 'not-present')
540
SmartServerResponse(('NoSuchRevision', 'not-present')), response)
543
class TestSmartServerBranchRequestLockWrite(tests.TestCaseWithMemoryTransport):
426
tests.TestCaseWithTransport.setUp(self)
546
tests.TestCaseWithMemoryTransport.setUp(self)
428
548
def test_lock_write_on_unlocked_branch(self):
429
549
backing = self.get_transport()
430
550
request = smart.branch.SmartServerBranchRequestLockWrite(backing)
431
551
branch = self.make_branch('.', format='knit')
432
552
repository = branch.repository
433
response = request.execute(backing.local_abspath(''))
553
response = request.execute('')
434
554
branch_nonce = branch.control_files._lock.peek().get('nonce')
435
555
repository_nonce = repository.control_files._lock.peek().get('nonce')
436
556
self.assertEqual(
497
617
backing = self.get_readonly_transport()
498
618
request = smart.branch.SmartServerBranchRequestLockWrite(backing)
499
619
branch = self.make_branch('.')
500
response = request.execute('')
620
root = self.get_transport().clone('/')
621
path = urlutils.relative_url(root.base, self.get_transport().base)
622
response = request.execute(path)
501
623
error_name, lock_str, why_str = response.args
502
624
self.assertFalse(response.is_successful())
503
625
self.assertEqual('LockFailed', error_name)
506
class TestSmartServerBranchRequestUnlock(tests.TestCaseWithTransport):
628
class TestSmartServerBranchRequestUnlock(tests.TestCaseWithMemoryTransport):
509
tests.TestCaseWithTransport.setUp(self)
631
tests.TestCaseWithMemoryTransport.setUp(self)
511
633
def test_unlock_on_locked_branch_and_repo(self):
512
634
backing = self.get_transport()
743
865
request = smart.repository.SmartServerRepositoryIsShared(backing)
744
866
self.make_repository('.', shared=False)
745
867
self.assertEqual(SmartServerResponse(('no', )),
746
request.execute(backing.local_abspath(''), ))
749
class TestSmartServerRepositoryLockWrite(tests.TestCaseWithTransport):
868
request.execute('', ))
871
class TestSmartServerRepositoryLockWrite(tests.TestCaseWithMemoryTransport):
752
tests.TestCaseWithTransport.setUp(self)
874
tests.TestCaseWithMemoryTransport.setUp(self)
754
876
def test_lock_write_on_unlocked_repo(self):
755
877
backing = self.get_transport()
756
878
request = smart.repository.SmartServerRepositoryLockWrite(backing)
757
879
repository = self.make_repository('.', format='knit')
758
response = request.execute(backing.local_abspath(''))
880
response = request.execute('')
759
881
nonce = repository.control_files._lock.peek().get('nonce')
760
882
self.assertEqual(SmartServerResponse(('ok', nonce)), response)
761
883
# The repository is now locked. Verify that with a new repository