Rev 4289: Add support for a RemoteBzrDirConfig to support optimising push operations which need to look for default stacking locations. in http://people.ubuntu.com/~robertc/baz2.0/pending/push.roundtrips

Robert Collins robertc at robertcollins.net
Tue Apr 14 03:35:52 BST 2009


At http://people.ubuntu.com/~robertc/baz2.0/pending/push.roundtrips

------------------------------------------------------------
revno: 4289
revision-id: robertc at robertcollins.net-20090414023507-935t0u7ab2rt7kfk
parent: pqm at pqm.ubuntu.com-20090413175307-kzfbzfxgscia4sto
committer: Robert Collins <robertc at robertcollins.net>
branch nick: push.roundtrips
timestamp: Tue 2009-04-14 12:35:07 +1000
message:
  Add support for a RemoteBzrDirConfig to support optimising push operations which need to look for default stacking locations.
=== modified file 'NEWS'
--- a/NEWS	2009-04-11 13:01:19 +0000
+++ b/NEWS	2009-04-14 02:35:07 +0000
@@ -50,6 +50,10 @@
 Internals
 *********
 
+* ``bzrlib.bzrdir.BzrDir._get_config`` now returns a ``TransportConfig``
+  or similar when the dir supports configuration settings. The base class
+  defaults to None. (Robert Collins)
+
 * ``bzrlib.tests.ExtendedTestResult`` has new methods ``startTests``
   called before the first test is started, ``done`` called after the last
   test completes, and a new parameter ``strict``. (Robert Collins)

=== modified file 'bzrlib/bzrdir.py'
--- a/bzrlib/bzrdir.py	2009-04-13 17:53:07 +0000
+++ b/bzrlib/bzrdir.py	2009-04-14 02:35:07 +0000
@@ -408,11 +408,10 @@
             stack_on_pwd = None
             config = found_bzrdir.get_config()
             stop = False
-            if config is not None:
-                stack_on = config.get_default_stack_on()
-                if stack_on is not None:
-                    stack_on_pwd = found_bzrdir.root_transport.base
-                    stop = True
+            stack_on = config.get_default_stack_on()
+            if stack_on is not None:
+                stack_on_pwd = found_bzrdir.root_transport.base
+                stop = True
             # does it have a repository ?
             try:
                 repository = found_bzrdir.open_repository()
@@ -744,9 +743,12 @@
         raise NotImplementedError(self.get_workingtree_transport)
 
     def get_config(self):
-        if getattr(self, '_get_config', None) is None:
-            return None
-        return self._get_config()
+        """Get configuration for this BzrDir."""
+        return config.BzrDirConfig(self)
+
+    def _get_config(self):
+        """By default, no configuration is available."""
+        return None
 
     def __init__(self, _transport, _format):
         """Initialize a Bzr control dir object.
@@ -1696,8 +1698,7 @@
         return format.open(self, _found=True)
 
     def _get_config(self):
-        return config.BzrDirConfig(self.transport)
-
+        return config.TransportConfig(self.transport, 'control.conf')
 
 class BzrDirFormat(object):
     """An encapsulation of the initialization and open routines for a format.

=== modified file 'bzrlib/config.py'
--- a/bzrlib/config.py	2009-04-11 13:01:19 +0000
+++ b/bzrlib/config.py	2009-04-14 02:35:07 +0000
@@ -1346,8 +1346,9 @@
 
 class BzrDirConfig(object):
 
-    def __init__(self, transport):
-        self._config = TransportConfig(transport, 'control.conf')
+    def __init__(self, bzrdir):
+        self._bzrdir = bzrdir
+        self._config = bzrdir._get_config()
 
     def set_default_stack_on(self, value):
         """Set the default stacking location.
@@ -1357,6 +1358,8 @@
         This policy affects all branches contained by this bzrdir, except for
         those under repositories.
         """
+        if self._config is None:
+            raise errors.BzrError("Cannot set configuration in %s" % self._bzrdir)
         if value is None:
             self._config.set_option('', 'default_stack_on')
         else:
