Rev 4249: Fix handling of fallback repositories some more in http://bazaar.launchpad.net/%7Evila/bzr/integration2

Vincent Ladeuil v.ladeuil+lp at free.fr
Fri Apr 3 17:05:48 BST 2009


At http://bazaar.launchpad.net/%7Evila/bzr/integration2

------------------------------------------------------------
revno: 4249 [merge]
revision-id: v.ladeuil+lp at free.fr-20090403160532-55znb9353wezpqgk
parent: pqm at pqm.ubuntu.com-20090403151446-o35ylr3cst5ioejg
parent: robertc at robertcollins.net-20090403020831-9hk3udjt5rd32iux
committer: Vincent Ladeuil <v.ladeuil+lp at free.fr>
branch nick: integration2
timestamp: Fri 2009-04-03 18:05:32 +0200
message:
  Fix handling of fallback repositories some more
modified:
  NEWS                           NEWS-20050323055033-4e00b5db738777ff
  bzrlib/remote.py               remote.py-20060720103555-yeeg2x51vn0rbtdp-1
  bzrlib/smart/branch.py         branch.py-20061124031907-mzh3pla28r83r97f-1
  bzrlib/smart/request.py        request.py-20061108095550-gunadhxmzkdjfeek-1
  bzrlib/tests/blackbox/test_push.py test_push.py-20060329002750-929af230d5d22663
  bzrlib/tests/test_remote.py    test_remote.py-20060720103555-yeeg2x51vn0rbtdp-2
  bzrlib/tests/test_smart.py     test_smart.py-20061122024551-ol0l0o0oofsu9b3t-2
------------------------------------------------------------
Use --levels 0 (or -n0) to see merged revisions.
-------------- next part --------------
=== modified file 'NEWS'
--- a/NEWS	2009-04-03 01:11:32 +0000
+++ b/NEWS	2009-04-03 16:05:32 +0000
@@ -290,6 +290,11 @@
   handle existing svn properties that define a list of keywords to be
   expanded.  (Ian Clatworthy)
 
+* ``RemoteBranchConfig`` will use a new verb ``Branch.set_config_option``
+  to write config settings to smart servers that support this, saving
+  5 round trips on the stacked streaming acceptance test.
+  (Robert Collins, Andrew Bennetts)
+
 * ``RemoteBranch`` now provides ``_get_config`` for access to just the
   branch specific configuration from a remote server, which uses the 
   already existing ``Branch.get_config_file`` smart verb.

=== modified file 'bzrlib/remote.py'
--- a/bzrlib/remote.py	2009-04-02 03:37:30 +0000
+++ b/bzrlib/remote.py	2009-04-03 02:08:31 +0000
@@ -917,12 +917,26 @@
         if isinstance(repository, RemoteRepository):
             raise AssertionError()
         self._real_repository = repository
-        # If the _real_repository has _fallback_repositories, clear them out,
-        # because we want it to have the same set as this repository.  This is
-        # reasonable to do because the fallbacks we clear here are from a
-        # "real" branch, and we're about to replace them with the equivalents
-        # from a RemoteBranch.
-        self._real_repository._fallback_repositories = []
+        # three code paths happen here:
+        # 1) old servers, RemoteBranch.open() calls _ensure_real before setting
+        # up stacking. In this case self._fallback_repositories is [], and the
+        # real repo is already setup. Preserve the real repo and
+        # RemoteRepository.add_fallback_repository will avoid adding
+        # duplicates.
+        # 2) new servers, RemoteBranch.open() sets up stacking, and when
+        # ensure_real is triggered from a branch, the real repository to
+        # set already has a matching list with separate instances, but
+        # as they are also RemoteRepositories we don't worry about making the
+        # lists be identical.
+        # 3) new servers, RemoteRepository.ensure_real is triggered before
+        # RemoteBranch.ensure real, in this case we get a repo with no fallbacks
+        # and need to populate it.
+        if (self._fallback_repositories and
+            len(self._real_repository._fallback_repositories) !=
+            len(self._fallback_repositories)):
+            if len(self._real_repository._fallback_repositories):
+                raise AssertionError(
+                    "cannot cleanly remove existing _fallback_repositories")
         for fb in self._fallback_repositories:
             self._real_repository.add_fallback_repository(fb)
         if self._lock_mode == 'w':
