Rev 2468: (Andrew Bennetts) Fix incompatibility with < 0.16 smart servers. in file:///home/pqm/archives/thelove/bzr/%2Btrunk/

Canonical.com Patch Queue Manager pqm at pqm.ubuntu.com
Mon Apr 30 03:59:43 BST 2007


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

------------------------------------------------------------
revno: 2468
revision-id: pqm at pqm.ubuntu.com-20070430025942-y83xydh67a37zebd
parent: pqm at pqm.ubuntu.com-20070430022343-wnbvslzfz6fpyyj7
parent: andrew.bennetts at canonical.com-20070430022545-iubud5mcxc1mdsw9
committer: Canonical.com Patch Queue Manager<pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Mon 2007-04-30 03:59:42 +0100
message:
  (Andrew Bennetts) Fix incompatibility with < 0.16 smart servers.
modified:
  bzrlib/tests/test_remote.py    test_remote.py-20060720103555-yeeg2x51vn0rbtdp-2
  bzrlib/transport/remote.py     ssh.py-20060608202016-c25gvf1ob7ypbus6-1
    ------------------------------------------------------------
    revno: 2466.2.4
    merged: andrew.bennetts at canonical.com-20070430022545-iubud5mcxc1mdsw9
    parent: andrew.bennetts at canonical.com-20070430020406-9vvmb4f9x8bdmvv8
    committer: Andrew Bennetts <andrew.bennetts at canonical.com>
    branch nick: hpss-older-server-compat-bug
    timestamp: Mon 2007-04-30 12:25:45 +1000
    message:
      Tweaks asked for by Robert.
    ------------------------------------------------------------
    revno: 2466.2.3
    merged: andrew.bennetts at canonical.com-20070430020406-9vvmb4f9x8bdmvv8
    parent: andrew.bennetts at canonical.com-20070430020205-ensbvu0t14yb3tk4
    committer: Andrew Bennetts <andrew.bennetts at canonical.com>
    branch nick: hpss-older-server-compat-bug
    timestamp: Mon 2007-04-30 12:04:06 +1000
    message:
      Remove another XXX.
    ------------------------------------------------------------
    revno: 2466.2.2
    merged: andrew.bennetts at canonical.com-20070430020205-ensbvu0t14yb3tk4
    parent: andrew.bennetts at canonical.com-20070427030144-vz2vna1t31ymdgz9
    committer: Andrew Bennetts <andrew.bennetts at canonical.com>
    branch nick: hpss-older-server-compat-bug
    timestamp: Mon 2007-04-30 12:02:05 +1000
    message:
      Add tests for RemoteTransport.is_readonly in the style of the other remote object tests.
    ------------------------------------------------------------
    revno: 2466.2.1
    merged: andrew.bennetts at canonical.com-20070427030144-vz2vna1t31ymdgz9
    parent: pqm at pqm.ubuntu.com-20070426211103-h84prqh7a4ad3ez2
    committer: Andrew Bennetts <andrew.bennetts at canonical.com>
    branch nick: hpss-older-server-compat-bug
    timestamp: Fri 2007-04-27 13:01:44 +1000
    message:
      Fix incompatibility with < 0.16 smart servers.
=== modified file 'bzrlib/tests/test_remote.py'
--- a/bzrlib/tests/test_remote.py	2007-04-26 08:15:40 +0000
+++ b/bzrlib/tests/test_remote.py	2007-04-30 02:04:06 +0000
@@ -44,6 +44,7 @@
 from bzrlib.smart import server, medium
 from bzrlib.smart.client import _SmartClient
 from bzrlib.transport.memory import MemoryTransport
+from bzrlib.transport.remote import RemoteTransport
 
 
 class BasicRemoteObjectTests(tests.TestCaseWithTransport):
@@ -60,12 +61,6 @@
         self.transport.disconnect()
         tests.TestCaseWithTransport.tearDown(self)
 
-    def test_is_readonly(self):
-        # XXX: this is a poor way to test RemoteTransport, but currently there's
-        # no easy way to substitute in a fake client on a transport like we can
-        # with RemoteBzrDir/Branch/Repository.
-        self.assertEqual(self.transport.is_readonly(), False)
-
     def test_create_remote_bzrdir(self):
         b = remote.RemoteBzrDir(self.transport)
         self.assertIsInstance(b, BzrDir)
@@ -104,20 +99,6 @@
         self.assertIsInstance(d, BzrDir)
 
 
