Rev 3078: Catch redirects when making directory for a new branch (Jonathan Lange) in file:///home/pqm/archives/thelove/bzr/%2Btrunk/

Canonical.com Patch Queue Manager pqm at pqm.ubuntu.com
Wed Dec 5 03:50:52 GMT 2007


At file:///home/pqm/archives/thelove/bzr/%2Btrunk/

------------------------------------------------------------
revno: 3078
revision-id:pqm at pqm.ubuntu.com-20071205035041-vjo05rrhyrqqmgxf
parent: pqm at pqm.ubuntu.com-20071205024011-bf20z11eucf3ltf1
parent: ian.clatworthy at internode.on.net-20071205030933-g0lj2zfcbjcp38n2
committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Wed 2007-12-05 03:50:41 +0000
message:
  Catch redirects when making directory for a new branch (Jonathan Lange)
modified:
  bzrlib/builtins.py             builtins.py-20050830033751-fc01482b9ca23183
  bzrlib/tests/blackbox/test_push.py test_push.py-20060329002750-929af230d5d22663
    ------------------------------------------------------------
    revno: 3077.1.1
    revision-id:ian.clatworthy at internode.on.net-20071205030933-g0lj2zfcbjcp38n2
    parent: pqm at pqm.ubuntu.com-20071205024011-bf20z11eucf3ltf1
    parent: jml at canonical.com-20071205021852-nzdcbnf5k6qoksbf
    committer: Ian Clatworthy <ian.clatworthy at internode.on.net>
    branch nick: ianc-integration
    timestamp: Wed 2007-12-05 13:09:33 +1000
    message:
      Catch redirects when making directory for a new branch (Jonathan Lange)
    modified:
      bzrlib/builtins.py             builtins.py-20050830033751-fc01482b9ca23183
      bzrlib/tests/blackbox/test_push.py test_push.py-20060329002750-929af230d5d22663
    ------------------------------------------------------------
    revno: 3066.3.3
    revision-id:jml at canonical.com-20071205021852-nzdcbnf5k6qoksbf
    parent: jml at canonical.com-20071203065235-kegbp7i5fv3evi02
    committer: jml at canonical.com
    branch nick: push-to-new-lp-branch
    timestamp: Wed 2007-12-05 13:18:52 +1100
    message:
      Unregister the test transport in order to be clean and to make test_selftest pass.
    modified:
      bzrlib/tests/blackbox/test_push.py test_push.py-20060329002750-929af230d5d22663
    ------------------------------------------------------------
    revno: 3066.3.2
    revision-id:jml at canonical.com-20071203065235-kegbp7i5fv3evi02
    parent: jml at canonical.com-20071203063020-tlt8roq0shhz7jut
    committer: jml at canonical.com
    branch nick: push-to-new-lp-branch
    timestamp: Mon 2007-12-03 17:52:35 +1100
    message:
      Add tests to check the handling of TooManyRedirections.
    modified:
      bzrlib/builtins.py             builtins.py-20050830033751-fc01482b9ca23183
      bzrlib/tests/blackbox/test_push.py test_push.py-20060329002750-929af230d5d22663
    ------------------------------------------------------------
    revno: 3066.3.1
    revision-id:jml at canonical.com-20071203063020-tlt8roq0shhz7jut
    parent: pqm at pqm.ubuntu.com-20071203012007-1tfytfzp7piacl7q
    committer: jml at canonical.com
    branch nick: push-to-new-lp-branch
    timestamp: Mon 2007-12-03 17:30:20 +1100
    message:
      Catch redirects raised by mkdir() in the push command. This is primarily
      helpful when using lp:/ URIs to make a new Launchpad branch.
    modified:
      bzrlib/builtins.py             builtins.py-20050830033751-fc01482b9ca23183
      bzrlib/tests/blackbox/test_push.py test_push.py-20060329002750-929af230d5d22663
=== modified file 'bzrlib/builtins.py'
--- a/bzrlib/builtins.py	2007-12-03 19:55:41 +0000
+++ b/bzrlib/builtins.py	2007-12-05 03:09:33 +0000
@@ -747,8 +747,17 @@
             # The destination doesn't exist; create it.
             # XXX: Refactor the create_prefix/no_create_prefix code into a
             #      common helper function
+
+            def make_directory(transport):
+                transport.mkdir('.')
+                return transport
+
+            def redirected(redirected_transport, e, redirection_notice):
+                return transport.get_transport(e.get_target_url())
+
             try:
