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