@@ -1057,7 +1071,9 @@
         # _real_branch had its get_stacked_on_url method called), then the
         # repository to be added may already be in the _real_repositories list.
         if self._real_repository is not None:
-            if repository not in self._real_repository._fallback_repositories:
+            fallback_locations = [repo.bzrdir.root_transport.base for repo in
+                self._real_repository._fallback_repositories]
+            if repository.bzrdir.root_transport.base not in fallback_locations:
                 self._real_repository.add_fallback_repository(repository)
 
     def add_inventory(self, revid, inv, parents):
@@ -2389,14 +2405,13 @@
         return section_obj.get(name, default)
 
     def _get_configobj(self):
-        path = self._branch.bzrdir._path_for_remote_call(
-            self._branch._client)
+        path = self._branch._remote_path()
         response = self._branch._client.call_expecting_body(
             'Branch.get_config_file', path)
         if response[0][0] != 'ok':
             raise UnexpectedSmartServerResponse(response)
-        bytes = response[1].read_body_bytes()
-        return config.ConfigObj([bytes], encoding='utf-8')
+        lines = response[1].read_body_bytes().splitlines()
+        return config.ConfigObj(lines, encoding='utf-8')
 
     def set_option(self, value, name, section=None):
         """Set the value associated with a named option.
@@ -2405,7 +2420,19 @@
         :param name: The name of the value to set
         :param section: The section the option is in (if any)
         """
-        return self._vfs_set_option(value, name, section)
+        medium = self._branch._client._medium
+        if medium._is_remote_before((1, 14)):
+            return self._vfs_set_option(value, name, section)
+        try:
+            path = self._branch._remote_path()
+            response = self._branch._client.call('Branch.set_config_option',
+                path, self._branch._lock_token, self._branch._repo_lock_token,
+                value.encode('utf8'), name, section or '')
+        except errors.UnknownSmartMethod:
+            medium._remember_remote_is_before((1, 14))
+            return self._vfs_set_option(value, name, section)
+        if response != ():
+            raise errors.UnexpectedSmartServerResponse(response)
 
     def _vfs_set_option(self, value, name, section=None):
         self._branch._ensure_real()

=== modified file 'bzrlib/smart/branch.py'
--- a/bzrlib/smart/branch.py	2009-04-02 03:37:30 +0000
+++ b/bzrlib/smart/branch.py	2009-04-03 00:37:53 +0000
@@ -148,6 +148,16 @@
             return FailedSmartServerResponse(('TipChangeRejected', msg))
 
 
+class SmartServerBranchRequestSetConfigOption(SmartServerLockedBranchRequest):
+    """Set an option in the branch configuration."""
+
+    def do_with_locked_branch(self, branch, value, name, section):
+        if not section:
+            section = None
+        branch._get_config().set_option(value.decode('utf8'), name, section)
+        return SuccessfulSmartServerResponse(())
+
+
 class SmartServerBranchRequestSetLastRevision(SmartServerSetTipRequest):
 
     def do_tip_change_with_locked_branch(self, branch, new_last_revision_id):

=== modified file 'bzrlib/smart/request.py'
--- a/bzrlib/smart/request.py	2009-03-26 06:59:15 +0000
+++ b/bzrlib/smart/request.py	2009-04-02 05:22:42 +0000
@@ -448,10 +448,12 @@
     'Branch.last_revision_info', 'bzrlib.smart.branch', 'SmartServerBranchRequestLastRevisionInfo')
 request_handlers.register_lazy(
     'Branch.lock_write', 'bzrlib.smart.branch', 'SmartServerBranchRequestLockWrite')
