Rev 4054: New version of the BzrDir.find_repository verb supporting _network_name to support removing more _ensure_real calls. in http://people.ubuntu.com/~robertc/baz2.0/RemoteRepository._format

Robert Collins robertc at robertcollins.net
Thu Feb 26 04:25:10 GMT 2009


At http://people.ubuntu.com/~robertc/baz2.0/RemoteRepository._format

------------------------------------------------------------
revno: 4054
revision-id: robertc at robertcollins.net-20090226042500-xl9urv7zcbvkfjvs
parent: pqm at pqm.ubuntu.com-20090225235242-3h3yxyd8smf6b0g2
committer: Robert Collins <robertc at robertcollins.net>
branch nick: RemoteRepository._format
timestamp: Thu 2009-02-26 15:25:00 +1100
message:
  New version of the BzrDir.find_repository verb supporting _network_name to support removing more _ensure_real calls.
=== modified file 'NEWS'
--- a/NEWS	2009-02-25 22:00:24 +0000
+++ b/NEWS	2009-02-26 04:25:00 +0000
@@ -111,6 +111,10 @@
       command object before the command is run (or help generated from
       it), without overriding the command. (Robert Collins)
 
+    * New version of the ``BzrDir.find_repository`` verb supporting
+      ``_network_name`` to support removing more _ensure_real calls.
+      (Robert Collins)
+
     * ``RemoteBranchFormat`` no longer claims to have a disk format string.
       (Robert Collins)
 

=== modified file 'bzrlib/remote.py'
--- a/bzrlib/remote.py	2009-02-25 05:06:51 +0000
+++ b/bzrlib/remote.py	2009-02-26 04:25:00 +0000
@@ -219,32 +219,60 @@
             format = BranchReferenceFormat()
             return format.open(self, _found=True, location=reference_url)
 
+    def _open_repo_v1(self, path):
+        verb = 'BzrDir.find_repository'
+        response = self._call(verb, path)
+        if response[0] != 'ok':
+            raise errors.UnexpectedSmartServerResponse(response)
+        # servers that only support the v1 method don't support external
+        # references either.
+        self._ensure_real()
+        repo = self._real_bzrdir.open_repository()
+        response = response + ('no', repo._format.network_name())
+        return response, repo
+
+    def _open_repo_v2(self, path):
+        verb = 'BzrDir.find_repositoryV2'
+        response = self._call(verb, path)
+        if response[0] != 'ok':
+            raise errors.UnexpectedSmartServerResponse(response)
+        self._ensure_real()
+        repo = self._real_bzrdir.open_repository()
+        response = response + (repo._format.network_name(),)
+        return response, repo
+
+    def _open_repo_v3(self, path):
+        verb = 'BzrDir.find_repositoryV3'
+        response = self._call(verb, path)
+        if response[0] != 'ok':
+            raise errors.UnexpectedSmartServerResponse(response)
+        return response, None
+
     def open_repository(self):
         path = self._path_for_remote_call(self._client)
-        verb = 'BzrDir.find_repositoryV2'
-        try:
-            response = self._call(verb, path)
-        except errors.UnknownSmartMethod:
-            verb = 'BzrDir.find_repository'
-            response = self._call(verb, path)
+        response = None
+        for probe in [self._open_repo_v3, self._open_repo_v2,
+            self._open_repo_v1]:
+            try:
+                response, real_repo = probe(path)
+                break
+            except errors.UnknownSmartMethod:
+                pass
+        if response is None:
+            raise errors.UnknownSmartMethod('BzrDir.find_repository{3,2,}')
         if response[0] != 'ok':
             raise errors.UnexpectedSmartServerResponse(response)
-        if verb == 'BzrDir.find_repository':
-            # servers that don't support the V2 method don't support external
-            # references either.
-            response = response + ('no', )
-        if not (len(response) == 5):
+        if len(response) != 6:
             raise SmartProtocolError('incorrect response length %s' % (response,))
         if response[1] == '':