@@ -1370,6 +1373,8 @@
         This policy affects all branches contained by this bzrdir, except for
         those under repositories.
         """
+        if self._config is None:
+            return None
         value = self._config.get_option('default_stack_on')
         if value == '':
             value = None

=== modified file 'bzrlib/remote.py'
--- a/bzrlib/remote.py	2009-04-09 20:23:07 +0000
+++ b/bzrlib/remote.py	2009-04-14 02:35:07 +0000
@@ -392,9 +392,8 @@
         return self._real_bzrdir.clone(url, revision_id=revision_id,
             force_new_repo=force_new_repo, preserve_stacking=preserve_stacking)
 
-    def get_config(self):
-        self._ensure_real()
-        return self._real_bzrdir.get_config()
+    def _get_config(self):
+        return RemoteBzrDirConfig(self)
 
 
 class RemoteRepositoryFormat(repository.RepositoryFormat):
@@ -2385,17 +2384,14 @@
         return self._real_branch.set_push_location(location)
 
 
-class RemoteBranchConfig(object):
-    """A Config that reads from a smart branch and writes via smart methods.
+class RemoteConfig(object):
+    """A Config that reads and writes from smart verbs.
 
     It is a low-level object that considers config data to be name/value pairs
     that may be associated with a section. Assigning meaning to the these
     values is done at higher levels like bzrlib.config.TreeConfig.
     """
 
-    def __init__(self, branch):
-        self._branch = branch
-
     def get_option(self, name, section=None, default=None):
         """Return the value associated with a named option.
 
@@ -2404,25 +2400,38 @@
         :param default: The value to return if the value is not set
         :return: The value or default value
         """
-        configobj = self._get_configobj()
-        if section is None:
-            section_obj = configobj
-        else:
-            try:
-                section_obj = configobj[section]
-            except KeyError:
-                return default
-        return section_obj.get(name, default)
+        try:
+            configobj = self._get_configobj()
+            if section is None:
+                section_obj = configobj
+            else:
+                try:
+                    section_obj = configobj[section]
+                except KeyError:
+                    return default
+            return section_obj.get(name, default)
+        except errors.UnknownSmartMethod:
+            return self._vfs_get_option(name, section, default)
 
-    def _get_configobj(self):
-        path = self._branch._remote_path()
-        response = self._branch._client.call_expecting_body(
-            'Branch.get_config_file', path)
+    def _response_to_configobj(self, response):
         if response[0][0] != 'ok':
             raise UnexpectedSmartServerResponse(response)
         lines = response[1].read_body_bytes().splitlines()
         return config.ConfigObj(lines, encoding='utf-8')
 