-request_handlers.register_lazy(
-    'Branch.revision_history', 'bzrlib.smart.branch', 'SmartServerRequestRevisionHistory')
-request_handlers.register_lazy(
-    'Branch.set_last_revision', 'bzrlib.smart.branch', 'SmartServerBranchRequestSetLastRevision')
+request_handlers.register_lazy( 'Branch.revision_history',
+    'bzrlib.smart.branch', 'SmartServerRequestRevisionHistory')
+request_handlers.register_lazy( 'Branch.set_config_option',
+    'bzrlib.smart.branch', 'SmartServerBranchRequestSetConfigOption')
+request_handlers.register_lazy( 'Branch.set_last_revision',
+    'bzrlib.smart.branch', 'SmartServerBranchRequestSetLastRevision')
 request_handlers.register_lazy(
     'Branch.set_last_revision_info', 'bzrlib.smart.branch',
     'SmartServerBranchRequestSetLastRevisionInfo')

=== modified file 'bzrlib/tests/blackbox/test_push.py'
--- a/bzrlib/tests/blackbox/test_push.py	2009-04-02 04:01:23 +0000
+++ b/bzrlib/tests/blackbox/test_push.py	2009-04-03 01:05:08 +0000
@@ -217,7 +217,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(47, self.hpss_calls)
+        self.assertLength(42, self.hpss_calls)
         remote = Branch.open('public')
         self.assertEndsWith(remote.get_stacked_on_url(), '/parent')
 

=== modified file 'bzrlib/tests/test_remote.py'
--- a/bzrlib/tests/test_remote.py	2009-04-02 03:37:30 +0000
+++ b/bzrlib/tests/test_remote.py	2009-04-03 01:21:06 +0000
@@ -1332,16 +1332,9 @@
         self.assertEqual('rejection message', err.msg)
 
 
-class TestBranchControlGetBranchConf(RemoteBranchTestCase):
-    """Getting the branch configuration should use an abstract method not vfs.
-    """
+class TestBranchGetSetConfig(RemoteBranchTestCase):
 
     def test_get_branch_conf(self):
-        # We should see that branch.get_config() does a single rpc to get the
-        # remote configuration file, abstracting away where that is stored on
-        # the server.  However at the moment it always falls back to using the
-        # vfs, and this would need some changes in config.py.
-
         # in an empty branch we decode the response properly
         client = FakeClient()
         client.add_expected_call(
@@ -1357,6 +1350,55 @@
              ('call_expecting_body', 'Branch.get_config_file', ('memory:///',))],
             client._calls)
 
+    def test_get_multi_line_branch_conf(self):
+        # Make sure that multiple-line branch.conf files are supported
+        #
+        # https://bugs.edge.launchpad.net/bzr/+bug/354075
+        client = FakeClient()
+        client.add_expected_call(
+            'Branch.get_stacked_on_url', ('memory:///',),
+            'error', ('NotStacked',),)
+        client.add_success_response_with_body('a = 1\nb = 2\nc = 3\n', 'ok')
+        transport = MemoryTransport()
+        branch = self.make_remote_branch(transport, client)
+        config = branch.get_config()
+        self.assertEqual(u'2', config.get_user_option('b'))
+
+    def test_set_option(self):
+        client = FakeClient()
+        client.add_expected_call(
+            'Branch.get_stacked_on_url', ('memory:///',),
+            'error', ('NotStacked',),)
+        client.add_expected_call(
+            'Branch.lock_write', ('memory:///', '', ''),
+            'success', ('ok', 'branch token', 'repo token'))
+        client.add_expected_call(
+            'Branch.set_config_option', ('memory:///', 'branch token',
+            'repo token', 'foo', 'bar', ''),
+            'success', ())
+        client.add_expected_call(
+            'Branch.unlock', ('memory:///', 'branch token', 'repo token'),
+            'success', ('ok',))
+        transport = MemoryTransport()
+        branch = self.make_remote_branch(transport, client)
+        branch.lock_write()
+        config = branch._get_config()
+        config.set_option('foo', 'bar')
+        branch.unlock()
+        client.finished_test()
+
+    def test_backwards_compat_set_option(self):
+        self.setup_smart_server_with_call_log()
+        branch = self.make_branch('.')
+        verb = 'Branch.set_config_option'
+        self.disable_verb(verb)
+        branch.lock_write()
+        self.addCleanup(branch.unlock)
+        self.reset_smart_call_log()
+        branch._get_config().set_option('value', 'name')
+        self.assertLength(10, self.hpss_calls)
+        self.assertEqual('value', branch._get_config().get_option('name'))
+
 
 class TestBranchLockWrite(RemoteBranchTestCase):
 