-            format = RemoteRepositoryFormat()
-            format.rich_root_data = (response[2] == 'yes')
-            format.supports_tree_reference = (response[3] == 'yes')
-            # No wire format to check this yet.
-            format.supports_external_lookups = (response[4] == 'yes')
+            # repo is at this dir.
+            format = response_tuple_to_repo_format(response[2:])
             # Used to support creating a real format instance when needed.
             format._creating_bzrdir = self
             remote_repo = RemoteRepository(self, format)
             format._creating_repo = remote_repo
+            if real_repo is not None:
+                remote_repo._set_real_repository(real_repo)
             return remote_repo
         else:
             raise errors.NoRepositoryPresent(self)

=== modified file 'bzrlib/smart/bzrdir.py'
--- a/bzrlib/smart/bzrdir.py	2009-02-24 08:09:17 +0000
+++ b/bzrlib/smart/bzrdir.py	2009-02-26 04:25:00 +0000
@@ -208,7 +208,32 @@
         returns information about the supports_external_lookups format
         attribute too.
 
-        :return: norepository or ok, relpath.
+        :return: norepository or ok, relpath, rich_root, tree_ref,
+            external_lookup.
+        """
+        try:
+            path, rich_root, tree_ref, external_lookup = self._find(path)
+            return SuccessfulSmartServerResponse(
+                ('ok', path, rich_root, tree_ref, external_lookup))
+        except errors.NoRepositoryPresent:
+            return FailedSmartServerResponse(('norepository', ))
+
+
+class SmartServerRequestFindRepositoryV3(SmartServerRequestFindRepository):
+
+    def do(self, path):
+        """try to find a repository from path upwards
+
+        This operates precisely like 'bzrdir.find_repository'.
+
+        If a bzrdir is not present, an exception is propogated
+        rather than 'no branch' because these are different conditions.
+
+        This is the third edition of this method introduced in bzr 1.13, which
+        returns information about the network name of the repository format.
+
+        :return: norepository or ok, relpath, rich_root, tree_ref,
+            external_lookup, network_name.
         """
         try:
             path, rich_root, tree_ref, external_lookup = self._find(path)

=== modified file 'bzrlib/smart/request.py'
--- a/bzrlib/smart/request.py	2009-02-24 08:09:17 +0000
+++ b/bzrlib/smart/request.py	2009-02-26 04:25:00 +0000
@@ -409,6 +409,8 @@
 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')

=== modified file 'bzrlib/tests/test_remote.py'
--- a/bzrlib/tests/test_remote.py	2009-02-24 08:09:17 +0000
+++ b/bzrlib/tests/test_remote.py	2009-02-26 04:25:00 +0000
@@ -532,22 +532,89 @@
         self.assertEqual(network_name, format.network_name())
 
 
-class TestBzrDirOpenRepository(tests.TestCase):
-
-    def test_backwards_compat_1_2(self):
-        transport = MemoryTransport()
-        transport.mkdir('quack')
-        transport = transport.clone('quack')
-        client = FakeClient(transport.base)
+class TestBzrDirOpenRepository(TestRemote):
+
+    def get_repo_format(self):
+        reference_bzrdir_format = bzrdir.format_registry.get('default')()
+        return reference_bzrdir_format.repository_format
+
+    def test_backwards_compat_1_2_3(self):
+        # fallback all the way to the first version.
+        reference_format = self.get_repo_format()
+        network_name = reference_format.network_name()
+        client = FakeClient('bzr://example.com/')
+        client.add_unknown_method_response('BzrDir.find_repositoryV3')
         client.add_unknown_method_response('BzrDir.find_repositoryV2')
         client.add_success_response('ok', '', 'no', 'no')
+        # A real repository instance will be created to determine the network
+        # name.
+        client.add_success_response_with_body(
+            "Bazaar-NG meta directory, format 1\n", 'ok')
+        client.add_success_response_with_body(
+            reference_format.get_format_string(), 'ok')
+        # PackRepository wants to do a stat
+        client.add_success_response('stat', '0', '65535')
+        remote_transport = RemoteTransport('bzr://example.com/quack/', medium=False,
+            _client=client)
+        bzrdir = RemoteBzrDir(remote_transport, remote.RemoteBzrDirFormat(),
+            _client=client)
+        repo = bzrdir.open_repository()
+        self.assertEqual(
+            [('call', 'BzrDir.find_repositoryV3', ('quack/',)),
+             ('call', 'BzrDir.find_repositoryV2', ('quack/',)),
+             ('call', 'BzrDir.find_repository', ('quack/',)),
+             ('call_expecting_body', 'get', ('/quack/.bzr/branch-format',)),
+             ('call_expecting_body', 'get', ('/quack/.bzr/repository/format',)),
+             ('call', 'stat', ('/quack/.bzr/repository',)),
+             ],
+            client._calls)
+        self.assertEqual(network_name, repo._format.network_name())
+
+    def test_backwards_compat_2(self):
+        # fallback to find_repositoryV2
+        reference_format = self.get_repo_format()
+        network_name = reference_format.network_name()
+        client = FakeClient('bzr://example.com/')
+        client.add_unknown_method_response('BzrDir.find_repositoryV3')
+        client.add_success_response('ok', '', 'no', 'no', 'no')
+        # A real repository instance will be created to determine the network
+        # name.
+        client.add_success_response_with_body(
+            "Bazaar-NG meta directory, format 1\n", 'ok')
+        client.add_success_response_with_body(
+            reference_format.get_format_string(), 'ok')
+        # PackRepository wants to do a stat
+        client.add_success_response('stat', '0', '65535')
+        remote_transport = RemoteTransport('bzr://example.com/quack/', medium=False,
+            _client=client)
+        bzrdir = RemoteBzrDir(remote_transport, remote.RemoteBzrDirFormat(),
+            _client=client)
+        repo = bzrdir.open_repository()
+        self.assertEqual(
+            [('call', 'BzrDir.find_repositoryV3', ('quack/',)),
+             ('call', 'BzrDir.find_repositoryV2', ('quack/',)),
+             ('call_expecting_body', 'get', ('/quack/.bzr/branch-format',)),
+             ('call_expecting_body', 'get', ('/quack/.bzr/repository/format',)),
+             ('call', 'stat', ('/quack/.bzr/repository',)),
+             ],
+            client._calls)
+        self.assertEqual(network_name, repo._format.network_name())
+
+    def test_current_server(self):
+        reference_format = self.get_repo_format()
+        network_name = reference_format.network_name()
+        transport = MemoryTransport()
+        transport.mkdir('quack')
+        transport = transport.clone('quack')
+        client = FakeClient(transport.base)
+        client.add_success_response('ok', '', 'no', 'no', 'no', network_name)
         bzrdir = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
             _client=client)
         repo = bzrdir.open_repository()
         self.assertEqual(
-            [('call', 'BzrDir.find_repositoryV2', ('quack/',)),
-             ('call', 'BzrDir.find_repository', ('quack/',))],
+            [('call', 'BzrDir.find_repositoryV3', ('quack/',))],
             client._calls)
+        self.assertEqual(network_name, repo._format.network_name())
 
 
 class OldSmartClient(object):

=== modified file 'bzrlib/transport/remote.py'
--- a/bzrlib/transport/remote.py	2009-02-23 15:42:47 +0000
+++ b/bzrlib/transport/remote.py	2009-02-26 04:25:00 +0000
@@ -90,14 +90,17 @@
             should only be used for testing purposes; normally this is
             determined from the medium.
         """
-        super(RemoteTransport, self).__init__(url,
-                                              _from_transport=_from_transport)
+        super(RemoteTransport, self).__init__(
+            url, _from_transport=_from_transport)
 
         # The medium is the connection, except when we need to share it with
         # other objects (RemoteBzrDir, RemoteRepository etc). In these cases
         # what we want to share is really the shared connection.
 
-        if _from_transport is None:
+        if (_from_transport is not None
+            and isinstance(_from_transport, RemoteTransport)):
+            _client = _from_transport._client
+        elif _from_transport is None:
             # If no _from_transport is specified, we need to intialize the
             # shared medium.
             credentials = None




More information about the bazaar-commits mailing list