+
+class RemoteBranchConfig(RemoteConfig):
+    """A RemoteConfig for Branches."""
+
+    def __init__(self, branch):
+        self._branch = branch
+
+    def _get_configobj(self):
+        path = self._branch._remote_path()
+        response = self._branch._client.call_expecting_body(
+            'Branch.get_config_file', path)
+        return self._response_to_configobj(response)
+
     def set_option(self, value, name, section=None):
         """Set the value associated with a named option.
 
@@ -2444,10 +2453,45 @@
         if response != ():
             raise errors.UnexpectedSmartServerResponse(response)
 
+    def _real_object(self):
+        self._branch._ensure_real()
+        return self._branch._real_branch
+
     def _vfs_set_option(self, value, name, section=None):
-        self._branch._ensure_real()
-        return self._branch._real_branch._get_config().set_option(
-            value, name, section)
+        return self._real_object()._get_config().set_option(
+            value, name, section)
+
+
+class RemoteBzrDirConfig(RemoteConfig):
+    """A RemoteConfig for BzrDirs."""
+
+    def __init__(self, bzrdir):
+        self._bzrdir = bzrdir
+
+    def _get_configobj(self):
+        path = self._bzrdir._path_for_remote_call(self._bzrdir._client)
+        response = self._bzrdir._call_expecting_body(
+            'BzrDir.get_config_file', path)
+        return self._response_to_configobj(response)
+
+    def _vfs_get_option(self, name, section, default):
+        return self._real_object()._get_config().get_option(
+            name, section, default)
+
+    def set_option(self, value, name, section=None):
+        """Set the value associated with a named option.
+
+        :param value: The value to set
+        :param name: The name of the value to set
+        :param section: The section the option is in (if any)
+        """
+        return self._real_object()._get_config().set_option(
+            value, name, section)
+
+    def _real_object(self):
+        self._bzrdir._ensure_real()
+        return self._bzrdir._real_bzrdir
+
 
 
 def _extract_tar(tar, to_dir):

=== modified file 'bzrlib/tests/blackbox/test_branch.py'
--- a/bzrlib/tests/blackbox/test_branch.py	2009-04-08 03:34:31 +0000
+++ b/bzrlib/tests/blackbox/test_branch.py	2009-04-14 02:35:07 +0000
@@ -272,7 +272,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.assertLength(53, self.hpss_calls)
+        self.assertLength(54, self.hpss_calls)
 
     def test_branch_from_trivial_branch_streaming_acceptance(self):
         self.setup_smart_server_with_call_log()

=== modified file 'bzrlib/tests/blackbox/test_push.py'
--- a/bzrlib/tests/blackbox/test_push.py	2009-04-08 03:34:31 +0000
+++ b/bzrlib/tests/blackbox/test_push.py	2009-04-14 02:35:07 +0000
@@ -201,7 +201,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.assertLength(20, self.hpss_calls)
+        self.assertLength(21, self.hpss_calls)
 
     def test_push_smart_stacked_streaming_acceptance(self):
         self.setup_smart_server_with_call_log()

=== modified file 'bzrlib/tests/test_remote.py'
--- a/bzrlib/tests/test_remote.py	2009-04-10 19:37:20 +0000
+++ b/bzrlib/tests/test_remote.py	2009-04-14 02:35:07 +0000
@@ -770,7 +770,15 @@
         return OldSmartClient()
 
 
-class RemoteBranchTestCase(TestRemote):
+class RemoteBzrDirTestCase(TestRemote):
+
+    def make_remote_bzrdir(self, transport, client):
+        """Make a RemotebzrDir using 'client' as the _client."""
+        return RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
+            _client=client)
+
+
+class RemoteBranchTestCase(RemoteBzrDirTestCase):
 
     def make_remote_branch(self, transport, client):
         """Make a RemoteBranch using 'client' as its _SmartClient.
@@ -781,8 +789,7 @@
         # we do not want bzrdir to make any remote calls, so use False as its
         # _client.  If it tries to make a remote call, this will fail
         # immediately.
-        bzrdir = RemoteBzrDir(transport, remote.RemoteBzrDirFormat(),
-            _client=False)
+        bzrdir = self.make_remote_bzrdir(transport, False)
         repo = RemoteRepository(bzrdir, None, _client=client)
         branch_format = self.get_branch_format()
         format = RemoteBranchFormat(network_name=branch_format.network_name())
@@ -1419,6 +1426,39 @@
         client.finished_test()
 
 
+class TestBzrDirGetSetConfig(RemoteBzrDirTestCase):
+
+    def test__get_config(self):
+        client = FakeClient()
+        client.add_success_response_with_body('default_stack_on = /\n', 'ok')
+        transport = MemoryTransport()
+        bzrdir = self.make_remote_bzrdir(transport, client)
+        config = bzrdir.get_config()
+        self.assertEqual('/', config.get_default_stack_on())
+        self.assertEqual(
+            [('call_expecting_body', 'BzrDir.get_config_file', ('memory:///',))],
+            client._calls)
+
+    def test_set_option_uses_vfs(self):
+        self.setup_smart_server_with_call_log()
+        bzrdir = self.make_bzrdir('.')
+        verb = 'BzrDir.get_config_file'
+        # self.disable_verb(verb)
+        self.reset_smart_call_log()
+        config = bzrdir.get_config()
+        config.set_default_stack_on('/')
+        self.assertLength(3, self.hpss_calls)
+
+    def test_backwards_compat_get_option(self):
+        self.setup_smart_server_with_call_log()
+        bzrdir = self.make_bzrdir('.')
+        verb = 'BzrDir.get_config_file'
+        self.reset_smart_call_log()
+        self.assertEqual(None,
+            bzrdir._get_config().get_option('default_stack_on'))
+        self.assertLength(3, self.hpss_calls)
+
+
 class TestTransportIsReadonly(tests.TestCase):
 
     def test_true(self):




More information about the bazaar-commits mailing list