27
27
from cStringIO import StringIO
29
29
from bzrlib import (
45
45
from bzrlib.branch import Branch
46
from bzrlib.bzrdir import (
46
from bzrlib.bzrdir import BzrDir, BzrDirFormat
51
47
from bzrlib.remote import (
53
49
RemoteBranchFormat,
56
53
RemoteRepositoryFormat,
58
55
from bzrlib.repofmt import groupcompress_repo, pack_repo
59
56
from bzrlib.revision import NULL_REVISION
60
from bzrlib.smart import medium
57
from bzrlib.smart import server, medium
61
58
from bzrlib.smart.client import _SmartClient
62
59
from bzrlib.smart.repository import SmartServerRepositoryGetParentMap
63
60
from bzrlib.tests import (
64
61
condition_isinstance,
65
62
split_suite_by_condition,
66
from bzrlib.transport import get_transport, http
69
67
from bzrlib.transport.memory import MemoryTransport
70
68
from bzrlib.transport.remote import (
283
280
self.expecting_body = True
284
281
return result[1], FakeProtocol(result[2], self)
286
def call_with_body_bytes(self, method, args, body):
287
self._check_call(method, args)
288
self._calls.append(('call_with_body_bytes', method, args, body))
289
result = self._get_next_response()
290
return result[1], FakeProtocol(result[2], self)
292
283
def call_with_body_bytes_expecting_body(self, method, args, body):
293
284
self._check_call(method, args)
294
285
self._calls.append(('call_with_body_bytes_expecting_body', method,
417
408
# Calling _remember_remote_is_before again with a lower value works.
418
409
client_medium._remember_remote_is_before((1, 5))
419
410
self.assertTrue(client_medium._is_remote_before((1, 5)))
420
# If you call _remember_remote_is_before with a higher value it logs a
421
# warning, and continues to remember the lower value.
422
self.assertNotContainsRe(self.get_log(), '_remember_remote_is_before')
423
client_medium._remember_remote_is_before((1, 9))
424
self.assertContainsRe(self.get_log(), '_remember_remote_is_before')
425
self.assertTrue(client_medium._is_remote_before((1, 5)))
411
# You cannot call _remember_remote_is_before with a larger value.
413
AssertionError, client_medium._remember_remote_is_before, (1, 9))
428
416
class TestBzrDirCloningMetaDir(TestRemote):
480
468
self.assertFinished(client)
483
class TestBzrDirOpen(TestRemote):
485
def make_fake_client_and_transport(self, path='quack'):
486
transport = MemoryTransport()
487
transport.mkdir(path)
488
transport = transport.clone(path)
489
client = FakeClient(transport.base)
490
return client, transport
492
def test_absent(self):
493
client, transport = self.make_fake_client_and_transport()
494
client.add_expected_call(
495
'BzrDir.open_2.1', ('quack/',), 'success', ('no',))
496
self.assertRaises(errors.NotBranchError, RemoteBzrDir, transport,
497
remote.RemoteBzrDirFormat(), _client=client, _force_probe=True)
498
self.assertFinished(client)
500
def test_present_without_workingtree(self):
501
client, transport = self.make_fake_client_and_transport()
502
client.add_expected_call(
503
'BzrDir.open_2.1', ('quack/',), 'success', ('yes', 'no'))
504
bd = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
505
_client=client, _force_probe=True)
506
self.assertIsInstance(bd, RemoteBzrDir)
507
self.assertFalse(bd.has_workingtree())
508
self.assertRaises(errors.NoWorkingTree, bd.open_workingtree)
509
self.assertFinished(client)
511
def test_present_with_workingtree(self):
512
client, transport = self.make_fake_client_and_transport()
513
client.add_expected_call(
514
'BzrDir.open_2.1', ('quack/',), 'success', ('yes', 'yes'))
515
bd = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
516
_client=client, _force_probe=True)
517
self.assertIsInstance(bd, RemoteBzrDir)
518
self.assertTrue(bd.has_workingtree())
519
self.assertRaises(errors.NotLocalUrl, bd.open_workingtree)
520
self.assertFinished(client)
522
def test_backwards_compat(self):
523
client, transport = self.make_fake_client_and_transport()
524
client.add_expected_call(
525
'BzrDir.open_2.1', ('quack/',), 'unknown', ('BzrDir.open_2.1',))
526
client.add_expected_call(
527
'BzrDir.open', ('quack/',), 'success', ('yes',))
528
bd = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
529
_client=client, _force_probe=True)
530
self.assertIsInstance(bd, RemoteBzrDir)
531
self.assertFinished(client)
533
def test_backwards_compat_hpss_v2(self):
534
client, transport = self.make_fake_client_and_transport()
535
# Monkey-patch fake client to simulate real-world behaviour with v2
536
# server: upon first RPC call detect the protocol version, and because
537
# the version is 2 also do _remember_remote_is_before((1, 6)) before
538
# continuing with the RPC.
539
orig_check_call = client._check_call
540
def check_call(method, args):
541
client._medium._protocol_version = 2
542
client._medium._remember_remote_is_before((1, 6))
543
client._check_call = orig_check_call
544
client._check_call(method, args)
545
client._check_call = check_call
546
client.add_expected_call(
547
'BzrDir.open_2.1', ('quack/',), 'unknown', ('BzrDir.open_2.1',))
548
client.add_expected_call(
549
'BzrDir.open', ('quack/',), 'success', ('yes',))
550
bd = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
551
_client=client, _force_probe=True)
552
self.assertIsInstance(bd, RemoteBzrDir)
553
self.assertFinished(client)
556
471
class TestBzrDirOpenBranch(TestRemote):
558
473
def test_backwards_compat(self):
1094
995
self.assertEqual({}, result)
1097
class TestBranchSetTagsBytes(RemoteBranchTestCase):
1099
def test_trivial(self):
1100
transport = MemoryTransport()
1101
client = FakeClient(transport.base)
1102
client.add_expected_call(
1103
'Branch.get_stacked_on_url', ('quack/',),
1104
'error', ('NotStacked',))
1105
client.add_expected_call(
1106
'Branch.set_tags_bytes', ('quack/', 'branch token', 'repo token'),
1108
transport.mkdir('quack')
1109
transport = transport.clone('quack')
1110
branch = self.make_remote_branch(transport, client)
1111
self.lock_remote_branch(branch)
1112
branch._set_tags_bytes('tags bytes')
1113
self.assertFinished(client)
1114
self.assertEqual('tags bytes', client._calls[-1][-1])
1116
def test_backwards_compatible(self):
1117
transport = MemoryTransport()
1118
client = FakeClient(transport.base)
1119
client.add_expected_call(
1120
'Branch.get_stacked_on_url', ('quack/',),
1121
'error', ('NotStacked',))
1122
client.add_expected_call(
1123
'Branch.set_tags_bytes', ('quack/', 'branch token', 'repo token'),
1124
'unknown', ('Branch.set_tags_bytes',))
1125
transport.mkdir('quack')
1126
transport = transport.clone('quack')
1127
branch = self.make_remote_branch(transport, client)
1128
self.lock_remote_branch(branch)
1129
class StubRealBranch(object):
1132
def _set_tags_bytes(self, bytes):
1133
self.calls.append(('set_tags_bytes', bytes))
1134
real_branch = StubRealBranch()
1135
branch._real_branch = real_branch
1136
branch._set_tags_bytes('tags bytes')
1137
# Call a second time, to exercise the 'remote version already inferred'
1139
branch._set_tags_bytes('tags bytes')
1140
self.assertFinished(client)
1142
[('set_tags_bytes', 'tags bytes')] * 2, real_branch.calls)
1145
998
class TestBranchLastRevisionInfo(RemoteBranchTestCase):
1147
1000
def test_empty_branch(self):
1247
1100
len(branch.repository._real_repository._fallback_repositories))
1249
1102
def test_get_stacked_on_real_branch(self):
1250
base_branch = self.make_branch('base')
1251
stacked_branch = self.make_branch('stacked')
1103
base_branch = self.make_branch('base', format='1.6')
1104
stacked_branch = self.make_branch('stacked', format='1.6')
1252
1105
stacked_branch.set_stacked_on_url('../base')
1253
1106
reference_format = self.get_repo_format()
1254
1107
network_name = reference_format.network_name()
1255
1108
client = FakeClient(self.get_url())
1256
1109
branch_network_name = self.get_branch_format().network_name()
1257
1110
client.add_expected_call(
1258
'BzrDir.open_branchV3', ('stacked/',),
1111
'BzrDir.open_branchV2', ('stacked/',),
1259
1112
'success', ('branch', branch_network_name))
1260
1113
client.add_expected_call(
1261
1114
'BzrDir.find_repositoryV3', ('stacked/',),
1262
'success', ('ok', '', 'yes', 'no', 'yes', network_name))
1115
'success', ('ok', '', 'no', 'no', 'yes', network_name))
1263
1116
# called twice, once from constructor and then again by us
1264
1117
client.add_expected_call(
1265
1118
'Branch.get_stacked_on_url', ('stacked/',),
1651
1514
branch.unlock()
1652
1515
self.assertFinished(client)
1654
def test_set_option_with_dict(self):
1655
client = FakeClient()
1656
client.add_expected_call(
1657
'Branch.get_stacked_on_url', ('memory:///',),
1658
'error', ('NotStacked',),)
1659
client.add_expected_call(
1660
'Branch.lock_write', ('memory:///', '', ''),
1661
'success', ('ok', 'branch token', 'repo token'))
1662
encoded_dict_value = 'd5:ascii1:a11:unicode \xe2\x8c\x9a3:\xe2\x80\xbde'
1663
client.add_expected_call(
1664
'Branch.set_config_option_dict', ('memory:///', 'branch token',
1665
'repo token', encoded_dict_value, 'foo', ''),
1667
client.add_expected_call(
1668
'Branch.unlock', ('memory:///', 'branch token', 'repo token'),
1670
transport = MemoryTransport()
1671
branch = self.make_remote_branch(transport, client)
1673
config = branch._get_config()
1675
{'ascii': 'a', u'unicode \N{WATCH}': u'\N{INTERROBANG}'},
1678
self.assertFinished(client)
1680
1517
def test_backwards_compat_set_option(self):
1681
1518
self.setup_smart_server_with_call_log()
1682
1519
branch = self.make_branch('.')
1689
1526
self.assertLength(10, self.hpss_calls)
1690
1527
self.assertEqual('value', branch._get_config().get_option('name'))
1692
def test_backwards_compat_set_option_with_dict(self):
1693
self.setup_smart_server_with_call_log()
1694
branch = self.make_branch('.')
1695
verb = 'Branch.set_config_option_dict'
1696
self.disable_verb(verb)
1698
self.addCleanup(branch.unlock)
1699
self.reset_smart_call_log()
1700
config = branch._get_config()
1701
value_dict = {'ascii': 'a', u'unicode \N{WATCH}': u'\N{INTERROBANG}'}
1702
config.set_option(value_dict, 'name')
1703
self.assertLength(10, self.hpss_calls)
1704
self.assertEqual(value_dict, branch._get_config().get_option('name'))
1707
1530
class TestBranchLockWrite(RemoteBranchTestCase):
2288
2092
repo.get_rev_id_for_revno, 5, (42, 'rev-foo'))
2289
2093
self.assertFinished(client)
2291
def test_branch_fallback_locking(self):
2292
"""RemoteBranch.get_rev_id takes a read lock, and tries to call the
2293
get_rev_id_for_revno verb. If the verb is unknown the VFS fallback
2294
will be invoked, which will fail if the repo is unlocked.
2296
self.setup_smart_server_with_call_log()
2297
tree = self.make_branch_and_memory_tree('.')
2300
rev1 = tree.commit('First')
2301
rev2 = tree.commit('Second')
2303
branch = tree.branch
2304
self.assertFalse(branch.is_locked())
2305
self.reset_smart_call_log()
2306
verb = 'Repository.get_rev_id_for_revno'
2307
self.disable_verb(verb)
2308
self.assertEqual(rev1, branch.get_rev_id(1))
2309
self.assertLength(1, [call for call in self.hpss_calls if
2310
call.call.method == verb])
2313
2096
class TestRepositoryIsShared(TestRemoteRepository):