-class ReadonlyRemoteTransportTests(tests.TestCaseWithTransport):
-
-    def setUp(self):
-        self.transport_server = server.ReadonlySmartTCPServer_for_testing
-        super(ReadonlyRemoteTransportTests, self).setUp()
-
-    def test_is_readonly_yes(self):
-        # XXX: this is a poor way to test RemoteTransport, but currently there's
-        # no easy way to substitute in a fake client on a transport like we can
-        # with RemoteBzrDir/Branch/Repository.
-        transport = self.get_readonly_transport()
-        self.assertEqual(transport.is_readonly(), True)
-
-
 class FakeProtocol(object):
     """Lookalike SmartClientRequestProtocolOne allowing body reading tests."""
 
@@ -404,6 +385,44 @@
             client._calls)
 
 
+class TestTransportIsReadonly(tests.TestCase):
+
+    def test_true(self):
+        client = FakeClient([(('yes',), '')])
+        transport = RemoteTransport('bzr://example.com/', medium=False,
+                                    _client=client)
+        self.assertEqual(True, transport.is_readonly())
+        self.assertEqual(
+            [('call', 'Transport.is_readonly', ())],
+            client._calls)
+
+    def test_false(self):
+        client = FakeClient([(('no',), '')])
+        transport = RemoteTransport('bzr://example.com/', medium=False,
+                                    _client=client)
+        self.assertEqual(False, transport.is_readonly())
+        self.assertEqual(
+            [('call', 'Transport.is_readonly', ())],
+            client._calls)
+
+    def test_error_from_old_server(self):
+        """bzr 0.15 and earlier servers don't recognise the is_readonly verb.
+        
+        Clients should treat it as a "no" response, because is_readonly is only
+        advisory anyway (a transport could be read-write, but then the
+        underlying filesystem could be readonly anyway).
+        """
+        client = FakeClient([(
+            ('error', "Generic bzr smart protocol error: "
+                      "bad request 'Transport.is_readonly'"), '')])
+        transport = RemoteTransport('bzr://example.com/', medium=False,
+                                    _client=client)
+        self.assertEqual(False, transport.is_readonly())
+        self.assertEqual(
+            [('call', 'Transport.is_readonly', ())],
+            client._calls)
+
+
 class TestRemoteRepository(tests.TestCase):
     """Base for testing RemoteRepository protocol usage.
     

=== modified file 'bzrlib/transport/remote.py'
--- a/bzrlib/transport/remote.py	2007-04-26 06:19:07 +0000
+++ b/bzrlib/transport/remote.py	2007-04-30 02:25:45 +0000
@@ -74,11 +74,17 @@
     # RemoteTransport is an adapter from the Transport object model to the 
     # SmartClient model, not an encoder.
 
-    def __init__(self, url, clone_from=None, medium=None):
+    def __init__(self, url, clone_from=None, medium=None, _client=None):
         """Constructor.
 
+        :param clone_from: Another RemoteTransport instance that this one is
+            being cloned from.  Attributes such as credentials and the medium
+            will be reused.
         :param medium: The medium to use for this RemoteTransport. This must be
             supplied if clone_from is None.
+        :param _client: Override the _SmartClient used by this transport.  This
+            should only be used for testing purposes; normally this is
+            determined from the medium.
         """
         ### Technically super() here is faulty because Transport's __init__
         ### fails to take 2 parameters, and if super were to choose a silly
@@ -97,6 +103,10 @@
             # reuse same connection
             self._medium = clone_from._medium
         assert self._medium is not None
+        if _client is None:
+            self._client = client._SmartClient(self._medium)
+        else:
+            self._client = _client
 
     def abspath(self, relpath):
         """Return the full url to the given relative path.
@@ -123,6 +133,12 @@
             return True
         elif resp == ('no', ):
             return False
+        elif resp == ('error', "Generic bzr smart protocol error: "
+                               "bad request 'Transport.is_readonly'"):
+            # XXX: nasty hack: servers before 0.16 don't have a
+            # 'Transport.is_readonly' verb, so we do what clients before 0.16
+            # did: assume False.
+            return False
         else:
             self._translate_error(resp)
         assert False, 'weird response %r' % (resp,)
@@ -160,12 +176,11 @@
 
     def _call2(self, method, *args):
         """Call a method on the remote server."""
-        return client._SmartClient(self._medium).call(method, *args)
+        return self._client.call(method, *args)
 
     def _call_with_body_bytes(self, method, args, body):
         """Call a method on the remote server with body bytes."""
-        smart_client = client._SmartClient(self._medium)
-        return smart_client.call_with_body_bytes(method, args, body)
+        return self._client.call_with_body_bytes(method, args, body)
 
     def has(self, relpath):
         """Indicate whether a remote file of the given name exists or not.




More information about the bazaar-commits mailing list