=== modified file 'bzrlib/tests/test_smart.py'
--- a/bzrlib/tests/test_smart.py	2009-03-24 23:19:12 +0000
+++ b/bzrlib/tests/test_smart.py	2009-04-02 05:22:42 +0000
@@ -502,7 +502,41 @@
             request.execute(''))
 
 
-class SetLastRevisionTestBase(tests.TestCaseWithMemoryTransport):
+class TestLockedBranch(tests.TestCaseWithMemoryTransport):
+
+    def get_lock_tokens(self, branch):
+        branch_token = branch.lock_write()
+        repo_token = branch.repository.lock_write()
+        branch.repository.unlock()
+        return branch_token, repo_token
+
+
+class TestSmartServerBranchRequestSetConfigOption(TestLockedBranch):
+
+    def test_value_name(self):
+        branch = self.make_branch('.')
+        request = smart.branch.SmartServerBranchRequestSetConfigOption(
+            branch.bzrdir.root_transport)
+        branch_token, repo_token = self.get_lock_tokens(branch)
+        config = branch._get_config()
+        result = request.execute('', branch_token, repo_token, 'bar', 'foo',
+            '')
+        self.assertEqual(SuccessfulSmartServerResponse(()), result)
+        self.assertEqual('bar', config.get_option('foo'))
+
+    def test_value_name_section(self):
+        branch = self.make_branch('.')
+        request = smart.branch.SmartServerBranchRequestSetConfigOption(
+            branch.bzrdir.root_transport)
+        branch_token, repo_token = self.get_lock_tokens(branch)
+        config = branch._get_config()
+        result = request.execute('', branch_token, repo_token, 'bar', 'foo',
+            'gam')
+        self.assertEqual(SuccessfulSmartServerResponse(()), result)
+        self.assertEqual('bar', config.get_option('foo', 'gam'))
+
+
+class SetLastRevisionTestBase(TestLockedBranch):
     """Base test case for verbs that implement set_last_revision."""
 
     def setUp(self):
@@ -512,11 +546,7 @@
         self.tree = self.make_branch_and_memory_tree('.')
 
     def lock_branch(self):
-        b = self.tree.branch
-        branch_token = b.lock_write()
-        repo_token = b.repository.lock_write()
-        b.repository.unlock()
-        return branch_token, repo_token
+        return self.get_lock_tokens(self.tree.branch)
 
     def unlock_branch(self):
         self.tree.branch.unlock()
@@ -1377,6 +1407,9 @@
             smart.request.request_handlers.get('Branch.revision_history'),
             smart.branch.SmartServerRequestRevisionHistory)
         self.assertEqual(
+            smart.request.request_handlers.get('Branch.set_config_option'),
+            smart.branch.SmartServerBranchRequestSetConfigOption)
+        self.assertEqual(
             smart.request.request_handlers.get('Branch.set_last_revision'),
             smart.branch.SmartServerBranchRequestSetLastRevision)
         self.assertEqual(



More information about the bazaar-commits mailing list