Rev 2524: Add tests around connection reuse. in file:///v/home/vila/src/experimental/reuse.transports/
Vincent Ladeuil
v.ladeuil+lp at free.fr
Thu Jun 7 12:22:06 BST 2007
At file:///v/home/vila/src/experimental/reuse.transports/
------------------------------------------------------------
revno: 2524
revision-id: v.ladeuil+lp at free.fr-20070607112203-2c3190a3ppqg9c6m
parent: v.ladeuil+lp at free.fr-20070606142608-i9ufaqewadslf1cn
committer: Vincent Ladeuil <v.ladeuil+lp at free.fr>
branch nick: reuse.transports
timestamp: Thu 2007-06-07 13:22:03 +0200
message:
Add tests around connection reuse.
* bzrlib/transport/__init__.py:
(ConnectedTransport._update_credentials): New method for
transports that can authenticate again while keeping the
connection alive.
* bzrlib/tests/test_transport_implementations.py:
(TransportTests.test__reuse_for,
TransportTests.test_reuse_connection_for_various_paths): More
tests for _reuse_for.
* bzrlib/tests/test_transport.py:
(TestConnectedTransport.test_connection_sharing_propagate_credentials):
Add test for _update_credentials.
(TestReusedTransports.test_reuse_same_transport): More tests.
modified:
bzrlib/tests/test_transport.py testtransport.py-20050718175618-e5cdb99f4555ddce
bzrlib/tests/test_transport_implementations.py test_transport_implementations.py-20051227111451-f97c5c7d5c49fce7
bzrlib/transport/__init__.py transport.py-20050711165921-4978aa7ce1285ad5
-------------- next part --------------
=== modified file 'bzrlib/tests/test_transport.py'
--- a/bzrlib/tests/test_transport.py 2007-06-06 13:52:02 +0000
+++ b/bzrlib/tests/test_transport.py 2007-06-07 11:22:03 +0000
@@ -546,6 +546,9 @@
base_url = self._server.get_url()
# try getting the transport via the regular interface:
t = get_transport(base_url)
+ # vila--20070607 if the following are commented out the test suite
+ # still pass. Is this really still needed or was it a forgotten
+ # temporary fix ?
if not isinstance(t, self.transport_class):
# we did not get the correct transport class type. Override the
# regular connection behaviour by direct construction.
@@ -680,6 +683,14 @@
self.assertIs(connection, c._get_connection())
self.assertIs(password, c._get_credentials())
+ # credentials can be updated
+ new_password = 'even more secret'
+ c._update_credentials(new_password)
+ self.assertIs(connection, t._get_connection())
+ self.assertIs(new_password, t._get_credentials())
+ self.assertIs(connection, c._get_connection())
+ self.assertIs(new_password, c._get_credentials())
+
class TestReusedTransports(TestCase):
"""Tests for transport reuse"""
@@ -694,13 +705,13 @@
t4 = get_transport('http://foo/path', possible_transports=[t3])
self.assertIs(t3, t4)
- t3 = get_transport('http://foo/path')
- t4 = get_transport('http://foo/path/', possible_transports=[t3])
- self.assertIs(t3, t4)
+ t5 = get_transport('http://foo/path')
+ t6 = get_transport('http://foo/path/', possible_transports=[t5])
+ self.assertIs(t5, t6)
def test_don_t_reuse_different_transport(self):
- t = get_transport('http://foo/path')
- t2 = get_transport('http://bar/path', possible_transports=[t])
+ t1 = get_transport('http://foo/path')
+ t2 = get_transport('http://bar/path', possible_transports=[t1])
self.assertIsNot(t, t2)
=== modified file 'bzrlib/tests/test_transport_implementations.py'
--- a/bzrlib/tests/test_transport_implementations.py 2007-06-06 14:26:08 +0000
+++ b/bzrlib/tests/test_transport_implementations.py 2007-06-07 11:22:03 +0000
@@ -1071,6 +1071,67 @@
self.assertEquals(t1._host, t2._host)
self.assertEquals(t1._port, t2._port)
+ def test__reuse_for(self):
+ t = self.get_transport()
+ if not isinstance(t, ConnectedTransport):
+ raise TestSkipped("not a connected transport")
+
+ def new_url(scheme=None, user=None, password=None,
+ host=None, port=None, path=None):
+ """Build a new url from t.base chaging only parts of it.
+
+ Only the parameters different from None will be changed.
+ """
+ if scheme is None: scheme = t._scheme
+ if user is None: user = t._user
+ if password is None: password = t._password
+ if user is None: user = t._user
+ if host is None: host = t._host
+ if port is None: port = t._port
+ if path is None: path = t._path
+ return t._unsplit_url(scheme, user, password, host, port, path)
+
+ self.assertIsNot(t, t._reuse_for(new_url(scheme='foo')))
+ if t._user == 'me':
+ user = 'you'
+ else:
+ user = 'me'
+ self.assertIsNot(t, t._reuse_for(new_url(user=user)))
+ # passwords are not taken into account because:
+ # - it makes no sense to have two different valid passwords for the
+ # same user
+ # - _password in ConnectedTransport is intended to collect what the
+ # user specified from the command-line and there are cases where the
+ # new url can contain no password (if the url was built from an
+ # existing transport.base for example)
+ # - password are considered part of the credentials provided at
+ # connection creation time and as such may not be present in the url
+ # (they may be typed by the user when prompted for example)
+ self.assertIs(t, t._reuse_for(new_url(password='from space')))
+ # We will not connect, we can use a invalid host
+ self.assertIsNot(t, t._reuse_for(new_url(host=t._host + 'bar')))
+ if t._port == 1234:
+ port = 4321
+ else:
+ port = 1234
+ self.assertIsNot(t, t._reuse_for(new_url(port=port)))
+
+ def test_reuse_connection_for_various_paths(self):
+ t = self.get_transport()
+ if not isinstance(t, ConnectedTransport):
+ raise TestSkipped("not a connected transport")
+
+ t.has('surely_not') # Force connection
+ self.assertIsNot(None, t._get_connection())
+
+ subdir = t._reuse_for(t.base + 'whatever/but/deep/down/the/path')
+ self.assertIsNot(t, subdir)
+ self.assertIs(t._get_connection(), subdir._get_connection())
+
+ home = subdir._reuse_for(t.base + 'home')
+ self.assertIs(t._get_connection(), home._get_connection())
+ self.assertIs(subdir._get_connection(), home._get_connection())
+
def test_clone(self):
# TODO: Test that clone moves up and down the filesystem
t1 = self.get_transport()
=== modified file 'bzrlib/transport/__init__.py'
--- a/bzrlib/transport/__init__.py 2007-06-06 14:26:08 +0000
+++ b/bzrlib/transport/__init__.py 2007-06-07 11:22:03 +0000
@@ -1057,7 +1057,9 @@
self._path) = self._initial_split_url(base)
if from_transport is not None:
# Copy the password as it does not appear in base and will be lost
- # otherwise.
+ # otherwise. It can appear in the _initial_split_url above if the
+ # user provided it on the command line. Otherwise, daughter classes
+ # will prompt the user for one when appropriate.
self._password = from_transport._password
base = self._unsplit_url(self._scheme,
@@ -1244,6 +1246,19 @@
(connection, credentials) = self._connection[0]
return self._connection[0][1]
+ def _update_credentials(self, credentials):
+ """Update the credentials of the current connection.
+
+ Some protocols can renegociate the credentials within a connection,
+ this method allows daughter classes to share updated credentials.
+
+ :param credentials: the updated credentials.
+ """
+ # We don't want to call _set_connection here as we are only updating
+ # the credentials not creating a new connection.
+ (connection, old_credentials) = self._connection[0]
+ self._connection[0] = (connection, credentials)
+
def _reuse_for(self, other_base):
"""Returns a transport sharing the same connection if possible.
@@ -1261,16 +1276,13 @@
"""
(scheme, user, password, host, port, path) = self._split_url(other_base)
transport = None
- # Don't compare passwords, they may be absent from other_base
- if (scheme,
- user,
- host, port) == (self._scheme,
- self._user,
- self._host, self._port):
+ # Don't compare passwords, they may be absent from other_base or from
+ # self and they don't carry more information than user anyway.
+ if (scheme, user, host, port) == (self._scheme,
+ self._user, self._host, self._port):
if not path.endswith('/'):
# This normally occurs at __init__ time, but it's easier to do
- # it now to avoid positives (creating two transports for the
- # same base).
+ # it now to avoid creating two transports for the same base.
path += '/'
if self._path == path:
# shortcut, it's really the same transport
@@ -1284,7 +1296,8 @@
# jam 20060426 For compatibility we copy the functions here
-# TODO: The should be marked as deprecated
+# TODO: They should be marked as deprecated
+# vila-20070606: How should we do that ?
urlescape = urlutils.escape
urlunescape = urlutils.unescape
# We try to recognize an url lazily (ignoring user, password, etc)
More information about the bazaar-commits
mailing list