Rev 4075: (robertc) Create new server verb BzrDir.cloning_metadir and alter in file:///home/pqm/archives/thelove/bzr/%2Btrunk/
Canonical.com Patch Queue Manager
pqm at pqm.ubuntu.com
Tue Mar 3 08:54:18 GMT 2009
At file:///home/pqm/archives/thelove/bzr/%2Btrunk/
------------------------------------------------------------
revno: 4075
revision-id: pqm at pqm.ubuntu.com-20090303085413-35seprvnu885xorz
parent: pqm at pqm.ubuntu.com-20090303054055-1qi1msga1fc98tkr
parent: robertc at robertcollins.net-20090303081205-acgt404g4sgftyqf
committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Tue 2009-03-03 08:54:13 +0000
message:
(robertc) Create new server verb BzrDir.cloning_metadir and alter
Branch.sprout to prevent race conditions during stacked
branching. (Robert Collins, Andrew Bennetts)
modified:
NEWS NEWS-20050323055033-4e00b5db738777ff
bzrlib/branch.py branch.py-20050309040759-e4baf4e0d046576e
bzrlib/bzrdir.py bzrdir.py-20060131065624-156dfea39c4387cb
bzrlib/remote.py remote.py-20060720103555-yeeg2x51vn0rbtdp-1
bzrlib/smart/bzrdir.py bzrdir.py-20061122024551-ol0l0o0oofsu9b3t-1
bzrlib/smart/request.py request.py-20061108095550-gunadhxmzkdjfeek-1
bzrlib/tests/__init__.py selftest.py-20050531073622-8d0e3c8845c97a64
bzrlib/tests/blackbox/test_branch.py test_branch.py-20060524161337-noms9gmcwqqrfi8y-1
bzrlib/tests/branch_implementations/test_push.py test_push.py-20070130153159-fhfap8uoifevg30j-1
bzrlib/tests/branch_implementations/test_sprout.py test_sprout.py-20070521151739-b8t8p7axw1h966ws-1
bzrlib/tests/bzrdir_implementations/test_bzrdir.py test_bzrdir.py-20060131065642-0ebeca5e30e30866
bzrlib/tests/test_remote.py test_remote.py-20060720103555-yeeg2x51vn0rbtdp-2
bzrlib/tests/test_smart.py test_smart.py-20061122024551-ol0l0o0oofsu9b3t-2
------------------------------------------------------------
revno: 4070.2.8
revision-id: robertc at robertcollins.net-20090303081205-acgt404g4sgftyqf
parent: robertc at robertcollins.net-20090303072225-ir6m88y7ppo10vn8
committer: Robert Collins <robertc at robertcollins.net>
branch nick: integration
timestamp: Tue 2009-03-03 19:12:05 +1100
message:
Really test the current BzrDir.cloning_metadir contract.
modified:
bzrlib/tests/test_remote.py test_remote.py-20060720103555-yeeg2x51vn0rbtdp-2
------------------------------------------------------------
revno: 4070.2.7
revision-id: robertc at robertcollins.net-20090303072225-ir6m88y7ppo10vn8
parent: robertc at robertcollins.net-20090303062928-q5akblb37uc0vzmu
committer: Robert Collins <robertc at robertcollins.net>
branch nick: integration
timestamp: Tue 2009-03-03 18:22:25 +1100
message:
Work around network_format_registry returning instances and do not mutate the lookup result. To be followed up with a root cause fix.
modified:
bzrlib/remote.py remote.py-20060720103555-yeeg2x51vn0rbtdp-1
------------------------------------------------------------
revno: 4070.2.6
revision-id: robertc at robertcollins.net-20090303062928-q5akblb37uc0vzmu
parent: robertc at robertcollins.net-20090303055317-1ehgjfxhzl1n4xb2
committer: Robert Collins <robertc at robertcollins.net>
branch nick: integration
timestamp: Tue 2009-03-03 17:29:28 +1100
message:
Missed one test.
modified:
bzrlib/tests/branch_implementations/test_push.py test_push.py-20070130153159-fhfap8uoifevg30j-1
------------------------------------------------------------
revno: 4070.2.5
revision-id: robertc at robertcollins.net-20090303055317-1ehgjfxhzl1n4xb2
parent: robertc at robertcollins.net-20090303041753-30ivxx4a0e24uoo7
parent: robertc at robertcollins.net-20090303055055-0g2rfypt83bapygo
committer: Robert Collins <robertc at robertcollins.net>
branch nick: integration
timestamp: Tue 2009-03-03 16:53:17 +1100
message:
Merge in Branch.sprout race condition fix, allowing all tests to pass.
modified:
bzrlib/branch.py branch.py-20050309040759-e4baf4e0d046576e
bzrlib/bzrdir.py bzrdir.py-20060131065624-156dfea39c4387cb
bzrlib/tests/__init__.py selftest.py-20050531073622-8d0e3c8845c97a64
bzrlib/tests/blackbox/test_branch.py test_branch.py-20060524161337-noms9gmcwqqrfi8y-1
bzrlib/tests/branch_implementations/test_sprout.py test_sprout.py-20070521151739-b8t8p7axw1h966ws-1
bzrlib/tests/test_remote.py test_remote.py-20060720103555-yeeg2x51vn0rbtdp-2
------------------------------------------------------------
revno: 4070.3.1
revision-id: robertc at robertcollins.net-20090303055055-0g2rfypt83bapygo
parent: robertc at robertcollins.net-20090303032751-ubyfhezgjul6y5ic
committer: Robert Collins <robertc at robertcollins.net>
branch nick: branch.roundtrips
timestamp: Tue 2009-03-03 16:50:55 +1100
message:
Alter branch sprouting with an alternate fix for stacked branches that does not require multiple copy_content_into and set_parent calls, reducing IO and round trips.
modified:
bzrlib/branch.py branch.py-20050309040759-e4baf4e0d046576e
bzrlib/bzrdir.py bzrdir.py-20060131065624-156dfea39c4387cb
bzrlib/tests/__init__.py selftest.py-20050531073622-8d0e3c8845c97a64
bzrlib/tests/blackbox/test_branch.py test_branch.py-20060524161337-noms9gmcwqqrfi8y-1
bzrlib/tests/branch_implementations/test_sprout.py test_sprout.py-20070521151739-b8t8p7axw1h966ws-1
bzrlib/tests/test_remote.py test_remote.py-20060720103555-yeeg2x51vn0rbtdp-2
------------------------------------------------------------
revno: 4070.2.4
revision-id: robertc at robertcollins.net-20090303041753-30ivxx4a0e24uoo7
parent: robertc at robertcollins.net-20090303032751-ubyfhezgjul6y5ic
committer: Robert Collins <robertc at robertcollins.net>
branch nick: integration
timestamp: Tue 2009-03-03 15:17:53 +1100
message:
Review feedback.
modified:
bzrlib/smart/bzrdir.py bzrdir.py-20061122024551-ol0l0o0oofsu9b3t-1
------------------------------------------------------------
revno: 4070.2.3
revision-id: robertc at robertcollins.net-20090303032751-ubyfhezgjul6y5ic
parent: robertc at robertcollins.net-20090303013422-cibt4toffn1f6i0h
committer: Robert Collins <robertc at robertcollins.net>
branch nick: branch.roundtrips
timestamp: Tue 2009-03-03 14:27:51 +1100
message:
Get BzrDir.cloning_metadir working.
modified:
NEWS NEWS-20050323055033-4e00b5db738777ff
bzrlib/bzrdir.py bzrdir.py-20060131065624-156dfea39c4387cb
bzrlib/remote.py remote.py-20060720103555-yeeg2x51vn0rbtdp-1
bzrlib/smart/bzrdir.py bzrdir.py-20061122024551-ol0l0o0oofsu9b3t-1
bzrlib/smart/request.py request.py-20061108095550-gunadhxmzkdjfeek-1
bzrlib/tests/blackbox/test_branch.py test_branch.py-20060524161337-noms9gmcwqqrfi8y-1
bzrlib/tests/branch_implementations/test_push.py test_push.py-20070130153159-fhfap8uoifevg30j-1
bzrlib/tests/bzrdir_implementations/test_bzrdir.py test_bzrdir.py-20060131065642-0ebeca5e30e30866
bzrlib/tests/test_remote.py test_remote.py-20060720103555-yeeg2x51vn0rbtdp-2
bzrlib/tests/test_smart.py test_smart.py-20061122024551-ol0l0o0oofsu9b3t-2
------------------------------------------------------------
revno: 4070.2.2
revision-id: robertc at robertcollins.net-20090303013422-cibt4toffn1f6i0h
parent: robertc at robertcollins.net-20090303010625-5bjnznbsmxv0bm7j
committer: Robert Collins <robertc at robertcollins.net>
branch nick: integration
timestamp: Tue 2009-03-03 12:34:22 +1100
message:
Add a get call to the effort test for pushing an empty branch: we need the network name in nearly all non-corner case operations - there is no real world impact.
modified:
bzrlib/tests/branch_implementations/test_push.py test_push.py-20070130153159-fhfap8uoifevg30j-1
------------------------------------------------------------
revno: 4070.2.1
revision-id: robertc at robertcollins.net-20090303010625-5bjnznbsmxv0bm7j
parent: pqm at pqm.ubuntu.com-20090302155409-89pygn9tisbc0lir
committer: Robert Collins <robertc at robertcollins.net>
branch nick: bzrdir.network_name
timestamp: Tue 2009-03-03 12:06:25 +1100
message:
Add a BzrDirFormat.network_name.
modified:
NEWS NEWS-20050323055033-4e00b5db738777ff
bzrlib/branch.py branch.py-20050309040759-e4baf4e0d046576e
bzrlib/bzrdir.py bzrdir.py-20060131065624-156dfea39c4387cb
bzrlib/remote.py remote.py-20060720103555-yeeg2x51vn0rbtdp-1
bzrlib/tests/bzrdir_implementations/test_bzrdir.py test_bzrdir.py-20060131065642-0ebeca5e30e30866
=== modified file 'NEWS'
--- a/NEWS 2009-03-03 03:01:49 +0000
+++ b/NEWS 2009-03-03 08:54:13 +0000
@@ -142,6 +142,8 @@
plugins to have hooks called on non-stacked instances.
(Robert Collins, #334187)
+ * ``BzrDir.cloning_metadir`` now has a RPC call. (Robert Collins)
+
* ``BzrDirFormat.__str__`` now uses the human readable description
rather than the sometimes-absent disk label. (Robert Collins)
@@ -172,8 +174,9 @@
``resume_write_group`` methods. These are currently only useful
with pack repositories. (Andrew Bennetts, Robert Collins)
- * ``RepositoryFormat`` objects now have a ``network_name`` for passing
- the format across RPC calls. (Robert Collins, Andrew Bennetts)
+ * ``BzrDirFormat``, ``BranchFormat`` and ``RepositoryFormat`` objects
+ now have a ``network_name`` for passing the format across RPC calls.
+ (Robert Collins, Andrew Bennetts)
* ``RepositoryFormat`` objects now all have a new attribute
``_serializer`` used by fetch when reserialising is required.
=== modified file 'bzrlib/branch.py'
--- a/bzrlib/branch.py 2009-03-02 04:45:02 +0000
+++ b/bzrlib/branch.py 2009-03-03 05:50:55 +0000
@@ -892,7 +892,7 @@
return result
@needs_read_lock
- def sprout(self, to_bzrdir, revision_id=None):
+ def sprout(self, to_bzrdir, revision_id=None, repository_policy=None):
"""Create a new line of development from the branch, into to_bzrdir.
to_bzrdir controls the branch format.
@@ -901,6 +901,8 @@
be truncated to end with revision_id.
"""
result = to_bzrdir.create_branch()
+ if repository_policy is not None:
+ repository_policy.configure_branch(result)
self.copy_content_into(result, revision_id=revision_id)
result.set_parent(self.bzrdir.root_transport.base)
return result
@@ -1709,7 +1711,7 @@
network_format_registry = registry.FormatRegistry()
"""Registry of formats indexed by their network name.
-The network name for a repository format is an identifier that can be used when
+The network name for a branch format is an identifier that can be used when
referring to formats with smart server operations. See
BranchFormat.network_name() for more detail.
"""
=== modified file 'bzrlib/bzrdir.py'
--- a/bzrlib/bzrdir.py 2009-02-26 06:01:51 +0000
+++ b/bzrlib/bzrdir.py 2009-03-03 05:50:55 +0000
@@ -1126,17 +1126,9 @@
# Not especially, but it's part of the contract.
result_branch = result.create_branch()
else:
- # Force NULL revision to avoid using repository before stacking
- # is configured.
- result_branch = source_branch.sprout(
- result, revision_id=_mod_revision.NULL_REVISION)
- parent_location = result_branch.get_parent()
+ result_branch = source_branch.sprout(result,
+ revision_id=revision_id, repository_policy=repository_policy)
mutter("created new branch %r" % (result_branch,))
- repository_policy.configure_branch(result_branch)
- if source_branch is not None:
- source_branch.copy_content_into(result_branch, revision_id)
- # Override copy_content_into
- result_branch.set_parent(parent_location)
# Create/update the result working tree
if (create_tree_if_local and
@@ -1779,6 +1771,16 @@
"""
return True
+ def network_name(self):
+ """A simple byte string uniquely identifying this format for RPC calls.
+
+ Bzr control formats use thir disk format string to identify the format
+ over the wire. Its possible that other control formats have more
+ complex detection requirements, so we permit them to use any unique and
+ immutable string they desire.
+ """
+ raise NotImplementedError(self.network_name)
+
def same_model(self, target_format):
return (self.repository_format.rich_root_data ==
target_format.rich_root_data)
@@ -1829,6 +1831,8 @@
@classmethod
def register_format(klass, format):
klass._formats[format.get_format_string()] = format
+ # bzr native formats have a network name of their format string.
+ network_format_registry.register(format.get_format_string(), format)
@classmethod
def register_control_format(klass, format):
@@ -1923,6 +1927,9 @@
"""
return False
+ def network_name(self):
+ return self.get_format_string()
+
def _open(self, transport):
"""See BzrDirFormat._open."""
return BzrDir4(transport, self)
@@ -1981,6 +1988,9 @@
result._init_workingtree()
return result
+ def network_name(self):
+ return self.get_format_string()
+
def _open(self, transport):
"""See BzrDirFormat._open."""
return BzrDir5(transport, self)
@@ -2038,6 +2048,9 @@
result._init_workingtree()
return result
+ def network_name(self):
+ return self.get_format_string()
+
def _open(self, transport):
"""See BzrDirFormat._open."""
return BzrDir6(transport, self)
@@ -2065,6 +2078,7 @@
def __init__(self):
self._workingtree_format = None
self._branch_format = None
+ self._repository_format = None
def __eq__(self, other):
if other.__class__ is not self.__class__:
@@ -2125,13 +2139,16 @@
"""See BzrDirFormat.get_format_description()."""
return "Meta directory format 1"
+ def network_name(self):
+ return self.get_format_string()
+
def _open(self, transport):
"""See BzrDirFormat._open."""
return BzrDirMeta1(transport, self)
def __return_repository_format(self):
"""Circular import protection."""
- if getattr(self, '_repository_format', None):
+ if self._repository_format:
return self._repository_format
from bzrlib.repository import RepositoryFormat
return RepositoryFormat.get_default_format()
@@ -2174,6 +2191,15 @@
__set_workingtree_format)
+network_format_registry = registry.FormatRegistry()
+"""Registry of formats indexed by their network name.
+
+The network name for a BzrDirFormat is an identifier that can be used when
+referring to formats with smart server operations. See
+BzrDirFormat.network_name() for more detail.
+"""
+
+
# Register bzr control format
BzrDirFormat.register_control_format(BzrDirFormat)
@@ -2706,12 +2732,22 @@
class RemoteBzrDirFormat(BzrDirMetaFormat1):
"""Format representing bzrdirs accessed via a smart server"""
+ def __init__(self):
+ BzrDirMetaFormat1.__init__(self)
+ self._network_name = None
+
def get_format_description(self):
return 'bzr remote bzrdir'
def get_format_string(self):
raise NotImplementedError(self.get_format_string)
+ def network_name(self):
+ if self._network_name:
+ return self._network_name
+ else:
+ raise AssertionError("No network name set.")
+
@classmethod
def probe_transport(klass, transport):
"""Return a RemoteBzrDirFormat object if it looks possible."""
@@ -2830,7 +2866,7 @@
"""Register a metadir subformat.
These all use a BzrDirMetaFormat1 bzrdir, but can be parameterized
- by the Repository format.
+ by the Repository/Branch/WorkingTreeformats.
:param repository_format: The fully-qualified repository format class
name as a string.
=== modified file 'bzrlib/remote.py'
--- a/bzrlib/remote.py 2009-03-02 07:13:41 +0000
+++ b/bzrlib/remote.py 2009-03-03 07:22:25 +0000
@@ -121,6 +121,8 @@
if not self._real_bzrdir:
self._real_bzrdir = BzrDir.open_from_transport(
self.root_transport, _server_formats=False)
+ self._format._network_name = \
+ self._real_bzrdir._format.network_name()
def _translate_error(self, err, **context):
_translate_error(err, bzrdir=self, **context)
@@ -131,9 +133,37 @@
self._next_open_branch_result = None
return BzrDir.break_lock(self)
- def cloning_metadir(self, stacked=False):
+ def _vfs_cloning_metadir(self, require_stacking=False):
self._ensure_real()
- return self._real_bzrdir.cloning_metadir(stacked)
+ return self._real_bzrdir.cloning_metadir(
+ require_stacking=require_stacking)
+
+ def cloning_metadir(self, require_stacking=False):
+ medium = self._client._medium
+ if medium._is_remote_before((1, 13)):
+ return self._vfs_cloning_metadir(require_stacking=require_stacking)
+ verb = 'BzrDir.cloning_metadir'
+ if require_stacking:
+ stacking = 'True'
+ else:
+ stacking = 'False'
+ path = self._path_for_remote_call(self._client)
+ try:
+ response = self._call(verb, path, stacking)
+ except errors.UnknownSmartMethod:
+ return self._vfs_cloning_metadir(require_stacking=require_stacking)
+ if len(response) != 3:
+ raise errors.UnexpectedSmartServerResponse(response)
+ control_name, repo_name, branch_name = response
+ # ICK: perhaps change these registries to be factories only?
+ format = bzrdir.network_format_registry.get(control_name).__class__()
+ if repo_name:
+ format.repository_format = repository.network_format_registry.get(
+ repo_name)
+ if branch_name:
+ format.set_branch_format(
+ branch.network_format_registry.get(branch_name))
+ return format
def create_repository(self, shared=False):
# as per meta1 formats - just delegate to the format object which may
=== modified file 'bzrlib/smart/bzrdir.py'
--- a/bzrlib/smart/bzrdir.py 2009-02-26 06:01:21 +0000
+++ b/bzrlib/smart/bzrdir.py 2009-03-03 04:17:53 +0000
@@ -18,7 +18,7 @@
from bzrlib import branch, errors, repository
-from bzrlib.bzrdir import BzrDir, BzrDirFormat
+from bzrlib.bzrdir import BzrDir, BzrDirFormat, BzrDirMetaFormat1
from bzrlib.smart.request import (
FailedSmartServerResponse,
SmartServerRequest,
@@ -53,6 +53,12 @@
class SmartServerRequestBzrDir(SmartServerRequest):
+ 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))
+ return self.do_bzrdir_request(*args)
+
def _boolean_to_yes_no(self, a_boolean):
if a_boolean:
return 'yes'
@@ -80,6 +86,30 @@
return '/'.join(segments)
+class SmartServerBzrDirRequestCloningMetaDir(SmartServerRequestBzrDir):
+
+ def do_bzrdir_request(self, require_stacking):
+ """Get the format that should be used when cloning from this dir."""
+ if require_stacking == "True":
+ require_stacking = True
+ else:
+ require_stacking = False
+ control_format = self._bzrdir.cloning_metadir(
+ require_stacking=require_stacking)
+ control_name = control_format.network_name()
+ # XXX: There should be a method that tells us that the format does/does not
+ # have subformats.
+ if isinstance(control_format, BzrDirMetaFormat1):
+ branch_name = control_format.get_branch_format().network_name()
+ repository_name = control_format.repository_format.network_name()
+ else:
+ # Only MetaDir has delegated formats today.
+ branch_name = ''
+ repository_name = ''
+ return SuccessfulSmartServerResponse((control_name, repository_name,
+ branch_name))
+
+
class SmartServerRequestCreateBranch(SmartServerRequestBzrDir):
def do(self, path, network_name):
=== modified file 'bzrlib/smart/request.py'
--- a/bzrlib/smart/request.py 2009-03-02 07:55:18 +0000
+++ b/bzrlib/smart/request.py 2009-03-03 03:27:51 +0000
@@ -408,6 +408,9 @@
request_handlers.register_lazy(
'Branch.unlock', 'bzrlib.smart.branch', 'SmartServerBranchRequestUnlock')
request_handlers.register_lazy(
+ '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')
=== modified file 'bzrlib/tests/__init__.py'
--- a/bzrlib/tests/__init__.py 2009-03-01 11:11:14 +0000
+++ b/bzrlib/tests/__init__.py 2009-03-03 05:50:55 +0000
@@ -1820,6 +1820,29 @@
return sio
+class CapturedCall(object):
+ """A helper for capturing smart server calls for easy debug analysis."""
+
+ def __init__(self, params, prefix_length):
+ """Capture the call with params and skip prefix_length stack frames."""
+ self.call = params
+ import traceback
+ # The last 5 frames are the __init__, the hook frame, and 3 smart
+ # client frames. Beyond this we could get more clever, but this is good
+ # enough for now.
+ stack = traceback.extract_stack()[prefix_length:-5]
+ self.stack = ''.join(traceback.format_list(stack))
+
+ def __str__(self):
+ return self.call.method
+
+ def __repr__(self):
+ return self.call.method
+
+ def stack(self):
+ return self.stack
+
+
class TestCaseWithMemoryTransport(TestCase):
"""Common test class for tests that do not need disk resources.
@@ -2116,9 +2139,13 @@
"""Sets up a smart server as the transport server with a call log."""
self.transport_server = server.SmartTCPServer_for_testing
self.hpss_calls = []
+ import traceback
+ # Skip the current stack down to the caller of
+ # setup_smart_server_with_call_log
+ prefix_length = len(traceback.extract_stack()) - 2
def capture_hpss_call(params):
- import traceback
- self.hpss_calls.append((params, traceback.format_stack()))
+ self.hpss_calls.append(
+ CapturedCall(params, prefix_length))
client._SmartClient.hooks.install_named_hook(
'call', capture_hpss_call, None)
=== modified file 'bzrlib/tests/blackbox/test_branch.py'
--- a/bzrlib/tests/blackbox/test_branch.py 2009-03-02 03:38:07 +0000
+++ b/bzrlib/tests/blackbox/test_branch.py 2009-03-03 05:50:55 +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(99, rpc_count)
+ self.assertEqual(71, rpc_count)
def test_branch_from_trivial_branch_streaming_acceptance(self):
self.setup_smart_server_with_call_log()
@@ -289,7 +289,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(25, rpc_count)
+ self.assertEqual(17, rpc_count)
class TestRemoteBranch(TestCaseWithSFTPServer):
=== modified file 'bzrlib/tests/branch_implementations/test_push.py'
--- a/bzrlib/tests/branch_implementations/test_push.py 2009-02-27 01:02:40 +0000
+++ b/bzrlib/tests/branch_implementations/test_push.py 2009-03-03 06:29:28 +0000
@@ -259,7 +259,7 @@
self.disableOptimisticGetParentMap()
self.assertFalse(local.is_locked())
local.push(remote)
- hpss_call_names = [item[0].method for item in self.hpss_calls]
+ hpss_call_names = [item.call.method for item in self.hpss_calls]
self.assertTrue('Repository.insert_stream' in hpss_call_names)
insert_stream_idx = hpss_call_names.index('Repository.insert_stream')
calls_after_insert_stream = hpss_call_names[insert_stream_idx:]
=== modified file 'bzrlib/tests/branch_implementations/test_sprout.py'
--- a/bzrlib/tests/branch_implementations/test_sprout.py 2009-02-24 05:37:17 +0000
+++ b/bzrlib/tests/branch_implementations/test_sprout.py 2009-03-03 05:50:55 +0000
@@ -19,6 +19,7 @@
import os
from bzrlib import (
branch as _mod_branch,
+ errors,
remote,
revision as _mod_revision,
tests,
@@ -151,3 +152,36 @@
raise KnownFailure('there is no support for'
' symlinks to non-ASCII targets (bug #272444)')
+ def assertBranchHookBranchIsStacked(self, pre_change_params):
+ # Just calling will either succeed or fail.
+ pre_change_params.branch.get_stacked_on_url()
+ self.hook_calls.append(pre_change_params)
+
+ def test_sprout_stacked_hooks_get_stacked_branch(self):
+ tree = self.make_branch_and_tree('source')
+ tree.commit('a commit')
+ revid = tree.commit('a second commit')
+ source = tree.branch
+ target_transport = self.get_transport('target')
+ self.hook_calls = []
+ _mod_branch.Branch.hooks.install_named_hook("pre_change_branch_tip",
+ self.assertBranchHookBranchIsStacked, None)
+ try:
+ dir = source.bzrdir.sprout(target_transport.base,
+ source.last_revision(), possible_transports=[target_transport],
+ source_branch=source, stacked=True)
+ except errors.UnstackableBranchFormat:
+ if isinstance(self.branch_format, _mod_branch.BzrBranchFormat4):
+ raise KnownFailure("Format 4 doesn't auto stack successfully.")
+ else:
+ raise
+ result = dir.open_branch()
+ self.assertEqual(revid, result.last_revision())
+ self.assertEqual(source.base, result.get_stacked_on_url())
+ # Smart servers invoke hooks on both sides
+ if isinstance(result, remote.RemoteBranch):
+ expected_calls = 2
+ else:
+ expected_calls = 1
+ self.assertEqual(expected_calls, len(self.hook_calls))
+
=== modified file 'bzrlib/tests/bzrdir_implementations/test_bzrdir.py'
--- a/bzrlib/tests/bzrdir_implementations/test_bzrdir.py 2009-03-02 03:38:07 +0000
+++ b/bzrlib/tests/bzrdir_implementations/test_bzrdir.py 2009-03-03 03:27:51 +0000
@@ -1165,6 +1165,28 @@
opened_dir._format)
self.failUnless(isinstance(opened_dir, bzrdir.BzrDir))
+ def test_format_network_name(self):
+ # All control formats must have a network name.
+ dir = self.make_bzrdir('.')
+ format = dir._format
+ # We want to test that the network_name matches the actual format on
+ # disk. For local control dirsthat means that using network_name as a
+ # key in the registry gives back the same format. For remote obects
+ # we check that the network_name of the RemoteBzrDirFormat we have
+ # locally matches the actual format present on disk.
+ if isinstance(format, bzrdir.RemoteBzrDirFormat):
+ dir._ensure_real()
+ real_dir = dir._real_bzrdir
+ network_name = format.network_name()
+ self.assertEqual(real_dir._format.network_name(), network_name)
+ else:
+ registry = bzrdir.network_format_registry
+ network_name = format.network_name()
+ looked_up_format = registry.get(network_name)
+ self.assertEqual(format.__class__, looked_up_format.__class__)
+ # The network name must be a byte string.
+ self.assertIsInstance(network_name, str)
+
def test_open_not_bzrdir(self):
# test the formats specific behaviour for no-content or similar dirs.
self.assertRaises(NotBranchError,
=== modified file 'bzrlib/tests/test_remote.py'
--- a/bzrlib/tests/test_remote.py 2009-02-26 06:01:21 +0000
+++ b/bzrlib/tests/test_remote.py 2009-03-03 08:12:05 +0000
@@ -349,6 +349,41 @@
AssertionError, client_medium._remember_remote_is_before, (1, 9))
+class TestBzrDirCloningMetaDir(TestRemote):
+
+ def test_backwards_compat(self):
+ self.setup_smart_server_with_call_log()
+ a_dir = self.make_bzrdir('.')
+ self.reset_smart_call_log()
+ verb = 'BzrDir.cloning_metadir'
+ self.disable_verb(verb)
+ format = a_dir.cloning_metadir()
+ call_count = len([call for call in self.hpss_calls if
+ call.call.method == verb])
+ self.assertEqual(1, call_count)
+
+ def test_current_server(self):
+ transport = self.get_transport('.')
+ transport = transport.clone('quack')
+ self.make_bzrdir('quack')
+ client = FakeClient(transport.base)
+ reference_bzrdir_format = bzrdir.format_registry.get('default')()
+ control_name = reference_bzrdir_format.network_name()
+ client.add_expected_call(
+ 'BzrDir.cloning_metadir', ('quack/', 'False'),
+ 'success', (control_name, '', '')),
+ a_bzrdir = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
+ _client=client)
+ result = a_bzrdir.cloning_metadir()
+ # We should have got a reference control dir with default branch and
+ # repository formats.
+ # This pokes a little, just to be sure.
+ self.assertEqual(bzrdir.BzrDirMetaFormat1, type(result))
+ self.assertEqual(None, result._repository_format)
+ self.assertEqual(None, result._branch_format)
+ client.finished_test()
+
+
class TestBzrDirOpenBranch(TestRemote):
def test_branch_present(self):
@@ -479,7 +514,7 @@
self.disable_verb('BzrDir.create_branch')
branch = repo.bzrdir.create_branch()
create_branch_call_count = len([call for call in self.hpss_calls if
- call[0].method == 'BzrDir.create_branch'])
+ call.call.method == 'BzrDir.create_branch'])
self.assertEqual(1, create_branch_call_count)
def test_current_server(self):
@@ -515,7 +550,7 @@
self.disable_verb('BzrDir.create_repository')
repo = bzrdir.create_repository()
create_repo_call_count = len([call for call in self.hpss_calls if
- call[0].method == 'BzrDir.create_repository'])
+ call.call.method == 'BzrDir.create_repository'])
self.assertEqual(1, create_repo_call_count)
def test_current_server(self):
@@ -1595,7 +1630,7 @@
self.disable_verb(verb)
repo.set_make_working_trees(True)
call_count = len([call for call in self.hpss_calls if
- call[0].method == verb])
+ call.call.method == verb])
self.assertEqual(1, call_count)
def test_current(self):
=== modified file 'bzrlib/tests/test_smart.py'
--- a/bzrlib/tests/test_smart.py 2009-03-02 07:13:41 +0000
+++ b/bzrlib/tests/test_smart.py 2009-03-03 03:27:51 +0000
@@ -38,7 +38,8 @@
)
from bzrlib.branch import Branch, BranchReferenceFormat
import bzrlib.smart.branch
-import bzrlib.smart.bzrdir
+import bzrlib.smart.bzrdir, bzrlib.smart.bzrdir as smart_dir
+import bzrlib.smart.packrepository
import bzrlib.smart.repository
from bzrlib.smart.request import (
FailedSmartServerResponse,
@@ -162,6 +163,24 @@
request.transport_from_client_path('foo/').base)
+class TestSmartServerBzrDirRequestCloningMetaDir(
+ tests.TestCaseWithMemoryTransport):
+ """Tests for BzrDir.cloning_metadir."""
+
+ def test_cloning_metadir(self):
+ """When there is a bzrdir present, the call succeeds."""
+ backing = self.get_transport()
+ dir = self.make_bzrdir('.')
+ local_result = dir.cloning_metadir()
+ request_class = smart_dir.SmartServerBzrDirRequestCloningMetaDir
+ request = request_class(backing)
+ expected = SuccessfulSmartServerResponse(
+ (local_result.network_name(),
+ local_result.repository_format.network_name(),
+ local_result.get_branch_format().network_name()))
+ self.assertEqual(expected, request.execute('', 'False'))
+
+
class TestSmartServerRequestCreateRepository(tests.TestCaseWithMemoryTransport):
"""Tests for BzrDir.create_repository."""
@@ -1176,6 +1195,9 @@
smart.request.request_handlers.get('BzrDirFormat.initialize'),
smart.bzrdir.SmartServerRequestInitializeBzrDir)
self.assertEqual(
+ smart.request.request_handlers.get('BzrDir.cloning_metadir'),
+ smart.bzrdir.SmartServerBzrDirRequestCloningMetaDir)
+ self.assertEqual(
smart.request.request_handlers.get('BzrDir.open_branch'),
smart.bzrdir.SmartServerRequestOpenBranch)
self.assertEqual(
More information about the bazaar-commits
mailing list