-                to_transport.mkdir('.')
+                to_transport = transport.do_catching_redirections(
+                    make_directory, to_transport, redirected)
             except errors.FileExists:
                 if not use_existing_dir:
                     raise errors.BzrCommandError("Target directory %s"
@@ -763,6 +772,9 @@
                         " leading parent directories."
                         % location)
                 _create_prefix(to_transport)
+            except errors.TooManyRedirections:
+                raise errors.BzrCommandError("Too many redirections trying "
+                                             "to make %s." % location)
 
             # Now the target directory exists, but doesn't have a .bzr
             # directory. So we need to create it, along with any work to create

=== modified file 'bzrlib/tests/blackbox/test_push.py'
--- a/bzrlib/tests/blackbox/test_push.py	2007-06-27 19:13:50 +0000
+++ b/bzrlib/tests/blackbox/test_push.py	2007-12-05 02:18:52 +0000
@@ -18,6 +18,7 @@
 """Black-box tests for bzr push."""
 
 import os
+import re
 
 from bzrlib import (
     errors,
@@ -28,6 +29,8 @@
 from bzrlib.osutils import abspath
 from bzrlib.repofmt.knitrepo import RepositoryFormatKnit1
 from bzrlib.tests.blackbox import ExternalBase
+from bzrlib.transport import register_transport, unregister_transport
+from bzrlib.transport.memory import MemoryServer, MemoryTransport
 from bzrlib.uncommit import uncommit
 from bzrlib.urlutils import local_path_from_url
 from bzrlib.workingtree import WorkingTree
@@ -244,3 +247,82 @@
         self.run_bzr_error(['At ../dir you have a valid .bzr control'],
                 'push ../dir',
                 working_dir='tree')
+
+
+class RedirectingMemoryTransport(MemoryTransport):
+
+    def mkdir(self, path, mode=None):
+        path = self.abspath(path)[len(self._scheme):]
+        if path == '/source':
+            raise errors.RedirectRequested(
+                path, self._scheme + '/target', is_permanent=True)
+        elif path == '/infinite-loop':
+            raise errors.RedirectRequested(
+                path, self._scheme + '/infinite-loop', is_permanent=True)
+        else:
+            return super(RedirectingMemoryTransport, self).mkdir(
+                path, mode)
+
+
+class RedirectingMemoryServer(MemoryServer):
+
+    def setUp(self):
+        self._dirs = {'/': None}
+        self._files = {}
+        self._locks = {}
+        self._scheme = 'redirecting-memory+%s:///' % id(self)
+        register_transport(self._scheme, self._memory_factory)
+
+    def _memory_factory(self, url):
+        result = RedirectingMemoryTransport(url)
+        result._dirs = self._dirs
+        result._files = self._files
+        result._locks = self._locks
+        return result
+
+    def tearDown(self):
+        unregister_transport(self._scheme, self._memory_factory)
+
+
+class TestPushRedirect(ExternalBase):
+
+    def setUp(self):
+        ExternalBase.setUp(self)
+        self.memory_server = RedirectingMemoryServer()
+        self.memory_server.setUp()
+        self.addCleanup(self.memory_server.tearDown)
+
+        # Make the branch and tree that we'll be pushing.
+        t = self.make_branch_and_tree('tree')
+        self.build_tree(['tree/file'])
+        t.add('file')
+        t.commit('commit 1')
+
+    def test_push_redirects_on_mkdir(self):
+        """If the push requires a mkdir, push respects redirect requests.
+
+        This is added primarily to handle lp:/ URI support, so that users can
+        push to new branches by specifying lp:/ URIs.
+        """
+        os.chdir('tree')
+        destination_url = self.memory_server.get_url() + 'source'
+        self.run_bzr('push %s' % destination_url)
+        os.chdir('..')
+
+        local_revision = Branch.open('tree').last_revision()
+        remote_revision = Branch.open(
+            self.memory_server.get_url() + 'target').last_revision()
+        self.assertEqual(remote_revision, local_revision)
+
+    def test_push_gracefully_handles_too_many_redirects(self):
+        """Push fails gracefully if the mkdir generates a large number of
+        redirects.
+        """
+        os.chdir('tree')
+        destination_url = self.memory_server.get_url() + 'infinite-loop'
+        out, err = self.run_bzr_error(
+            ['Too many redirections trying to make %s\\.\n'
+             % re.escape(destination_url)],
+            'push %s' % destination_url, retcode=3)
+        os.chdir('..')
+        self.assertEqual('', out)




More information about the bazaar-commits mailing list