Rev 4085: Make accessing a branch.tags.get_tag_dict use a smart[er] method rather than VFS calls and real objects. in http://people.ubuntu.com/~robertc/baz2.0/branch.roundtrips
Robert Collins
robertc at robertcollins.net
Fri Mar 6 03:55:31 GMT 2009
At http://people.ubuntu.com/~robertc/baz2.0/branch.roundtrips
------------------------------------------------------------
revno: 4085
revision-id: robertc at robertcollins.net-20090306035527-sm1gsd3nh3f2mxpa
parent: pqm at pqm.ubuntu.com-20090306030219-enauehb3achqqq7c
committer: Robert Collins <robertc at robertcollins.net>
branch nick: branch.roundtrips
timestamp: Fri 2009-03-06 14:55:27 +1100
message:
Make accessing a branch.tags.get_tag_dict use a smart[er] method rather than VFS calls and real objects.
=== modified file 'NEWS'
--- a/NEWS 2009-03-06 01:01:32 +0000
+++ b/NEWS 2009-03-06 03:55:27 +0000
@@ -155,6 +155,10 @@
INTERNALS:
+ * Branching from a non-stacked branch on a smart protocol is now
+ free of virtual file system methods.
+ (Robert Collins, Andrew Bennetts)
+
* Branch and Repository creation on a bzr+ssh://server are now done
via RPC calls rather than VFS calls, reducing round trips for
pushing new branches substantially. (Robert Collins)
=== modified file 'bzrlib/branch.py'
--- a/bzrlib/branch.py 2009-03-06 01:02:59 +0000
+++ b/bzrlib/branch.py 2009-03-06 03:55:27 +0000
@@ -83,12 +83,8 @@
# - RBC 20060112
base = None
- # override this to set the strategy for storing tags
- def _make_tags(self):
- return DisabledTags(self)
-
def __init__(self, *ignored, **ignored_too):
- self.tags = self._make_tags()
+ self.tags = self._format.make_tags(self)
self._revision_history_cache = None
self._revision_id_to_revno_cache = None
self._partial_revision_id_to_revno_cache = {}
@@ -155,11 +151,25 @@
The default implementation returns False if this branch has no tags,
and True the rest of the time. Subclasses may override this.
"""
- return self.tags.supports_tags() and self.tags.get_tag_dict()
+ return self.supports_tags() and self.tags.get_tag_dict()
def get_config(self):
return BranchConfig(self)
+ def _get_tags_bytes(self):
+ """Get the bytes of a serialised tags dict.
+
+ Note that not all branches support tags, nor do all use the same tags
+ logic: this method is specific to BasicTags. Other tag implementations
+ may use the same method name and behave differently, safely, because
+ of the double-dispatch via
+ format.make_tags->tags_instance->get_tags_dict.
+
+ :return: The bytes of the tags file.
+ :seealso: Branch._set_tags_bytes.
+ """
+ return self._transport.get_bytes('tags')
+
def _get_nick(self, local=False, possible_transports=None):
config = self.get_config()
# explicit overrides master, but don't look for master if local is True
@@ -565,6 +575,17 @@
"""
raise NotImplementedError(self.set_stacked_on_url)
+ def _set_tags_bytes(self, bytes):
+ """Mirror method for _get_tags_bytes.
+
+ :seealso: Branch._get_tags_bytes.
+ """
+ self.lock_write()
+ try:
+ self._transport.put_bytes('tags', bytes)
+ finally:
+ self.unlock()
+
def _cache_revision_history(self, rev_history):
"""Set the cached revision history to rev_history.
@@ -1280,6 +1301,20 @@
"""
return True
+ def make_tags(self, branch):
+ """Create a tags object for branch.
+
+ This method is on BranchFormat, because BranchFormats are reflected
+ over the wire via network_name(), whereas full Branch instances require
+ multiple VFS method calls to operate at all.
+
+ The default implementation returns a disabled-tags instance.
+
+ Note that it is normal for branch to be a RemoteBranch when using tags
+ on a RemoteBranch.
+ """
+ return DisabledTags(branch)
+
def network_name(self):
"""A simple byte string uniquely identifying this format for RPC calls.
@@ -1609,6 +1644,11 @@
]
return self._initialize_helper(a_bzrdir, utf8_files)
+ def make_tags(self, branch):
+ """See bzrlib.branch.BranchFormat.make_tags()."""
+ return BasicTags(branch)
+
+
class BzrBranchFormat7(BranchFormatMetadir):
"""Branch format with last-revision, tags, and a stacked location pointer.
@@ -1643,6 +1683,10 @@
self._matchingbzrdir.repository_format = \
RepositoryFormatKnitPack5RichRoot()
+ def make_tags(self, branch):
+ """See bzrlib.branch.BranchFormat.make_tags()."""
+ return BasicTags(branch)
+
def supports_stacking(self):
return True
@@ -2505,9 +2549,6 @@
value = self.get_config().get_user_option('append_revisions_only')
return value == 'True'
- def _make_tags(self):
- return BasicTags(self)
-
@needs_write_lock
def generate_revision_history(self, revision_id, last_rev=None,
other_branch=None):
=== modified file 'bzrlib/remote.py'
--- a/bzrlib/remote.py 2009-03-06 02:21:00 +0000
+++ b/bzrlib/remote.py 2009-03-06 03:55:27 +0000
@@ -226,17 +226,30 @@
def get_branch_reference(self):
"""See BzrDir.get_branch_reference()."""
+ response = self._get_branch_reference()
+ if response[0] == 'ref':
+ return response[1]
+ else:
+ return None
+
+ def _get_branch_reference(self):
path = self._path_for_remote_call(self._client)
+ medium = self._client._medium
+ if not medium._is_remote_before((1, 13)):
+ try:
+ response = self._call('BzrDir.open_branchV2', path)
+ if response[0] not in ('ref', 'branch'):
+ raise errors.UnexpectedSmartServerResponse(response)
+ return response
+ except errors.UnknownSmartMethod:
+ pass
response = self._call('BzrDir.open_branch', path)
- if response[0] == 'ok':
- if response[1] == '':
- # branch at this location.
- return None
- else:
- # a branch reference, use the existing BranchReference logic.
- return response[1]
+ if response[0] != 'ok':
+ raise errors.UnexpectedSmartServerResponse(response)
+ if response[1] != '':
+ return ('ref', response[1])
else:
- raise errors.UnexpectedSmartServerResponse(response)
+ return ('branch', '')
def _get_tree_branch(self):
"""See BzrDir._get_tree_branch()."""
@@ -250,14 +263,16 @@
result = self._next_open_branch_result
self._next_open_branch_result = None
return result
- reference_url = self.get_branch_reference()
- if reference_url is None:
- # branch at this location.
- return RemoteBranch(self, self.find_repository())
- else:
+ response = self._get_branch_reference()
+ if response[0] == 'ref':
# a branch reference, use the existing BranchReference logic.
format = BranchReferenceFormat()
return format.open(self, _found=True, location=reference_url)
+ branch_format_name = response[1]
+ if not branch_format_name:
+ branch_format_name = None
+ format = RemoteBranchFormat(network_name=branch_format_name)
+ return RemoteBranch(self, self.find_repository(), format=format)
def _open_repo_v1(self, path):
verb = 'BzrDir.find_repository'
@@ -1562,16 +1577,22 @@
class RemoteBranchFormat(branch.BranchFormat):
- def __init__(self):
+ def __init__(self, network_name=None):
super(RemoteBranchFormat, self).__init__()
self._matchingbzrdir = RemoteBzrDirFormat()
self._matchingbzrdir.set_branch_format(self)
self._custom_format = None
+ self._network_name = network_name
def __eq__(self, other):
return (isinstance(other, RemoteBranchFormat) and
self.__dict__ == other.__dict__)
+ def _ensure_real(self):
+ if self._custom_format is None:
+ self._custom_format = branch.network_format_registry.get(
+ self._network_name)
+
def get_format_description(self):
return 'Remote BZR Branch'
@@ -1625,8 +1646,7 @@
if response[0] != 'ok':
raise errors.UnexpectedSmartServerResponse(response)
# Turn the response into a RemoteRepository object.
- format = RemoteBranchFormat()
- format._network_name = response[1]
+ format = RemoteBranchFormat(network_name=response[1])
repo_format = response_tuple_to_repo_format(response[3:])
if response[2] == '':
repo_bzrdir = a_bzrdir
@@ -1643,10 +1663,15 @@
remote_branch._last_revision_info_cache = 0, NULL_REVISION
return remote_branch
+ def make_tags(self, branch):
+ self._ensure_real()
+ return self._custom_format.make_tags(branch)
+
def supports_tags(self):
# Remote branches might support tags, but we won't know until we
# access the real remote branch.
- return True
+ self._ensure_real()
+ return self._custom_format.supports_tags()
class RemoteBranch(branch.Branch, _RpcHelper):
@@ -1711,13 +1736,14 @@
if real_branch is not None:
self._format._network_name = \
self._real_branch._format.network_name()
- #else:
- # # XXX: Need to get this from BzrDir.open_branch's return value.
- # self._ensure_real()
- # self._format._network_name = \
- # self._real_branch._format.network_name()
else:
self._format = format
+ if not self._format._network_name:
+ # Did not get from open_branchV2 - old server.
+ self._ensure_real()
+ self._format._network_name = \
+ self._real_branch._format.network_name()
+ self.tags = self._format.make_tags(self)
# The base class init is not called, so we duplicate this:
hooks = branch.Branch.hooks['open']
for hook in hooks:
@@ -1848,6 +1874,20 @@
raise errors.UnexpectedSmartServerResponse(response)
return response[1]
+ def _vfs_get_tags_bytes(self):
+ self._ensure_real()
+ return self._real_branch._get_tags_bytes()
+
+ def _get_tags_bytes(self):
+ medium = self._client._medium
+ if medium._is_remote_before((1, 13)):
+ return self._vfs_get_tags_bytes()
+ try:
+ response = self._call('Branch.get_tags_bytes', self._remote_path())
+ except errors.UnknownSmartMethod:
+ return self._vfs_get_tags_bytes()
+ return response[0]
+
def lock_read(self):
self.repository.lock_read()
if not self._lock_mode:
@@ -1907,6 +1947,10 @@
self.repository.lock_write(self._repo_lock_token)
return self._lock_token or None
+ def _set_tags_bytes(self, bytes):
+ self._ensure_real()
+ return self._real_branch._set_tags_bytes(bytes)
+
def _unlock(self, branch_token, repo_token):
err_context = {'token': str((branch_token, repo_token))}
response = self._call(
@@ -2150,11 +2194,6 @@
self.set_revision_history(self._lefthand_history(revision_id,
last_rev=last_rev,other_branch=other_branch))
- @property
- def tags(self):
- self._ensure_real()
- return self._real_branch.tags
-
def set_push_location(self, location):
self._ensure_real()
return self._real_branch.set_push_location(location)
=== modified file 'bzrlib/smart/branch.py'
--- a/bzrlib/smart/branch.py 2009-03-06 01:38:43 +0000
+++ b/bzrlib/smart/branch.py 2009-03-06 03:55:27 +0000
@@ -100,6 +100,14 @@
return SuccessfulSmartServerResponse((parent,))
+class SmartServerBranchGetTagsBytes(SmartServerBranchRequest):
+
+ def do_with_branch(self, branch):
+ """Return the _get_tags_bytes for a branch."""
+ bytes = branch._get_tags_bytes()
+ return SuccessfulSmartServerResponse((bytes,))
+
+
class SmartServerBranchRequestGetStackedOnURL(SmartServerBranchRequest):
def do_with_branch(self, branch):
=== modified file 'bzrlib/smart/bzrdir.py'
--- a/bzrlib/smart/bzrdir.py 2009-03-05 04:37:03 +0000
+++ b/bzrlib/smart/bzrdir.py 2009-03-06 03:55:27 +0000
@@ -55,8 +55,11 @@
def do(self, path, *args):
"""Open a BzrDir at path, and return self.do_bzrdir_request(*args)."""
- self._bzrdir = BzrDir.open_from_transport(
- self.transport_from_client_path(path))
+ try:
+ self._bzrdir = BzrDir.open_from_transport(
+ self.transport_from_client_path(path))
+ except errors.NotBranchError:
+ return FailedSmartServerResponse(('nobranch', ))
return self.do_bzrdir_request(*args)
def _boolean_to_yes_no(self, a_boolean):
@@ -298,21 +301,30 @@
return SuccessfulSmartServerResponse(('ok', ))
-class SmartServerRequestOpenBranch(SmartServerRequest):
-
- def do(self, path):
- """try to open a branch at path and return ok/nobranch.
-
- If a bzrdir is not present, an exception is propogated
- rather than 'no branch' because these are different conditions.
- """
- bzrdir = BzrDir.open_from_transport(
- self.transport_from_client_path(path))
+class SmartServerRequestOpenBranch(SmartServerRequestBzrDir):
+
+ def do_bzrdir_request(self):
+ """open a branch at path and return the branch reference or branch."""
try:
- reference_url = bzrdir.get_branch_reference()
+ reference_url = self._bzrdir.get_branch_reference()
if reference_url is None:
return SuccessfulSmartServerResponse(('ok', ''))
else:
return SuccessfulSmartServerResponse(('ok', reference_url))
except errors.NotBranchError:
return FailedSmartServerResponse(('nobranch', ))
+
+
+class SmartServerRequestOpenBranchV2(SmartServerRequestBzrDir):
+
+ def do_bzrdir_request(self):
+ """open a branch at path and return the reference or format."""
+ try:
+ reference_url = self._bzrdir.get_branch_reference()
+ if reference_url is None:
+ format = self._bzrdir.open_branch()._format.network_name()
+ return SuccessfulSmartServerResponse(('branch', format))
+ else:
+ return SuccessfulSmartServerResponse(('ref', reference_url))
+ except errors.NotBranchError:
+ return FailedSmartServerResponse(('nobranch', ))
=== modified file 'bzrlib/smart/request.py'
--- a/bzrlib/smart/request.py 2009-03-05 05:26:24 +0000
+++ b/bzrlib/smart/request.py 2009-03-06 03:55:27 +0000
@@ -388,10 +388,14 @@
request_handlers.register_lazy(
'append', 'bzrlib.smart.vfs', 'AppendRequest')
request_handlers.register_lazy(
- 'Branch.get_config_file', 'bzrlib.smart.branch', 'SmartServerBranchGetConfigFile')
+ 'Branch.get_config_file', 'bzrlib.smart.branch',
+ 'SmartServerBranchGetConfigFile')
request_handlers.register_lazy(
'Branch.get_parent', 'bzrlib.smart.branch', 'SmartServerBranchGetParent')
request_handlers.register_lazy(
+ 'Branch.get_tags_bytes', 'bzrlib.smart.branch',
+ 'SmartServerBranchGetTagsBytes')
+request_handlers.register_lazy(
'Branch.get_stacked_on_url', 'bzrlib.smart.branch', 'SmartServerBranchRequestGetStackedOnURL')
request_handlers.register_lazy(
'Branch.last_revision_info', 'bzrlib.smart.branch', 'SmartServerBranchRequestLastRevisionInfo')
@@ -413,19 +417,29 @@
'BzrDir.cloning_metadir', 'bzrlib.smart.bzrdir',
'SmartServerBzrDirRequestCloningMetaDir')
request_handlers.register_lazy(
- 'BzrDir.create_branch', 'bzrlib.smart.bzrdir', 'SmartServerRequestCreateBranch')
-request_handlers.register_lazy(
- 'BzrDir.create_repository', 'bzrlib.smart.bzrdir', 'SmartServerRequestCreateRepository')
-request_handlers.register_lazy(
- 'BzrDir.find_repository', 'bzrlib.smart.bzrdir', 'SmartServerRequestFindRepositoryV1')
-request_handlers.register_lazy(
- 'BzrDir.find_repositoryV2', 'bzrlib.smart.bzrdir', 'SmartServerRequestFindRepositoryV2')
-request_handlers.register_lazy(
- 'BzrDir.find_repositoryV3', 'bzrlib.smart.bzrdir', 'SmartServerRequestFindRepositoryV3')
-request_handlers.register_lazy(
- 'BzrDirFormat.initialize', 'bzrlib.smart.bzrdir', 'SmartServerRequestInitializeBzrDir')
-request_handlers.register_lazy(
- 'BzrDir.open_branch', 'bzrlib.smart.bzrdir', 'SmartServerRequestOpenBranch')
+ 'BzrDir.create_branch', 'bzrlib.smart.bzrdir',
+ 'SmartServerRequestCreateBranch')
+request_handlers.register_lazy(
+ 'BzrDir.create_repository', 'bzrlib.smart.bzrdir',
+ 'SmartServerRequestCreateRepository')
+request_handlers.register_lazy(
+ 'BzrDir.find_repository', 'bzrlib.smart.bzrdir',
+ 'SmartServerRequestFindRepositoryV1')
+request_handlers.register_lazy(
+ 'BzrDir.find_repositoryV2', 'bzrlib.smart.bzrdir',
+ 'SmartServerRequestFindRepositoryV2')
+request_handlers.register_lazy(
+ 'BzrDir.find_repositoryV3', 'bzrlib.smart.bzrdir',
+ 'SmartServerRequestFindRepositoryV3')
+request_handlers.register_lazy(
+ 'BzrDirFormat.initialize', 'bzrlib.smart.bzrdir',
+ 'SmartServerRequestInitializeBzrDir')
+request_handlers.register_lazy(
+ 'BzrDir.open_branch', 'bzrlib.smart.bzrdir',
+ 'SmartServerRequestOpenBranch')
+request_handlers.register_lazy(
+ 'BzrDir.open_branchV2', 'bzrlib.smart.bzrdir',
+ 'SmartServerRequestOpenBranchV2')
request_handlers.register_lazy(
'delete', 'bzrlib.smart.vfs', 'DeleteRequest')
request_handlers.register_lazy(
=== modified file 'bzrlib/tag.py'
--- a/bzrlib/tag.py 2009-01-17 01:30:58 +0000
+++ b/bzrlib/tag.py 2009-03-06 03:55:27 +0000
@@ -57,9 +57,6 @@
def _not_supported(self, *a, **k):
raise errors.TagsNotSupported(self.branch)
- def supports_tags(self):
- return False
-
set_tag = _not_supported
get_tag_dict = _not_supported
_set_tag_dict = _not_supported
@@ -79,9 +76,6 @@
"""Tag storage in an unversioned branch control file.
"""
- def supports_tags(self):
- return True
-
def set_tag(self, tag_name, tag_target):
"""Add a tag definition to the branch.
@@ -111,7 +105,7 @@
self.branch.lock_read()
try:
try:
- tag_content = self.branch._transport.get_bytes('tags')
+ tag_content = self.branch._get_tags_bytes()
except errors.NoSuchFile, e:
# ugly, but only abentley should see this :)
trace.warning('No branch/tags file in %s. '
@@ -158,14 +152,12 @@
def _set_tag_dict(self, new_dict):
"""Replace all tag definitions
+ WARNING: Calling this on an unlocked branch will lock it, and will
+ replace the tags without warning on conflicts.
+
:param new_dict: Dictionary from tag name to target.
"""
- self.branch.lock_write()
- try:
- self.branch._transport.put_bytes('tags',
- self._serialize_tag_dict(new_dict))
- finally:
- self.branch.unlock()
+ return self.branch._set_tags_bytes(self._serialize_tag_dict(new_dict))
def _serialize_tag_dict(self, tag_dict):
td = dict((k.encode('utf-8'), v)
@@ -205,7 +197,7 @@
"""
if self.branch == to_tags.branch:
return
- if not self.supports_tags():
+ if not self.branch.supports_tags():
# obviously nothing to copy
return
source_dict = self.get_tag_dict()
=== modified file 'bzrlib/tests/__init__.py'
--- a/bzrlib/tests/__init__.py 2009-03-04 06:56:23 +0000
+++ b/bzrlib/tests/__init__.py 2009-03-06 03:55:27 +0000
@@ -776,6 +776,11 @@
TestCase._active_threads = threading.activeCount()
self.addCleanup(self._check_leaked_threads)
+ def debug(self):
+ # debug a frame up.
+ import pdb
+ pdb.Pdb().set_trace(sys._getframe().f_back)
+
def exc_info(self):
absent_attr = object()
exc_info = getattr(self, '_exc_info', absent_attr)
=== modified file 'bzrlib/tests/blackbox/test_branch.py'
--- a/bzrlib/tests/blackbox/test_branch.py 2009-03-03 05:50:55 +0000
+++ b/bzrlib/tests/blackbox/test_branch.py 2009-03-06 03:55:27 +0000
@@ -273,7 +273,7 @@
# being too low. If rpc_count increases, more network roundtrips have
# become necessary for this use case. Please do not adjust this number
# upwards without agreement from bzr's network support maintainers.
- self.assertEqual(71, rpc_count)
+ self.assertEqual(65, rpc_count)
def test_branch_from_trivial_branch_streaming_acceptance(self):
self.setup_smart_server_with_call_log()
@@ -289,7 +289,8 @@
# being too low. If rpc_count increases, more network roundtrips have
# become necessary for this use case. Please do not adjust this number
# upwards without agreement from bzr's network support maintainers.
- self.assertEqual(17, rpc_count)
+ self.debug()
+ self.assertEqual(11, rpc_count)
class TestRemoteBranch(TestCaseWithSFTPServer):
=== modified file 'bzrlib/tests/branch_implementations/test_push.py'
--- a/bzrlib/tests/branch_implementations/test_push.py 2009-03-03 06:29:28 +0000
+++ b/bzrlib/tests/branch_implementations/test_push.py 2009-03-06 03:55:27 +0000
@@ -418,7 +418,7 @@
self.empty_branch.push(target)
self.assertEqual(
['BzrDir.open',
- 'BzrDir.open_branch',
+ 'BzrDir.open_branchV2',
'BzrDir.find_repositoryV3',
'Branch.get_stacked_on_url',
'Branch.lock_write',
=== modified file 'bzrlib/tests/branch_implementations/test_tags.py'
--- a/bzrlib/tests/branch_implementations/test_tags.py 2009-01-17 01:30:58 +0000
+++ b/bzrlib/tests/branch_implementations/test_tags.py 2009-03-06 03:55:27 +0000
@@ -38,16 +38,12 @@
class TestBranchTags(TestCaseWithBranch):
def setUp(self):
+ TestCaseWithBranch.setUp(self)
# formats that don't support tags can skip the rest of these
# tests...
- fmt = self.branch_format
- f = getattr(fmt, 'supports_tags')
- if f is None:
- raise TestSkipped("format %s doesn't declare whether it "
- "supports tags, assuming not" % fmt)
- if not f():
- raise TestSkipped("format %s doesn't support tags" % fmt)
- TestCaseWithBranch.setUp(self)
+ branch = self.make_branch('probe')
+ if not branch._format.supports_tags():
+ raise TestSkipped("format %s doesn't support tags" % branch._format)
def test_tags_initially_empty(self):
b = self.make_branch('b')
@@ -156,17 +152,12 @@
"""Formats that don't support tags should give reasonable errors."""
def setUp(self):
- fmt = self.branch_format
- supported = getattr(fmt, 'supports_tags')
- if supported is None:
- warn("Format %s doesn't declare whether it supports tags or not"
- % fmt)
- raise TestSkipped('No tag support at all')
- if supported():
+ TestCaseWithBranch.setUp(self)
+ branch = self.make_branch('probe')
+ if branch._format.supports_tags():
raise TestSkipped("Format %s declares that tags are supported"
- % fmt)
+ % branch._format)
# it's covered by TestBranchTags
- TestCaseWithBranch.setUp(self)
def test_tag_methods_raise(self):
b = self.make_branch('b')
=== modified file 'bzrlib/tests/test_remote.py'
--- a/bzrlib/tests/test_remote.py 2009-03-06 02:23:20 +0000
+++ b/bzrlib/tests/test_remote.py 2009-03-06 03:55:27 +0000
@@ -42,6 +42,7 @@
from bzrlib.bzrdir import BzrDir, BzrDirFormat
from bzrlib.remote import (
RemoteBranch,
+ RemoteBranchFormat,
RemoteBzrDir,
RemoteBzrDirFormat,
RemoteRepository,
@@ -262,6 +263,10 @@
class TestRemote(tests.TestCaseWithMemoryTransport):
+ def get_branch_format(self):
+ reference_bzrdir_format = bzrdir.format_registry.get('default')()
+ return reference_bzrdir_format.get_branch_format()
+
def get_repo_format(self):
reference_bzrdir_format = bzrdir.format_registry.get('default')()
return reference_bzrdir_format.repository_format
@@ -386,16 +391,29 @@
class TestBzrDirOpenBranch(TestRemote):
+ def test_backwards_compat(self):
+ self.setup_smart_server_with_call_log()
+ self.make_branch('.')
+ a_dir = BzrDir.open(self.get_url('.'))
+ self.reset_smart_call_log()
+ verb = 'BzrDir.open_branchV2'
+ self.disable_verb(verb)
+ format = a_dir.open_branch()
+ call_count = len([call for call in self.hpss_calls if
+ call.call.method == verb])
+ self.assertEqual(1, call_count)
+
def test_branch_present(self):
reference_format = self.get_repo_format()
network_name = reference_format.network_name()
+ branch_network_name = self.get_branch_format().network_name()
transport = MemoryTransport()
transport.mkdir('quack')
transport = transport.clone('quack')
client = FakeClient(transport.base)
client.add_expected_call(
- 'BzrDir.open_branch', ('quack/',),
- 'success', ('ok', ''))
+ 'BzrDir.open_branchV2', ('quack/',),
+ 'success', ('branch', branch_network_name))
client.add_expected_call(
'BzrDir.find_repositoryV3', ('quack/',),
'success', ('ok', '', 'no', 'no', 'no', network_name))
@@ -419,7 +437,7 @@
_client=client)
self.assertRaises(errors.NotBranchError, bzrdir.open_branch)
self.assertEqual(
- [('call', 'BzrDir.open_branch', ('quack/',))],
+ [('call', 'BzrDir.open_branchV2', ('quack/',))],
client._calls)
def test__get_tree_branch(self):
@@ -447,9 +465,10 @@
client = FakeClient(transport.base)
reference_format = self.get_repo_format()
network_name = reference_format.network_name()
+ branch_network_name = self.get_branch_format().network_name()
client.add_expected_call(
- 'BzrDir.open_branch', ('~hello/',),
- 'success', ('ok', ''))
+ 'BzrDir.open_branchV2', ('~hello/',),
+ 'success', ('branch', branch_network_name))
client.add_expected_call(
'BzrDir.find_repositoryV3', ('~hello/',),
'success', ('ok', '', 'no', 'no', 'no', network_name))
@@ -687,7 +706,7 @@
return OldSmartClient()
-class RemoteBranchTestCase(tests.TestCase):
+class RemoteBranchTestCase(TestRemote):
def make_remote_branch(self, transport, client):
"""Make a RemoteBranch using 'client' as its _SmartClient.
@@ -701,7 +720,9 @@
bzrdir = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
_client=False)
repo = RemoteRepository(bzrdir, None, _client=client)
- return RemoteBranch(bzrdir, repo, _client=client)
+ branch_format = self.get_branch_format()
+ format = RemoteBranchFormat(network_name=branch_format.network_name())
+ return RemoteBranch(bzrdir, repo, _client=client, format=format)
class TestBranchGetParent(RemoteBranchTestCase):
@@ -754,6 +775,36 @@
self.assertEqual('http://foo/', result)
+class TestBranchGetTagsBytes(RemoteBranchTestCase):
+
+ def test_backwards_compat(self):
+ self.setup_smart_server_with_call_log()
+ branch = self.make_branch('.')
+ self.reset_smart_call_log()
+ verb = 'Branch.get_tags_bytes'
+ self.disable_verb(verb)
+ branch.tags.get_tag_dict()
+ call_count = len([call for call in self.hpss_calls if
+ call.call.method == verb])
+ self.assertEqual(1, call_count)
+
+ def test_trivial(self):
+ transport = MemoryTransport()
+ client = FakeClient(transport.base)
+ client.add_expected_call(
+ 'Branch.get_stacked_on_url', ('quack/',),
+ 'error', ('NotStacked',))
+ client.add_expected_call(
+ 'Branch.get_tags_bytes', ('quack/',),
+ 'success', ('',))
+ transport.mkdir('quack')
+ transport = transport.clone('quack')
+ branch = self.make_remote_branch(transport, client)
+ result = branch.tags.get_tag_dict()
+ client.finished_test()
+ self.assertEqual({}, result)
+
+
class TestBranchLastRevisionInfo(RemoteBranchTestCase):
def test_empty_branch(self):
@@ -827,9 +878,10 @@
stacked_branch = self.make_branch('stacked', format='1.6')
stacked_branch.set_stacked_on_url('../base')
client = FakeClient(self.get_url())
+ branch_network_name = self.get_branch_format().network_name()
client.add_expected_call(
- 'BzrDir.open_branch', ('stacked/',),
- 'success', ('ok', ''))
+ 'BzrDir.open_branchV2', ('stacked/',),
+ 'success', ('branch', branch_network_name))
client.add_expected_call(
'BzrDir.find_repositoryV3', ('stacked/',),
'success', ('ok', '', 'no', 'no', 'no',
@@ -862,9 +914,10 @@
reference_format = self.get_repo_format()
network_name = reference_format.network_name()
client = FakeClient(self.get_url())
+ branch_network_name = self.get_branch_format().network_name()
client.add_expected_call(
- 'BzrDir.open_branch', ('stacked/',),
- 'success', ('ok', ''))
+ 'BzrDir.open_branchV2', ('stacked/',),
+ 'success', ('branch', branch_network_name))
client.add_expected_call(
'BzrDir.find_repositoryV3', ('stacked/',),
'success', ('ok', '', 'no', 'no', 'no', network_name))
=== modified file 'bzrlib/tests/test_smart.py'
--- a/bzrlib/tests/test_smart.py 2009-03-06 02:23:20 +0000
+++ b/bzrlib/tests/test_smart.py 2009-03-06 03:55:27 +0000
@@ -364,6 +364,36 @@
request.execute('reference'))
+class TestSmartServerRequestOpenBranchV2(TestCaseWithChrootedTransport):
+
+ def test_no_branch(self):
+ """When there is no branch, ('nobranch', ) is returned."""
+ backing = self.get_transport()
+ self.make_bzrdir('.')
+ request = smart.bzrdir.SmartServerRequestOpenBranchV2(backing)
+ self.assertEqual(SmartServerResponse(('nobranch', )),
+ request.execute(''))
+
+ def test_branch(self):
+ """When there is a branch, 'ok' is returned."""
+ backing = self.get_transport()
+ expected = self.make_branch('.')._format.network_name()
+ request = smart.bzrdir.SmartServerRequestOpenBranchV2(backing)
+ self.assertEqual(SuccessfulSmartServerResponse(('branch', expected)),
+ request.execute(''))
+
+ def test_branch_reference(self):
+ """When there is a branch reference, the reference URL is returned."""
+ backing = self.get_transport()
+ request = smart.bzrdir.SmartServerRequestOpenBranchV2(backing)
+ branch = self.make_branch('branch')
+ checkout = branch.create_checkout('reference',lightweight=True)
+ reference_url = BranchReferenceFormat().get_reference(checkout.bzrdir)
+ self.assertFileEqual(reference_url, 'reference/.bzr/branch/location')
+ self.assertEqual(SuccessfulSmartServerResponse(('ref', reference_url)),
+ request.execute('reference'))
+
+
class TestSmartServerRequestRevisionHistory(tests.TestCaseWithMemoryTransport):
def test_empty(self):
@@ -696,6 +726,19 @@
response)
+class TestSmartServerBranchRequestGetTagsBytes(tests.TestCaseWithMemoryTransport):
+# Only called when the branch format and tags match [yay factory
+# methods] so only need to test straight forward cases.
+
+ def test_get_bytes(self):
+ base_branch = self.make_branch('base')
+ request = smart.branch.SmartServerBranchGetTagsBytes(
+ self.get_transport())
+ response = request.execute('base')
+ self.assertEquals(
+ SuccessfulSmartServerResponse(('',)), response)
+
+
class TestSmartServerBranchRequestGetStackedOnURL(tests.TestCaseWithMemoryTransport):
def test_get_stacked_on_url(self):
@@ -1209,6 +1252,9 @@
smart.request.request_handlers.get('Branch.get_parent'),
smart.branch.SmartServerBranchGetParent)
self.assertEqual(
+ smart.request.request_handlers.get('Branch.get_tags_bytes'),
+ smart.branch.SmartServerBranchGetTagsBytes)
+ self.assertEqual(
smart.request.request_handlers.get('Branch.lock_write'),
smart.branch.SmartServerBranchRequestLockWrite)
self.assertEqual(
@@ -1242,6 +1288,9 @@
smart.request.request_handlers.get('BzrDir.open_branch'),
smart.bzrdir.SmartServerRequestOpenBranch)
self.assertEqual(
+ smart.request.request_handlers.get('BzrDir.open_branchV2'),
+ smart.bzrdir.SmartServerRequestOpenBranchV2)
+ self.assertEqual(
smart.request.request_handlers.get('PackRepository.autopack'),
smart.packrepository.SmartServerPackRepositoryAutopack)
self.assertEqual(
=== modified file 'bzrlib/tests/test_tag.py'
--- a/bzrlib/tests/test_tag.py 2009-01-17 01:30:58 +0000
+++ b/bzrlib/tests/test_tag.py 2009-03-06 03:55:27 +0000
@@ -161,9 +161,6 @@
branch = self.make_branch('.')
self.tags = DisabledTags(branch)
- def test_supports_tags(self):
- self.assertEqual(self.tags.supports_tags(), False)
-
def test_set_tag(self):
self.assertRaises(errors.TagsNotSupported, self.tags.set_tag)
More information about the bazaar-commits
mailing list